From 24a0dcc95ffb3fe6b7892368400cdcb0b5ffb0b8 Mon Sep 17 00:00:00 2001 From: Robert Oanta Date: Mon, 24 Apr 2023 18:04:47 +0300 Subject: [PATCH] feat: refactor, remove hardcoded youtube rtmp url --- .../org/jitsi/jibri/api/http/HttpApi.kt | 8 ++-- .../org/jitsi/jibri/api/xmpp/XmppApi.kt | 25 +------------ .../service/impl/StreamingJibriService.kt | 37 +++++++++++++------ 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/main/kotlin/org/jitsi/jibri/api/http/HttpApi.kt b/src/main/kotlin/org/jitsi/jibri/api/http/HttpApi.kt index 936e12f4..eed59acc 100644 --- a/src/main/kotlin/org/jitsi/jibri/api/http/HttpApi.kt +++ b/src/main/kotlin/org/jitsi/jibri/api/http/HttpApi.kt @@ -62,7 +62,7 @@ data class StartServiceParams( */ val callLoginParams: XmppCredentials? = null, val sinkType: RecordingSinkType, - val youTubeStreamKey: String? = null, + val rtmpUrl: String? = null, /** * Params to be used if [RecordingSinkType] is [RecordingSinkType.GATEWAY] */ @@ -197,8 +197,8 @@ class HttpApi( ) } RecordingSinkType.STREAM -> { - val youTubeStreamKey = startServiceParams.youTubeStreamKey - ?: throw IllegalStateException("Stream key missing") + val rtmpUrl = startServiceParams.rtmpUrl + ?: throw IllegalStateException("Rtmp url missing") // If it's a stream, it must have the callLoginParams set val callLoginParams = startServiceParams.callLoginParams ?: throw IllegalStateException("Call login params missing") @@ -208,7 +208,7 @@ class HttpApi( startServiceParams.callParams, startServiceParams.sessionId, callLoginParams, - youTubeStreamKey + rtmpUrl ), environmentContext = null, statusHandler diff --git a/src/main/kotlin/org/jitsi/jibri/api/xmpp/XmppApi.kt b/src/main/kotlin/org/jitsi/jibri/api/xmpp/XmppApi.kt index ebf5c4c9..33be0687 100644 --- a/src/main/kotlin/org/jitsi/jibri/api/xmpp/XmppApi.kt +++ b/src/main/kotlin/org/jitsi/jibri/api/xmpp/XmppApi.kt @@ -30,7 +30,6 @@ import org.jitsi.jibri.service.JibriServiceStatusHandler import org.jitsi.jibri.service.ServiceParams import org.jitsi.jibri.service.impl.SipGatewayServiceParams import org.jitsi.jibri.service.impl.StreamingParams -import org.jitsi.jibri.service.impl.YOUTUBE_URL import org.jitsi.jibri.sipgateway.SipClientParams import org.jitsi.jibri.statsd.JibriStatsDClient import org.jitsi.jibri.statsd.STOPPED_ON_XMPP_CLOSED @@ -388,29 +387,14 @@ class XmppApi( ) } JibriMode.STREAM -> { - val rtmpUrl = if (startIq.streamId.isRtmpUrl()) { - startIq.streamId - } else { - "$YOUTUBE_URL/${startIq.streamId}" - } - val viewingUrl = if (startIq.youtubeBroadcastId != null) { - if (startIq.youtubeBroadcastId.isViewingUrl()) { - startIq.youtubeBroadcastId - } else { - "http://youtu.be/${startIq.youtubeBroadcastId}" - } - } else { - null - } - logger.info("Using RTMP URL $rtmpUrl and viewing URL $viewingUrl") jibriManager.startStreaming( serviceParams, StreamingParams( callParams, startIq.sessionId, xmppEnvironment.callLogin, - rtmpUrl = rtmpUrl, - viewingUrl = viewingUrl + rtmpUrl = startIq.streamId, + viewingUrl = startIq.youtubeBroadcastId ), environmentContext, serviceStatusHandler @@ -435,10 +419,5 @@ class XmppApi( } } -private fun String.isRtmpUrl(): Boolean = - startsWith("rtmp://", ignoreCase = true) || startsWith("rtmps://", ignoreCase = true) -private fun String.isViewingUrl(): Boolean = - startsWith("http://", ignoreCase = true) || startsWith("https://", ignoreCase = true) - private fun createEnvironmentContext(xmppEnvironment: XmppEnvironmentConfig, mucClient: MucClient) = EnvironmentContext("${xmppEnvironment.name}-${mucClient.id}") diff --git a/src/main/kotlin/org/jitsi/jibri/service/impl/StreamingJibriService.kt b/src/main/kotlin/org/jitsi/jibri/service/impl/StreamingJibriService.kt index 04ef5e7e..b85839fd 100644 --- a/src/main/kotlin/org/jitsi/jibri/service/impl/StreamingJibriService.kt +++ b/src/main/kotlin/org/jitsi/jibri/service/impl/StreamingJibriService.kt @@ -17,7 +17,6 @@ package org.jitsi.jibri.service.impl -import org.jitsi.xmpp.extensions.jibri.JibriIq import org.jitsi.jibri.capture.ffmpeg.FfmpegCapturer import org.jitsi.jibri.config.Config import org.jitsi.jibri.config.XmppCredentials @@ -33,9 +32,9 @@ import org.jitsi.jibri.status.ComponentState import org.jitsi.jibri.status.ErrorScope import org.jitsi.jibri.util.whenever import org.jitsi.metaconfig.config +import org.jitsi.xmpp.extensions.jibri.JibriIq import java.util.regex.Pattern -const val YOUTUBE_URL = "rtmp://a.rtmp.youtube.com/live2" private const val STREAMING_MAX_BITRATE = 2976 /** @@ -76,6 +75,7 @@ class StreamingJibriService( init { logger.addContext("session_id", streamingParams.sessionId) } + private val capturer = FfmpegCapturer(logger) private val sink: Sink private val jibriSelenium = JibriSelenium(logger) @@ -97,18 +97,15 @@ class StreamingJibriService( } override fun start() { + if (!streamingParams.rtmpUrl.isValidRtmpUrl()) { + publishSessionError("RTMP URL ${streamingParams.rtmpUrl} is not valid") + return + } if (rtmpAllowList.none { it.matcher(streamingParams.rtmpUrl).matches() }) { - logger.error("RTMP url ${streamingParams.rtmpUrl} is not allowed") - publishStatus( - ComponentState.Error( - JibriError( - ErrorScope.SESSION, - "RTMP URL ${streamingParams.rtmpUrl} is not allowed" - ) - ) - ) + publishSessionError("RTMP URL ${streamingParams.rtmpUrl} is not allowed") return } + jibriSelenium.joinCall( streamingParams.callParams.callUrlInfo.copy(urlParams = RECORDING_URL_OPTIONS), streamingParams.callLoginParams @@ -120,6 +117,9 @@ class StreamingJibriService( jibriSelenium.addToPresence("session_id", streamingParams.sessionId) jibriSelenium.addToPresence("mode", JibriIq.RecordingMode.STREAM.toString()) streamingParams.viewingUrl?.let { viewingUrl -> + if (!viewingUrl.isValidViewingUrl()) { + logger.warn("Viewing URL ${streamingParams.viewingUrl} is not valid") + } if (!jibriSelenium.addToPresence("live-stream-view-url", viewingUrl)) { logger.error("Error adding live stream url to presence") } @@ -133,6 +133,21 @@ class StreamingJibriService( } } + private fun publishSessionError(errorMessage: String) { + logger.error(errorMessage) + publishStatus( + ComponentState.Error( + JibriError(ErrorScope.SESSION, errorMessage) + ) + ) + } + + private fun String.isValidRtmpUrl(): Boolean = + startsWith("rtmp://", ignoreCase = true) || startsWith("rtmps://", ignoreCase = true) + + private fun String.isValidViewingUrl(): Boolean = + startsWith("http://", ignoreCase = true) || startsWith("https://", ignoreCase = true) + override fun stop() { logger.info("Stopping capturer") capturer.stop()