Spaces:
Runtime error
Runtime error
File size: 10,298 Bytes
1767f84 36321f6 1767f84 36321f6 1767f84 36321f6 1767f84 36321f6 1767f84 36321f6 1767f84 36321f6 1767f84 36321f6 1767f84 d0826bc 1767f84 d0826bc 1767f84 d0826bc 1767f84 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
from PIL import Image
from utils import *
from app_utils import *
debug = False
dir_path = os.path.dirname(os.path.realpath(__file__))
# os.environ['FLASK_APP'] = dir_path + 'app2.py'
# if debug: os.environ['FLASK_ENV'] = 'development'
#
#
# app = Flask(__name__)
# app.config['SECRET_KEY'] = os.urandom(64)
# app.config['SESSION_TYPE'] = 'filesystem'
# app.config['SESSION_FILE_DIR'] = './.flask_session/'
# Session(app)
st.set_page_config(
page_title="EmotionPlaylist",
page_icon="🎧",
)
st.title('Customize Emotional Playlists')
def setup_streamlite():
setup_credentials()
print('Here1')
image = Image.open(dir_path + '/image.png')
st.image(image)
st.markdown("This app let's you quickly build playlists in a customized way: ")
st.markdown("* **It's easy**: you won't have to add songs one by one,\n"
"* **You're in control**: you provide a source of candidate songs, select a list of genres and choose the mood for the playlist.")
st.subheader("Step 1: Connect to your Spotify app")
st.markdown("Log into your Spotify account to let the app create the custom playlist.")
print('Here2')
if 'login' not in st.session_state:
sp, user_id = new_get_client(session=st.session_state)
if sp != None:
print("USER", user_id)
legit_genres = sp.recommendation_genre_seeds()['genres']
st.session_state['login'] = (sp, user_id, legit_genres)
# if 'login' not in st.session_state:
# login = centered_button(st.button, 'Log in', n_columns=7)
# if login or debug:
# sp, user_id = get_client(session=st.session_state)
# user_id = sp.me()['id']
# legit_genres = sp.recommendation_genre_seeds()['genres']
# st.session_state['login'] = (sp, user_id, legit_genres)
if 'login' in st.session_state or debug:
print('Here8')
if not debug: sp, user_id, legit_genres = st.session_state['login']
st.success('You are logged in.')
st.subheader("Step 2: Select candidate songs")
st.markdown("This can be done in three ways: \n"
"1. Get songs from a list of artists\n"
"2. Get songs from a list of users (and their playlists)\n"
"3. Get songs from a list of playlists.\n"
"For this you'll need to collect the urls of artists, users and/or playlists by clicking on 'Share' and copying the urls."
"You need to provide at least one source of music.")
label_artist = "Add a list of artist urls, one per line (optional)"
artists_links = st.text_area(label_artist, value="")
users_playlists = "Add a list of users urls, one per line (optional)"
users_links = st.text_area(users_playlists, value="")
label_playlists = "Add a list of playlists urls, one per line (optional)"
playlist_links = st.text_area(label_playlists, value="https://open.spotify.com/playlist/1H7a4q8JZArMQiidRy6qon?si=529184bbe93c4f73")
button = centered_button(st.button, 'Extract music', n_columns=5)
if button or debug:
if playlist_links != "":
playlist_uris = extract_uris_from_links(playlist_links, url_type='playlist')
else:
raise ValueError('Please enter a list of playlists')
# Scanning playlists
st.spinner(text="Scanning music sources..")
data_tracks = get_all_tracks_from_playlists(sp, playlist_uris, verbose=True)
st.success(f'{len(data_tracks.keys())} tracks found!')
# Extract audio features
st.spinner(text="Extracting audio features..")
all_tracks_uris = np.array(list(data_tracks.keys()))
all_audio_features = [data_tracks[uri]['track']['audio_features'] for uri in all_tracks_uris]
all_tracks_audio_features = dict(zip(relevant_audio_features, [[audio_f[k] for audio_f in all_audio_features] for k in relevant_audio_features]))
genres = dict()
for index, uri in enumerate(all_tracks_uris):
track = data_tracks[uri]
track_genres = track['track']['genres']
for g in track_genres:
if g not in genres.keys():
genres[g] = [index]
else:
genres[g].append(index)
genres = aggregate_genres(genres, legit_genres)
genres_labels = sorted(genres.keys())
st.success(f'Audio features extracted!')
st.session_state['music_extracted'] = dict(all_tracks_uris=all_tracks_uris,
all_tracks_audio_features=all_tracks_audio_features,
genres=genres,
genres_labels=genres_labels)
if 'music_extracted' in st.session_state.keys():
all_tracks_uris = st.session_state['music_extracted']['all_tracks_uris']
all_tracks_audio_features = st.session_state['music_extracted']['all_tracks_audio_features']
genres = st.session_state['music_extracted']['genres']
genres_labels = st.session_state['music_extracted']['genres_labels']
st.subheader("Step 3: Customize it!")
st.markdown("##### Which genres?")
st.markdown("Check boxes to select genres, see how many tracks were selected below. Note: to check all, first uncheck all (bug).")
columns = st.columns(np.ones(5))
with columns[1]:
check_all = st.button('Check all')
with columns[3]:
uncheck_all = st.button('Uncheck all')
if 'checkboxes' not in st.session_state.keys():
st.session_state['checkboxes'] = [True] * len(genres_labels)
empty_checkboxes = wall_of_checkboxes(genres_labels, max_width=5)
if check_all:
st.session_state['checkboxes'] = [True] * len(genres_labels)
if uncheck_all:
st.session_state['checkboxes'] = [False] * len(genres_labels)
for i_emc, emc in enumerate(empty_checkboxes):
st.session_state['checkboxes'][i_emc] = emc.checkbox(genres_labels[i_emc], value=st.session_state['checkboxes'][i_emc])
# filter songs by genres
selected_labels = [genres_labels[i] for i in range(len(genres_labels)) if st.session_state['checkboxes'][i]]
genre_selected_indexes = []
for label in selected_labels:
genre_selected_indexes += genres[label]
genre_selected_indexes = np.array(sorted(set(genre_selected_indexes)))
if len(genre_selected_indexes) < 10:
st.warning('Please select more genres or add more music sources.')
else:
st.success(f'{len(genre_selected_indexes)} candidate tracks selected.')
st.markdown("##### What's the mood?")
valence = st.slider('Valence (0 negative, 100 positive)', min_value=0, max_value=100, value=100, step=1) / 100
energy = st.slider('Energy (0 low, 100 high)', min_value=0, max_value=100, value=100, step=1) / 100
danceability = st.slider('Danceability (0 low, 100 high)', min_value=0, max_value=100, value=100, step=1) / 100
target_mood = np.array([valence, energy, danceability]).reshape(1, 3)
candidate_moods = np.array([np.array(all_tracks_audio_features[feature])[genre_selected_indexes] for feature in ['valence', 'energy', 'danceability']]).T
distances = np.sqrt(((candidate_moods - target_mood) ** 2).sum(axis=1))
min_dist_indexes = np.argsort(distances)
n_candidates = distances.shape[0]
if n_candidates < 25:
st.warning('Please add more music sources or select more genres.')
else:
playlist_length = st.number_input(f'Pick a playlist length, given {n_candidates} candidates.', min_value=5,
value=min(10, n_candidates//5), max_value=n_candidates//5)
selected_tracks_indexes = genre_selected_indexes[min_dist_indexes[:playlist_length]]
selected_tracks_uris = all_tracks_uris[selected_tracks_indexes]
np.random.shuffle(selected_tracks_uris)
playlist_name = st.text_input('Playlist name', value='Mood Playlist')
if playlist_name == '':
st.warning('Please enter a playlist name.')
else:
generation_button = centered_button(st.button, 'Generate playlist', n_columns=5)
if generation_button:
description = f'Emotion Playlist for Valence: {valence}, Energy: {energy}, Danceability: {danceability}). ' \
f'Playlist generated by the EmotionPlaylist app: https://huggingface.co/spaces/ccolas/EmotionPlaylist.'
playlist_info = sp.user_playlist_create(user_id, playlist_name, public=True, collaborative=False, description=description)
playlist_uri = playlist_info['uri'].split(':')[-1]
sp.playlist_add_items(playlist_uri, selected_tracks_uris)
st.write(
f"""
<html>
<body>
<center>
<iframe style = "border-radius:12px" src="https://open.spotify.com/embed/playlist/{playlist_uri}" allowtransparency="true"
allow="encrypted-media" width="80%" height="580" frameborder="0"></iframe></center></body></html>
""", unsafe_allow_html=True)
st.success(f'The playlist has been generated, find it [here](https://open.spotify.com/playlist/{playlist_uri}).')
stop = 1
if __name__ == '__main__':
setup_streamlite() |