YouTube is the homepage of video content, but it's also filled with clickbait—titles designed to entice viewers but often fail to deliver on their promises.

As clickbait continues to thrive, it becomes increasingly challenging for users to discern if a video’s title genuinely reflects its content.

This article walks you through building a YouTube Clickbait Checker using AI to analyze YouTube video titles against the actual content of the video.

The application transcribes the video, compares the title with the transcript, and calculates a clickbait probability score.

0:00
/0:00

YouTube Clickbait Checker web application in action


And here is the final product live:

Is It Clickbait?
Check if a YouTube video is clickbait

Goals

The goals for this web applications are quite simple:

  • Download YouTube videos and extract their audio.
  • Transcribe the audio using Deepgram's Speech-to-Text API.
  • Analyze the title against the transcript using Mistral AI to evaluate the likelihood of clickbait.
  • Display the clickbait score in a simple web interface.

Tech Stack

In terms of tech stack, we will also keep it simple and create a single backend in Flask and just simple HTML with Javascript for the frontend.

Backend:

  • Flask for the web framework.
  • yt-dlp for downloading YouTube videos and extracting audio.
  • Deepgram API for transcribing video audio into text. You can signup to Deepgram for free and receive $200 of credits without credit card.
  • Mistral AI to analyze the correlation between the video title and transcript. You will need access to an API Key.

Frontend:

  • HTML/CSS/JavaScript to create a user interface that allows input of YouTube URLs and display results.

Ready to enhance your coding skills?

Check out Developer Service Blog Courses for beginner-friendly lessons on core programming concepts and Python.

Start learning today and build your path to becoming a confident developer! 🚀


Application Architecture

The architecture of the app can be broken down into several key components:

  • Frontend: A simple HTML page where users input the YouTube URL. The form submission triggers an API call to the backend.
  • Backend: The Flask server handles the following tasks:
    • Download the YouTube video using yt-dlp.
    • Extract audio from the video and pass it to the Deepgram API for transcription.
    • Compare the transcript with the video title using the Mistral AI model.
    • Calculate and return a clickbait score based on the comparison.
  • AI Models: Mistral AI is used to analyze the relevance of the video title with the content provided by the transcript.

Step-by-Step Guide

Step 1: Setting Up the Project Structure

Your project should have the following structure:

/project-folder
    /templates
        index.html
    app.py
    deepgram_wrapper.py
    mistral_wrapper.py
  • index.html: Contains the frontend of the application.
  • app.py: Main Flask application that handles routing and API logic.
  • deepgram_wrapper.py: Contains the logic for interacting with the Deepgram API.
  • mistral_wrapper.py: Contains the logic for Mistral AI model integration.

You will also need to install the following requirements:

pip install Flask deepgram-sdk python-decouple mistralai Jinja2 

And make sure to create and .env file with the API Keys:

# DEEPGRAM API
DEEPGRAM_API_KEY=<YOUR_DEEPGRAM_API_KEY>

# MISTRAL API
MISTRAL_API_KEY=<YOUR_MISTRAL_API_KEY>
MISTRAL_MODEL=mistral-small-2409

Step 2: Frontend HTML (index.html)

The frontend is a simple HTML page that allows users to input a YouTube video URL and submit the form.

Upon submission, it sends an API request to the backend.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Clickbait Checker</title>
</head>
<body>
    <h1>YouTube Clickbait Checker</h1>
    <form id="clickbaitForm">
        <label for="video_url">YouTube Video URL:</label>
        <input type="text" id="video_url" name="video_url" required size="100S"><br><br>

        <input type="submit" value="Check Clickbait">
    </form>

    <div id="result"></div>

    <script>
        document.getElementById('clickbaitForm').addEventListener('submit', async (e) => {
            e.preventDefault();

            const video_url = document.getElementById('video_url').value;
            document.getElementById('result').innerHTML = "<hr><p>Loading...</p>";
            const response = await fetch('/check_clickbait', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ video_url }),
            });

            const result = await response.json();
            document.getElementById('result').innerHTML =
                "<hr>" +
                "<h2>Result</h2>" +
                "<p><strong>Clickbait Score:</strong> " + result.clickbait_score + "%</p>" +
                "<p><strong>Reason:</strong> " + result.reason + "</p>";
        });
    </script>
</body>
</html>

This page provides an input form where users submit a YouTube URL.

The JavaScript fetches the backend API results and displays them.


Step 3: Backend Code (app.py)

The backend uses Flask to handle incoming requests, download YouTube videos, and perform analysis.

Here’s a breakdown of the Flask app (app.py):

import os
import yt_dlp
from flask import Flask, request, jsonify, render_template
from deepgram import DeepgramClient
from deepgram_wrapper import transcribe_audio_from_url
from mistral_wrapper import run_mistral

# Initialize the app
app = Flask(__name__)

# Set up the Deepgram API key (replace with your own)
DEEPGRAM_API_KEY = 'your_deepgram_api_key'
dg_client = DeepgramClient(DEEPGRAM_API_KEY)


# Function to download YouTube video using yt-dlp
def download_audio(url):
    ytdlp_options = {
        'format': 'bestaudio/best',
        'outtmpl': 'audio.%(ext)s',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'wav',
            'preferredquality': '192',
        }],
    }
    # Download the audio file
    with yt_dlp.YoutubeDL(ytdlp_options) as ydl:
        ydl.download([url])
    # Get title of the video
    video_info = ydl.extract_info(url, download=False)
    video_title = video_info['title']
    # Return the file path
    return 'audio.wav', video_title


# Function to transcribe audio using Deepgram
async def transcribe_audio(file_path):
    transcription, error = transcribe_audio_from_url(file_path)
    return transcription, error


# Function to analyze content using Mistral
async def analyze_content(content, title):
    analysis, error = run_mistral(content, title)
    return analysis, error


# Route to serve the index.html page
@app.route('/')
def home():
    return render_template('index.html')


# Endpoint to check for clickbait
@app.route('/check_clickbait', methods=['POST'])
async def check_clickbait():
    data = request.json
    video_url = data['video_url']

    # Download the video and extract audio
    print('Downloading audio...')
    audio_file_path, video_title = download_audio(video_url)
    print(f'Video title: {video_title}')

    # Transcribe the audio
    print('Transcribing audio...')
    transcript, error = await transcribe_audio(audio_file_path)
    print(f'Transcript: {transcript[:100]}...')

    # Use the AI model to analyze the title against the transcript
    print('Analyzing content...')
    analysis_result, error = await analyze_content(transcript, video_title)
    print(f'Analysis result: {analysis_result}')

    # Clean up downloaded audio file
    os.remove(audio_file_path)

    # Return the analysis as a percentage of clickbait likelihood
    clickbait_score = analysis_result['clickbait_score'] * 100
    reason = analysis_result['reason']
    return jsonify({'clickbait_score': clickbait_score, 'reason': reason})


if __name__ == '__main__':
    app.run(debug=True)

This file defines two key routes:

  • Home Route (/): Returns the index HTML page.
  • Clickbait Checker API (/check_clickbait): Downloads the YouTube video, transcribes the audio, and checks the clickbait score using AI.

Step 4: Integrating Deepgram (deepgram_wrapper.py)

To convert the audio into text, we use the Deepgram API.

Here’s the logic to transcribe audio files using Deepgram:

import os
import httpx
from decouple import config
from deepgram import DeepgramClient, PrerecordedOptions, FileSource

# Load your Deepgram API key from an environment variable
API_KEY = config("DEEPGRAM_API_KEY")

# Create a Deepgram client using the API key
deepgram = DeepgramClient(API_KEY)


# Function to transcribe an audio file
def transcribe_audio_from_url(audio_url: str):
    try:
        # Configure Deepgram options for audio analysis
        options = PrerecordedOptions(
            model="nova-2",
            smart_format=True,
            diarize=True,
        )

        # Call the transcribe_file method on the prerecorded class
        with open(audio_url, "rb") as file:
            buffer_data = file.read()

        payload: FileSource = {
            "buffer": buffer_data,
        }

        # Call the transcribe_url method with the audio payload and options
        file_response = deepgram.listen.rest.v("1").transcribe_file(payload, options)

        # Convert the response to a dictionary
        response_dict = file_response.to_dict()

        # Extract the transcription from the response
        transcript = response_dict["results"]["channels"][0]["alternatives"][0]["transcript"]

        # Return the transcription
        return transcript, None

    except Exception as e:
        print(f"Exception: {e}")
        return None, str(e)

This script is designed to transcribe audio files using the Deepgram API:

  • Loads Deepgram API key securely using decouple and initializes a client.
  • Transcribes audio by reading the file, applying options like speaker diarization and smart formatting, and sending it to the Deepgram API.
  • Extracts and returns the transcription, with error handling for any issues during the process.

Step 5: Analyzing Title with Mistral (mistral_wrapper.py)

Mistral is used to compare the video title with the transcript to calculate how much the title reflects the content.