1lint commited on
Commit
8075337
1 Parent(s): aff7142

minor updates

Browse files
Files changed (3) hide show
  1. app.py +65 -35
  2. header.md +1 -2
  3. theme.py +3 -18
app.py CHANGED
@@ -1,5 +1,5 @@
1
  from gradio_client import Client
2
- import yt_dlp # pip install yt-dlp
3
 
4
  import subprocess
5
 
@@ -15,20 +15,44 @@ VIDEO_DIRECTORY = "videos"
15
 
16
  client = Client("abidlabs/music-separation")
17
 
 
18
  def acapellify(audio_path):
19
  result = client.predict(audio_path, api_name="/predict")
20
  return result[0]
21
 
 
22
  # based on https://github.com/gradio-app/gradio/blob/bebfb72b353a4280155cf7070441fc476ac10172/guides/06_client-libraries/fastapi-app-with-the-gradio-client.md
23
  def process_video(video_path):
24
  old_audio = os.path.basename(video_path).split(".")[0] + ".m4a"
25
- subprocess.run(['ffmpeg', '-y', '-i', video_path, '-vn', '-acodec', 'copy', old_audio])
26
-
 
 
27
  new_audio = acapellify(old_audio)
28
-
29
- new_video = f"acap_{Path(video_path).name}"
30
  new_video_path = f"{VIDEO_DIRECTORY}/{new_video}"
31
- subprocess.call(['ffmpeg', '-y', '-i', video_path, '-i', new_audio, '-map', '0:v', '-map', '1:a', '-c:v', 'copy', '-c:a', 'aac', '-strict', 'experimental', new_video_path])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  # remove old audio and video
34
  os.remove(old_audio)
@@ -39,49 +63,48 @@ def process_video(video_path):
39
 
40
  return new_video_path, new_audio_path
41
 
42
- # filename default value will return name of video on youtube
43
- def download_yt_url(url: str, filename: str = "%(title)s", format = 'mp4'):
44
 
45
- output_path = f"{VIDEO_DIRECTORY}/{filename}.{format}"
 
 
46
 
47
  # restrict video length so one user doesn't take up all our bandwidth
48
  def video_filter(info):
49
- MAX_DURATION = 10*60
50
- duration = info.get('duration')
51
  if duration and duration > MAX_DURATION:
52
- raise Exception(f'The video is too long at {duration}s, choose a video less than {MAX_DURATION}s')
 
 
53
 
54
  ydl_opts = {
55
- 'match_filter': video_filter,
56
- 'format': f'{format}/bestaudio',
57
- 'outtmpl': output_path,
58
  }
59
 
60
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
61
  error_code = ydl.download([url])
62
- #info = ydl.extract_info(url, extra_info={"output_path": output_path})
63
 
64
  if error_code:
65
- raise Exception(f"Failed to download video, error code: {error_code}")
66
-
67
  return output_path
68
 
69
 
70
  def wrap_html(filename):
71
-
72
  yt_url = f"https://www.youtube.com/watch?v={filename}"
73
 
74
  return f"""<h1><center>Original Video</center></h1>
75
  <center><a href='{yt_url}'>{yt_url}</a></center>
76
  <br>
77
- <center><iframe width="560" height="315" src="https://www.youtube.com/embed/{filename}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></center>
78
  """
79
 
80
-
81
 
82
  # ideally yt_url should be validated
83
  def acapellify_url(yt_url, gr_request: gr.Request):
84
-
85
  # example filename: https://www.youtube.com/watch?v=TasKo5HHWb4 -> TasKo5HHWb4
86
  filename = yt_url.split("=", 1)[-1].split("=", 1)[0]
87
 
@@ -91,18 +114,19 @@ def acapellify_url(yt_url, gr_request: gr.Request):
91
  return new_video_path, new_audio_path, wrap_html(filename)
92
 
93
 
94
-
95
-
96
-
97
  def load_mystery_video(gr_request: gr.Request):
98
-
99
  video_paths = list(Path(VIDEO_DIRECTORY).glob("*.mp4"))
 
100
 
101
- selected_video = video_paths[random.randrange(len(video_paths))]
 
 
 
102
 
103
- filename = selected_video.name.replace("acap_", "").split(".", 1)[0]
 
 
104
  selected_audio = Path(VIDEO_DIRECTORY) / f"{filename}.m4a"
105
-
106
 
107
  selected_video = str(selected_video)
108
  selected_audio = str(selected_audio)
@@ -113,15 +137,13 @@ def load_mystery_video(gr_request: gr.Request):
113
  with open("header.md", "r") as markdown_file:
114
  markdown_text = markdown_file.read()
115
 
116
- with gr.Blocks(theme=theme) as demo:
117
-
118
  with gr.Row():
119
  header = gr.Markdown(markdown_text)
120
  with gr.Row().style(equal_height=True):
121
-
122
  with gr.Column(scale=0.4, variant="panel"):
123
  input_url = gr.Textbox(label="Youtube URL")
124
-
125
  process_video_btn = gr.Button("Acapellify", variant="primary")
126
  mystery_btn = gr.Button("Mysterious Video")
127
 
@@ -131,8 +153,16 @@ with gr.Blocks(theme=theme) as demo:
131
  output_video = gr.Video(label="Acapellified Video")
132
  output_audio = gr.Audio(label="Acapellified Audio")
133
 
134
- process_video_btn.click(fn=acapellify_url, inputs=[input_url], outputs=[output_video, output_audio, static_path_display])
135
- mystery_btn.click(fn=load_mystery_video, inputs=[], outputs=[output_video, output_audio, static_path_display])
 
 
 
 
 
 
 
 
136
 
137
  if __name__ == "__main__":
138
  os.makedirs(VIDEO_DIRECTORY, exist_ok=True)
 
1
  from gradio_client import Client
2
+ import yt_dlp # pip install yt-dlp
3
 
4
  import subprocess
5
 
 
15
 
16
  client = Client("abidlabs/music-separation")
17
 
18
+
19
  def acapellify(audio_path):
20
  result = client.predict(audio_path, api_name="/predict")
21
  return result[0]
22
 
23
+
24
  # based on https://github.com/gradio-app/gradio/blob/bebfb72b353a4280155cf7070441fc476ac10172/guides/06_client-libraries/fastapi-app-with-the-gradio-client.md
25
  def process_video(video_path):
26
  old_audio = os.path.basename(video_path).split(".")[0] + ".m4a"
27
+ subprocess.run(
28
+ ["ffmpeg", "-y", "-i", video_path, "-vn", "-acodec", "copy", old_audio]
29
+ )
30
+
31
  new_audio = acapellify(old_audio)
32
+
33
+ new_video = f"{Path(video_path).name}"
34
  new_video_path = f"{VIDEO_DIRECTORY}/{new_video}"
35
+ subprocess.call(
36
+ [
37
+ "ffmpeg",
38
+ "-y",
39
+ "-i",
40
+ video_path,
41
+ "-i",
42
+ new_audio,
43
+ "-map",
44
+ "0:v",
45
+ "-map",
46
+ "1:a",
47
+ "-c:v",
48
+ "copy",
49
+ "-c:a",
50
+ "aac",
51
+ "-strict",
52
+ "experimental",
53
+ new_video_path,
54
+ ]
55
+ )
56
 
57
  # remove old audio and video
58
  os.remove(old_audio)
 
63
 
64
  return new_video_path, new_audio_path
65
 
 
 
66
 
67
+ # filename default value will return name of video on youtube
68
+ def download_yt_url(url: str, filename: str = "%(title)s", format="mp4"):
69
+ output_path = f"{filename}.{format}"
70
 
71
  # restrict video length so one user doesn't take up all our bandwidth
72
  def video_filter(info):
73
+ MAX_DURATION = 10 * 60
74
+ duration = info.get("duration")
75
  if duration and duration > MAX_DURATION:
76
+ raise gr.Error(
77
+ f"The video is too long at {duration}s, choose a video less than {MAX_DURATION}s"
78
+ )
79
 
80
  ydl_opts = {
81
+ "match_filter": video_filter,
82
+ "format": f"{format}/bestaudio",
83
+ "outtmpl": output_path,
84
  }
85
 
86
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
87
  error_code = ydl.download([url])
88
+ # info = ydl.extract_info(url, extra_info={"output_path": output_path})
89
 
90
  if error_code:
91
+ raise gr.Error(f"Failed to download video, error code: {error_code}")
92
+
93
  return output_path
94
 
95
 
96
  def wrap_html(filename):
 
97
  yt_url = f"https://www.youtube.com/watch?v={filename}"
98
 
99
  return f"""<h1><center>Original Video</center></h1>
100
  <center><a href='{yt_url}'>{yt_url}</a></center>
101
  <br>
102
+ <center><iframe width="100%" height="315" src="https://www.youtube.com/embed/{filename}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></center>
103
  """
104
 
 
105
 
106
  # ideally yt_url should be validated
107
  def acapellify_url(yt_url, gr_request: gr.Request):
 
108
  # example filename: https://www.youtube.com/watch?v=TasKo5HHWb4 -> TasKo5HHWb4
109
  filename = yt_url.split("=", 1)[-1].split("=", 1)[0]
110
 
 
114
  return new_video_path, new_audio_path, wrap_html(filename)
115
 
116
 
 
 
 
117
  def load_mystery_video(gr_request: gr.Request):
 
118
  video_paths = list(Path(VIDEO_DIRECTORY).glob("*.mp4"))
119
+ n_videos = len(video_paths)
120
 
121
+ if not n_videos:
122
+ raise gr.Error(
123
+ "No videos archived yet. Enter a Youtube URL to add the first video!"
124
+ )
125
 
126
+ selected_video = video_paths[random.randrange(n_videos)]
127
+
128
+ filename = selected_video.name.split(".", 1)[0]
129
  selected_audio = Path(VIDEO_DIRECTORY) / f"{filename}.m4a"
 
130
 
131
  selected_video = str(selected_video)
132
  selected_audio = str(selected_audio)
 
137
  with open("header.md", "r") as markdown_file:
138
  markdown_text = markdown_file.read()
139
 
140
+ with gr.Blocks(theme=theme, css="footer {visibility: hidden}") as demo:
 
141
  with gr.Row():
142
  header = gr.Markdown(markdown_text)
143
  with gr.Row().style(equal_height=True):
 
144
  with gr.Column(scale=0.4, variant="panel"):
145
  input_url = gr.Textbox(label="Youtube URL")
146
+
147
  process_video_btn = gr.Button("Acapellify", variant="primary")
148
  mystery_btn = gr.Button("Mysterious Video")
149
 
 
153
  output_video = gr.Video(label="Acapellified Video")
154
  output_audio = gr.Audio(label="Acapellified Audio")
155
 
156
+ process_video_btn.click(
157
+ fn=acapellify_url,
158
+ inputs=[input_url],
159
+ outputs=[output_video, output_audio, static_path_display],
160
+ )
161
+ mystery_btn.click(
162
+ fn=load_mystery_video,
163
+ inputs=[],
164
+ outputs=[output_video, output_audio, static_path_display],
165
+ )
166
 
167
  if __name__ == "__main__":
168
  os.makedirs(VIDEO_DIRECTORY, exist_ok=True)
header.md CHANGED
@@ -1,3 +1,2 @@
1
  # <p style="text-align: center;">Acapellify: Extract vocals from Youtube Video URL</p>
2
- ### <p style="text-align: center;">Based on https://gradio.app/fastapi-app-with-the-gradio-client/</p>
3
- ### <p style="text-align: center;">Hosted on HF Spaces, backend uses gradio client linked to abidlabs/music-separation</p>
 
1
  # <p style="text-align: center;">Acapellify: Extract vocals from Youtube Video URL</p>
2
+ ### <p style="text-align: center;">Based on https://gradio.app/fastapi-app-with-the-gradio-client/, Hosted on HF Spaces</p>
 
theme.py CHANGED
@@ -1,8 +1,5 @@
1
-
2
  import gradio as gr
3
- from gradio.themes.utils import colors, fonts, sizes
4
-
5
- from gradio.themes import Soft, Base
6
 
7
 
8
  yfu_red = colors.Color(
@@ -23,11 +20,11 @@ yfu_red = colors.Color(
23
  white = colors.Color(
24
  name="white",
25
  c50="#ff2c65",
26
- c100="#ff2c65", # text color
27
  c200="#ff2c65",
28
  c300="#ff2c65",
29
  c400="#ff2c65",
30
- c500="#ff2c65", # secondary text color
31
  c600="#ffffff",
32
  c700="#ffffff",
33
  c800="#ffffff",
@@ -42,32 +39,25 @@ theme = gr.themes.Soft(
42
  ).set(
43
  body_background_fill="white",
44
  panel_background_fill="white",
45
-
46
  background_fill_primary="white",
47
  background_fill_primary_dark="white",
48
-
49
  panel_background_fill_dark="white",
50
  panel_border_color="*primary_50",
51
  panel_border_color_dark="*primary_50",
52
-
53
  body_text_color="*primary_50",
54
  body_text_color_dark="*primary_50",
55
  body_text_color_subdued="*primary_50",
56
  body_text_color_subdued_dark="*primary_50",
57
-
58
  table_even_background_fill="white",
59
  table_even_background_fill_dark="white",
60
  table_odd_background_fill="*primary_100",
61
  table_odd_background_fill_dark="*primary_100",
62
  table_row_focus="*primary_200",
63
  table_row_focus_dark="*primary_200",
64
-
65
  input_background_fill_focus="*primary_200",
66
  input_background_fill_focus_dark="*primary_200",
67
-
68
  checkbox_background_color_focus="*primary_200",
69
  checkbox_background_color_focus_dark="*primary_200",
70
-
71
  border_color_primary_dark="*primary_50",
72
  checkbox_border_color_dark="*primary_50",
73
  table_border_color_dark="*primary_50",
@@ -79,13 +69,8 @@ theme = gr.themes.Soft(
79
  checkbox_label_text_color_selected="*primary_50",
80
  button_cancel_text_color="white",
81
  block_border_color="*primary_50",
82
-
83
- #button_secondary_background_fill=None,
84
- #button_secondary_background_fill_dark=None,
85
  button_secondary_background_fill_hover="*primary_200",
86
  button_secondary_background_fill_hover_dark="*primary_200",
87
-
88
  stat_background_fill="*primary_200",
89
  stat_background_fill_dark="*primary_200",
90
-
91
  )
 
 
1
  import gradio as gr
2
+ from gradio.themes.utils import colors
 
 
3
 
4
 
5
  yfu_red = colors.Color(
 
20
  white = colors.Color(
21
  name="white",
22
  c50="#ff2c65",
23
+ c100="#ff2c65", # text color
24
  c200="#ff2c65",
25
  c300="#ff2c65",
26
  c400="#ff2c65",
27
+ c500="#ff2c65", # secondary text color
28
  c600="#ffffff",
29
  c700="#ffffff",
30
  c800="#ffffff",
 
39
  ).set(
40
  body_background_fill="white",
41
  panel_background_fill="white",
 
42
  background_fill_primary="white",
43
  background_fill_primary_dark="white",
 
44
  panel_background_fill_dark="white",
45
  panel_border_color="*primary_50",
46
  panel_border_color_dark="*primary_50",
 
47
  body_text_color="*primary_50",
48
  body_text_color_dark="*primary_50",
49
  body_text_color_subdued="*primary_50",
50
  body_text_color_subdued_dark="*primary_50",
 
51
  table_even_background_fill="white",
52
  table_even_background_fill_dark="white",
53
  table_odd_background_fill="*primary_100",
54
  table_odd_background_fill_dark="*primary_100",
55
  table_row_focus="*primary_200",
56
  table_row_focus_dark="*primary_200",
 
57
  input_background_fill_focus="*primary_200",
58
  input_background_fill_focus_dark="*primary_200",
 
59
  checkbox_background_color_focus="*primary_200",
60
  checkbox_background_color_focus_dark="*primary_200",
 
61
  border_color_primary_dark="*primary_50",
62
  checkbox_border_color_dark="*primary_50",
63
  table_border_color_dark="*primary_50",
 
69
  checkbox_label_text_color_selected="*primary_50",
70
  button_cancel_text_color="white",
71
  block_border_color="*primary_50",
 
 
 
72
  button_secondary_background_fill_hover="*primary_200",
73
  button_secondary_background_fill_hover_dark="*primary_200",
 
74
  stat_background_fill="*primary_200",
75
  stat_background_fill_dark="*primary_200",
 
76
  )