本文へジャンプ

EC2内にFFmpegをインストールしてAWS MediaPackageのエンドポイントからMP4ファイルを作成する方法

Posted by DEW

今回は実務で検証する機会があり、まだあまり参考になる記事がなく苦労したので、同じような境遇の人(かなり少数だと思いますがw)に向けて、つまづいた点も含めて、実際に行った変換に成功するまでの手順を書いていきたいと思います!

FFmpeg

まずは動画配信に関するセットアップ

今回はOBSからサンプル動画をAWS MediaLiveに送出してエンコードを行い、MediaPackageで配信するという流れで試していきます。
流れを図にすると以下のような感じです。大勢の方に配信する際はMediaPackageのURLをCloudFront経由で配信することにより、キャッシュさせることができますのでコストを削減できますが、今回はテストのみなので、CloudFrontは使用していません。

図 - モバイルファーストデザインの制作フロー

OBSはこちらからダウンロードできます。OBSダウンロードページ
ちなみにMacOS、Windowsどちらも対応しています。
ソフトウェアはWireCastなどでも問題ありませんので、お好きなソフトウェアをお使い下さい。

次にMediaLiveとMediaPacageの設定ですが、テストの場合パラメータは基本的にデフォルトのものでも大丈夫です。
ただし、エンドポイントからMP4にデータを変換する場合は、そもそもエンドポイントがアーカイブできる状態にしておく必要がありますので、Media Packageのエンドポイントの設定内にある、Startover windowをONにして数値を86,400と入力しておいて下さい。(これにより配信開始してから24時間後まではエンドポイントにアクセスすると配信していた動画を視聴できるようになります)
作成する順序は

  • MediaPackageのChannelを作成
  • MediaPackageのエンドポイントを作成
  • MediaLiveのInputsを作成(RTMP Pushを選択)
  • MediaLiveのChannelを作成(Channel templateでHTTP live streaming MediaPackageを選択し、上記で作成したMediaPackageのChannel、MediaLiveのInputsをアタッチする。)

になります。
今回は主にFFmpegに関するブログ記事のため、詳細な手順は省かせて頂きますが、この辺りの準備作業から配信方法までの詳細な手順はこちらのクラスメソッドさんの記事が参考になるかと思います。
参考記事

配信に使用したURLの確認

さてここまで準備ができましたら、実際に動画を配信することができるようになっていますので、上記の参考記事を見ながら実際に配信して動画を視聴してみましよう。(説明丸投げですみません)

MediaPackageのコンソール画面から視聴できるか確認してみます。

MediaPackage コンソール画面

ちなみに私の方でテスト配信に使用したのは、弊社のMEDIAプロダクション事業部が手掛けているモーターサイクルメディア『RIDE HI』に関するYoutubeチャンネルの動画になりますので、ここを見てしまった人はこちらからチャンネル登録の方もお願いします。

EC2にffmpegにインストール

さて、ここからが本題です。
まず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でm3u8をMP4へ変換

やっと準備が整ったのでお待ちかねのFFmpegを使用したファイル変換を行っていきたいと思います。
FFmpegでm3u8をmp4に変換する際のサンプルコードは下記になります。

ffmpeg -i "FILE_PATH" -movflags faststart -c copy -map 0:0 -map 0:1 sample.mp4

簡単にオプションの説明をすると、

  • -i :変換元のファイルパスを指定します。
  • -movflags faststart :moov atomの位置(メタ情報の位置)を先頭に持って来てネットでの再生環境へ最適化します。
  • -c copy :動画・音声を複製するという意味で、HLSのようなストリーミング動画を保存する際に使用します。
  • -map 0:0 -map 0:1 :-mapの「0:0」や「1:0」は、どのファイルを何番目のストリームに配置するのかを指定しています。 (0:0が映像、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つで設定していました。

MediaPackage outputs

今回は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でした。

Recent Entries
MD EVENT REPORT
What's Hot?
こんな僕たちの仲間に入りませんか?
Movable Type AWS 移管&アップグレード サービス
乃木坂・六本木 撮影配信スタジオ
すべてのコンテンツ/プラットフォームを、ひとつのコンテンツ管理システムで。