如果主持人设置会议密码,Jibri 无法录制

Jibri is unable to record if a moderator sets a meeting password

我已经使用 docker 设置了 jibri。当我在设置会议密码后尝试录制会议时收到一条消息 Recording is stopped,当我检查日志时发现 jibri 用户无法绕过会议密码。

jibri 日志片段

Not joined yet: Cannot read property 'isJoined' of undefined

完整的 jibri 容器日志

inalize script 2020-08-19 18:05:51.883 FINE: [71] org.jitsi.xmpp.mucclient.MucClient.log() Received an IQ with type set: IQ Stanza (jibri http://jitsi.org/protocol/jibri) [to=jibri@auth.r.example.in/ERYyDatF,from=jibribrewery@internal-muc.r.example.in/focus,id=amlicmlAYXV0aC5yLmRvY2FkZW5hLmluL0VSWXlEYXRGAFBJdlNrLTE3MADqyFaI3En3qssrxLJFjhPZ,type=set,]
2020-08-19 18:05:51.888 INFO: [71] org.jitsi.jibri.api.xmpp.XmppApi.handleJibriIq() Received JibriIq <iq to='jibri@auth.r.example.in/ERYyDatF' from='jibribrewery@internal-muc.r.example.in/focus' id='amlicmlAYXV0aC5yLmRvY2FkZW5hLmluL0VSWXlEYXRGAFBJdlNrLTE3MADqyFaI3En3qssrxLJFjhPZ' type='set'><jibri xmlns='http://jitsi.org/protocol/jibri' action='start' recording_mode='file' room='test@muc.r.example.in' session_id='ewgvpnxhkrjuiays' app_data='{"file_recording_metadata":{"share":true}}'/></iq> from environment [MucClient id=xmpp.r.example.in hostname=xmpp.r.example.in]
2020-08-19 18:05:51.890 INFO: [71] org.jitsi.jibri.api.xmpp.XmppApi.handleStartJibriIq() Received start request, starting service
2020-08-19 18:05:51.938 INFO: [71] org.jitsi.jibri.api.xmpp.XmppApi.handleStartService() Parsed call url info: CallUrlInfo(baseUrl=https://r.example.in, callName=test, urlParams=[])
2020-08-19 18:05:51.939 INFO: [71] org.jitsi.jibri.JibriManager.startFileRecording() Starting a file recording with params: FileRecordingRequestParams(callParams=CallParams(callUrlInfo=CallUrlInfo(baseUrl=https://r.example.in, callName=test, urlParams=[])), sessionId=ewgvpnxhkrjuiays, callLoginParams=XmppCredentials(domain=recorder.r.example.in, username=recorder, password=46ea1b0e6252479eb6cc647bed7cfc18)) finalize script path: /config/finalize.sh and recordings directory: /config/recording
Starting ChromeDriver 78.0.3904.105 (60e2d8774a8151efa6a00b1f358371b1e0e07ee2-refs/branch-heads/3904@{#877}) on port 13074
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
2020-08-19 18:05:53.109 INFO: [71] org.openqa.selenium.remote.ProtocolHandshake.createSession() Detected dialect: OSS
2020-08-19 18:05:53.131 INFO: [71] org.jitsi.jibri.selenium.JibriSelenium.<init>() Starting empty call check with a timeout of PT30S
2020-08-19 18:05:53.143 FINE: [71] org.jitsi.jibri.capture.ffmpeg.FfmpegCapturer.<init>() Detected os as OS: LINUX
2020-08-19 18:05:53.149 INFO: [71] org.jitsi.jibri.service.impl.FileRecordingJibriService.<init>() Writing recording to /config/recording/ewgvpnxhkrjuiays
2020-08-19 18:05:53.152 FINE: [71] org.jitsi.jibri.statsd.JibriStatsDClient.incrementCounter() Incrementing statsd counter: start:recording
2020-08-19 18:05:53.153 INFO: [71] org.jitsi.jibri.status.JibriStatusManager.log() Busy status has changed: IDLE -> BUSY
2020-08-19 18:05:53.153 INFO: [71] org.jitsi.jibri.api.xmpp.XmppApi.updatePresence() Jibri reports its status is now JibriStatus(busyStatus=BUSY, health=OverallHealth(healthStatus=HEALTHY, details={})), publishing presence to connections
2020-08-19 18:05:53.153 FINE: [71] org.jitsi.xmpp.mucclient.MucClientManager.log() Setting a presence extension: org.jitsi.xmpp.extensions.jibri.JibriStatusPacketExt@15f928f8
2020-08-19 18:05:53.154 FINE: [71] org.jitsi.xmpp.mucclient.MucClientManager.log() Replacing presence extension: org.jitsi.xmpp.extensions.jibri.JibriStatusPacketExt@3935e9a8
2020-08-19 18:05:53.156 INFO: [71] org.jitsi.jibri.api.xmpp.XmppApi.handleStartJibriIq() Sending 'pending' response to start IQ
2020-08-19 18:05:53.161 FINE: [52] org.jitsi.xmpp.extensions.DefaultPacketExtensionProvider.parse() Could not add a provider for element busy-status from namespace http://jitsi.org/protocol/jibri
2020-08-19 18:05:53.161 FINE: [52] org.jitsi.xmpp.extensions.DefaultPacketExtensionProvider.parse() Could not add a provider for element health-status from namespace http://jitsi.org/protocol/health
2020-08-19 18:05:55.313 FINE: [83] org.jitsi.jibri.selenium.pageobjects.CallPage.visit() Visiting url https://r.example.in/test#config.iAmRecorder=true&config.externalConnectUrl=null&config.startWithAudioMuted=true&config.startWithVideoMuted=true&interfaceConfig.APP_NAME="Jibri"&config.analytics.disabled=true&config.p2p.enabled=false&config.prejoinPageEnabled=false&config.requireDisplayName=false
2020-08-19 18:05:56.088 FINE: [83] org.jitsi.jibri.selenium.pageobjects.CallPage.apply() Not joined yet: Cannot read property 'isJoined' of undefined
2020-08-19 18:05:56.608 FINE: [83] org.jitsi.jibri.selenium.pageobjects.CallPage.apply() Not joined yet: Cannot read property 'isJoined' of undefined
2020-08-19 18:06:26.478 SEVERE: [83] org.jitsi.jibri.selenium.pageobjects.CallPage.visit() Timed out waiting for call page to load
2020-08-19 18:06:26.483 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.onSeleniumStateChange() Transitioning from state Starting up to Error: FailedToJoinCall SESSION Failed to join the call
2020-08-19 18:06:26.485 INFO: [83] org.jitsi.jibri.service.impl.FileRecordingJibriService.onServiceStateChange() File recording service transitioning from state Starting up to Error: FailedToJoinCall SESSION Failed to join the call
2020-08-19 18:06:26.487 INFO: [83] org.jitsi.jibri.api.xmpp.XmppApi.invoke() Current service had an error Error: FailedToJoinCall SESSION Failed to join the call, sending error iq <iq to='jibribrewery@internal-muc.r.example.in/focus' id='HISVW-32' type='set'><jibri xmlns='http://jitsi.org/protocol/jibri' status='off' failure_reason='error' should_retry='true'/></iq>
2020-08-19 18:06:26.488 FINE: [83] org.jitsi.jibri.statsd.JibriStatsDClient.incrementCounter() Incrementing statsd counter: stop:recording
2020-08-19 18:06:26.488 INFO: [83] org.jitsi.jibri.JibriManager.stopService() Stopping the current service
2020-08-19 18:06:26.489 INFO: [83] org.jitsi.jibri.service.impl.FileRecordingJibriService.stop() Stopping capturer
2020-08-19 18:06:26.490 INFO: [83] org.jitsi.jibri.util.JibriSubprocess.ffmpeg.stop() Stopping ffmpeg process
2020-08-19 18:06:26.490 INFO: [83] org.jitsi.jibri.util.JibriSubprocess.ffmpeg.stop() ffmpeg exited with value null
2020-08-19 18:06:26.491 INFO: [83] org.jitsi.jibri.service.impl.FileRecordingJibriService.stop() Quitting selenium
2020-08-19 18:06:26.507 INFO: [83] org.jitsi.jibri.service.impl.FileRecordingJibriService.stop() Participants in this recording: []
2020-08-19 18:06:26.580 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Leaving call and quitting browser
2020-08-19 18:06:26.581 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Recurring call status checks cancelled
2020-08-19 18:06:26.596 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Got 12 log entries for type browser
2020-08-19 18:06:26.668 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Got 1086 log entries for type driver
2020-08-19 18:06:26.802 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Got 0 log entries for type client
2020-08-19 18:06:26.802 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Leaving web call
2020-08-19 18:06:31.850 SEVERE: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Error trying to leave the call: org.openqa.selenium.JavascriptException: javascript error: The timeout for the confirmation about leaving the room expired.
  (Session info: chrome=78.0.3904.97)
  (Driver info: chromedriver=78.0.3904.105 (60e2d8774a8151efa6a00b1f358371b1e0e07ee2-refs/branch-heads/3904@{#877}),platform=Linux 4.15.0-111-generic x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
Build info: version: 'unknown', revision: 'unknown', time: 'unknown'
System info: host: '4a4d5ccd62bb', ip: '172.20.0.6', os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-111-generic', java.version: '1.8.0_252'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, acceptSslCerts: false, applicationCacheEnabled: false, browserConnectionEnabled: false, browserName: chrome, chrome: {chromedriverVersion: 78.0.3904.105 (60e2d8774a81..., userDataDir: /tmp/.com.google.Chrome.OfQexN}, cssSelectorsEnabled: true, databaseEnabled: false, goog:chromeOptions: {debuggerAddress: localhost:33417}, handlesAlerts: true, hasTouchScreen: false, javascriptEnabled: true, locationContextEnabled: true, mobileEmulationEnabled: false, nativeEvents: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), rotatable: false, setWindowRect: true, strictFileInteractability: false, takesHeapSnapshot: true, takesScreenshot: true, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unexpectedAlertBehaviour: ignore, unhandledPromptBehavior: ignore, version: 78.0.3904.97, webStorageEnabled: true}
Session ID: add424a6f715dda3b7ecc4d8be721d3b with stack:
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:423)
org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:214)
org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166)
org.openqa.selenium.remote.http.JsonHttpResponseCodec.reconstructValue(JsonHttpResponseCodec.java:40)
org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:80)
org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:44)
org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:543)
org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:480)
org.jitsi.jibri.selenium.pageobjects.CallPage.leave(CallPage.kt:221)
org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser(JibriSelenium.kt:299)
org.jitsi.jibri.service.impl.FileRecordingJibriService.stop(FileRecordingJibriService.kt:190)
org.jitsi.jibri.JibriManager.stopService(JibriManager.kt:257)
org.jitsi.jibri.JibriManager$startService.invoke(JibriManager.kt:206)
org.jitsi.jibri.JibriManager$startService.invoke(JibriManager.kt:84)
org.jitsi.jibri.util.StatusPublisher$addStatusHandler.invoke(StatusPublisher.kt:37)
org.jitsi.jibri.util.StatusPublisher$addStatusHandler.invoke(StatusPublisher.kt:29)
org.jitsi.jibri.util.StatusPublisher$publishStatus.invoke(StatusPublisher.kt:53)
org.jitsi.jibri.util.StatusPublisher$publishStatus.invoke(StatusPublisher.kt:29)
kotlin.collections.CollectionsKt__MutableCollectionsKt.filterInPlace$CollectionsKt__MutableCollectionsKt(MutableCollections.kt:293)
kotlin.collections.CollectionsKt__MutableCollectionsKt.retainAll(MutableCollections.kt:284)
org.jitsi.jibri.util.StatusPublisher.publishStatus(StatusPublisher.kt:53)
org.jitsi.jibri.service.impl.StatefulJibriService.onServiceStateChange(StatefulJibriService.kt:40)
org.jitsi.jibri.service.impl.StatefulJibriService.access$onServiceStateChange(StatefulJibriService.kt:26)
org.jitsi.jibri.service.impl.StatefulJibriService.invoke(StatefulJibriService.kt:35)
org.jitsi.jibri.service.impl.StatefulJibriService.invoke(StatefulJibriService.kt:26)
org.jitsi.jibri.util.NotifyingStateMachine.notify(NotifyingStateMachine.kt:26)
org.jitsi.jibri.service.JibriServiceStateMachine.access$notify(JibriServiceStateMachine.kt:46)
org.jitsi.jibri.service.JibriServiceStateMachine$stateMachine.invoke(JibriServiceStateMachine.kt:100)
org.jitsi.jibri.service.JibriServiceStateMachine$stateMachine.invoke(JibriServiceStateMachine.kt:46)
com.tinder.StateMachine.notifyOnTransition(StateMachine.kt:65)
com.tinder.StateMachine.transition(StateMachine.kt:23)
org.jitsi.jibri.service.JibriServiceStateMachine.transition(JibriServiceStateMachine.kt:112)
org.jitsi.jibri.service.impl.StatefulJibriService$registerSubComponent.invoke(StatefulJibriService.kt:46)
org.jitsi.jibri.service.impl.StatefulJibriService$registerSubComponent.invoke(StatefulJibriService.kt:26)
org.jitsi.jibri.util.StatusPublisher$addStatusHandler.invoke(StatusPublisher.kt:37)
org.jitsi.jibri.util.StatusPublisher$addStatusHandler.invoke(StatusPublisher.kt:29)
org.jitsi.jibri.util.StatusPublisher$publishStatus.invoke(StatusPublisher.kt:53)
org.jitsi.jibri.util.StatusPublisher$publishStatus.invoke(StatusPublisher.kt:29)
kotlin.collections.CollectionsKt__MutableCollectionsKt.filterInPlace$CollectionsKt__MutableCollectionsKt(MutableCollections.kt:293)
kotlin.collections.CollectionsKt__MutableCollectionsKt.retainAll(MutableCollections.kt:284)
org.jitsi.jibri.util.StatusPublisher.publishStatus(StatusPublisher.kt:53)
org.jitsi.jibri.selenium.JibriSelenium.onSeleniumStateChange(JibriSelenium.kt:184)
org.jitsi.jibri.selenium.JibriSelenium.access$onSeleniumStateChange(JibriSelenium.kt:116)
org.jitsi.jibri.selenium.JibriSelenium.invoke(JibriSelenium.kt:169)
org.jitsi.jibri.selenium.JibriSelenium.invoke(JibriSelenium.kt:116)
org.jitsi.jibri.util.NotifyingStateMachine.notify(NotifyingStateMachine.kt:26)
org.jitsi.jibri.selenium.SeleniumStateMachine.access$notify(SeleniumStateMachine.kt:33)
org.jitsi.jibri.selenium.SeleniumStateMachine$stateMachine.invoke(SeleniumStateMachine.kt:78)
org.jitsi.jibri.selenium.SeleniumStateMachine$stateMachine.invoke(SeleniumStateMachine.kt:33)
com.tinder.StateMachine.notifyOnTransition(StateMachine.kt:65)
com.tinder.StateMachine.transition(StateMachine.kt:23)
org.jitsi.jibri.selenium.SeleniumStateMachine.transition(SeleniumStateMachine.kt:83)
org.jitsi.jibri.selenium.JibriSelenium$joinCall.run(JibriSelenium.kt:260)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)

2020-08-19 18:06:31.850 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Quitting chrome driver
2020-08-19 18:06:31.932 INFO: [83] org.jitsi.jibri.selenium.JibriSelenium.leaveCallAndQuitBrowser() Chrome driver quit
2020-08-19 18:06:31.933 INFO: [83] org.jitsi.jibri.service.impl.FileRecordingJibriService.stop() Finalizing the recording
2020-08-19 18:06:41.949 SEVERE: [83] org.jitsi.jibri.service.impl.FileRecordingJibriService.finalize() Timed out waiting for process logger task to complete
2020-08-19 18:06:41.949 INFO: [83] org.jitsi.jibri.service.impl.FileRecordingJibriService.finalize() Recording finalize script finished with exit value 0
2020-08-19 18:06:41.951 INFO: [83] org.jitsi.jibri.status.JibriStatusManager.log() Busy status has changed: BUSY -> IDLE
2020-08-19 18:06:41.951 INFO: [83] org.jitsi.jibri.api.xmpp.XmppApi.updatePresence() Jibri reports its status is now JibriStatus(busyStatus=IDLE, health=OverallHealth(healthStatus=HEALTHY, details={})), publishing presence to connections
2020-08-19 18:06:41.952 FINE: [83] org.jitsi.xmpp.mucclient.MucClientManager.log() Setting a presence extension: org.jitsi.xmpp.extensions.jibri.JibriStatusPacketExt@1d998819
2020-08-19 18:06:41.953 FINE: [83] org.jitsi.xmpp.mucclient.MucClientManager.log() Replacing presence extension: org.jitsi.xmpp.extensions.jibri.JibriStatusPacketExt@15f928f8
2020-08-19 18:06:41.959 FINE: [52] org.jitsi.xmpp.extensions.DefaultPacketExtensionProvider.parse() Could not add a provider for element busy-status from namespace http://jitsi.org/protocol/jibri
2020-08-19 18:06:41.959 FINE: [52] org.jitsi.xmpp.extensions.DefaultPacketExtensionProvider.parse() Could not add a provider for element health-status from namespace http://jitsi.org/protocol/health

请帮忙。

您需要使用外部脚本来允许 jibri user 绕过会议密码。 jitsi-docker github 存储库中已经存在一个错误。下面是该错误中提到的脚本片段。


local MUC_NS = "http://jabber.org/protocol/muc";
local jid = require "util.jid";
local pre_jibri_user = os.getenv("JIBRI_RECORDER_USER")
local pre_jibri_domain = os.getenv("XMPP_RECORDER_DOMAIN")

module:hook("muc-occupant-pre-join", function (event)
    local room, stanza = event.room, event.stanza;

    local user, domain, res = jid.split(event.stanza.attr.from);
    log("info", "--------------> user %s domain %s res %s pass %s", tostring(user),tostring(domain),tostring(res),tostring(room:get_password())); 
    
    if ( user == pre_jibri_user and domain == pre_jibri_domain ) then
      local join = stanza:get_child("x", MUC_NS);
      join:tag("password", { xmlns = MUC_NS }):text(room:get_password()); 
    end;
end);
  1. 你可以命名它mod_jibri_bypass_pswd.lua
  2. 放入prosody-plugins-custom目录然后
  3. 将此 mod jibri_bypass_pswd 添加到 prosody/defaults/conf.d/jitsi-meet.cfg.lua 在主要 module_enabledComponent "{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }}" "muc".

片段我是如何添加的

modules_enabled = {
        "bosh";
        "pubsub";
        "ping";
        "speakerstats";
        "conference_duration";
        {{ if and $ENABLE_LOBBY (not $ENABLE_GUEST_DOMAIN) }}
        "muc_lobby_rooms";
        {{ end }}
        {{ if .Env.XMPP_MODULES }}
        "{{ join "\";\n\"" (splitList "," .Env.XMPP_MODULES) }}";
        {{ end }}
        {{ if and $ENABLE_AUTH (eq $AUTH_TYPE "ldap") }}
        "auth_cyrus";
        {{end}}
        {{ if .Env.ENABLE_RECORDING }}
        "jibri_bypass_pswd";
        {{ end }}
    }
Component "{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }}" "muc"
    storage = "memory"
    modules_enabled = {
        "ping";
        {{ if .Env.XMPP_INTERNAL_MUC_MODULES }}
        "{{ join "\";\n\"" (splitList "," .Env.XMPP_INTERNAL_MUC_MODULES) }}";
        {{ end }}
        {{ if .Env.ENABLE_RECORDING }}
        "jibri_bypass_pswd";
        {{ end }}
    }
    muc_room_locking = false
    muc_room_default_public_jids = true

注意:在prosody服务环境下添加ENABLE_RECORDING=1