Stream to any OR Multiple RTMP Destinations + Record Simultaneously

Thanks masteryoda , for your excellent idea of achieve FB live through script

I able to solve the problem and now can stream directly to Facebook live without Apache and Stunnel given that ffmpeg support rtmps: protocol. This script check stream key and if stream is of pattern of Facebook Live then stream to Facebook Live else stream to YouTube

below script served the purpose
++++++++
#!/bin/bash

COMANDO="/usr/local/bin/ffmpeg"
while test $# -gt 0
do
T="1" if [ "{1:0:32}" == “rtmp://a.rtmp.youtube.com/live2/” ]; then
# T will contain the rtmp key from jitsi meet page.
streamkey=${T:32}
if [[ $streamkey == “s_sc=” ]]; then
COMANDO="COMANDO rtmps://live-api-s.facebook.com:443/rtmp/{T:32}"
else
COMANDO="$COMANDO $T"
fi
else
COMANDO="$COMANDO $T"
fi
shift
done
echo “$COMANDO”>>/tmp/logs
exec COMANDO PROCESS_FFMPEG=!
wait $PROCESS_FFMPEG
$COMANDO
+++++++++++++++++++

Just make sure ffmpeg support rtmps: protocol.

ffmpeg -protocols|grep rtmps

Note: This only stream to Facebook live or Youtube , not any other platform

I think You can make it stream to both…

Just drop the key that put in popup window and use permanent keys in the script & see if that works

Yes right, but my requirement was to either stream to Facebook or YouTube, and stream key need to be provided in each conference.

Thanks

worked like a charm, thanks alot !!

@masteryoda

would it work right if i want to serve RTMP stream over a client in a local environment.

means, if i have a rtmp server running locally on the same vm/machine as jibri, would i just give the rmtp url as 127.0.0.1/stream or something like that?

would it reduce the load of sending out to another rtmp server and instead self-host the server? as you can, please share your thoughts on this.

yes, that should work. you need nginx on jibri though

1 Like

Yes, works like a charm. I have Jibri and this installed on a 4core/16GB GCP instance with a static ffmpeg build (4.2.2) and it’s working well. The only issue is that stopping the live stream doesn’t stop the live event on Vimeo automatically.

1 Like

i dont know about vimeo. YT (you have to enable auto-stop) periscope and facebook (again enable auto-stop) does stop automatically though when you stop streaming

OK - I figured it out - there’s a 5-minute time-out window after the stream stops before it auto-stops… Thanks for the solution - it solves a lot of problems without having to hack the code!

1 Like

When i am trying with facebook i did not succeed to go live
2020-05-30T13:28:21.767Z [modules/connectivity/ParticipantConnectionStatus.js] <S.onTrackRtcMuted>: No participant for id: 76a39186
s @ md5.js:1
onTrackRtcMuted @ lib-jitsi-meet.min.js?v=4127:1
a.emit @ lib-jitsi-meet.min.js?v=4127:1
_onTrackMute @ md5.js:1
(anonymous) @ md5.js:1
Logger.js:154 2020-05-30T13:28:36.858Z [JitsiMeetJS.js] <Object.getGlobalOnErrorHandler>: UnhandledError: null Script: null Line: null Column: null StackTrace: Error: Jingle error: {“reason”:“timeout”,“session”:“JingleSessionPC[p2p=true,initiator=true,sid=c4f27d3a7578]”}
at JingleSessionPC.js:2328
at I.TimedHandler.handler (strophe.umd.js:2732)
at I.TimedHandler.run (strophe.umd.js:1938)
at I.Connection._onIdle (strophe.umd.js:3869)
at strophe.umd.js:3886
s @ md5.js:1
getGlobalOnErrorHandler @ async.js:1
window.onerror @ app.bundle.min.js?v=4127:1
callErrorHandler @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
run @ lib-jitsi-meet.min.js?v=4127:1
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
Logger.js:154 2020-05-30T13:28:36.860Z [modules/xmpp/JingleSessionPC.js] “session-initiate” error null
s @ md5.js:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
run @ lib-jitsi-meet.min.js?v=4127:1
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
Logger.js:154 2020-05-30T13:28:36.962Z [JitsiMeetJS.js] <Object.getGlobalOnErrorHandler>: UnhandledError: null Script: null Line: null Column: null StackTrace: Error: Jingle error: {“reason”:“timeout”,“session”:“JingleSessionPC[p2p=true,initiator=true,sid=c4f27d3a7578]”}
at JingleSessionPC.js:2328
at I.TimedHandler.handler (strophe.umd.js:2732)
at I.TimedHandler.run (strophe.umd.js:1938)
at I.Connection._onIdle (strophe.umd.js:3869)
at strophe.umd.js:3886
s @ md5.js:1
getGlobalOnErrorHandler @ async.js:1
window.onerror @ app.bundle.min.js?v=4127:1
callErrorHandler @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
run @ lib-jitsi-meet.min.js?v=4127:1
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
Logger.js:154 2020-05-30T13:28:38.001Z [JitsiMeetJS.js] <Object.getGlobalOnErrorHandler>: UnhandledError: null Script: null Line: null Column: null StackTrace: Error: Jingle error: {“reason”:“timeout”,“session”:“JingleSessionPC[p2p=true,initiator=true,sid=c4f27d3a7578]”}
at JingleSessionPC.js:2328
at I.TimedHandler.handler (strophe.umd.js:2732)
at I.TimedHandler.run (strophe.umd.js:1938)
at I.Connection._onIdle (strophe.umd.js:3869)
at strophe.umd.js:3886
s @ md5.js:1
getGlobalOnErrorHandler @ async.js:1
window.onerror @ app.bundle.min.js?v=4127:1
callErrorHandler @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
run @ lib-jitsi-meet.min.js?v=4127:1
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1
setTimeout (async)
_onIdle @ lib-jitsi-meet.min.js?v=4127:1
(anonymous) @ lib-jitsi-meet.min.js?v=4127:1

Facebook uses rtmps NOT rtmp

Check the protocol

see i have used rtmps

Logger.js:154 2020-05-30T18:26:31.603Z [JitsiMeetJS.js] <Object.getGlobalOnErrorHandler>: UnhandledError: null Script: null Line: null Column: null StackTrace: Error: TPC[1,p2p:false]: no peer media info available for 618ae226 at A._remoteTrackAdded (TraceablePeerConnection.js:783) at A._remoteStreamAdded (TraceablePeerConnection.js:660) at RTCPeerConnection.A.m.a.usesPlanB.peerconnection.onaddstream (TraceablePeerConnection.js:277)

s @ md5.js:1
getGlobalOnErrorHandler @ async.js:1
window.onerror @ app.bundle.min.js?v=4127:sourcemap:1
callErrorHandler @ lib-jitsi-meet.min.js?v=4127:1
A._remoteTrackAdded @ md5.js:1
A._remoteStreamAdded @ md5.js:1
A.m.a.usesPlanB.peerconnection.onaddstream @ md5.js:1

the Facebook rtmps URL is wrong. it must be

rtmps://live-api-s.facebook.com:443/rtmp/

did you upload recording somewhare (aws s3) ?

Hi all!

I followed the instructions on this thread to be able to stream to YouTube and Facebook.

Jitsi/Jibri setup is based on the “quick jibri installer”.

Both the RTMP and the Jitsi/Jibri servers are on Digital Ocean Basic Droplets with 8gb Memory and 4 CPUs.

I was able to make things work and stream simultaneously on YT and FB.

However, the Live Stream gets disconnected every 10 mins or so.

Jibri Log that I got:
2020-06-20 09:22:56.785 INFO: [38] org.jitsi.jibri.capture.ffmpeg.FfmpegCapturer.onFfmpegStateMachineStateChange() Ffmpeg capturer transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/https://www.youtube.com/watch?v=[video-id]: Input/output error
2020-06-20 09:22:56.786 INFO: [38] org.jitsi.jibri.service.impl.StreamingJibriService.onServiceStateChange() Streaming service transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/https://www.youtube.com/watch?v=[video-id]: Input/output error
2020-06-20 09:34:03.282 INFO: [52] org.jitsi.jibri.capture.ffmpeg.FfmpegCapturer.onFfmpegStateMachineStateChange() Ffmpeg capturer transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 09:34:03.282 INFO: [52] org.jitsi.jibri.service.impl.StreamingJibriService.onServiceStateChange() Streaming service transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 09:45:04.591 INFO: [53] org.jitsi.jibri.capture.ffmpeg.FfmpegCapturer.onFfmpegStateMachineStateChange() Ffmpeg capturer transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 09:45:04.591 INFO: [53] org.jitsi.jibri.service.impl.StreamingJibriService.onServiceStateChange() Streaming service transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 09:56:01.746 INFO: [117] org.jitsi.jibri.capture.ffmpeg.FfmpegCapturer.onFfmpegStateMachineStateChange() Ffmpeg capturer transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 09:56:01.747 INFO: [117] org.jitsi.jibri.service.impl.StreamingJibriService.onServiceStateChange() Streaming service transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 10:06:58.827 INFO: [82] org.jitsi.jibri.capture.ffmpeg.FfmpegCapturer.onFfmpegStateMachineStateChange() Ffmpeg capturer transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 10:06:58.828 INFO: [82] org.jitsi.jibri.service.impl.StreamingJibriService.onServiceStateChange() Streaming service transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 10:18:06.840 INFO: [190] org.jitsi.jibri.capture.ffmpeg.FfmpegCapturer.onFfmpegStateMachineStateChange() Ffmpeg capturer transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error
2020-06-20 10:18:06.841 INFO: [190] org.jitsi.jibri.service.impl.StreamingJibriService.onServiceStateChange() Streaming service transitioning from state Starting up to Error: SESSION rtmp://[rtmp-server-ip]:1935/live/[stream-key]: Input/output error

Any help would be much appreaciated.

Hi, @masteryoda Any way to edit after install JIbri this line?:

private const val YOUTUBE_URL = “rtmp://a.rtmp.youtube.com/live2”
private const val STREAMING_MAX_BITRATE = 2976

Hello, @masteryoda I want to live stream on Vimeo. I follow your step on my Debian server but i can’t get success. Can you please told me when is mistake from my side?

This is my “nano /etc/nginx/nginx.conf” is this okay or i have to change anything?

rtmp {
server {
listen 1935;
chunk_size 4096;

            application live {
                    live on;
                     #Set this to "record off" if you don't want to save a copy of your broadcasts
                     record all;
                     # The directory in which the recordings will be stored. 
                     record_path /var/www/html/recordings;
                     record_unique on;

                    #Facebook
                    push rtmp://127.0.0.1:1936/rtmp/INSERT-YOUR-STATIC-STREAM-KEY;

                    #Periscope -- Goto pscp.tv/account/producer & create a stream. select the region of your choice and copy & paste it at the en$
                    exec /usr/bin/ffmpeg -i rtmp://127.0.0.1/live/$name -crf 30 -preset ultrafast -acodec aac -strict experimental -ar 44100 -ac $

                    #Youtube Stream - YT doesnt assign a permanent stream key, BUT if you reuse an earlier stream, the key doesnt change. EDIT: a$
                    push rtmp://a.rtmp.youtube.com/live2/YOUTUBE-stream-key;
            }
    }

}

nano /etc/default/stunnel4

/etc/default/stunnel

Julien LEMOINE speedblue@debian.org

September 2003

FILES="/etc/stunnel/*.conf"
OPTIONS=""

Change to one to enable ppp restart scripts

PPP_RESTART=0

Change to enable the setting of limits on the stunnel instances

For example, to set a large limit on file descriptors (to enable

more simultaneous client connections), set RLIMITS="-n 4096"

More than one resource limit may be modified at the same time,

e.g. RLIMITS="-n 4096 -d unlimited"

RLIMITS=""

nano /etc/stunnel/stunnel.conf

pid = /var/run/stunnel4/stunnel.pid
output = /var/log/stunnel4/stunnel.log

setuid = stunnel4
setgid = stunnel4

https://www.stunnel.org/faq.html

socket = r:TCP_NODELAY=1
socket = l:TCP_NODELAY=1

debug = 4

[fb-live]
client = yes
accept = 1936
connect = rtmp-global.cloud.vimeo.com
verifyChain = no

nano ffmpeg

#!/bin/bash

COMMAND="/usr/bin/ffmpeg"

while test $# -gt 0
do
T="1" if [ "{1:0:32}" == “rtmp://a.rtmp.youtube.com/live2/” ]; then
# T will contain the rtmp key from jitsi meet page. Make sure you use the correct IP Address OF the rtmp server you setup earlier
COMMAND="COMMAND rtmp://myip:1935/live/{T:32}"
else
COMMAND="$COMMAND $T"
fi
shift
done

echo “RUNNING FFMPEG: «$COMMAND».”

exec COMMAND PROCESS_FFMPEG=!

echo “Esperando finalización del proceso: ${PROCESO_FFMPEG}.”
wait $PROCESS_FFMPEG

systemctl edit --full jibri

[Unit]
Description=Jibri Process
Requires=jibri-icewm.service jibri-xorg.service
After=network.target

[Service]
User=jibri
Group=jibri
PermissionsStartOnly=true
ExecStart=/opt/jitsi/jibri/launch.sh
ExecStop=/opt/jitsi/jibri/graceful_shutdown.sh
ExecReload=/opt/jitsi/jibri/reload.sh
Environment=“PATH=/opt/util:/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64/bin/java:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”
Restart=always
RestartPreventExitStatus=255
Type=simple

[Install]
WantedBy=multi-user.target

I have 3 java files: adoptopenjdk-8-hotspot-amd64 / java-1.11.0-openjdk-amd64 / java-11-openjdk-amd64

Hi @masteryoda
I have a question. Could you please help me to solve it. My question is aren’t there are any possible way to dump the variable $name in nginx?
Another thing is, is that possible to know that the output is the exact same thing of the front input? .What I need to be done is, pass the Stream key from the front end and use the same key for these three. Then to automatically stream them into the correct RTMP channel. Thank you

the stream key is just a place holder. you can pretty much put anything in there as long as you pipe it to the RTMP/NGINX server. there you can specify the correct rtmp server & streamkey.

you cannot use the same streamkey on the frontend and to all other destinations. each destination has its own unique stream key