Spaces:
Runtime error
Runtime error
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)
|