From f9ccea52357f1c26a0b9e7223ff7561131a29a88 Mon Sep 17 00:00:00 2001 From: Clayton Groeneveld Date: Wed, 10 Jul 2019 00:45:35 -0500 Subject: [PATCH] libobs: Add media control support to backend --- libobs/obs-source.c | 134 ++++++++++++++++++++++++++++++++++++++++++++ libobs/obs-source.h | 27 +++++++++ libobs/obs.h | 13 +++++ 3 files changed, 174 insertions(+) diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 88ce0b271..dd1304b89 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -80,6 +80,14 @@ static const char *source_signals[] = { "void transition_start(ptr source)", "void transition_video_stop(ptr source)", "void transition_stop(ptr source)", + "void media_play(ptr source)", + "void media_pause(ptr source)", + "void media_restart(ptr source)", + "void media_stopped(ptr source)", + "void media_next(ptr source)", + "void media_previous(ptr source)", + "void media_started(ptr source)", + "void media_ended(ptr source)", NULL, }; @@ -4742,3 +4750,129 @@ enum obs_icon_type obs_source_get_icon_type(const char *id) const struct obs_source_info *info = get_source_info(id); return (info) ? info->icon_type : OBS_ICON_TYPE_UNKNOWN; } + +void obs_source_media_play_pause(obs_source_t *source, bool pause) +{ + if (!obs_source_valid(source, "obs_source_media_play_pause")) + return; + + if (!source->info.media_play_pause) + return; + + source->info.media_play_pause(source->context.data, pause); + + if (pause) + obs_source_dosignal(source, NULL, "media_pause"); + else + obs_source_dosignal(source, NULL, "media_play"); +} + +void obs_source_media_restart(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_restart")) + return; + + if (!source->info.media_restart) + return; + + source->info.media_restart(source->context.data); + + obs_source_dosignal(source, NULL, "media_restart"); +} + +void obs_source_media_stop(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_stop")) + return; + + if (!source->info.media_stop) + return; + + source->info.media_stop(source->context.data); + + obs_source_dosignal(source, NULL, "media_stopped"); +} + +void obs_source_media_next(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_next")) + return; + + if (!source->info.media_next) + return; + + source->info.media_next(source->context.data); + + obs_source_dosignal(source, NULL, "media_next"); +} + +void obs_source_media_previous(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_previous")) + return; + + if (!source->info.media_previous) + return; + + source->info.media_previous(source->context.data); + + obs_source_dosignal(source, NULL, "media_previous"); +} + +int64_t obs_source_media_get_duration(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_get_duration")) + return 0; + + if (source->info.media_get_duration) + return source->info.media_get_duration(source->context.data); + else + return 0; +} + +int64_t obs_source_media_get_time(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_get_time")) + return 0; + + if (source->info.media_get_time) + return source->info.media_get_time(source->context.data); + else + return 0; +} + +void obs_source_media_set_time(obs_source_t *source, int64_t ms) +{ + if (!obs_source_valid(source, "obs_source_media_set_time")) + return; + + if (source->info.media_set_time) + source->info.media_set_time(source->context.data, ms); +} + +enum obs_media_state obs_source_media_get_state(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_get_state")) + return OBS_MEDIA_STATE_NONE; + + if (source->info.media_get_state) + return source->info.media_get_state(source->context.data); + else + return OBS_MEDIA_STATE_NONE; +} + +void obs_source_media_started(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_started")) + return; + + obs_source_dosignal(source, NULL, "media_started"); +} + +void obs_source_media_ended(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_media_ended")) + return; + + obs_source_dosignal(source, NULL, "media_ended"); +} diff --git a/libobs/obs-source.h b/libobs/obs-source.h index 9ade083dd..b3dcf4097 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -60,6 +60,17 @@ enum obs_icon_type { OBS_ICON_TYPE_CUSTOM, }; +enum obs_media_state { + OBS_MEDIA_STATE_NONE, + OBS_MEDIA_STATE_PLAYING, + OBS_MEDIA_STATE_OPENING, + OBS_MEDIA_STATE_BUFFERING, + OBS_MEDIA_STATE_PAUSED, + OBS_MEDIA_STATE_STOPPED, + OBS_MEDIA_STATE_ENDED, + OBS_MEDIA_STATE_ERROR, +}; + /** * @name Source output flags * @@ -170,6 +181,11 @@ enum obs_icon_type { /** Used internally for audio submixing */ #define OBS_SOURCE_SUBMIX (1 << 12) +/** + * Source type can be controlled by media controls + */ +#define OBS_SOURCE_CONTROLLABLE_MEDIA (1 << 13) + /** @} */ typedef void (*obs_source_enum_proc_t)(obs_source_t *parent, @@ -496,6 +512,17 @@ struct obs_source_info { /** Icon type for the source */ enum obs_icon_type icon_type; + + /** Media controls */ + void (*media_play_pause)(void *data, bool pause); + void (*media_restart)(void *data); + void (*media_stop)(void *data); + void (*media_next)(void *data); + void (*media_previous)(void *data); + int64_t (*media_get_duration)(void *data); + int64_t (*media_get_time)(void *data); + void (*media_set_time)(void *data, int64_t seconds); + enum obs_media_state (*media_get_state)(void *data); }; EXPORT void obs_register_source_s(const struct obs_source_info *info, diff --git a/libobs/obs.h b/libobs/obs.h index 401d5ff5a..c6990734b 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -1317,6 +1317,19 @@ EXPORT bool obs_source_audio_active(const obs_source_t *source); EXPORT uint32_t obs_source_get_last_obs_version(const obs_source_t *source); +/** Media controls */ +EXPORT void obs_source_media_play_pause(obs_source_t *source, bool pause); +EXPORT void obs_source_media_restart(obs_source_t *source); +EXPORT void obs_source_media_stop(obs_source_t *source); +EXPORT void obs_source_media_next(obs_source_t *source); +EXPORT void obs_source_media_previous(obs_source_t *source); +EXPORT int64_t obs_source_media_get_duration(obs_source_t *source); +EXPORT int64_t obs_source_media_get_time(obs_source_t *source); +EXPORT void obs_source_media_set_time(obs_source_t *source, int64_t ms); +EXPORT enum obs_media_state obs_source_media_get_state(obs_source_t *source); +EXPORT void obs_source_media_started(obs_source_t *source); +EXPORT void obs_source_media_ended(obs_source_t *source); + /* ------------------------------------------------------------------------- */ /* Transition-specific functions */ enum obs_transition_target {