0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonでyt-dlpを使ってYouTube音声を高品質に抽出する実践ガイド【バッチ処理・WAV/FLAC・エラーハンドリング付き・2026年版】

0
Posted at

YouTube から音声を抽出したいとき、ブラウザのオンラインツールでは「1ファイルずつ」「128kbps MP3のみ」「広告だらけ」という制限に直面することが多いです。Pythonスクリプトでyt-dlpを使えば、プレイリスト一括処理・WAV/FLAC高品質出力・エラー自動リトライが全て自動化できます。

この記事では、yt-dlpのPythonライブラリとしての使い方を実践的にまとめます。コマンドライン基礎から始め、バッチ処理・フォーマット制御・認証動画の取得まで、そのまま使えるコードブロック付きで解説します。

ブラウザやGUIで手軽に済ませたい場合は YouTubeから音声を抽出する方法7選(ブラウザ〜CLI) にまとめています。

yt-dlpとは?なぜ最善の選択か?

結論:yt-dlpはyoutube-dlのアクティブなフォーク版で、2026年現在も活発にメンテナンスされている唯一の信頼できるYouTube音声抽出ライブラリです。

ライブラリ 状態(2026年) 最大品質 Python API
yt-dlp ✅ 活発にメンテナンス中 WAV / FLAC / 320kbps MP3
youtube-dl ⚠️ 更新停滞(非推奨) MP3
pytube / pytubefix ⚠️ 頻繁に壊れる MP4のみ(音声別途抽出要)
moviepy ❌ ラッパーのみ MP3 / WAV(低効率)

yt-dlpがyoutube-dl・pytube・moviepyより優れている理由は、YouTube APIの変更に追随するスピードが圧倒的に速いためです。pytube系は数ヶ月に一度「突然動かなくなる」現象が起きますが、yt-dlpは数日以内に修正されます。

インストール

pip install yt-dlp
# ffmpegも必要(フォーマット変換に使用)
# macOS
brew install ffmpeg
# Ubuntu/Debian
sudo apt install ffmpeg
# Windows: https://ffmpeg.org/download.html

バージョン確認:

yt-dlp --version
# 2026.xx.xx

コマンドラインでの基本的な音声抽出(おさらい)

# MP3(320kbps)
yt-dlp -x --audio-format mp3 --audio-quality 0 "URL"

# WAV(可逆)
yt-dlp -x --audio-format wav "URL"

# FLAC(可逆圧縮)
yt-dlp -x --audio-format flac "URL"

--audio-quality 0 は最高ビットレートを指定します(MP3の場合は320kbps)。

次のセクションから、Pythonスクリプトとして組み込む方法を説明します。

PythonスクリプトからYDL(YoutubeDL)クラスを使う

yt-dlpはコマンドラインツールですが、yt_dlp.YoutubeDL クラスを直接インポートしてPythonから制御できます。

シンプルなMP3抽出

import yt_dlp

def extract_audio_mp3(url: str, output_dir: str = ".") -> str:
    """YouTube URLからMP3(320kbps)を抽出してファイルパスを返す。"""
    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": f"{output_dir}/%(title)s.%(ext)s",
        "postprocessors": [
            {
                "key": "FFmpegExtractAudio",
                "preferredcodec": "mp3",
                "preferredquality": "320",
            }
        ],
        "quiet": True,
    }
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=True)
        title = info.get("title", "audio")
        return f"{output_dir}/{title}.mp3"

if __name__ == "__main__":
    path = extract_audio_mp3("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
    print(f"保存先: {path}")

WAV(可逆)抽出

import yt_dlp
from pathlib import Path

def extract_audio_wav(url: str, output_dir: str = ".") -> Path:
    """YouTube URLからWAV(可逆)を抽出してPathを返す。"""
    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": f"{output_dir}/%(id)s.%(ext)s",
        "postprocessors": [
            {
                "key": "FFmpegExtractAudio",
                "preferredcodec": "wav",
            }
        ],
        "quiet": True,
    }
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=True)
        video_id = info["id"]
        return Path(output_dir) / f"{video_id}.wav"

YouTubeの音声はOpus(最大160kbps)またはAAC(最大256kbps)でエンコードされています。WAVやFLACで保存しても、元データがそのビットレートのため「可逆」ではなく「再エンコードなし」の意味です。実質的な上限は元ストリームの品質です。

バッチ処理:複数URLを一括抽出

URLリストをファイルから読み込んで一括処理する実装です。

import yt_dlp
from pathlib import Path

def batch_extract(urls: list[str], output_dir: str = "downloads") -> dict[str, str]:
    """
    複数URLから音声を一括抽出する。
    戻り値: {url: 保存先パス or エラーメッセージ}
    """
    Path(output_dir).mkdir(exist_ok=True)
    results: dict[str, str] = {}

    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": f"{output_dir}/%(id)s.%(ext)s",
        "postprocessors": [
            {
                "key": "FFmpegExtractAudio",
                "preferredcodec": "mp3",
                "preferredquality": "320",
            }
        ],
        "quiet": True,
        "ignoreerrors": True,  # 1本失敗しても続行
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        for url in urls:
            try:
                info = ydl.extract_info(url, download=True)
                if info:
                    video_id = info["id"]
                    results[url] = str(Path(output_dir) / f"{video_id}.mp3")
                else:
                    results[url] = "ERROR: extract_info returned None"
            except Exception as e:
                results[url] = f"ERROR: {e}"

    return results


if __name__ == "__main__":
    urls = [
        "https://www.youtube.com/watch?v=VIDEO_ID_1",
        "https://www.youtube.com/watch?v=VIDEO_ID_2",
        "https://www.youtube.com/watch?v=VIDEO_ID_3",
    ]
    results = batch_extract(urls, output_dir="my_audio")
    for url, result in results.items():
        print(f"{url}{result}")

プレイリスト全曲を一括抽出

import yt_dlp

def extract_playlist(playlist_url: str, output_dir: str = "playlist") -> None:
    """YouTubeプレイリストの全曲を音声抽出する。"""
    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": f"{output_dir}/%(playlist_index)02d_%(title)s.%(ext)s",
        "postprocessors": [
            {
                "key": "FFmpegExtractAudio",
                "preferredcodec": "mp3",
                "preferredquality": "320",
            }
        ],
        "ignoreerrors": True,
        "quiet": False,  # プレイリストは進捗を表示
    }
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.download([playlist_url])


if __name__ == "__main__":
    extract_playlist(
        "https://www.youtube.com/playlist?list=PLAYLIST_ID",
        output_dir="my_playlist"
    )

%(playlist_index)02d でゼロパディングしたトラック番号をファイル名に付与します(例:01_曲名.mp3)。

フォーマット指定の詳細設定

yt-dlpのフォーマット指定文字列は非常に柔軟です。

# 利用可能なフォーマット一覧を取得(ダウンロードなし)
import yt_dlp
import json

with yt_dlp.YoutubeDL({"quiet": True}) as ydl:
    info = ydl.extract_info("URL", download=False)
    for fmt in info.get("formats", []):
        if fmt.get("acodec") != "none":
            print(f"ID={fmt['format_id']} | codec={fmt.get('acodec')} | abr={fmt.get('abr')}kbps | ext={fmt['ext']}")

よく使うフォーマット指定パターン:

目的 format 指定
最高品質音声(自動) "bestaudio/best"
Opusのみ(最軽量) "bestaudio[ext=webm]"
AACのみ "bestaudio[acodec=mp4a.40.2]"
最大160kbps以下 "bestaudio[abr<=160]"

フォーマット指定後に最高音質のOpus → WAVが最高品質ルートになります。Opusは元データに最も近い形式でYouTubeから配信されます。

エラーハンドリングとリトライ

ネットワークエラーや削除済み動画への対処:

import yt_dlp
import time
import logging

logger = logging.getLogger(__name__)

def extract_with_retry(url: str, output_dir: str = ".", max_retries: int = 3) -> str | None:
    """エラー時に最大max_retries回リトライする音声抽出。"""
    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": f"{output_dir}/%(id)s.%(ext)s",
        "postprocessors": [
            {"key": "FFmpegExtractAudio", "preferredcodec": "mp3", "preferredquality": "320"}
        ],
        "retries": 3,          # yt-dlp組み込みリトライ
        "fragment_retries": 3,
        "quiet": True,
    }

    for attempt in range(1, max_retries + 1):
        try:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                info = ydl.extract_info(url, download=True)
                return f"{output_dir}/{info['id']}.mp3"
        except yt_dlp.utils.DownloadError as e:
            if "Video unavailable" in str(e) or "Private video" in str(e):
                logger.warning(f"スキップ(削除/非公開): {url}")
                return None  # リトライ不要
            if attempt < max_retries:
                wait = 2 ** attempt  # 指数バックオフ
                logger.warning(f"試行 {attempt}/{max_retries} 失敗。{wait}秒後にリトライ: {e}")
                time.sleep(wait)
            else:
                logger.error(f"最大リトライ数到達: {url}{e}")
                return None
    return None

年齢制限・ログインが必要な動画の取得

cookieをブラウザからエクスポートして使用します:

# Chrome/Firefoxのcookieをエクスポート(ブラウザでYouTubeにログイン済みであること)
yt-dlp --cookies-from-browser chrome -x --audio-format mp3 "URL"

Pythonから:

import yt_dlp

ydl_opts = {
    "format": "bestaudio/best",
    "cookiesfrombrowser": ("chrome",),  # または ("firefox",)
    "outtmpl": "%(id)s.%(ext)s",
    "postprocessors": [
        {"key": "FFmpegExtractAudio", "preferredcodec": "mp3", "preferredquality": "320"}
    ],
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download(["URL"])

メタデータのみ取得(ダウンロードなし)

曲タイトル・アーティスト・長さなどのメタデータだけ取得したい場合:

import yt_dlp

def get_metadata(url: str) -> dict:
    """ダウンロードせずにメタデータのみ取得する。"""
    with yt_dlp.YoutubeDL({"quiet": True}) as ydl:
        info = ydl.extract_info(url, download=False)
        return {
            "id": info.get("id"),
            "title": info.get("title"),
            "uploader": info.get("uploader"),
            "duration": info.get("duration"),   # 秒
            "view_count": info.get("view_count"),
            "upload_date": info.get("upload_date"),
        }

meta = get_metadata("https://www.youtube.com/watch?v=VIDEO_ID")
print(meta)

音声抽出後にAIステム分離を行う場合

抽出した音声からボーカルとインストゥルメンタルを分離したい場合は、以前の記事「yt-dlp + AI音源分離パイプライン」 をご参照ください。Demucs htdemucsを使ったPython実装をそのまま使えます。

ノーコードで手軽に試したい場合は StemSplit YouTube Stem Splitter でURLを貼り付けるだけで音声抽出 → ステム分離が完結します。

比較まとめ

方法 バッチ処理 最大品質 ログイン対応 Python統合
yt-dlp CLI WAV/FLAC ✓(subprocess)
yt-dlp Python API WAV/FLAC ✓(ネイティブ)
pytube / pytubefix △(手動ループ) MP4音声のみ
moviepy MP3/WAV
StemSplit API MP3 320kbps - ✓(REST)

yt-dlpのPython APIは最も機能が揃っており、CLIと全く同じ機能をスクリプト内で利用できます。

ブラウザでの手軽な方法や他のツール(VLC、4K Video Downloader、モバイルアプリ等)については YouTubeから音声を抽出する7つの方法まとめ をご覧ください。

よくある質問

yt-dlpのPython APIとCLIは何が違いますか?

結論:機能は同一です。CLIはシェルからの直接実行向けで、Python APIはスクリプト・アプリへの組み込み向けです。同じYoutubeDLクラスをどちらも使用します。

yt-dlpが突然動かなくなった場合は?

結論:まず pip install -U yt-dlp で最新版に更新してください。YouTubeがAPIを変更した際、yt-dlpは数日以内に対応します。古いバージョンを使い続けると動かなくなります。

youtube-dlからyt-dlpへの移行方法は?

結論:インポート名を youtube_dl から yt_dlp に変えるだけでほぼ互換性があります。オプション名はほぼ同じですが、一部に新しいオプションが追加されています。

プレイリストの一部だけダウンロードするには?

結論playliststartplaylistend、または playlist_items で指定します。

ydl_opts = {
    "playlist_items": "1-10",  # 1曲目から10曲目
    # または
    "playliststart": 5,
    "playlistend": 15,
}

関連記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?