跳到主要內容

利用 Jitsi 建立個人化的視訊會議平台

 

近期因為疫情的關係,越來越多企業開始實施分流或在家工作,視訊會議的需求也日益增加。
在商用解決方案選擇上,有不少企業會選擇知名品牌的產品,例如 Cisco WebexGoogle MeetMicrosoft TeamsZoom 都是很不錯的方案。

KKBOX 集團在去年便試行及做好充分 work from home 的準備,今年五月也因應疫情升溫,全員 work from home 至今兩個月有餘。
當然,取之 Open Source,也要對社群有些貢獻。在這一屆 COSCUP,我們要來介紹 Open Source 圈中也很知名,效果也很不錯的一套視訊會議平台:Jitsi
除了基本的視訊會議功能外,在最後我們也會示範如何透過 Jitsi 畫面輸出到 YouTube/Twitch 或其他支援 RTMP 的平台進行直播。

由於篇幅有限,且 Jitsi 可以調整的細節非常多。今天我們純粹很快速的示範,如何簡單的建置出一個 Jitsi 環境,並提供單場會議內容錄影或直播。
Jitsi 的文件可以在這裡找到。

今天透過 AWS Lightsail 的 $10/month instance(1 core CPU + 2GB RAM + 60GB SSD),作業系統則是 Ubuntu 20.04 來示範。當然,使用其他 VPS 亦可,大同小異,這邊直接跳過 VPS 相關的建置過程。
*firewall 相關資料參考這裡這裡

針對系統做必要的更新

基本的 apt repository 更新:

$ sudo apt update

因為後面要示範的會議錄影及直播需要使用 ALSA loopback device,如果是 EC2 or Lightsail 則需要額外安裝 generic kernel():

$ sudo apt install linux-image-generic linux-headers-generic linux-image-extra-virtual

接著做系統套件們的更新:

$ sudo apt dist-upgrade
$ sudo apt autoremove

如果是 AWS EC2 or Lightsail 則需要另外再將預設的 AWS optimized kernel 移除():

$ sudo apt remove linux-image-aws linux-aws-* linux-image-*-aws

最後將 snd-aloop module 設為開機自動載入,重開機:

$ sudo sh -c "echo 'snd-aloop' >> /etc/modules"
$ sudo reboot

:可以參考這裡*

接著將 Jitsi 官方的 apt repository 與 gpg key 加進來,並安裝 jitsi-meet:

$ sudo sh -c "echo 'deb https://download.jitsi.org unstable/' > /etc/apt/sources.list.d/jitsi-unstable.list"
$ wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add -
$ sudo apt update
$ sudo apt install jitsi-meet

過程中會提示輸入 server hostname,在這裡我們輸入 coscup.kk.stream(請自行替換這個 hostname 為你自己的 hostname)。

在安裝過程時先選擇自己簽發憑證(self-signed)

後面再透過 Let’s Encrypt 簽發真正可用的憑證或自行替換購買的憑證:

$ sudo /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh

接下來參考這裡相關的說明,開始調整 Jitsi 設定。

調整 Prosody 的設定:

$ sudo vim /etc/prosody/conf.d/coscup.kk.stream.cfg.lua

找到 VirtualHost "coscup.kk.stream" 這一段,將裡面的 authentication = "anonymous" 改成 authentication = "internal_hashed"(關閉匿名使用模式,使用簡單帳號管理機制)

接著在 VirtualHost "coscup.kk.stream" 這一段的後面加上:

VirtualHost "guest.coscup.kk.stream"
    authentication = "anonymous"
    c2s_require_encryption = false

調整 jitsi-meet 的設定:

$ sudo vim /etc/jitsi/meet/coscup.kk.stream-config.js

找到 hosts 的區段,加上 anonymous domain 設定 anonymousdomain: 'guest.coscup.kk.stream',

調整 jicofo 設定:

$ sudo sh -c "echo 'org.jitsi.jicofo.auth.URL=XMPP:coscup.kk.stream' >> /etc/jitsi/jicofo/sip-communicator.properties"

建立一個接下來會用到的 Jitsi 管理者帳號:

$ sudo prosodyctl register <帳號名稱> coscup.kk.stream <密碼>
# 例如 sudo prosodyctl register coscup coscup.kk.stream ilovecoscup

錄影需求,接下來安裝 Jibri 與 FFmpeg 與 Google Chrome 與 Chromedriver

$ sudo apt install jibri ffmpeg
$ wget -qO - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
$ sudo sh -c "echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' > /etc/apt/sources.list.d/google-chrome.list"
$ sudo apt update
$ sudo apt install google-chrome-stable
$ sudo mkdir -p /etc/opt/chrome/policies/managed
$ sudo sh -c "echo '{ "CommandLineFlagSecurityWarningsEnabled": false }' >>/etc/opt/chrome/policies/managed/managed_policies.json"
$ CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`
$ wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -P ~/
$ unzip ~/chromedriver_linux64.zip -d ~/
$ rm ~/chromedriver_linux64.zip
$ sudo mv -f ~/chromedriver /usr/local/bin/chromedriver
$ sudo chown root:root /usr/local/bin/chromedriver
$ sudo chmod 0755 /usr/local/bin/chromedriver
$ sudo apt install default-jre-headless curl alsa-utils icewm xdotool xserver-xorg-input-void xserver-xorg-video-dummy

加上 Prosody 錄影相關的 vhost:

$ sudo vim /etc/prosody/conf.d/coscup.kk.stream.cfg.lua

加上這一段

VirtualHost "recorder.coscup.kk.stream"
    modules_enabled = {
        "ping";
    }
    authentication = "internal_plain"

建立兩個帳號給 jibri(密碼自行替換):

$ sudo prosodyctl register jibri auth.coscup.kk.stream jibriauthpass
$ sudo prosodyctl register recorder recorder.coscup.kk.stream jibrirecorderpass

調整 jicofo 的 jibri BREWERY 及 PENDING_TIMEOUT 及 SHORT_ID 參數:

$ sudo sh -c "echo 'org.jitsi.jicofo.jibri.BREWERY=JibriBrewery@internal.auth.coscup.kk.stream' >> /etc/jitsi/jicofo/sip-communicator.properties"
$ sudo sh -c "echo 'org.jitsi.jicofo.jibri.PENDING_TIMEOUT=90' >> /etc/jitsi/jicofo/sip-communicator.properties"
$ sudo sh -c "echo 'org.jitsi.jicofo.SHORT_ID=1' >> /etc/jitsi/jicofo/sip-communicator.properties"

最後開啟 Jitsi 的錄影及 live 功能:

$ sudo vim /etc/jitsi/meet/coscup.kk.stream-config.js

在 testing 區段找到相關地方調整成

        fileRecordingsEnabled: true, 
        liveStreamingEnabled: true, 
        hiddenDomain: 'recorder.coscup.kk.stream',

加上 jibri 設定:

$ sudo vim /etc/jitsi/jibri/jibri.conf

置換成這樣(其中 jibri 及 recorder 這兩個帳號的密碼要跟早先建立的相同)

jibri {
  id = "coscup.kk.stream-1"
  single-use-mode = false
  api {
    http {
      external-api-port = 2222
      internal-api-port = 3333
    }
    xmpp {
      environments = [{
        name = "COSCUP Jitsi Demo"
        xmpp-server-hosts = ["coscup.kk.stream"]
        xmpp-domain = "coscup.kk.stream"
        control-login = {
          domain = "auth.coscup.kk.stream"
          username = "jibri"
          password = "jibriauthpass"
        }
        control-muc = {
          domain = "internal.auth.coscup.kk.stream"
          room-name = "JibriBrewery"
          nickname = "jibri-nickname"
        }
        call-login = {
          domain = "recorder.coscup.kk.stream"
          username = "recorder"
          password = "jibrirecorderpass"
        }
        strip-from-room-domain = "conference."
        usage-timeout = 3 hour
        trust-all-xmpp-certs = true
      }]
    }
  }
  recording {
    recordings-directory = "/srv/recordings"
    finalize-script = ""
  }
  streaming {
    rtmp-allow-list = [
      ".*"
    ]
  }
  ffmpeg {
    resolution = "1920x1080"
    audio-source = "alsa"
    audio-device = "plug:bsnoop"
  }
  chrome {
    flags = [
      "--use-fake-ui-for-media-stream",
      "--start-maximized",
      "--kiosk",
      "--enabled",
      "--disable-infobars",
      "--autoplay-policy=no-user-gesture-required"
    ]
  }
  stats {
    enable-stats-d = true
  }
  webhook {
    subscribers = []
  }
  call-status-checks {
    no-media-timeout = 30 seconds
    all-muted-timeout = 10 minutes
    default-call-empty-timeout = 30 seconds
  }
}

建立錄影用的目錄:

$ sudo mkdir /srv/recordings
$ sudo chown jibri:jibri /srv/recordings

將 jibri 加入存取 video/audio 相關 device 的系統群組:

$ sudo usermod -aG adm,audio,video,plugdev jibri

讓 jibri 開機就跑起來:

$ sudo systemctl enable jibri

重開機,大功告成

$ sudo reboot

接著就能直接以瀏覽器打開 Jitsi,並且可以建立新的會議室:

如果主持人尚未加入,請等待主持人。

如果你就是主持人,則輸入稍早建立的管理者帳號密碼:

接著就可以邀請大家加入會議啦:

也可以建立這場會議的錄影或將其透過 RTMP 往其他直播平台輸出:

留言

這個網誌中的熱門文章

為什麼電視直播比賽總是比網路快?看低延遲串流如何搶秒數

  大多時候,你在網路上看的 Live 直播串流,其實不是與現實世界完全同步的即時轉播,先看看以下這些場景,相信對你來說並不陌生。 NBA 冠軍賽才正看到精彩處,隔壁鄰居卻突然爆出一陣歡呼,原來,用電視觀賞同一場比賽的他們,比你早 30 秒歡呼慶祝三分球入網,不小心點開社群媒體,更發現朋友們早已發文熱烈討論比賽結果。 就像電影被暴雷一樣,少了即時參與的驚喜感、提早知道結局,觀看直播活動的樂趣頓時大打折扣。 或是,收看跨年演唱會時,正當你興高采烈倒數最後 30 秒時,才發現,窗外的慶祝煙火已經此起彼落,大家都已經跨入新的一年,只有你還停留在前一年。 雖然從絕對時間來看,這些狀況都僅有延遲短短幾秒鐘,但在體感上,觀賞體驗卻大受影響,用「失之毫釐,差之千里」來形容再恰當不過。 使用直播串流時,為什麼你的世界總是比別人慢幾秒?原因正是「串流延遲」。 從攝影機到觀眾螢幕的層層關卡 串流延遲,指的是攝影機拍到影像後,直到觀眾端螢幕出現畫面的時間差。 一般來說,有線電視直播約延遲 5 到 10 秒,而 YouTube、LINE、Twitch 等多數 OTT 平台,延遲大多介於 15 秒至 30 秒,距離延遲秒數低於 3 秒的「超低延遲」(Ultra Low Latency)標準,還有一大段距離,這也讓現有直播內容的互動效果有限。 但想克服延遲並不容易,光是一段畫面要從現場攝影機,傳到電腦和手機螢幕,中間所需流程多到難以想像。 KKStream 執行副總李卓軒 Kevin C.H. Lee 解釋,這流程大致包含一開始的攝影機收取影音訊號,接著需轉換訊號、傳輸、上傳雲端、加密、備份,傳到終端裝置後再解碼,最後才是播放。 這整段「螢幕到螢幕」的過程,就像是將包裹從A點運送到B點,只要中間有幾個環節耽誤,就會讓整體運送時間不斷疊加。「每個步驟都要優化,只要有個點延遲很高,加總起來就無法達到超低延遲的標準,這需要很強的技術掌控力。」Kevin 說。 另一個挑戰則在於,由於各大終端裝置原廠(如Apple、Google)雖然有提供低延遲串流相對應的規範,但並未說明實際的執行細節,因此串流技術業者只能自己摸索。 受限於技術瓶頸,目前大多數的直播串流服務,只能在延遲、直播規模和影像品質三者間取捨。例如,常見的視訊會議軟體,像是 Zoom、Google Meet,雖然延遲相對低,但參與人數上...

COSCUP x UbuCon Asia 2026 錄取攤位公告/Full List of Accepted Community Booths at COSCUP x UbuCon Asia 2026

Full List of Accepted Community Booths at COSCUP x UbuCon Asia 2026 COSCUP x UbuCon Asia 2026 Booth now release. See which community you can meet on COSCUP x UbuCon Asia 2026. No. Community Introduction 01 UbuCon Asia HackMD 02 Ubuntu Community & Ubuntu-TW HackMD 03 Cloud Native Taiwan User Group x WasmEdge HackMD 04 Automotive Grade Linux HackMD 05 Ruby Taiwan HackMD 06 Wikimedia Movement in AI Era HackMD 07 t2linux HackMD 08 Twinkle AI HackMD 09 Taiwan JVM Team HackMD 10 Interledger Foundation HackMD 11 SITCON Student Information Technology Conference HackMD 12 OpenEverest HackMD 13 WordPress Taiwan Community HackMD 14 OSPN (Open Source People Network) Japan HackMD 15 GolangTW HackMD 16 opencocon distribution HackMD 17 Open Culture Foundation HackMD 18 GDG TW (Google Developers Groups Taiwan) HackMD 19 FediDev KR & FediLUG (Japan) HackMD 20 Blockchain and Distributed Ledger HackMD 21 Open-EP (E-Paper) Community HackMD 22 FOSS for All HackMD 23 ...

你的程式碼,你的硬體,你的 AI。掌握你的晶片未來。Your code, your hardware, your AI. Own your silicon future.

在 Tenstorrent,我們從晶片設計的最底層開始打造一切。我們不只採用 RISC-V,更將我們的擴充指令集規格全數公開。指令集架構 (ISA) 與硬體架構也完全開源。整個軟體堆疊,從韌體 (firmware)、運算核心 (compute kernels) 到編譯器,全都放在 GitHub 上,並採用你真正能用的授權條款 (Apache 2.0 / GPL)。我們的下一代晶片 Blackhole,旨在掃除傳統設計的低效率,讓你直接掌控資料流 (dataflow),實現更高的速度與電源效率。 Blackhole p150 (單晶片,次世代架構): 32G 記憶體,512GB/s 頻寬 387 TFLOPS (BFP8) / 774 TFLOPS (FP8) 大規模可程式化 RISC-V 核心陣列 算子函式庫、編譯器,整個軟體堆疊 — 全部開源 (OSS) 以原生 CCL 達成真正的多卡擴充,拒絕使用 PCIe workaround $1399 Wormhole n300 (雙晶片,經市場驗證的成熟架構): 24G 記憶體,576GB/s 頻寬 262 TFLOPS (BFP8) / 466 TFLOPS (FP8) 大規模可程式化 RISC-V 核心陣列 算子函式庫、編譯器,整個軟體堆疊 — 全部開源 (OSS) 以原生 CCL 達成真正的多卡擴充,拒絕使用 PCIe 土炮 $1499 現已上市。 立即在官網購買運算卡,或在我們的雲端平台上體驗。 如果你受夠了嚴苛的 EULA (使用者授權合約) 或處處受限的記憶體;又或者,你一直想親自動手,深入探索驅動你類神經網路的 C++ 程式碼;甚至想挑戰組合語言,親眼見證它...