今回は実務で検証する機会があり、まだあまり参考になる記事がなく苦労したので、同じような境遇の人(かなり少数だと思いますがw)に向けて、つまづいた点も含めて、実際に行った変換に成功するまでの手順を書いていきたいと思います!
今回はOBSからサンプル動画をAWS MediaLiveに送出してエンコードを行い、MediaPackageで配信するという流れで試していきます。
流れを図にすると以下のような感じです。大勢の方に配信する際はMediaPackageのURLをCloudFront経由で配信することにより、キャッシュさせることができますのでコストを削減できますが、今回はテストのみなので、CloudFrontは使用していません。
OBSはこちらからダウンロードできます。OBSダウンロードページ
ちなみにMacOS、Windowsどちらも対応しています。
ソフトウェアはWireCastなどでも問題ありませんので、お好きなソフトウェアをお使い下さい。
次にMediaLiveとMediaPacageの設定ですが、テストの場合パラメータは基本的にデフォルトのものでも大丈夫です。
ただし、エンドポイントからMP4にデータを変換する場合は、そもそもエンドポイントがアーカイブできる状態にしておく必要がありますので、Media Packageのエンドポイントの設定内にある、Startover windowをONにして数値を86,400と入力しておいて下さい。(これにより配信開始してから24時間後まではエンドポイントにアクセスすると配信していた動画を視聴できるようになります)
作成する順序は
になります。
今回は主にFFmpegに関するブログ記事のため、詳細な手順は省かせて頂きますが、この辺りの準備作業から配信方法までの詳細な手順はこちらのクラスメソッドさんの記事が参考になるかと思います。
参考記事
さてここまで準備ができましたら、実際に動画を配信することができるようになっていますので、上記の参考記事を見ながら実際に配信して動画を視聴してみましよう。(説明丸投げですみません)
MediaPackageのコンソール画面から視聴できるか確認してみます。
ちなみに私の方でテスト配信に使用したのは、弊社のMEDIAプロダクション事業部が手掛けているモーターサイクルメディア『RIDE HI』に関するYoutubeチャンネルの動画になりますので、ここを見てしまった人はこちらからチャンネル登録の方もお願いします。
さて、ここからが本題です。
まずEC2インスタンス(t2microで大丈夫です)を一台用意し、FFmpegをインストールしていきます。
EC2にsshログインし、下記のコマンドを順に実行しインストールを完了させます。
sudo su - //rootユーザーに切り替えます。 cd /usr/local/bin //ディレクトリを移動します。 mkdir ffmpeg && cd ffmpeg //FFmpegをダウンロードしてくるディレクトリを作成して移動します。 wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz //ffmpegファイルをダウンロードしてきます。 tar -xf ffmpeg-release-amd64-static.tar.xz //ダウンロードしたファイルを解凍します。 cd ffmpeg-4.3.1-amd64-static //解凍したファイルのディレクトリに移動します。 ./ffmpeg -version //バージョンを確認します。
私の場合は、
ffmpeg version 4.3.1-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2020 the FFmpeg developers
と表示され、バージョン4.3.1がインストールできていることが確認できました。
やっと準備が整ったのでお待ちかねのFFmpegを使用したファイル変換を行っていきたいと思います。
FFmpegでm3u8をmp4に変換する際のサンプルコードは下記になります。
ffmpeg -i "FILE_PATH" -movflags faststart -c copy -map 0:0 -map 0:1 sample.mp4
簡単にオプションの説明をすると、
では変換コマンドも分かったところで早速MediaPackageのエンドポイントから、MP4ファイルを生成してみましょう。
ffmpeg -i "https://×××××××××.mediapackage.ap-northeast-1.amazonaws.com/out/v1/××××××××××/index.m3u8" -movflags faststart -c copy -map 0:0 -map 0:1 sample.mp4
そうです。これでMP4に変換できるならば苦労しなかったです(泣)
[mp4 @ 0x7135d80] sample rate not set Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
一見変換が進んでいるようなログの流れ方はするものの、最後にこのようなエラーが出てしまっているかと思います。
なぜ失敗してしまうのか。これはMediaPackageのエンドポイントに原因がありました。
試しにエンドポイントをcurlで叩いてみました。
#EXTM3U #EXT-X-VERSION:3 #EXT-X-INDEPENDENT-SEGMENTS #EXT-X-STREAM-INF:BANDWIDTH=3955604,AVERAGE-BANDWIDTH=2526923,RESOLUTION=960x540,FRAME-RATE=29.970,CODECS="avc1.640029,mp4a.40.2" index_1.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=5890605,AVERAGE-BANDWIDTH=3736888,RESOLUTION=1280x720,FRAME-RATE=29.970,CODECS="avc1.640029,mp4a.40.2" index_2.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=8381120,AVERAGE-BANDWIDTH=5311567,RESOLUTION=1280x720,FRAME-RATE=29.970,CODECS="avc1.640029,mp4a.40.2" ・ ・ ・ ・ #EXT-X-STREAM-INF:BANDWIDTH=1465516,AVERAGE-BANDWIDTH=952780,RESOLUTION=640x360,FRAME-RATE=29.970,CODECS="avc1.4D401E,mp4a.40.2" index_8.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=2196480,AVERAGE-BANDWIDTH=1426923,RESOLUTION=768x432,FRAME-RATE=29.970,CODECS="avc1.4D4029,mp4a.40.2" index_9.m3u8
ん、なんかいっぱい出てきた(焦)。
実はAWSのコンソール画面に表示されるエンドポイントは親マニフェストであり、上記の9つの子マニフェストへのパスが書かれているだけなので、変換元に指定するパスとしては子マニフェストの方を指定しなければ変換できないのです。
ちなみに、上記のように9つ出てくる理由としてはもうお気づきかもしれませんが、MediaLiveの設定で、「MediaPackage outputs」に指定した数になります。
私の場合、今回は9つで設定していました。
今回はindex_2のファイルをMP4に変換したいと思いますので、下記のようなコマンドを実行します。
ffmpeg -i "https://×××××××××.mediapackage.ap-northeast-1.amazonaws.com/out/v1/××××××××××/index_2.m3u8" -movflags faststart -c copy -map 0:0 -map 0:1 sample.mp4
すると今度は
[https @ 0x73facc0] Opening 'https://×××××××.mediapackage.ap-northeast-1.amazonaws.com/out/v1/××××××/index_2.m3u8' for reading [hls @ 0x7269480] Skip ('#EXT-X-VERSION:3') [hls @ 0x7269480] Skip ('#EXT-X-DISCONTINUITY') Last message repeated 1 times
をずっと繰り返してしまうかと思います。
そうです、修正が必要なポイントがもう一つあります。
もう一つの修正すべきポイントはエンドポイントにパラメータを追加をすることです。
Startover windowをONにしている場合、エンドポイントの後ろに配信していた時間を指定することが必要になります。
またクラスメソッドさんの記事になってしまいますが、参考記はこちら。
ですので今回の場合も時間指定することによって、うまく変換ができるようになります。
今回の最終的な変換コマンドは下記のようになります。
ffmpeg -i "https://×××××××××.mediapackage.ap-northeast-1.amazonaws.com/out/v1/××××××××××/index_2.m3u8?start=2021-02-08T09:00:00+09:00&end=2021-02-08T10:00:00+09:00" -movflags faststart -c copy -map 0:0 -map 0:1 sample.mp4
(*startとendの時間は実際に配信した時間を指定して下さい。)
お疲れ様でした。これで変換が無事成功しました!
AWS自体にも配信向けサービスは充実していて、ファイル変換をしてくれるサービスもありますが、今回は色々と制約もあったためこのような方法でMP4へ変換を行いました。
今回初めてFFmpegを使用してみたのですが、非常に使いやすくで強力なソフトウェアだと感じました。
私は業界未経験からMDに入社してもうすぐ1年になりますが、この1年で学べたことは多く、今回のように全く触ったことがないようなソフトウェアを使用しての実装もできるようになりました(今回はFFmpegの使用方法が簡単でドキュメントも多かっただけですがw)。
何が言いたいかと言うと、現在(21年2月現在)MDでは経験者の方はもちろんのこと、SERVICE事業部では私のような経験は浅いけどやる気はあるよ!というフロントエンド寄りのエンジニアの方も採用募集中ですので、ご興味持って頂けた方、又は周りに興味がありそうな方がいらっしゃる場合はこちらのフォームからご連絡下さい!
以上、SERVICE事業部入社1年目サーバサイドエンジニアのDEWでした。