方法をある程度絞ることができたのでまとめる。
参考:
最終的な引数等はこうなった
avconv -f video4linux2 -input_format mjpeg -video_size 1280x720 -pix_fmt yvyu422 -i /dev/video0 \
-f alsa -ac 2 -ar 44100 -i hw:1,0 \
-vcodec libx264 -preset veryfast -b:v 512000 \
-acodec libfdk_aac -b:a 256000 -ar 44100 \
-f hls -hls_list_size 10 -hls_time 10 out.m3u8
avconv
の使い方こちらにまとめた avconvの使い方
Webカメラからフレームレート、解像度、フォーマットを指定して取得するには
video4linux2
以降から入力デバイスを指定するまでの間に、
-framerate
-input_format
-video_size
width:height
を指定する。
Encoding example
Example to encode video from
/dev/video0
:ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 output.mkv
… This webcam from my example can support both a raw and compressed format, and you can tell ffmpeg which one you want with the
-input_format
input option. This example will copy the video stream (no re-encoding):ffmpeg -f video4linux2 -input_format mjpeg -i /dev/video0 -c:v copy output.mkv
….
さらに、Webカメラの入力フォーマットYUV4:2:2だが、
これを直接扱う、またはavconv
がYUV4:2:0と認識して変換を行ってしまうと表示がされない問題が生じた。
… As for your command I recommend adding
-pix_fmt yuv420p
as an output option. Otherwise ffmpeg may select 4:2:2 as shown in your output and I don’t know any non-FFmpeg based players that can handle that. …
-pix_fmt yuv420p
画像形式を YUV 形式で YUV420 に指定。jpeg をそのまま動画にすると YUV422 になり、 Mac の QuickTime で再生できなかった。一般的な変換である YUV420 に変換した。
-vf format=yuv420p
という書式もある。どちらが好ましいのか分からなかった。
この問題に関しては入力側に-pix_fmt yvyu422
を指定することで解決した。おそらくHLSに変換する過程で
yuyv422 -> yuv420p 変換が自動的に行われている。
利用できるカメラの情報を取得する方法は Linux: 利用できるWebカメラの情報を取得するにまとめた。
ここまでの指定が
avconv -f video4linux2 -input_format mjpeg -video_size 1280x720 -pix_fmt yvyu422 -i /dev/video0
になる。
適切なALSAデバイスからサンプリングレート、チャンネル数を指定して音声を取得するには
alsa
以降から入力デバイスを指定するまでの間に、
-ac
-ar
を指定する。
Record audio from your microphone
When doing screencast recordings, you usually want to record your voice too:
ffmpeg -f alsa -ac 1 -ar 44100 -i hw:0 -t 30 out.wav
Looking at our example device listing, this would be the same as this:
ffmpeg -f alsa -ac 1 -ar 44100 -i default:CARD=ICH5 -t 30 out.wav
利用できるALSAデバイスをの情報を取得する方法は、 Linux: 利用できるオーディオデバイスの情報を取得する にまとめた。
ここまでの指定が
-f alsa -ac 2 -ar 44100 -i hw:1,0
になる。
libx264で手軽に圧縮方法などを指定するにはプリセットを用いる。
H.264のプリセット
ffmpegのH.264の説明を読みます。
https://trac.ffmpeg.org/wiki/Encode/H.264
プリセットはエンコードのスピードと圧縮率に影響をもたらすオプションのコレクションです、と。 遅いプリセットほどより良い圧縮を提供します。そして、速いほうから順に、 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placeboで、 placeboは非常に遅いですが圧縮率もveryslowと1%くらいしか変わらないので無視してください、と書いてあります。 デフォルトは、mediumです。
圧縮は画質に影響するのかという点について、プリセットとは別に画質は
-crf
オプションで指定します。 また-tune
オプションで最適化されます。今回は-crf 18
(ほぼ無劣化に見える品質)と-tune film
(実写最適化)を指定します。
まとめと考察
veryfastが優秀なので採用。 動画によって(実写、アニメ、ノイズの量など)結果は異なると思うので、試してみるのが大事。 値はマシンスペックに依存する部分もありますが、比率はあまり変わらないと思います。
ライブ配信はエンコードが実時間より短くなければならない。 なのでまとめにあがっているようにveryfastを採用しようと思う。
また、今回はビットレートでの指定を行う。配信するファイルサイズがわかりやすい方がよい。
ビットレートの指定方法はこちらにまとめた avconvの使い方。
ここまでの指定が
-vcodec libx264 -preset veryfast -b:v 512000
となる。
こちらもまずはプロファイルを指定する。
AAC-LC(AAC Low Complexity)
AACの基本機能のみで構成されたもの。一般的にAACと言えばこのAAC-LCを指す。
MP3と比べて特に低ビットレートにおいて音質が良い。192kbps以上ではMP3との顕著な差はないものの、概ねAACが良質である。 80kbps以下の低ビットレートでは音が破綻することがある。
HE-AAC(High-Efficiency AAC)
通常のAACにSBR(Spectral Band Replication、スペクトル帯域複製)という疑似補完技術を組み込んだもの。
あらかじめ圧縮によって失われる高周波数部分を抜き出し、圧縮後も残る低い周波数の部分との関連を分析し、 SBRという補助的なパラメータとして保存する。低周波数部分はAACとして圧縮される。 再生する際は、中低音域のAACに加えて、圧縮の際にカットされて失われた高音域をSBRデータを元に復元して合成する。
AAC+SBRという形式のため、HE-AACに対応してないデコーダーでも、低音質にはなるもののAAC部分のみを再生できる特長がある。
AAC-LCより高圧縮であり、特に48~80kbps程度の低ビットレートで音の破綻を防ぐのに効果がある。一方でそれ以上はビットレートを上げても音質がそれほど向上しない性質を持つ。
fdk-aac の使い方
ffmpeg -i infile -acodec libfdk_aac -profile:a aac_he -ab 48k -ar 44100 -ac 2 -afterburner 1 out.m4a
-profile:a
で指定できるのが
aac_low
- AAC-LC 何も指定しないとこれになる
aac_he
- HE-AAC 44.1kHzでは28kから使える 推奨32k-48k
aac_he_v2
- HE-AACv2 44.1kHzでは28k-64kまで使える 推奨16-24k(24kHz,22.05kHz)
aac_ld
- AAC-LD flashで再生不可
aac_eld
- AAC-ELD flashで再生不可
音質に重点を置いた高ビットレートでの配信ならばHE-AACを使う必要はない。なので今回-profile:a
の指定はしなかった。
ビットレートやサンプリングレートの指定方法はこちらに avconvの使い方。
ここまでの指定が
-acodec libfdk_aac -b:a 256000 -ar 44100
最後にHLSの指定を行う。
2種類のファイルを用意して動画配信する
HLSでは、 (1)「.ts」形式の「動画」ファイル と、 (2)「.m3u8」形式のプレイリストファイル という、 2種類のファイルのみでライブ動画配信を実現します。
.tsファイル(動画)
.tsファイルは、配信映像が数秒の長さに分割された動画ファイルです。 ひとつのライブ配信に対して、大量の.tsファイルが使用されます。
.m3u8(プレイリスト)
一方、.m3u8ファイルは、ひとつのライブ配信に対してひとつで十分です。
しかし.m3u8は、ライブ配信「全体」のプレイリストではなく、 ライブ配信の「一部」の.tsファイルについてのみのプレイリストとなっています。
どういうことかというと、時間が経過するに従って、 .m3u8ファイルの内容は更新され、プレイリストの内容が少しずつ前進していくのです。
そのため、.m3u8には、「何番目の.tsファイルを起点とするプレイリストか」という情報と 「各.tsファイルのURL・長さ」という情報に加えて、 「プレイリスト自体の更新頻度(秒)」 に関する情報が掲載されています。
なので個別に.tsファイルを吐き出してプレイリストを更新し続ければ配信は可能だが、
avconv
は既にHLS用の出力をサポートしている。
HLS出力は拡張子.m3u8
を見てHLS出力をしてくれるようだが、
一応-f hls
でHLSフォーマットを指定しておく。
暗号化など、特に指定しない場合は
-hls_time seconds
-hls_list_size size
の2点だけ指定、あるいは既定値のまま実行で問題ない。
15.4 hls
Apple HTTP Live Streaming muxer that segments MPEG-TS according to the HTTP Live Streaming specification.
It creates a playlist file and numbered segment files. The output filename specifies the playlist filename; the segment filenames receive the same basename as the playlist, a sequential number and a
.ts
extension.avconv -i in.nut out.m3u8
-hls_time seconds
- Set the segment length in seconds.
-hls_list_size size
- Set the maximum number of playlist entries.
….
Got it!
The Mini Recorder shoots at 10 bits rather than 8 (which I assumed considering Adobe’s live encoder said it would be 8).
Here is the fixed code:
./bmdcapture -m 14 -p yuv10 -C 0 -F nut -f pipe:1 \ | avconv -vsync passthrough -y -i - -vcodec copy -pix_fmt uyvy422 -strict experimental \ -f hls -hls_list_size 999 +live -strict experimental out.m3u8
ここまでの指定が
-f hls -hls_list_size 10 -hls_time 10 out.m3u8
になる。
ここまでを続けて記述したのが冒頭の
avconv -f video4linux2 -input_format mjpeg -video_size 1280x720 -pix_fmt yvyu422 -i /dev/video0 \
-f alsa -ac 2 -ar 44100 -i hw:1,0 \
-vcodec libx264 -preset veryfast -b:v 512000 \
-acodec libfdk_aac -b:a 256000 -ar 44100 \
-f hls -hls_list_size 10 -hls_time 10 out.m3u8
になる。この引数から必要な部分を変更すればそれに応じたHLS用のファイルが出力されるようになる。
ただ、古い.tsファイルが延々と残り続けるので長時間の配信の場合、適宜削除していかねばならない。
上記引数を/var/www/html
で実行した場合、
http://WebサーバのURL/out.m3u8
でライブストリーミングを見ることができる。