From be77b13e5826dec6eaefd35c5d10fa1087d8c308 Mon Sep 17 00:00:00 2001 From: cg2121 Date: Mon, 24 Jul 2017 10:45:39 -0500 Subject: [PATCH] vlc-source: Add media control hotkeys This adds play/pause, restart, stop, next, and previous hotkeys to the VLC source. Closes jp9000/obs-studio#972 --- plugins/vlc-video/data/locale/en-US.ini | 5 + plugins/vlc-video/vlc-video-plugin.c | 4 + plugins/vlc-video/vlc-video-plugin.h | 6 ++ plugins/vlc-video/vlc-video-source.c | 128 ++++++++++++++++++++++++ 4 files changed, 143 insertions(+) diff --git a/plugins/vlc-video/data/locale/en-US.ini b/plugins/vlc-video/data/locale/en-US.ini index d11b7594b..7bf200434 100644 --- a/plugins/vlc-video/data/locale/en-US.ini +++ b/plugins/vlc-video/data/locale/en-US.ini @@ -7,3 +7,8 @@ PlaybackBehavior.StopRestart="Stop when not visible, restart when visible" PlaybackBehavior.PauseUnpause="Pause when not visible, unpause when visible" PlaybackBehavior.AlwaysPlay="Always play even when not visible" NetworkCaching="Network Caching (ms)" +PlayPause="Play/Pause" +Restart="Restart" +Stop="Stop" +PlaylistNext="Next" +PlaylistPrev="Previous" diff --git a/plugins/vlc-video/vlc-video-plugin.c b/plugins/vlc-video/vlc-video-plugin.c index 49c4e4843..4160f9107 100644 --- a/plugins/vlc-video/vlc-video-plugin.c +++ b/plugins/vlc-video/vlc-video-plugin.c @@ -53,6 +53,8 @@ LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_PLAYER libvlc_media_list_player_set_media_pla LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_LIST libvlc_media_list_player_set_media_list_; LIBVLC_MEDIA_LIST_PLAYER_EVENT_MANAGER libvlc_media_list_player_event_manager_; LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE libvlc_media_list_player_set_playback_mode_; +LIBVLC_MEDIA_LIST_PLAYER_NEXT libvlc_media_list_player_next_; +LIBVLC_MEDIA_LIST_PLAYER_PREVIOUS libvlc_media_list_player_previous_; void *libvlc_module = NULL; libvlc_instance_t *libvlc = NULL; @@ -115,6 +117,8 @@ static bool load_vlc_funcs(void) LOAD_VLC_FUNC(libvlc_media_list_player_set_media_list); LOAD_VLC_FUNC(libvlc_media_list_player_event_manager); LOAD_VLC_FUNC(libvlc_media_list_player_set_playback_mode); + LOAD_VLC_FUNC(libvlc_media_list_player_next); + LOAD_VLC_FUNC(libvlc_media_list_player_previous); return true; } diff --git a/plugins/vlc-video/vlc-video-plugin.h b/plugins/vlc-video/vlc-video-plugin.h index 53cb2551e..189b3f87f 100644 --- a/plugins/vlc-video/vlc-video-plugin.h +++ b/plugins/vlc-video/vlc-video-plugin.h @@ -111,6 +111,10 @@ typedef libvlc_event_manager_t *(*LIBVLC_MEDIA_LIST_PLAYER_EVENT_MANAGER)( typedef void (*LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE)( libvlc_media_list_player_t *p_mlp, libvlc_playback_mode_t e_mode); +typedef int (*LIBVLC_MEDIA_LIST_PLAYER_NEXT)( + libvlc_media_list_player_t *p_mlp); +typedef int (*LIBVLC_MEDIA_LIST_PLAYER_PREVIOUS)( + libvlc_media_list_player_t *p_mlp); /* -------------------------------------------------------------------- */ @@ -159,6 +163,8 @@ extern LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_PLAYER libvlc_media_list_player_set_me extern LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_LIST libvlc_media_list_player_set_media_list_; extern LIBVLC_MEDIA_LIST_PLAYER_EVENT_MANAGER libvlc_media_list_player_event_manager_; extern LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE libvlc_media_list_player_set_playback_mode_; +extern LIBVLC_MEDIA_LIST_PLAYER_NEXT libvlc_media_list_player_next_; +extern LIBVLC_MEDIA_LIST_PLAYER_PREVIOUS libvlc_media_list_player_previous_; #define EXTENSIONS_AUDIO \ "*.3ga;" \ diff --git a/plugins/vlc-video/vlc-video-source.c b/plugins/vlc-video/vlc-video-source.c index c70b5b34d..1e3a09ef8 100644 --- a/plugins/vlc-video/vlc-video-source.c +++ b/plugins/vlc-video/vlc-video-source.c @@ -57,6 +57,12 @@ struct vlc_source { enum behavior behavior; bool loop; bool shuffle; + + obs_hotkey_id play_pause_hotkey; + obs_hotkey_id restart_hotkey; + obs_hotkey_id stop_hotkey; + obs_hotkey_id playlist_next_hotkey; + obs_hotkey_id playlist_prev_hotkey; }; static libvlc_media_t *get_media(struct darray *array, const char *path) @@ -611,11 +617,133 @@ static void vlcs_stopped(const struct libvlc_event_t *event, void *data) UNUSED_PARAMETER(event); } +static void vlcs_play_pause(void *data) +{ + struct vlc_source *c = data; + + libvlc_media_list_player_pause_(c->media_list_player); +} + +static void vlcs_restart(void *data) +{ + struct vlc_source *c = data; + + libvlc_media_list_player_stop_(c->media_list_player); + libvlc_media_list_player_play_(c->media_list_player); +} + +static void vlcs_stop(void *data) +{ + struct vlc_source *c = data; + + libvlc_media_list_player_stop_(c->media_list_player); + obs_source_output_video(c->source, NULL); +} + +static void vlcs_playlist_next(void *data) +{ + struct vlc_source *c = data; + + libvlc_media_list_player_next_(c->media_list_player); +} + +static void vlcs_playlist_prev(void *data) +{ + struct vlc_source *c = data; + + libvlc_media_list_player_previous_(c->media_list_player); +} + +static void vlcs_play_pause_hotkey(void *data, obs_hotkey_id id, + obs_hotkey_t *hotkey, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(hotkey); + + struct vlc_source *c = data; + + if (pressed && obs_source_active(c->source)) + vlcs_play_pause(c); +} + +static void vlcs_restart_hotkey(void *data, obs_hotkey_id id, + obs_hotkey_t *hotkey, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(hotkey); + + struct vlc_source *c = data; + + if (pressed && obs_source_active(c->source)) + vlcs_restart(c); +} + +static void vlcs_stop_hotkey(void *data, obs_hotkey_id id, + obs_hotkey_t *hotkey, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(hotkey); + + struct vlc_source *c = data; + + if (pressed && obs_source_active(c->source)) + vlcs_stop(c); +} + +static void vlcs_playlist_next_hotkey(void *data, obs_hotkey_id id, + obs_hotkey_t *hotkey, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(hotkey); + + struct vlc_source *c = data; + + if (pressed && obs_source_active(c->source)) + vlcs_playlist_next(c); +} + +static void vlcs_playlist_prev_hotkey(void *data, obs_hotkey_id id, + obs_hotkey_t *hotkey, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(hotkey); + + struct vlc_source *c = data; + + if (pressed && obs_source_active(c->source)) + vlcs_playlist_prev(c); +} + static void *vlcs_create(obs_data_t *settings, obs_source_t *source) { struct vlc_source *c = bzalloc(sizeof(*c)); c->source = source; + c->play_pause_hotkey = obs_hotkey_register_source(source, + "VLCSource.PlayPause", + obs_module_text("PlayPause"), + vlcs_play_pause_hotkey, c); + + c->restart_hotkey = obs_hotkey_register_source(source, + "VLCSource.Restart", + obs_module_text("Restart"), + vlcs_restart_hotkey, c); + + c->stop_hotkey = obs_hotkey_register_source(source, + "VLCSource.Stop", + obs_module_text("Stop"), + vlcs_stop_hotkey, c); + + c->playlist_next_hotkey = obs_hotkey_register_source(source, + "VLCSource.PlaylistNext", + obs_module_text("PlaylistNext"), + vlcs_playlist_next_hotkey, c); + + c->playlist_prev_hotkey = obs_hotkey_register_source(source, + "VLCSource.PlaylistPrev", + obs_module_text("PlaylistPrev"), + vlcs_playlist_prev_hotkey, c); + pthread_mutex_init_value(&c->mutex); if (pthread_mutex_init(&c->mutex, NULL) != 0) goto error;