From d870bbb643930183322d36e57b03a5a03b61d012 Mon Sep 17 00:00:00 2001 From: Palana Date: Mon, 23 Nov 2015 15:28:25 +0100 Subject: [PATCH] obs-ffmpeg: Add custom muxer options to ffmpeg-mux --- plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c | 31 +++++++++++++- plugins/obs-ffmpeg/obs-ffmpeg-mux.c | 49 ++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c index ec139033e..74bb1f4fd 100644 --- a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c @@ -73,6 +73,7 @@ struct main_params { int fps_num; int fps_den; char *acodec; + char *muxer_settings; }; struct audio_params { @@ -247,6 +248,9 @@ static bool init_params(int *argc, char ***argv, struct main_params *params, } *p_audio = audio; + + get_opt_str(argc, argv, ¶ms->muxer_settings, "muxer settings"); + return true; } @@ -461,13 +465,38 @@ static inline int open_output_file(struct ffmpeg_mux *ffm) sizeof(ffm->output->filename)); ffm->output->filename[sizeof(ffm->output->filename) - 1] = 0; - ret = avformat_write_header(ffm->output, NULL); + AVDictionary *dict = NULL; + if ((ret = av_dict_parse_string(&dict, ffm->params.muxer_settings, + "=", " ", 0))) { + printf("Failed to parse muxer settings: %s\n%s", + av_err2str(ret), ffm->params.muxer_settings); + + av_dict_free(&dict); + } + + if (av_dict_count(dict) > 0) { + printf("Using muxer settings:"); + + AVDictionaryEntry *entry = NULL; + while ((entry = av_dict_get(dict, "", entry, + AV_DICT_IGNORE_SUFFIX))) + printf("\n\t%s=%s", entry->key, entry->value); + + printf("\n"); + } + + ret = avformat_write_header(ffm->output, &dict); if (ret < 0) { printf("Error opening '%s': %s", ffm->params.file, av_err2str(ret)); + + av_dict_free(&dict); + return ret == -22 ? FFM_UNSUPPORTED : FFM_ERROR; } + av_dict_free(&dict); + return FFM_SUCCESS; } diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c index 4fcce09d1..404ad7fd2 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c @@ -21,6 +21,8 @@ #include #include "ffmpeg-mux/ffmpeg-mux.h" +#include + #define do_log(level, format, ...) \ blog(level, "[ffmpeg muxer: '%s'] " format, \ obs_output_get_name(stream->output), ##__VA_ARGS__) @@ -112,6 +114,51 @@ static void add_audio_encoder_params(struct dstr *cmd, obs_encoder_t *aencoder) dstr_free(&name); } +static void log_muxer_params(struct ffmpeg_muxer *stream, const char *settings) +{ + int ret; + + AVDictionary *dict = NULL; + if ((ret = av_dict_parse_string(&dict, settings, "=", " ", 0))) { + warn("Failed to parse muxer settings: %s\n%s", + av_err2str(ret), settings); + + av_dict_free(&dict); + return; + } + + if (av_dict_count(dict) > 0) { + struct dstr str = {0}; + + AVDictionaryEntry *entry = NULL; + while ((entry = av_dict_get(dict, "", entry, + AV_DICT_IGNORE_SUFFIX))) + dstr_catf(&str, "\n\t%s=%s", entry->key, entry->value); + + info("Using muxer settings:%s", str.array); + dstr_free(&str); + } + + av_dict_free(&dict); +} + +static void add_muxer_params(struct dstr *cmd, struct ffmpeg_muxer *stream) +{ + obs_data_t *settings = obs_output_get_settings(stream->output); + struct dstr mux = {0}; + + dstr_copy(&mux, obs_data_get_string(settings, "muxer_settings")); + + log_muxer_params(stream, mux.array); + + dstr_replace(&mux, "\"", "\\\""); + obs_data_release(settings); + + dstr_catf(cmd, "\"%s\" ", mux.array ? mux.array : ""); + + dstr_free(&mux); +} + static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd) { obs_encoder_t *vencoder = obs_output_get_video_encoder(stream->output); @@ -144,6 +191,8 @@ static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd) add_audio_encoder_params(cmd, aencoders[i]); } } + + add_muxer_params(cmd, stream); } static bool ffmpeg_mux_start(void *data)