Beispiel #1
0
/**
 * Get the properties for the capture
 */
static obs_properties_t *xshm_properties(void *vptr)
{
	XSHM_DATA(vptr);

	obs_properties_t *props = obs_properties_create();

	obs_properties_add_list(props, "screen", obs_module_text("Screen"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
	obs_properties_add_bool(props, "show_cursor",
			obs_module_text("CaptureCursor"));
	obs_property_t *advanced = obs_properties_add_bool(props, "advanced",
			obs_module_text("AdvancedSettings"));
	obs_property_t *server = obs_properties_add_text(props, "server",
			obs_module_text("XServer"), OBS_TEXT_DEFAULT);

	obs_property_set_modified_callback(advanced, xshm_toggle_advanced);
	obs_property_set_modified_callback(server, xshm_server_changed);

	/* trigger server callback to get screen count ... */
	obs_data_t *settings = obs_source_get_settings(data->source);
	obs_property_modified(server, settings);
	obs_data_release(settings);

	return props;
}
Beispiel #2
0
static obs_properties_t *v4l2_properties(void *vptr)
{
	V4L2_DATA(vptr);

	obs_properties_t *props = obs_properties_create();

	obs_property_t *device_list = obs_properties_add_list(props,
			"device_id", obs_module_text("Device"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);

	obs_property_t *input_list = obs_properties_add_list(props,
			"input", obs_module_text("Input"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);

	obs_property_t *format_list = obs_properties_add_list(props,
			"pixelformat", obs_module_text("VideoFormat"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);

	obs_property_t *standard_list = obs_properties_add_list(props,
			"standard", obs_module_text("VideoStandard"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
	obs_property_set_visible(standard_list, false);

	obs_property_t *dv_timing_list = obs_properties_add_list(props,
			"dv_timing", obs_module_text("DVTiming"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
	obs_property_set_visible(dv_timing_list, false);

	obs_property_t *resolution_list = obs_properties_add_list(props,
			"resolution", obs_module_text("Resolution"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);

	obs_properties_add_list(props,
			"framerate", obs_module_text("FrameRate"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);

	obs_properties_add_bool(props,
			"buffering", obs_module_text("UseBuffering"));

	obs_data_t *settings = obs_source_get_settings(data->source);
	v4l2_device_list(device_list, settings);
	obs_data_release(settings);

	obs_property_set_modified_callback(device_list, device_selected);
	obs_property_set_modified_callback(input_list, input_selected);
	obs_property_set_modified_callback(format_list, format_selected);
	obs_property_set_modified_callback(resolution_list,
			resolution_selected);

	return props;
}
static obs_properties_t *crop_filter_properties(void *data)
{
	obs_properties_t *props = obs_properties_create();

	obs_property_t *p = obs_properties_add_bool(props, "relative",
			obs_module_text("Crop.Relative"));

	obs_property_set_modified_callback(p, relative_clicked);

	obs_properties_add_int(props, "left", obs_module_text("Crop.Left"),
			0, 8192, 1);
	obs_properties_add_int(props, "top", obs_module_text("Crop.Top"),
			0, 8192, 1);
	obs_properties_add_int(props, "right", obs_module_text("Crop.Right"),
			0, 8192, 1);
	obs_properties_add_int(props, "bottom", obs_module_text("Crop.Bottom"),
			0, 8192, 1);
	obs_properties_add_int(props, "cx", obs_module_text("Crop.Width"),
			0, 8192, 1);
	obs_properties_add_int(props, "cy", obs_module_text("Crop.Height"),
			0, 8192, 1);

	UNUSED_PARAMETER(data);
	return props;
}
Beispiel #4
0
static obs_properties_t *chroma_key_properties(void *data)
{
	obs_properties_t *props = obs_properties_create();

	obs_property_t *p = obs_properties_add_list(props,
			SETTING_COLOR_TYPE, TEXT_COLOR_TYPE,
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	obs_property_list_add_string(p, obs_module_text("Green"), "green");
	obs_property_list_add_string(p, obs_module_text("Blue"), "blue");
	obs_property_list_add_string(p, obs_module_text("Magenta"), "magenta");
	obs_property_list_add_string(p, obs_module_text("Custom"), "custom");

	obs_property_set_modified_callback(p, key_type_changed);

	obs_properties_add_color(props, SETTING_KEY_COLOR, TEXT_KEY_COLOR);
	obs_properties_add_int_slider(props, SETTING_SIMILARITY,
			TEXT_SIMILARITY, 1, 1000, 1);
	obs_properties_add_int_slider(props, SETTING_SMOOTHNESS,
			TEXT_SMOOTHNESS, 1, 1000, 1);
	obs_properties_add_int_slider(props, SETTING_SPILL,
			TEXT_SPILL, 1, 1000, 1);

	obs_properties_add_int(props, SETTING_OPACITY, TEXT_OPACITY, 0, 100, 1);
	obs_properties_add_float_slider(props, SETTING_CONTRAST,
			TEXT_CONTRAST, -1.0, 1.0, 0.01);
	obs_properties_add_float_slider(props, SETTING_BRIGHTNESS,
			TEXT_BRIGHTNESS, -1.0, 1.0, 0.01);
	obs_properties_add_float_slider(props, SETTING_GAMMA,
			TEXT_GAMMA, -1.0, 1.0, 0.01);

	UNUSED_PARAMETER(data);
	return props;
}
Beispiel #5
0
static obs_properties_t *decklink_get_properties(void *data)
{
	obs_properties_t *props = obs_properties_create();

	obs_property_t *list = obs_properties_add_list(props, DEVICE_HASH,
			TEXT_DEVICE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	obs_property_set_modified_callback(list, decklink_device_changed);

	fill_out_devices(list);

	list = obs_properties_add_list(props, MODE_ID, TEXT_MODE,
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);

	list = obs_properties_add_list(props, PIXEL_FORMAT,
			TEXT_PIXEL_FORMAT, OBS_COMBO_TYPE_LIST,
			OBS_COMBO_FORMAT_INT);
	obs_property_list_add_int(list, "8-bit YUV", bmdFormat8BitYUV);
	obs_property_list_add_int(list, "8-bit BGRA", bmdFormat8BitBGRA);

	list = obs_properties_add_list(props, CHANNEL_FORMAT,
			TEXT_CHANNEL_FORMAT, OBS_COMBO_TYPE_LIST,
			OBS_COMBO_FORMAT_INT);
	obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_NONE,
			SPEAKERS_UNKNOWN);
	obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_0CH,
			SPEAKERS_STEREO);

	obs_properties_add_bool(props, BUFFERING, TEXT_BUFFERING);

	UNUSED_PARAMETER(data);
	return props;
}
Beispiel #6
0
static obs_properties_t *obs_x264_props(void *unused)
{
	UNUSED_PARAMETER(unused);

	obs_properties_t *props = obs_properties_create();
	obs_property_t *list;
	obs_property_t *p;

	obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, 1);

	p = obs_properties_add_bool(props, "use_bufsize", TEXT_CUSTOM_BUF);
	obs_property_set_modified_callback(p, use_bufsize_modified);
	obs_properties_add_int(props, "buffer_size", TEXT_BUF_SIZE, 0,
			10000000, 1);

	obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 0, 20, 1);
	p = obs_properties_add_bool(props, "cbr", TEXT_USE_CBR);
	obs_properties_add_int(props, "crf", TEXT_CRF, 0, 51, 1);

	obs_property_set_modified_callback(p, use_cbr_modified);

	list = obs_properties_add_list(props, "preset", TEXT_PRESET,
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	add_strings(list, x264_preset_names);

	list = obs_properties_add_list(props, "profile", TEXT_PROFILE,
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	obs_property_list_add_string(list, TEXT_NONE, "");
	obs_property_list_add_string(list, "baseline", "baseline");
	obs_property_list_add_string(list, "main", "main");
	obs_property_list_add_string(list, "high", "high");

	list = obs_properties_add_list(props, "tune", TEXT_TUNE,
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	obs_property_list_add_string(list, TEXT_NONE, "");
	add_strings(list, x264_tune_names);

	obs_properties_add_bool(props, "vfr", TEXT_VFR);

	obs_properties_add_text(props, "x264opts", TEXT_X264_OPTS,
			OBS_TEXT_DEFAULT);

	return props;
}
Beispiel #7
0
static obs_properties_t *scale_filter_properties(void *data)
{
	obs_properties_t *props = obs_properties_create();
	struct obs_video_info ovi;
	obs_property_t *p;
	uint32_t cx;
	uint32_t cy;

	struct {
		int cx;
		int cy;
	} downscales[NUM_DOWNSCALES];

	/* ----------------- */

	obs_get_video_info(&ovi);
	cx = ovi.base_width;
	cy = ovi.base_height;

	for (size_t i = 0; i < NUM_DOWNSCALES; i++) {
		downscales[i].cx = (int)((double)cx / downscale_vals[i]);
		downscales[i].cy = (int)((double)cy / downscale_vals[i]);
	}

	p = obs_properties_add_list(props, S_SAMPLING, T_SAMPLING,
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	obs_property_set_modified_callback(p, sampling_modified);
	obs_property_list_add_string(p, T_SAMPLING_POINT,    S_SAMPLING_POINT);
	obs_property_list_add_string(p, T_SAMPLING_BILINEAR, S_SAMPLING_BILINEAR);
	obs_property_list_add_string(p, T_SAMPLING_BICUBIC,  S_SAMPLING_BICUBIC);
	obs_property_list_add_string(p, T_SAMPLING_LANCZOS,  S_SAMPLING_LANCZOS);

	/* ----------------- */

	p = obs_properties_add_list(props, S_RESOLUTION, T_RESOLUTION,
			OBS_COMBO_TYPE_EDITABLE, OBS_COMBO_FORMAT_STRING);

	obs_property_list_add_string(p, T_NONE, T_NONE);
	obs_property_list_add_string(p, T_BASE, T_BASE);

	for (size_t i = 0; i < NUM_ASPECTS; i++)
		obs_property_list_add_string(p, aspects[i], aspects[i]);

	for (size_t i = 0; i < NUM_DOWNSCALES; i++) {
		char str[32];
		snprintf(str, 32, "%dx%d", downscales[i].cx, downscales[i].cy);
		obs_property_list_add_string(p, str, str);
	}

	obs_properties_add_bool(props, S_UNDISTORT, T_UNDISTORT);

	/* ----------------- */

	UNUSED_PARAMETER(data);
	return props;
}
static obs_properties_t *stinger_properties(void *data)
{
	obs_properties_t *ppts = obs_properties_create();

	obs_properties_set_flags(ppts, OBS_PROPERTIES_DEFER_UPDATE);

	obs_properties_add_path(ppts, "path",
			obs_module_text("VideoFile"),
			OBS_PATH_FILE,
			FILE_FILTER, NULL);
	obs_property_t *list = obs_properties_add_list(ppts, "tp_type",
			obs_module_text("TransitionPointType"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
	obs_property_list_add_int(list,
			obs_module_text("TransitionPointTypeTime"),
			TIMING_TIME);
	obs_property_list_add_int(list,
			obs_module_text("TransitionPointTypeFrame"),
			TIMING_FRAME);

	obs_property_set_modified_callback(list, transition_point_type_modified);

	obs_properties_add_int(ppts, "transition_point",
			obs_module_text("TransitionPoint"),
			0, 120000, 1);

	obs_property_t *monitor_list = obs_properties_add_list(ppts,
			"audio_monitoring", obs_module_text("AudioMonitoring"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
	obs_property_list_add_int(monitor_list,
			obs_module_text("AudioMonitoring.None"),
			OBS_MONITORING_TYPE_NONE);
	obs_property_list_add_int(monitor_list,
			obs_module_text("AudioMonitoring.MonitorOnly"),
			OBS_MONITORING_TYPE_MONITOR_ONLY);
	obs_property_list_add_int(monitor_list,
			obs_module_text("AudioMonitoring.Both"),
			OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);

	obs_property_t *audio_fade_style = obs_properties_add_list(ppts,
			"audio_fade_style", obs_module_text("AudioFadeStyle"),
			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
	obs_property_list_add_int(audio_fade_style,
			obs_module_text("AudioFadeStyle.FadeOutFadeIn"),
			FADE_STYLE_FADE_OUT_FADE_IN);
	obs_property_list_add_int(audio_fade_style,
			obs_module_text("AudioFadeStyle.CrossFade"),
			FADE_STYLE_CROSS_FADE);

	UNUSED_PARAMETER(data);
	return ppts;
}
Beispiel #9
0
static obs_properties_t *obs_qsv_props(void *unused)
{
	UNUSED_PARAMETER(unused);

	obs_properties_t *props = obs_properties_create();
	obs_property_t *list;

	list = obs_properties_add_list(props, "target_usage", TEXT_SPEED,
		OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	add_strings(list, qsv_usage_names);

	list = obs_properties_add_list(props, "profile", TEXT_PROFILE,
		OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	add_strings(list, qsv_profile_names);

	obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 1, 20, 1);
	obs_properties_add_int(props, "async_depth", TEXT_ASYNC_DEPTH, 1, 7, 1);

	list = obs_properties_add_list(props, "rate_control", TEXT_RATE_CONTROL,
		OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
	add_rate_controls(list, qsv_ratecontrols);
	obs_property_set_modified_callback(list, rate_control_modified);

	obs_property_t *p;
	p = obs_properties_add_int(props, "bitrate", TEXT_TARGET_BITRATE, 50,
			10000000, 50);
	obs_property_int_set_suffix(p, " Kbps");

	p = obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50,
			10000000, 50);
	obs_property_int_set_suffix(p, " Kbps");

	obs_properties_add_int(props, "accuracy", TEXT_ACCURACY, 0, 10000, 1);
	obs_properties_add_int(props, "convergence", TEXT_CONVERGENCE, 0, 10, 1);
	obs_properties_add_int(props, "qpi", "QPI", 1, 51, 1);
	obs_properties_add_int(props, "qpp", "QPP", 1, 51, 1);
	obs_properties_add_int(props, "qpb", "QPB", 1, 51, 1);
	obs_properties_add_int(props, "icq_quality", TEXT_ICQ_QUALITY, 1, 51, 1);
	obs_properties_add_int(props, "la_depth", TEXT_LA_DEPTH, 10, 100, 1);

	return props;
}
Beispiel #10
0
static obs_properties_t *rtmp_custom_properties(void *unused)
{
	UNUSED_PARAMETER(unused);

	obs_properties_t *ppts = obs_properties_create();
	obs_property_t *p;

	obs_properties_add_text(ppts, "server", "URL", OBS_TEXT_DEFAULT);

	obs_properties_add_text(ppts, "key", obs_module_text("StreamKey"),
			OBS_TEXT_PASSWORD);

	p = obs_properties_add_bool(ppts, "use_auth", obs_module_text("UseAuth"));
	obs_properties_add_text(ppts, "username", obs_module_text("Username"),
			OBS_TEXT_DEFAULT);
	obs_properties_add_text(ppts, "password", obs_module_text("Password"),
			OBS_TEXT_PASSWORD);
	obs_property_set_modified_callback(p, use_auth_modified);
	return ppts;
}
static obs_properties_t *qtwebkit_get_properties(void *)
{
	obs_properties_t *props = obs_properties_create();

	obs_property_t *prop = obs_properties_add_bool(props, "is_local_file",
			obs_module_text("LocalFile"));

	obs_property_set_modified_callback(prop, is_local_file_modified);
	obs_properties_add_path(props, "local_file", obs_module_text("LocalFile"),
			OBS_PATH_FILE, "*.*", nullptr);
	obs_properties_add_text(props, "url", obs_module_text("URL"), OBS_TEXT_DEFAULT);

	obs_properties_add_int(props, "width", obs_module_text("Width"), 1, 4096, 1);
	obs_properties_add_int(props, "height", obs_module_text("Height"), 1, 4096, 1);
	obs_properties_add_int(props, "fps", obs_module_text("FPS"), 1, 60, 1);
	obs_properties_add_path(props, "css_file", obs_module_text("CustomCSS"),
			OBS_PATH_FILE, "*.css", nullptr);

	obs_properties_add_button(props, "reload", obs_module_text("Reload"), reload_button_clicked);

	return props;
}
Beispiel #12
0
static obs_properties_t *expander_properties(void *data)
{
	struct expander_data *cd = data;
	obs_properties_t *props = obs_properties_create();
	obs_source_t *parent = NULL;

	if (cd)
		parent = obs_filter_get_parent(cd->context);

	obs_property_t *presets = obs_properties_add_list(props, S_PRESETS,
			TEXT_PRESETS, OBS_COMBO_TYPE_LIST,
			OBS_COMBO_FORMAT_STRING);
	obs_property_list_add_string(presets, TEXT_PRESETS_EXP, "expander");
	obs_property_list_add_string(presets, TEXT_PRESETS_GATE, "gate");
	obs_property_set_modified_callback(presets, presets_changed);
	obs_properties_add_float_slider(props, S_RATIO,
			TEXT_RATIO, MIN_RATIO, MAX_RATIO, 0.1);
	obs_properties_add_float_slider(props, S_THRESHOLD,
			TEXT_THRESHOLD, MIN_THRESHOLD_DB, MAX_THRESHOLD_DB,
			0.1);
	obs_properties_add_int_slider(props, S_ATTACK_TIME,
			TEXT_ATTACK_TIME, MIN_ATK_RLS_MS, MAX_ATK_MS, 1);
	obs_properties_add_int_slider(props, S_RELEASE_TIME,
			TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, MAX_RLS_MS, 1);
	obs_properties_add_float_slider(props, S_OUTPUT_GAIN,
			TEXT_OUTPUT_GAIN, MIN_OUTPUT_GAIN_DB,
			MAX_OUTPUT_GAIN_DB, 0.1);
	obs_property_t *detect = obs_properties_add_list(props, S_DETECTOR,
			TEXT_DETECTOR, OBS_COMBO_TYPE_LIST,
			OBS_COMBO_FORMAT_STRING);
	obs_property_list_add_string(detect, TEXT_RMS, "RMS");
	obs_property_list_add_string(detect, TEXT_PEAK, "peak");
	obs_property_list_add_string(detect, TEXT_NONE, "none");

	UNUSED_PARAMETER(data);
	return props;
}
static obs_properties_t *ffmpeg_source_getproperties(void *data)
{
	struct dstr filter = {0};
	UNUSED_PARAMETER(data);

	obs_properties_t *props = obs_properties_create();

	obs_properties_set_flags(props, OBS_PROPERTIES_DEFER_UPDATE);

	obs_property_t *prop;
	// use this when obs allows non-readonly paths
	prop = obs_properties_add_bool(props, "is_local_file",
			obs_module_text("LocalFile"));

	obs_property_set_modified_callback(prop, is_local_file_modified);

	dstr_copy(&filter, obs_module_text("MediaFileFilter.AllMediaFiles"));
	dstr_cat(&filter, media_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.VideoFiles"));
	dstr_cat(&filter, video_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.AudioFiles"));
	dstr_cat(&filter, audio_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.AllFiles"));
	dstr_cat(&filter, " (*.*)");

	obs_properties_add_path(props, "local_file",
			obs_module_text("LocalFile"), OBS_PATH_FILE,
			filter.array, NULL);
	dstr_free(&filter);

	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);

	obs_properties_add_text(props, "input_format",
			obs_module_text("InputFormat"), OBS_TEXT_DEFAULT);

	obs_properties_add_bool(props, "hw_decode",
			obs_module_text("HardwareDecode"));

	obs_properties_add_bool(props, "clear_on_media_end",
			obs_module_text("ClearOnMediaEnd"));

	prop = obs_properties_add_bool(props, "advanced",
			obs_module_text("Advanced"));

	obs_property_set_modified_callback(prop, is_advanced_modified);

	obs_properties_add_bool(props, "force_scale",
			obs_module_text("ForceFormat"));

	prop = obs_properties_add_int(props, "audio_buffer_size",
			obs_module_text("AudioBufferSize"), 1, 9999, 1);

	obs_property_set_visible(prop, false);

	prop = obs_properties_add_int(props, "video_buffer_size",
			obs_module_text("VideoBufferSize"), 1, 9999, 1);

	obs_property_set_visible(prop, false);

	prop = obs_properties_add_list(props, "frame_drop",
			obs_module_text("FrameDropping"), OBS_COMBO_TYPE_LIST,
			OBS_COMBO_FORMAT_INT);

	obs_property_list_add_int(prop, obs_module_text("DiscardNone"),
			AVDISCARD_NONE);
	obs_property_list_add_int(prop, obs_module_text("DiscardDefault"),
			AVDISCARD_DEFAULT);
	obs_property_list_add_int(prop, obs_module_text("DiscardNonRef"),
			AVDISCARD_NONREF);
	obs_property_list_add_int(prop, obs_module_text("DiscardBiDir"),
			AVDISCARD_BIDIR);
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 67, 100)
	obs_property_list_add_int(prop, obs_module_text("DiscardNonIntra"),
			AVDISCARD_NONINTRA);
#endif
	obs_property_list_add_int(prop, obs_module_text("DiscardNonKey"),
			AVDISCARD_NONKEY);
	obs_property_list_add_int(prop, obs_module_text("DiscardAll"),
			AVDISCARD_ALL);

	obs_property_set_visible(prop, false);

	return props;
}
Beispiel #14
0
static obs_properties_t *ffmpeg_source_getproperties(void *data)
{
	struct ffmpeg_source *s = data;
	struct dstr filter = {0};
	struct dstr path = {0};
	UNUSED_PARAMETER(data);

	obs_properties_t *props = obs_properties_create();

	obs_properties_set_flags(props, OBS_PROPERTIES_DEFER_UPDATE);

	obs_property_t *prop;
	// use this when obs allows non-readonly paths
	prop = obs_properties_add_bool(props, "is_local_file",
			obs_module_text("LocalFile"));

	obs_property_set_modified_callback(prop, is_local_file_modified);

	dstr_copy(&filter, obs_module_text("MediaFileFilter.AllMediaFiles"));
	dstr_cat(&filter, media_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.VideoFiles"));
	dstr_cat(&filter, video_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.AudioFiles"));
	dstr_cat(&filter, audio_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.AllFiles"));
	dstr_cat(&filter, " (*.*)");

	if (s && s->input && *s->input) {
		const char *slash;

		dstr_copy(&path, s->input);
		dstr_replace(&path, "\\", "/");
		slash = strrchr(path.array, '/');
		if (slash)
			dstr_resize(&path, slash - path.array + 1);
	}

	obs_properties_add_path(props, "local_file",
			obs_module_text("LocalFile"), OBS_PATH_FILE,
			filter.array, path.array);
	dstr_free(&filter);
	dstr_free(&path);

	prop = 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);

	obs_properties_add_text(props, "input_format",
			obs_module_text("InputFormat"), OBS_TEXT_DEFAULT);

#ifndef __APPLE__
	obs_properties_add_bool(props, "hw_decode",
			obs_module_text("HardwareDecode"));
#endif

	obs_properties_add_bool(props, "clear_on_media_end",
			obs_module_text("ClearOnMediaEnd"));

	prop = obs_properties_add_bool(props, "close_when_inactive",
			obs_module_text("CloseFileWhenInactive"));

	obs_property_set_long_description(prop,
			obs_module_text("CloseFileWhenInactive.ToolTip"));

	prop = obs_properties_add_list(props, "color_range",
			obs_module_text("ColorRange"), OBS_COMBO_TYPE_LIST,
			OBS_COMBO_FORMAT_INT);
	obs_property_list_add_int(prop, obs_module_text("ColorRange.Auto"),
			VIDEO_RANGE_DEFAULT);
	obs_property_list_add_int(prop, obs_module_text("ColorRange.Partial"),
			VIDEO_RANGE_PARTIAL);
	obs_property_list_add_int(prop, obs_module_text("ColorRange.Full"),
			VIDEO_RANGE_FULL);

	return props;
}