2018年10月20日土曜日

ストリーム動画をダウンロードする その1.アドレスを調べる

※作成したアプリを公開する予定はありません。
この記事をそのまま利用してアプリを製作しても、すべてのサイトでダウンロード可能なわけではないし、考慮すべき問題が他にも出てきます。
ビギナー開発者がアプリケーションを作成するための取っ掛かりになれば、、、程度の記事です。
抜粋されているソースの言語はC#です。他の言語でも考え方は同じだと思います。

ネットで配信されているStreamを保存したいなと思い調べてみました。
基本的には動画のストリームを保存することが出来れば良いだけです。
なのでダウンロードするファイルのアドレスが分かれば良いはず。。。
実際の通信を確認するにはFiddlerというアプリを使用します。
起動すると現在行われている通信が表示されます。

初期設定では大量の通信が流れているため、調査が難しい状態です。


このアイコンを通信を確認したいウインドウにドラッグ&ドロップします。
また、F12キーで通信のキャプチャを停止できます。必要な通信が流れていかないように、不要なときはキャプチャを停止しましょう。

実際にYoutubeの通信を確認します。
Fiddlerを起動してから、Youtubeへアクセスして動画を閲覧します。

サイトにアクセスすると、Fiddlerにはズラズラと通信情報が表示されるので、適当なところでF12キーを押してキャプチャを停止しましょう。再生が始まって数秒で充分です。

まず、アクセスしたURLが表示されています。
ここが解析のスタート地点になります。

その後、しばらくして、動画のダウンロードが始まっています。

ここに表示されているアドレスにアクセスすれば動画がダウンロードが出来ることになりますね。

少し脱線しますが、この動画の場合、動画ファイルと音源ファイルが別々にダウンロードされているようです。
Youtubeでは複数の画質での配信がされているため、音源を分けているのでしょうか?
(Youtubeのなかでも古い形式のものは、動画にそのまま音声も含まれています)

もし、このようなファイルをダウンロードするとしたら、動画ファイルと音声ファイルをくっつける作業が別途必要ということになります。

ソースはこんな感じでしょうか。
引数のtargetUrlに動画のアドレスを入れます。
簡略化のため、出力されるファイル名は”youtube.mp4”固定としています。

public static async void Download(string targetUrl)
{
 HttpClient client = new HttpClient();
 HttpResponseMessage res = await client.GetAsync(targetUrl, HttpCompletionOption.ResponseHeadersRead);

 using (var fileStream = File.Create("youtube.mp4"))
 {
  using (var httpStream = await res.Content.ReadAsStreamAsync())
  {
   httpStream.CopyTo(fileStream);
   fileStream.Flush();
  }
 }
}