2025年6月15日日曜日

janusのstreaming配信をdockerを利用して動かす


重要な点: janusは設定ファイルに不備があっても動いてしまうので、起動ログに異常が無いか見よう

この記事で最も言いたいことは「起動ログで異常が発生していないかよく見ましょう」です。
janusは設定ファイルに不備があると標準の設定ファイルに切り替えて起動するので、設定ファイルの内容を変えて再起動したのに設定が反映されてないことがあります。

不備があったときはこのような内容が表示されます。
[ERR] [config.c:janus_config_parse:205] Error parsing config file at line 81: syntax error
Failed to load /opt/janus/etc/janus/janus.jcfg, trying the INI instead...
[ERR] [config.c:janus_config_parse:191] -- Error reading configuration file 'janus.cfg'... error 2 (No such file or directory)
Error reading/parsing the configuration file in /opt/janus/etc/janus, going on with the defaults and the command line arguments
上記のログは「/opt/janus/etc/janus/janus.jcfg」の81行目に異常があることを知らせています。

起動しても設定に不備があるとそれ以後の設定を呼んでくれないことに注意です。

背景

janus(やぬす)とはWebRTCの通信の中継を行ってくれるサーバーのプログラムです。
dockerを使って動かしつつpublic ipとドメインを割り当てたサーバーで動かすのに勝手が分からず数週間ほどを要したので、備忘録として実施内容を記事に残します。

使ったもの

  • 開発用PC
    ubuntu22.04をインストールしたPCで動作確認しました。 
  • git
  • docker
  • ffmpeg
  • AWS EC2

LAN内で動かす: docker compose up

下記リポジトリをpullしてsubmoduleを更新してdocker compose upすればLAN内でjanusを試せます。
asukiaaa/janus-practice
git pull https://github.com/asukiaaa/janus-practice
cd janus-practice
docker compose up

dockerのコンテナを起動したら http://localhost:3001 でjanusのstreamingデモページを見れます。
Opus/VP8 のstramを選んでWatchを押すと、janusから配信される動画の待ち状態になります。



USBカメラを繋ぎffmpegをインストールしたubuntuで下記のコマンドを実行すると、USBカメラの動画VP8方式のrtpプロトコルでstreaming配信できます。
今回は動画だけ配信できれば良かったので、下記のコマンドは音声は無しの配信です。
/dev/video0のところはPCの状況に合わせてvideo1やvideo2に変えてください。
ffmpeg -f v4l2 \
-pix_fmt uyvy422 \
-video_size 640x480 \
-framerate 10 \
-i /dev/video0 \
-an -c:v libvpx -deadline realtime -f rtp rtp://localhost:5004

連携が成功すると localhost:3001 で動画を見れます。


要所を解説します。

janusのstreamingとhttpを有効化

streamingのサンプルページではhttpのapiでstreamingの情報取得を行っているので、httpとstreamingを有効にします。

8088ポートの/janusでapi通信可能にします。
サンプルのjcfgファイル(janus.transport.http.jcfg.sample)をコピーして使えばよいです。
janus.transport.http.jcfg
general: {
json = "indented"
base_path = "/janus"
http = true
port = 8088
}

5004ポートでコーデックがvp8のrrpの動画streamingを受け取る設定を有効にします。
サンプルのjcfgファイル(janus.plugin.streaming.jcfg.sample.in)をコピーして使えば良いです。
janus.plugin.streaming.jcfg
rtp-sample: {
type = "rtp"
id = 1
description = "Opus/VP8 live stream coming from external source"
metadata = "You can use this metadata section to put any info you want!"
audio = true
video = true
audioport = 5002
audiopt = 111
audiocodec = "opus"
videoport = 5004
videopt = 100
videocodec = "vp8"
secret = "adminpwd"
}

dockerで動かすjanusに対して上記の設定ファイルの配置と必要なポートの開放を行います。
httpのapi通雨信用に8088を、rtp受信用に5004を開きます。
rtp受信用のポートは今後受信する口が増えるのを見越して5000-5100をまとめて開いています。
docker-compose.yml
services:
janus:
ports:
- "5000-5100:5000-5100/udp" # rtp input
- "8088:8088" # general

ビルド済みのコンテナ(sucwangsr/janus-webrtc-gateway-docker)を使う場合は設定ファイルを /usr/local/etc/janus/ に置きます。
自前でビルドする場合はjanus-gatewayビルド時のprefixのパスに応じて配置場所が変わります。
docker-compose.yml
services:
janus:
image: 'sucwangsr/janus-webrtc-gateway-docker:1.3.0-slim'
volumes:
- type: bind
source: ./janus/config/janus.transport.http.jcfg
target: /usr/local/etc/janus/janus.transport.http.jcfg
- type: bind
source: ./janus/config/janus.plugin.streaming.jcfg
target: /usr/local/etc/janus/janus.plugin.streaming.jcfg
ports:
- "5000-5100:5000-5100/udp" # rtp input
- "8088:8088" # general

janusのstreamingのhtmlとjsをwebpack環境で3001に配信

今回動作例として紹介するdockerコンテナjanus-interface-webpackjanusのstreamingのデモページで使われるjsとhtmlファイルの一部を修正しつつ配信し、nodejsのjanus-gatewayライブラリと組み合わせて動作させ、webpackでまとめています。
自前でfrontendを作る場合はnodejsやwebpackと組み合わせ構成する場合があると思うので、この構成にしました。
各ファイルの概要を解説します。

janus-interface-webpack/index.html
janus-gateway/html/demos/streaming.htmlの不要な依存を削除してwebpackでまとめたjsファイルを取り込む設定にしたhtmlファイルです。

janus-interface-webpack/src/main.js
janus-gateway/html/demos/streaming.jsをwebpackでビルド時にエラーにならないよう一部を修正しつつ、janus-gatewayをnodejsのライブラリをimportする方式で利用するjsファイルです。

janus-interface-webpack/package.json
nodejsのライブラリとしてjanus-gatewayやwebpackを取り込んでいます。

janus-interface-webpack/webpack.config.js
webpackの設定です。
janus-gatewayライブラリはwebrtc-adapterがadapterとして定義済みの環境で動かされる前提のコードになっているため、ProvidePluginを利用してwebrtc-adapterをadapterとして定義しています。
janus-interface-webpack/webpack.config.js
const webpack = require('webpack');

module.exports = {
plugins: [
new webpack.ProvidePlugin({ adapter: ['webrtc-adapter', 'default'] }),
],
devServer: {
allowedHosts: "all",
static: ".",
compress: true,
port: process.env.PORT,
},
}

webpackのdev serverで利用するポートはdocker-composeで指定したかったので、process.envを利用して環境変数のPORTを使っています。
janus-interface-webpack/webpack.config.js
const webpack = require('webpack');

module.exports = {
devServer: {
port: process.env.PORT,
},
}

docker-compose.yml
webpackのdev server機能でhtmlとjsをportは3001ポートで配信します。
docker-compose.yml
services:
janus-interface-webpack:
image: node:23-bullseye
working_dir: /app
command: bash -c "yarn && npx --yes webpack serve"
volumes:
- ./janus-interface-webpack:/app
ports:
- 3001:3001
environment:
- PORT=3001

概要説明は以上です。
詳しい設定が知りたい方はgithubで公開しているコードをご覧いただくか、ブログのコメントで追加説明希望箇所をご要望ください。

public ipのサーバーで動かす

LANで動かす場合に加えてこれらの設定追加が必要です。
これらの設定は固有のpublic ipやhost名などを含むためリポジトリには含めていません。

nat_1_1_mappingにサーバーのpublic ipを記述

janusは自身が動いている環境のpublic ipを把握できないようなので、janus.jcfgのnatにnat_1_1_mappingとしてipを記述します。
janus.jcfg
nat: {
  nat_1_1_mapping = "3.333.222.222" # janusを動かすサーバーのpublic ip
}

docker-composeに記述を追加してjanus.jcfgをjanusに読み込ませます。
docker-compose.yml
services:
janus:
volumes:
- type: bind
source: ./janus/config/janus.jcfg
target: /usr/local/etc/janus/janus.jcfg

ドメインを割り当てる場合、apiやhtmlの配信口をtls(https)対応

janusにtls機能はありますが、プロキシサーバー(apacheやnginx)を使うならそれらに任せても良いです。
以前把握したswagを利用したtls対応を行う場合は、下記のような設定で可能です。

紹介する設定のsome.your-domain.comの箇所を自身のドメイン名に置き換えてください。

webpack dev serverはwebsocketを使うので、その設定も有効にしています。
なお、今回は説明量低減のためwebpack dev serverをpublic ipで動かしていますが、本番環境では不適切なので、本番環境ではpublic buildしたjsとhtmlを80ポートで配信などの変更を行ってください。
swag/config/nginx/proxy-confs/your-domain.subdomain.conf(subdomain.conf で終わるファイル)
## Version 2024/12/17 - Changelog: https://github.com/linuxserver/docker-swag/commits/master/root/defaults/nginx/site-confs/default.conf.sample
# for janus http api
server {
listen 8089 ssl;
listen [::]:8089 ssl;
ssl_certificate /config/keys/cert.crt;
ssl_certificate_key /config/keys/cert.key;

server_name some.your-domain.com;
include /config/nginx/ssl.conf;

location / {
proxy_pass http://janus:8088;
# proxy_pass http://host.docker.internal:8088;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}

# janus interface webpack
server {
listen 3001 ssl;
listen [::]:3001 ssl;
ssl_certificate /config/keys/cert.crt;
ssl_certificate_key /config/keys/cert.key;
include /config/nginx/ssl.conf;

server_name some.your-domain.com;

location /ws {
proxy_pass http://janus-interface-webpack:3001/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}

location / {
proxy_pass http://janus-interface-webpack:3001;
}
}

利用するドメイン名を指定しつつswagを起動します。
3001番ポートはswagを介してtls化したので、webpack-interfaceコンテナは閉じ、swagで開きます。
docker-compose.yml
services:
swag:
image: lscr.io/linuxserver/swag
container_name: swag
depends_on:
- back
- janus
- janus-interface-webpack
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Tokyo
- URL=some.your-domain.com
# - SUBDOMAINS=www,
- VALIDATION=http
# - CERTPROVIDER= #optional
# - DNSPLUGIN=cloudflare #optional
# - EMAIL=<e-mail> #optional
# - ONLY_SUBDOMAINS=false #optional
# - EXTRA_DOMAINS=<extradomains> #optional
- STAGING=false #optional
volumes:
- ./swag/config:/config
ports:
# - 443:443
# - 80:80
- 3001:3001
- "8089:8089" # general secure
# - "8989:8989" # wss
# - "7989:7989" # admin wss
restart: unless-stopped

AWSのEC2を使う場合はセキュリティグループのインバウンドルールに設定を追加して該当するポートを開放

この記事で利用するポートはこれらです。
3001 tcp: webpackで配信するinterface
8089 tcp: tls対応後のjausのhttp api
5000-5100 udp: janusのrtp受信用ポート

EC2で使う場合はこれらを開いておきます。




おわり

janusをdockerで動かす方法とpublic ipを割り当てたサーバーで動かす方法を把握しました。
自分でも大雑把な説明だとは思いますが、取り組んだことの記録や解説が無いよりは良いと思ったので記事にまとめました。
解説におかしなところがあればコメントなどでご指摘いただけると嬉しいです。

参考

この記事で紹介したdocker関係の設定やプログラムを公開しているリポジトリです。
https://github.com/asukiaaa/janus-practice

全体の流れを参考にした記事です。
【JanusでWebRTCのサーバーを構築してみた】githubやプラグインも紹介
GStreamer から WebRTC Janus に配信を行う
docker-webrtc-janus

ffmpegコマンドを参考にしたページです。
WebRTCを動かしてみる(Janus版)
ffmpeg publishing VP8 to Janus Gateway 100% CPU MBP

janus公式の困りごと相談ページです。
https://janus.discourse.group/

janusのプログラムを管理するリポジトリです。
https://github.com/meetecho/janus-gateway

0 件のコメント :