Hero img
gstreamerでsrt配信、HLS変換をしてみる

gstreamerでsrt配信、視聴、変換ができるまでのサーバー構築

ubuntuサーバーでgstreamerを使用し(Secure Reliable Transport)、srt配信し、srt受信ができるようにしてみた。ついでにHLS,DASH変換もしてみる


目次

  • SRT
  • gstreamerを使う理由
  • 環境
  • SRTインストール
  • gstreamer
  • クライアントの送信・受信
  • ffmpeg
  • マルチプラットフォーム
  • HLS,DASH
  • nginx設定
  • HLS変換
  • できない場合
  • ブラウザーで再生するには...
  • まとめ

SRT

正式名(Secure Reliable Transport)で前々から目を付けていLarix BroadcasterとOBS,libVLCで映像配信、視聴をしていましたが、今回簡単ではありますがgstreamerを使用し、srt配信・受信の環境を構築してみました。

gstreamerを使う理由

gstreamerを使う理由として、SRTのビルド後に「srt-live-transmit」というアプリケーションがあり、これを使用し、配信ができるのですが、視聴側が1人のみで複数人で視聴ができないので、gstreamerを使用します。複数人の受信が実現する方法がgstreamerだったので使うことにしました。

環境

  • Ubuntu 22.04.2 LTS
  • gst-inspect-1.0 version 1.20.3
  • libsrt.so.1.5.2
# 確認方法
cat /etc/issue
gst-inspect-1.0 --version

SRTインストール

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-complete

SRTバージョン

他の記事ではgstreamerはSRTバージョン1.4.2が必要だと言うことでしたが、ビルドが通らず、最新のSRTでビルドしたらできたので1.5.2を使用します。

gstreamer

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

ffmpegでsrt映像配信を行います。

windows-cmd
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

ffplyaで再生

次に受信をしてみます。
受信はffplayが簡単なのでこれを使っていきます。

windows-cmd
ffplay -i srt://192.168.1.108:5678 -x 300

これでsrt配信と受信ができました。 gstreamer-video-recive

マルチプラットフォーム

srt再生はブラウザーが非対応なため...再生が可能な端末、環境が限られています。
DASHとHLSに変換して配信している方がqiitaで公開しているので拝借します。ありがとうございます。

HLS,DASH

HLS,DASHを使うためには配信サーバー(ウェブサーバー)が必要なため、ngxinを使う。ついでに再生できるページも作る。

nginx設定

nginxのインストール等は別の記事でお願いします。 nginxで以下の設定をし、ipaddressでブラウザーのページがアクセスできるようにします。

nginx.conf
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>

htmlを修正

source srcは変更する必要があります。

HLS変換

srtビルド時に作成されるsrt-live-transmitを利用し、映像を受け取り、別ポートに受け渡すスクリプト作成します。
以下はsrt2000ポートで受け取って5000ポートに受け渡す「rc.local.sh」と HLS,DASH変換しているスクリプト「publish.sh」を作成します。

フォルダー構成
#私の場合次のようにしています。
root
├─srtstream
	├──rc.local.sh
	├──publish.sh
rc.local.sh
#!/bin/bash

/usr/local/bin/srt-live-transmit srt://:2000 udp://127.0.0.1:5000 -v
publish.sh
#!/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

ターミナル二つ起動した場合こんな感じになります。

gstreamer-hls-b

配信してみる

windows-cmd
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"

配信が成功していると次のように画面が変わる

gstreamer-hls-a

また、正常動作すると、日付でフォルダーが作成される。

gstreamer-hls-create-folder

ブラウザーで再生してみたらこんな感じ

gstreamer-hls-play

できない場合

ポート開放

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が次主流になっていくのかな?

関連記事

コメント

コメントを書く

質問や、間違いがありましたら、お気軽にどうぞ

※お名前とコメントの内容を入力してください。
※全てこのブログ上に公表されます。
※許可なく管理者によって修正・削除する場合がございます。 詳しくはプライバシーポリシーを参照ください