ubuntuサーバーでgstreamerを使用し(Secure Reliable Transport)、srt配信し、srt受信ができるようにしてみた。ついでにHLS,DASH変換もしてみる
正式名(Secure Reliable Transport)で前々から目を付けていLarix BroadcasterとOBS,libVLCで映像配信、視聴をしていましたが、今回簡単ではありますがgstreamerを使用し、srt配信・受信の環境を構築してみました。
gstreamerを使う理由として、SRTのビルド後に「srt-live-transmit」というアプリケーションがあり、これを使用し、配信ができるのですが、視聴側が1人のみで複数人で視聴ができないので、gstreamerを使用します。複数人の受信が実現する方法がgstreamerだったので使うことにしました。
# 確認方法
cat /etc/issue
gst-inspect-1.0 --version
UbuntuにSRTをインストールします。インストール方法はgithubからソースコードダウンロードし、cmakeでビルドをする必要があります。
Haivisiongithubからダウンロードができます。
# git install
sudo apt install git
# clone source
git clone https://github.com/Haivision/srt.git
次にcmakeを使うために必要なものをインストールし、ビルドを実行します。
ビルド方法は公式から確認ができます。
## 公式から引用
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install tclsh pkg-config cmake libssl-dev build-essential
cd srt
./configure
sudo make install
ビルドが完了後次のようにファイルが生成されていればOKです。
他の記事ではgstreamerはSRTバージョン1.4.2が必要だと言うことでしたが、ビルドが通らず、最新のSRTでビルドしたらできたので1.5.2を使用します。
SRTのインストール作業が終わりましたので、次はgstreamerのプラグインをインストールしていきます。
sudo apt install gstreamer1.0-plugins-bad gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly
プラグインが追加されているのかを確認します。
gst-inspect-1.0 |grep srt
#出力例
srt: srtclientsink: SRT sink
srt: srtclientsrc: SRT source
srt: srtserversink: SRT sink
srt: srtserversrc: SRT source
srt: srtsink: SRT sink
srt: srtsrc: SRT source
ここまで確認出来たら、次は実際にgstreamerを起動してみます。
gst-launch-1.0 srtclientsrc uri="srt://:1234" ! srtserversink uri="srt://:5678"
gstreamerの起動ができたので、次にgstreamerに映像を送信し、gstreamerの映像を受信するクライアント側をテストします。
srt配信にはffmpeg obsがあります。どちらでも問題ありません。
配信と受信はWindowsPCで確認しています。
ffmpegでsrt映像配信を行います。
ffmpeg -re -stream_loop -1 -i "videofilename.mp4" -c:v libx264 -preset ultrafast -tune zerolatency -c:a aac -f mpegts "srt://192.168.1.123:1234?mode=caller"
# 使用する際変更するべき部分
# videofilename.mp4
# srt:ipaddress:port
次に受信をしてみます。
受信はffplayが簡単なのでこれを使っていきます。
ffplay -i srt://192.168.1.108:5678 -x 300
これでsrt配信と受信ができました。
srt再生はブラウザーが非対応なため...再生が可能な端末、環境が限られています。
DASHとHLSに変換して配信している方がqiitaで公開しているので拝借します。ありがとうございます。
HLS,DASHを使うためには配信サーバー(ウェブサーバー)が必要なため、ngxinを使う。ついでに再生できるページも作る。
nginxのインストール等は別の記事でお願いします。 nginxで以下の設定をし、ipaddressでブラウザーのページがアクセスできるようにします。
http{
...省略
server{
listen 80;
location / {
root /var/www/html/live/;
}
}
}
そしてliveフォルダーに再生テスト用にhtmlを置きます。
<head>
<link href="https://vjs.zencdn.net/8.6.0/video-js.css" rel="stylesheet" />
</head>
<body>
<video
id="my-video"
class="video-js"
controls
preload="auto"
width="640"
height="264"
data-setup="{}"
>
<source src="./20231122/both/master.m3u8" type="application/x-mpegURL" />
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a
web browser that
<a href="https://videojs.com/html5-video-support/" target="_blank"
>supports HTML5 video</a
>
</p>
</video>
<script src="https://vjs.zencdn.net/8.6.0/video.min.js"></script>
</body>
source srcは変更する必要があります。
srtビルド時に作成されるsrt-live-transmitを利用し、映像を受け取り、別ポートに受け渡すスクリプト作成します。
以下はsrt2000ポートで受け取って5000ポートに受け渡す「rc.local.sh」と
HLS,DASH変換しているスクリプト「publish.sh」を作成します。
#私の場合次のようにしています。
root
├─srtstream
├──rc.local.sh
├──publish.sh
#!/bin/bash
/usr/local/bin/srt-live-transmit srt://:2000 udp://127.0.0.1:5000 -v
#!/bin/bash
TODAY=$(date '+%Y%m%d')
mkdir /var/www/html/live/$TODAY
mkdir /var/www/html/live/$TODAY/both
/usr/bin/ffmpeg \
-i udp://:5000 \
-preset ultrafast -tune zerolatency -flags +global_header \
-c:v libx264 -pix_fmt yuv420p -c:a aac -b:a 128k -ac 1 -ar 44100 \
-use_timeline 0 -use_template 1 -utc_timing_url "https://time.akamai.com/?iso" -index_correction 1 \
-live 1 -streaming 1 -f dash -seg_duration 1 -dash_segment_type mp4 \
-ldash 1 -target_latency '0.5' -write_prft 1 -window_size 3 \
-force_key_frames "expr:gte(t,n_forced*1)" \
-adaptation_sets "id=0,streams=v id=1,streams=a" \
-map v:0 -filter:v:0 "scale=-1:1080,drawtext=:text=(6000k):fontsize=32:x=32:y=32:box=1:boxcolor=white:fontcolor=black" \
-b:v:0 6000k -s:v:0 1920x1080 -profile:v:0 baseline \
-map v:0 -filter:v:1 "scale=-1:720,drawtext=:text=(3000k):fontsize=32:x=32:y=32:box=1:boxcolor=white:fontcolor=black" \
-b:v:1 3000k -s:v:1 720x480 -profile:v:1 baseline \
-map v:0 -filter:v:2 "scale=-1:360,drawtext=:text=(1500k):fontsize=32:x=32:y=32:box=1:boxcolor=white:fontcolor=black" \
-b:v:2 1500k -s:v:2 640x360 -profile:v:2 baseline \
-map 0:a \
-init_seg_name init-stream_r\$RepresentationID\$.mp4 -media_seg_name media-stream_r\$RepresentationID\$-\$Number%08d\$.mp4 \
-format_options "movflags=+cmaf" \
-hls_playlist 1 -hls_master_name master.m3u8 -hls_flags independent_segments -hls_flags program_date_time \
/var/www/html/live/$TODAY/both/manifest.mpd
その後スクリプトを実行します。 バックグランド起動は次のようにできるが、ログとかすぐ見れるのでターミナル2つ起動した方が良いかも
#フルパス
#参考程度で
nohup /srtstream/rc.local.sh &
nohup /srtstream/publish.sh &
./rc.local.sh
./publish.sh
ターミナル二つ起動した場合こんな感じになります。
ffmpeg -re -stream_loop -1 -i "video.mp4" -vf scale=480:-1,format=yuv420p -c:v h264_nvenc -c:a libmp3lame -g 15 -framerate 30 -b:v 400k -b:a 96k -maxrate 600k -pkt_size 600 -f mpegts "srt://192.168.1.11:2000"
配信が成功していると次のように画面が変わる
また、正常動作すると、日付でフォルダーが作成される。
ブラウザーで再生してみたらこんな感じ
sudo ufw allow 2000
sudo ufw allow 80
フォルダーが作成されない場合
publish.shがフォルダー作成の権限がないかもしれないので
chmod 755でpublish.shに権限を与えておく
srcのパスが間違っているかもしれないので、 ブラウザーでm3u8を直接叩いてみる
例
http://ipaddress/今日の日付/both/master.m3u8
master.m3u8がダウンロードされない場合はパスが間違っているかも
SRTをサポートされていないので現時点では不可能そのため、HLS,DASHに頼る必要がある。
HLS,DASHを使うと遅くなるのでは?
確かに4秒遅延があります。セグメント分けるという技術上、遅延はどうしようもない。
SRTは良い技術だと思うのですがブラウザーでは使えないORZ...
ブラウザーで低遅延と言えばwebRTCですが webRTC嫌い twitch のwarpと言うものがあります。そろそろ正式にブラウザー側がサポートされればいいのだが...
gstreamerを利用し、srtのライブ配信環境ができました。プロダクションレベルではありませんが、デバックレベル、テストレベルで使う分には問題なく使用できます。
srtがかなり良いと感じていましたが、普及が進まず、割とショック。配信プロトコルの中でかなり良いと思うのですが...
RTMP,WebRTC rtp, hlsがやはり主流ですね。Enhanced RTMPが次主流になっていくのかな?
質問や、間違いがありましたら、お気軽にどうぞ
※お名前とコメントの内容を入力してください。
※全てこのブログ上に公表されます。
※許可なく管理者によって修正・削除する場合がございます。 詳しくはプライバシーポリシーを参照ください