Reaper200 commited on
Commit
659fed0
·
verified ·
1 Parent(s): e568ad2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -77
app.py CHANGED
@@ -1,98 +1,101 @@
1
  import streamlit as st
2
  import requests
 
3
  import torchaudio
4
- from audiocraft.models import MusicGen
5
  from pydub import AudioSegment
6
- import os
7
- import time
8
 
9
- # Constants
10
- AUDIO_OUTPUT_PATH = "voice_output.mp3"
11
- COMBINED_OUTPUT_PATH = "combined_output.mp3"
12
- MUSICGEN_OUTPUT_PATH = "musicgen_output.wav"
13
- RESEMBLE_API_TOKEN = "your_resemble_api_token_here"
14
 
15
- # Streamlit UI
16
- st.set_page_config(page_title="AI Music Generator", layout="centered")
17
- st.title("AI Music Generator like Suno")
18
 
19
- # Step 1: User Lyrics Input
20
- st.subheader("Step 1: Enter Your Lyrics")
21
- lyrics = st.text_area("Lyrics (max 300 characters)", max_chars=300)
22
 
23
- # Step 2: Generate Voice with Resemble AI
24
- st.subheader("Step 2: Generate Voice")
25
- project_uuid = st.text_input("Enter your Resemble Project UUID", "96e7c9b4-voice")
26
- voice_clip_uuid = st.text_input("Enter your Voice Clip UUID (or leave blank to generate new)", "")
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- # Function to call Resemble API
29
- def generate_voice_with_resemble(text, project_uuid):
 
30
  headers = {
31
- "Authorization": f"Token {RESEMBLE_API_TOKEN}",
32
- "Accept": "application/json",
33
  "Content-Type": "application/json"
34
  }
35
- data = {
36
- "project_uuid": project_uuid,
37
- "title": "streamlit_clip",
38
- "body": text,
39
- "voice": "your_custom_voice_id_if_needed"
40
  }
41
- res = requests.post("https://app.resemble.ai/api/v2/clips", headers=headers, json=data)
42
- res_data = res.json()
43
- clip_id = res_data.get("item", {}).get("uuid")
44
 
45
- if not clip_id:
46
- st.error("Failed to create clip on Resemble.")
 
 
 
47
  return None
48
 
49
- # Polling for completion
50
- for _ in range(30):
51
- clip_res = requests.get(f"https://app.resemble.ai/api/v2/clips/{clip_id}", headers=headers)
52
- clip_info = clip_res.json()
53
- if clip_info.get("is_complete"):
54
- audio_url = clip_info.get("audio_src")
55
- audio_data = requests.get(audio_url).content
56
- with open(AUDIO_OUTPUT_PATH, "wb") as f:
57
- f.write(audio_data)
58
- return AUDIO_OUTPUT_PATH
59
- time.sleep(3)
60
- return None
61
 
62
- if st.button("Generate Voice") and lyrics:
63
- st.info("Requesting Resemble to generate voice...")
64
- path = generate_voice_with_resemble(lyrics, project_uuid)
65
- if path and os.path.exists(path):
66
- st.audio(path, format="audio/mp3")
67
  else:
68
- st.error("Voice generation failed.")
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
- # Step 3: Generate Instrumental
71
- st.subheader("Step 3: Generate Instrumental")
72
- prompt = st.text_input("Describe the music (e.g. energetic trap beat)", "emotional trap beat")
 
 
 
 
 
73
 
74
- if st.button("Generate Music"):
75
- with st.spinner("Generating music..."):
76
- model = MusicGen.get_pretrained("facebook/musicgen-small")
77
- model.set_generation_params(duration=5)
78
- output = model.generate([prompt])
79
- torchaudio.save(MUSICGEN_OUTPUT_PATH, output[0].cpu(), 32000)
80
- st.audio(MUSICGEN_OUTPUT_PATH, format="audio/wav")
81
- st.success("Instrumental generated!")
82
 
83
- # Step 4: Combine
84
- st.subheader("Step 4: Combine Voice and Beat")
85
- if os.path.exists(MUSICGEN_OUTPUT_PATH) and os.path.exists(AUDIO_OUTPUT_PATH):
86
- try:
87
- beat = AudioSegment.from_wav(MUSICGEN_OUTPUT_PATH)
88
- voice = AudioSegment.from_mp3(AUDIO_OUTPUT_PATH)
89
- voice = voice - 4
90
- beat = beat - 2
91
- combined = beat.overlay(voice)
92
- combined.export(COMBINED_OUTPUT_PATH, format="mp3")
93
- st.audio(COMBINED_OUTPUT_PATH, format="audio/mp3")
94
- st.success("Combined track ready!")
95
- except Exception as e:
96
- st.error(f"Error combining files: {e}")
97
- else:
98
- st.info("Generate both voice and music to combine.")
 
1
  import streamlit as st
2
  import requests
3
+ import os
4
  import torchaudio
 
5
  from pydub import AudioSegment
6
+ from audiocraft.models import MusicGen
7
+ from tempfile import NamedTemporaryFile
8
 
9
+ # CONFIGURATION
10
+ RESEMBLE_API_KEY = os.getenv("RESEMBLE_API_KEY", "your_resemble_api_key")
11
+ PROJECT_UUID = "96e7c9b4-voice"
 
 
12
 
13
+ st.set_page_config(page_title="Suno-Like Music App", layout="centered")
14
+ st.title("Suno-Like AI Music Generator")
 
15
 
16
+ # Lyrics Input
17
+ st.subheader("Step 1: Enter Lyrics")
18
+ lyrics = st.text_area("Write your lyrics here:", "We go hard, never stop, always chasing dreams")
19
 
20
+ # Prompt Input
21
+ st.subheader("Step 2: Describe Your Beat")
22
+ prompt = st.text_input("Beat style (e.g. dark trap, chill pop):", "dark emotional trap beat with heavy bass")
23
+
24
+ # Generate Instrumental
25
+ music_path = None
26
+ if st.button("Generate Music"):
27
+ with st.spinner("Generating instrumental..."):
28
+ model = MusicGen.get_pretrained("facebook/musicgen-small")
29
+ model.set_generation_params(duration=10)
30
+ output = model.generate([prompt])
31
+ music_path = "output_music.wav"
32
+ torchaudio.save(music_path, output[0].cpu(), 32000)
33
+ st.audio(music_path, format="audio/wav")
34
+ st.success("Instrumental ready!")
35
 
36
+ # Generate Voice with Resemble AI
37
+ def generate_voice_with_resemble(lyrics, project_uuid):
38
+ url = f"https://app.resemble.ai/api/v2/projects/{project_uuid}/clips"
39
  headers = {
40
+ "Authorization": f"Token {RESEMBLE_API_KEY}",
 
41
  "Content-Type": "application/json"
42
  }
43
+
44
+ payload = {
45
+ "title": "AI Generated Clip",
46
+ "body": lyrics,
47
+ "is_active": True
48
  }
 
 
 
49
 
50
+ response = requests.post(url, headers=headers, json=payload)
51
+
52
+ if response.status_code != 200:
53
+ st.error(f"Resemble API Error: {response.status_code}")
54
+ st.text(response.text)
55
  return None
56
 
57
+ res_data = response.json()
58
+ clip_url = res_data.get("item", {}).get("audio_src")
59
+ return clip_url
 
 
 
 
 
 
 
 
 
60
 
61
+ voice_path = None
62
+ if st.button("Generate Voice with Resemble"):
63
+ if not lyrics:
64
+ st.warning("Please enter lyrics first.")
 
65
  else:
66
+ with st.spinner("Generating voice..."):
67
+ audio_url = generate_voice_with_resemble(lyrics, PROJECT_UUID)
68
+ if audio_url:
69
+ response = requests.get(audio_url)
70
+ if response.status_code == 200:
71
+ with NamedTemporaryFile(delete=False, suffix=".mp3") as f:
72
+ f.write(response.content)
73
+ voice_path = f.name
74
+ st.audio(voice_path, format="audio/mp3")
75
+ st.success("Voice generation complete!")
76
+ else:
77
+ st.error("Failed to download audio from Resemble.")
78
+ else:
79
+ st.error("Voice generation failed.")
80
 
81
+ # Combine Voice and Instrumental
82
+ if st.button("Combine Voice and Beat"):
83
+ if not music_path or not voice_path:
84
+ st.warning("Generate both voice and music before combining.")
85
+ else:
86
+ try:
87
+ beat = AudioSegment.from_wav(music_path)
88
+ voice = AudioSegment.from_mp3(voice_path)
89
 
90
+ voice = voice - 2
91
+ beat = beat - 4
92
+
93
+ combined = beat.overlay(voice)
94
+ combined_path = "combined_output.mp3"
95
+ combined.export(combined_path, format="mp3")
 
 
96
 
97
+ st.audio(combined_path, format="audio/mp3")
98
+ st.success("Final output ready!")
99
+ except Exception as e:
100
+ st.error(f"Error while c
101
+ ombining: {e}")