diff --git a/obs/data/locale/en-US.ini b/obs/data/locale/en-US.ini index bf35c1c5a..ef4741c66 100644 --- a/obs/data/locale/en-US.ini +++ b/obs/data/locale/en-US.ini @@ -326,6 +326,9 @@ Basic.Settings.Output.Adv.Recording.Type="Type" Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Custom Output (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Use stream encoder)" +Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg Output Type" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="Output to URL" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Output to File" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Common recording formats" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="All Files" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="File path or URL" diff --git a/obs/forms/OBSBasicSettings.ui b/obs/forms/OBSBasicSettings.ui index 33fd51f96..646628996 100644 --- a/obs/forms/OBSBasicSettings.ui +++ b/obs/forms/OBSBasicSettings.ui @@ -7,7 +7,7 @@ 0 0 895 - 602 + 614 @@ -1293,7 +1293,7 @@ 0 - + @@ -1315,42 +1315,104 @@ - - - - - - true + + + + 0 + + + + + 3 - - - - - - true + + 0 - - Browse + + 0 - - - + + 0 + + + 0 + + + + + true + + + + + + + Browse + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + + - + Basic.Settings.Output.Adv.FFmpeg.Format + + + + + + Basic.Settings.Output.Adv.FFmpeg.FormatDesc + + + + + + + + + + + Basic.Settings.Output.VideoBitrate - + 0 @@ -1363,7 +1425,7 @@ - + @@ -1379,7 +1441,7 @@ - + false @@ -1389,34 +1451,34 @@ - + Basic.Settings.Output.Adv.FFmpeg.VEncoder - + - + Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings - + - + Basic.Settings.Output.AudioBitrate - + 32 @@ -1432,14 +1494,14 @@ - + Basic.Settings.Output.Adv.AudioTrack - + @@ -1494,43 +1556,62 @@ - + Basic.Settings.Output.Adv.FFmpeg.AEncoder - + + + + Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings - + - - - - - + + + + + 0 + 0 + + + + + 170 + 0 + + - + Basic.Settings.Output.Adv.FFmpeg.Type + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - Basic.Settings.Output.Adv.FFmpeg.FormatDesc - + + + + + Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile + + + + + Basic.Settings.Output.Adv.FFmpeg.Type.URL + + - - - @@ -2171,8 +2252,8 @@ 0 0 - 98 - 28 + 67 + 16 @@ -2559,8 +2640,8 @@ 0 0 - 325 - 229 + 428 + 287 @@ -2789,8 +2870,8 @@ setCurrentIndex(int) - 310 - 29 + 159 + 34 241 @@ -2821,12 +2902,12 @@ setEnabled(bool) - 422 - 168 + 875 + 254 - 420 - 188 + 875 + 291 @@ -2837,12 +2918,12 @@ setEnabled(bool) - 503 - 160 + 875 + 254 - 501 - 209 + 875 + 328 @@ -2853,12 +2934,12 @@ setVisible(bool) - 439 - 240 + 875 + 360 - 750 - 295 + 875 + 427 @@ -2869,12 +2950,12 @@ setVisible(bool) - 482 - 241 + 875 + 360 - 367 - 295 + 466 + 427 @@ -2885,12 +2966,12 @@ setVisible(bool) - 459 - 234 + 875 + 360 - 750 - 347 + 875 + 503 @@ -2901,12 +2982,12 @@ setVisible(bool) - 554 - 236 + 875 + 360 - 367 - 347 + 466 + 503 @@ -2917,12 +2998,12 @@ setVisible(bool) - 398 - 241 + 871 + 360 - 410 - 261 + 875 + 392 @@ -2933,12 +3014,12 @@ setEnabled(bool) - 318 - 312 + 466 + 464 - 473 - 311 + 875 + 464 @@ -2949,12 +3030,12 @@ setVisible(bool) - 456 - 241 + 875 + 360 - 260 - 315 + 457 + 464 @@ -2965,12 +3046,12 @@ setVisible(bool) - 525 - 238 + 875 + 360 - 519 - 317 + 875 + 464 @@ -2981,12 +3062,12 @@ setCurrentIndex(int) - 259 - 101 + 705 + 144 - 243 - 106 + 396 + 245 @@ -2997,12 +3078,12 @@ setEnabled(bool) - 259 - 113 + 514 + 344 - 230 - 125 + 748 + 344 @@ -3013,12 +3094,12 @@ setEnabled(bool) - 468 - 110 + 864 + 141 - 362 - 136 + 427 + 178 @@ -3029,12 +3110,12 @@ setEnabled(bool) - 468 - 110 + 864 + 141 - 468 - 136 + 864 + 178 @@ -3045,12 +3126,12 @@ setEnabled(bool) - 468 - 110 + 864 + 141 - 299 - 162 + 427 + 215 @@ -3061,12 +3142,12 @@ setEnabled(bool) - 468 - 110 + 864 + 141 - 468 - 162 + 864 + 215 @@ -3077,12 +3158,12 @@ setEnabled(bool) - 270 - 237 + 427 + 355 - 437 - 237 + 862 + 355 @@ -3093,12 +3174,12 @@ setEnabled(bool) - 259 - 113 + 424 + 331 - 230 - 125 + 658 + 331 @@ -3109,12 +3190,12 @@ setEnabled(bool) - 444 - 162 + 875 + 254 - 298 - 190 + 466 + 291 @@ -3125,12 +3206,28 @@ setEnabled(bool) - 475 - 161 + 875 + 254 - 350 - 218 + 466 + 328 + + + + + advOutFFType + currentIndexChanged(int) + stackedWidget_2 + setCurrentIndex(int) + + + 732 + 179 + + + 777 + 206 diff --git a/obs/window-basic-main-outputs.cpp b/obs/window-basic-main-outputs.cpp index a35bd0456..591f3f9bf 100644 --- a/obs/window-basic-main-outputs.cpp +++ b/obs/window-basic-main-outputs.cpp @@ -298,6 +298,7 @@ struct AdvancedOutput : BasicOutputHandler { OBSEncoder h264Streaming; OBSEncoder h264Recording; + bool ffmpegOutput; bool ffmpegRecording; bool useStreamEncoder; @@ -351,7 +352,9 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_) const char *recordEncoder = config_get_string(main->Config(), "AdvOut", "RecEncoder"); - ffmpegRecording = astrcmpi(recType, "FFmpeg") == 0; + ffmpegOutput = astrcmpi(recType, "FFmpeg") == 0; + ffmpegRecording = ffmpegOutput && + config_get_bool(main->Config(), "AdvOut", "FFOutputToFile"); useStreamEncoder = astrcmpi(recordEncoder, "none") == 0; OBSData streamEncSettings = GetDataFromJsonFile("streamEncoder.json"); @@ -363,7 +366,7 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_) throw "Failed to create stream output (advanced output)"; obs_output_release(streamOutput); - if (ffmpegRecording) { + if (ffmpegOutput) { fileOutput = obs_output_create("ffmpeg_output", "adv_ffmpeg_output", nullptr, nullptr); if (!fileOutput) @@ -447,7 +450,7 @@ inline void AdvancedOutput::UpdateRecordingSettings() void AdvancedOutput::Update() { UpdateStreamSettings(); - if (!useStreamEncoder && !ffmpegRecording) + if (!useStreamEncoder && !ffmpegOutput) UpdateRecordingSettings(); UpdateAudioSettings(); } @@ -649,7 +652,7 @@ void AdvancedOutput::SetupOutputs() SetupStreaming(); - if (ffmpegRecording) + if (ffmpegOutput) SetupFFmpeg(); else SetupRecording(); @@ -667,7 +670,7 @@ int AdvancedOutput::GetAudioBitrate(size_t i) const bool AdvancedOutput::StartStreaming(obs_service_t *service) { if (!useStreamEncoder || - (!ffmpegRecording && !obs_output_active(fileOutput))) { + (!ffmpegOutput && !obs_output_active(fileOutput))) { UpdateStreamSettings(); } @@ -697,8 +700,11 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) bool AdvancedOutput::StartRecording() { + const char *path; + const char *format; + if (!useStreamEncoder) { - if (!ffmpegRecording) { + if (!ffmpegOutput) { UpdateRecordingSettings(); } } else if (!obs_output_active(streamOutput)) { @@ -710,11 +716,11 @@ bool AdvancedOutput::StartRecording() if (!Active()) SetupOutputs(); - if (!ffmpegRecording) { - const char *path = config_get_string(main->Config(), - "AdvOut", "RecFilePath"); - const char *format = config_get_string(main->Config(), - "AdvOut", "RecFormat"); + if (!ffmpegOutput || ffmpegRecording) { + path = config_get_string(main->Config(), "AdvOut", + ffmpegRecording ? "FFFilePath" : "RecFilePath"); + format = config_get_string(main->Config(), "AdvOut", + ffmpegRecording ? "FFExtension" : "RecFormat"); os_dir_t *dir = path ? os_opendir(path) : nullptr; @@ -737,7 +743,9 @@ bool AdvancedOutput::StartRecording() strPath += GenerateTimeDateFilename(format); obs_data_t *settings = obs_data_create(); - obs_data_set_string(settings, "path", strPath.c_str()); + obs_data_set_string(settings, + ffmpegRecording ? "url" : "path", + strPath.c_str()); obs_output_update(fileOutput, settings); diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp index c3b40056b..f0e1c718e 100644 --- a/obs/window-basic-main.cpp +++ b/obs/window-basic-main.cpp @@ -681,6 +681,11 @@ bool OBSBasic::InitBasicConfigDefaults() config_set_default_string(basicConfig, "AdvOut", "RecEncoder", "none"); + config_set_default_bool (basicConfig, "AdvOut", "FFOutputToFile", + true); + config_set_default_string(basicConfig, "AdvOut", "FFFilePath", + GetDefaultVideoSavePath().c_str()); + config_set_default_string(basicConfig, "AdvOut", "FFExtension", "mp4"); config_set_default_uint (basicConfig, "AdvOut", "FFVBitrate", 2500); config_set_default_bool (basicConfig, "AdvOut", "FFUseRescale", false); diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp index 3814e13c4..96a1fb09b 100644 --- a/obs/window-basic-settings.cpp +++ b/obs/window-basic-settings.cpp @@ -300,6 +300,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->advOutRecTrack2, CHECK_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->advOutRecTrack3, CHECK_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->advOutRecTrack4, CHECK_CHANGED, OUTPUTS_CHANGED); + HookWidget(ui->advOutFFType, COMBO_CHANGED, OUTPUTS_CHANGED); + HookWidget(ui->advOutFFRecPath, EDIT_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->advOutFFURL, EDIT_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->advOutFFFormat, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->advOutFFVBitrate, SCROLL_CHANGED, OUTPUTS_CHANGED); @@ -1172,6 +1174,10 @@ static void SelectEncoder(QComboBox *combo, const char *name, int id) void OBSBasicSettings::LoadAdvOutputFFmpegSettings() { + bool saveFile = config_get_bool(main->Config(), "AdvOut", + "FFOutputToFile"); + const char *path = config_get_string(main->Config(), "AdvOut", + "FFFilePath"); const char *url = config_get_string(main->Config(), "AdvOut", "FFURL"); const char *format = config_get_string(main->Config(), "AdvOut", "FFFormat"); @@ -1200,7 +1206,9 @@ void OBSBasicSettings::LoadAdvOutputFFmpegSettings() const char *aEncCustom = config_get_string(main->Config(), "AdvOut", "FFACustom"); - ui->advOutFFURL->setText(url); + ui->advOutFFType->setCurrentIndex(saveFile ? 0 : 1); + ui->advOutFFRecPath->setText(QT_UTF8(path)); + ui->advOutFFURL->setText(QT_UTF8(url)); SelectFormat(ui->advOutFFFormat, format, mimeType); ui->advOutFFVBitrate->setValue(videoBitrate); ui->advOutFFUseRescale->setChecked(rescale); @@ -2008,11 +2016,23 @@ void OBSBasicSettings::SaveFormat(QComboBox *combo) desc.name); config_set_string(main->Config(), "AdvOut", "FFFormatMimeType", desc.mimeType); + + const char *ext = ff_format_desc_extensions(desc.desc); + string extStr = ext; + + char *comma = strchr(&extStr[0], ','); + if (comma) + comma = 0; + + config_set_string(main->Config(), "AdvOut", "FFExtension", + extStr.c_str()); } else { config_set_string(main->Config(), "AdvOut", "FFFormat", nullptr); config_set_string(main->Config(), "AdvOut", "FFFormatMimeType", nullptr); + + config_remove_value(main->Config(), "AdvOut", "FFExtension"); } } @@ -2078,6 +2098,9 @@ void OBSBasicSettings::SaveOutputSettings() (ui->advOutRecTrack3->isChecked() ? (1<<2) : 0) | (ui->advOutRecTrack4->isChecked() ? (1<<3) : 0)); + config_set_bool(main->Config(), "AdvOut", "FFOutputToFile", + ui->advOutFFType->currentIndex() == 0 ? true : false); + SaveEdit(ui->advOutFFRecPath, "AdvOut", "FFFilePath"); SaveEdit(ui->advOutFFURL, "AdvOut", "FFURL"); SaveFormat(ui->advOutFFFormat); SaveSpinBox(ui->advOutFFVBitrate, "AdvOut", "FFVBitrate"); @@ -2387,19 +2410,15 @@ void OBSBasicSettings::on_advOutRecPathBrowse_clicked() void OBSBasicSettings::on_advOutFFPathBrowse_clicked() { - QString filter; - filter += QTStr("Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common"); - filter += " (*.avi *.mp4 *.flv *.ts *.mkv *.wav *.aac);;"; - filter += QTStr("Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All"); - filter += " (*.*)"; - - QString file = QFileDialog::getSaveFileName(this, - QTStr("Basic.Settings.Output.SelectFile"), - ui->simpleOutputPath->text(), filter); - if (file.isEmpty()) + QString dir = QFileDialog::getExistingDirectory(this, + QTStr("Basic.Settings.Output.SelectDirectory"), + ui->advOutRecPath->text(), + QFileDialog::ShowDirsOnly | + QFileDialog::DontResolveSymlinks); + if (dir.isEmpty()) return; - ui->advOutFFURL->setText(file); + ui->advOutFFRecPath->setText(dir); } void OBSBasicSettings::on_advOutEncoder_currentIndexChanged(int idx)