File size: 4,466 Bytes
3bc66db
7fcdf2d
3bc66db
 
5c3e19a
9fbf065
3bc66db
06a7ff5
3bc66db
 
 
 
 
 
 
f7cb882
68bbcdf
 
7fcdf2d
 
68bbcdf
7fcdf2d
 
 
 
 
 
68bbcdf
9deff0a
7fcdf2d
14ab511
7fcdf2d
68bbcdf
 
9deff0a
f7cb882
7fcdf2d
f7cb882
3bc66db
 
 
 
741e534
541a629
68bbcdf
14ab511
 
7fcdf2d
9deff0a
3bc66db
 
7fcdf2d
3bc66db
f44975c
3bc66db
 
5c3e19a
3bc66db
 
 
 
 
 
 
 
 
775bf34
3bc66db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bee8a86
8f5e168
e68d649
 
 
84cc5d0
aa67515
3bc66db
 
 
 
 
58464e5
3bc66db
 
afb439e
3bc66db
 
 
 
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
import gradio as gr
import os, re

from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI
from youtube_transcript_api import YouTubeTranscriptApi
from langchain.schema import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain.chains import LLMChain
from langchain.prompts.chat import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate,
)


def get_transcript(video_url):
    try:
        # Use a regular expression to extract video ID from the YouTube URL
        video_id_match = re.search(r"(?:https?://)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})", video_url)
        
        if not video_id_match:
            return "Invalid YouTube URL"
        
        video_id = video_id_match.group(1)
        
        # Fetch the transcript
        transcript = YouTubeTranscriptApi.get_transcript(video_id)

        # Join the transcript text into a single string
        text = "\n".join([t["text"] for t in transcript])
        return text  # Return the transcript as a string
        
    except Exception as e:
        return f"Error fetching transcript: Unable to fetch subtitles."


    
def create_db_from_video_url(video_url, api_key):
    """
    Creates an Embedding of the Video and performs 
    """
    embeddings = GoogleGenerativeAIEmbeddings(model="models/text-embedding-004", google_api_key=api_key)
    
    transcripts = get_transcript(video_url)
    
    # Convert transcript string into a Document
    doc_convert = Document(page_content=transcripts)

    # cannot provide this directly to the model so we are splitting the transcripts into small chunks
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
    docs = text_splitter.split_documents([doc_convert])

    db = FAISS.from_documents(docs, embedding=embeddings)
    return db

    
def get_response(video, request):
    """
    Usind Gemini Pro to get the response. It can handle upto 32k tokens.
    """
    API_KEY = os.environ.get("API_Key")
    db = create_db_from_video_url(video, API_KEY)
    docs = db.similarity_search(query=request, k=5)
    docs_content = " ".join([doc.page_content for doc in docs])

    chat = ChatGoogleGenerativeAI(model="gemini-1.5-flash", google_api_key=API_KEY, convert_system_message_to_human=True)

    # creating a template for request
    template = """
    You are an assistant that can answer questions about youtube videos based on
    video transcripts: {docs}

    Only use factual information from the transcript to answer the question.

    If you don't have enough information to answer the question, say "I don't know".

    Your Answers should be detailed.
    """

    system_msg_prompt = SystemMessagePromptTemplate.from_template(template)

    # human prompt
    human_template = "Answer the following questions: {question}"
    human_msg_prompt = HumanMessagePromptTemplate.from_template(human_template)

    chat_prompt = ChatPromptTemplate.from_messages(
        [system_msg_prompt, human_msg_prompt]
    )

    chain = LLMChain(llm=chat, prompt=chat_prompt)

    response = chain.run(question=request, docs=docs_content)

    return response

# creating title, description for the web app
title = "YouTube Video Assistant πŸ§‘β€πŸ’»"
description = "Answers to the Questions asked by the user on the specified YouTube video. (English Only).\n\n"\
"Click here to view [demo](https://huggingface.co/spaces/Kathir0011/YouTube_Video_Assistant/blob/main/README.md)."
article = "Other Projects:<br/>"\
"πŸ’° [Health Insurance Predictor](http://health-insurance-cost-predictor-k19.streamlit.app/)<br/>"\
"πŸ“° [Fake News Detector](https://fake-news-detector-k19.streamlit.app/)<br/>"\
"πŸͺΆ [Birds Classifier](https://huggingface.co/spaces/Kathir0011/Birds_Classification)"

# building the app
youtube_video_assistant = gr.Interface(
    fn=get_response,
    inputs=[gr.Text(label="Enter the Youtube Video URL:", placeholder="Example: https://www.youtube.com/watch?v=MnDudvCyWpc"),
            gr.Text(label="Enter your Question", placeholder="Example: What's the video is about?")],
    outputs=gr.TextArea(label="Answers using Gemini-1.5-flash:"),
    title=title,
    description=description,
    article=article
)

# launching the web app
youtube_video_assistant.launch()