Ver código fonte

obs-ffmpeg: Add "restart when active" media source property

Adds the option of making the media file restart when the source becomes
active (such as switching to a scene with it).

Due to lack of libff features to start/stop/pause/seek media files,
currently this just destroys the demuxer and recreates it.  Ideally,
libff should have some functions to allow a more optimal means of doing
those things.
jp9000 10 anos atrás
pai
commit
22885713b0

+ 1 - 0
plugins/obs-ffmpeg/data/locale/en-US.ini

@@ -21,6 +21,7 @@ DiscardBiDir="Bi-Directional Frames"
 DiscardNonIntra="Non-Intra Frames"
 DiscardNonKey="Non-Key Frames"
 DiscardAll="All Frames (Careful!)"
+RestartWhenActivated="Restart playback when source becomes active"
 
 MediaFileFilter.AllMediaFiles="All Media Files"
 MediaFileFilter.VideoFiles="Video Files"

+ 36 - 2
plugins/obs-ffmpeg/obs-ffmpeg-source.c

@@ -56,6 +56,7 @@ struct ffmpeg_source {
 	bool is_forcing_scale;
 	bool is_hw_decoding;
 	bool is_clear_on_media_end;
+	bool restart_on_activate;
 };
 
 static bool set_obs_frame_colorprops(struct ff_frame *frame,
@@ -328,6 +329,7 @@ static void ffmpeg_source_defaults(obs_data_t *settings)
 	obs_data_set_default_bool(settings, "is_local_file", true);
 	obs_data_set_default_bool(settings, "looping", false);
 	obs_data_set_default_bool(settings, "clear_on_media_end", true);
+	obs_data_set_default_bool(settings, "restart_on_activate", true);
 	obs_data_set_default_bool(settings, "force_scale", true);
 #if defined(_WIN32) || defined(__APPLE__)
 	obs_data_set_default_bool(settings, "hw_decode", true);
@@ -373,6 +375,9 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data)
 
 	obs_properties_add_bool(props, "looping", obs_module_text("Looping"));
 
+	obs_properties_add_bool(props, "restart_on_activate",
+			obs_module_text("RestartWhenActivated"));
+
 	obs_properties_add_text(props, "input",
 			obs_module_text("Input"), OBS_TEXT_DEFAULT);
 
@@ -458,13 +463,15 @@ static void dump_source_info(struct ffmpeg_source *s, const char *input,
 			"\tis_looping:              %s\n"
 			"\tis_forcing_scale:        %s\n"
 			"\tis_hw_decoding:          %s\n"
-			"\tis_clear_on_media_end:   %s",
+			"\tis_clear_on_media_end:   %s\n"
+			"\trestart_on_activate:     %s",
 			input ? input : "(null)",
 			input_format ? input_format : "(null)",
 			s->is_looping ? "yes" : "no",
 			s->is_forcing_scale ? "yes" : "no",
 			s->is_hw_decoding ? "yes" : "no",
-			s->is_clear_on_media_end ? "yes" : "no");
+			s->is_clear_on_media_end ? "yes" : "no",
+			s->restart_on_activate ? "yes" : "no");
 
 	if (!is_advanced)
 		return;
@@ -537,6 +544,8 @@ static void ffmpeg_source_update(void *data, obs_data_t *settings)
 	s->is_hw_decoding = obs_data_get_bool(settings, "hw_decode");
 	s->is_clear_on_media_end = obs_data_get_bool(settings,
 			"clear_on_media_end");
+	s->restart_on_activate = obs_data_get_bool(settings,
+			"restart_on_activate");
 	s->is_forcing_scale = true;
 
 	if (is_advanced) {
@@ -604,6 +613,29 @@ static void ffmpeg_source_destroy(void *data)
 	bfree(s);
 }
 
+static void ffmpeg_source_activate(void *data)
+{
+	struct ffmpeg_source *s = data;
+
+	if (s->restart_on_activate)
+		ffmpeg_source_start(s);
+}
+
+static void ffmpeg_source_deactivate(void *data)
+{
+	struct ffmpeg_source *s = data;
+
+	if (s->restart_on_activate) {
+		if (s->demuxer != NULL) {
+			ff_demuxer_free(s->demuxer);
+			s->demuxer = NULL;
+
+			if (s->is_clear_on_media_end)
+				obs_source_output_video(s->source, NULL);
+		}
+	}
+}
+
 struct obs_source_info ffmpeg_source = {
 	.id             = "ffmpeg_source",
 	.type           = OBS_SOURCE_TYPE_INPUT,
@@ -613,5 +645,7 @@ struct obs_source_info ffmpeg_source = {
 	.destroy        = ffmpeg_source_destroy,
 	.get_defaults   = ffmpeg_source_defaults,
 	.get_properties = ffmpeg_source_getproperties,
+	.activate       = ffmpeg_source_activate,
+	.deactivate     = ffmpeg_source_deactivate,
 	.update         = ffmpeg_source_update
 };