😂

yt-dlpで動画・音声をいい感じに落とそうと紆余曲折して結局バッチファイルに落ち着いた話

に公開
1

最初に結論、後ろに雑談をまとめてあります。目次で好きなとこ読んでね。

前提環境・結論

  • Windows
  • yt-dlpのパスが通っている
  • ffmpegもyt-dlpの依存関係で必要

最終的に作ったコード

フォーマットのチェック用

起動して、URLを入力すると、利用可能なフォーマットのリストが表示される。
最初にyt-dlpの基本オプション(このバッチファイルではすべてのLOOPで固定)を宣言、次にURLの入力を待ち、それらをyt-dlpに渡して実行する。終了次第、再度URLの入力を待つ、というLOOPを回している。これらは、以降のバッチファイルでも基本の構造。

ListFormatsCheck.bat
@echo off
chcp 65001 >nul
setlocal
set "PYTHONIOENCODING=utf-8"

echo == DL4 init ==
echo == LIST FORMATS ==
:: 基本のyt-dlpオプション
set YTDLPOPTS=^
  --list-formats ^
  --yes-playlist

:LOOP

:: URL入力
set "URL="
set /p "URL=Enter URL (blank to exit): "
if not defined URL goto END

:: yt-dlp実行
yt-dlp %YTDLPOPTS% "%URL%"

echo(

goto LOOP

:END
endlocal

動画を.mkv・最高画質でダウンロード

保存先を2通り選べるようしており、Enterを入力するだけなら前回の入力を引き継ぐようにしてある。これは、次の音声も同じ。defaultと入力すると、フォルダ名の指定を解除し、初期状態に戻せる。

  • .\Musics\%%(uploader,NA)s\%%(title)s.%%(ext)s
    複数チャンネルの動画が含まれるプレイリストを入力すると、この状態では、チャンネル名でフォルダ分けされる。
    ex.) .\Musics\YouTube Japan 公式チャンネル\好きなことで、生きていく - はじめしゃちょー - YouTube TVCM.mkv
  • .\Musics\%FOLDER%\%%(title)s.%%(ext)s
    複数チャンネルの動画が含まれるプレイリストを入力しても、入力したフォルダ直下に保存される。
    ex.) .\Musics\TEST\好きなことで、生きていく - はじめしゃちょー - YouTube TVCM.mkv (フォルダ名をTESTと入力した場合)
mkv_画質最高.bat
@echo off
chcp 65001 >nul
setlocal
set "PYTHONIOENCODING=utf-8"

echo == DL4 init ==
echo == mkv BEST ==
:: 基本のyt-dlpオプション
set YTDLPOPTS=^
  -f "bv*+ba/best" ^
  --embed-thumbnail --embed-metadata --embed-chapters --add-metadata ^
  --download-archive "archive1.txt" ^
  --yes-playlist

:LOOP

:: 出力先設定、yt-dlpオプション追記
echo blank to set [%FOLDER%], DON'T USE \ / : * ? ^" ^< ^> ^| 
echo or input ^"default^", then set default[%%uploader]
set /p "FOLDER=Folder Name: "

if defined FOLDER (
  :: default入力で戻す。
  if "%FOLDER%"=="default" (
    set "FOLDER="
    goto default
  )
  set "OUTTPL=.\Movies\%FOLDER%\%%(title)s.%%(ext)s"
) else (
  :default
  set "OUTTPL=.\Movies\%%(uploader,NA)s\%%(title)s.%%(ext)s"
)
echo Save to: %OUTTPL%

:: URL入力
set "URL="
set /p "URL=Enter URL (blank to exit): "
if not defined URL goto END

:: yt-dlp実行
yt-dlp %YTDLPOPTS% -o "%OUTTPL%" "%URL%"

echo(

goto LOOP

:END
endlocal

音声を.m4a・ビットレート192Kbpsでダウンロード

動画もそうですが、archive.txtを用意しておくと、二重のダウンロードを検出してくれるので時間も容量も節約できます、リスク低減にもなります。おすすめ。

m4a_音質192K.bat
@echo off
chcp 65001 >nul
setlocal
set "PYTHONIOENCODING=utf-8"

echo == DL4 init ==
echo == m4a 192K ==
:: 基本のyt-dlpオプション
set YTDLPOPTS=^
  -f "ba[acodec^=mp4a]" ^
  --extract-audio ^
  --audio-quality 192K ^
  --embed-thumbnail --embed-metadata --embed-chapters --add-metadata ^
  --download-archive "archive2.txt" ^
  --yes-playlist

:LOOP

:: 出力先設定、yt-dlpオプション追記
echo blank to set [%FOLDER%], DON'T USE \ / : * ? ^" ^< ^> ^| 
echo or input ^"default^", then set default[%%uploader]
set /p "FOLDER=Folder Name: "

if defined FOLDER (
  :: default入力で戻す。
  if "%FOLDER%"=="default" (
    set "FOLDER="
    goto default
  )
  set "OUTTPL=.\Musics\%FOLDER%\%%(title)s.%%(ext)s"
) else (
  :default
  set "OUTTPL=.\Musics\%%(uploader,NA)s\%%(title)s.%%(ext)s"
)
echo Save to: %OUTTPL%

:: URL入力
set "URL="
set /p "URL=Enter URL (blank to exit): "
if not defined URL goto END

:: yt-dlp実行
yt-dlp %YTDLPOPTS% -o "%OUTTPL%" "%URL%"

echo(

goto LOOP

:END
endlocal

経緯と雑談

この大データ時代(BIG DATA ERA)、自分の手元にデータがないとストリーミングサイトにはサブスクで搾取され、いい感じにAIにデータを学習できなかったりするじゃないですか。

なので、自分の手元にいろんなデータを置いておこうと思ったんですよ。ついでに容量もそこそこにしておきたかった。

でも動画って容量食うじゃないですか。でもコーデックによって圧縮率が変わったり、ビットレート落としたりできるみたいなんですよ。ffmpegで。

https://aviutl.info/ko-dekku-tigai/
↑イメージ掴むにはおすすめです。
https://trac.ffmpeg.org/wiki
↑やっぱ豊富なドキュメントは正義。

なので、yt-dlpで動画落としてきて、ffmpegで圧縮してみようと思ったわけなんですね。そういうソフトを3世代にわたってここ1週間ぐらいで作ってみました。バッチファイルからpythonに至るまで割といろいろ調べたんですね。いい経験だった...。

ですが、yt-dlpで映像と音声別々で落としてくると、それを内部的にはffmpegで合成しているみたいで。yt-dlpのオプションを甚だしく弄ると大体のことには対応できそうなんですよね。

さらに、yt-dlpとffmpegを組み合わせるソフトを自分で作っていて思ったのは、自分が欲しいものが明確でないと、無駄に自由度の幅を持たせようとしてしまって、結局中途半端な出来に終わってしまうことですね。特にpythonで作った最後のやつはひどかった。今になってわかったのは、結局何百行もコード書いて実現できたことは、yt-dlpで一行書いたり、あるいはバッチファイルでffmpegと合わせて二行書けば終わることだったんです。あまりにも悲しい!

怠けずyt-dlpとffmpegのドキュメント読もうぜ。あと、そういうの紹介しているブログも、網羅しているようで一部しか書いていなかったりするので、なおさら公式ドキュメントを読もう。英語を恐るるなかれ。

参考になる~~~

さて、yt-dlpで特に有用なページをいくつか紹介します。

https://scrapbox.io/Mijinko/yt-dlpで最高品質の動画をダウンロードする
↑最初にイメージを掴むならこれはわかりやすい。
https://tooltorisetsu.xyz/yt-dlp-option/
↑すごいAI生成感が否めないが、かなりわかりやすい。他のブログで書かれていないプレイリストの話も書かれており、私はこれにうちのめされて、「もうバッチファイル数行で良くない?」になった。
https://github.com/yt-dlp/yt-dlp
たぶんこれを読むのが一番早いと思います。

pythonで作る利点として、複数の用途、例えば動画だけでなく音声ファイルとしてもオプションで切り替えてダウンロードできるようにすることを考えていたんですがねぇ。2番目の記事を読んで、「バッチファイル切り替えればよくね?」 の思いに至りました。

さらに、例えば音声ファイルなら、--audio-qualityというビットレートをある程度指定できるオプションがyt-dlpには存在していて、改めてffmpegを自分で噛ませる必要もないわけです。主張したいのは、yt-dlpのオプションの自由度マジで高いから一度見てみてください。多分大抵のことができます。

https://github.com/yt-dlp/yt-dlp

Discussion

落雁落雁

ちなみにYouTubeから動画本体のデータを保存するのは、YouTubeの利用規約的にダメらしいです。IP BANとかなるらしいので大変だ。俺等はプラットフォーマーの犬ってわけ。(伝え聞いた話 & AI)