├── packages.txt
├── Fear.npy
├── Sad.npy
├── logo.png
├── model.h5
├── Angry.npy
├── Happy.npy
├── Neutral.npy
├── emotion.npy
├── label.npy
├── Surprise.npy
├── vibescape.gif
├── tempCodeRunnerFile.py
├── polarplot.py
├── LICENSE
├── requirements.txt
├── songrecommendations.py
├── README.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── 1_🎵_Homepage.py
└── pages
├── 4_❤️_Youtube.py
├── 2_🧡_Soundcloud.py
├── 5_📊_Analyzer .py
└── 3_💚_Spotify.py
/packages.txt:
--------------------------------------------------------------------------------
1 | libgl1
2 | ffmpeg
3 | libsm6
4 | libxext6
--------------------------------------------------------------------------------
/Fear.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/Fear.npy
--------------------------------------------------------------------------------
/Sad.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/Sad.npy
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/logo.png
--------------------------------------------------------------------------------
/model.h5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/model.h5
--------------------------------------------------------------------------------
/Angry.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/Angry.npy
--------------------------------------------------------------------------------
/Happy.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/Happy.npy
--------------------------------------------------------------------------------
/Neutral.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/Neutral.npy
--------------------------------------------------------------------------------
/emotion.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/emotion.npy
--------------------------------------------------------------------------------
/label.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/label.npy
--------------------------------------------------------------------------------
/Surprise.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/Surprise.npy
--------------------------------------------------------------------------------
/vibescape.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NebulaTris/vibescape/HEAD/vibescape.gif
--------------------------------------------------------------------------------
/tempCodeRunnerFile.py:
--------------------------------------------------------------------------------
1 | if st.session_state["run"] != "false":
2 | webrtc_streamer(key="key", desired_playing_state=True , video_processor_factory=EmotionProcessor)
--------------------------------------------------------------------------------
/polarplot.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import streamlit as st
4 |
5 | def feature_plot(features):
6 |
7 | labels= list(features)[:]
8 | stats= features.mean().tolist()
9 |
10 | angles=np.linspace(0, 2*np.pi, len(labels), endpoint=False)
11 |
12 | # close the plot
13 | stats=np.concatenate((stats,[stats[0]]))
14 | angles=np.concatenate((angles,[angles[0]]))
15 |
16 | #Size of the figure
17 | fig=plt.figure(figsize = (18,18))
18 |
19 | ax = fig.add_subplot(221, polar=True)
20 | ax.plot(angles, stats, 'o-', linewidth=2, label = "Features", color= 'gray')
21 | ax.fill(angles, stats, alpha=0.25, facecolor='gray')
22 | ax.set_thetagrids(angles[0:7] * 180/np.pi, labels , fontsize = 13)
23 |
24 |
25 | ax.set_rlabel_position(250)
26 | plt.yticks([0.2 , 0.4 , 0.6 , 0.8 ], ["0.2",'0.4', "0.6", "0.8"], color="grey", size=12)
27 | plt.ylim(0,1)
28 |
29 | plt.legend(loc='best', bbox_to_anchor=(0.1, 0.1))
30 |
31 | st.pyplot(plt)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Shambhavi Mishra
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | absl-py==1.4.0
2 | aiohttp==3.8.5
3 | aiohttp-retry==2.8.3
4 | aioice==0.9.0
5 | aiortc==1.5.0
6 | aiosignal==1.3.1
7 | altair==5.0.1
8 | anyio==3.7.0
9 | appdirs==1.4.4
10 | argon2-cffi==21.3.0
11 | argon2-cffi-bindings==21.2.0
12 | arrow==1.2.3
13 | astunparse==1.6.3
14 | async-timeout==4.0.2
15 | atomicwrites==1.4.0
16 | av==10.0.0
17 | backports.weakref==1.0.post1
18 | bleach==6.0.0
19 | blinker==1.6.2
20 | brotlipy==0.7.0
21 | cachetools==5.3.1
22 | jupyter-events==0.6.3
23 | jupyter_client==8.3.0
24 | jupyter_server_terminals==0.4.4
25 | jupyterlab-pygments==0.2.2
26 | keras==2.13.1
27 | keras-utils==1.0.13
28 | markdown-it-py==3.0.0
29 | markdownlit==0.0.7
30 | mdurl==0.1.2
31 | mediapipe==0.10.1
32 | mypy-extensions==0.4.3
33 | nbclassic==1.0.0
34 | nbclient==0.8.0
35 | nbconvert==7.6.0
36 | notebook==6.5.4
37 | notebook_shim==0.2.3
38 | oauthlib==3.2.2
39 | opencv-python-headless==4.8.0.76
40 | openpyxl==3.0.10
41 | overrides==7.3.1
42 | pandocfilters==1.5.0
43 | pep8==1.7.1
44 | pylibsrtp==0.8.0
45 | pyOpenSSL==23.2.0
46 | PyQt5==5.15.7
47 | PyQtWebEngine==5.15.4
48 | pytest==7.1.2
49 | python-dotenv==1.0.0
50 | python-json-logger==2.0.7
51 | python-lsp-jsonrpc==1.0.0
52 | queuelib==1.5.0
53 | scikit-learn==1.3.0
54 | scipy==1.10.0
55 | seaborn==0.12.2
56 | spotipy==2.23.0
57 | sounddevice==0.4.6
58 | streamlit==1.25.0
59 | streamlit-camera-input-live==0.2.0
60 | streamlit-card==0.0.61
61 | streamlit-embedcode==0.1.2
62 | streamlit-extras==0.3.0
63 | streamlit-faker==0.0.2
64 | streamlit-image-coordinates==0.1.6
65 | streamlit-keyup==0.2.0
66 | streamlit-lottie==0.0.5
67 | streamlit-on-Hover-tabs==1.0.1
68 | streamlit-option-menu==0.3.6
69 | streamlit-player==0.1.5
70 | streamlit-toggle-switch==1.0.2
71 | streamlit-vertical-slider==1.0.2
72 | streamlit-webrtc==0.45.1
73 | tensorboard==2.13.0
74 | tensorboard-data-server==0.7.1
75 | tensorflow==2.13.0
76 | tensorflow-estimator==2.13.0
77 | tensorflow-hub==0.14.0
78 | tensorflow-io-gcs-filesystem==0.31.0
79 | twilio==8.5.0
80 | webcolors==1.13
81 | webencodings==0.5.1
82 | websocket-client==1.6.1
83 |
--------------------------------------------------------------------------------
/songrecommendations.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import base64
3 |
4 | import matplotlib.pyplot as plt
5 | import numpy as np
6 | import seaborn as sns
7 | import streamlit as st
8 | from PIL import Image
9 |
10 | def get_token(clientId,clientSecret):
11 | url = "https://accounts.spotify.com/api/token"
12 | headers = {}
13 | data = {}
14 | message = f"{clientId}:{clientSecret}"
15 | messageBytes = message.encode('ascii')
16 | base64Bytes = base64.b64encode(messageBytes)
17 | base64Message = base64Bytes.decode('ascii')
18 | headers['Authorization'] = "Basic " + base64Message
19 | data['grant_type'] = "client_credentials"
20 | r = requests.post(url, headers=headers, data=data)
21 | token = r.json()['access_token']
22 | return token
23 |
24 |
25 | def get_track_recommendations(seed_tracks,token):
26 | limit = 10
27 | recUrl = f"https://api.spotify.com/v1/recommendations?limit={limit}&seed_tracks={seed_tracks}"
28 |
29 | headers = {
30 | "Authorization": "Bearer " + token
31 | }
32 |
33 | res = requests.get(url=recUrl, headers=headers)
34 | return res.json()
35 |
36 | def song_recommendation_vis(reco_df):
37 | reco_df['duration_min'] = round(reco_df['duration_ms'] / 1000, 0)
38 | reco_df["popularity_range"] = reco_df["popularity"] - (reco_df['popularity'].min() - 1)
39 |
40 | plt.figure(figsize=(15, 6), facecolor=(.9, .9, .9))
41 |
42 | x = reco_df['name']
43 | y = reco_df['duration_min']
44 | s = reco_df['popularity_range']*20
45 |
46 | color_labels = reco_df['explicit'].unique()
47 | rgb_values = sns.color_palette("Set1", 8)
48 | color_map = dict(zip(color_labels, rgb_values))
49 |
50 | plt.scatter(x, y, s, alpha=0.7, c=reco_df['explicit'].map(color_map))
51 | plt.xticks(rotation=90)
52 | plt.legend()
53 | # show the graph
54 | plt.show()
55 |
56 | st.pyplot(plt)
57 |
58 |
59 | # def save_album_image(img_url, track_id):
60 | # r = requests.get(img_url)
61 | # open('img/' + track_id + '.jpg', "wb").write(r.content)
62 |
63 | # def get_album_mage(track_id):
64 | # return Image.open('img/' + track_id + '.jpg')
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://vibescape.streamlit.app/)
2 |
3 | Vibescape is an emotion music recommender system that provides a unique and personalized music streaming experience. It utilizes facial emotion detection to analyze the user's emotions and recommend songs that match their mood. The application supports streaming from popular platforms such as Spotify, SoundCloud, and YouTube.
4 |
5 | **Live Demo** **here**
6 |
7 | ## Features
8 | - **Emotion-based Music Recommendation:** Vibescape uses facial emotion detection to analyze the user's emotions and recommends songs that match their mood.
9 | - **Streaming from Multiple Platforms:** Users can stream music from their favorite platforms including Spotify, SoundCloud, and YouTube.
10 | - **Personalized Playlists:** The application creates personalized playlists based on the user's emotions and preferences.
11 | - **User-Friendly Interface:** Vibescape offers an intuitive and easy-to-use interface for a seamless music streaming experience.
12 |
13 | ## Installation and Setup
14 |
15 | 1. Clone the repository:
16 | ```bash
17 | git clone https://github.com/NebulaTris/vibescape.git
18 | cd vibescape
19 | ```
20 |
21 | 2. Install the required dependencies using `pip`:
22 | ```bash
23 | pip install -r requirements.txt
24 | ```
25 |
26 | ## Usage
27 |
28 | 1. Run the Streamlit app:
29 | ```bash
30 | streamlit run 1_🎵_Homepage.py
31 | ```
32 |
33 | 2. Open your web browser and go to `http://localhost:8501` to access the Vibescape application.
34 |
35 | ## Emotion Detection
36 |
37 | Vibescape uses facial emotion detection to analyze the user's emotions. Make sure your device has a camera enabled to utilize this feature effectively.
38 |
39 | ## Supported Platforms
40 |
41 | Vibescape supports music streaming from the following platforms:
42 | - Spotify
43 | - SoundCloud
44 | - YouTube
45 |
46 | ## Contributing
47 |
48 | Contributions are welcome! If you'd like to contribute to Vibescape, please follow these steps:
49 | 1. Fork the repository.
50 | 2. Create a new branch for your feature/bugfix.
51 | 3. Commit your changes and push to your fork.
52 | 4. Submit a pull request with a detailed description of your changes.
53 |
54 | ## License
55 |
56 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
57 |
58 |
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | share/python-wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | MANIFEST
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .nox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | *.py,cover
50 | .hypothesis/
51 | .pytest_cache/
52 | cover/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | .pybuilder/
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | # For a library or package, you might want to ignore these files since the code is
87 | # intended to run in multiple environments; otherwise, check them in:
88 | # .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # poetry
98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99 | # This is especially recommended for binary packages to ensure reproducibility, and is more
100 | # commonly ignored for libraries.
101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102 | #poetry.lock
103 |
104 | # pdm
105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106 | #pdm.lock
107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108 | # in version control.
109 | # https://pdm.fming.dev/#use-with-ide
110 | .pdm.toml
111 |
112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113 | __pypackages__/
114 |
115 | # Celery stuff
116 | celerybeat-schedule
117 | celerybeat.pid
118 |
119 | # SageMath parsed files
120 | *.sage.py
121 |
122 | # Environments
123 | .env
124 | .venv
125 | env/
126 | venv/
127 | ENV/
128 | env.bak/
129 | venv.bak/
130 |
131 | # Spyder project settings
132 | .spyderproject
133 | .spyproject
134 |
135 | # Rope project settings
136 | .ropeproject
137 |
138 | # mkdocs documentation
139 | /site
140 |
141 | # mypy
142 | .mypy_cache/
143 | .dmypy.json
144 | dmypy.json
145 |
146 | # Pyre type checker
147 | .pyre/
148 |
149 | # pytype static type analyzer
150 | .pytype/
151 |
152 | # Cython debug symbols
153 | cython_debug/
154 |
155 | # PyCharm
156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158 | # and can be added to the global gitignore or merged into this file. For a more nuclear
159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160 | #.idea/
161 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | Discord (@nebulatris).
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | This documentation contains a set of guidelines to help you during the contribution process.
4 |
5 | ## Submitting Contributions👩📈
6 |
7 | Below you will find the process and workflow used to review and merge your changes.
8 |
9 | 1. Find/Create an issue
10 |
11 | - Take a look at the Existing Issues or create your **own** Issues!
12 | - Wait for the Issue to be assigned to you after which you can start working on it.
13 | - Note : Every change in this project should/must have an associated issue.
14 |
15 |
16 | 2. Fork the repository by clicking on the ["Fork"](https://github.com/NebulaTris/vibescape/fork) button at the top right corner of the page.
17 |
18 |
19 | 3. Once you are in your fork the url should look something like
20 | `https://github.com//vibescape/`
21 |
22 | 4. Go to preferred folder in your computer and paste the following command (Only one of it if you don't have ssh setup then go with HTTP command)
23 | - For HTTP
24 | ```
25 | git clone https://github.com//vibescape.git
26 | ```
27 | - For SSH
28 | ```bash
29 | git clone git@github.com:/vibescape.git
30 | ```
31 |
32 | 5. Now enter the folder by running the following command
33 | ```bash
34 | cd vibescape
35 | ```
36 |
37 | 5. Now you are in the `vibescape` folder
38 |
39 | 6. Now go ahead and create a new branch, then switch to that branch.
40 | ```bash
41 | git checkout -b fix-issue-
42 | ```
43 |
44 | 7. Make your changes to the codebase. Test your changes to make sure they work as expected.
45 |
46 | 8. After done you can now push this changes. for doing that follow the following command chain
47 | - `git status` (Shows the changed files)
48 | - `git add .` (Will add all the files to staging area)
49 | - `git commit -m "feat/docs/fix: "`
50 | - `git push origin fix-issue-`
51 |
52 | - **NOTE**: A PR should have only one commit. Multiple commits should be squashed.
53 |
54 | 9. Create a Pull Request:
55 | - Go to your forked GitHub repository and navigate to the Pull Request section.
56 | - Click on the pop-up that says "Pull Request" to be redirected to the pull request page.
57 | - Fill in the form template of the pull request, adding a title and description that explain your contribution.
58 | - Include screenshots if they help clarify the enhancement/implementation/bug/documentation.
59 | - Click on **Submit** to create the pull request*
60 |
61 | 10. Hurrey! You just did your contribution to this project 🎉
62 |
63 | 11. Wait for your pull request to be reviewed and merged.
64 |
65 | >NOTE: Please make sure to follow the [Code of conduct](https://github.com/NebulaTris/vibescape/blob/master/CODE_OF_CONDUCT.md) while contributing.
66 |
67 |
68 | ## Alternatively, using GitHub Codespaces:
69 |
70 | 1. Follow steps 1 to 3 above, to fork the repository.
71 | 2. Navigate to the forked repository i.e. `https://github.com//vibescape/`
72 | 3. Click **Code**, then click **Create codespace on master**.
73 | 4. A new codespace will be created.
74 | 5. Follow steps 6 to 9 above using the terminal in the codespace. Instead of step 9 you can also directly create a PR through codespace by going to the **Source Control view** in **Activity Bar**.
75 |
76 | ## Alternatively, using GitHub Desktop:
77 | 1. Open GitHub Desktop and log in to your GitHub account.
78 |
79 | 2. Make sure you are on the "Current Repository" view. If not, go to "File" and select "Add Local Repository" to add your repository.
80 |
81 | 3. In the "Current Repository" view, ensure you are on the branch that you want to submit a pull request for. If you're not on the correct branch, use the "Branch" menu to switch to the correct branch.
82 |
83 | 4. Once you're on the correct branch, make your changes and commit them to the branch. You can do this by clicking the "+" button in the upper-left corner of the GitHub Desktop window, making your changes, and then entering a commit message.
84 |
85 | 5. After you've made your changes and committed them, click the "Push origin" button in the top-right corner of the GitHub Desktop window. This will push your changes to the remote repository on GitHub.
86 |
87 | 6. Now, go to the GitHub website, navigate to your fork of the repository, and you should see a button to "Compare & pull request" between your fork and the original repository, click on it.
88 |
89 | 7. On the pull request page, you can review your changes and add any additional information, such as a title and a description, that you want to include with your pull request.
90 |
91 | 8. Once you're satisfied with your pull request, click the "Create pull request" button to submit it.
92 |
93 | **Note:** In order to create a pull request, you must have a fork of the original repository in your GitHub account and you must have made the changes in that forked repository.
94 |
95 |
96 | ## Your Pull Request has been submitted and will be reviewed by the maintainer and merged.
97 |
98 |
99 | ### Need more help?🤔
100 |
101 | You can refer to the following articles on basics of Git and Github and also contact the Project Mentors,
102 | in case you are stuck:
103 |
104 | - [Watch this video to get started, if you have no clue about open source](https://youtu.be/SYtPC9tHYyQ)
105 | - [Forking a Repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo)
106 | - [Cloning a Repo](https://help.github.com/en/desktop/contributing-to-projects/creating-a-pull-request)
107 | - [How to create a Pull Request](https://opensource.com/article/19/7/create-pull-request-github)
108 | - [Getting started with Git and GitHub](https://towardsdatascience.com/getting-started-with-git-and-github-6fcd0f2d4ac6)
109 | - [Learn GitHub from Scratch](https://lab.github.com/githubtraining/introduction-to-github)
110 |
111 |
112 | Hope you will learn something new while contributing in this project!!😇
113 |
--------------------------------------------------------------------------------
/1_🎵_Homepage.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | #Imports for streamlit
3 | import streamlit as st
4 | import av
5 | import cv2
6 | from streamlit_webrtc import (
7 | RTCConfiguration,
8 | VideoProcessorBase,
9 | WebRtcMode,
10 | webrtc_streamer,
11 | )
12 | from streamlit_extras.switch_page_button import switch_page
13 | from streamlit_extras.app_logo import add_logo
14 |
15 | #Imports for ml model
16 | import numpy as np
17 | import mediapipe as mp
18 | from keras.models import load_model
19 |
20 |
21 | st.set_page_config(
22 | page_title="Vibescape",
23 | page_icon="🎵",
24 | )
25 |
26 | page_bg_img = """
27 |
120 | """
121 | add_logo("https://github.com/NebulaTris/vibescape/blob/main/logo.png?raw=true")
122 | st.markdown(page_bg_img, unsafe_allow_html=True)
123 | st.title("Vibescape 🎉🎶")
124 | st.sidebar.success("Select a page below.")
125 | st.sidebar.text("Developed by Shambhavi")
126 |
127 | st.markdown("**Hey there, emotion explorer! Are you ready for a wild ride through the rollercoaster of feelings?** 🎢🎵")
128 | st.markdown("**Welcome to Vibescape, where our snazzy AI meets your wacky emotional world head-on! We've got our virtual goggles on (nope, not really, but it sounds cool** 😎 **) to analyze your emotions using a webcam. And what do we do with all those emotions, you ask? We turn them into the most toe-tapping, heartwarming, and occasionally hilarious music playlists you've ever heard!** 🕺💃")
129 | st.markdown("**You've heard of Spotify, SoundCloud, and YouTube, right? Well, hold onto your hats because Vibescape combines these musical behemoths into one epic entertainment extravaganza! Now you can dive into your favorite streaming services with a twist — they'll be serving up songs based on your mood!** 🎶")
130 | st.markdown("**Feeling like a happy-go-lucky panda today? We've got a playlist for that! Or perhaps you've got the moody blues? No worries, Vibescape has your back. Our AI wizardry detects your vibes and serves up the tunes that match your moment.** 🐼🎉")
131 | st.markdown("**So, get ready for a whirlwind of emotions and music. Vibescape is here to turn your webcam into a mood ring, your screen into a dance floor, and your heart into a DJ booth. What's next? Well, that's entirely up to you and your ever-changing feelings!**")
132 | st.markdown("**So, strap in** 🚀 **, hit that webcam** 📷 **, and let the musical journey begin! Vibescape is your ticket to a rollercoaster of emotions, all set to your favorite tunes.** 🎢🎵")
133 |
134 | RTC_CONFIGURATION = RTCConfiguration(
135 | {"iceServers": [{
136 | "urls": ["stun:stun.l.google.com:19302"]
137 | }]})
138 |
139 | # CWD path
140 | HERE = Path(__file__).parent
141 |
142 | model = load_model("model.h5")
143 | label = np.load("label.npy")
144 |
145 | holistic = mp.solutions.holistic
146 | hands = mp.solutions.hands
147 | holis = holistic.Holistic()
148 | drawing = mp.solutions.drawing_utils
149 |
150 | if "run" not in st.session_state:
151 | st.session_state["run"] = ""
152 |
153 | run = np.load("emotion.npy")[0]
154 |
155 | try:
156 | emotion = np.load("emotion.npy")[0]
157 | except:
158 | emotion = ""
159 |
160 |
161 | class EmotionProcessor(VideoProcessorBase):
162 | def recv(self, frame: av.VideoFrame) -> av.VideoFrame:
163 | frm = frame.to_ndarray(format="bgr24")
164 | frm = cv2.flip(frm, 1)
165 | res = holis.process(cv2.cvtColor(frm, cv2.COLOR_BGR2RGB))
166 |
167 | lst = []
168 | if res.face_landmarks:
169 | for i in res.face_landmarks.landmark:
170 | lst.append(i.x - res.face_landmarks.landmark[1].x)
171 | lst.append(i.y - res.face_landmarks.landmark[1].y)
172 |
173 | if res.left_hand_landmarks:
174 | for i in res.left_hand_landmarks.landmark:
175 | lst.append(i.x - res.left_hand_landmarks.landmark[8].x)
176 | lst.append(i.y - res.left_hand_landmarks.landmark[8].y)
177 | else:
178 | for i in range(42):
179 | lst.append(0.0)
180 |
181 | if res.right_hand_landmarks:
182 | for i in res.right_hand_landmarks.landmark:
183 | lst.append(i.x - res.right_hand_landmarks.landmark[8].x)
184 | lst.append(i.y - res.right_hand_landmarks.landmark[8].y)
185 | else:
186 | for i in range(42):
187 | lst.append(0.0)
188 |
189 | lst = np.array(lst).reshape(1, -1)
190 |
191 | pred = label[np.argmax(model.predict(lst))]
192 | print(pred)
193 | cv2.putText(frm, pred, (50,50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)
194 |
195 | np.save("emotion.npy",np.array([pred]))
196 |
197 | emotion = pred
198 |
199 | drawing.draw_landmarks(frm, res.face_landmarks, holistic.FACEMESH_CONTOURS)
200 | drawing.draw_landmarks(frm, res.left_hand_landmarks, hands.HAND_CONNECTIONS)
201 | drawing.draw_landmarks(frm, res.right_hand_landmarks, hands.HAND_CONNECTIONS)
202 |
203 | return av.VideoFrame.from_ndarray(frm, format="bgr24")
204 |
205 |
206 |
207 | webrtc_streamer(key="key", desired_playing_state=st.session_state.get("run", "") == "true" ,mode=WebRtcMode.SENDRECV, rtc_configuration=RTC_CONFIGURATION, video_processor_factory=EmotionProcessor, media_stream_constraints={
208 | "video": True,
209 | "audio": False
210 | },
211 | async_processing=True)
212 |
213 |
214 | col1, col2, col6 = st.columns([1, 1, 1])
215 |
216 | with col1:
217 | start_btn = st.button("Start")
218 | with col6:
219 | stop_btn = st.button("Stop")
220 |
221 | if start_btn:
222 | st.session_state["run"] = "true"
223 | st.experimental_rerun()
224 |
225 | if stop_btn:
226 | st.session_state["run"] = "false"
227 | st.experimental_rerun()
228 | else:
229 | if not emotion:
230 | pass
231 | else:
232 | np.save("emotion.npy", np.array([""]))
233 | st.session_state["emotion"] = run
234 | st.success("Your current emotion is: " + emotion)
235 | st.subheader("Choose your streaming service")
236 |
237 | col3, col4, col5 = st.columns(3)
238 |
239 | with col4:
240 | btn = st.button("Spotify")
241 | if btn:
242 | switch_page("Spotify")
243 |
244 | with col5:
245 | btn2 = st.button("Youtube")
246 | if btn2:
247 | switch_page("Youtube")
248 |
249 | with col3:
250 | btn3 = st.button("Soundcloud")
251 | if btn3:
252 | switch_page("Soundcloud")
--------------------------------------------------------------------------------
/pages/4_❤️_Youtube.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 | import webbrowser
3 | from streamlit_extras.app_logo import add_logo
4 | from streamlit_player import st_player
5 |
6 | page_bg_img = """
7 |
97 | """
98 | add_logo("https://github.com/NebulaTris/vibescape/blob/main/logo.png?raw=true")
99 |
100 | st.markdown(page_bg_img, unsafe_allow_html=True)
101 | st.title("❤️ Vibescape-Youtube")
102 | st.markdown(''':red[**Note : It is recommended that you scan your face , for Vibescape to groove with you!**]''')
103 |
104 | st.sidebar.success("Youtube has been selected as your music player.")
105 | st.sidebar.text("Developed by Shambhavi")
106 |
107 |
108 | if "run" not in st.session_state:
109 | st.write("**Looks like you have skipped the face scan on the homepage and came here, just for music, just choose your vibe manually for Vibescape to groove with you!**")
110 | option = st.selectbox(
111 | 'What''s your vibe today?',
112 | ('Happy', 'Sad', 'Angry','Fear','Surprise','Neutral'))
113 | if option == "Happy":
114 | st.session_state["emotion"] = "Happy"
115 | elif option == "Sad":
116 | st.session_state["emotion"] = "Sad"
117 | elif option == "Angry":
118 | st.session_state["emotion"] = "Angry"
119 | elif option == "Fear":
120 | st.session_state["emotion"] = "Fear"
121 | elif option == "Surprise":
122 | st.session_state["emotion"] = "Surprise"
123 | else:
124 | st.session_state["emotion"] = "Neutral"
125 | else:
126 | st.write("You current emotion is: " , st.session_state["emotion"])
127 |
128 | col1, col2 = st.columns(2)
129 |
130 | with col1:
131 | hindi = st.button("Hindi")
132 | if hindi:
133 | if st.session_state["emotion"] == "Happy":
134 | st_player("https://www.youtube.com/watch?v=OcmcptbsvzQ")
135 | elif st.session_state["emotion"] == "Sad":
136 | st_player("https://www.youtube.com/watch?v=e6LMUGrN57A")
137 | elif st.session_state["emotion"] == "Angry":
138 | st_player("https://www.youtube.com/playlist?list=PLxNm0dqHxmlupV3dr7uq4Rl8L5nwlGKQA")
139 | elif st.session_state["emotion"] == "Fear":
140 | st_player("https://www.youtube.com/watch?v=8joIt7wsayU")
141 | elif st.session_state["emotion"] == "Surprise":
142 | st_player("https://www.youtube.com/watch?v=rtTI1rh9U5M")
143 | elif st.session_state["emotion"] == "Neutral":
144 | st_player("https://www.youtube.com/watch?v=EVF_AuhJgLg")
145 | else:
146 | st_player("hhttps://www.youtube.com/watch?v=S_TW9h7vUB8&list=RDEMyQ80_Idfp-UOKusrpqoh-g&start_radio=1")
147 |
148 | bengali = st.button("Bengali")
149 | if bengali:
150 | if st.session_state["emotion"] == "Happy":
151 | st_player("https://www.youtube.com/playlist?list=PLzxTmXYDR-xXsilCSwT-Bds5w96k2GOXF")
152 | elif st.session_state["emotion"] == "Sad":
153 | st_player("https://www.youtube.com/watch?v=RRbqeGr8mJE")
154 | elif st.session_state["emotion"] == "Angry":
155 | st_player("https://www.youtube.com/watch?v=_RBlE6Ar8mw")
156 | elif st.session_state["emotion"] == "Fear":
157 | st_player("https://www.youtube.com/watch?v=5PtVfECix1M")
158 | elif st.session_state["emotion"] == "Surprise":
159 | st_player("https://www.youtube.com/watch?v=39uMLYTh40Q")
160 | elif st.session_state["emotion"] == "Neutral":
161 | st_player("https://www.youtube.com/watch?v=39uMLYTh40Q")
162 | else:
163 | st_player("https://www.youtube.com/watch?v=5TJqoxsoXc4")
164 |
165 | marathi = st.button("Marathi")
166 | if marathi:
167 | if st.session_state["emotion"] == "Happy":
168 | st_player("https://www.youtube.com/playlist?list=PLN_pFG_Bv6D4-gpRS06J2auY87DQaEDuo")
169 | elif st.session_state["emotion"] == "Sad":
170 | st_player("https://www.youtube.com/playlist?list=PLpjbqr-x3QIpcfrn_McAvi80s5bGuWr9f")
171 | elif st.session_state["emotion"] == "Angry":
172 | st_player("https://www.youtube.com/playlist?list=PLpjbqr-x3QIpw79fcOQJDi3FdMcYwWZki")
173 | elif st.session_state["emotion"] == "Fear":
174 | st_player("https://soundcloud.com/miss_happy/sets/hindi-songs")
175 | elif st.session_state["emotion"] == "Surprise":
176 | st_player("https://www.youtube.com/watch?v=imUUogeGUio")
177 | elif st.session_state["emotion"] == "Neutral":
178 | st_player("https://www.youtube.com/watch?v=xUSTF4Gyj8M")
179 | else:
180 | st_player("https://www.youtube.com/watch?v=xUSTF4Gyj8M")
181 |
182 | with col2:
183 | english = st.button("English")
184 | if english:
185 | if st.session_state["emotion"] == "Happy":
186 | st_player("https://www.youtube.com/watch?v=ONM4uXLe8CU")
187 | elif st.session_state["emotion"] == "Sad":
188 | st_player("https://www.youtube.com/watch?v=BwleOnML1Fo")
189 | elif st.session_state["emotion"] == "Angry":
190 | st_player("https://www.youtube.com/watch?v=YnezhNgzdss")
191 | elif st.session_state["emotion"] == "Fear":
192 | st_player("https://www.youtube.com/watch?v=G-YNNJIe2Vk")
193 | elif st.session_state["emotion"] == "Surprise":
194 | st_player("https://www.youtube.com/watch?v=zStYh2eHOWk")
195 | elif st.session_state["emotion"] == "Neutral":
196 | st_player("https://www.youtube.com/watch?v=KNaCJYX-mgY")
197 | else:
198 | st_player("https://www.youtube.com/watch?v=KNaCJYX-mgY")
199 |
200 | punjabi = st.button("Punjabi")
201 | if punjabi:
202 | if st.session_state["emotion"] == "Happy":
203 | st_player("https://www.youtube.com/watch?v=heXb7XQYVKo")
204 | elif st.session_state["emotion"] == "Sad":
205 | st_player("https://www.youtube.com/watch?v=8Jq0E9ryVEc")
206 | elif st.session_state["emotion"] == "Angry":
207 | st_player("https://www.youtube.com/watch?v=Pha76iGaauM")
208 | elif st.session_state["emotion"] == "Fear":
209 | st.write("No such playlist found , hence default playlist is being played.")
210 | st_player("https://www.youtube.com/watch?v=Id2fc96XPYE")
211 | elif st.session_state["emotion"] == "Surprise":
212 | st_player("https://www.youtube.com/watch?v=Id2fc96XPYE")
213 | elif st.session_state["emotion"] == "Neutral":
214 | st_player("https://www.youtube.com/watch?v=QbXLf5QvNUM")
215 | else:
216 | st_player("https://www.youtube.com/watch?v=QbXLf5QvNUM")
217 |
218 | telugu = st.button("Telugu")
219 | if telugu:
220 | if st.session_state["emotion"] == "Happy":
221 | st_player("https://www.youtube.com/playlist?list=PLMpEfaKcGjpWEgNtdnsvLX6LzQL0UC0EM")
222 | elif st.session_state["emotion"] == "Sad":
223 | st_player("https://www.youtube.com/watch?v=yvnsgYQyGXo")
224 | elif st.session_state["emotion"] == "Angry":
225 | st_player("https://www.youtube.com/watch?v=CYj6li9939w")
226 | elif st.session_state["emotion"] == "Fear":
227 | st.write("No such playlist found , hence default playlist is being played.")
228 | st_player("https://www.youtube.com/playlist?list=PL4sNEU2Mgm6bNnbM-qKPmTwwDromFqpMQ")
229 | elif st.session_state["emotion"] == "Surprise":
230 | st_player("https://www.youtube.com/watch?v=ADqgenM4uqQ")
231 | elif st.session_state["emotion"] == "Neutral":
232 | st_player("https://www.youtube.com/playlist?list=PL4sNEU2Mgm6bNnbM-qKPmTwwDromFqpMQ")
233 | else:
234 | st.write("No such playlist found , hence default playlist is being played.")
235 | st_player("https://www.youtube.com/playlist?list=PL4sNEU2Mgm6bNnbM-qKPmTwwDromFqpMQ")
--------------------------------------------------------------------------------
/pages/2_🧡_Soundcloud.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 | import webbrowser
3 | from streamlit_extras.app_logo import add_logo
4 | import streamlit.components.v1 as components
5 | from streamlit_player import st_player
6 |
7 | page_bg_img = """
8 |
98 | """
99 | add_logo("https://github.com/NebulaTris/vibescape/blob/main/logo.png?raw=true")
100 |
101 | st.markdown(page_bg_img, unsafe_allow_html=True)
102 | st.title("🧡 Vibescape-Soundcloud")
103 | st.markdown(''':orange[**Note : It is recommended that you scan your face , for Vibescape to groove with you!**]''')
104 | st.sidebar.success("Soundcloud has been selected as your music player.")
105 | st.sidebar.text("Developed by Shambhavi")
106 |
107 | if "run" not in st.session_state:
108 | st.write("**Looks like you have skipped the face scan on the homepage and came here, just for music, just choose your vibe manually for Vibescape to groove with you!**")
109 | option = st.selectbox(
110 | 'What''s your vibe today?',
111 | ('Happy', 'Sad', 'Angry','Fear','Surprise','Neutral'))
112 | if option == "Happy":
113 | st.session_state["emotion"] = "Happy"
114 | elif option == "Sad":
115 | st.session_state["emotion"] = "Sad"
116 | elif option == "Angry":
117 | st.session_state["emotion"] = "Angry"
118 | elif option == "Fear":
119 | st.session_state["emotion"] = "Fear"
120 | elif option == "Surprise":
121 | st.session_state["emotion"] = "Surprise"
122 | else:
123 | st.session_state["emotion"] = "Neutral"
124 | else:
125 | st.write("You current emotion is: " , st.session_state["emotion"])
126 |
127 | col1, col2 = st.columns(2)
128 |
129 | with col1:
130 | hindi = st.button("Hindi")
131 | if hindi:
132 | if st.session_state["emotion"] == "Happy":
133 | st_player("https://soundcloud.com/miss_happy/sets/hindi-songs")
134 | elif st.session_state["emotion"] == "Sad":
135 | st_player("https://soundcloud.com/aryan-ambuj-752291555/sets/sad-hindi-songs-a-little")
136 | elif st.session_state["emotion"] == "Angry":
137 | st_player("https://soundcloud.com/user-905375441/sets/hindi-rap-songs")
138 | elif st.session_state["emotion"] == "Fear":
139 | st_player("https://soundcloud.com/narendraswapnil/sets/aavirbhaav-a-hindi-horror")
140 | elif st.session_state["emotion"] == "Surprise":
141 | st_player("https://soundcloud.com/maryam-zeb-592867892/sets/hot-hindi-hits-2010-2020")
142 | elif st.session_state["emotion"] == "Neutral":
143 | st_player("https://soundcloud.com/user635881277/sets/hindi-hits")
144 | else:
145 | st_player("hhttps://soundcloud.com/user635881277/sets/hindi-hits")
146 |
147 | bengali = st.button("Bengali")
148 | if bengali:
149 | if st.session_state["emotion"] == "Happy":
150 | st_player("https://soundcloud.com/h-a-i/sets/bengali-songs")
151 | elif st.session_state["emotion"] == "Sad":
152 | st_player("https://soundcloud.com/rechna-begum/sets/bengali-songs")
153 | elif st.session_state["emotion"] == "Angry":
154 | st_player("https://soundcloud.com/dj-aryan-music")
155 | elif st.session_state["emotion"] == "Fear":
156 | st.write("No such playlist found , hence default playlist is being played.")
157 | st_player("https://soundcloud.com/mushera-khandaker-1/sets/bengali-songs")
158 | elif st.session_state["emotion"] == "Surprise":
159 | st_player("https://soundcloud.com/mushera-khandaker-1/sets/bengali-songs")
160 | elif st.session_state["emotion"] == "Neutral":
161 | st_player("https://soundcloud.com/ayesha-laskar/sets/bengali-songs")
162 | else:
163 | st_player("https://soundcloud.com/ayesha-laskar/sets/bengali-songs")
164 |
165 | marathi = st.button("Marathi")
166 | if marathi:
167 | if st.session_state["emotion"] == "Happy":
168 | st_player("https://soundcloud.com/mahesh-gaikwad-301342141/sets/dj-marathi-song")
169 | elif st.session_state["emotion"] == "Sad":
170 | st_player("https://soundcloud.com/ghostblogger/break-up-ke-baad-marathi-song")
171 | elif st.session_state["emotion"] == "Angry":
172 | st_player("https://soundcloud.com/sandip-vadde-915668005/sets/marathi-rap")
173 | elif st.session_state["emotion"] == "Fear":
174 | st.write("No such playlist found , hence default playlist is being played.")
175 | st_player("https://soundcloud.com/shrawan-paradkar/sets/marathi-songs")
176 | elif st.session_state["emotion"] == "Surprise":
177 | st_player("https://soundcloud.com/mahesh-gaikwad-301342141/sets/dj-marathi-song")
178 | elif st.session_state["emotion"] == "Neutral":
179 | st_player("https://soundcloud.com/shrawan-paradkar/sets/marathi-songs")
180 | else:
181 | st_player("https://soundcloud.com/shrawan-paradkar/sets/marathi-songs")
182 |
183 | with col2:
184 | english = st.button("English")
185 | if english:
186 | if st.session_state["emotion"] == "Happy":
187 | st_player("https://soundcloud.com/gabriela-astudillo-398435247/sets/happy-english-music")
188 | elif st.session_state["emotion"] == "Sad":
189 | st_player("https://soundcloud.com/jishnu-rajwani-695997535/sets/famous-english-sad-songs-of")
190 | elif st.session_state["emotion"] == "Angry":
191 | st_player("https://soundcloud.com/thomashayden/sets/tech-house-vibes-only")
192 | elif st.session_state["emotion"] == "Fear":
193 | st_player("https://soundcloud.com/tito-tito-675324717/sets/horror-english")
194 | elif st.session_state["emotion"] == "Surprise":
195 | st_player("https://soundcloud.com/manea-claudia/sets/top-love-songs-2022-playlist-1")
196 | elif st.session_state["emotion"] == "Neutral":
197 | st_player("https://soundcloud.com/sejal-agarkar/sets/english-songs-hits")
198 | else:
199 | st_player("https://soundcloud.com/mona-khaled-858700005/sets/english-cringe")
200 |
201 | punjabi = st.button("Punjabi")
202 | if punjabi:
203 | if st.session_state["emotion"] == "Happy":
204 | st_player("https://soundcloud.com/danyal-safir/sets/punjabi-party-songs-2022")
205 | elif st.session_state["emotion"] == "Sad":
206 | st_player("https://soundcloud.com/tania-tania-658084779/sets/best-punjabi-sad-songs-2023")
207 | elif st.session_state["emotion"] == "Angry":
208 | st_player("https://soundcloud.com/jas-singh-31/sets/gym-punjabi-playlist")
209 | elif st.session_state["emotion"] == "Fear":
210 | st_player("https://soundcloud.com/user-94762183/timmy-trumpet-punjabi-x-code_pandorum-murda-fvck-riddim-x-horror-noise-ofdts-mashup")
211 | elif st.session_state["emotion"] == "Surprise":
212 | st_player("https://soundcloud.com/itslovesmusic/sets/top-50-punjabi-songs-2022-1")
213 | elif st.session_state["emotion"] == "Neutral":
214 | st_player("https://soundcloud.com/tania-tania-658084779/sets/best-punjabi-hits-songs-2023")
215 | else:
216 | st_player("https://soundcloud.com/gvdotbnerxpu/sets/bad-punjabi-remix")
217 |
218 | telugu = st.button("Telugu")
219 | if telugu:
220 | if st.session_state["emotion"] == "Happy":
221 | st_player("https://soundcloud.com/sumit-indoria/sets/telugu-party-time")
222 | elif st.session_state["emotion"] == "Sad":
223 | st_player("https://soundcloud.com/user-738522704/sets/sad-telugu-songs")
224 | elif st.session_state["emotion"] == "Angry":
225 | st_player("https://soundcloud.com/user-692822299/sets/telugu-workout-remix")
226 | elif st.session_state["emotion"] == "Fear":
227 | st.write("No such playlist found , hence default playlist is being played.")
228 | st_player("https://soundcloud.com/vinod-kumar-761560211/sets/telugu-songs-regular-update")
229 | elif st.session_state["emotion"] == "Surprise":
230 | st_player("https://soundcloud.com/vinod-kumar-761560211/sets/telugu-songs-regular-update")
231 | elif st.session_state["emotion"] == "Neutral":
232 | st_player("https://soundcloud.com/vinod-kumar-761560211/sets/telugu-songs-regular-update")
233 | else:
234 | st.write("No such playlist found , hence default playlist is being played.")
235 | st_player("https://soundcloud.com/vinod-kumar-761560211/sets/telugu-songs-regular-update")
236 |
--------------------------------------------------------------------------------
/pages/5_📊_Analyzer .py:
--------------------------------------------------------------------------------
1 | #import os
2 | import streamlit as st
3 | import pandas as pd
4 |
5 | import spotipy
6 | from spotipy.oauth2 import SpotifyClientCredentials
7 |
8 | import polarplot
9 | import songrecommendations
10 |
11 | #from dotenv import load_dotenv
12 | #load_dotenv()
13 |
14 | SPOTIPY_CLIENT_ID = 'fcbb0f29936b4f8ba90c4a606e516a67'
15 | SPOTIPY_CLIENT_SECRET = '9b66b9a7c4ec4f2ba5fe21b6575da778'
16 |
17 | auth_manager = SpotifyClientCredentials(client_id=SPOTIPY_CLIENT_ID, client_secret=SPOTIPY_CLIENT_SECRET)
18 | sp = spotipy.Spotify(auth_manager=auth_manager)
19 |
20 | from streamlit_extras.app_logo import add_logo
21 | from streamlit_player import st_player
22 |
23 | page_bg_img = """
24 |
117 | """
118 | add_logo("https://github.com/NebulaTris/vibescape/blob/main/logo.png?raw=true")
119 |
120 | st.markdown(page_bg_img, unsafe_allow_html=True)
121 |
122 | st.header('Analyzer & Recommender 📊')
123 |
124 |
125 | search_choices = ['Song/Track', 'Artist']
126 | search_selected = st.sidebar.selectbox("Your search choice please: ", search_choices)
127 |
128 | search_keyword = st.text_input(search_selected + " (Keyword Search)")
129 | button_clicked = st.button("Search")
130 |
131 |
132 | search_results = []
133 | tracks = []
134 | artists = []
135 | albums = []
136 | if search_keyword is not None and len(str(search_keyword)) > 0:
137 | if search_selected == 'Song/Track':
138 | st.write("Start song/track search")
139 | tracks = sp.search(q='track:'+ search_keyword,type='track', limit=20)
140 | tracks_list = tracks['tracks']['items']
141 | if len(tracks_list) > 0:
142 | for track in tracks_list:
143 | #st.write(track['name'] + " - By - " + track['artists'][0]['name'])
144 | search_results.append(track['name'] + " - By - " + track['artists'][0]['name'])
145 |
146 | elif search_selected == 'Artist':
147 | st.write("Start artist search")
148 | artists = sp.search(q='artist:'+ search_keyword,type='artist', limit=20)
149 | artists_list = artists['artists']['items']
150 | if len(artists_list) > 0:
151 | for artist in artists_list:
152 | # st.write(artist['name'])
153 | search_results.append(artist['name'])
154 |
155 | selected_artist = None
156 | selected_track = None
157 | if search_selected == 'Song/Track':
158 | selected_track = st.selectbox("Select your song/track: ", search_results)
159 | elif search_selected == 'Artist':
160 | selected_artist = st.selectbox("Select your artist: ", search_results)
161 |
162 |
163 | if selected_track is not None and len(tracks) > 0:
164 | tracks_list = tracks['tracks']['items']
165 | track_id = None
166 | if len(tracks_list) > 0:
167 | for track in tracks_list:
168 | str_temp = track['name'] + " - By - " + track['artists'][0]['name']
169 | if str_temp == selected_track:
170 | track_id = track['id']
171 | track_album = track['album']['name']
172 | img_album = track['album']['images'][1]['url']
173 | #songrecommendations.save_album_image(img_album, track_id)
174 | selected_track_choice = None
175 | if track_id is not None:
176 | #image = songrecommendations.get_album_mage(track_id)
177 | # st.image(image)
178 | track_choices = ['Song Features', 'Similar Songs Recommendation']
179 | selected_track_choice = st.sidebar.selectbox('Please select track choice: ', track_choices)
180 | if selected_track_choice == 'Song Features':
181 | track_features = sp.audio_features(track_id)
182 | df = pd.DataFrame(track_features, index=[0])
183 | df_features = df.loc[: ,['acousticness', 'danceability', 'energy', 'instrumentalness', 'liveness', 'speechiness', 'valence']]
184 | st.dataframe(df_features)
185 | polarplot.feature_plot(df_features)
186 | elif selected_track_choice == 'Similar Songs Recommendation':
187 | token = songrecommendations.get_token(SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET)
188 | similar_songs_json = songrecommendations.get_track_recommendations(track_id, token)
189 | recommendation_list = similar_songs_json['tracks']
190 | recommendation_list_df = pd.DataFrame(recommendation_list)
191 | # st.dataframe(recommendation_list_df)
192 | recommendation_df = recommendation_list_df[['name', 'explicit', 'duration_ms', 'popularity']]
193 | st.dataframe(recommendation_df)
194 | # st.write("Recommendations....")
195 | songrecommendations.song_recommendation_vis(recommendation_df)
196 |
197 | else:
198 | st.write("Please select a track from the list")
199 |
200 | st.sidebar.text("Developed by Shambhavi")
201 | # elif selected_album is not None and len(albums) > 0:
202 | # albums_list = albums['albums']['items']
203 | # album_id = None
204 | # album_uri = None
205 | # album_name = None
206 | # if len(albums_list) > 0:
207 | # for album in albums_list:
208 | # str_temp = album['name'] + " - By - " + album['artists'][0]['name']
209 | # if selected_album == str_temp:
210 | # album_id = album['id']
211 | # album_uri = album['uri']
212 | # album_name = album['name']
213 | # if album_id is not None and album_uri is not None:
214 | # st.write("Collecting all the tracks for the album :" + album_name)
215 | # album_tracks = sp.album_tracks(album_id)
216 | # df_album_tracks = pd.DataFrame(album_tracks['items'])
217 | # # st.dataframe(df_album_tracks)
218 | # df_tracks_min = df_album_tracks.loc[:,
219 | # ['id', 'name', 'duration_ms', 'explicit', 'preview_url']]
220 | # # st.dataframe(df_tracks_min)
221 | # for idx in df_tracks_min.index:
222 | # with st.container():
223 | # col1, col2, col3, col4 = st.columns((4,4,1,1))
224 | # col11, col12 = st.columns((8,2))
225 | # col1.write(df_tracks_min['id'][idx])
226 | # col2.write(df_tracks_min['name'][idx])
227 | # col3.write(df_tracks_min['duration_ms'][idx])
228 | # col4.write(df_tracks_min['explicit'][idx])
229 | # if df_tracks_min['preview_url'][idx] is not None:
230 | # col11.write(df_tracks_min['preview_url'][idx])
231 | # with col12:
232 | # st.audio(df_tracks_min['preview_url'][idx], format="audio/mp3")
233 |
234 |
235 | if selected_artist is not None and len(artists) > 0:
236 | artists_list = artists['artists']['items']
237 | artist_id = None
238 | artist_uri = None
239 | selected_artist_choice = None
240 | if len(artists_list) > 0:
241 | for artist in artists_list:
242 | if selected_artist == artist['name']:
243 | artist_id = artist['id']
244 | artist_uri = artist['uri']
245 |
246 | if artist_id is not None:
247 | artist_choice = ['Albums', 'Top Songs']
248 | selected_artist_choice = st.sidebar.selectbox('Select artist choice', artist_choice)
249 |
250 | if selected_artist_choice is not None:
251 | if selected_artist_choice == 'Albums':
252 | artist_uri = 'spotify:artist:' + artist_id
253 | album_result = sp.artist_albums(artist_uri, album_type='album')
254 | all_albums = album_result['items']
255 | col1, col2, col3 = st.columns((6,4,2))
256 | for album in all_albums:
257 | col1.write(album['name'])
258 | col2.write(album['release_date'])
259 | col3.write(album['total_tracks'])
260 | elif selected_artist_choice == 'Top Songs':
261 | artist_uri = 'spotify:artist:' + artist_id
262 | top_songs_result = sp.artist_top_tracks(artist_uri)
263 | for track in top_songs_result['tracks']:
264 | with st.container():
265 | col1, col2, col3, col4 = st.columns((4,4,2,2))
266 | col11, col12 = st.columns((10,2))
267 | col21, col22 = st.columns((11,1))
268 | col31, col32 = st.columns((11,1))
269 | col1.write(track['id'])
270 | col2.write(track['name'])
271 | if track['preview_url'] is not None:
272 | col11.write(track['preview_url'])
273 | with col12:
274 | st.audio(track['preview_url'], format="audio/mp3")
275 | with col3:
276 | def feature_requested():
277 | track_features = sp.audio_features(track['id'])
278 | df = pd.DataFrame(track_features, index=[0])
279 | df_features = df.loc[: ,['acousticness', 'danceability', 'energy', 'instrumentalness', 'liveness', 'speechiness', 'valence']]
280 | with col21:
281 | st.dataframe(df_features)
282 | with col31:
283 | polarplot.feature_plot(df_features)
284 |
285 | feature_button_state = st.button('Track Audio Features', key=track['id'], on_click=feature_requested)
286 | with col4:
287 | def similar_songs_requested():
288 | token = songrecommendations.get_token(SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET)
289 | similar_songs_json = songrecommendations.get_track_recommendations(track['id'], token)
290 | recommendation_list = similar_songs_json['tracks']
291 | recommendation_list_df = pd.DataFrame(recommendation_list)
292 | recommendation_df = recommendation_list_df[['name', 'explicit', 'duration_ms', 'popularity']]
293 | with col21:
294 | st.dataframe(recommendation_df)
295 | with col31:
296 | songrecommendations.song_recommendation_vis(recommendation_df)
297 |
298 | # similar_songs_state = st.button('Similar Songs', key=track['id'], on_click=similar_songs_requested)
299 | st.write('----')
300 |
--------------------------------------------------------------------------------
/pages/3_💚_Spotify.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 | import webbrowser
3 | from streamlit_extras.app_logo import add_logo
4 | import streamlit.components.v1 as components
5 |
6 | page_bg_img = """
7 |
97 | """
98 | add_logo("https://github.com/NebulaTris/vibescape/blob/main/logo.png?raw=true")
99 |
100 | st.markdown(page_bg_img, unsafe_allow_html=True)
101 | st.title("Vibescape-Spotify 💚")
102 | st.markdown(''':green[**Note : It is recommended that you scan your face , for Vibescape to groove with you!**]''')
103 | st.sidebar.success("Spotify has been selected as your music player.")
104 | st.sidebar.text("Developed by Shambhavi")
105 |
106 | if "run" not in st.session_state:
107 | st.write("**Looks like you have skipped the face scan on the homepage and came here, just for music, just choose your vibe manually for Vibescape to groove with you!**")
108 | option = st.selectbox(
109 | 'What''s your vibe today?',
110 | ('Happy', 'Sad', 'Angry','Fear','Surprise','Neutral'))
111 | if option == "Happy":
112 | st.session_state["emotion"] = "Happy"
113 | elif option == "Sad":
114 | st.session_state["emotion"] = "Sad"
115 | elif option == "Angry":
116 | st.session_state["emotion"] = "Angry"
117 | elif option == "Fear":
118 | st.session_state["emotion"] = "Fear"
119 | elif option == "Surprise":
120 | st.session_state["emotion"] = "Surprise"
121 | else:
122 | st.session_state["emotion"] = "Neutral"
123 | else:
124 | st.write("You current emotion is: " , st.session_state["emotion"])
125 |
126 | col1, col2 = st.columns(2)
127 |
128 | with col1:
129 | hindi = st.button("Hindi")
130 | if hindi:
131 | if st.session_state["emotion"] == "Happy":
132 | components.html(
133 | """
134 | """,height=600)
135 | elif st.session_state["emotion"] == "Sad":
136 | components.html(
137 | """
138 | """,height=600)
139 | elif st.session_state["emotion"] == "Angry":
140 | components.html(
141 | """
142 | """,height=600)
143 | elif st.session_state["emotion"] == "Fear":
144 | components.html(
145 | """
146 | """,height=600)
147 | elif st.session_state["emotion"] == "Surprise":
148 | components.html(
149 | """
150 | """,height=600)
151 | elif st.session_state["emotion"] == "Neutral":
152 | components.html(
153 | """
154 | """,height=600)
155 | else:
156 | components.html(
157 | """
158 | """,height=600)
159 |
160 | bengali = st.button("Bengali")
161 | if bengali:
162 | if st.session_state["emotion"] == "Happy":
163 | components.html(
164 | """
165 | """,height=600)
166 | elif st.session_state["emotion"] == "Sad":
167 | components.html(
168 | """
169 | """,height=600)
170 | elif st.session_state["emotion"] == "Angry":
171 | components.html(
172 | """
173 | """,height=600)
174 | elif st.session_state["emotion"] == "Fear":
175 | components.html(
176 | """
177 | """,height=600)
178 | elif st.session_state["emotion"] == "Surprise":
179 | components.html(
180 | """
181 | """,height=600)
182 | elif st.session_state["emotion"] == "Neutral":
183 | components.html(
184 | """
185 | """,height=600)
186 | else:
187 | components.html(
188 | """
189 | """,height=600)
190 |
191 | marathi = st.button("Marathi")
192 | if marathi:
193 | if st.session_state["emotion"] == "Happy":
194 | components.html(
195 | """
196 | """,height=600)
197 | elif st.session_state["emotion"] == "Sad":
198 | components.html(
199 | """
200 | """,height=600)
201 | elif st.session_state["emotion"] == "Angry":
202 | components.html(
203 | """
204 | """,height=600)
205 | elif st.session_state["emotion"] == "Fear":
206 | st.write("No playlist available for this emotion. Hence default playlist is being played.")
207 | components.html(
208 | """
209 | """,height=600)
210 | elif st.session_state["emotion"] == "Surprise":
211 | components.html(
212 | """
213 | """,height=600)
214 | elif st.session_state["emotion"] == "Neutral":
215 | components.html(
216 | """
217 | """,height=600)
218 | else:
219 | components.html(
220 | """
221 | """,height=600)
222 |
223 | with col2:
224 | english = st.button("English")
225 | if english:
226 | if st.session_state["emotion"] == "Happy":
227 | components.html(
228 | """
229 | """,height=600)
230 | elif st.session_state["emotion"] == "Sad":
231 | components.html(
232 | """
233 | """,height=600)
234 | elif st.session_state["emotion"] == "Angry":
235 | components.html(
236 | """
237 | """,height=600)
238 | elif st.session_state["emotion"] == "Fear":
239 | components.html(
240 | """
241 | """,height=600)
242 | elif st.session_state["emotion"] == "Surprise":
243 | components.html(
244 | """
245 | """,height=600)
246 | elif st.session_state["emotion"] == "Neutral":
247 | components.html(
248 | """
249 | """,height=600)
250 | else:
251 | components.html(
252 | """
253 | """,height=600)
254 |
255 | punjabi = st.button("Punjabi")
256 | if punjabi:
257 | if st.session_state["emotion"] == "Happy":
258 | components.html(
259 | """
260 | """,height=600)
261 | elif st.session_state["emotion"] == "Sad":
262 | components.html(
263 | """
264 | """,height=600)
265 | elif st.session_state["emotion"] == "Angry":
266 | components.html(
267 | """
268 | """,height=600)
269 | elif st.session_state["emotion"] == "Fear":
270 | st.write("No playlist available for this emotion. Hence default playlist is being played.")
271 | components.html(
272 | """
273 | """,height=600)
274 | elif st.session_state["emotion"] == "Surprise":
275 | components.html(
276 | """
277 | """,height=600)
278 | elif st.session_state["emotion"] == "Neutral":
279 | components.html(
280 | """
281 | """,height=600)
282 | else:
283 | components.html(
284 | """
285 | """,height=600)
286 |
287 | telugu = st.button("Telugu")
288 | if telugu:
289 | if st.session_state["emotion"] == "Happy":
290 | components.html(
291 | """
292 | """,height=600)
293 | elif st.session_state["emotion"] == "Sad":
294 | components.html(
295 | """
296 | """,height=600)
297 | elif st.session_state["emotion"] == "Angry":
298 | components.html(
299 | """
300 | """,height=600)
301 | elif st.session_state["emotion"] == "Fear":
302 | components.html(
303 | """
304 | """,height=600)
305 | elif st.session_state["emotion"] == "Surprise":
306 | components.html(
307 | """
308 | """,height=600)
309 | elif st.session_state["emotion"] == "Neutral":
310 | components.html(
311 | """
312 | """,height=600)
313 | else:
314 | components.html(
315 | """
316 | """,height=600)
317 |
--------------------------------------------------------------------------------