marquesafonso commited on
Commit
8cdcb92
·
1 Parent(s): b6093b0

add font and text color args. fix api behaviour. improve readme.

Browse files
README.md CHANGED
@@ -22,14 +22,28 @@ Note that this assumes a proper Git installation and ssh key configuration.
22
 
23
  ## Quick start
24
 
25
- Run the following code to your example. The example is based on a youtube video url (optional):
 
 
 
 
 
 
 
 
26
 
27
  ```
28
- pipenv run python .\main.py --invideo_dir './data/' --invideo_filename '<your_video>.mp4' --outvideo_path './data/<output_video>.mp4' --video_url 'https://www.youtube.com/watch?v=<your_youtube_video>' --srt_path '<your_srt_file>.srt'
29
  ```
30
 
31
- Fontsize and Background Color arguments are available:
 
 
 
 
32
 
33
  ```
34
- pipenv run python .\main.py --invideo_dir './data/' --invideo_filename '<your_video>.mp4' --outvideo_path './data/<output_video>.mp4' --video_url 'https://www.youtube.com/watch?v=<your_youtube_video>' --srt_path '<your_srt_file>.srt' --fontsize 28 --bg_color None
35
  ```
 
 
 
22
 
23
  ## Quick start
24
 
25
+ ### Command Line Interface
26
+
27
+ Run the following code to your example using the CLI. The example is based on a youtube video url (optional):
28
+
29
+ ```
30
+ pipenv run python .\cli.py --invideo_filename '<your_file_name>' --video_url 'https://www.youtube.com/watch?v=<your_youtube_video>' --max_words_per_line 8
31
+ ```
32
+
33
+ Fontsize, Font, Background Color and Text Color arguments are available:
34
 
35
  ```
36
+ pipenv run python .\cli.py --invideo_filename '<your_file>' --video_url 'https://www.youtube.com/watch?v=<your_youtube_video>' --max_words_per_line 8 --fontsize 28 --font "Arial-Bold" --bg_color None --text_color 'white'
37
  ```
38
 
39
+ ### API
40
+
41
+ A FastAPI API is also made available.
42
+
43
+ To start the API run:
44
 
45
  ```
46
+ pipenv run uvicorn main:app --reload
47
  ```
48
+
49
+ Then check the [submit_video](http://127.0.0.1:8000/submit_video/) endpoint.
cli_app.py → cli.py RENAMED
@@ -11,11 +11,13 @@ logging.basicConfig(filename='main.log',
11
  format='%(asctime)s %(levelname)s %(message)s',
12
  datefmt='%m/%d/%Y %I:%M:%S %p')
13
 
14
- def main(video_url,
15
- invideo_filename,
16
- fontsize,
17
- bg_color,
18
- max_words_per_line
 
 
19
  ):
20
  INVIDEO_DIR = os.path.join('data/',invideo_filename)
21
  if not os.path.exists(INVIDEO_DIR):
@@ -29,28 +31,32 @@ def main(video_url,
29
  if not os.path.exists(SRT_PATH):
30
  transcriber(stream_title, SRT_PATH, max_words_per_line)
31
  pbar.update(33.33)
32
- subtitler(stream_title, SRT_PATH, OUTVIDEO_PATH,fontsize, bg_color)
33
  pbar.update(33.34)
34
  return
35
  INVIDEO_PATH = os.path.join(INVIDEO_DIR, f"{invideo_filename}.mp4")
36
  if not os.path.exists(SRT_PATH):
37
  transcriber(INVIDEO_PATH, SRT_PATH, max_words_per_line)
38
  pbar.update(66.66)
39
- subtitler(INVIDEO_PATH, SRT_PATH, OUTVIDEO_PATH, fontsize,bg_color)
40
  pbar.update(33.34)
41
 
42
  if __name__ == '__main__':
43
  parser = ArgumentParser()
44
- parser.add_argument('--invideo_filename', required=True, type=str, help='filename')
45
  parser.add_argument('--video_url', required=False, default=None, type=str, help='A video file to be subtitled (Optional)')
 
46
  parser.add_argument('--fontsize', required=False, default=32, type=int, help='Font size for captions (int)')
47
- parser.add_argument('--bg_color', required=False, default="#070a13b3", type=str, help='Hex color value for caption background colour.')
48
- parser.add_argument("--max_words_per_line", type=int, default=None, help="(requires --word_timestamps True, no effect with --max_line_width) the maximum number of words in a segment")
 
49
  args = parser.parse_args()
50
  # Example usage
51
  main(args.video_url,
52
  args.invideo_filename,
 
53
  args.fontsize,
 
54
  args.bg_color,
55
- args.max_words_per_line,
56
  )
 
11
  format='%(asctime)s %(levelname)s %(message)s',
12
  datefmt='%m/%d/%Y %I:%M:%S %p')
13
 
14
+ def main(video_url:str,
15
+ invideo_filename:str,
16
+ max_words_per_line:int,
17
+ fontsize:int,
18
+ font:str,
19
+ bg_color:str,
20
+ text_color:str
21
  ):
22
  INVIDEO_DIR = os.path.join('data/',invideo_filename)
23
  if not os.path.exists(INVIDEO_DIR):
 
31
  if not os.path.exists(SRT_PATH):
32
  transcriber(stream_title, SRT_PATH, max_words_per_line)
33
  pbar.update(33.33)
34
+ subtitler(stream_title, SRT_PATH, OUTVIDEO_PATH,fontsize, font, bg_color, text_color)
35
  pbar.update(33.34)
36
  return
37
  INVIDEO_PATH = os.path.join(INVIDEO_DIR, f"{invideo_filename}.mp4")
38
  if not os.path.exists(SRT_PATH):
39
  transcriber(INVIDEO_PATH, SRT_PATH, max_words_per_line)
40
  pbar.update(66.66)
41
+ subtitler(INVIDEO_PATH, SRT_PATH, OUTVIDEO_PATH, fontsize, font, bg_color, text_color)
42
  pbar.update(33.34)
43
 
44
  if __name__ == '__main__':
45
  parser = ArgumentParser()
46
+ parser.add_argument('--invideo_filename', required=True, type=str, help='Filename to caption.')
47
  parser.add_argument('--video_url', required=False, default=None, type=str, help='A video file to be subtitled (Optional)')
48
+ parser.add_argument("--max_words_per_line", type=int, default=None, help="the maximum number of words in a segment. (int)")
49
  parser.add_argument('--fontsize', required=False, default=32, type=int, help='Font size for captions (int)')
50
+ parser.add_argument('--font', required=False, default="FuturaPTHeavy", type=str, help='Font style for captions (str)')
51
+ parser.add_argument('--bg_color', required=False, default="#070a13b3", type=str, help='Hex color value for caption background colour. (str)')
52
+ parser.add_argument('--text_color', required=False, default="white", type=str, help='color value for caption text. (str)')
53
  args = parser.parse_args()
54
  # Example usage
55
  main(args.video_url,
56
  args.invideo_filename,
57
+ args.max_words_per_line,
58
  args.fontsize,
59
+ args.font,
60
  args.bg_color,
61
+ args.text_color
62
  )
example_cmd.txt DELETED
@@ -1,5 +0,0 @@
1
- [example no background]
2
- pipenv run python .\main.py --invideo_dir './data/' --invideo_filename '<your_video>.mp4' --outvideo_path './data/<output_video>.mp4' --video_url 'https://www.youtube.com/watch?v=<your_youtube_video>' --srt_path '<your_srt_file>.srt' --fontsize 28 --bg_color None
3
-
4
- [example with background]
5
- pipenv run python .\main.py --invideo_dir './data/' --invideo_filename '<your_video>.mp4' --outvideo_path './data/<output_video>.mp4' --video_url 'https://www.youtube.com/watch?v=<your_youtube_video>' --srt_path '<your_srt_file>.srt'
 
 
 
 
 
 
main.py CHANGED
@@ -16,10 +16,13 @@ async def get_form():
16
  <html>
17
  <body>
18
  <form action="/process_video/" enctype="multipart/form-data" method="post">
19
- <input type="file" name="file"><br>
20
- Font size: <input type="number" name="fontsize" value="32"><br>
21
- Background color: <input type="text" name="bg_color" value="#070a13b3"><br>
22
  Max words per line: <input type="number" name="max_words_per_line" value="8"><br>
 
 
 
 
23
  <input type="submit">
24
  </form>
25
  </body>
@@ -28,26 +31,43 @@ async def get_form():
28
  return HTMLResponse(content=html_content)
29
 
30
  @app.post("/process_video/")
31
- async def process_video_api(file: UploadFile = File(...),
32
- fontsize: Optional[int] = Form(32),
 
 
 
33
  bg_color: Optional[str] = Form("#070a13b3"),
34
- max_words_per_line: Optional[int] = Form(8)):
 
35
  try:
36
- if not str(file.filename).endswith('.mp4'):
37
  raise HTTPException(status_code=400, detail="Invalid file type. Please upload an MP4 file.")
38
- # Save the uploaded file to a temporary file
39
  temp_dir = os.path.join(os.getcwd(),"temp")
40
  os.makedirs(temp_dir, exist_ok=True)
41
- temp_input_path = os.path.join(temp_dir, file.filename)
42
- # Copy UploadFile to the temp_input_path
43
  with open(temp_input_path, 'wb') as buffer:
44
  try:
45
- shutil.copyfileobj(file.file, buffer)
46
  finally:
47
- file.file.close()
 
 
 
 
 
 
 
 
 
 
 
48
  # Process the video
49
- output_path = process_video(temp_input_path, fontsize, bg_color, max_words_per_line)
 
50
  # Return the processed video file
51
- return FileResponse(output_path, media_type="video/mp4", filename=f"result_{file.filename}")
 
52
  except Exception as e:
53
  raise HTTPException(status_code=500, detail=str(e))
 
16
  <html>
17
  <body>
18
  <form action="/process_video/" enctype="multipart/form-data" method="post">
19
+ Video File: <input type="file" name="video_file"><br>
20
+ Subtitles File: <input type="file" name="srt_file"><br>
 
21
  Max words per line: <input type="number" name="max_words_per_line" value="8"><br>
22
+ Font size: <input type="number" name="fontsize" value="36"><br>
23
+ Font: <input type="text" name="font" value="FuturaPTHeavy"><br>
24
+ Background color: <input type="text" name="bg_color" value="#070a13b3"><br>
25
+ Text color: <input type="text" name="text_color" value="white"><br>
26
  <input type="submit">
27
  </form>
28
  </body>
 
31
  return HTMLResponse(content=html_content)
32
 
33
  @app.post("/process_video/")
34
+ async def process_video_api(video_file: UploadFile = File(...),
35
+ srt_file: Optional[UploadFile] = File(...),
36
+ max_words_per_line: Optional[int] = Form(8),
37
+ fontsize: Optional[int] = Form(36),
38
+ font: Optional[str] = Form("FuturaPTHeavy"),
39
  bg_color: Optional[str] = Form("#070a13b3"),
40
+ text_color: Optional[str] = Form("white")
41
+ ):
42
  try:
43
+ if not str(video_file.filename).endswith('.mp4'):
44
  raise HTTPException(status_code=400, detail="Invalid file type. Please upload an MP4 file.")
45
+ # Create temp dir
46
  temp_dir = os.path.join(os.getcwd(),"temp")
47
  os.makedirs(temp_dir, exist_ok=True)
48
+ temp_input_path = os.path.join(temp_dir, video_file.filename)
49
+ # Copy video UploadFile to the temp_input_path
50
  with open(temp_input_path, 'wb') as buffer:
51
  try:
52
+ shutil.copyfileobj(video_file.file, buffer)
53
  finally:
54
+ video_file.file.close()
55
+ # Copy srt UploadFile to the temp_input_path
56
+ if srt_file.size > 0:
57
+ SRT_PATH = os.path.abspath(f"{temp_input_path.split('.')[0]}.srt")
58
+ with open(SRT_PATH, 'wb') as buffer:
59
+ try:
60
+ shutil.copyfileobj(srt_file.file, buffer)
61
+ finally:
62
+ srt_file.file.close()
63
+ # Process the video
64
+ output_path = process_video(temp_input_path, SRT_PATH, max_words_per_line, fontsize, font, bg_color, text_color)
65
+ return FileResponse(output_path, media_type="video/mp4", filename=f"result_{video_file.filename}")
66
  # Process the video
67
+ output_path = process_video(temp_input_path, None, max_words_per_line, fontsize, font, bg_color, text_color)
68
+ # FileResponse(output_path, media_type="text/srt", filename=f"result_{video_file.filename.split('.')[0]}.srt")
69
  # Return the processed video file
70
+ return FileResponse(output_path, media_type="video/mp4", filename=f"result_{video_file.filename}")
71
+
72
  except Exception as e:
73
  raise HTTPException(status_code=500, detail=str(e))
utils/process_video.py CHANGED
@@ -1,5 +1,4 @@
1
  # Import necessary modules
2
- from utils.download_video import download_video
3
  from utils.transcriber import transcriber
4
  from utils.subtitler import subtitler
5
  import logging, os
@@ -13,15 +12,21 @@ logging.basicConfig(filename='main.log',
13
 
14
  # API Function
15
  def process_video(invideo_filename:str,
 
 
16
  fontsize:str,
 
17
  bg_color:str,
18
- max_words_per_line:int
19
  ):
 
 
 
 
20
  SRT_PATH = os.path.abspath(f"{invideo_filename.split('.')[0]}.srt")
21
- OUTVIDEO_PATH = os.path.join("temp/", f"result.mp4")
22
  if not os.path.exists(SRT_PATH):
23
  transcriber(invideo_filename, SRT_PATH, max_words_per_line)
24
  logging.info("Transcription Complete")
25
- subtitler(invideo_filename, SRT_PATH, OUTVIDEO_PATH, fontsize, bg_color)
26
  logging.info("Subtitling Complete")
27
  return OUTVIDEO_PATH
 
1
  # Import necessary modules
 
2
  from utils.transcriber import transcriber
3
  from utils.subtitler import subtitler
4
  import logging, os
 
12
 
13
  # API Function
14
  def process_video(invideo_filename:str,
15
+ srt_path: str,
16
+ max_words_per_line:int,
17
  fontsize:str,
18
+ font:str,
19
  bg_color:str,
20
+ text_color:str
21
  ):
22
+ OUTVIDEO_PATH = os.path.join("temp/", "result.mp4")
23
+ if srt_path:
24
+ subtitler(invideo_filename, srt_path, OUTVIDEO_PATH, fontsize, font, bg_color, text_color)
25
+ return OUTVIDEO_PATH
26
  SRT_PATH = os.path.abspath(f"{invideo_filename.split('.')[0]}.srt")
 
27
  if not os.path.exists(SRT_PATH):
28
  transcriber(invideo_filename, SRT_PATH, max_words_per_line)
29
  logging.info("Transcription Complete")
30
+ subtitler(invideo_filename, SRT_PATH, OUTVIDEO_PATH, fontsize, font, bg_color, text_color)
31
  logging.info("Subtitling Complete")
32
  return OUTVIDEO_PATH
utils/subtitler.py CHANGED
@@ -23,22 +23,25 @@ def parse_srt(srt_file):
23
 
24
 
25
  def subtitler(video_file:str,
26
- srt_file:str,
27
  output_file:str,
28
  fontsize:int,
29
- bg_color:str):
 
 
 
30
  """Add subtitles from an SRT file to a video."""
31
  video_file = os.path.abspath(video_file)
32
- srt_file = os.path.abspath(srt_file)
33
  output_file = os.path.abspath(output_file)
34
 
35
  clip = VideoFileClip(video_file)
36
- subtitles = parse_srt(srt_file)
37
 
38
  subtitle_clips = []
39
  for start, end, text in subtitles:
40
  # Create TextClip with specified styling
41
- txt_clip = TextClip(text, fontsize=fontsize, color='white', font="Arial-Bold", method='caption',
42
  bg_color=bg_color, align='center', size=(clip.w*1/2, None))
43
  txt_clip = txt_clip.set_position(('center', 'bottom')).set_duration(clip.duration).set_start(start).set_end(end)
44
  subtitle_x_position = 'center'
 
23
 
24
 
25
  def subtitler(video_file:str,
26
+ srt_path:str,
27
  output_file:str,
28
  fontsize:int,
29
+ font: str,
30
+ bg_color:str,
31
+ text_color:str
32
+ ):
33
  """Add subtitles from an SRT file to a video."""
34
  video_file = os.path.abspath(video_file)
35
+ srt_path = os.path.abspath(srt_path)
36
  output_file = os.path.abspath(output_file)
37
 
38
  clip = VideoFileClip(video_file)
39
+ subtitles = parse_srt(srt_path)
40
 
41
  subtitle_clips = []
42
  for start, end, text in subtitles:
43
  # Create TextClip with specified styling
44
+ txt_clip = TextClip(text, fontsize=fontsize, color=text_color, font=font, method='caption',
45
  bg_color=bg_color, align='center', size=(clip.w*1/2, None))
46
  txt_clip = txt_clip.set_position(('center', 'bottom')).set_duration(clip.duration).set_start(start).set_end(end)
47
  subtitle_x_position = 'center'
utils/transcriber.py CHANGED
@@ -58,6 +58,4 @@ def transcriber(input_path:str,
58
 
59
  logging.info("Detected language '%s' with probability %f" % (info.language, info.language_probability))
60
  logging.info("Writing file...")
61
- write_srt(segments=segments, srt_path=srt_path, max_words_per_line=max_words_per_line)
62
-
63
-
 
58
 
59
  logging.info("Detected language '%s' with probability %f" % (info.language, info.language_probability))
60
  logging.info("Writing file...")
61
+ write_srt(segments=segments, srt_path=srt_path, max_words_per_line=max_words_per_line)