File size: 4,232 Bytes
84a2d01
a4e49da
9fecb60
 
5a9597e
9fecb60
 
4379280
9fecb60
 
 
 
064b756
8f936a5
9fecb60
08d3703
064b756
 
 
9fecb60
064b756
9fecb60
 
 
 
 
 
 
 
064b756
9fecb60
 
 
daee22a
9fecb60
 
064b756
9fecb60
064b756
08d3703
9fecb60
064b756
065ab00
9fecb60
0fe9459
04a8676
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9fecb60
064b756
9fecb60
 
08d3703
9fecb60
 
 
08d3703
9fecb60
 
 
 
 
08d3703
9fecb60
 
 
 
 
 
 
 
 
 
 
08d3703
 
 
 
 
 
064b756
08d3703
 
 
 
 
 
 
 
 
 
 
064b756
9fecb60
 
 
 
f3aa119
064b756
 
08d3703
f3aa119
9fecb60
08d3703
f3aa119
9fecb60
08d3703
f3aa119
9fecb60
08d3703
f3aa119
9fecb60
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
import whisper
from moviepy.video.io.VideoFileClip import VideoFileClip
from transformers import pipeline
import nltk
import os
import re
import random
import subprocess
from sklearn.feature_extraction.text import TfidfVectorizer
from nltk.tokenize import sent_tokenize
from nltk.corpus import stopwords

# πŸ“¦ Download NLTK data (ideally run this in setup instead of here)
nltk.download('punkt_tab')
nltk.download('stopwords')

# πŸ”„ Global models (load once)
whisper_model = whisper.load_model("tiny.en")  # Use 'base.en' for better accuracy if on GPU
summarizer = pipeline("summarization", model="t5-small", device=-1)  # Use device=0 if GPU available

# πŸ”½ Download YouTube video
def download_youtube_video(youtube_url, filename="youtube_video.mp4"):
    print(f"⬇️ Downloading YouTube video via yt-dlp: {youtube_url}")
    command = ["yt-dlp", "-f", "best[ext=mp4]+bestaudio/best", "-o", filename, youtube_url]
    result = subprocess.run(command, capture_output=True, text=True)
    if result.returncode != 0:
        raise Exception("YouTube download failed: " + result.stderr)
    return filename

# 🎧 Extract audio from video
def extract_audio(video_path):
    clip = VideoFileClip(video_path)
    audio_path = "temp_audio.wav"
    clip.audio.write_audiofile(audio_path, codec='pcm_s16le')
    return audio_path

# πŸ“ Transcribe audio using Whisper
def transcribe_audio(audio_path):
    result = whisper_model.transcribe(audio_path)
    return result["text"]

# πŸ“„ Generate summary in chunks
def generate_summary(text, default_max_len=130, default_min_len=30):
    sentences = sent_tokenize(text)
    chunks = [' '.join(sentences[i:i + 10]) for i in range(0, len(sentences), 10)]
    summary = ""

    for chunk in chunks:
        input_len = len(chunk.split())
        dynamic_max = max(20, min(default_max_len, input_len - 1))
        dynamic_min = max(10, min(default_min_len, dynamic_max - 10))

        result = summarizer(
            chunk,
            max_length=dynamic_max,
            min_length=dynamic_min,
            do_sample=False
        )[0]["summary_text"]

        summary += result + " "

    return summary.strip()

# ❓ Generate quiz
def generate_quiz(text, num_questions=5):
    sentences = sent_tokenize(text)
    tfidf = TfidfVectorizer(stop_words='english', max_features=300)
    X = tfidf.fit_transform(sentences)
    quiz = []
    used = set()

    for _ in range(num_questions):
        i = random.choice([x for x in range(len(sentences)) if x not in used])
        used.add(i)
        question = sentences[i]
        options = [question]

        while len(options) < 4:
            j = random.randint(0, len(sentences) - 1)
            if j != i and sentences[j] not in options:
                options.append(sentences[j])
        random.shuffle(options)
        quiz.append({
            "question": question,
            "options": options,
            "answer": question
        })

    return "\n\n".join([
        f"Q{i + 1}: {q['question']}\nOptions:\n" +
        "\n".join([f"{chr(65 + j)}. {opt}" for j, opt in enumerate(q['options'])])
        for i, q in enumerate(quiz)
    ])

# πŸ“Ί Subtitle formatting
def generate_subtitles(text, max_words_per_line=10):
    sentences = sent_tokenize(text)
    subtitles = []
    count = 1
    for sentence in sentences:
        chunks = [sentence[i:i + max_words_per_line] for i in range(0, len(sentence), max_words_per_line)]
        for chunk in chunks:
            subtitles.append(f"{count}. {chunk}")
            count += 1
    return "\n".join(subtitles)

# πŸ§ͺ Main processor
def process_video(video_path, selected_services):
    results = {}
    print("πŸ”§ Extracting audio...")
    audio_path = extract_audio(video_path)

    if "Transcription" in selected_services:
        transcription = transcribe_audio(audio_path)
        results["transcription"] = transcription

        if "Summary" in selected_services:
            results["summary"] = generate_summary(transcription)

        if "Subtitles" in selected_services:
            results["subtitles"] = generate_subtitles(transcription)

        if "Quiz" in selected_services:
            results["quiz"] = generate_quiz(transcription)

    return results