Browse Source

VLCPlaybackController: Decouple Metadata and controlcenter code from playback

Carola Nitz 7 years ago
parent
commit
0f8bdb39c1

+ 4 - 3
Apple-TV/Playback/Playback Info/VLCPlaybackInfoMediaInfoTVViewController.m

@@ -10,6 +10,7 @@
  *****************************************************************************/
 
 #import "VLCPlaybackInfoMediaInfoTVViewController.h"
+#import "VLCMetadata.h"
 
 @interface VLCPlaybackInfoMediaInfoTVViewController ()
 
@@ -46,7 +47,7 @@
 - (void)viewWillAppear:(BOOL)animated
 {
     VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
-    self.titleLabel.text = vpc.mediaTitle;
+    self.titleLabel.text = vpc.metadata.title;
 
     VLCMediaPlayer *player = vpc.mediaPlayer;
     VLCMedia *media = player.media;
@@ -104,7 +105,7 @@
          NSLocalizedString(@"DURATION", nil),
          media.length.verboseStringValue];
     }
-    if (!vpc.audioOnlyPlaybackSession) {
+    if (!vpc.metadata.isAudioOnly) {
         metaDataString = [metaDataString stringByAppendingFormat:@"%@: %@ (%@)\n",
                           NSLocalizedString(@"VIDEO_DIMENSIONS", nil),
                           [NSString stringWithFormat:NSLocalizedString(@"FORMAT_VIDEO_DIMENSIONS", nil),
@@ -144,7 +145,7 @@
 
 - (void)updateMediaTitle
 {
-    self.titleLabel.text = [VLCPlaybackController sharedInstance].mediaTitle;
+    self.titleLabel.text = [VLCPlaybackController sharedInstance].metadata.title;
 }
 
 @end

+ 2 - 1
Apple-TV/Playback/Playback Info/VLCPlaybackInfoSubtitlesFetcherViewController.m

@@ -12,6 +12,7 @@
 #import "VLCPlaybackInfoSubtitlesFetcherViewController.h"
 #import "MetadataFetcherKit.h"
 #import "NSString+Locale.h"
+#import "VLCMetadata.h"
 
 #define SPUDownloadReUseIdentifier @"SPUDownloadReUseIdentifier"
 #define SPUDownloadHeaderReUseIdentifier @"SPUDownloadHeaderReUseIdentifier"
@@ -95,7 +96,7 @@
     VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     _osoFetcher.subtitleLanguageId = [defaults stringForKey:kVLCSettingLastUsedSubtitlesSearchLanguage];
-    [_osoFetcher searchForSubtitlesWithQuery:vpc.mediaTitle];
+    [_osoFetcher searchForSubtitlesWithQuery:vpc.metadata.title];
 }
 
 - (void)MDFOSOFetcher:(MDFOSOFetcher *)aFetcher didFindSubtitles:(NSArray<MDFSubtitleItem *> *)subtitles forSearchRequest:(NSString *)searchRequest

+ 22 - 0
SharedSources/VLCMetadata.h

@@ -0,0 +1,22 @@
+//
+//  VLCMediaPlayer + Metadata.h
+//  VLC
+//
+//  Created by Carola Nitz on 9/27/17.
+//  Copyright © 2017 VideoLAN. All rights reserved.
+//
+
+@interface VLCMetaData: NSObject
+
+@property(readwrite, copy) NSString *title;
+@property(readwrite) UIImage *artworkImage;
+@property(readwrite, copy) NSString *artist;
+@property(readwrite, copy) NSString *albumName;
+@property(readwrite, assign) BOOL isAudioOnly;
+@property(readwrite) NSNumber *trackNumber;
+@property(readwrite) NSNumber *playbackDuration;
+@property(readwrite) NSNumber *elapsedPlaybackTime;
+@property(readwrite) NSNumber *playbackRate;
+
+- (void)updateMetadataFromMediaPlayer:(VLCMediaPlayer *)mediaPlayer;
+@end

+ 125 - 0
SharedSources/VLCMetadata.m

@@ -0,0 +1,125 @@
+//
+//  VLCMediaPlayer + Metadata.m
+//  VLC
+//
+//  Created by Carola Nitz on 9/27/17.
+//  Copyright © 2017 VideoLAN. All rights reserved.
+//
+
+#import "VLCMetadata.h"
+#import <MediaPlayer/MediaPlayer.h>
+#import "VLCPlaybackController.h"
+
+#if TARGET_OS_IOS
+#import "VLCKeychainCoordinator.h"
+#import "VLCThumbnailsCache.h"
+#endif
+
+@implementation VLCMetaData
+
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+    }
+    return self;
+}
+
+- (void)updateMetadataFromMediaPlayer:(VLCMediaPlayer *)mediaPlayer;
+{
+#if TARGET_OS_IOS
+    MLFile *item;
+
+    if ([VLCPlaybackController sharedInstance].mediaList) {
+        NSArray *matches = [MLFile fileForURL:mediaPlayer.media.url];
+        item = matches.firstObject;
+    }
+
+    if (item) {
+        if (item.isAlbumTrack) {
+            self.title = item.albumTrack.title;
+            self.artist = item.albumTrack.artist;
+            self.albumName = item.albumTrack.album.name;
+        } else
+            self.title = item.title;
+
+        /* MLKit knows better than us if this thing is audio only or not */
+        self.isAudioOnly = [item isSupportedAudioFile];
+    } else {
+#endif
+        NSDictionary * metaDict = mediaPlayer.media.metaDictionary;
+
+        if (metaDict) {
+            self.title = metaDict[VLCMetaInformationNowPlaying] ? metaDict[VLCMetaInformationNowPlaying] : metaDict[VLCMetaInformationTitle];
+            self.artist = metaDict[VLCMetaInformationArtist];
+            self.albumName = metaDict[VLCMetaInformationAlbum];
+            self.trackNumber = metaDict[VLCMetaInformationTrackNumber];
+        }
+#if TARGET_OS_IOS
+    }
+#endif
+
+    if (!self.isAudioOnly) {
+        /* either what we are playing is not a file known to MLKit or
+         * MLKit fails to acknowledge that it is audio-only.
+         * Either way, do a more expensive check to see if it is really audio-only */
+        NSArray *tracks = mediaPlayer.media.tracksInformation;
+        NSUInteger trackCount = tracks.count;
+        self.isAudioOnly = YES;
+        for (NSUInteger x = 0 ; x < trackCount; x++) {
+            if ([[tracks[x] objectForKey:VLCMediaTracksInformationType] isEqualToString:VLCMediaTracksInformationTypeVideo]) {
+                self.isAudioOnly = NO;
+                break;
+            }
+        }
+    }
+
+    if (self.isAudioOnly) {
+#if TARGET_OS_IOS
+        self.artworkImage = [VLCThumbnailsCache thumbnailForManagedObject:item];
+
+        if (self.artworkImage) {
+            if (self.artist)
+                self.title = [self.title stringByAppendingFormat:@" — %@", self.artist];
+            if (self.albumName)
+                self.title = [self.title stringByAppendingFormat:@" — %@", self.albumName];
+        }
+#endif
+        if (self.title.length < 1)
+            self.title = [[mediaPlayer.media url] lastPathComponent];
+    }
+    self.playbackDuration = @(mediaPlayer.media.length.intValue / 1000.);
+    self.playbackRate = @(mediaPlayer.rate);
+    self.elapsedPlaybackTime = @(mediaPlayer.media.length.intValue / 1000.);
+    [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackControllerPlaybackMetadataDidChange object:self];
+#if TARGET_OS_IOS
+    if ([[VLCKeychainCoordinator defaultCoordinator] passcodeLockEnabled]) return;
+#endif
+    [self populateInfoCenterFromMetadata];
+}
+
+- (void)populateInfoCenterFromMetadata
+{
+    NSMutableDictionary *currentlyPlayingTrackInfo = [NSMutableDictionary dictionary];
+    currentlyPlayingTrackInfo[MPMediaItemPropertyPlaybackDuration] = self.playbackDuration;
+    currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = self.elapsedPlaybackTime;
+    currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyPlaybackRate] = self.playbackRate;
+
+    currentlyPlayingTrackInfo[MPMediaItemPropertyTitle] = self.title;
+    currentlyPlayingTrackInfo[MPMediaItemPropertyArtist] = self.artist;
+    currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTitle] = self.albumName;
+
+    if ([self.trackNumber intValue] > 0)
+        currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTrackNumber] = self.trackNumber;
+
+#if TARGET_OS_IOS
+    if (self.artworkImage) {
+        MPMediaItemArtwork *mpartwork = [[MPMediaItemArtwork alloc] initWithImage:self.artworkImage];
+        currentlyPlayingTrackInfo[MPMediaItemPropertyArtwork] = mpartwork;
+    }
+#endif
+
+    [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = currentlyPlayingTrackInfo;
+}
+
+@end

+ 2 - 1
SharedSources/VLCPlayerControlWebSocket.m

@@ -11,6 +11,7 @@
  *****************************************************************************/
 
 #import "VLCPlayerControlWebSocket.h"
+#import "VLCMetadata.h"
 
 @implementation VLCPlayerControlWebSocket
 
@@ -122,7 +123,7 @@
 
             if (media) {
                 NSURL *url = media.url;
-                NSString *mediaTitle = vpc.mediaTitle;
+                NSString *mediaTitle = vpc.metadata.title;
                 if (!mediaTitle)
                     mediaTitle = url.lastPathComponent;
                 NSDictionary *mediaDict = @{ @"id" : url.absoluteString,

+ 2 - 1
Sources/VLCHTTPConnection.m

@@ -25,6 +25,7 @@
 #import "NSString+SupportedMedia.h"
 #import "UIDevice+VLC.h"
 #import "VLCHTTPUploaderController.h"
+#import "VLCMetaData.h"
 
 #if TARGET_OS_IOS
 #import "VLCThumbnailsCache.h"
@@ -463,7 +464,7 @@
         return [[HTTPErrorResponse alloc] initWithErrorCode:404];
     }
 
-    NSString *mediaTitle = vpc.mediaTitle;
+    NSString *mediaTitle = vpc.metadata.title;
     if (!mediaTitle)
         mediaTitle = @"";
     NSDictionary *mediaDict = @{ @"id" : media.url.absoluteString,

+ 10 - 14
Sources/VLCMiniPlaybackView.m

@@ -13,6 +13,7 @@
 #import "VLCMiniPlaybackView.h"
 #import "VLCPlaybackController.h"
 #import "VLCPlayerDisplayController.h"
+#import "VLCMetadata.h"
 
 #if TARGET_OS_IOS
 #import "VLCLibraryViewController.h"
@@ -208,16 +209,11 @@ currentMediaHasTrackToChooseFrom:(BOOL)currentMediaHasTrackToChooseFrom
     [self updatePlayPauseButton];
 }
 
-- (void)displayMetadataForPlaybackController:(VLCPlaybackController *)controller
-                                       title:(NSString *)title
-                                     artwork:(UIImage *)artwork
-                                      artist:(NSString *)artist
-                                       album:(NSString *)album
-                                   audioOnly:(BOOL)audioOnly
+- (void)displayMetadataForPlaybackController:(VLCPlaybackController *)controller metadata:(VLCMetaData *)metadata
 {
-    if (audioOnly) {
+    if (metadata.isAudioOnly) {
         _artworkView.contentMode = UIViewContentModeScaleAspectFill;
-        _artworkView.image = artwork ? artwork : [UIImage imageNamed:@"no-artwork"];
+        _artworkView.image = metadata.artworkImage?: [UIImage imageNamed:@"no-artwork"];
         if (_videoView) {
             [_videoView removeFromSuperview];
             _videoView = nil;
@@ -242,14 +238,14 @@ currentMediaHasTrackToChooseFrom:(BOOL)currentMediaHasTrackToChooseFrom
     }
 
     NSString *metaDataString;
-    if (artist)
-        metaDataString = artist;
-    if (album)
-        metaDataString = [metaDataString stringByAppendingFormat:@" — %@", album];
+    if (metadata.artist)
+        metaDataString = metadata.artist;
+    if (metadata.albumName)
+        metaDataString = [metaDataString stringByAppendingFormat:@" — %@", metadata.albumName];
     if (metaDataString)
-        metaDataString = [metaDataString stringByAppendingFormat:@"\n%@", title];
+        metaDataString = [metaDataString stringByAppendingFormat:@"\n%@", metadata.title];
     else
-        metaDataString = title;
+        metaDataString = metadata.title;
 
     _metaDataLabel.text = metaDataString;
 }

+ 2 - 1
Sources/VLCMovieViewControlPanelView.m

@@ -13,6 +13,7 @@
 
 #import "VLCMovieViewControlPanelView.h"
 #import "VLCPlaybackController.h"
+#import "VLCMetadata.h"
 
 @interface VLCMovieViewControlPanelView ()
 
@@ -246,7 +247,7 @@ static const CGFloat maxCompactWidth = 420.0;
     [self updatePlayPauseButton];
 
     self.trackSwitcherButton.hidden = !self.playbackController.currentMediaHasTrackToChooseFrom;
-    self.videoFilterButton.hidden = self.playbackController.audioOnlyPlaybackSession;
+    self.videoFilterButton.hidden = self.playbackController.metadata.isAudioOnly;
 }
 
 - (void)updatePlayPauseButton

+ 9 - 13
Sources/VLCMovieViewController.m

@@ -34,6 +34,7 @@
 #import "VLCSlider.h"
 #import "VLCLibraryViewController.h"
 #import "VLCTrackSelectorView.h"
+#import "VLCMetadata.h"
 
 #define FORWARD_SWIPE_DURATION 30
 #define BACKWARD_SWIPE_DURATION 10
@@ -992,28 +993,23 @@ currentMediaHasTrackToChooseFrom:(BOOL)currentMediaHasTrackToChooseFrom
                      }];
 }
 
-- (void)displayMetadataForPlaybackController:(VLCPlaybackController *)controller
-                                       title:(NSString *)title
-                                     artwork:(UIImage *)artwork
-                                      artist:(NSString *)artist
-                                       album:(NSString *)album
-                                   audioOnly:(BOOL)audioOnly
+- (void)displayMetadataForPlaybackController:(VLCPlaybackController *)controller metadata:(VLCMetaData *)metadata
 {
     if (!_viewAppeared)
         return;
 
-    self.trackNameLabel.text = title;
-    self.artworkImageView.image = artwork;
-    if (!artwork) {
-        self.artistNameLabel.text = artist;
-        self.albumNameLabel.text = album;
+    self.trackNameLabel.text = metadata.title;
+    self.artworkImageView.image = metadata.artworkImage;
+    if (!metadata.artworkImage) {
+        self.artistNameLabel.text = metadata.artist;
+        self.albumNameLabel.text = metadata.albumName;
     } else
         self.artistNameLabel.text = self.albumNameLabel.text = nil;
 
-    [self hideShowAspectratioButton:audioOnly];
+    [self hideShowAspectratioButton:metadata.isAudioOnly];
     [_controllerPanel updateButtons];
     
-    _audioOnly = audioOnly;
+    _audioOnly = metadata.isAudioOnly;
 }
 
 - (IBAction)playPause

+ 4 - 8
Sources/VLCPlaybackController.h

@@ -22,6 +22,7 @@ extern NSString *const VLCPlaybackControllerPlaybackMetadataDidChange;
 extern NSString *const VLCPlaybackControllerPlaybackPositionUpdated;
 
 @class VLCPlaybackController;
+@class VLCMetaData;
 
 @protocol VLCPlaybackControllerDelegate <NSObject>
 @optional
@@ -33,12 +34,7 @@ currentMediaHasTrackToChooseFrom:(BOOL)currentMediaHasTrackToChooseFrom
           forPlaybackController:(VLCPlaybackController *)controller;
 - (void)prepareForMediaPlayback:(VLCPlaybackController *)controller;
 - (void)showStatusMessage:(NSString *)statusMessage forPlaybackController:(VLCPlaybackController *)controller;
-- (void)displayMetadataForPlaybackController:(VLCPlaybackController *)controller
-                                       title:(NSString *)title
-                                     artwork:(UIImage *)artwork
-                                      artist:(NSString *)artist
-                                       album:(NSString *)album
-                                   audioOnly:(BOOL)audioOnly;
+- (void)displayMetadataForPlaybackController:(VLCPlaybackController *)controller metadata:(VLCMetaData *)metadata;
 
 @end
 
@@ -67,6 +63,8 @@ currentMediaHasTrackToChooseFrom:(BOOL)currentMediaHasTrackToChooseFrom
 @property (nonatomic, weak) id<VLCPlaybackControllerDelegate> delegate;
 
 @property (nonatomic, readonly) VLCMediaPlayerState mediaPlayerState;
+@property (nonatomic, readonly) VLCMetaData *metadata;
+
 @property (nonatomic, readonly) NSInteger mediaDuration;
 @property (nonatomic, readonly) BOOL isPlaying;
 @property (nonatomic, readwrite) VLCRepeatMode repeatMode;
@@ -77,8 +75,6 @@ currentMediaHasTrackToChooseFrom:(BOOL)currentMediaHasTrackToChooseFrom
 @property (nonatomic, readonly) BOOL currentMediaHasChapters;
 @property (nonatomic, readonly) BOOL currentMediaHasTrackToChooseFrom;
 @property (nonatomic, readonly) BOOL activePlaybackSession;
-@property (nonatomic, readonly) BOOL audioOnlyPlaybackSession;
-@property (nonatomic, readonly) NSString *mediaTitle;
 @property (nonatomic, readwrite) BOOL fullscreenSessionRequested;
 @property (nonatomic, readonly) NSDictionary *mediaOptionsDictionary;
 @property (nonatomic, readonly) NSTimer* sleepTimer;

+ 14 - 172
Sources/VLCPlaybackController.m

@@ -20,17 +20,10 @@
 #import <CommonCrypto/CommonDigest.h>
 #import "UIDevice+VLC.h"
 #import <AVFoundation/AVFoundation.h>
-#import <MediaPlayer/MediaPlayer.h>
 #import "VLCPlayerDisplayController.h"
 #import "VLCConstants.h"
 #import "VLCRemoteControlService.h"
-
-#if TARGET_OS_IOS
-#import "VLCKeychainCoordinator.h"
-#import "VLCThumbnailsCache.h"
-#import "VLCLibraryViewController.h"
-#import <WatchKit/WatchKit.h>
-#endif
+#import "VLCMetadata.h"
 
 NSString *const VLCPlaybackControllerPlaybackDidStart = @"VLCPlaybackControllerPlaybackDidStart";
 NSString *const VLCPlaybackControllerPlaybackDidPause = @"VLCPlaybackControllerPlaybackDidPause";
@@ -63,18 +56,10 @@ VLCMediaDelegate, VLCRemoteControlServiceDelegate>
 
     NSUInteger _currentAspectRatio;
 
-    float _currentPlaybackRate;
     UIView *_videoOutputViewWrapper;
     UIView *_actualVideoOutputView;
     UIView *_preBackgroundWrapperView;
 
-    /* cached stuff for the VC */
-    NSString *_title;
-    UIImage *_artworkImage;
-    NSString *_artist;
-    NSString *_albumName;
-    BOOL _mediaIsAudioOnly;
-
     BOOL _needsMetadataUpdate;
     BOOL _mediaWasJustStarted;
     BOOL _recheckForExistingThumbnail;
@@ -127,6 +112,7 @@ VLCMediaDelegate, VLCRemoteControlServiceDelegate>
         [defaultCenter addObserver:self selector:@selector(applicationDidEnterBackground:)
                               name:UIApplicationDidEnterBackgroundNotification object:nil];
 
+        _metadata = [VLCMetaData new];
         _dialogProvider = [[VLCDialogProvider alloc] initWithLibrary:[VLCLibrary sharedLibrary] customUI:NO];
 
         _playbackSessionManagementLock = [[NSLock alloc] init];
@@ -487,7 +473,7 @@ VLCMediaDelegate, VLCRemoteControlServiceDelegate>
 
 - (NSInteger)mediaDuration
 {
-    return _listPlayer.mediaPlayer.media.length.intValue;;
+    return _mediaPlayer.media.length.intValue;;
 }
 
 - (BOOL)isPlaying
@@ -520,38 +506,27 @@ VLCMediaDelegate, VLCRemoteControlServiceDelegate>
     return _activeSession;
 }
 
-- (BOOL)audioOnlyPlaybackSession
-{
-    return _mediaIsAudioOnly;
-}
-
-- (NSString *)mediaTitle
-{
-    return _title;
-}
-
 - (float)playbackRate
 {
-    float f_rate = _mediaPlayer.rate;
-    _currentPlaybackRate = f_rate;
-    return f_rate;
+    return _mediaPlayer.rate;
 }
 
 - (void)setPlaybackRate:(float)playbackRate
 {
-    if (_currentPlaybackRate != playbackRate)
-        [_mediaPlayer setRate:playbackRate];
-    _currentPlaybackRate = playbackRate;
+    [_mediaPlayer setRate:playbackRate];
+    _metadata.playbackRate = @(_mediaPlayer.rate);
 }
 
 - (void)setAudioDelay:(float)audioDelay
 {
     _mediaPlayer.currentAudioPlaybackDelay = 1000000.*audioDelay;
 }
+
 - (float)audioDelay
 {
     return _mediaPlayer.currentAudioPlaybackDelay/1000000.;
 }
+
 -(void)setSubtitleDelay:(float)subtitleDeleay
 {
     _mediaPlayer.currentVideoSubTitleDelay = 1000000.*subtitleDeleay;
@@ -914,142 +889,14 @@ VLCMediaDelegate, VLCRemoteControlServiceDelegate>
     if (_needsMetadataUpdate == NO) {
         _needsMetadataUpdate = YES;
         dispatch_async(dispatch_get_main_queue(), ^{
-            [self _updateDisplayedMetadata];
+            [_metadata updateMetadataFromMediaPlayer:_mediaPlayer];
+            _needsMetadataUpdate = NO;
+            if ([self.delegate respondsToSelector:@selector(displayMetadataForPlaybackController:metadata:)])
+                [self.delegate displayMetadataForPlaybackController:self metadata:_metadata];
         });
     }
 }
 
-- (void)_updateDisplayedMetadata
-{
-    _needsMetadataUpdate = NO;
-
-    NSNumber *trackNumber;
-
-    NSString *title;
-    NSString *artist;
-    NSString *albumName;
-    UIImage* artworkImage;
-    BOOL mediaIsAudioOnly = NO;
-
-#if TARGET_OS_IOS
-    MLFile *item;
-
-    if (self.mediaList) {
-        NSArray *matches = [MLFile fileForURL:_mediaPlayer.media.url];
-        item = matches.firstObject;
-    }
-
-    if (item) {
-        if (item.isAlbumTrack) {
-            title = item.albumTrack.title;
-            artist = item.albumTrack.artist;
-            albumName = item.albumTrack.album.name;
-        } else
-            title = item.title;
-
-        /* MLKit knows better than us if this thing is audio only or not */
-        mediaIsAudioOnly = [item isSupportedAudioFile];
-    } else {
-#endif
-        NSDictionary * metaDict = _mediaPlayer.media.metaDictionary;
-
-        if (metaDict) {
-            title = metaDict[VLCMetaInformationNowPlaying] ? metaDict[VLCMetaInformationNowPlaying] : metaDict[VLCMetaInformationTitle];
-            artist = metaDict[VLCMetaInformationArtist];
-            albumName = metaDict[VLCMetaInformationAlbum];
-            trackNumber = metaDict[VLCMetaInformationTrackNumber];
-        }
-#if TARGET_OS_IOS
-    }
-#endif
-
-    if (!mediaIsAudioOnly) {
-        /* either what we are playing is not a file known to MLKit or
-         * MLKit fails to acknowledge that it is audio-only.
-         * Either way, do a more expensive check to see if it is really audio-only */
-        NSArray *tracks = _mediaPlayer.media.tracksInformation;
-        NSUInteger trackCount = tracks.count;
-        mediaIsAudioOnly = YES;
-        for (NSUInteger x = 0 ; x < trackCount; x++) {
-            if ([[tracks[x] objectForKey:VLCMediaTracksInformationType] isEqualToString:VLCMediaTracksInformationTypeVideo]) {
-                mediaIsAudioOnly = NO;
-                break;
-            }
-        }
-    }
-
-    if (mediaIsAudioOnly) {
-#if TARGET_OS_IOS
-        artworkImage = [VLCThumbnailsCache thumbnailForManagedObject:item];
-
-        if (artworkImage) {
-            if (artist)
-                title = [title stringByAppendingFormat:@" — %@", artist];
-            if (albumName)
-                title = [title stringByAppendingFormat:@" — %@", albumName];
-        }
-#endif
-
-        if (title.length < 1)
-            title = [[_mediaPlayer.media url] lastPathComponent];
-    }
-
-    /* populate delegate with metadata info */
-    if ([self.delegate respondsToSelector:@selector(displayMetadataForPlaybackController:title:artwork:artist:album:audioOnly:)])
-        [self.delegate displayMetadataForPlaybackController:self
-                                                      title:title
-                                                    artwork:artworkImage
-                                                     artist:artist
-                                                      album:albumName
-                                                  audioOnly:mediaIsAudioOnly];
-
-    /* populate now playing info center with metadata information */
-    NSMutableDictionary *currentlyPlayingTrackInfo = [NSMutableDictionary dictionary];
-    currentlyPlayingTrackInfo[MPMediaItemPropertyPlaybackDuration] = @(_mediaPlayer.media.length.intValue / 1000.);
-    currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] =  @(_mediaPlayer.time.intValue / 1000.);
-    currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyPlaybackRate] = @(_mediaPlayer.isPlaying ? _mediaPlayer.rate : 0.0);
-
-    /* don't leak sensitive information to the OS, if passcode lock is enabled */
-#if TARGET_OS_IOS
-    if (![[VLCKeychainCoordinator defaultCoordinator] passcodeLockEnabled]) {
-#endif
-        if (title)
-            currentlyPlayingTrackInfo[MPMediaItemPropertyTitle] = title;
-        if (artist.length > 0)
-            currentlyPlayingTrackInfo[MPMediaItemPropertyArtist] = artist;
-        if (albumName.length > 0)
-            currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTitle] = albumName;
-
-        if ([trackNumber intValue] > 0)
-            currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTrackNumber] = trackNumber;
-
-#if TARGET_OS_IOS
-        /* FIXME: UGLY HACK
-         * iOS 8.2 and 8.3 include an issue which will lead to a termination of the client app if we set artwork
-         * when the playback initialized through the watch extension
-         * radar://pending */
-        if ([WKInterfaceDevice class] != nil) {
-            if ([WKInterfaceDevice currentDevice] != nil)
-                goto setstuff;
-        }
-        if (artworkImage) {
-            MPMediaItemArtwork *mpartwork = [[MPMediaItemArtwork alloc] initWithImage:artworkImage];
-            currentlyPlayingTrackInfo[MPMediaItemPropertyArtwork] = mpartwork;
-        }
-    }
-#endif
-
-setstuff:
-    [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = currentlyPlayingTrackInfo;
-    [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackControllerPlaybackMetadataDidChange object:self];
-
-    _title = title;
-    _artist = artist;
-    _albumName = albumName;
-    _artworkImage = artworkImage;
-    _mediaIsAudioOnly = mediaIsAudioOnly;
-}
-
 #if TARGET_OS_IOS
 - (void)_recoverLastPlaybackStateOfItem:(MLFile *)item
 {
@@ -1099,13 +946,8 @@ setstuff:
 
 - (void)recoverDisplayedMetadata
 {
-    if ([self.delegate respondsToSelector:@selector(displayMetadataForPlaybackController:title:artwork:artist:album:audioOnly:)])
-        [self.delegate displayMetadataForPlaybackController:self
-                                                      title:_title
-                                                    artwork:_artworkImage
-                                                     artist:_artist
-                                                      album:_albumName
-                                                  audioOnly:_mediaIsAudioOnly];
+    if ([self.delegate respondsToSelector:@selector(displayMetadataForPlaybackController:metadata:)])
+        [self.delegate displayMetadataForPlaybackController:self metadata:_metadata];
 }
 
 - (void)recoverPlaybackState

+ 14 - 0
VLC.xcodeproj/project.pbxproj

@@ -57,6 +57,11 @@
 		41EB91D81F7BE6F700821AA5 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 417D7F5F1F7BA26200DDF36A /* VLCRemoteControlService.m */; };
 		41EB91D91F7BE6F900821AA5 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 417D7F5F1F7BA26200DDF36A /* VLCRemoteControlService.m */; };
 		41EB91DA1F7BE6F900821AA5 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 417D7F5F1F7BA26200DDF36A /* VLCRemoteControlService.m */; };
+		41EB91DD1F7BFF8500821AA5 /* VLCMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */; };
+		41EB91DE1F7BFF8500821AA5 /* VLCMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */; };
+		41EB91DF1F7BFF8500821AA5 /* VLCMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */; };
+		41EB91E01F7BFF8500821AA5 /* VLCMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */; };
+		41EB91E11F7C0A7F00821AA5 /* VLCMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */; };
 		41F5C0781F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 41F5C0771F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.m */; };
 		41F5C07B1F42E567005EB9CB /* VLCMediaDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 41F5C07A1F42E567005EB9CB /* VLCMediaDataSource.m */; };
 		41F5C07C1F42E567005EB9CB /* VLCMediaDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 41F5C07A1F42E567005EB9CB /* VLCMediaDataSource.m */; };
@@ -1190,6 +1195,8 @@
 		41CD69591A29D72600E60BCE /* VLCBoxController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCBoxController.m; path = Sources/VLCBoxController.m; sourceTree = SOURCE_ROOT; };
 		41CD695A1A29D72600E60BCE /* VLCBoxTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCBoxTableViewController.h; path = Sources/VLCBoxTableViewController.h; sourceTree = SOURCE_ROOT; };
 		41CD695B1A29D72600E60BCE /* VLCBoxTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCBoxTableViewController.m; path = Sources/VLCBoxTableViewController.m; sourceTree = SOURCE_ROOT; };
+		41EB91DB1F7BFF8400821AA5 /* VLCMetadata.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCMetadata.h; sourceTree = "<group>"; };
+		41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCMetadata.m; sourceTree = "<group>"; };
 		41F5C0761F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VLCLibrarySearchDisplayDataSource.h; path = Sources/VLCLibrarySearchDisplayDataSource.h; sourceTree = SOURCE_ROOT; };
 		41F5C0771F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = VLCLibrarySearchDisplayDataSource.m; path = Sources/VLCLibrarySearchDisplayDataSource.m; sourceTree = SOURCE_ROOT; };
 		41F5C0791F42E567005EB9CB /* VLCMediaDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VLCMediaDataSource.h; path = Sources/VLCMediaDataSource.h; sourceTree = SOURCE_ROOT; };
@@ -3183,6 +3190,8 @@
 				DDBE44FE1BFB6A8B00E5D35E /* CAAnimation+VLCWiggle.m */,
 				417E68B71F321EFF00DB9BB2 /* VLCActivityViewControllerVendor.h */,
 				417E68B81F321EFF00DB9BB2 /* VLCActivityViewControllerVendor.m */,
+				41EB91DB1F7BFF8400821AA5 /* VLCMetadata.h */,
+				41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */,
 			);
 			path = SharedSources;
 			sourceTree = "<group>";
@@ -4378,6 +4387,7 @@
 				DDEAECBF1BDEBF6700756C83 /* VLCNetworkServerLoginInformation.m in Sources */,
 				DD3EFF381BDEBCE500B68579 /* VLCLocalNetworkServiceNetService.m in Sources */,
 				DD8095D61BE3C3BA0065D8E1 /* VLCTransportBar.m in Sources */,
+				41EB91DE1F7BFF8500821AA5 /* VLCMetadata.m in Sources */,
 				DDDEA6AF1BE027FA000BB7A2 /* VLCServerBrowsingTVViewController.m in Sources */,
 				DD3EFF461BDEBCE500B68579 /* VLCLocalNetworkServiceBrowserManualConnect.m in Sources */,
 				7D13347F1BE132ED0012E919 /* VLCLocalNetworkServiceUPnP.m in Sources */,
@@ -4470,6 +4480,7 @@
 				7D63BB911D414212003C60D3 /* Reachability.m in Sources */,
 				7D63BB921D414212003C60D3 /* VLCDropboxCollectionViewController.m in Sources */,
 				7D63BB931D414212003C60D3 /* VLCLocalNetworkServiceBrowserDSM.m in Sources */,
+				41EB91E11F7C0A7F00821AA5 /* VLCMetadata.m in Sources */,
 				7D63BB941D414212003C60D3 /* VLCNetworkServerLoginInformation+Keychain.m in Sources */,
 				7D63BB951D414212003C60D3 /* BasicUPnPDevice+VLC.m in Sources */,
 				7D63BB961D414212003C60D3 /* VLCAboutViewController.m in Sources */,
@@ -4678,6 +4689,7 @@
 				7DE7D2CE1D42900700B3AD27 /* VLCNetworkLoginDataSourceLogin.m in Sources */,
 				7D787F871D40FDE70003CFA1 /* VLCSidebarController.m in Sources */,
 				7D787F881D40FDE70003CFA1 /* VLCNetworkLoginViewController.m in Sources */,
+				41EB91E01F7BFF8500821AA5 /* VLCMetadata.m in Sources */,
 				7D787F891D40FDE70003CFA1 /* MappingModel_2_5_to_2_6.xcmappingmodel in Sources */,
 				7DE7D2CF1D42900C00B3AD27 /* VLCNetworkLoginDataSourceProtocol.m in Sources */,
 				7D787F8A1D40FDE70003CFA1 /* VLCWiFiUploadTableViewCell.m in Sources */,
@@ -4742,6 +4754,7 @@
 				41F9BC7C1F4F20E400268461 /* VLCTrackSelectorView.m in Sources */,
 				7D378499183A98D1009EE944 /* VLCPlaylistCollectionViewCell.m in Sources */,
 				DD8F84311B00EB3B0009138A /* VLCPlaybackController+MediaLibrary.m in Sources */,
+				41EB91DD1F7BFF8500821AA5 /* VLCMetadata.m in Sources */,
 				DD3EFF551BDEBCE500B68579 /* VLCLocalNetworkServiceBrowserDSM.m in Sources */,
 				7D37849A183A98D1009EE944 /* VLCPlaylistTableViewCell.m in Sources */,
 				7D37849B183A98D1009EE944 /* VLCLibraryViewController.m in Sources */,
@@ -4951,6 +4964,7 @@
 				7DC5501C1C046615007B4E42 /* VLCPlayerDisplayController.m in Sources */,
 				7DC5501D1C046615007B4E42 /* VLCSharedLibraryParser.m in Sources */,
 				7DC5501E1C046615007B4E42 /* VLCCloudStorageTableViewController.m in Sources */,
+				41EB91DF1F7BFF8500821AA5 /* VLCMetadata.m in Sources */,
 				7DC5501F1C046615007B4E42 /* VLCGoogleDriveTableViewController.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;