デジタル時計を載せた生放送を FFmpeg だけで実現する
生放送の遅延確認で現在時刻を載せた配信が欲しかったので作成。ついでに Docker Image 化もしてみました。
経緯
担当している某生放送サービスにて、遅延の確認や開発のために流しっぱなしの時刻つき配信が欲しかったので整備してみました。
OBS に時計を表示させれば簡単だったのですが、パブリックドメインで軽量な時計ツールが意外と無かったのと、実 PC での配信だとスケールしづらい上に何かとめんどくさいので Docker 化して自動配信にしたかったのが動機です。
最終的にはこんな感じで動画上に時計を表示させることに成功。
時計部分は FFmpeg のフィルタで合成しているので、見た目やフォントは好きなようにカスタマイズできます。
構成
Dockerfile
NotoSans-Bold.ttf
src.mp4
start.sh*
Font と MP4 はライセンス的に問題ないものを拝借。
スクリプト
start.sh
Dockerfile の ENTRYPOINT
に直接コマンドを書くとややこしくなるのと、スクリプトを直接叩いてデバッグしたかったので実行コマンドを別スクリプトにしました。
#!/bin/bash
ffmpeg -re -stream_loop -1 -i 'src.mp4' -vf "drawtext=fontfile=./NotoSans-Bold.ttf: text='%{localtime\:%F%n%n%T}': fontcolor=black@0.8:fontsize=64: x=32: y=32" -vcodec libx264 -x264-params keyint=30 -acodec aac -f flv "${TARGET_RTMP_URL}"
FFmpeg での配信コマンドについては以下の記事でも紹介してあります。
テスト用の自動配信環境を Docker と FFmpeg で構築してみる | CyberAgent Developers Blog | サイバーエージェント デベロッパーズブログ
ざっくりオプションの説明をすると、
-re
- 入力動画のフレームレート速度でファイルを読み込むオプション
- つけない場合はエンコードで処理できるスピードをそのまま出力スピードに使ってしまうので、たとえば 2 倍速でエンコードできる場合、配信が 2 倍速の動画になってしまう
-stream_loop 1
- 入力ソースを無限ループさせるオプション
-i 'src.mp4'
- 入力ソースの指定
-vf
- ビデオフィルタ
- 複数のフィルタを
:
区切りで指定できる
drawtext=fontfile=./NotoSans-Bold.ttf
- フォントファイルの指定
text='%{localtime\:%F%n%n%T}'
- 今回の肝になる時計部分。
strtime
のフォーマットで指定できる。%F
: ハイフン区切りの年月日%n
: 改行%T
::
区切りの時分秒
fontcolor=black@0.8
- 字の色
@0.8
はアルファ値(透過)。 1 が透過なし。 0 が透明。
fontsize=64
- フォントサイズ
x=32
- 表示位置(横)
y=32
- 表示位置(縦)
-vcodec libx264 -x264-params keyint=30
- ビデオコーデックの指定
- 今回は配信サービスの都合上、
H264
でKeyframe Interval
を30
にした。
-acodec aac
- 音声コーデックを
AAC
にした
- 音声コーデックを
-f flv
- 出力フォーマットの指定
- 今回は
RTMP
での配信をするためflv
指定
"${TARGET_RTMP_URL}"
- 出力先の指定
- 今回は変数にしたので、配信サービスの
RTMP
出力先 URL を指定する rtmp://hogehoge.com/hogehoge:1935
みたいな- Docker 化した場合は
-e
オプションで-e 'TARGET_RTMP_URL=rtmp://hogehoge.com/hogehoge:1935'
で指定できる
Dockerfile
FROM horiryota/ffmpeg
COPY src.mp4 ./
COPY start.sh ./
COPY NotoSans-Bold.ttf ./
ENTRYPOINT ["/bin/sh", "./start.sh"]
Dockerfile は COPY して start.sh
を叩くだけです。
ちなみに FFmpeg の Docker Image は jrottenberg/ffmpeg をお借りしようと思いましたが、時計を表示するための drawtext
フィルタを使うのに必要なビルドオプション --enable-libfreetype
が設定されていなかったので自分で用意。
FFmpeg の Dockerfile は以下。
FROM gliderlabs/alpine:3.4
ENV TZ="JST-9"
ENV FFMPEG_VERSION=3.2.4
RUN \
apk update && \
apk add --no-cache \
freetype-dev \
openssl-dev \
rtmpdump-dev \
x264-dev \
yasm-dev \
zlib-dev \
&& \
apk add --no-cache --virtual=build-dependencies \
build-base \
curl \
nasm \
tar \
bzip2 \
&& \
DIR=$(mktemp -d) && cd ${DIR} && \
wget http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz -O - | tar zxvf - -C . && \
cd ffmpeg-${FFMPEG_VERSION} && \
./configure \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--enable-small \
--disable-ffplay \
--disable-ffserver \
--disable-doc \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--enable-libx264 \
--enable-postproc \
--enable-avresample \
--enable-libfreetype \
--enable-openssl \
--disable-debug \
&& \
make && \
make install && \
make distclean && \
rm -rf ${DIR} && \
apk del build-dependencies && \
rm -rf /var/cache/apk/*
使い方
Doker Image なので以下のようなコマンドで配信できるはず。
docker run -e 'TARGET_RTMP_URL=rtmp://hogehoge.com/hogehoge:1935' horiryota/auto-broadcast
以上
とりあえず配信しっぱなしにはできたので、 CPU などのリソース表示や fps 、 bitrate などの配信状態表示にも挑戦してみたいところ。
FFmpeg はオプションが多くて全然把握しきれないので、覚えたものからメモっていきたい。