Youtube AI helper - transkrypcja audio z Whisper

Dowiedz się, jak wyekstraktować audio z filmu YouTube i automatycznie zamienić je na tekst z timestampami używając bibliotek yt_dlp i Whisper od OpenAI. Pierwszy krok do budowania narzędzi AI dla twórców wideo.
python
ai
youtube
whisper
Author

De. Os.

Published

March 20, 2026

Youtube AI helper.

Nikomu nie trzeba przedstawiać youtube. Platformę codziennie ogląda miliony użytkowników, a po pandemii Covid, wiele osób zamieniło tradycyjną telewizję na platformę, której właścicielem jest google.

Jest to ogromna skarbnica wiedzy, rozrywki i opinii. Nic więc dziwnego, że kiedy twórcy chatbotów LLM nakarmili je całą wiedzą tekstową dostępną w internecie, śmiało ruszyli po wiedzę dostępną w filmach youtube. Śmiem twierdzić, że mógł to być jeden z powodów powstania biblioteki whisper.

Ten projekt dedykuję twórcom filmów youtube. Pokażę, jak za pomocą pythona i AI można stworzyć dla filmu spis treści, napisy, dubbing, shortsy, tytuł i opis SEO, a także miniaturkę idealnie pasującą do filmu.

Whisper - daj AI moc słuchania.

Whisper to biblioteka od firmy OpenAI, która pozwala na transkrypcję plików dźwiękowych. Dzięki niej możemy tworzyć podsumowania naszych spotkań, ale też ekstraktować tekst z jakiegokolwiek pliku audio. Dzięki temu, że oprócz tekstu otrzymujemy timestampy, możemy wykorzystać ją do tworzenia spisów treści, kreowania shortsów z pełnego pliku wideo, czy tworzyć napisy do naszych filmów.

Krok 1 - Ekstrakcja audio i transkrypcja tekstu.

Zanim jednak wykorzystamy moc AI, najpierw potrzebujemy wyekstraktować dźwięk z naszego filmu wideo, a potem zrobić transkrypcję.

Oprócz wspomnianego już whispera, użyję tutaj biblioteki yt_dlp - która jest rozbudowaną biblioteką open source zbudowaną na oficjalnej youtube API i pozwala między innymi na ekstrakcę audio.

Do dzieła!

# import i instalacja bibliotek
# zainstaluj biblioteki za pomocą pip install yt_dlp whisper-openai
import yt_dlp
import whisper
from datetime import datetime
def extract_sound_from_youtube(url, out_f_name):
    """Extract and save audio from given youtube url"""
    ydl_opts = {
        'format': 'bestaudio/best',
        'outtmpl': f'{out_f_name}_audio.%(ext)s',
        'http_headers': {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        },
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
        }],
    }
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.download([url])

def transcribe(audio_file, lang="pl", verbose=False):
    """Transkript text from audio file"""
    model = whisper.load_model("medium", device="cuda")  # użyje GPU
    result = model.transcribe(audio_file, language=lang, verbose=verbose)  # force polish
    return result
# Ekstrakcja audio z youtube
extract_sound_from_youtube(youtube_url, out_f_name)

# Transkrypcja wyekstraktowanego audio
audio_file = f"{out_f_name}_audio.mp3"
transkrypcja = transcribe(audio_file, lang="en")
[youtube] Extracting URL: https://www.youtube.com/watch?v=q6ErZWARhcY
[youtube] q6ErZWARhcY: Downloading webpage
WARNING: [youtube] No supported JavaScript runtime could be found. Only deno is enabled by default; to use another runtime add  --js-runtimes RUNTIME[:PATH]  to your command/config. YouTube extraction without a JS runtime has been deprecated, and some formats may be missing. See  https://github.com/yt-dlp/yt-dlp/wiki/EJS  for details on installing one
[youtube] q6ErZWARhcY: Downloading android vr player API JSON
[info] q6ErZWARhcY: Downloading 1 format(s): 251
[download] Destination: msaylor_interview_audio.webm
[download] 100% of   14.97MiB in 00:00:01 at 13.82MiB/s    
[ExtractAudio] Destination: msaylor_interview_audio.mp3
Deleting original file msaylor_interview_audio.webm (pass -k to keep)
100%|██████████| 105513/105513 [00:28<00:00, 3673.80frames/s]
# zobaczymy co mamy w transkrypcji
transkrypcja.keys()
dict_keys(['text', 'segments', 'language'])
def seconds_to_timestamp(seconds: float) -> str:
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = int(seconds % 60)
    
    if hours > 0:
        return f"{hours}:{minutes:02d}:{secs:02d}"
    return f"{minutes}:{secs:02d}"

# Przykład:
seconds_to_timestamp(3723.5)  # "1:02:03"
seconds_to_timestamp(323.5)   # "5:23"

def save_transkript(transkrypcja, output_file, verbose=True):
    """SAving transcription to file and disply if verbose = True"""
    lines = []
    for segment in transkrypcja["segments"]:
        start = segment["start"]  # sekundy
        end = segment["end"]
        text = segment["text"]
        line = f"[{seconds_to_timestamp(start)} - {seconds_to_timestamp(end)}]\n {text}\n\n"
        lines.append(line)
        if verbose:
            print(line)
    with open(output_file, mode="w") as f:
        f.writelines(lines)
        
    
save_transkript(transkrypcja, "agent_md_file.txt", verbose=False)
# sprawdźmy kilka linii z pliku z transkrypcją
with open("agent_md_file.txt", "r") as f:
    lines = f.readlines(500)

    for line in lines:
        print(line)
[0:00 - 0:09]

  And so when you start to understand the impact of technology as metallic money on economic networks



[0:10 - 0:17]

  and then the impact of a ship with guns on it, on that economic network or the impact of



[0:18 - 0:25]

  not having immunity to all the germs the Europeans brought or the impact of not having steel and



[0:25 - 0:30]

  being stuck in the stone age, all of those things have an impact on the way the world evolved. And



[0:30 - 0:47]

  I think Bitcoin is crossing every one of those fields right now. Hey guys, welcome to Everyday

Podsumowanie i następne kroki.

Udało się nam wyekstraktować tekst z filmu. Tekst jest podstawą pracy z dzisiejszą AI. AI czyli LLMy są stworzone do pracy z tekstem, a to oznacza, że mając narzędzie które pozwala zamienić dźwięk na tekst możemy z nim zrobić na prawdę wiele.

To oznacza, że ten notatnik może być wstępem do wielu narzędzi, dlatego nie dodaję już nic innego tutaj - w ten sposób każdy może go użyć do własnych celów.