Jeffgold commited on
Commit
6312c58
·
1 Parent(s): 99535b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -53
app.py CHANGED
@@ -1,21 +1,22 @@
1
  import logging
2
- import shutil
3
- from pathlib import Path
4
- from moviepy.editor import VideoFileClip
5
- import gradio as gr
6
  import requests
7
  from urllib.parse import urlparse
8
  import subprocess
9
- import atexit
10
  from flask import Flask, send_from_directory
11
  from threading import Thread
 
 
 
12
 
13
  # Initialize a Flask application
14
  app = Flask(__name__)
15
 
 
 
 
16
  @app.route('/files/<path:path>')
17
  def serve_file(path):
18
- return send_from_directory(Path.cwd(), path)
19
 
20
  # Start the Flask server in a new thread
21
  Thread(target=app.run, kwargs={'host': '0.0.0.0', 'port': 5000}).start()
@@ -23,47 +24,41 @@ Thread(target=app.run, kwargs={'host': '0.0.0.0', 'port': 5000}).start()
23
  logging.basicConfig(level=logging.INFO)
24
 
25
  def download_file(url, destination):
26
- """Downloads a file from a url to a destination."""
27
  response = requests.get(url)
28
  response.raise_for_status()
29
  with open(destination, 'wb') as f:
30
  f.write(response.content)
31
 
32
  def get_input_path(video_file, video_url):
33
- """Returns the path to the video file, downloading it if necessary."""
34
  if video_file is not None:
35
  return Path(video_file.name)
36
  elif video_url:
37
  url_path = urlparse(video_url).path
38
  file_name = Path(url_path).name
39
- destination = Path.cwd() / file_name
40
  download_file(video_url, destination)
41
  return destination
42
  else:
43
  raise ValueError("No input was provided.")
44
 
45
  def get_output_path(input_path, res):
46
- """Returns the path to the output file, creating it if necessary."""
47
- output_path = Path.cwd() / (Path(input_path).stem + f"_{res}.m3u8")
48
  return output_path
49
 
50
  def get_aspect_ratio(input_path, aspect_ratio):
51
- """Returns the aspect ratio of the video, calculating it if necessary."""
52
  if aspect_ratio is not None:
53
  return aspect_ratio
54
  video = VideoFileClip(str(input_path))
55
  return f"{video.size[0]}:{video.size[1]}"
56
 
57
  def create_master_playlist(output_paths):
58
- """Creates a master playlist .m3u8 file that includes all other .m3u8 files."""
59
- master_playlist_path = Path.cwd() / "master_playlist.m3u8"
60
  with open(master_playlist_path, 'w') as f:
61
  f.write("#EXTM3U\n")
62
  for path in output_paths:
63
  f.write(f"#EXT-X-STREAM-INF:BANDWIDTH={1000*1000},RESOLUTION={path.stem.split('_')[-1]}\n")
64
  f.write(f"{path.name}\n")
65
- return master_playlist_path # make sure this is a single Path object
66
-
67
 
68
  def convert_video(video_file, quality, aspect_ratio, video_url):
69
  input_path = get_input_path(video_file, video_url)
@@ -85,7 +80,7 @@ def convert_video(video_file, quality, aspect_ratio, video_url):
85
  "ffmpeg", "-i", str(input_path), "-c:v", "libx264", "-crf", str(quality),
86
  "-vf", f"scale={scale}:force_original_aspect_ratio=decrease,pad=ceil(iw/2)*2:ceil(ih/2)*2",
87
  "-hls_time", "10", "-hls_playlist_type", "vod", "-hls_segment_filename",
88
- str(Path.cwd() / f"{output_path.stem}_%03d.ts"), str(output_path)
89
  ]
90
 
91
  logging.info("Running ffmpeg command: " + ' '.join(ffmpeg_command))
@@ -102,8 +97,8 @@ def convert_video(video_file, quality, aspect_ratio, video_url):
102
  video_path = f'http://localhost:5000/files/{path.name}'
103
  video_component = f'''
104
  <div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 10px;">
105
- <video width="320" height="240" controls>
106
- <source src="{video_path}" type="video/mp4">
107
  Your browser does not support the video tag.
108
  </video>
109
  <p>
@@ -117,47 +112,20 @@ def convert_video(video_file, quality, aspect_ratio, video_url):
117
  return "\n".join(html_blocks),
118
 
119
  video_file = gr.inputs.File(label="Video File")
120
- quality = gr.inputs.Dropdown(
121
- choices=["18", "23", "27", "28", "32"],
122
- default="27",
123
- label="Quality"
124
- )
125
- aspect_ratio = gr.inputs.Dropdown(
126
- choices=["16:9", "1:1", "4:3", "3:2", "5:4", "21:9", "1.85:1", "2.35:1", "3:1", "360", "9:16", "2:1", "1:2", "9:1"],
127
- default="16:9",
128
- label="Aspect ratio (width:height)"
129
- )
130
  standard_resolutions = [4320, 2160, 1440, 1080, 720, 480, 360, 240, 144] # 8K, 4K, 2K, Full HD, HD, SD in pixels
131
  video_url = gr.inputs.Textbox(label="Or enter video URL")
132
 
133
- inputs = [
134
- gr.components.File(label="Video File"),
135
- gr.components.Dropdown(
136
- choices=["18", "23", "27", "28", "32"],
137
- default="27",
138
- label="Quality"
139
- ),
140
- gr.components.Dropdown(
141
- choices=["16:9", "1:1", "4:3", "3:2", "5:4", "21:9", "1.85:1", "2.35:1", "3:1", "360", "9:16", "2:1", "1:2", "9:1"],
142
- default="16:9",
143
- label="Aspect ratio (width:height)"
144
- ),
145
- gr.components.Textbox(label="Or enter video URL")
146
- ]
147
-
148
- outputs = [
149
- gr.components.HTML(label="Download Links"),
150
- gr.components.Video(label="Video Player"),
151
- gr.components.Textbox(label="Text Files", type="text")
152
- ]
153
-
154
  interface = gr.Interface(
155
  fn=convert_video,
156
- inputs=inputs,
157
- outputs=outputs,
 
 
158
  title="Video Converter",
159
  description="A simple video converter app",
160
  allow_flagging=False
161
  )
162
 
163
- interface.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import logging
 
 
 
 
2
  import requests
3
  from urllib.parse import urlparse
4
  import subprocess
 
5
  from flask import Flask, send_from_directory
6
  from threading import Thread
7
+ from pathlib import Path
8
+ from moviepy.editor import VideoFileClip
9
+ import gradio as gr
10
 
11
  # Initialize a Flask application
12
  app = Flask(__name__)
13
 
14
+ output_dir = Path.cwd() / "output"
15
+ output_dir.mkdir(exist_ok=True)
16
+
17
  @app.route('/files/<path:path>')
18
  def serve_file(path):
19
+ return send_from_directory(output_dir, path)
20
 
21
  # Start the Flask server in a new thread
22
  Thread(target=app.run, kwargs={'host': '0.0.0.0', 'port': 5000}).start()
 
24
  logging.basicConfig(level=logging.INFO)
25
 
26
  def download_file(url, destination):
 
27
  response = requests.get(url)
28
  response.raise_for_status()
29
  with open(destination, 'wb') as f:
30
  f.write(response.content)
31
 
32
  def get_input_path(video_file, video_url):
 
33
  if video_file is not None:
34
  return Path(video_file.name)
35
  elif video_url:
36
  url_path = urlparse(video_url).path
37
  file_name = Path(url_path).name
38
+ destination = output_dir / file_name
39
  download_file(video_url, destination)
40
  return destination
41
  else:
42
  raise ValueError("No input was provided.")
43
 
44
  def get_output_path(input_path, res):
45
+ output_path = output_dir / (Path(input_path).stem + f"_{res}.m3u8")
 
46
  return output_path
47
 
48
  def get_aspect_ratio(input_path, aspect_ratio):
 
49
  if aspect_ratio is not None:
50
  return aspect_ratio
51
  video = VideoFileClip(str(input_path))
52
  return f"{video.size[0]}:{video.size[1]}"
53
 
54
  def create_master_playlist(output_paths):
55
+ master_playlist_path = output_dir / "master_playlist.m3u8"
 
56
  with open(master_playlist_path, 'w') as f:
57
  f.write("#EXTM3U\n")
58
  for path in output_paths:
59
  f.write(f"#EXT-X-STREAM-INF:BANDWIDTH={1000*1000},RESOLUTION={path.stem.split('_')[-1]}\n")
60
  f.write(f"{path.name}\n")
61
+ return master_playlist_path
 
62
 
63
  def convert_video(video_file, quality, aspect_ratio, video_url):
64
  input_path = get_input_path(video_file, video_url)
 
80
  "ffmpeg", "-i", str(input_path), "-c:v", "libx264", "-crf", str(quality),
81
  "-vf", f"scale={scale}:force_original_aspect_ratio=decrease,pad=ceil(iw/2)*2:ceil(ih/2)*2",
82
  "-hls_time", "10", "-hls_playlist_type", "vod", "-hls_segment_filename",
83
+ str(output_dir / f"{output_path.stem}_%03d.ts"), str(output_path)
84
  ]
85
 
86
  logging.info("Running ffmpeg command: " + ' '.join(ffmpeg_command))
 
97
  video_path = f'http://localhost:5000/files/{path.name}'
98
  video_component = f'''
99
  <div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 10px;">
100
+ <video controls>
101
+ <source src="{video_path}" type="application/x-mpegURL">
102
  Your browser does not support the video tag.
103
  </video>
104
  <p>
 
112
  return "\n".join(html_blocks),
113
 
114
  video_file = gr.inputs.File(label="Video File")
115
+ quality = gr.inputs.Dropdown(choices=["18", "23", "27", "28", "32"], default="27", label="Quality")
116
+ aspect_ratio = gr.inputs.Dropdown(choices=["16:9", "1:1", "4:3", "3:2", "5:4", "21:9", "1.85:1", "2.35:1", "3:1", "360", "9:16", "2:1", "1:2", "9:1"], default="16:9", label="Aspect ratio (width:height)")
 
 
 
 
 
 
 
 
117
  standard_resolutions = [4320, 2160, 1440, 1080, 720, 480, 360, 240, 144] # 8K, 4K, 2K, Full HD, HD, SD in pixels
118
  video_url = gr.inputs.Textbox(label="Or enter video URL")
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  interface = gr.Interface(
121
  fn=convert_video,
122
+ inputs=[video_file, quality, aspect_ratio, video_url],
123
+ outputs=[
124
+ gr.outputs.HTML(label="Download Links")
125
+ ],
126
  title="Video Converter",
127
  description="A simple video converter app",
128
  allow_flagging=False
129
  )
130
 
131
+ interface.launch(server_name="0.0.0.0", server_port=7860)