Spaces:
Sleeping
Sleeping
File size: 5,805 Bytes
9451c89 fff2596 9451c89 2f90f69 fff2596 9451c89 | 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 |
import streamlit as st
from dotenv import load_dotenv
import os
import google.generativeai as genai
from youtube_transcript_api import YouTubeTranscriptApi #Used to fetch the transcript of a YouTube video.
from urllib.parse import urlparse, parse_qs #Used to extract the video ID from a YouTube URL.
import time
# Load environment variables
load_dotenv()
# Configure Gemini AI
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
# Page Configuration
st.set_page_config(page_title="YouTube AI Notes", page_icon="π", layout="wide")
# Sidebar
with st.sidebar:
st.title("π Menu")
st.subheader("π― How It Works")
st.markdown("""
1. **Copy the YouTube Video Link** (Right-click & select 'Copy link')
2. **Paste the link & click 'Generate AI Notes'**
3. **AI extracts the transcript** π₯
4. **Generates concise, structured notes**π
""")
# st.subheader("π Why Copy Link Address?")
# st.markdown("""
# - **Pasting the URL directly from the address bar might not work.**
# - **Why?** Because YouTube URLs contain extra parameters (like playlists or timestamps) that can break the extraction process.
# - **Solution?** Always **right-click the video & select 'Copy link address'** before pasting. β
# """)
st.subheader("π©βπ» About the Creator")
st.markdown("""
**Prarthana** β AI Enthusiast & Data Scientist in the making.
- Follow me on [GitHub](https://github.com/Prarthana-Singh)
- Connect on [LinkedIn](https://linkedin.com/in/prarthanasingh)
""")
# Custom CSS for Styling
st.markdown("""
<style>
body {
background-color: #121212;
color: #FFFFFF;
}
.title {
font-size: 40px;
font-weight: bold;
text-align: center;
color: #F4D03F;
}
.stTextInput>div>div>input {
background-color: #1E1E1E;
color: #FFFFFF;
border-radius: 8px;
padding: 10px;
}
.stButton>button {
background-color: #F4D03F;
color: black;
font-weight: bold;
border-radius: 8px;
padding: 10px 20px;
}
.stButton>button:hover {
background-color: #FFD700;
}
.summary-card {
background-color: #1E1E1E;
padding: 15px;
border-radius: 10px;
box-shadow: 0px 4px 10px rgba(255, 255, 255, 0.2);
}
.footer {
text-align: center;
font-size: 14px;
color: #AAAAAA;
}
</style>
""", unsafe_allow_html=True)
# Extract Video ID from YouTube URL
# def extract_video_id(youtube_url):
# parsed_url = urlparse(youtube_url) # ParseResult(scheme='https', netloc='www.youtube.com', path='/watch', params='', query='v=O0GNrvO7wD0', fragment='')
# video_id = parse_qs(parsed_url.query).get("v")
# return video_id[0] if video_id else None
def extract_video_id(video_url):
parsed_url = urlparse(video_url) # URL ko parse karna
query_params = parse_qs(parsed_url.query) # Query parameters extract karna
# β
Try to get video ID from "v"
video_id = query_params.get("v", [None])[0]
# β
If "v" is not found, check for "si" (shortened URL case)
if not video_id and "youtu.be" in parsed_url.netloc:
video_id = parsed_url.path.lstrip("/") # Remove leading "/"
return video_id
# Fetch YouTube Transcript
def extract_transcript_details(video_id):
try:
transcript_text = YouTubeTranscriptApi.get_transcript(video_id)
return " ".join([i["text"] for i in transcript_text])
except Exception:
return None
# Generate Summary with Gemini AI
def generate_gemini_content(transcript_text):
prompt = """You are an AI-based YouTube video summarizer.
Extract key points from the transcript and summarize the video into concise, structured notes within 250 words. Here is the transcript:\n"""
model = genai.GenerativeModel("gemini-2.0-flash")
response = model.generate_content(prompt + transcript_text)
return response.text
# UI Layout
st.markdown("<div class='title'>YouTube AI Notes Converter</div>", unsafe_allow_html=True)
st.markdown("π₯ **Convert YouTube Videos into AI-generated Notes!**")
# Copy Link Address Warning
st.warning("β οΈ **Important:** Always 'Copy Link' from YouTube before pasting!")
youtube_link = st.text_input("π Enter YouTube Video Link:")
if youtube_link:
video_id = extract_video_id(youtube_link)
if video_id:
st.image(f"http://img.youtube.com/vi/{video_id}/0.jpg", use_container_width=True)
else:
st.error("β οΈ Invalid YouTube link! Please enter a correct URL.")
# Button to Generate Notes
if st.button("β¨ Generate AI Notes"):
if not youtube_link:
st.warning("π΄ Please enter a valid YouTube link.")
elif not video_id:
st.error("β οΈ Could not extract video ID. Please check the URL.")
else:
with st.spinner("π Fetching transcript and generating notes..."):
time.sleep(2)
transcript_text = extract_transcript_details(video_id)
if not transcript_text:
st.error("β Transcripts are disabled for this video.")
else:
with st.spinner("β¨ AI is summarizing the video..."):
time.sleep(2)
summary = generate_gemini_content(transcript_text)
st.markdown("<div class='summary-card'><h2>π AI-Generated Notes:</h2>", unsafe_allow_html=True)
st.write(summary)
st.markdown("</div>", unsafe_allow_html=True)
# Footer
st.markdown("<div class='footer'>β¨ Made with β€οΈ by Prarthana β¨</div>", unsafe_allow_html=True)
|