YouTubeダウンロードプログラム-実戦編(1)


[0] TL;TR


簡単なシナリオでYouTubeとNaver TVの動画をダウンロードします.

[1]きっかけ


youtube-dlはPythonベースのCLIプログラムで、Youtubeのビデオリンクを入力するとビデオをダウンロードできます.youtube-dl "https://www.youtube.com/watch?v=asdbasdf"YouTubeの広告も見なくていいmp 4ファイルにすぐにダウンロードできます.YouTubeだけでなく、ネイバーTVアフリカTVなど複数のサイトをサポートしている.持って使っても幸せだけど、「どうやってやったの?」気になります.今回のキャンペーンは、Youtube動画と共にネイバーTV動画をDIYにダウンロードしたシャベルと結果についてです.

[2] Youtube


Debug Elements



DebuggerでYouTubeビデオエリアを撮影した時の様子ですが、srcはちょっと変な顔をしていました.例えば2479142 attributeは、blobで始まる奇妙なurlであるビデオのソースurlを直接含んでいると思います.ブラウザの新しいタブを開き、blobパスを入力して接続します.
Not allowed to load local resource:blob: https://www.youtube.com/18eddd0a-abca-4ae4-be79-a340a6bb24e2
咆哮して間違いを犯す.blobは少し怪しいので,これに対して次の位置決めで処理することにし,まず他の方法を探索する.

Debug Network


DebuggerのNetworkラベルページを開くと、次のように表示されます.

上のスクリーンショットでは、srcで始まるrequestが繰り返し呼び出され、応答の容量がかなり大きいので、これはビデオソースだと思います.response headerを見るとhttps://youtube.com/movie.mp4なので、ビデオソースは正しいです.ソースコードを追跡してrequestを追跡します.base.まずjsの4199行を見てみましょう.

xhrの存在から,ここではビデオに対する要求であり,42227行のonDoneはコールバック関数のように見える.ついて来い

見つけた!onDoneコールバック関数は応答を処理し、ここでvideoplayback?をブレークポイントでコンソールに打つ.ArrayBufferの長さは非常に大きく、ビデオに関するバイナリデータのようです.またurlのインデックスが変化し,繰り返し呼び出されるため,ビデオはクリップダウンロードに分けられる.requestのurlをコピーして新しいラベルに貼り付けると、ビデオが再生されます.Webmというファイルをダウンロードして開くと、ビデオは数秒後に終わり、音も出ません.つまり、これはビデオのみのファイルで、YouTubeではビデオと音声が別々に提供されています(ビデオによってmp 4が与えられる場合があります).したがって,すべてのセグメントを最初から最後までダウンロードして1つに統合し,ffmpegでビデオと音声を統合符号化する必要がある.しかし流れが複雑なので、まずは簡単なネイバーTVを試してみます.

[3] Naver TV


Youtubeと同様の方法でdebuggerのNetworkタブでrequest/responseを中心にデバッグ
Naver TV用ビデオプレーヤーprisemplayer.
content-type: video/mp4からのリクエストの容量から見ると先ほどのYoutubeとは違うようですtsという拡張子があります.上記の方法でダウンロードすると再生できます(.tsはMPEG streamで、音声とビデオが一体化し、完全に再生できるファイルです).tsファイルは1番からi番まで、すべてのtsファイルをダウンロードして順番に1つのファイルに統合すると、完全なビデオになります.ここでヒントがあります.右クリックすると、以下のようにfetch、cURLなど多くの形式でrequestをコピーできます.

terminalからダウンロードし、cURLを選択し、this.xhr.responseではなくcontent_512000_{index}_tsに変更し、shell scriptを実行するとビデオファイルをダウンロードできます.次のスクリプトを実行すると出力されます.tsという名前の完全なファイルが完了しました.
# SAMPLE CODE(NOT WORK)
curl 'https://naver-mbc-h.smartmediarep.com/{길어서 생략}/content_5120000_[0-9].ts?{이후 생략}' \
  -H 'authority: naver-mbc-h.smartmediarep.com' \
  -H {헤더 길어서 생략} \
  -H 'accept-language: en-US,en;q=0.9,ko;q=0.8' \
  --compressed \
  >> output.ts

[4] YouTube download


video source


Naver TVで行った方法に従って、Networkタグからビデオソースに対する要求を以下のように取得します.

さっきと違って複雑です.ビデオカートリッジファイルではないので、ここにインデックスに関する情報があるはずですが、表示されている部分から見ると0.tsというquery stringパラメータがあります.1640846の数字をビデオの最後の対応するインデックスに変更すると、ビデオ全体をダウンロードできます.最後のインデックスはどうやって取りましたか?まず、ビデオの最後の部分で提起された要求を振り返ってみましょう.このビデオは約9分間のビデオで、最後のインデックスは66921103です.上記のrangeの代わりに[0-9].tsでcURLスクリプトを作成します.以下に示します.
# NOT WORK
# video only
curl 'https://r3---sn-3u-bh2ey.googlevideo.com/videoplayback?expire=1626545945&ei=range=0-164084{.. 이후 중략}' \
  -H 'authority: r3---sn-3u-bh2ey.googlevideo.com' \
   {... header 중략 }
  -H 'accept-language: en-US,en;q=0.9,ko-KR;q=0.8,ko;q=0.7' \
  --compressed \
>> movie.webm 
ダウンロードしたファイルの拡張子はwebmです.これは、応答ヘッダから見るとrange=0-1640846range=0-66921103であるためです.Chromeでこのファイルを開くと、ビデオは最初から最後まで完全で、もちろん音は出ません.今から声を出しましょう.

audio source


デバッガのネットワークラベルを再開し、対応する音声リクエストに従ってダウンロードします.よく見るとビデオリクエストと違い、Response Headerを見るとcontent-typeと書いてあります.cURLコードを開いたら、次のようにrangeを変更してダウンロードします.今回のファイルの拡張子もwebmです.
curl 'https://r3---sn-3u-bh2ey.googlevideo.com/videoplayback?expire=1626545945&range=0-8544830&rn=2{... url 중략 }&rbuf=0' \
  -H 'authority: r3---sn-3u-bh2ey.googlevideo.com' \
  { ... header 중략}
  -H 'accept-language: en-US,en;q=0.9,ko-KR;q=0.8,ko;q=0.7' \
  --compressed \
>> audio.webm
このファイルはChromeで再生されていて、音だけが最初から最後まで良いです

ffmpeg


今、ビデオファイルと音声ファイルを手に入れました.この2つのファイルを合わせればいいです.ffmpegをインストールし、次のように端末に電話します.video/webmoutput.mp 4を再生し、音声ビデオは正常です.

[5]考えるべきこと


上記の例によれば、YoutubeやNaver TVで動画を再生する方法は以下のように推測される.
  • サーバは、content-type: audio/webmのような完全なビデオファイルを提供しません.
  • ブラウザは、start-endに相当するフラグメントをサーバに要求し、ArrayBufferとして応答を受信する.
  • の後、ブラウザはArrayBufferを再生可能な形状に加工し、./ffmpeg -i video.webm -i audio.webm -c:v copy -c:a copy output.mp4 Elementで
  • を再生する.
    今回の放送では、ビデオダウンロードの実戦でデバッグプロセスと簡単な端末コードを理解し、次の放送では、これらの小細工で知ったキーワードBLOBとHLSを使用しました.

    [6]参照


    https://kibua20.tistory.com/130
    https://kibua20.tistory.com/79