UI: Enable multiple audio tracks in Simple Output recording

This adds support for multiple audio tracks in Simple Output for
recordings.
This is enabled for all quality presets (including "Lossless") except
"Same as Stream".
This is also enabled for the Replay Buffer.
An exception is made for flv recording format since it only allows a
single audio track.
The recorded track (and streaming track) is then Track 1 as before.

Signed-off-by: pkv <pkv@obsproject.com>
This commit is contained in:
pkv
2022-07-22 15:28:26 +02:00
committed by Ryan Foster
parent 1b68944107
commit d18b38e784
5 changed files with 378 additions and 9 deletions

View File

@@ -438,6 +438,7 @@ struct SimpleOutput : BasicOutputHandler {
OBSEncoder audioRecording;
OBSEncoder audioArchive;
OBSEncoder videoRecording;
OBSEncoder audioTrack[MAX_AUDIO_MIXES];
string videoEncoder;
string videoQuality;
@@ -502,8 +503,6 @@ void SimpleOutput::LoadRecordingPreset_Lossless()
obs_data_set_string(settings, "video_encoder", "utvideo");
obs_data_set_string(settings, "audio_encoder", "pcm_s16le");
int aMixes = 1;
obs_output_set_mixers(fileOutput, aMixes);
obs_output_update(fileOutput, settings);
}
@@ -611,6 +610,25 @@ void SimpleOutput::LoadRecordingPreset()
if (!success)
throw "Failed to create audio recording encoder "
"(simple output)";
for (int i = 0; i < MAX_AUDIO_MIXES; i++) {
char name[23];
if (strcmp(audio_encoder, "opus") == 0) {
snprintf(name, sizeof name,
"simple_opus_recording%d", i);
success = CreateSimpleOpusEncoder(
audioTrack[i], GetAudioBitrate(), name,
i);
} else {
snprintf(name, sizeof name,
"simple_aac_recording%d", i);
success = CreateSimpleAACEncoder(
audioTrack[i], GetAudioBitrate(), name,
i);
}
if (!success)
throw "Failed to create multi-track audio recording encoder "
"(simple output)";
}
}
}
@@ -813,7 +831,23 @@ void SimpleOutput::UpdateRecordingAudioSettings()
obs_data_set_int(settings, "bitrate", 192);
obs_data_set_string(settings, "rate_control", "CBR");
obs_encoder_update(audioRecording, settings);
int tracks =
config_get_int(main->Config(), "SimpleOutput", "RecTracks");
const char *recFormat =
config_get_string(main->Config(), "SimpleOutput", "RecFormat");
const char *quality =
config_get_string(main->Config(), "SimpleOutput", "RecQuality");
bool flv = strcmp(recFormat, "flv") == 0;
if (flv || strcmp(quality, "Stream") == 0) {
obs_encoder_update(audioRecording, settings);
} else {
for (int i = 0; i < MAX_AUDIO_MIXES; i++) {
if ((tracks & (1 << i)) != 0) {
obs_encoder_update(audioTrack[i], settings);
}
}
}
}
#define CROSS_DIST_CUTOFF 2000.0
@@ -987,6 +1021,11 @@ inline void SimpleOutput::SetupOutputs()
obs_encoder_set_video(videoStreaming, obs_get_video());
obs_encoder_set_audio(audioStreaming, obs_get_audio());
obs_encoder_set_audio(audioArchive, obs_get_audio());
int tracks =
config_get_int(main->Config(), "SimpleOutput", "RecTracks");
const char *recFormat =
config_get_string(main->Config(), "SimpleOutput", "RecFormat");
bool flv = strcmp(recFormat, "flv") == 0;
if (usingRecordingPreset) {
if (ffmpegOutput) {
@@ -994,8 +1033,21 @@ inline void SimpleOutput::SetupOutputs()
obs_get_audio());
} else {
obs_encoder_set_video(videoRecording, obs_get_video());
obs_encoder_set_audio(audioRecording, obs_get_audio());
if (flv) {
obs_encoder_set_audio(audioRecording,
obs_get_audio());
} else {
for (int i = 0; i < MAX_AUDIO_MIXES; i++) {
if ((tracks & (1 << i)) != 0) {
obs_encoder_set_audio(
audioTrack[i],
obs_get_audio());
}
}
}
}
} else {
obs_encoder_set_audio(audioRecording, obs_get_audio());
}
}
@@ -1175,6 +1227,16 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
void SimpleOutput::UpdateRecording()
{
const char *recFormat =
config_get_string(main->Config(), "SimpleOutput", "RecFormat");
bool flv = strcmp(recFormat, "flv") == 0;
int tracks =
config_get_int(main->Config(), "SimpleOutput", "RecTracks");
int idx = 0;
int idx2 = 0;
const char *quality =
config_get_string(main->Config(), "SimpleOutput", "RecQuality");
if (replayBufferActive || recordingActive)
return;
@@ -1190,11 +1252,33 @@ void SimpleOutput::UpdateRecording()
if (!ffmpegOutput) {
obs_output_set_video_encoder(fileOutput, videoRecording);
obs_output_set_audio_encoder(fileOutput, audioRecording, 0);
if (flv || strcmp(quality, "Stream") == 0) {
obs_output_set_audio_encoder(fileOutput, audioRecording,
0);
} else {
for (int i = 0; i < MAX_AUDIO_MIXES; i++) {
if ((tracks & (1 << i)) != 0) {
obs_output_set_audio_encoder(
fileOutput, audioTrack[i],
idx++);
}
}
}
}
if (replayBuffer) {
obs_output_set_video_encoder(replayBuffer, videoRecording);
obs_output_set_audio_encoder(replayBuffer, audioRecording, 0);
if (flv || strcmp(quality, "Stream") == 0) {
obs_output_set_audio_encoder(replayBuffer,
audioRecording, 0);
} else {
for (int i = 0; i < MAX_AUDIO_MIXES; i++) {
if ((tracks & (1 << i)) != 0) {
obs_output_set_audio_encoder(
replayBuffer, audioTrack[i],
idx2++);
}
}
}
}
recordingConfigured = true;
@@ -1222,6 +1306,11 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer)
config_get_int(main->Config(), "SimpleOutput", "RecRBTime");
int rbSize =
config_get_int(main->Config(), "SimpleOutput", "RecRBSize");
int tracks =
config_get_int(main->Config(), "SimpleOutput", "RecTracks");
const char *recFormat =
config_get_string(main->Config(), "SimpleOutput", "RecFormat");
bool flv = strcmp(recFormat, "flv") == 0;
bool is_fragmented = strcmp(format, "fmp4") == 0 ||
strcmp(format, "fmov") == 0;
@@ -1253,6 +1342,8 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer)
f.c_str(), ffmpegOutput);
obs_data_set_string(settings, ffmpegOutput ? "url" : "path",
strPath.c_str());
if (ffmpegOutput)
obs_output_set_mixers(fileOutput, tracks);
}
// Use fragmented MOV/MP4 if user has not already specified custom movflags