kevinwang676 commited on
Commit
8f95a54
·
1 Parent(s): 74e658e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +209 -0
app.py ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import librosa
3
+ import soundfile
4
+ import gradio as gr
5
+ from scipy.io import wavfile
6
+ import subprocess
7
+ from pathlib import Path
8
+ import time
9
+ import random
10
+ from datetime import datetime
11
+ from scipy.io.wavfile import write
12
+ from pydub import AudioSegment
13
+ high_quality = True
14
+
15
+
16
+ def svc(audio_src, audio_ref, singing_check):
17
+ wav1, sr1 = librosa.load(audio_src, sr=24000)
18
+ soundfile.write("audio_source.wav", wav1, sr1)
19
+ wav2, sr2 = librosa.load(audio_ref, sr=24000)
20
+ soundfile.write("audio_reference.wav", wav2, sr2)
21
+ if singing_check == True:
22
+ os.system("python infer.py --src_wav_path audio_source.wav --ref_wav_path audio_reference.wav --out_path output.wav")
23
+
24
+ else:
25
+ os.system("python infer.py --src_wav_path audio_source.wav --ref_wav_path audio_reference.wav --out_path output.wav --speech_enroll")
26
+
27
+ return "output.wav"
28
+
29
+ def youtube_downloader(
30
+ video_identifier,
31
+ start_time,
32
+ end_time,
33
+ is_full_song,
34
+ output_filename="track.wav",
35
+ num_attempts=5,
36
+ url_base="",
37
+ quiet=False,
38
+ force=True,
39
+ ):
40
+ if is_full_song:
41
+ ydl_opts = {
42
+ 'noplaylist': True,
43
+ 'format': 'bestaudio/best',
44
+ 'postprocessors': [{
45
+ 'key': 'FFmpegExtractAudio',
46
+ 'preferredcodec': 'wav',
47
+ }],
48
+ "outtmpl": 'dl_audio/youtube_audio',
49
+ }
50
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
51
+ ydl.download([video_identifier])
52
+ audio_path = "dl_audio/youtube_audio.wav"
53
+ return audio_path
54
+
55
+ else:
56
+ output_path = Path(output_filename)
57
+ if output_path.exists():
58
+ if not force:
59
+ return output_path
60
+ else:
61
+ output_path.unlink()
62
+
63
+ quiet = "--quiet --no-warnings" if quiet else ""
64
+ command = f"""
65
+ yt-dlp {quiet} -x --audio-format wav -f bestaudio -o "{output_filename}" --download-sections "*{start_time}-{end_time}" "{url_base}{video_identifier}" # noqa: E501
66
+ """.strip()
67
+
68
+ attempts = 0
69
+ while True:
70
+ try:
71
+ _ = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
72
+ except subprocess.CalledProcessError:
73
+ attempts += 1
74
+ if attempts == num_attempts:
75
+ return None
76
+ else:
77
+ break
78
+
79
+ if output_path.exists():
80
+ return output_path
81
+ else:
82
+ return None
83
+
84
+ def audio_separated(audio_input, progress=gr.Progress()):
85
+ # start progress
86
+ progress(progress=0, desc="Starting...")
87
+ time.sleep(0.1)
88
+
89
+ # check file input
90
+ if audio_input is None:
91
+ # show progress
92
+ for i in progress.tqdm(range(100), desc="Please wait..."):
93
+ time.sleep(0.01)
94
+
95
+ return (None, None, 'Please input audio.')
96
+
97
+ # create filename
98
+ filename = str(random.randint(10000,99999))+datetime.now().strftime("%d%m%Y%H%M%S")
99
+
100
+ # progress
101
+ progress(progress=0.10, desc="Please wait...")
102
+
103
+ # make dir output
104
+ os.makedirs("output", exist_ok=True)
105
+
106
+ # progress
107
+ progress(progress=0.20, desc="Please wait...")
108
+
109
+ # write
110
+ if high_quality:
111
+ write(filename+".wav", audio_input[0], audio_input[1])
112
+ else:
113
+ write(filename+".mp3", audio_input[0], audio_input[1])
114
+
115
+ # progress
116
+ progress(progress=0.50, desc="Please wait...")
117
+
118
+ # demucs process
119
+ if high_quality:
120
+ command_demucs = "python3 -m demucs --two-stems=vocals -d cpu "+filename+".wav -o output"
121
+ else:
122
+ command_demucs = "python3 -m demucs --two-stems=vocals --mp3 --mp3-bitrate 128 -d cpu "+filename+".mp3 -o output"
123
+
124
+ os.system(command_demucs)
125
+
126
+ # progress
127
+ progress(progress=0.70, desc="Please wait...")
128
+
129
+ # remove file audio
130
+ if high_quality:
131
+ command_delete = "rm -v ./"+filename+".wav"
132
+ else:
133
+ command_delete = "rm -v ./"+filename+".mp3"
134
+
135
+ os.system(command_delete)
136
+
137
+ # progress
138
+ progress(progress=0.80, desc="Please wait...")
139
+
140
+ # progress
141
+ for i in progress.tqdm(range(80,100), desc="Please wait..."):
142
+ time.sleep(0.1)
143
+
144
+ if high_quality:
145
+ return "./output/htdemucs/"+filename+"/vocals.wav","./output/htdemucs/"+filename+"/no_vocals.wav","Successfully..."
146
+ else:
147
+ return "./output/htdemucs/"+filename+"/vocals.mp3","./output/htdemucs/"+filename+"/no_vocals.mp3","Successfully..."
148
+
149
+ # mix vocal and non-vocal
150
+ def mix(audio1, audio2):
151
+ sound1 = AudioSegment.from_file(audio1)
152
+ sound2 = AudioSegment.from_file(audio2)
153
+ length = len(sound1)
154
+ mixed = sound1[:length].overlay(sound2)
155
+
156
+ mixed.export("song.wav", format="wav")
157
+
158
+ return "song.wav"
159
+
160
+ app = gr.Blocks()
161
+
162
+ with app:
163
+ gr.Markdown("# <center>🥳💕🎶 NeuCo AI歌手,无需训练、一键翻唱</center>")
164
+ gr.Markdown("## <center>🌟 只需10秒音频,一键翻唱任意歌手的任意歌曲! </center>")
165
+ gr.Markdown("### <center>🌊 更多精彩应用,敬请关注[滔滔AI](http://www.talktalkai.com);滔滔AI,为爱滔滔!💕</center>")
166
+ with gr.Row():
167
+ with gr.Column():
168
+ ydl_url_input = gr.Textbox(label="音乐视频网址(可直接填写相应的BV号)", value = "https://www.bilibili.com/video/BV...")
169
+ with gr.Row():
170
+ start = gr.Number(value=0, label="起始时间 (秒)")
171
+ end = gr.Number(value=15, label="结束时间 (秒)")
172
+ check_full = gr.Checkbox(label="是否上传整首歌曲", info="若勾选则不需要填写起止时间", value=False)
173
+ ydl_url_submit = gr.Button("提取声音文件吧", variant="primary")
174
+ as_audio_submit = gr.Button("去除背景音吧", variant="primary")
175
+
176
+ with gr.Column():
177
+ ydl_audio_output = gr.Audio(label="歌曲原声")
178
+ as_audio_input = ydl_audio_output
179
+ as_audio_vocals = gr.Audio(label="歌曲人声部分", type="filepath")
180
+ as_audio_no_vocals = gr.Audio(label="歌曲伴奏部分", type="filepath", visible=False)
181
+ as_audio_message = gr.Textbox(label="Message", visible=False)
182
+
183
+ ydl_url_submit.click(fn=youtube_downloader, inputs=[ydl_url_input, start, end, check_full], outputs=[ydl_audio_output])
184
+ as_audio_submit.click(fn=audio_separated, inputs=[as_audio_input], outputs=[as_audio_vocals, as_audio_no_vocals, as_audio_message], show_progress=True, queue=True)
185
+
186
+ with gr.Row():
187
+ with gr.Column():
188
+ inp_src = as_audio_vocals
189
+ inp_ref = gr.Audio(label="请上传您喜欢的参考音频", type="filepath")
190
+ check_singing = gr.Checkbox(label="参考音频是否为歌曲", info="勾选:参考音频是歌曲;不勾选:参考音频是语音", value=True)
191
+ btn1 = gr.Button("一键歌声转换吧!", variant="primary")
192
+ btn2 = gr.Button("加入歌曲伴奏吧!", variant="primary")
193
+
194
+ with gr.Column():
195
+ out_svc = gr.Audio(label="为您生成的专属歌曲", type="filepath", interactive=False)
196
+ new_song = gr.Audio(label="AI歌手+伴奏", type="filepath")
197
+
198
+ btn1.click(svc, [inp_src, inp_ref, check_singing], out_svc)
199
+ btn2.click(fn=mix, inputs=[out_svc, as_audio_no_vocals], outputs=[new_song])
200
+
201
+ gr.Markdown("### <center>注意❗:请不要生成会对个人以及组织造成侵害的内容,此程序仅供科研、学习及个人娱乐使用。</center>")
202
+ gr.HTML('''
203
+ <div class="footer">
204
+ <p>🌊🏞️🎶 - 江水东流急,滔滔无尽声。 明·顾璘
205
+ </p>
206
+ </div>
207
+ ''')
208
+
209
+ app.queue().launch(show_error=True)