Janus のインストール
〜 WebRTC サーバの実装 〜
2026-05-05 作成 福島
TOP > tips > janus
[ TIPS | TOYS | OTAKU | LINK | MOVIE | CGI | AvTitle | ConfuTerm | HIST | AnSt | Asob | Shell | GBC | LLM ]

0. 前置き

WebRTC サーバである Janus (読み: ヤヌス) をインストールします。
WebRTC は簡単に言うと、音声や動画を中継するシステムです。
Janus のクライアントアプリはサンプルが提供されています。

本稿では Janus を LAN (192.168.xx.xx) で稼働させ、サーバとして Linux を、
クライアントとしてスマートフォンでサンプルを動作させることを前提とします。
(対応確認のために PC の Web ブラウザも使用しています)

LAN で WebRTC を使用する場合はスマートフォンの対応に偏りがあり、
すべてのスマートフォンで使用できるわけではなく、Firefox や Safari ではマイクやカメラが許可されません。

マイク / カメラ入力の対応状況 (LAN)
動作可否OS / 基本ソフトWeb ブラウザ備考
Android 15Chrome 147.0.7727.137OK 問題なし
×Firefox 150.0.1マイク / カメラ ともにエラー
iOS 18.7.8Chrome 147.0.7727.99OK 問題なし
×Firefox 150.1マイク / カメラ ともにエラー
×Safari/604.1
Windows11 Pro 24H2Chrome 147.0.7727.138Echo Test はエラー
Audio Room はエラーにならない
Firefox 150.0.1
Microsoft Edge 147.0.3912.98
×macOS Sequoia 15.7.2Chrome 147.0.7727.138https: で LAN に接続できない
×Firefox 150.0.1マイク / カメラ ともにエラー
×Safari 26.3

Janus のインストール環境
• AlmaLinux release 10.0 (Purple Lion)
(IP アドレス: 192.168.11.20/24)
• Janus version: 1203 (1.2.3)


1. Janus のインストール

今回はこれに従う。

1-1. Janus をコンパイルするために開発ツールをインストールする。
$ su
# dnf install -y epel-release
# dnf config-manager --set-enabled crb
# dnf groupinstall -y "Development Tools"
# dnf install -y git wget make cmake gcc gcc-c++ kernel-devel libtool autoconf automake pkgconfig which
# dnf install -y libmicrohttpd-devel jansson-devel libsrtp-devel libnice-devel glib2-devel opus-devel libogg-devel \
libcurl-devel libconfig-devel libwebsockets libwebsockets-devel gengetopt lua-devel
# exit
1-2. Janus をコンパイルする。
$ wget https://github.com/meetecho/janus-gateway/archive/refs/tags/v1.2.3.tar.gz
$ tar xzf v1.2.3.tar.gz
$ cd janus-gateway-1.2.3/
janus-gateway-1.2.3/$ ./autogen.sh
janus-gateway-1.2.3/$ ./configure --prefix=/opt/janus \
--disable-rabbitmq --disable-mqtt --disable-data-channels \
--enable-rest --enable-websockets --enable-recordings
janus-gateway-1.2.3/$ make
1-3. Janus をインストールする。
janus-gateway-1.2.3/$ su
janus-gateway-1.2.3/# make install
janus-gateway-1.2.3/# make configs
janus-gateway-1.2.3/# exit

janus-gateway-1.2.3/$ /opt/janus/bin/janus --version
Janus version: 1203 (1.2.3)
Janus commit: not-a-git-repo
Compiled on:  Fri Oct 24 03:28:55 AM JST 2025  

janus-gateway-1.2.3/$ ls -ogh /opt/janus/share/janus/html/demos/ | head
total 884K
-rw-r--r--. 1 9.9K Oct 25 00:54 admin.html
-rw-r--r--. 1  53K Oct 25 00:54 admin.js
-rw-r--r--. 1 5.6K Oct 25 00:54 audiobridge.html
-rw-r--r--. 1  21K Oct 25 00:54 audiobridge.js
drwxr-xr-x. 2   84 Oct 25 00:54 background
-rw-r--r--. 1 8.4K Oct 25 00:54 canvas.html
-rw-r--r--. 1  25K Oct 25 00:54 canvas.js
-rw-r--r--. 1 7.5K Oct 25 00:54 devices.html
-rw-r--r--. 1  30K Oct 25 00:54 devices.js
janus-gateway-1.2.3/$ cd
$
1-4. 動作確認用に RTP (UDP) の使用範囲を狭くする。
動作確認やリバースプロキシをしないなら、この設定は不要。

$ su
# vim /opt/janus/etc/janus/janus.jcfg


media: { #ipv6 = true #ipv6_linklocal = true #min_nack_queue = 500 rtp_port_range = "10000-10009" #dtls_mtu = 1200 #no_media_timer = 1 #slowlink_threshold = 4 #twcc_period = 100 #dtls_timeout = 500 # Janus は、キーフレームに関係する NACK キューに対して最適化を行うことができます。 # 具体的には、キーフレームがユーザーに送信される都度に NACK バッファを空にするよう Janus を設定できます。 # これにより、Janus はキーフレームが送信される直前に送信されたパケットに対する NACK 要求を無視できます。 # これは、キーフレームによってユーザーに完全に機能する画像が復元されると想定できるためです。 # (これが、ビデオの再送信が一般的に必要な主な理由です) # この最適化はほとんどの場合正常に動作することが知られていますが、 # 一部の極端な場合は逆効果になる可能性があるため、デフォルトでは無効になっています。 #nack_optimizations = true # もし DSCP パケットのマーキングと優先順位付けが必要なら dscp プロパティを特定の値に設定できます。 # そして Janus は libnice を使用して、すべての送信パケットにその値を設定しようとします。 # 通常は音声、ビデオ、データのいずれを使用ときに応じて異なる値を使用しろと言われていますが、 # Janus ではすべてのピア接続がが束ねられているため、使用できるのは 1 つだけです。 # 詳細については、次の文書を参照してください。 # https://tools.ietf.org/html/draft-ietf-tsvwg-rtcweb-qos-18#page-6 # 意味がわからない場合は、この設定に触れないでください。 #dscp = 46 }
(標準は rtp_port_range = "20000-40000")

# exit
$
1-5. ファイアウォールを設定する。
$ su
# firewall-cmd --permanent --add-port=8080/tcp --add-port=8443/tcp # デモサイト表示用
# firewall-cmd --permanent --add-port=8088/tcp --add-port=8188/tcp # Janus 本体用
# firewall-cmd --permanent --add-port=8089/tcp --add-port=8989/tcp # Janus 本体用 (secure)
# firewall-cmd --permanent --add-port=10000-10009/udp # Janus 本体用
# firewall-cmd --reload
# firewall-cmd --list-ports
8080/tcp 8088/tcp 8089/tcp 8188/tcp 8443/tcp 8989/tcp 10000-10009/udp  
# exit
$
1-6. Janus を起動する。
$ /opt/janus/bin/janus &

• 起動を確認する。(1)
$ curl -s http://192.168.11.20:8088/janus/info | head
{
   "janus": "server_info",
   "transaction": "ijB64zwFjbD",
   "name": "Janus WebRTC Server",
   "version": 1203,
   "version_string": "1.2.3",
   "author": "Meetecho s.r.l.",
   "commit-hash": "not-a-git-repo",
   "compile-time": "2025年 10月 25日 土曜日 11:34:16 JST",
   "log-to-stdout": true,
• 起動を確認する。(2)
$ curl -s http://192.168.11.20:8188/ | tidy -q -i 2> /dev/null
<!DOCTYPE html>
<html>
<head>
  <meta name="generator" content=
  "HTML Tidy for HTML5 for Linux version 5.8.0">
  <link rel="stylesheet" type="text/css" href="/error.css">
  <title></title>
</head>
<body>
  <h1>403</h1>
</body>
</html>


2. 証明書の発行

LAN なので正規の証明書は使用できない。自己発行の証明書を作成する。

2-1. 自己証明書を作成する。
$ su
# mkdir -p /opt/janus/etc/janus/certs/
# cd /opt/janus/etc/janus/certs/
/opt/janus/etc/janus/certs/# openssl req -x509 -newkey rsa:2048 -nodes \
-keyout ./janus.key -out ./janus.pem \
-days 3650 -subj /CN=192.168.11.20
/opt/janus/etc/janus/certs/# chmod 600 ./janus.key
/opt/janus/etc/janus/certs/# ls -ogh

/opt/janus/etc/janus/certs/# openssl x509 -in ./janus.pem -text -noout | head
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            5b:3a:a6:de:aa:93:dd:c6:93:ee:50:ae:95:aa:66:eb:c7:c5:7a:5a
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=192.168.11.20
        Validity
            Not Before: Nov 10 06:44:14 2025 GMT
            Not After : Nov  8 06:44:14 2035 GMT
2-2. 証明書を組み込む。
/opt/janus/etc/janus/certs/# cd /opt/janus/etc/janus/

Janus 全体の設定ファイルに公開鍵ペアのファイル位置を記述する。
/opt/janus/etc/janus/# vim janus.jcfg
 • janus.jcfg
certificates: {
    cert_pem = "/opt/janus/etc/janus/certs/janus.pem"
    cert_key = "/opt/janus/etc/janus/certs/janus.key"
    #cert_pwd = "secretpassphrase"
    # ……
}
http 通信の設定ファイルに公開鍵ペアのファイル位置と https の許可を記述する。
/opt/janus/etc/janus/# vim janus.transport.http.jcfg
 • janus.transport.http.jcfg
general: {
    #events = true
    json = "indented"

    base_path = "/janus"
    http = true
    port = 8088
    #interface = "eth0"
    #ip = "192.168.0.1"

    https = true
    secure_port = 8089
    #secure_interface = "eth0"
    #secure_ip = "192.168.0.1"
    #acl = "127.,192.168.0."
    #acl_forwarded = true

    #mhd_connection_limit = 1020
    #mhd_debug = false
}

# ……
certificates: {
    cert_pem = "/opt/janus/etc/janus/certs/janus.pem"
    cert_key = "/opt/janus/etc/janus/certs/janus.key"
    #cert_pwd = "secretpassphrase"
    # ……
}
websocket 通信の設定ファイルに公開鍵ペアのファイル位置と wss の許可を記述する。
/opt/janus/etc/janus/# vim janus.transport.websockets.jcfg
 • janus.transport.websockets.jcfg
general: {
    #events = true
    json = "indented"

    #pingpong_trigger = 30
    #pingpong_timeout = 10

    ws = true
    ws_port = 8188
    #ws_interface = "eth0"
    #ws_ip = "192.168.0.1"
    #ws_unix = "/run/ws.sock"

    wss = true
    wss_port = 8989
    #wss_interface = "eth0"
    #wss_ip = "192.168.0.1"
    #wss_unix = "/run/wss.sock"
    #ws_logging = "err,warn"

    #ws_acl = "127.,192.168.0."
    #ws_acl_forwarded = true
}

# ……
certificates: {
    cert_pem = "/opt/janus/etc/janus/certs/janus.pem"
    cert_key = "/opt/janus/etc/janus/certs/janus.key"
    #cert_pwd = "secretpassphrase"
    # ……
}
2-3. Janus を再起動する。
• Janus を停止する。
/opt/janus/etc/janus/# ps ax | grep janus
 159676 pts/0    Sl     0:00 /opt/janus/bin/janus   ← これ  
 159700 pts/0    S+     0:00 grep --color=auto janus
/opt/janus/etc/janus/# kill 159676
(プロセスが 1 つしかないと分かっているなら pkill janus でも可)

• Janus を起動する。(公開鍵を root で作成したため root で起動する)
/opt/janus/etc/janus/# /opt/janus/bin/janus &
/opt/janus/etc/janus/# exit
$
2-4. デフォルトルートの変更について (必要なら)
起動時のメッセージが以下のように表示される。
Using 192.168.11.20 as local IP... はデフォルトルートを指しているので、
これを変更する場合は (設定ファイルではなく) OS のデフォルトルートを変更する。
Janus version: 1203 (1.2.3)
Janus commit: not-a-git-repo
Compiled on:  2025? 10? 25? ??? 11:34:16 JST

Logger plugins folder: /opt/janus/lib/janus/loggers
[WARN]  Couldn't access logger plugins folder...
---------------------------------------------------
  Starting Meetecho Janus (WebRTC Server) v1.2.3
---------------------------------------------------

Checking command line arguments...
Debug/log level is 4
Debug/log timestamps are disabled
Debug/log colors are enabled
Adding 'vmnet' to the ICE ignore list...
Using 192.168.11.20 as local IP...  ← これはデフォルトルート
Token based authentication disabled
Initializing recorder code
RTP port range: 10000 -- 10009
  ……


3. 動作確認 (http / https)

3-1. Linux クライアントから動作確認する。
トランザクションを生成する。
$ curl -k -X POST https://192.168.11.20:8089/janus \
-H 'Content-Type: application/json' \
-d '{"janus":"create", "transaction":"test1"}'
{
   "janus": "success",
   "transaction": "test1",
   "data": {
      "id": 0123456789012345    ← 生成されたトランザクション ID (毎回異なる値)
   }
}

トランザクションにプラグインを接続する。(上記で生成されたトランザクション ID を指定)
$ curl -k -X POST https://192.168.11.20:8089/janus/0123456789012345 \
-H 'Content-Type: application/json' \
-d '{"janus":"attach", "transaction":"test2", "plugin":"janus.plugin.echotest"}'
{
   "janus": "success",
   "session_id": 0123456789012345,
   "transaction": "test2",
   "data": {
      "id": 1123456789012345
   }
}

エラーにならなければ OK
この例では二つとも "janus": "success" になっている。
3-2. Windows クライアントから動作確認する。
Windows で標準の curl は異常なので正常へ変更してから実行する。

− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # トランザクションを作成する
PS C:\> curl -k -X POST https://192.168.11.20:8089/janus `
 -H 'Content-Type: application/json' `
 -d '{"""janus""":"""create""","""transaction""":"""test1"""}' 
{
   "janus": "success",
   "transaction": "test1",
   "data": {
      "id": 2123456789012345  ← 生成されたトランザクション ID (毎回異なる値)
   }
}

PS C:\> # トランザクションにプラグインを接続する (上記で生成されたトランザクション ID を指定)
PS C:\> curl -k -X POST https://192.168.11.20:8089/janus/2123456789012345 `
 -H 'Content-Type: application/json' `
 -d '{"""janus""":"""attach""", """transaction""":"""test2""",
      """plugin""":"""janus.plugin.echotest"""}' 
{
   "janus": "success",
   "session_id": 2123456789012345,
   "transaction": "test2",
   "data": {
      "id": 3123456789012345
   }
}

PS C:\> exit 

PoorShell ではアホみたいにダブルクォートを記入しなければならない。

エラーにならなければ OK
この例では二つとも "janus": "success" になっている。


4. 動作確認 (websocket wss)

websocket は tcp だがプロトコルが単純でないため curl や wsbsocat では動作確認できない。
Python で動作確認する。

4-1. Linux クライアントから動作確認する。
4-1-1. Python のモジュール websocket-client をインストールする。
websocket と websocket-client の衝突を回避するために、両方を
一旦アンインストールしてから websocket-client をインストールし直す。
(なぜか、両方とも同じモジュール名「websocket」を名乗っている)

$ pip uninstall -y websocket websocket-client
$ pip install websocket-client
4-1-2. Python で動作確認する。
$ python << EOF | head
import websocket, ssl, uuid, json

# WebSocket で接続 (証明書の整合性を無視)
ws = websocket.create_connection(
    "wss://192.168.11.20:8989/janus",
    sslopt={"cert_reqs": ssl.CERT_NONE},
    subprotocols=["janus-protocol"]
)

# info リクエストを送信
tran_id = str(uuid.uuid4())  # トランザクション ID を生成
ws.send(json.dumps({"janus": "info", "transaction": tran_id}))

response = ws.recv()  # 応答を受信
ws.close()

print(response)   # 応答を出力
EOF
結果表示はこんな感じ
{
   "janus": "server_info",
   "transaction": "39705530-3dfb-4c1c-9c95-2b79be0caf1f",
   "name": "Janus WebRTC Server",
   "version": 1203,
   "version_string": "1.2.3",
   "author": "Meetecho s.r.l.",
   "commit-hash": "not-a-git-repo",
   "compile-time": "2025年 11月 17日 月曜日 11:33:34 JST",
   "log-to-stdout": true,
4-2. Windows クライアントから動作確認する。
4-2-1. Python のモジュール websocket-client をインストールする。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # pip を最新バージョンにする
PS C:\> python -m pip install --upgrade pip 
Requirement already satisfied: pip in c:\users\who\appdata\local\programs\python\python313\
lib\site-packages (25.3)

PS C:\> # websocket, websocket-client をアンインストールする
PS C:\> pip uninstall -y websocket websocket-client 
Found existing installation: websocket 0.2.1
Uninstalling websocket-0.2.1:
  Successfully uninstalled websocket-0.2.1
WARNING: Skipping websocket-client as it is not installed.

PS C:\> # websocket-client をインストールする
PS C:\> pip install websocket-client 
Collecting websocket-client
  Using cached websocket_client-1.9.0-py3-none-any.whl.metadata (8.3 kB)
Using cached websocket_client-1.9.0-py3-none-any.whl (82 kB)
Installing collected packages: websocket-client
Successfully installed websocket-client-1.9.0

PS C:\> exit 

4-2-2. Python で動作確認する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> @"
import websocket, ssl, uuid, json

# WebSocket で接続 (証明書の整合性を無視)
ws = websocket.create_connection(
    "wss://192.168.11.20:8989/janus",
    sslopt={"cert_reqs": ssl.CERT_NONE},
    subprotocols=["janus-protocol"]
)

# info リクエストを送信
tran_id = str(uuid.uuid4())  # トランザクション ID を生成
ws.send(json.dumps({"janus": "info", "transaction": tran_id}))

response = ws.recv()  # 応答を受信
ws.close()

print(response)   # 応答を出力
"@ | python | Select-Object -First 10 
    ↓ 実行結果 ↓

{ "janus": "server_info", "transaction": "d1ab0781-964d-4e52-9ede-757e71851940", "name": "Janus WebRTC Server", "version": 1203, "version_string": "1.2.3", "author": "Meetecho s.r.l.", "commit-hash": "not-a-git-repo", "compile-time": "2025年 11月 17日 月曜日 11:33:34 JST", "log-to-stdout": true,

PS C:\> exit


5. デモサーバを起動

Janus は通常の Web サーバを提供しないため、他の手段で Web サーバを用意する必要がある。

5-1. 設置手順に従ったデモサーバの場合。(http)
5-1-1. 対象ディレクトリへ移動
janus-gateway-1.2.3/$ cd /opt/janus/share/janus/html/
5-1-2. ポート 8080 でデモサーバを起動
/opt/janus/share/janus/html/$ python -m http.server 8080 &
5-1-3. w3m でデモサーバをアクセス (http)
/opt/janus/share/janus/html/$ w3m -dump http://192.168.11.20:8080/demos/ | head

python -m http.server からの出力 (上記 5-1-2 の出力)
192.168.11.20 - - [07/Nov/2025 16:06:35] "GET /demos/ HTTP/1.0" 200 -            

w3m の表示
Fork me on GitHub

Janus WebRTC Server: Demo Tests

Plugin demos

Echo Test         A simple Echo Test demo, with knobs to control the bitrate.
Streaming         A media Streaming demo, with sample live and on-demand
                  streams.
Video Call        A Video Call demo, a bit like AppRTC but with media passing
5-2. https を使ったデモサーバの場合。
5-2-1. 対象ディレクトリへ移動
janus-gateway-1.2.3/$ cd /opt/janus/share/janus/html/
5-2-2. ポート 8443 でデモサーバを起動
公開鍵を root で作成したため root で起動する)
/opt/janus/share/janus/html/$ su
/opt/janus/share/janus/html/# (python << EOF
import http.server, ssl

SERV_PORT = ('0.0.0.0', 8443)
crt = '/opt/janus/etc/janus/certs/janus.pem'
key = '/opt/janus/etc/janus/certs/janus.key'

# 証明書のコンテキストを用意
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile=crt, keyfile=key)

# HTTP ハンドラを用意
class Handler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

# HTTP サーバを作成して HTTPS にラップ
httpd = http.server.HTTPServer(SERV_PORT, Handler)
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)

print(f'Serving HTTPS on {SERV_PORT}')
httpd.serve_forever()
EOF
) &
/opt/janus/share/janus/html/# exit
/opt/janus/share/janus/html/$
5-2-3. w3m でデモサーバをアクセス (https)
/opt/janus/share/janus/html/$ yes | w3m -dump https://192.168.11.20:8443/demos/ | head
自己証明書を使用しているので以下の警告(質問)が表示される。ここで y を答えるため yes コマンドを使用している。
self-signed certificate: accept? (y/n)

python << EOF からの出力 (上記 5-2-2 の出力)
192.168.11.20 - - [16/Nov/2025 16:15:35] "GET /demos/ HTTP/1.0" 200 -            

w3m からの出力
Fork me on GitHub

Janus WebRTC Server: Demo Tests

Plugin demos

Echo Test         A simple Echo Test demo, with knobs to control the bitrate.
Streaming         A media Streaming demo, with sample live and on-demand
                  streams.
Video Call        A Video Call demo, a bit like AppRTC but with media passing


6. 動作確認 (スマートフォン)

デモサーバ https://192.168.11.20:8443/demos/ を下記ブラウザで開き、動作確認する。

LAN での動作確認なので、それぞれの端末は当該 LAN に (Wifi で) 接続しておく。
スマートフォンブラウザ
Android 15Chrome 147.0.7727.137
iOS 18.7.8Chrome 147.0.7727.99

6-1. Echo Test (独立テスト)
スマートフォンを 1 台用意し Echo Test ページから ボタンをクリックする。
(Echo Test は https://…/demos/echotest.html)

⇒ マイクで入力した音声がエコーバックされる。
6-2. Audio Room (相互テスト)
スマートフォンを 2 台用意し Audio Room ページから ボタンをクリックする。
(Audio Room は https://…/demos/audiobridge.html)

ユーザ名 (display name) を入力し ボタンをクリックする。
(Audio Room は 1 つだけ。個人情報はしゃべらないように)

⇒ マイクで入力した音声が参加者に流れる。(自分へはエコーバックされない)