├── 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 | [![header](vibescape.gif)](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 | --------------------------------------------------------------------------------