mp4 を iOS で見るには。
Apacheで動画ファイルを配信するのが一番楽なんですが。
iOS のSafariは、動画ファイル先頭だけ読み込んで、mp4のメタデータ無ければ末尾を取りに行きます。
これが、ネットワークが貧弱なときに時間がかかってしまって結構辛い。
とくに AirPlay をAppleTVでやってると読込時間で疲れてしまう。
HLSで動画を部分的に分割して読み込ませる。
HLS は Apple が定義している動画の分割ダウンロードの仕組み。
mp4 を TS にして配信するだけじゃなく、シークや巻き戻し時に、HTTP経由で分割済みのファイルをダウンロードしてくる。
ts は h264 と aac が対応していて、一番良く使うと思う。
ffmpeg で HLS ファイルを作る
/usr/local/bin/ffmpeg -i input.mpeg -vcodec libx264 \ -s 1280x720 \ -acodec libfaac -b:a 256k\ -flags +loop-global_header \ -bsf h264_mp4toannexb \ -f segment -segment_format mpegts \ -segment_time 10 \ -segment_list happy.m3u8 happy_%04d.ts
動画解像度のサイズやビットレートは変えても大丈夫。
オプションについて。
- -bsf h264_mp4toannexb bsf は ビットストリーム出力の指定。 h264_mp4toannexb がmp4のストリーミング
- -flags +loop-global_header mp4 のメタデータを先頭に。
- -f segment -segment_format mpegts これはTSファイルにしている。
- -segment_time 10 分割の時間を10秒程度にする。
- -segment_list happy.m3u8 セグメントの分割されたファイル一覧(プレイリスト)
- happy_%04d.ts 出力されるファイル名。 %04d が連番の形式
再生する方法
iOS 機器で、 m3u8 のファイルを開けばイイ。
HTMLに書くなら、
<video src="path/to/name.m3u8"></video>
再生チェックはVLCとSafari
VLCにURLを渡すと再生できる。但し、ローカルのm3u8 ははダメ。HTTP前提です。
後でサンプル書きますが、m3u8 の中身に相対パスが書かれているのです。
入力に使える動画について
ffmpeg が対応している動画ならたいてい読み込める。
もちろんパイプで渡せる。
また、USBのカメラやfacetimeカメラを取得してWEBサーバーに配置することでライブストリーミングが可能になる。
recpt1 --b25 --strip --sid hd 22 300 - | ffmpeg -
などとrecpt1 と組み合わせても強い。
あれ?もしかしてffserver なくても行けるんじゃ。これ強い。
m3u8 のファイルの中身
at a4c19beea7bfbd97e611917a9eef4f79.m3u8 #EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-ALLOW-CACHE:YES #EXT-X-TARGETDURATION:18 #EXTINF:10.810800, a4c19beea7bfbd97e611917a9eef4f79.00000.ts #EXTINF:15.315300, a4c19beea7bfbd97e611917a9eef4f79.00001.ts #EXTINF:5.271933, a4c19beea7bfbd97e611917a9eef4f79.00002.ts #EXTINF:16.683333, a4c19beea7bfbd97e611917a9eef4f79.00003.ts #EXTINF:7.073733, (中略 a4c19beea7bfbd97e611917a9eef4f79.00269.ts #EXT-X-ENDLIST
EXTINF はファイルに含まれる秒数かな?
HTTPヘッダ
拡張子がm3u8 なら問題ないんだけど。拡張子を変えても、ヘッダがアレばチャント認識できる。
AddType application/x-mpegURL .m3u8 AddType application/x-mpegURL .playlist AddType video/MP2T .ts
たとえば、playlistという拡張子でも ストリーミングはできますね。
takuya@~/Desktop$ curl -I http://192.168.2.1/hls/test.playlist HTTP/1.1 200 OK Date: Tue, 05 Apr 2016 18:59:23 GMT Server: Apache/2.2.22 (Debian) Pxxx Last-Modified: Tue, 05 Apr 2016 17:27:01 GMT ETag: "5d4014b-402a-xxxfc02737f84b" Accept-Ranges: bytes Content-Length: 16426 Content-Type: application/x-mpegurl
HLS でファイルを作るメリット
動画を変換中でも再生ができる。コレが一番のメリット。
HLSだとストリーミングっぽく、ファイル断片をクライアントが取りに来てくれるので、結構簡単にライブストリーミングが可能になる。
断片化ファイルが10秒なら、10秒視聴中に10秒転送すると途切れることなく視聴できる。
このことから、必要な回線速度(クライアント側)が非常に計算しやすい。
また、クライアント側の回線速度が計算できると同時視聴数を考慮してサーバー側の必要回線速度も計算しやすいね。
通信もHTTPなので扱いやすい!シーク時キャッシュさせやすいかも。*1
一度にmp4 を読み込まないので、LTE通信などには優しい。10分くらいを先読みで読みこむようだ。
シーク時に再度読み込みが発生するのは辛い。
PC/OSXのChromeは非対応。 Android版は対応している。
お手軽で、良い世の中になったね。
ffmpeg を使えば、便利すぎて、考えることをやめてしまう。
参考資料
HTML5のvideoタグで利用するmp4の動画を作る時のTips - Qiita
追記
なんでこんなことが必要か?単純な説明では、ブラウザはRANGEリクエストで10バイト目から20バイト目をApacheにリクエストできるが、10秒目から20秒目をリクエスト出来ないから。そもそも10秒目が何バイト目に当たるかはわからないし。HTTPには秒数指定で転送するための定義がない。だから事前に秒数ごとにファイルを分割して保存したものを転送するか、アクトビラみたいにApache側に秒数指定を実装するかだ。
*1: リクエストログ調べたけどキャッシュしてないっぽい。