m◯ssavのコンテンツをローカル保存する

というわけで第一回はこれ。早速やる。
自分の思考と試行の流れをダラダラ書くので読みにくいと思うけど、自分のために書いてるのでいいことにする。ではスタート。

とりあえずアクセス

  • とりあえずアクセス

  • 開発者ツール開く

  • 再生ボタン押す

  • networkタブ眺める

  • それっぽいの見つける
    →ここでhlsと判明する

  • m3u8を探すも見つからない

  • ページ再読み込み

  • playlist.m3u8ってのを見つける

  • vlc playerで当該URLを叩く
    →まんま見られる

  • vlc playerでローカル保存しようとしてみる
    →問題なく保存できる

自動化について考える

  • linux上で動かすことを考え、ページのURL渡したら落とせるようなものをイメージする(シェルスクリプト想定)

  • とりあえず単純にcurlして取れるソースの中にplaylist.m3u8のURLあるか確認

  • そもそもcurlできない。cloudflareに怒られる

  • どうせUAだろうと思ってUser-Agent指定して事なきを得るが、playlist.m3u8のURLはモロ書きされておらず

  • んじゃどうやってんねんってことでもう一回開発者ツールにらめっこ

  • playlist.m3u8を呼び出してるtsとにらめっこしてくと、このURLを組み立ててるJavaScriptをページのソース内に発見(addEventListenerでDOMContentLoaded指定してそこでevalされる)

  • 開発者ツール内でevalの中身を実行すると見事に目的のものをほぼゲット(コードは以下の用な感じ、一部改変)

eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('e=\'8://7.6/5-4-3-2-1/d.0\';c=\'8://7.6/5-4-3-2-1/a/9.0\';b=\'8://7.6/5-4-3-2-1/a/9.0\';',15,15,'m3u8|cae90411b475|9b04|4e8c|5790|6bebda56|com|hogehoge|https|video|842x480|source1280|source842|playlist|source'.split('|'),0,{}))

ほしいのは上のコードの変数pの中身にあるので、「return p」を「console.log(p)」に変更して、node経由で実行すれば良さそうと判断

組み立て

というわけで流れはできた。以下のような感じ。

  1. ページ取得

  2. eval部分抜き出し

  3. return p をconsole.log(p)に書き換え

  4. nodeで経由で実行

  5. 得られたURLをffmpegへ流し込み

得られたコードは以下の通り

#!/bin/bash
TARGET=`curl -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1' $1 |grep "eval(function" | perl -pe 's/^\s+//' | perl -pe 's/return p/console.log(p)/' | node | perl -pe "s/';.*//" | perl -pe "s/source='//"`
echo $TARGET
ffmpeg -i ${TARGET} -c copy `basename $1`.mp4

動作テスト

引数にページのURLを与えて実行してみるとエラー。ffmpegでエラーになってる。https通信なんてできんぞボケーって怒られてる。opensslのオプションがenableになってないらしいので、ffmpeg入れ替えて再実行して事なきを得る。

複数取得

これで一つ指定して一つ取得できるようになったので、次はリストで取得できるようにする。と言ってもテキストファイル用意して1行毎にURL書いてそれをwhile readで読んで渡せばいいやって思ってやったら、1行目しか実行されず。で、ググるとffmpegが悪さしてると判明。

上記ページのとおりに修正して意図通りの動作することを確認。
はい、おしまい。

この記事が気に入ったらサポートをしてみませんか?