2020年4月4日土曜日

IIS(ASP.NET Core 3.0)でHLS配信

HLS配信が簡単に実現できそうだったので試してみました。
1時間くらいで出来るつもりで始めたのに、再生可能になるまで時間かかった・・・

「ASP.NET Core 3.0」で発行されたサイトについて、動画配信を試してみました。
FFmpegについてはWindowsで使用しています。

1.処理の流れ

HLSは

  • 分割した動画(tsファイル)を作成
  • プレイリスト(m3u8ファイル)を作成
  • MIME設定に拡張子追加
  • 表示させたいhtmlで<video>タグで指定

だけで実現可能らしいです。

ASP.Net
Chrome
の考慮が必要です。

動画の分割とプレイリストの作成はFFmpegで可能です。
ffmpegについはほかの記事もあるので参考にしてください。

2.動画の準備

再生させたい動画を分割し、プレイリストも作成します。
分割にはffmpegを使用しています。
実行するコマンドは以下です。


  ffmpeg -i movie.mp4 -acodec copy -vcodec copy -vbsf h264_mp4toannexb -map 0 -f segment -segment_format mpegts -segment_time 5 -segment_list stream/playlist.m3u8 -segment_list_flags -cache -movflags faststart -vprofile baseline -level 3.0 -g 150 -b:v 519k -s 768x432 -ar 44100 -flags +loop-global_header  stream/v%03d.ts  

実行前にFFmpegの実行ファイルの直下に「stream」フォルダを作成しておいてください
分割したい動画を「movie.mp4」としています。


各オプションの意味は以下
-i movie.mp4 分割したい動画を指定
-acodec copy 音声コーデックはそのまま
-vcodec copy 映像コーデックはそのまま
-vbsf h264_mp4toannexb
-map 0 入力と出力のマッピング
-f segment 出力フォーマットは「セグメント分割」
-segment_format mpegts セグメントのフォーマットは「MPEG-TS」
-segment_time 5 5秒間隔で分割
-segment_list stream/playlist.m3u8 プレイリストのパスを指定
-segment_list_flags -cache キャッシュを無効(だと思う)
-movflags faststart メタデータを先頭に移動して再生開始を高速化
-vprofile baseline プロファイルにbaseline指定
-level 3.0 プロファイルレベル
-g 150 GOPを150に設定
-b:v 519k ビットレート
-s 768x432 映像サイズ
-ar 44100 サンプルレート
-flags +loop-global_header メタデータを先頭に移動
stream/v%03d.ts 分割ファイル名


補足)GOPについて
GOPの設定値はこちらのサイトの解説がわかりやすいです。
画像のシーク(動画の再生位置の移動)に影響するようで、フレームレートと比較して設定したほうが良いそうです。
小さい値のほうが、ファイルサイズが大きくなるけど、シーク性能が上がるようです。
ffmpegによるmp4形式の動画のキーフレームの設定について


分割が成功すると「stream」フォルダにファイルが作成されます。


playlist.m3u8がプレイリストです。
メモ帳で開くとこんな感じ。
特に編集は不要です。

分割された動画は指定した時間で分割された動画となっています。


3.MIMEの設定

ここでハマりました。

IISでMIMEの種類で以下を追加すれば良いと思ったのですが、うまくいかず・・・
.m3u8 application/vnd.apple.mpegurl
.ts video/mp2t

IISでMIME設定したにも関わらず、動画再生がされません。
また、プレイリストに直接アクセスしても404 NotFoundとなってしまいました。


どうやらASP.Netでは別途、設定が必要だったようです。
Startup.cs の Configure()で以下を追記します。


provider = new FileExtensionContentTypeProvider();
provider.Mappings[".m3u8"] = "application/x-mpegURL";
provider.Mappings[".ts"] = "video/MP2T";

app.UseStaticFiles(new StaticFileOptions()
{
 ContentTypeProvider = provider,
});

設定を追加した後にサイトを再発行することで、ファイルにアクセス可能となりました♪
(プレイリストに直接アクセスしているので、ダウンロードとして扱われました)



4.Chromeでの再生(hls.js)

作成した動画はHTMLに以下のタグを埋め込むだけで再生可能です。
<video src="./stream/playlist.m3u8" controls/>
ただ、これだとChromeなどが未対応で再生できません。

そこで、再生はhls.jsを使用します。
手順などは、こちらのサイトをマンマ使用したので、リンクをそのまま参照ください。

hls.jsでお手軽 動画・生配信視聴プレイヤー作ってみた 【お盆休みの自由研究2019その1】


ASP.NetではHeadタグは_Layout.cshtmlに設定します。


これでChromeから再生ができました☆


参考サイト

HTTP Live Streaming 動画配信のやり方 (実践)
動画の分割はffmpeg以外の手法ですが、一連の流れがわかりやすいと思います。

HTTP Live Streaming (HLS)の基本とngx_http_hls_moduleについて調べて試してみた
上のサイトと同様に、一連の流れがわかりやすいと思います。
後悔するWebサーバはnginxです。

HLSについて知っていることを話します
スライドショーでザックリ内容を把握するのに助かりました。