💾

yt-dlpをPythonから呼び出してみようか

に公開

yt-dlp

yt-dlpはYoutube-DLというソフトのフォーク版でより高速になっています。
コマンドラインから呼び出すことも可能です。

Terminal
yt-dlp -f b <URL>

あとはPythonのモジュールとしても使えます。
基本のコードです。

main.py
import yt_dlp

url = "https://youtu.be/lewZyfuI0Vs?si=qLt-Cg0ZDhPOy6qF"

ydl_opts = {
    'format':'best',
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download([url])

このコードを実行するとurlの動画がダウンロードされます。でもこれだけならpythonから呼び出す理由ないですよね…

レッツ ラ デモンストレーション

main.py
import yt_dlp

-url = "https://youtu.be/lewZyfuI0Vs?si=qLt-Cg0ZDhPOy6qF"
+url = input("URL:")

ydl_opts = {
    'format':'best',
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download([url])

これに書き換えるだけで、、、

URLを入力できるようになるわけですよ。
さぁて、ここからが本題です。

本題

基本的にメインの処理は ydl_opts で指定できる。

フォーマットの選択

ydl_opts = {
    'format':'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]',
}

コマンドラインの -f に相当する。-f の時と同じように指定できます。
best だけだと1280*720の動画がダウンロードされます。

ydl_opts = {
    'format':'bestaudio',
}

だと最高音質でダウンロードされます。

ファイル名を変更

ydl_opts = {
    'outtmpl':'%(title)s.%(ext)s',
}

コマンドラインの -o に相当する。-o の時と同じように指定できます。
この例だと<タイトル>.<拡張子>って感じになります。
なお詳しくはこれを見てね
https://masayoshi-9a7ee.hatenablog.com/entry/2021/11/06/112639

エラーを無視する

ydl_opts = {
    'ignoreerrors':True,
}

で諸々のエラーを無視できます。エラーハンドリングなんてめんどくさいのでこれで済ませよう!!()

サムネイルを埋め込む

ydl_opts = {
    'writethumbnail': 'true',
    'postprocessors': [
        {
            'key': 'EmbedThumbnail',
            'already_have_thumbnail': False,
        }
    ],
}

眠くて書くのがダルくなってきた
'postprocessors' でダウンロード後の処理を指定できるよ。ココに関しては日本語の情報が少なかったので、githubのissueとかすごく長いpyファイルから読み取ってました。
already_have_thumbnailTrue にすると画像ファイルが自動で削除されません。
なので基本的には False に設定します。

音声を抽出

ydl_opts = {
    'format': 'bestaudio',
    'postprocessors': [
        {
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
	    'preferredquality': '128',
        }
    ],
}

これでね、mp3に変換されます。
preferredcodecでコーデックを、preferredqualityで音質を選択可能です。
mp3の場合はビットレートを入力できます。

メタデータを埋め込む

ydl_opts = {
    'format': 'bestaudio',
    'postprocessors': [
        {
            'key': 'FFmpegMetadata',
            'add_metadata': True,
        }
    ],
}

これだけ。

進捗を非表示

ydl_opts = {
    'noprogress': True,
}


↑これが表示されなくなります。

progress_hook

def hook(d):
    if d['status'] == 'downloading':
        # ダウンロード中の処理
        print(f"進捗: {d['_percent_str']}")
    elif d['status'] == 'finished':
        # ダウンロード完了時の処理
        print("ダウンロード完了")
ydl_opts = {
    'progress_hooks': [hook],
    'format': format,
    'noprogress': True,
}

progress_hook を使ってダウンロード処理とかの進捗を監視できたりイベントが発生した際に処理を呼び出せるます。
print でやるなら必要ないですけど、GUI化するときは情報表示するために必要だと思います。

以上

以上です。ひとまず寝て分かりにくい箇所があったら随時追記・編集していきますね。

Discussion