import logging import os from pathlib import Path import requests import streamlit as st from app.examples import show_examples from demucs_runner import separator from lib.st_custom_components import st_audiorec from helpers import load_audio_segment, plot_audio from sidebar import text as text_side logging.basicConfig( format="%(asctime)s %(levelname)-8s %(message)s", level=logging.DEBUG, datefmt="%Y-%m-%d %H:%M:%S", ) max_duration = 10 # in seconds model = "htdemucs" extensions = ["mp3", "wav", "ogg", "flac"] # we will look for all those file types. two_stems = None # only separate one stems from the rest, for instance # Options for the output audio. mp3 = True mp3_rate = 320 float32 = False # output as float 32 wavs, unsused if 'mp3' is True. int24 = False # output as int24 wavs, unused if 'mp3' is True. # You cannot set both `float32 = True` and `int24 = True` !! out_path = Path("/tmp") in_path = Path("/tmp") def url_is_valid(url): if url.startswith("http") is False: st.error("URL should start with http or https.") return False elif url.split(".")[-1] not in extensions: st.error("Extension not supported.") return False try: r = requests.get(url) r.raise_for_status() return True except Exception: st.error("URL is not valid.") return False def run(): st.markdown("

🎶 Music Source Splitter

", unsafe_allow_html=True) st.markdown("
Hight Quality Audio Source Separation
", unsafe_allow_html=True) st.sidebar.markdown(text_side, unsafe_allow_html=True) st.markdown(""" """, unsafe_allow_html=True, ) filename = None choice = st.radio(label=" ", options=["🔗 From URL", "⬆️ Upload File", "🎤 Record Audio"], horizontal=True) if choice == "🔗 From URL": url = st.text_input("Paste the URL of the audio file", key="url", help="Supported formats: mp3, wav, ogg, flac.") if url != "": # check if the url is valid if url_is_valid(url): with st.spinner("Downloading audio..."): filename = url.split("/")[-1] os.system(f"wget -O {in_path / filename} {url}") elif choice == "⬆️ Upload File": uploaded_file = st.file_uploader("Choose a file", type=extensions, key="file", help="Supported formats: mp3, wav, ogg, flac.") if uploaded_file is not None: with open(in_path / uploaded_file.name, "wb") as f: f.write(uploaded_file.getbuffer()) filename = uploaded_file.name elif choice == "🎤 Record Audio": wav_audio_data = st_audiorec() if wav_audio_data is not None: if wav_audio_data != b'RIFF,\x00\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x02\x00\x80>\x00\x00\x00\xfa\x00\x00\x04\x00\x10\x00data\x00\x00\x00\x00': filename = "recording.wav" with open(in_path / filename, "wb") as f: f.write(wav_audio_data) if filename is not None: song = load_audio_segment(in_path / filename, filename.split(".")[-1]) n_secs = round(len(song) / 1000) audio_file = open(in_path / filename, "rb") audio_bytes = audio_file.read() start_time = st.slider("Choose the start time", min_value=0, max_value=n_secs, step=1, value=0, help=f"Maximum duration is {max_duration} seconds.") _ = st.audio(audio_bytes, start_time=start_time) end_time = min(start_time + max_duration, n_secs) song = song[start_time*1000:end_time*1000] tot_time = end_time - start_time st.info(f"Audio source will be processed from {start_time} to {end_time} seconds.", icon="⏱") execute = st.button("Split Music 🎶", type="primary") if execute: song.export(in_path / filename, format=filename.split(".")[-1]) with st.spinner(f"Splitting source audio, it will take almost {round(tot_time*3.6)} seconds..."): separator( tracks=[in_path / filename], out=out_path, model=model, device="cpu", shifts=1, overlap=0.5, stem=two_stems, int24=int24, float32=float32, clip_mode="rescale", mp3=mp3, mp3_bitrate=mp3_rate, jobs=os.cpu_count(), verbose=True, ) last_dir = ".".join(filename.split(".")[:-1]) for file in ["vocals.mp3", "drums.mp3", "bass.mp3", "other.mp3"]: file = out_path / Path(model) / last_dir / file st.markdown("
", unsafe_allow_html=True) label = file.name.split(".")[0].replace("_", " ").capitalize() # add emoji to label label = { "Drums": "🥁", "Bass": "🎸", "Other": "🎹", "Vocals": "🎤", }.get(label) + " " + label st.markdown("

" + label + "

", unsafe_allow_html=True) cols = st.columns(2) with cols[0]: auseg = load_audio_segment(file, "mp3") plot_audio(auseg) with cols[1]: audio_file = open(file, "rb") audio_bytes = audio_file.read() st.audio(audio_bytes) if __name__ == "__main__": run() st.markdown("

", unsafe_allow_html=True) with st.expander("Show examples", expanded=False): show_examples()