Ver Fonte

UI: Allow services to use different outputs

Allows a service to specify the output it needs in order to function as
configured.

NOTE: This functionality should be considered temporary as a seamless
means of implementing support for different output types within the same
service.  Ideally, different services should be used for this
functionality.
jp9000 há 8 anos atrás
pai
commit
3491487c71

+ 15 - 6
UI/window-basic-auto-config-test.cpp

@@ -157,6 +157,8 @@ static inline void string_depad_key(string &key)
 	}
 }
 
+const char *FindAudioEncoderFromCodec(const char *type);
+
 void AutoConfigTestPage::TestBandwidthThread()
 {
 	bool connected = false;
@@ -189,9 +191,6 @@ void AutoConfigTestPage::TestBandwidthThread()
 			"test_aac", nullptr, 0, nullptr);
 	OBSService service = obs_service_create(serverType,
 			"test_service", nullptr, nullptr);
-	OBSOutput output = obs_output_create("rtmp_output",
-			"test_stream", nullptr, nullptr);
-	obs_output_release(output);
 	obs_encoder_release(vencoder);
 	obs_encoder_release(aencoder);
 	obs_service_release(service);
@@ -251,19 +250,29 @@ void AutoConfigTestPage::TestBandwidthThread()
 		servers.resize(1);
 
 	/* -----------------------------------*/
-	/* apply settings                     */
+	/* apply service settings             */
 
 	obs_service_update(service, service_settings);
 	obs_service_apply_encoder_settings(service,
 			vencoder_settings, aencoder_settings);
 
-	obs_encoder_update(vencoder, vencoder_settings);
-	obs_encoder_update(aencoder, aencoder_settings);
+	/* -----------------------------------*/
+	/* create output                      */
+
+	const char *output_type = obs_service_get_output_type(service);
+	if (!output_type)
+		output_type = "rtmp_output";
+
+	OBSOutput output = obs_output_create(output_type,
+			"test_stream", nullptr, nullptr);
+	obs_output_release(output);
 	obs_output_update(output, output_settings);
 
 	/* -----------------------------------*/
 	/* connect encoders/services/outputs  */
 
+	obs_encoder_update(vencoder, vencoder_settings);
+	obs_encoder_update(aencoder, aencoder_settings);
 	obs_encoder_set_video(vencoder, obs_get_video());
 	obs_encoder_set_audio(aencoder, obs_get_audio());
 

+ 87 - 53
UI/window-basic-main-outputs.cpp

@@ -313,12 +313,6 @@ void SimpleOutput::LoadRecordingPreset()
 
 SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 {
-	streamOutput = obs_output_create("rtmp_output", "simple_stream",
-			nullptr, nullptr);
-	if (!streamOutput)
-		throw "Failed to create stream output (simple output)";
-	obs_output_release(streamOutput);
-
 	const char *encoder = config_get_string(main->Config(), "SimpleOutput",
 			"StreamEncoder");
 	if (strcmp(encoder, SIMPLE_ENCODER_QSV) == 0)
@@ -334,16 +328,6 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 				"simple_aac", 0))
 		throw "Failed to create aac streaming encoder (simple output)";
 
-	streamDelayStarting.Connect(obs_output_get_signal_handler(streamOutput),
-			"starting", OBSStreamStarting, this);
-	streamStopping.Connect(obs_output_get_signal_handler(streamOutput),
-			"stopping", OBSStreamStopping, this);
-
-	startStreaming.Connect(obs_output_get_signal_handler(streamOutput),
-			"start", OBSStartStreaming, this);
-	stopStreaming.Connect(obs_output_get_signal_handler(streamOutput),
-			"stop", OBSStopStreaming, this);
-
 	LoadRecordingPreset();
 
 	if (!ffmpegOutput) {
@@ -650,15 +634,63 @@ inline void SimpleOutput::SetupOutputs()
 	}
 }
 
+const char *FindAudioEncoderFromCodec(const char *type)
+{
+	const char *alt_enc_id = nullptr;
+	size_t i = 0;
+
+	while (obs_enum_encoder_types(i++, &alt_enc_id)) {
+		const char *codec = obs_get_encoder_codec(alt_enc_id);
+		if (strcmp(type, codec) == 0) {
+			return alt_enc_id;
+		}
+	}
+
+	return nullptr;
+}
+
 bool SimpleOutput::StartStreaming(obs_service_t *service)
 {
 	if (!Active())
 		SetupOutputs();
 
+	/* --------------------- */
+
+	const char *type = obs_service_get_output_type(service);
+	if (!type)
+		type = "rtmp_output";
+
+	/* XXX: this is messy and disgusting and should be refactored */
+	if (outputType != type) {
+		streamOutput = obs_output_create(type, "simple_stream",
+				nullptr, nullptr);
+		if (!streamOutput)
+			return false;
+		obs_output_release(streamOutput);
+
+		streamDelayStarting.Connect(
+				obs_output_get_signal_handler(streamOutput),
+				"starting", OBSStreamStarting, this);
+		streamStopping.Connect(
+				obs_output_get_signal_handler(streamOutput),
+				"stopping", OBSStreamStopping, this);
+
+		startStreaming.Connect(
+				obs_output_get_signal_handler(streamOutput),
+				"start", OBSStartStreaming, this);
+		stopStreaming.Connect(
+				obs_output_get_signal_handler(streamOutput),
+				"stop", OBSStopStreaming, this);
+
+		outputType = type;
+	}
+
 	obs_output_set_video_encoder(streamOutput, h264Streaming);
 	obs_output_set_audio_encoder(streamOutput, aacStreaming, 0);
 	obs_output_set_service(streamOutput, service);
 
+	/* --------------------- */
+
 	bool reconnect = config_get_bool(main->Config(), "Output",
 			"Reconnect");
 	int retryDelay = config_get_uint(main->Config(), "Output",
@@ -986,12 +1018,6 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 	OBSData streamEncSettings = GetDataFromJsonFile("streamEncoder.json");
 	OBSData recordEncSettings = GetDataFromJsonFile("recordEncoder.json");
 
-	streamOutput = obs_output_create("rtmp_output", "adv_stream",
-			nullptr, nullptr);
-	if (!streamOutput)
-		throw "Failed to create stream output (advanced output)";
-	obs_output_release(streamOutput);
-
 	if (ffmpegOutput) {
 		fileOutput = obs_output_create("ffmpeg_output",
 				"adv_ffmpeg_output", nullptr, nullptr);
@@ -1035,16 +1061,6 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 			      "(advanced output)";
 	}
 
-	streamDelayStarting.Connect(obs_output_get_signal_handler(streamOutput),
-			"starting", OBSStreamStarting, this);
-	streamStopping.Connect(obs_output_get_signal_handler(streamOutput),
-			"stopping", OBSStreamStopping, this);
-
-	startStreaming.Connect(obs_output_get_signal_handler(streamOutput),
-			"start", OBSStartStreaming, this);
-	stopStreaming.Connect(obs_output_get_signal_handler(streamOutput),
-			"stop", OBSStopStreaming, this);
-
 	startRecording.Connect(obs_output_get_signal_handler(fileOutput),
 			"start", OBSStartRecording, this);
 	stopRecording.Connect(obs_output_get_signal_handler(fileOutput),
@@ -1094,12 +1110,6 @@ inline void AdvancedOutput::SetupStreaming()
 			"Rescale");
 	const char *rescaleRes = config_get_string(main->Config(), "AdvOut",
 			"RescaleRes");
-	bool multitrack = config_get_bool(main->Config(), "AdvOut",
-			"Multitrack");
-	int trackIndex = config_get_int(main->Config(), "AdvOut",
-			"TrackIndex");
-	int trackCount = config_get_int(main->Config(), "AdvOut",
-			"TrackCount");
 	unsigned int cx = 0;
 	unsigned int cy = 0;
 
@@ -1112,21 +1122,6 @@ inline void AdvancedOutput::SetupStreaming()
 
 	obs_encoder_set_scaled_size(h264Streaming, cx, cy);
 	obs_encoder_set_video(h264Streaming, obs_get_video());
-
-	obs_output_set_video_encoder(streamOutput, h264Streaming);
-
-	if (multitrack) {
-		int i = 0;
-		for (; i < trackCount; i++)
-			obs_output_set_audio_encoder(streamOutput, aacTrack[i],
-					i);
-		for (; i < MAX_AUDIO_MIXES; i++)
-			obs_output_set_audio_encoder(streamOutput, nullptr, i);
-
-	} else {
-		obs_output_set_audio_encoder(streamOutput,
-				aacTrack[trackIndex - 1], 0);
-	}
 }
 
 inline void AdvancedOutput::SetupRecording()
@@ -1320,6 +1315,45 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
 	if (!Active())
 		SetupOutputs();
 
+	/* --------------------- */
+
+	int trackIndex = config_get_int(main->Config(), "AdvOut",
+			"TrackIndex");
+
+	const char *type = obs_service_get_output_type(service);
+	if (!type)
+		type = "rtmp_output";
+
+	/* XXX: this is messy and disgusting and should be refactored */
+	if (outputType != type) {
+		streamOutput = obs_output_create(type, "adv_stream",
+				nullptr, nullptr);
+		if (!streamOutput)
+			return false;
+		obs_output_release(streamOutput);
+
+		streamDelayStarting.Connect(
+				obs_output_get_signal_handler(streamOutput),
+				"starting", OBSStreamStarting, this);
+		streamStopping.Connect(
+				obs_output_get_signal_handler(streamOutput),
+				"stopping", OBSStreamStopping, this);
+
+		startStreaming.Connect(
+				obs_output_get_signal_handler(streamOutput),
+				"start", OBSStartStreaming, this);
+		stopStreaming.Connect(
+				obs_output_get_signal_handler(streamOutput),
+				"stop", OBSStopStreaming, this);
+
+		outputType = type;
+	}
+
+	obs_output_set_video_encoder(streamOutput, h264Streaming);
+	obs_output_set_audio_encoder(streamOutput, aacTrack[trackIndex - 1], 0);
+
+	/* --------------------- */
+
 	obs_output_set_service(streamOutput, service);
 
 	bool reconnect = config_get_bool(main->Config(), "Output", "Reconnect");

+ 4 - 0
UI/window-basic-main-outputs.hpp

@@ -1,5 +1,7 @@
 #pragma once
 
+#include <string>
+
 class OBSBasic;
 
 struct BasicOutputHandler {
@@ -12,6 +14,8 @@ struct BasicOutputHandler {
 	bool                   replayBufferActive = false;
 	OBSBasic               *main;
 
+	std::string            outputType;
+
 	OBSSignal              startRecording;
 	OBSSignal              stopRecording;
 	OBSSignal              startReplayBuffer;