@@ -33,6 +33,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
3333#define OUTPUT_JSON_NAME " output.json"
3434#define OUTPUT_MONITORING_INTERVAL_MSECS 1000
3535#define OUTPUT_RETRY_TIMEOUT_MSECS 3500
36+ #define OUTPUT_START_DELAY_MSECS 1000
3637#define OUTPUT_SCREENSHOT_HEIGHT 720
3738
3839inline audio_t *createSilenceAudio ()
@@ -763,14 +764,17 @@ audio_t *EgressLinkOutput::createAudio(QString audioSourceUuid)
763764bool EgressLinkOutput::createStreamingOutput (obs_data_t *egressSettings)
764765{
765766 // Service : always use rtmp_custom
766- service = obs_service_create (" rtmp_custom" , qUtf8Printable (name), egressSettings, nullptr );
767+ service =
768+ obs_service_create (" rtmp_custom" , qUtf8Printable (QString (" %1.Service" ).arg (name)), egressSettings, nullptr );
767769 if (!service) {
768770 obs_log (LOG_ERROR, " %s: Failed to create service" , qUtf8Printable (name));
769771 return false ;
770772 }
771773
772774 // Output : always use ffmpeg_mpegts_muxer
773- streamingOutput = obs_output_create (" ffmpeg_mpegts_muxer" , qUtf8Printable (name), egressSettings, nullptr );
775+ streamingOutput = obs_output_create (
776+ " ffmpeg_mpegts_muxer" , qUtf8Printable (QString (" %1.Streaming" ).arg (name)), egressSettings, nullptr
777+ );
774778 if (!streamingOutput) {
775779 obs_log (LOG_ERROR, " %s: Failed to create streaming output" , qUtf8Printable (name));
776780 return false ;
@@ -794,7 +798,8 @@ bool EgressLinkOutput::createRecordingOutput(obs_data_t *egressSettings)
794798
795799 // No abort happen even if failed to create output
796800 OBSDataAutoRelease recordingSettings = createRecordingSettings (egressSettings);
797- recordingOutput = obs_output_create (outputId, qUtf8Printable (name), recordingSettings, nullptr );
801+ recordingOutput =
802+ obs_output_create (outputId, qUtf8Printable (QString (" %1.Recording" ).arg (name)), recordingSettings, nullptr );
798803 if (!recordingOutput) {
799804 obs_log (LOG_ERROR, " %s: Failed to create recording output" , qUtf8Printable (name));
800805 return false ;
@@ -812,7 +817,9 @@ bool EgressLinkOutput::createVideoEncoder(obs_data_t *egressSettings, video_t *v
812817 return false ;
813818 }
814819 obs_log (LOG_DEBUG, " %s: Video encoder: %s" , qUtf8Printable (name), videoEncoderId);
815- videoEncoder = obs_video_encoder_create (videoEncoderId, qUtf8Printable (name), egressSettings, nullptr );
820+ videoEncoder = obs_video_encoder_create (
821+ videoEncoderId, qUtf8Printable (QString (" %1.VideoEncoder" ).arg (name)), egressSettings, nullptr
822+ );
816823 if (!videoEncoder) {
817824 obs_log (LOG_ERROR, " %s: Failed to create video encoder: %s" , qUtf8Printable (name), videoEncoderId);
818825 return false ;
@@ -851,8 +858,9 @@ bool EgressLinkOutput::createAudioEncoder(obs_data_t *egressSettings, QString au
851858 obs_log (LOG_DEBUG, " %s: Audio source: Master track %d" , qUtf8Printable (name), value);
852859 }
853860
854- audioEncoder =
855- obs_audio_encoder_create (audioEncoderId, qUtf8Printable (name), audioEncoderSettings, audioTrack, nullptr );
861+ audioEncoder = obs_audio_encoder_create (
862+ audioEncoderId, qUtf8Printable (QString (" %1.AudioEncoder" ).arg (name)), audioEncoderSettings, audioTrack, nullptr
863+ );
856864 if (!audioEncoder) {
857865 obs_log (LOG_ERROR, " %s: Failed to create audio encoder: %s" , qUtf8Printable (name), audioEncoderId);
858866 return false ;
@@ -1008,23 +1016,44 @@ void EgressLinkOutput::start()
10081016
10091017 // --- Start recording output ---//
10101018 if (reconstructPipeline && recordingOutput) {
1011- obs_output_set_video_encoder (recordingOutput, videoEncoder);
1012- obs_output_set_audio_encoder (recordingOutput, audioEncoder, 0 ); // Don't support multiple audio outputs
1019+ // Starts recording output later
1020+ setRecordingStatus (RECORDING_OUTPUT_STATUS_ACTIVATING);
1021+ }
10131022
1014- if (!obs_output_start (recordingOutput)) {
1015- obs_log (LOG_ERROR, " %s: Failed to start recording output" , qUtf8Printable (name));
1016- setRecordingStatus (RECORDING_OUTPUT_STATUS_ERROR);
1023+ // --- Start streaming output ---//
1024+ if (reconstructPipeline && streamingOutput) {
1025+ // Save current timestamp to reduce reconnection with timeout
1026+ connectionAttemptingAt = QDateTime ().currentMSecsSinceEpoch ();
1027+ // Starts streaming output later
1028+ setStatus (EGRESS_LINK_OUTPUT_STATUS_ACTIVATING);
1029+
1030+ /*
1031+ obs_output_set_video_encoder(streamingOutput, videoEncoder);
1032+ obs_output_set_audio_encoder(streamingOutput, audioEncoder, 0); // Don't support multiple audio outputs
1033+
1034+ if (!obs_output_start(streamingOutput)) {
1035+ obs_log(LOG_ERROR, "%s: Failed to start streaming output", qUtf8Printable(name));
1036+ setStatus(EGRESS_LINK_OUTPUT_STATUS_ERROR);
10171037 } else {
10181038 if (source) {
10191039 obs_source_inc_showing(source);
10201040 }
1021- obs_log (LOG_INFO, " %s: Activated recording output" , qUtf8Printable (name));
1022- setRecordingStatus (RECORDING_OUTPUT_STATUS_ACTIVE);
1041+ obs_log(LOG_INFO, "%s: Activated streaming output", qUtf8Printable(name));
1042+ setStatus(EGRESS_LINK_OUTPUT_STATUS_ACTIVE);
1043+ apiClient->incrementActiveOutputs();
10231044 }
1045+ */
10241046 }
1047+ }();
1048+ apiClient->syncUplinkStatus ();
1049+ locker.unlock ();
1050+ }
10251051
1026- // --- Start streaming output ---//
1027- if (reconstructPipeline && streamingOutput) {
1052+ void EgressLinkOutput::startStreaming ()
1053+ {
1054+ QMutexLocker locker (&outputMutex);
1055+ [&]() {
1056+ if (streamingOutput) {
10281057 // Save current timestamp to reduce reconnection with timeout
10291058 connectionAttemptingAt = QDateTime ().currentMSecsSinceEpoch ();
10301059
@@ -1048,6 +1077,29 @@ void EgressLinkOutput::start()
10481077 locker.unlock ();
10491078}
10501079
1080+ void EgressLinkOutput::startRecording ()
1081+ {
1082+ QMutexLocker locker (&outputMutex);
1083+ [&]() {
1084+ if (recordingOutput) {
1085+ obs_output_set_video_encoder (recordingOutput, videoEncoder);
1086+ obs_output_set_audio_encoder (recordingOutput, audioEncoder, 0 ); // Don't support multiple audio outputs
1087+
1088+ if (!obs_output_start (recordingOutput)) {
1089+ obs_log (LOG_ERROR, " %s: Failed to start recording output" , qUtf8Printable (name));
1090+ setRecordingStatus (RECORDING_OUTPUT_STATUS_ERROR);
1091+ } else {
1092+ if (source) {
1093+ obs_source_inc_showing (source);
1094+ }
1095+ obs_log (LOG_INFO, " %s: Activated recording output" , qUtf8Printable (name));
1096+ setRecordingStatus (RECORDING_OUTPUT_STATUS_ACTIVE);
1097+ }
1098+ }
1099+ }();
1100+ locker.unlock ();
1101+ }
1102+
10511103// Modifies state of members:
10521104// source, activeSourceUuid, streamingOutput, recordingOutput, service, videoEncoder, audioEncoder, sourceView,
10531105// audioSource, audioSilence
@@ -1176,7 +1228,24 @@ void EgressLinkOutput::onSnapshotTimerTimeout()
11761228void EgressLinkOutput::onMonitoringTimerTimeout ()
11771229{
11781230 auto interlockType = apiClient->getSettings ()->value (" interlock_type" , DEFAULT_INTERLOCK_TYPE);
1179- if (status != EGRESS_LINK_OUTPUT_STATUS_ACTIVE && status != EGRESS_LINK_OUTPUT_STATUS_STAND_BY) {
1231+
1232+ auto activateStreaming = status == EGRESS_LINK_OUTPUT_STATUS_ACTIVATING;
1233+ auto activateRecording = recordingStatus == RECORDING_OUTPUT_STATUS_ACTIVATING;
1234+
1235+ if (activateStreaming || activateRecording) {
1236+ // Prioritize activating output
1237+
1238+ if (QDateTime ().currentMSecsSinceEpoch () - connectionAttemptingAt > OUTPUT_START_DELAY_MSECS) {
1239+ // Delaying at least OUTPUT_START_DELAY_MSECS after attempting activate
1240+ if (activateStreaming) {
1241+ startStreaming ();
1242+ }
1243+ if (activateRecording) {
1244+ startRecording ();
1245+ }
1246+ }
1247+
1248+ } else if (status != EGRESS_LINK_OUTPUT_STATUS_ACTIVE && status != EGRESS_LINK_OUTPUT_STATUS_STAND_BY) {
11801249 if (interlockType == " always_on" ) {
11811250 start ();
11821251 } else if (interlockType == " streaming" ) {
@@ -1196,10 +1265,9 @@ void EgressLinkOutput::onMonitoringTimerTimeout()
11961265 start ();
11971266 }
11981267 }
1199- return ;
1200- }
12011268
1202- if (QDateTime ().currentMSecsSinceEpoch () - connectionAttemptingAt > OUTPUT_RETRY_TIMEOUT_MSECS) {
1269+ } else if (QDateTime ().currentMSecsSinceEpoch () - connectionAttemptingAt > OUTPUT_RETRY_TIMEOUT_MSECS) {
1270+ // Delaying at least OUTPUT_RETRY_TIMEOUT_MSECS after attempting start
12031271 if (interlockType.isEmpty ()) {
12041272 // Always off
12051273 stop ();
0 commit comments