123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- /*****************************************************************************
- * VLCMediaListPlayer.m: VLCKit.framework VLCMediaListPlayer implementation
- *****************************************************************************
- * Copyright (C) 2009 Pierre d'Herbemont
- * Partial Copyright (C) 2009-2017 Felix Paul Kühne
- * Copyright (C) 2009-2019 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Pierre d'Herbemont <pdherbemont # 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
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
- #import "VLCMediaListPlayer.h"
- #import "VLCMedia.h"
- #import "VLCMediaPlayer.h"
- #import "VLCMediaList.h"
- #import "VLCLibVLCBridging.h"
- #import "VLCLibrary.h"
- #import "VLCEventManager.h"
- @interface VLCMediaListPlayer () {
- void *instance;
- VLCMedia *_rootMedia;
- VLCMediaPlayer *_mediaPlayer;
- VLCMediaList *_mediaList;
- VLCRepeatMode _repeatMode;
- dispatch_queue_t _libVLCBackgroundQueue;
- }
- - (void)mediaListPlayerPlayed;
- - (void)mediaListPlayerNextItemSet:(VLCMedia *)media;
- - (void)mediaListPlayerStopped;
- @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
- {
- if (self = [super init]) {
- _libVLCBackgroundQueue = dispatch_queue_create("libvlcQueue", DISPATCH_QUEUE_SERIAL);
- VLCLibrary *library;
- if (options != nil) {
- library = [[VLCLibrary alloc] initWithOptions:options];
- } else
- library = [VLCLibrary sharedLibrary];
- instance = libvlc_media_list_player_new([library instance]);
- _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];
- }
- - (instancetype)init
- {
- return [self initWithOptions:nil andDrawable:nil];
- }
- - (instancetype)initWithDrawable:(id)drawable
- {
- return [self initWithOptions:nil andDrawable:drawable];
- }
- - (void)dealloc
- {
- [_mediaPlayer stop];
- [self unregisterObservers];
- libvlc_media_list_player_release(instance);
- }
- - (VLCMediaPlayer *)mediaPlayer
- {
- return _mediaPlayer;
- }
- - (void)setMediaList:(VLCMediaList *)mediaList
- {
- if (_mediaList == mediaList)
- return;
- _mediaList = mediaList;
- libvlc_media_list_player_set_media_list(instance, [mediaList libVLCMediaList]);
- [self willChangeValueForKey:@"rootMedia"];
- _rootMedia = nil;
- [self didChangeValueForKey:@"rootMedia"];
- }
- - (VLCMediaList *)mediaList
- {
- return _mediaList;
- }
- - (void)setRootMedia:(VLCMedia *)media
- {
- if (_rootMedia == media)
- return;
- _rootMedia = nil;
- VLCMediaList *mediaList = [[VLCMediaList alloc] init];
- if (media)
- [mediaList addMedia:media];
- // This will clean rootMedia
- [self setMediaList:mediaList];
- // Thus set rootMedia here.
- _rootMedia = media;
- }
- - (VLCMedia *)rootMedia
- {
- return _rootMedia;
- }
- - (void)playMedia:(VLCMedia *)media
- {
- dispatch_async(_libVLCBackgroundQueue, ^{
- libvlc_media_list_player_play_item(instance, [media libVLCMediaDescriptor]);
- });
- }
- - (void)play
- {
- dispatch_async(_libVLCBackgroundQueue, ^{
- libvlc_media_list_player_play(instance);
- });
- }
- - (void)pause
- {
- dispatch_async(_libVLCBackgroundQueue, ^{
- libvlc_media_list_player_set_pause(instance, 1);
- });
- }
- - (void)stop
- {
- libvlc_media_list_player_stop_async(instance);
- }
- - (BOOL)next
- {
- return libvlc_media_list_player_next(instance) == 0 ? YES : NO;
- }
- - (BOOL)previous
- {
- return libvlc_media_list_player_previous(instance) == 0 ? YES : NO;
- }
- - (void)playItemAtNumber:(NSNumber *)index
- {
- dispatch_async(_libVLCBackgroundQueue, ^{
- libvlc_media_list_player_play_item_at_index(instance, [index intValue]);
- });
- }
- - (void)setRepeatMode:(VLCRepeatMode)repeatMode
- {
- libvlc_playback_mode_t mode;
- switch (repeatMode) {
- case VLCRepeatAllItems:
- mode = libvlc_playback_mode_loop;
- break;
- case VLCDoNotRepeat:
- mode = libvlc_playback_mode_default;
- break;
- case VLCRepeatCurrentItem:
- mode = libvlc_playback_mode_repeat;
- break;
- default:
- NSAssert(0, @"Should not be reached");
- break;
- }
- libvlc_media_list_player_set_playback_mode(instance, mode);
- _repeatMode = repeatMode;
- }
- - (VLCRepeatMode)repeatMode
- {
- return _repeatMode;
- }
- #pragma mark - Delegate methods
- - (void)mediaListPlayerPlayed
- {
- if ([_delegate respondsToSelector:@selector(mediaListPlayerFinishedPlayback:)]) {
- [_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
|