File size: 7,132 Bytes
d37d466
 
 
 
 
07e0963
 
 
 
 
d37d466
 
07e0963
d37d466
 
 
 
 
 
 
 
 
 
 
01ab163
 
 
d37d466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
07e0963
 
 
 
 
 
 
 
 
d37d466
 
 
 
07e0963
 
1e3e045
 
07e0963
 
d37d466
 
 
 
07e0963
 
d37d466
 
38feb31
d37d466
38feb31
d37d466
 
07e0963
d37d466
 
 
 
 
ecbf455
d37d466
07e0963
d37d466
 
 
 
 
af73cff
 
d37d466
af73cff
d37d466
 
 
e1a9353
 
 
d37d466
 
 
 
 
 
 
 
 
 
 
 
 
 
e1a9353
 
 
 
 
 
 
 
 
 
d37d466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ecee8be
38feb31
d37d466
 
 
 
 
 
99bcf2e
d37d466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import streamlit as st
import tempfile
import os
import yt_dlp
from moviepy.editor import VideoFileClip

from openai import OpenAI
client = OpenAI()



# Set your OpenAI API key (make sure it's set in Hugging Face Spaces secrets)
#openai.api_key = os.getenv("OPENAI_API_KEY")

# ---------------------------
# Helper Functions
# ---------------------------
def download_video(youtube_url: str, output_path: str) -> str:
    """Download a YouTube video using yt-dlp and save it to the given output path."""
    try:
        ydl_opts = {
            'format': 'best',
            'outtmpl': os.path.join(output_path, '%(title)s.%(ext)s'),
            'noplaylist': True,
            'quiet': True,
             'cookiesfrombrowser': ('chrome',),  # Extract cookies from Chrome
            'verbose': True  # Optional: for more detailed output
        }
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(youtube_url, download=True)
            title = info.get('title', 'video')
            video_path = os.path.join(output_path, f"{title}.mp4")
            return video_path
    except Exception as e:
        st.error(f"Error downloading video: {e}")
        return None

def extract_audio(video_path: str) -> str:
    """Extract audio from the video file and save as MP3."""
    try:
        # Sanitize filename if needed (e.g., replace problematic characters)
        safe_video_path = video_path.replace("|", "_").replace(":", "_")
        clip = VideoFileClip(safe_video_path)
        audio_path = safe_video_path.replace(".mp4", ".mp3")
        clip.audio.write_audiofile(audio_path, codec='mp3')
        clip.close()
        return audio_path
    except Exception as e:
        st.error(f"Error extracting audio: {e}")
        return None

# audio_file = open("/path/to/file/speech.mp3", "rb")
# transcription = client.audio.transcriptions.create(
#   model="whisper-1", 
#   file=audio_file, 
#   response_format="text"
# )

# print(transcription.text)

def transcribe_audio(audio_path: str) -> str:
    """Transcribe the audio to text using OpenAI's Whisper API."""
    try:
        with open(audio_path, "rb") as audio_file:
            transcript = client.audio.transcriptions.create(
                      model="whisper-1", 
                      file=audio_file 
                      #response_format="text"
                    )
        return transcript.text
    except Exception as e:
        st.error(f"Error transcribing audio: {e}")
        return ""



def generate_summary(transcript_text: str) -> str:
    """Generate a concise summary of the transcript using OpenAI."""
    prompt = f"Summarize the following video transcript in a concise manner, highlighting the key points that the user should know:\n\n{transcript_text}. Feel free to use bullet points, bold, italics and headers to empasize key points where necessary"
    messages = [
        {"role": "system", "content": "You are an helpful assistant."},
        {"role": "user", "content": prompt}
    ]
    completion = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
    return completion.choices[0].message.content.strip()

def get_chat_response(transcript_text: str, conversation_history: list, user_query: str) -> str:
    """Generate a chat response using the transcript as context."""
    messages = conversation_history + [
        {"role": "user", "content": f"Based on the video transcript:\n\n{transcript_text}\n\nQuestion: {user_query}"}
    ]
    completion = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
    return completion.choices[0].message.content.strip()

# ---------------------------
# Sidebar: Input Options
# ---------------------------
#st.sidebar.title("Video Input Options")
st.sidebar.title("Upload a video")

input_mode = st.sidebar.radio("Select Input Type", ("Upload Video")) #, "YouTube URL"))

transcript_text = ""
if input_mode == "Upload Video":
    uploaded_video = st.sidebar.file_uploader("Upload a video file (MP4)", type="mp4")
# elif input_mode == "YouTube URL":
#     youtube_url = st.sidebar.text_input("Enter YouTube video URL:")

# ---------------------------
# Process Video Input
# ---------------------------
if input_mode == "Upload Video" and uploaded_video is not None:
    with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp:
        tmp.write(uploaded_video.read())
        video_path = tmp.name
    st.sidebar.success("Video uploaded successfully!")
    audio_path = extract_audio(video_path)
    if audio_path:
        transcript_text = transcribe_audio(audio_path)
        if transcript_text:
            st.sidebar.success("Audio transcribed successfully!")
# elif input_mode == "YouTube URL" and youtube_url:
#     with tempfile.TemporaryDirectory() as temp_dir:
#         video_path = download_video(youtube_url, temp_dir)
#         if video_path:
#             st.sidebar.success("Video downloaded successfully!")
#             audio_path = extract_audio(video_path)
#             if audio_path:
#                 transcript_text = transcribe_audio(audio_path)
#                 if transcript_text:
#                     st.sidebar.success("Audio transcribed successfully!")

if transcript_text:
    st.session_state.transcript_text = transcript_text

# ---------------------------
# Sidebar: Action Selection
# ---------------------------
st.sidebar.title("Select Action")
action_mode = st.sidebar.radio("Choose Action", ("Summary", "Chat"))

# ---------------------------
# Session State Initialization for Chat
# ---------------------------
if "chat_history" not in st.session_state:
    st.session_state.chat_history = [{"role": "assistant", "content": "Hi, how can I help you with the video content?"}]

# ---------------------------
# Main Display Area
# ---------------------------
st.title("Video Chat")
st.write('Tired of watching long boring videos? Summarize your videos in seconds or just chat!')

if "transcript_text" not in st.session_state or not st.session_state.transcript_text:
    st.info("Please provide a video input from the sidebar to begin.")
else:
    transcript_text = st.session_state.transcript_text
    if action_mode == "Summary":
        #st.header("Summary & Key Points")
        with st.spinner("Generating summary..."):
            summary = generate_summary(transcript_text)
        st.write(summary)
    elif action_mode == "Chat":
        st.header("Chat with Your Study Companion")
        for msg in st.session_state.chat_history:
            st.chat_message(msg["role"]).write(msg["content"])
        user_query = st.chat_input("Ask a question about the video content:")
        if user_query:
            st.session_state.chat_history.append({"role": "user", "content": user_query})
            st.chat_message("user").write(user_query)
            with st.spinner("Processing your question..."):
                response = get_chat_response(transcript_text, st.session_state.chat_history, user_query)
            st.session_state.chat_history.append({"role": "assistant", "content": response})
            st.chat_message("assistant").write(response)