diff --git a/libobs/obs-output.c b/libobs/obs-output.c index bf1f13ac9625a3c0167c78fed7195084bf1fb9d9..f798109bebe3666f548bdd466dc513d5c5d197df 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -126,6 +126,15 @@ void obs_output_update(obs_output_t output, obs_data_t settings) output->callbacks.update(output->data, output->settings); } +obs_data_t obs_output_get_settings(obs_output_t output) +{ + if (!output) + return NULL; + + obs_data_addref(output->settings); + return output->settings; +} + bool obs_output_canpause(obs_output_t output) { return output->callbacks.pause != NULL; diff --git a/obs/forms/OBSBasic.ui b/obs/forms/OBSBasic.ui index 46ef8c98e2651f2767013afd760cacbba1a3ed2e..f59d6598557346ba87f9291e25cca28d52903bae 100644 --- a/obs/forms/OBSBasic.ui +++ b/obs/forms/OBSBasic.ui @@ -45,8 +45,8 @@ - 50 - 30 + 0 + 0 32 32 @@ -340,6 +340,9 @@ + + false + Start Streaming @@ -436,6 +439,9 @@ + + false + :/res/images/properties.ico:/res/images/properties.ico @@ -445,6 +451,9 @@ + + false + :/res/images/properties.ico:/res/images/properties.ico diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp index 5b7ced1d0416b54111ec6c98c7c6cba0af2b78a5..ab3580ec8666830319fff39b96284c73116c3875 100644 --- a/obs/window-basic-main.cpp +++ b/obs/window-basic-main.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "obs-app.hpp" #include "window-basic-settings.hpp" @@ -35,7 +36,8 @@ Q_DECLARE_METATYPE(OBSSceneItem); OBSBasic::OBSBasic(QWidget *parent) : OBSMainWindow (parent), - ui (new Ui::OBSBasic) + ui (new Ui::OBSBasic), + outputTest (NULL) { ui->setupUi(this); } @@ -64,10 +66,6 @@ void OBSBasic::OBSInit() obs_load_module("test-input"); obs_load_module("obs-ffmpeg"); - /*obs_output_t output = obs_output_create("ffmpeg_output", "test", - NULL); - obs_output_start(output);*/ - /* HACK: fixes a qt bug with native widgets with native repaint */ ui->previewContainer->repaint(); } @@ -540,6 +538,36 @@ void OBSBasic::on_actionSourceDown_triggered() { } +void OBSBasic::on_recordButton_clicked() +{ + if (outputTest) { + obs_output_destroy(outputTest); + outputTest = NULL; + ui->recordButton->setText("Start Recording"); + } else { + QString path = QFileDialog::getSaveFileName(this, + "Please enter a file name", QString(), + "Video Files (*.mp4)"); + + if (path.isNull() || path.isEmpty()) + return; + + obs_data_t data = obs_data_create(); + obs_data_setstring(data, "filename", QT_TO_UTF8(path)); + + outputTest = obs_output_create("ffmpeg_output", "test", data); + obs_data_release(data); + + if (!obs_output_start(outputTest)) { + obs_output_destroy(outputTest); + outputTest = NULL; + return; + } + + ui->recordButton->setText("Stop Recording"); + } +} + void OBSBasic::on_settingsButton_clicked() { OBSBasicSettings settings(this); diff --git a/obs/window-basic-main.hpp b/obs/window-basic-main.hpp index 3ddb9a2bf4317b5bcc38b71d25f294170f842462..2434a9bd0333a437232921d38b1e3bc57f6ac20e 100644 --- a/obs/window-basic-main.hpp +++ b/obs/window-basic-main.hpp @@ -31,6 +31,7 @@ class OBSBasic : public OBSMainWindow { private: std::unordered_map sourceSceneRefs; + obs_output_t outputTest; OBSScene GetCurrentScene(); OBSSceneItem GetCurrentSceneItem(); @@ -87,6 +88,7 @@ private slots: void on_actionSourceProperties_triggered(); void on_actionSourceUp_triggered(); void on_actionSourceDown_triggered(); + void on_recordButton_clicked(); void on_settingsButton_clicked(); public: diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c index d3183c8099fc14a521ef9536ffc68e89395748a1..f744b39bad4701a6a044bcba04b2bee23e3d75a5 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-output.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c @@ -19,7 +19,6 @@ #include "obs-ffmpeg-output.h" /* TODO: remove these later */ -#define FILENAME_TODO "D:\\test.avi" #define SPS_TODO 44100 /* NOTE: much of this stuff is test stuff that was more or less copied from @@ -233,11 +232,11 @@ static inline bool open_output_file(struct ffmpeg_data *data) int ret; if ((format->flags & AVFMT_NOFILE) == 0) { - ret = avio_open(&data->output->pb, FILENAME_TODO, + ret = avio_open(&data->output->pb, data->filename_test, AVIO_FLAG_WRITE); if (ret < 0) { blog(LOG_ERROR, "Couldn't open file '%s', %s", - FILENAME_TODO, av_err2str(ret)); + data->filename_test, av_err2str(ret)); return false; } } @@ -245,7 +244,7 @@ static inline bool open_output_file(struct ffmpeg_data *data) ret = avformat_write_header(data->output, NULL); if (ret < 0) { blog(LOG_ERROR, "Error opening file '%s': %s", - FILENAME_TODO, av_err2str(ret)); + data->filename_test, av_err2str(ret)); return false; } @@ -286,15 +285,19 @@ static void ffmpeg_data_free(struct ffmpeg_data *data) memset(data, 0, sizeof(struct ffmpeg_data)); } -static bool ffmpeg_data_init(struct ffmpeg_data *data) +static bool ffmpeg_data_init(struct ffmpeg_data *data, const char *filename) { memset(data, 0, sizeof(struct ffmpeg_data)); + data->filename_test = filename; + + if (!filename || !*filename) + return false; av_register_all(); /* TODO: settings */ avformat_alloc_output_context2(&data->output, NULL, NULL, - FILENAME_TODO); + data->filename_test); if (!data->output) { blog(LOG_ERROR, "Couldn't create avformat context"); goto fail; @@ -327,7 +330,7 @@ void test_callback(void *param, int bla, const char *format, va_list args) blogva(LOG_INFO, format, args); } -struct ffmpeg_output *ffmpeg_output_create(const char *settings, +struct ffmpeg_output *ffmpeg_output_create(obs_data_t settings, obs_output_t output) { struct ffmpeg_output *data = bzalloc(sizeof(struct ffmpeg_output)); @@ -347,7 +350,7 @@ void ffmpeg_output_destroy(struct ffmpeg_output *data) } } -void ffmpeg_output_update(struct ffmpeg_output *data, const char *settings) +void ffmpeg_output_update(struct ffmpeg_output *data, obs_data_t settings) { } @@ -521,7 +524,15 @@ bool ffmpeg_output_start(struct ffmpeg_output *data) return false; } - if (!ffmpeg_data_init(&data->ff_data)) + const char *filename_test; + obs_data_t settings = obs_output_get_settings(data->output); + filename_test = obs_data_getstring(settings, "filename"); + obs_data_release(settings); + + if (!filename_test || !*filename_test) + return false; + + if (!ffmpeg_data_init(&data->ff_data, filename_test)) return false; struct audio_convert_info aci; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.h b/plugins/obs-ffmpeg/obs-ffmpeg-output.h index cd3165d1572a3c1f8dc5981452df4def001322d1..34029b25c0c1f336adae690287ad3bd5cb5f6399 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-output.h +++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.h @@ -43,6 +43,8 @@ struct ffmpeg_data { AVFrame *aframe; int total_samples; + const char *filename_test; + bool initialized; }; @@ -54,12 +56,12 @@ struct ffmpeg_output { EXPORT const char *ffmpeg_output_getname(const char *locale); -EXPORT struct ffmpeg_output *ffmpeg_output_create(const char *settings, +EXPORT struct ffmpeg_output *ffmpeg_output_create(obs_data_t settings, obs_output_t output); EXPORT void ffmpeg_output_destroy(struct ffmpeg_output *data); EXPORT void ffmpeg_output_update(struct ffmpeg_output *data, - const char *settings); + obs_data_t settings); EXPORT bool ffmpeg_output_start(struct ffmpeg_output *data); EXPORT void ffmpeg_output_stop(struct ffmpeg_output *data);