File size: 3,668 Bytes
19f5fa0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import os
import requests
import gradio as gr

from time import time
from pytube import YouTube
from moviepy.editor import *
from moviepy.video.tools.subtitles import SubtitlesClip


GLADIA_API_KEY = os.environ.get("GLADIA_API_KEY")


headers = {
    "accept": "application/json",
    "x-gladia-key": GLADIA_API_KEY,
}

ACCEPTED_LANGUAGE_BEHAVIOUR = [
    "manual",
    "automatic single language",
    "automatic multiple languages",
]


def __download_youtube_video(youtube_url: str, path):

    youtube_video = YouTube(youtube_url)

    video_stream = youtube_video.streams.filter(res="720p").first()

    if not video_stream:
        video_stream = youtube_video.streams.filter(res="480p").first()

    if not video_stream:
        video_stream = youtube_video.streams.filter(res="360p").first()

    video_stream.download(filename=path)


def __apply_srt_to_video(path_to_srt: str, path_to_video: str, output_path: str):

    def __generator(raw_txt):

        MIN_LINE_SIZE = 80
        MAX_LINE_SIZE = 140

        text_to_display = []

        while raw_txt:
            idx = MIN_LINE_SIZE if MIN_LINE_SIZE < len(raw_txt) else len(raw_txt)

            while idx <= len(raw_txt) and raw_txt[idx - 1] not in ('\n', ' ', ',', ';', '.', '-') and idx < MAX_LINE_SIZE:
                idx += 1

            text_to_display.append(raw_txt[:idx])
            raw_txt = raw_txt[idx:]

        text_to_display = "\n".join(text_to_display)

        return TextClip(text_to_display, font='Arial', fontsize=30, color='white')

    subs = SubtitlesClip(path_to_srt, __generator)
    subtitles = SubtitlesClip(subs, __generator)

    video = VideoFileClip(path_to_video)

    # Combine video and subtitle clips
    result = CompositeVideoClip([video, subtitles.set_pos(('center','bottom'))])

    # Write the result to a new video file
    result.write_videofile(output_path)


def youtube_subtitler(youtube_url: str):
    files_to_remove = []

    try:
        path_to_srt = f"/tmp/{str(time())}.srt"

        files = {
            'audio_url': (None, youtube_url),
            'output_format': (None, "srt"),
            'language_behaviour': (None, 'automatic multiple languages'),
        }

        response = requests.post(
            'https://api.gladia.io/audio/text/audio-transcription/?output_format=srt',
            headers=headers,
            files=files
        )

        if response.status_code != 200:
            raise RuntimeError(f"Failed to transcribe the video: {response.content}")

        with open(path_to_srt, "w+") as f:
            f.write(response.json()["prediction"])

        files_to_remove.append(path_to_srt)

        path_to_video = f"/tmp/{str(time())}.mp4"

        __download_youtube_video(youtube_url=youtube_url, path=path_to_video)

        files_to_remove.append(path_to_video)

        output_path = f"/tmp/{str(time())}.mp4"

        __apply_srt_to_video(
            path_to_srt=path_to_srt,
            path_to_video=path_to_video,
            output_path=output_path
        )

    finally:
        for file in files_to_remove:
            os.remove(file)

    return output_path


iface = gr.Interface(
    title="Gladia.io Youtube Subtitler",
    description="""Burn subtitles into your youtube video using Gladia's Audio-Transcription solution.
    <br/><br/>
    You are more than welcome to join us on [Slack](https://gladia-io.slack.com)
    and don't forget to get your own API key on [Gladia.io](https://gladia.io/) during the free alpha !
    """,
    fn=youtube_subtitler,
    inputs=[
        gr.Text(label="Youtube URL"),
    ], outputs=[
        gr.Video(format="mp4"),
    ],
)

iface.queue()
iface.launch()