Commit
·
44d365d
1
Parent(s):
1b8b58c
add max_words_per_line. reduce args. fix paths.
Browse files- main.py +25 -16
- utils/download_video.py +4 -2
- utils/transcriber.py +31 -7
main.py
CHANGED
@@ -12,36 +12,45 @@ logging.basicConfig(filename='main.log',
|
|
12 |
datefmt='%m/%d/%Y %I:%M:%S %p')
|
13 |
|
14 |
def main(video_url,
|
15 |
-
srt_path,
|
16 |
-
invideo_dir,
|
17 |
invideo_filename,
|
18 |
-
outvideo_path,
|
19 |
fontsize,
|
20 |
-
bg_color
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
with tqdm(total=100, desc="Overall Progress") as pbar:
|
22 |
if video_url != None:
|
23 |
-
stream_title = download_video(video_url,
|
24 |
pbar.update(33.33)
|
25 |
-
if not os.path.exists(
|
26 |
-
transcriber(stream_title,
|
27 |
pbar.update(33.33)
|
28 |
-
subtitler(stream_title,
|
29 |
pbar.update(33.34)
|
30 |
return
|
31 |
-
|
32 |
-
|
|
|
33 |
pbar.update(66.66)
|
34 |
-
subtitler(
|
35 |
pbar.update(33.34)
|
|
|
36 |
if __name__ == '__main__':
|
37 |
parser = ArgumentParser()
|
38 |
-
parser.add_argument('--
|
39 |
-
parser.add_argument('--invideo_filename', required=True, type=str, help='filename and extension of ')
|
40 |
-
parser.add_argument('--outvideo_path', required=True, help='path to the output video')
|
41 |
parser.add_argument('--video_url', required=False, default=None, type=str, help='A video file to be subtitled (Optional)')
|
42 |
-
parser.add_argument('--srt_path', required=False, default="data/audio.srt", type=str, help='path to the srt file (default: data/audio.srt)')
|
43 |
parser.add_argument('--fontsize', required=False, default=32, type=int, help='Font size for captions (int)')
|
44 |
parser.add_argument('--bg_color', required=False, default="#070a13b3", type=str, help='Hex color value for caption background colour.')
|
|
|
45 |
args = parser.parse_args()
|
46 |
# Example usage
|
47 |
-
main(args.video_url,
|
|
|
|
|
|
|
|
|
|
|
|
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):
|
22 |
+
os.makedirs(INVIDEO_DIR)
|
23 |
+
SRT_PATH = os.path.join(INVIDEO_DIR, f"{invideo_filename}.srt")
|
24 |
+
OUTVIDEO_PATH = os.path.join(INVIDEO_DIR, f"result_{invideo_filename}.mp4")
|
25 |
with tqdm(total=100, desc="Overall Progress") as pbar:
|
26 |
if video_url != None:
|
27 |
+
stream_title = download_video(video_url, INVIDEO_DIR, invideo_filename)
|
28 |
pbar.update(33.33)
|
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 |
+
)
|
utils/download_video.py
CHANGED
@@ -1,12 +1,14 @@
|
|
1 |
from pytube import YouTube
|
|
|
2 |
|
3 |
def download_video(input_file, output_path, filename):
|
|
|
4 |
try:
|
5 |
yt = YouTube(input_file)
|
6 |
video_stream = yt.streams.filter(progressive=True, file_extension='mp4').order_by('resolution').desc().first()
|
7 |
if video_stream:
|
8 |
-
video_stream.download(output_path=output_path,filename=
|
9 |
-
video_title =
|
10 |
return video_title
|
11 |
else:
|
12 |
return "No suitable stream found for this video."
|
|
|
1 |
from pytube import YouTube
|
2 |
+
import os
|
3 |
|
4 |
def download_video(input_file, output_path, filename):
|
5 |
+
full_filename = f"{filename}.mp4"
|
6 |
try:
|
7 |
yt = YouTube(input_file)
|
8 |
video_stream = yt.streams.filter(progressive=True, file_extension='mp4').order_by('resolution').desc().first()
|
9 |
if video_stream:
|
10 |
+
video_stream.download(output_path=output_path,filename=full_filename)
|
11 |
+
video_title = os.path.join(output_path, full_filename)
|
12 |
return video_title
|
13 |
else:
|
14 |
return "No suitable stream found for this video."
|
utils/transcriber.py
CHANGED
@@ -8,14 +8,35 @@ logging.basicConfig(filename='main.log',
|
|
8 |
datefmt='%m/%d/%Y %I:%M:%S %p')
|
9 |
logging.getLogger("faster_whisper").setLevel(logging.DEBUG)
|
10 |
|
11 |
-
def write_srt(segments, srt_path):
|
12 |
-
"""Write segments to an SRT file."""
|
13 |
with open(srt_path, "w", encoding='utf-8') as file:
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
16 |
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
model_size = "large-v3"
|
20 |
|
21 |
# Run on GPU with FP16
|
@@ -32,8 +53,11 @@ def transcriber(input_path:str, srt_path:str):
|
|
32 |
beam_size=5,
|
33 |
vad_filter=True,
|
34 |
vad_parameters=dict(min_silence_duration_ms=500),
|
|
|
35 |
)
|
36 |
|
37 |
logging.info("Detected language '%s' with probability %f" % (info.language, info.language_probability))
|
38 |
logging.info("Writing file...")
|
39 |
-
write_srt(segments=segments, srt_path=srt_path)
|
|
|
|
|
|
8 |
datefmt='%m/%d/%Y %I:%M:%S %p')
|
9 |
logging.getLogger("faster_whisper").setLevel(logging.DEBUG)
|
10 |
|
11 |
+
def write_srt(segments, srt_path, max_words_per_line):
|
12 |
+
"""Write segments to an SRT file with a maximum number of words per line."""
|
13 |
with open(srt_path, "w", encoding='utf-8') as file:
|
14 |
+
line_counter = 1
|
15 |
+
for _, segment in enumerate(segments):
|
16 |
+
words_in_line = []
|
17 |
+
for w, word in enumerate(segment.words):
|
18 |
+
words_in_line.append(word)
|
19 |
|
20 |
+
# Write the line if max words limit reached or it's the last word in the segment
|
21 |
+
if len(words_in_line) == max_words_per_line or w == len(segment.words) - 1:
|
22 |
+
if words_in_line: # Check to avoid writing a line if there are no words
|
23 |
+
start_time = words_in_line[0].start
|
24 |
+
end_time = words_in_line[-1].end
|
25 |
+
line_text = ' '.join([w.word.strip() for w in words_in_line])
|
26 |
+
|
27 |
+
file.write(f"{line_counter}\n{start_time} --> {end_time}\n{line_text}\n\n")
|
28 |
+
|
29 |
+
# Reset for the next line and increment line counter
|
30 |
+
line_counter += 1
|
31 |
+
|
32 |
+
words_in_line = [] # Reset words list for the next line
|
33 |
+
|
34 |
+
|
35 |
+
|
36 |
+
def transcriber(input_path:str,
|
37 |
+
srt_path:str,
|
38 |
+
max_words_per_line:int):
|
39 |
+
|
40 |
model_size = "large-v3"
|
41 |
|
42 |
# Run on GPU with FP16
|
|
|
53 |
beam_size=5,
|
54 |
vad_filter=True,
|
55 |
vad_parameters=dict(min_silence_duration_ms=500),
|
56 |
+
word_timestamps=True
|
57 |
)
|
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 |
+
|