Browse Source

VLCMediaListPlayer: Add libvlc callbacks

Soomin Lee 6 years ago
parent
commit
8112341a10
2 changed files with 126 additions and 5 deletions
  1. 31 3
      Headers/Public/VLCMediaListPlayer.h
  2. 95 2
      Sources/VLCMediaListPlayer.m

+ 31 - 3
Headers/Public/VLCMediaListPlayer.h

@@ -3,11 +3,13 @@
  *****************************************************************************
  * Copyright (C) 2009 Pierre d'Herbemont
  * Partial Copyright (C) 2009-2013 Felix Paul Kühne
- * Copyright (C) 2009-2013 VLC authors and VideoLAN
+ * Copyright (C) 2009-2019 VLC authors and VideoLAN
+
  * $Id$
  *
  * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
- *          Felix Paul Kühne <fkuehne # videolan.org
+ *          Felix Paul Kühne <fkuehne # videolan.org>
+ *          Soomin Lee <bubu # mikan.io>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -24,7 +26,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-@class VLCMedia, VLCMediaPlayer, VLCMediaList;
+@class VLCMedia, VLCMediaPlayer, VLCMediaList, VLCMediaListPlayer;
 
 /**
  * VLCRepeatMode
@@ -36,6 +38,27 @@ typedef NS_ENUM(NSInteger, VLCRepeatMode) {
     VLCRepeatAllItems
 };
 
+@protocol VLCMediaListPlayerDelegate <NSObject>
+@optional
+/**
+ * Sent when VLCMediaListPlayer has finished playing.
+ */
+- (void)mediaListPlayerFinishedPlayback:(VLCMediaListPlayer *)player;
+
+/**
+ * Sent when VLCMediaListPlayer going to play next media
+ */
+- (void)mediaListPlayer:(VLCMediaListPlayer *)player
+              nextMedia:(VLCMedia *)media;
+
+/**
+ * Sent when VLCMediaListPlayer is stopped.
+ * Internally or by using the stop()
+ * \see stop
+ */
+- (void)mediaListPlayerStopped:(VLCMediaListPlayer *)player;
+@end
+
 /**
  * A media list player, which eases the use of playlists
  */
@@ -60,6 +83,11 @@ typedef NS_ENUM(NSInteger, VLCRepeatMode) {
 @property (readonly) VLCMediaPlayer *mediaPlayer;
 
 /**
+ * Receiver's delegate
+ */
+@property (nonatomic, weak) id <VLCMediaListPlayerDelegate> delegate;
+
+/**
  * initializer with a certain drawable
  * \note drawable can also be set later
  */

+ 95 - 2
Sources/VLCMediaListPlayer.m

@@ -3,11 +3,12 @@
  *****************************************************************************
  * Copyright (C) 2009 Pierre d'Herbemont
  * Partial Copyright (C) 2009-2017 Felix Paul Kühne
- * Copyright (C) 2009-2013 VLC authors and VideoLAN
+ * Copyright (C) 2009-2019 VLC authors and VideoLAN
  * $Id$
  *
  * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
- *          Felix Paul Kühne <fkuehne # videolan.org
+ *          Felix Paul Kühne <fkuehne # videolan.org>
+ *          Soomin Lee <bubu # mikan.io>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -30,6 +31,7 @@
 #import "VLCMediaList.h"
 #import "VLCLibVLCBridging.h"
 #import "VLCLibrary.h"
+#import "VLCEventManager.h"
 
 @interface VLCMediaListPlayer () {
     void *instance;
@@ -41,6 +43,36 @@
 }
 @end
 
+static void HandleMediaListPlayerPlayed(const libvlc_event_t * event, void * self)
+{
+    @autoreleasepool {
+        [[VLCEventManager sharedManager] callOnMainThreadObject:(__bridge id)(self)
+                                                     withMethod:@selector(mediaListPlayerPlayed)
+                                           withArgumentAsObject:nil];
+    }
+}
+
+static void HandleMediaListPlayerNextItemSet(const libvlc_event_t * event, void * self)
+{
+    @autoreleasepool {
+        VLCMedia *media = [[VLCMedia alloc]
+                           initWithLibVLCMediaDescriptor:event->u.media_list_player_next_item_set.item];
+
+        [[VLCEventManager sharedManager] callOnMainThreadObject:(__bridge id)(self)
+                                                     withMethod:@selector(mediaListPlayerNextItemSet:)
+                                           withArgumentAsObject:media];
+    }
+}
+
+static void HandleMediaListPlayerStopped(const libvlc_event_t * event, void * self)
+{
+    @autoreleasepool {
+        [[VLCEventManager sharedManager] callOnMainThreadObject:(__bridge id)(self)
+                                                     withMethod:@selector(mediaListPlayerStopped)
+                                           withArgumentAsObject:nil];
+    }
+}
+
 @implementation VLCMediaListPlayer
 
 - (instancetype)initWithOptions:(NSArray *)options andDrawable:(id)drawable
@@ -59,10 +91,46 @@
         _mediaPlayer = [[VLCMediaPlayer alloc] initWithLibVLCInstance:libvlc_media_list_player_get_media_player(instance) andLibrary:library];
         if (drawable != nil)
             [_mediaPlayer setDrawable:drawable];
+
+        [self registerObservers];
     }
     return self;
 }
 
+- (void)registerObservers
+{
+    __block libvlc_event_manager_t * p_em = libvlc_media_list_player_event_manager(instance);
+
+    if (!p_em) {
+        return;
+    }
+
+    dispatch_sync(_libVLCBackgroundQueue,^{
+        libvlc_event_attach(p_em, libvlc_MediaListPlayerPlayed,
+                            HandleMediaListPlayerPlayed, (__bridge void *)(self));
+        libvlc_event_attach(p_em, libvlc_MediaListPlayerNextItemSet,
+                            HandleMediaListPlayerNextItemSet, (__bridge void *)(self));
+        libvlc_event_attach(p_em, libvlc_MediaListPlayerStopped,
+                            HandleMediaListPlayerStopped, (__bridge void *)(self));
+    });
+}
+
+- (void)unregisterObservers
+{
+    libvlc_event_manager_t * p_em = libvlc_media_list_player_event_manager(instance);
+
+    if (!p_em) {
+        return;
+    }
+
+    libvlc_event_detach(p_em, libvlc_MediaListPlayerPlayed,
+                        HandleMediaListPlayerPlayed, (__bridge void *)(self));
+    libvlc_event_detach(p_em, libvlc_MediaListPlayerNextItemSet,
+                        HandleMediaListPlayerNextItemSet, (__bridge void *)(self));
+    libvlc_event_detach(p_em, libvlc_MediaListPlayerStopped,
+                        HandleMediaListPlayerStopped, (__bridge void *)(self));
+}
+
 - (instancetype)initWithOptions:(NSArray *)options
 {
     return [self initWithOptions:options andDrawable:nil];
@@ -81,6 +149,7 @@
 - (void)dealloc
 {
     [_mediaPlayer stop];
+    [self unregisterObservers];
     libvlc_media_list_player_release(instance);
 }
 
@@ -205,4 +274,28 @@
 {
     return _repeatMode;
 }
+
+#pragma mark - Delegate methods
+
+- (void)mediaListPlayerPlayed
+{
+    if ([_delegate respondsToSelector:@selector(mediaListPlayerPlayed)]) {
+        [_delegate mediaListPlayerFinishedPlayback:self];
+    }
+}
+
+- (void)mediaListPlayerNextItemSet:(VLCMedia *)media
+{
+    if ([_delegate respondsToSelector:@selector(mediaListPlayer:nextMedia:)]) {
+        [_delegate mediaListPlayer:self nextMedia:media];
+    }
+}
+
+- (void)mediaListPlayerStopped
+{
+    if ([_delegate respondsToSelector:@selector(mediaListPlayerStopped)]) {
+        [_delegate mediaListPlayerStopped:self];
+    }
+}
+
 @end