動画をDLする

Python

最低限のテンプレート

outtmplはoutput templateの略であり、出力先のテンプレート(雛型)という意味です

import yt_dlp

# 
url = input('YOUTUBE URL: ')
file_name = input('FILE NAME: ')

# 動画をDLする
option = {
    'format': 'best',
    'outtmpl': 'C:/Users/{ユーザー名}/Downloads/' + file_name + '.%(ext)s',
}
video = yt_dlp.YoutubeDL(option).download([url])

動画をサムネ付きでDLする場合

option = {
    'writethumbnail': 'embed=thumbnail',
}

動画を最高画質でDLしたい場合

最高画質の映像ファイルと最高画質の音声ファイルを別々にDLして合成してくれます

option = {
    'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]',
    もしくは
    'format': 'bestvideo+bestaudio/best',
}

音声をDLする

‘.%(ext)s’のままにすると拡張子がwebmになる可能性があります

option = {
    'format': 'bestaudio',
    'outtmpl': 'C:/Users/{ユーザー名}/Downloads/' + file_name + '.mp3',
    'postprocessors': [
        {
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192'
        }
    ]
}

403エラー

yt_dlp.utils.DownloadError: ERROR: unable to download video data: HTTP Error 403: Forbidden
というエラーが発生する場合は、次のコマンドでyt-dlpを最新版にアップデートすること
Reference: https://manumaruscript.com/yt-dlp-http-error-403-forbidden/

pip install -U yt-dlp

Whisperエラー

UserWarning: FP16 is not supported on CPU; using FP32 instead
  warnings.warn("FP16 is not supported on CPU; using FP32 instead"
が出る場合は、GPUが使われていません
次のコマンドでGPU(CUDA)対応のtorchをインストールしてください
(※cu121はCUDA 12.xに対応しています。ご自身のGPUが古い場合はcu118に変えます)
そしてタスクマネージャーを見ながらGPUが使われていることを確認します

pip uninstall torch -y
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

pipelineエラー

ValueError: Due to a serious vulnerability issue in `torch.load`, even with `weights_only=True`, we now require users to upgrade torch to at least v2.6 in order to use the function. This version restriction does not apply when loading files with safetensors.
See the vulnerability report here https://nvd.nist.gov/vuln/detail/CVE-2025-32434
というエラーが出るかもしれません
PyTorchには脆弱性があるため、transformers(Hugging Face)を使う場合、
古いPyTorchでモデルをロードするのは禁止されています
summarizer = pipeline("summarization") の行でHuggingFaceが内部的にtorch.load()を呼び出しますが、
PyTorchのバージョンが2.6未満だとブロックされます
そのため、PyTorchをGPU(CUDA)対応のv2.6以上にアップデートします

pip install -U torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

インストール後は
print(torch.__version__)
で2.6.0になっていればOKです

2.9.0+cpu
となっている場合は、CPUしか使用しないのでアンインストールしてGPU対応に変えます
pip uninstall torch torchvision torchaudio -y
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121




その後、ImportError:
 requires the protobuf library but it was not found in your environment. Check out the instructions on the
installation page of its repo: https://github.com/protocolbuffers/protobuf/tree/master/python#installation and follow the ones        
that match your environment. Please note that you may need to restart your runtime after installation.
というエラーが出る場合は、
protobufをインストールし直します

pip uninstall protobuf -y
pip install -U protobuf

音声をダウンロードして文字起こしして要約する

pip install openai-whisper
pip install yt_dlp
pip install openai
import yt_dlp
import whisper
from openai import OpenAI


# 音声のダウンロード
url = "https://www.youtube.com/watch?v=xxx"
option = {
  "format": "bestaudio/best",
  "outtmpl": "audio.%(ext)s"
}
with yt_dlp.YoutubeDL(option) as ydl:
  info = ydl.extract_info(url, download=True)   # このファイルと同階層にaudio.webmがDLされる
  filename = ydl.prepare_filename(info)


# 文字起こし
model = whisper.load_model("base")
result = model.transcribe(filename)
text = result["text"]


# 要約
cilent = OpenAI(api_key="sk-あなたのAPIキー")
prompt = f"次の内容を日本語で要約してください:\n\n{text}"
response = client.cha.completions.create(
  model="gpt-4o-mini",
  messages=[{"role": "user", "content": prompt}]
)
summary = response.choices[0].message.content
print(summary)

openAIのAPIのアカウント開設【https://www.qbook.jp/column/2121.html

次のようなエラーが出る場合は、

openai.RateLimitError: Error code: 429 - 
{'error': {'message': 'You exceeded your current quota, please check your plan and billing details. For more information on this error, read the docs: https://platform.openai.com/docs/guides/error-codes/api-errors.',
           'type': 'insufficient_quota',
           'param': None,
           'code': 'insufficient_quota'}} 

APIキーは有効だが、課金枠(quota)がゼロになっているため新しいリクエストが拒否された

ことを意味します

OpenAIのAPIは無料枠がありません

最安のGPT-4o miniは

・入力料金100万トークンあたり$0.15ドル

・出力料金100万トークンあたり$0.60ドル

です

・GeminiAPIは無料枠が多い

・Hugging Faceの要約モデルは完全無料のAPIが多い(Hugging Face Transformersなど)(しかし日本語は苦手だし、要約スピードが遅い)

ので、Hugging Faceの要約モデルをつかってみた ↓

# pip install yt_dlp
# pip install openai-whisper
import whisper
import yt_dlp
# pip install transformers torch
from transformers import pipeline


# ==========
# 1️⃣ YouTubeから音声をダウンロード
# ==========
url = "https://www.youtube.com/watch?v=EEoBA2GMswo"

option = {
    "format": "bestaudio/best",
    "outtmpl": "audio.%(ext)s"
}

with yt_dlp.YoutubeDL(option) as ydl:
    info = ydl.extract_info(url, download=True)
    filename = ydl.prepare_filename(info)


# ==========
# 2️⃣ Whisperで文字起こし
# ==========
model = whisper.load_model("base")
result = model.transcribe(filename)
text = result["text"]

print("\n--- 文字起こし結果(抜粋)---")
print(text[:500] + "...\n")


# ==========
# 3️⃣ Hugging Faceで要約(OpenAI不要)
# ==========
print("要約中...(少し時間がかかる場合があります)")

# 要約パイプラインを準備
summarizer = pipeline("summarization", model="facebook/bart-large-cnn")

# テキストが長すぎるとエラーになるので、分割して処理
max_chunk = 1000
chunks = [text[i:i + max_chunk] for i in range(0, len(text), max_chunk)]

summaries = []
for chunk in chunks:
    summary = summarizer(chunk, max_length=200, min_length=50, do_sample=False)
    summaries.append(summary[0]['summary_text'])

final_summary = " ".join(summaries)

print("\n--- 要約結果 ---\n")
print(final_summary)

しかし、15分の動画の要約が完了するまで30分以上かかるので、使い物にならない!!!

最終盤

import os
import yt_dlp
import whisper
from transformers import pipeline

url = "https://www.youtube.com/watch?v=UWoxTPU5rvQ"
os.makedirs("download", exist_ok=True)
option = {
        'format': 'bestaudio/best',
        'outtmpl': f'download/sample.%(ext)s',
        #'cookiesfrombrowser': ('chrome',),
}
yt_dlp.YoutubeDL(option).download([url]) 
    
with yt_dlp.YoutubeDL(option) as ydl:
    info = ydl.extract_info(url, download=True)
    audio_path = ydl.prepare_filename(info)


print("\n === 文字起こし中 ===\n")

model_size="small"
model = whisper.load_model(model_size)
result = model.transcribe(audio_path)
text = result['text']

print(text)
print("\n === 要約中 ===\n")

# 多言語対応モデル(facebook/mbart-large-50-many-to-many-mmt)は50言語に対応
# ただし、要約された文章(=summary)が英語で表示される
summarizer = pipeline("summarization", model="facebook/mbart-large-50-many-to-many-mmt")

# 日本語対応モデル(sonoisa/t5-base-japanese)は英語が交じると精度が落ちる
# 英語と日本語が混在した文章を日本語で要約したい場合は、多言語対応モデルのほうがいい
#summarizer = pipeline(
#    "summarization",
#    model="sonoisa/t5-base-japanese",
#    tokenizer="sonoisa/t5-base-japanese",
#    device=0 # GPU使用
#)
max_chunk = 1000
chunks = [text[i:i+max_chunk] for i in range(0, len(text), max_chunk)]
summary = ""
for chunk in chunks:
    # 空文字や空白だけをスキップ
    if not chunk.strip():
        continue
    summary = summarizer(chunk, max_length=150, min_length=50, do_sample=False)
    summary += summary[0]['summary_text'] + " "


    
print("\n === 要約(英語) ===\n")
print(summary)

translator = pipeline(
    "translation",
    model="facebook/mbart-large-50-many-to-many-mmt",
    tokenizer="facebook/mbart-large-50-many-to-many-mmt",
    src_lang="en_XX",
    tgt_lang="ja_XX",
)
japanese_summary = translator(summary)[0]["translation_text"]

print("\n === 要約(日本語) ===\n")
print(japanese_summary)

BACK