Spaces:
Sleeping
Sleeping
from pathlib import Path | |
import streamlit as st | |
from streamlit_player import st_player | |
from streamlit_searchbox import st_searchbox | |
from service.youtube import ( | |
get_youtube_url, | |
search_youtube, | |
download_audio_from_youtube, | |
) | |
from helpers import ( | |
get_random_song, | |
load_audio_segment, | |
streamlit_player, | |
local_audio, | |
) | |
from service.vocal_remover.runner import separate, load_model | |
from footer import footer | |
from header import header | |
from loguru import logger as log | |
out_path = Path("/tmp") | |
in_path = Path("/tmp") | |
sess = st.session_state | |
def show_karaoke(pathname): | |
cols = st.columns([1, 1, 3, 1]) | |
with cols[1]: | |
sess.delay = st.slider( | |
label="Adjust video start delay in seconds (higher values anticipate lyrics)", | |
key="delay_slider", | |
value=2, | |
min_value=0, | |
max_value=5, | |
help="Synchronize youtube player with karaoke audio by adding a delay to the youtube player.", | |
) | |
with cols[2]: | |
events = st_player( | |
local_audio(pathname), | |
**{ | |
"progress_interval": 1000, | |
"playing": False, | |
"muted": False, | |
"light": False, | |
"play_inline": True, | |
"playback_rate": 1, | |
"height": 40, | |
"config": { | |
"start": 0, | |
"forceAudio": True, | |
}, | |
"events": ["onProgress", "onPlay"], | |
}, | |
key="karaoke_player", | |
) | |
st.markdown( | |
"<center>⬆️ Click on the play button to start karaoke<center>", | |
unsafe_allow_html=True, | |
) | |
with st.columns([1, 4, 1])[1]: | |
if events.name == "onPlay": | |
st.session_state.player_restart = True | |
log.info(f"Play Karaoke - {sess.selected_value}") | |
elif events.name == "onProgress" and events.data["playedSeconds"] > 0: | |
if st.session_state.player_restart: | |
sess.tot_delay = sess.delay + events.data["playedSeconds"] | |
st.session_state.player_restart = False | |
st_player( | |
sess.url + f"&t={sess.tot_delay}s", | |
**{ | |
"progress_interval": 1000, | |
"playing": True, | |
"muted": True, | |
"light": False, | |
"play_inline": False, | |
"playback_rate": 1, | |
"height": 250, | |
"events": None, | |
}, | |
key="yt_muted_player", | |
) | |
def body(): | |
st.markdown("<center>Search for a song on YouTube<center>", unsafe_allow_html=True) | |
yt_cols = st.columns([1, 3, 2, 1]) | |
with yt_cols[1]: | |
selected_value = st_searchbox( | |
search_youtube, | |
label=None, | |
placeholder="Search by name...", | |
clear_on_submit=True, | |
key="yt_searchbox", | |
) | |
if selected_value is not None and selected_value in sess.video_options: | |
sess.random_song = None | |
if selected_value != sess.selected_value: # New song selected | |
sess.executed = False | |
sess.selected_value = selected_value | |
sess.url = get_youtube_url(selected_value) | |
with yt_cols[2]: | |
if st.button("🎲 Random song", use_container_width=True): | |
sess.last_dir, sess.url = get_random_song() | |
sess.selected_value = sess.last_dir | |
sess.random_song = True | |
sess.video_options = [] | |
sess.executed = False | |
if sess.url is not None: | |
player_cols = st.columns([2, 2, 1, 1], gap="medium") | |
with player_cols[1]: | |
player = st.empty() | |
streamlit_player( | |
player, | |
sess.url, | |
height=200, | |
is_active=False, | |
muted=False, | |
start=0, | |
key="yt_player", | |
events=["onProgress"], | |
) | |
# Separate vocals | |
cols_before_sep = st.columns([2, 4, 2]) | |
with cols_before_sep[1]: | |
execute_button = st.empty() | |
execute = execute_button.button( | |
"Confirm and remove vocals 🎤 🎶", | |
type="primary", | |
use_container_width=True, | |
) | |
if execute or sess.executed: | |
execute_button.empty() | |
player.empty() | |
if execute: | |
sess.executed = False | |
if sess.random_song is None: | |
if not sess.executed: | |
cols_spinners = st.columns([1, 2, 1]) | |
with cols_spinners[1]: | |
with st.spinner( | |
"Separating vocals from music, it could take a few minutes... Don't close this page!" | |
): | |
sess.filename = download_audio_from_youtube(sess.url, in_path) | |
if sess.filename is None: | |
st.stop() | |
sess.url = None | |
filename = sess.filename | |
song = load_audio_segment( | |
in_path / filename, filename.split(".")[-1] | |
) | |
song.export(in_path / filename, format=filename.split(".")[-1]) | |
model, device = load_model(pretrained_model="baseline.pth") | |
separate( | |
input=in_path / filename, | |
model=model, | |
device=device, | |
output_dir=out_path, | |
only_no_vocals=True, | |
) | |
selected_value = None | |
sess.last_dir = ".".join(sess.filename.split(".")[:-1]) | |
sess.executed = True | |
else: | |
sess.executed = True | |
if sess.executed: | |
show_karaoke(out_path / "vocal_remover" / sess.last_dir / "no_vocals.mp3") | |
if __name__ == "__main__": | |
header() | |
body() | |
footer() | |