File size: 3,334 Bytes
ea6f179
 
 
 
 
 
 
 
 
 
4b3ad7b
ea6f179
a73b7f1
 
ea6f179
a7bbb2a
ea6f179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a799e09
4b3ad7b
ea6f179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c94171a
7dd4d3b
 
ea6f179
 
 
 
 
 
9f5404a
ea6f179
 
 
9f5404a
7dd4d3b
 
 
 
ea6f179
9f5404a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# Copyright (c) 2024, please contact before redistribution/modification

FONT_URL = 'https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hjQ.ttf'
from moviepy.editor import *
import whisper
from cached_path import cached_path
from moviepy.video.tools.subtitles import SubtitlesClip
import torch
import tempfile
import gradio as gr
from pathlib import Path

mdl = whisper.load_model("base" if torch.cuda.is_available() else 'tiny')
if torch.cuda.is_available(): mdl.to('cuda')
def subtitle(input):
    input = str(input)
    status = "**Starting...**"
    yield status, gr.update()
    gr.Info("Transcribing...")
    status += "\n\n[1/5] Transcribing... (may take a while)"
    yield status, gr.update()
    transcript = mdl.transcribe(
        word_timestamps=True,
        audio=input
    )
    status += "\n\n[2/5] Processing subtitles..."
    yield status, gr.update()
    gr.Info("Processing subtitles...")
    subs = []
    for segment in transcript['segments']:
        for word in segment['words']:
            subs.append(((word['start'], word['end'],), word['word'].strip(),))
    status += "\n\n[3/5] Loading video..."
    yield status, gr.update()
    gr.Info("Loading video...")
    print(input)
    video = VideoFileClip(Path(input))
    width, height = video.size
    generator = lambda txt: TextClip(txt, size=(width * (3 / 4) + 8, None), color='white', stroke_color='black', stroke_width=8, method='caption', fontsize=min(width / 7, height / 7), font=str(cached_path(FONT_URL)))
    generator1 = lambda txt: TextClip(txt, size=(width * (3 / 4), None), color='white', method='caption', fontsize=min(width / 7, height / 7), font=str(cached_path(FONT_URL)))
    status += "\n\n[4/5] Loading video clip..."
    yield status, gr.update()
    gr.Info("Loading video clip...")
    subtitles = SubtitlesClip(subs, generator)
    subtitles2 = SubtitlesClip(subs, generator1)
    result_1 = CompositeVideoClip([video, subtitles.set_pos(('center','center'))])
    result = CompositeVideoClip([result_1, subtitles2.set_pos(('center','center'))])
    status += "\n\n[5/5] Writing video... (may take a while)"
    yield status, gr.update()
    gr.Info("Writing video...")
    with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as f:
        result.write_videofile(f.name, codec='h264_videotoolbox', audio_codec='aac', threads=64)
    status += "\n\n**Done!**"
    yield status, f.name
    return

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column(scale=3):
            gr.Markdown("""
# AutoSubs

Automatically add on-screen subtitles to your videos.

**NOTE:** Uploading copyrighted/NSFW content to this service is strictly prohibited.

The maximum length of video is 5 minutes. This service probably won't work well on non-English videos.

Powered by OAI Whisper & MoviePy!
""")
            vid_inp = gr.Video(interactive=True, label="Upload or record video", max_length=300)
            go_btn = gr.Button("Transcribe!", variant="primary")
        with gr.Column(scale=1):
            status = gr.Markdown("**Status updates will appear here.**")
            vid_out = gr.Video(interactive=False, label="Result")
    go_btn.click(subtitle, inputs=[vid_inp], outputs=[status, vid_out])
demo.queue(api_open=False, default_concurrency_limit=20).launch(show_api=False)