File size: 5,162 Bytes
24cf2ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5a38be6
2709dcf
24cf2ab
5a38be6
 
 
 
 
24cf2ab
5a38be6
24cf2ab
 
 
 
 
 
 
 
 
 
 
 
 
5a38be6
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
import streamlit as st
import pandas as pd
from faster_whisper import WhisperModel
import logging
import os
import pysrt
from transformers import MarianMTModel, MarianTokenizer
import ffmpeg

# Configuration initiale et chargement des données
url = "https://huggingface.co/Lenylvt/LanguageISO/resolve/main/iso.md"
df = pd.read_csv(url, delimiter="|", skiprows=2, header=None).dropna(axis=1, how='all')
df.columns = ['ISO 639-1', 'ISO 639-2', 'Language Name', 'Native Name']
df['ISO 639-1'] = df['ISO 639-1'].str.strip()

language_options = df['ISO 639-1'].tolist()
model_size_options = ["tiny", "base", "small", "medium", "large", "large-v2", "large-v3"]

logging.basicConfig(level=logging.DEBUG)

def text_to_srt(text):
    lines = text.split('\n')
    srt_content = ""
    for i, line in enumerate(lines):
        if line.strip() == "":
            continue
        try:
            times, content = line.split(']', 1)
            start, end = times[1:].split(' -> ')
            if start.count(":") == 1:
                start = "00:" + start
            if end.count(":") == 1:
                end = "00:" + end
            srt_content += f"{i+1}\n{start.replace('.', ',')} --> {end.replace('.', ',')}\n{content.strip()}\n\n"
        except ValueError:
            continue
    temp_file_path = '/tmp/output.srt'
    with open(temp_file_path, 'w', encoding='utf-8') as file:
        file.write(srt_content)
    return temp_file_path

def format_timestamp(seconds):
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    seconds_remainder = seconds % 60
    return f"{hours:02d}:{minutes:02d}:{seconds_remainder:06.3f}"

def translate_text(text, source_language_code, target_language_code):
    model_name = f"Helsinki-NLP/opus-mt-{source_language_code}-{target_language_code}"
    if source_language_code == target_language_code:
        return "Translation between the same languages is not supported."
    try:
        tokenizer = MarianTokenizer.from_pretrained(model_name)
        model = MarianMTModel.from_pretrained(model_name)
    except Exception as e:
        return f"Failed to load model for {source_language_code} to {target_language_code}: {str(e)}"
    translated = model.generate(**tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512))
    translated_text = tokenizer.decode(translated[0], skip_special_tokens=True)
    return translated_text

def transcribe(audio_file_path, model_size="base"):
    device = "cpu"
    compute_type = "int8"
    model = WhisperModel(model_size, device=device, compute_type=compute_type)
    segments, _ = model.transcribe(audio_file_path)
    transcription_with_timestamps = [
        f"[{format_timestamp(segment.start)} -> {format_timestamp(segment.end)}] {segment.text}"
        for segment in segments
    ]
    return "\n".join(transcription_with_timestamps)

def add_subtitle_to_video(input_video, subtitle_file, subtitle_language, soft_subtitle=False):
    video_input_stream = ffmpeg.input(input_video)
    subtitle_input_stream = ffmpeg.input(subtitle_file)
    input_video_name = os.path.splitext(os.path.basename(input_video))[0]
    output_video = f"/tmp/{input_video_name}_subtitled.mp4"
    if soft_subtitle:
        stream = ffmpeg.output(video_input_stream, subtitle_input_stream, output_video, **{"c": "copy", "c:s": "mov_text"})
    else:
        stream = ffmpeg.output(video_input_stream, output_video, vf=f"subtitles={subtitle_file}")
    ffmpeg.run(stream, overwrite_output=True)
    return output_video

st.title("Video Subtitle Creation")
st.write("For API use please visit [this space](https://huggingface.co/spaces/Lenylvt/VideoSubtitleCreation-API)")

uploaded_file = st.file_uploader("📹 Upload Video", type=["mp4", "avi", "mov"])
action = st.radio("🧷 Select Action", ["Transcribe and Add Subtitles", "Transcribe, Translate and Add Subtitles"])
source_language = st.selectbox("1️⃣ Source Language", options=language_options, index=language_options.index('en'))
target_language = st.selectbox("2️⃣ Target Language", options=language_options, index=language_options.index('fr'))
model_size = st.selectbox("📜 Model Size", options=model_size_options)

if st.button("📁 Process Video"):
    if uploaded_file is not None:
        with st.spinner('Processing...'):
            audio_file_path = f"/tmp/{uploaded_file.name}"
            with open(audio_file_path, "wb") as f:
                f.write(uploaded_file.getvalue())
            transcription = transcribe(audio_file_path, model_size)
            srt_path = text_to_srt(transcription)
            if action == "Transcribe and Add Subtitles":
                output_video_path = add_subtitle_to_video(audio_file_path, srt_path, subtitle_language="eng", soft_subtitle=False)
            else:  # Transcribe, Translate and Add Subtitles
                translated_srt_path = translate_text(srt_path, source_language, target_language)
                output_video_path = add_subtitle_to_video(audio_file_path, translated_srt_path, target_language, soft_subtitle=False)
            st.video(output_video_path)
            st.success("🟢 Processing Completed")