瀏覽代碼

VLCPlaybackController: save and restore playbackstate with new library

Delete old Medialibrary methods for playback
Carola Nitz 6 年之前
父節點
當前提交
574839ba6c

+ 0 - 28
SharedSources/MLMediaLibrary+playlist.h

@@ -1,28 +0,0 @@
-/*****************************************************************************
- * MLMediaLibrary+playlist.h
- * VLC for iOS
- *****************************************************************************
- * Copyright (c) 2015 VideoLAN. All rights reserved.
- * $Id$
- *
- * Authors: Tobias Conradi <videolan # tobias-conradi.de>
- *          Carola Nitz <caro # videolan.org>
- *          Felix Paul Kühne <fkuehne # videolan.org>
- *
- * Refer to the COPYING file of the official project for license.
- *****************************************************************************/
-
-typedef enum {
-    VLCLibraryModeAllFiles  = 0,
-    VLCLibraryModeAllAlbums = 1,
-    VLCLibraryModeAllSeries = 2,
-    VLCLibraryModeCreateFolder = 3,
-    VLCLibraryModeFolder = 4
-} VLCLibraryMode;
-
-@interface MLMediaLibrary (playlist)
-
-- (nonnull NSArray *)playlistArrayForGroupObject:(nonnull id)groupObject;
-- (nonnull NSArray *)playlistArrayForLibraryMode:(VLCLibraryMode)libraryMode;
-
-@end

+ 0 - 97
SharedSources/MLMediaLibrary+playlist.m

@@ -1,97 +0,0 @@
-/*****************************************************************************
- * MLMediaLibrary+playlist.m
- * VLC for iOS
- *****************************************************************************
- * Copyright (c) 2015 VideoLAN. All rights reserved.
- * $Id$
- *
- * Authors: Tobias Conradi <videolan # tobias-conradi.de>
- *          Carola Nitz <caro # videolan.org>
- *          Felix Paul Kühne <fkuehne # videolan.org>
- *
- * Refer to the COPYING file of the official project for license.
- *****************************************************************************/
-
-#import "MLMediaLibrary+playlist.h"
-
-@implementation MLMediaLibrary (playlist)
-
-
-- (nonnull NSArray *)playlistArrayForGroupObject:(nonnull id)groupObject
-{
-    if([groupObject isKindOfClass:[MLLabel class]]) {
-        return [(MLLabel *)groupObject sortedFolderItems];
-    } else if ([groupObject isKindOfClass:[MLAlbum class]]) {
-        return [(MLAlbum *)groupObject sortedTracks];
-    } else if ([groupObject isKindOfClass:[MLShow class]]){
-        return [(MLShow *)groupObject sortedEpisodes];
-    } else {
-        NSAssert(NO, @"this shouldn't have happened check the grouObjects type");
-        return nil;
-    }
-}
-
-//TODO: this code could use refactoring to be more readable
-- (nonnull NSArray *)playlistArrayForLibraryMode:(VLCLibraryMode)libraryMode
-{
-
-    NSMutableArray *objects = [NSMutableArray array];
-    if (libraryMode == VLCLibraryModeFolder) {
-        return  objects;
-    }
-
-    /* add all albums */
-    if (libraryMode != VLCLibraryModeAllSeries) {
-        NSArray *rawAlbums = [MLAlbum allAlbums];
-        for (MLAlbum *album in rawAlbums) {
-            if (album.name.length > 0 && album.tracks.count > 1)
-                [objects addObject:album];
-        }
-    }
-    if (libraryMode == VLCLibraryModeAllAlbums) {
-        return objects;
-    }
-
-    /* add all shows */
-    NSArray *rawShows = [MLShow allShows];
-    for (MLShow *show in rawShows) {
-        if (show.name.length > 0 && show.episodes.count > 1)
-            [objects addObject:show];
-    }
-    if (libraryMode == VLCLibraryModeAllSeries) {
-        return objects;
-    }
-
-    /* add all folders*/
-    NSArray *allFolders = [MLLabel allLabels];
-    for (MLLabel *folder in allFolders)
-        [objects addObject:folder];
-
-    /* add all remaining files */
-    NSArray *allFiles = [MLFile allFiles];
-    for (MLFile *file in allFiles) {
-        if (file.labels.count > 0) continue;
-
-        if (!file.isShowEpisode && !file.isAlbumTrack)
-            [objects addObject:file];
-        else if (file.isShowEpisode) {
-            if (file.showEpisode.show.episodes.count < 2)
-                [objects addObject:file];
-
-            /* older MediaLibraryKit versions don't send a show name in a popular
-             * corner case. hence, we need to work-around here and force a reload
-             * afterwards as this could lead to the 'all my shows are gone'
-             * syndrome (see #10435, #10464, #10432 et al) */
-            if (file.showEpisode.show.name.length == 0) {
-                file.showEpisode.show.name = NSLocalizedString(@"UNTITLED_SHOW", nil);
-            }
-        } else if (file.isAlbumTrack) {
-            if (file.albumTrack.album.tracks.count < 2)
-                [objects addObject:file];
-        }
-    }
-
-    return objects;
-}
-
-@end

+ 1 - 13
SharedSources/MediaLibraryModel/MediaModel.swift

@@ -40,7 +40,7 @@ extension VLCMLMedia {
         return lhs.identifier() == rhs.identifier()
     }
 }
-
+// MARK: - ViewModel
 extension VLCMLMedia {
     @objc func mediaDuration() -> String {
         return String(format: "%@", VLCTime(int: Int32(duration())))
@@ -50,18 +50,6 @@ extension VLCMLMedia {
         return ByteCountFormatter.string(fromByteCount: Int64(mainFile()?.size() ?? 0),
                                          countStyle: .file)
     }
-
-    func mediaProgress() -> Float {
-        guard let string = metadata(of: .progress).str as NSString? else {
-            return 0.0
-        }
-        return string.floatValue
-    }
-
-    func isNew() -> Bool {
-        let integer = metadata(of: .seen).integer()
-        return integer == 0
-    }
 }
 
 // MARK: - CoreSpotlight

+ 19 - 0
SharedSources/MediaLibraryService.swift

@@ -291,14 +291,33 @@ extension MediaLibraryService {
 
     @objc func fetchMedia(with mrl: URL?) -> VLCMLMedia? {
         guard let mrl = mrl  else {
+            assertionFailure("MedialibraryService: no mrl")
             return nil
         }
         return medialib.media(withMrl: mrl)
     }
 
+
     @objc func media(for identifier: VLCMLIdentifier) -> VLCMLMedia? {
         return medialib.media(withIdentifier: identifier)
     }
+
+    func savePlaybackState(from player: VLCPlaybackController) {
+
+        let media = player.currentlyPlayingMedia
+        guard let mlMedia = fetchMedia(with: media.url.absoluteURL) else {
+            // we opened a url and not a local file
+            return
+        }
+
+        mlMedia.isNew = false
+        mlMedia.progress = player.playbackPosition
+        mlMedia.audioTrackIndex = Int64(player.indexOfCurrentAudioTrack)
+        mlMedia.subtitleTrackIndex = Int64(player.indexOfCurrentSubtitleTrack)
+        mlMedia.chapterIndex = Int64(player.indexOfCurrentChapter)
+        mlMedia.titleIndex = Int64(player.indexOfCurrentTitle)
+        //create a new thumbnail
+    }
 }
 
 // MARK: - Audio methods

+ 0 - 3
Sources/MediaCategories/MediaCategoryViewController.swift

@@ -397,9 +397,6 @@ private extension VLCMediaCategoryViewController {
 // MARK: - Player
 
 extension VLCMediaCategoryViewController {
-    func play(mediaObject: NSManagedObject) {
-        VLCPlaybackController.sharedInstance().playMediaLibraryObject(mediaObject)
-    }
 
     func play(media: VLCMLMedia) {
         VLCPlaybackController.sharedInstance().fullscreenSessionRequested = media.subtype() != .albumTrack

+ 2 - 2
Sources/MediaCategoryCells/MediaCollectionViewCell.swift

@@ -59,7 +59,7 @@ class MediaCollectionViewCell: BaseCollectionViewCell {
         if audiotrack.isThumbnailGenerated() {
             thumbnailView.image = UIImage(contentsOfFile: audiotrack.thumbnail.path)
         }
-        newLabel.isHidden = !audiotrack.isNew()
+        newLabel.isHidden = !audiotrack.isNew
     }
 
     func update(album: VLCMLAlbum) {
@@ -80,7 +80,7 @@ class MediaCollectionViewCell: BaseCollectionViewCell {
         if movie.isThumbnailGenerated() {
             thumbnailView.image = UIImage(contentsOfFile: movie.thumbnail.path)
         }
-        newLabel.isHidden = !movie.isNew()
+        newLabel.isHidden = !movie.isNew
     }
 
     func update(playlist: VLCMLPlaylist) {

+ 2 - 2
Sources/MediaCategoryCells/MovieCollectionViewCell.swift

@@ -60,10 +60,10 @@ class MovieCollectionViewCell: BaseCollectionViewCell {
         if movie.isThumbnailGenerated() {
             thumbnailView.image = UIImage(contentsOfFile: movie.thumbnail.path)
         }
-        let progress = movie.mediaProgress()
+        let progress = movie.progress
         progressView.isHidden = progress == 0
         progressView.progress = progress
-        newLabel.isHidden = !movie.isNew()
+        newLabel.isHidden = !movie.isNew
     }
 
     func update(playlist: VLCMLPlaylist) {

+ 12 - 2
Sources/MiniPlayer/AudioMiniPlayer.swift

@@ -26,10 +26,12 @@ class AudioMiniPlayer: UIView, MiniPlayer {
     @IBOutlet private weak var previousButton: UIButton!
     @IBOutlet private weak var nextButton: UIButton!
 
+    private var mediaService: MediaLibraryService
     private lazy var playbackController = VLCPlaybackController.sharedInstance()
 
-    override init(frame: CGRect) {
-        super.init(frame: frame)
+    @objc init(service: MediaLibraryService) {
+        self.mediaService = service
+        super.init(frame: .zero)
         initView()
         setupConstraint()
     }
@@ -108,6 +110,14 @@ extension AudioMiniPlayer {
     func playbackPositionUpdated(_ controller: VLCPlaybackController) {
         progressBarView.progress = controller.playbackPosition
     }
+
+    func savePlaybackState(_ controller: VLCPlaybackController) {
+        mediaService.savePlaybackState(from: controller)
+    }
+
+    func media(forPlaying media: VLCMedia) -> VLCMLMedia? {
+        return mediaService.fetchMedia(with: media.url)
+    }
 }
 
 // MARK: - UI Receivers

+ 10 - 0
Sources/VLCMovieViewController.m

@@ -1093,6 +1093,16 @@ currentMediaHasTrackToChooseFrom:(BOOL)currentMediaHasTrackToChooseFrom
     _multiSelectionView.mediaHasChapters = currentMediaHasChapters;
 }
 
+- (void)savePlaybackState:(VLCPlaybackController *)controller
+{
+    [_services.medialibraryService savePlaybackStateFrom:controller];
+}
+
+- (VLCMLMedia *)mediaForPlayingMedia:(VLCMedia *)media
+{
+    return [_services.medialibraryService fetchMediaWith:media.url];
+}
+
 - (void)showStatusMessage:(NSString *)statusMessage
 {
     [self.statusLabel showStatusMessage:statusMessage];

+ 3 - 5
Sources/VLCPlaybackController+MediaLibrary.h

@@ -2,10 +2,10 @@
  * VLCPlaybackController+MediaLibrary.h
  * VLC for iOS
  *****************************************************************************
- * Copyright (c) 2015 VideoLAN. All rights reserved.
+ * Copyright (c) 2015-2019 VideoLAN. All rights reserved.
  * $Id$
  *
- * Authors: Tobias Conradi <videolan # tobias-conradi.de>
+ * Authors: Carola Nitz     <caro #videolan.org>
  *
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
@@ -13,10 +13,8 @@
 #import "VLCPlaybackController.h"
 
 @class VLCMLMedia;
-@class NSManagedObject;
 @interface VLCPlaybackController (MediaLibrary)
-- (void)playMediaLibraryObject:(NSManagedObject *)mediaObject;
+
 - (void)playMedia:(VLCMLMedia *)media;
 - (void)playMediaAtIndex:(NSInteger)index fromCollection:(NSArray<VLCMLMedia *> *)collection;
-- (void)openMediaLibraryObject:(NSManagedObject *)mediaObject;
 @end

+ 3 - 118
Sources/VLCPlaybackController+MediaLibrary.m

@@ -2,42 +2,21 @@
  * VLCPlaybackController+MediaLibrary.m
  * VLC for iOS
  *****************************************************************************
- * Copyright (c) 2015 VideoLAN. All rights reserved.
+ * Copyright (c) 2015-2019 VideoLAN. All rights reserved.
  * $Id$
  *
- * Authors: Tobias Conradi <videolan # tobias-conradi.de>
+ * Authors: Carola Nitz     <caro #videolan.org>
+ *          Tobias Conradi  <videolan # tobias-conradi.de>
  *
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
 
 #import "VLCPlaybackController+MediaLibrary.h"
-#import <CoreData/CoreData.h>
 #import <VLCMediaLibraryKit/VLCMLFile.h>
 #import <VLCMediaLibraryKit/VLCMLMedia.h>
 
 @implementation VLCPlaybackController (MediaLibrary)
 
-/*
- Open a file in the libraryViewController and toggle the playstate
-
- @param mediaObject the object that should be openend
- 
-*/
-
-- (void)playMediaLibraryObject:(NSManagedObject *)mediaObject
-{
-    self.fullscreenSessionRequested = YES;
-    if ([mediaObject isKindOfClass:[MLFile class]]) {
-        [self configureWithFile:(MLFile *)mediaObject];
-    }
-    else if ([mediaObject isKindOfClass:[MLAlbumTrack class]]) {
-        [self configureWithAlbumTrack:(MLAlbumTrack *)mediaObject];
-        self.fullscreenSessionRequested = NO;
-    }
-    else if ([mediaObject isKindOfClass:[MLShowEpisode class]])
-        [self configureWithShowEpisode:(MLShowEpisode *)mediaObject];
-}
-
 - (void)playMediaAtIndex:(NSInteger)index fromCollection:(NSArray<VLCMLMedia *> *)collection
 {
     [self configureMediaListWithMLMedia:collection indexToPlay:(int) index];
@@ -48,100 +27,6 @@
     [self configureMediaListWithMLMedia:@[media] indexToPlay:0];
 }
 
-/*
-Open a file in the libraryViewController without changing the playstate
-
-@param mediaObject the object that should be openend
-
-*/
-
-- (void)openMediaLibraryObject:(NSManagedObject *)mediaObject
-{
-    if (!self.isPlaying) {
-        //if nothing is playing start playing
-        [self playMediaLibraryObject:mediaObject];
-        return;
-    }
-    MLFile *newFile;
-    if ([mediaObject isKindOfClass:[MLAlbumTrack class]]) {
-        newFile = ((MLAlbumTrack *)mediaObject).anyFileFromTrack;
-    } else if ([mediaObject isKindOfClass:[MLShowEpisode class]]) {
-        newFile = ((MLShowEpisode *)mediaObject).anyFileFromEpisode;
-    } else if ([mediaObject isKindOfClass:[MLFile class]]) {
-        newFile = (MLFile *)mediaObject;
-    }
-
-    //if the newfile is not the currently playing one, stop and start the new one else do nothing
-    VLCMedia *currentlyPlayingFile = self.currentlyPlayingMedia;
-    MLFile *currentMLFile = [MLFile fileForURL:currentlyPlayingFile.url].firstObject;
-    if (![currentMLFile isEqual:newFile]) {
-        [self stopPlayback];
-        [self playMediaLibraryObject:mediaObject];
-    }
-}
-
-- (void)configureWithFile:(MLFile *)file
-{
-    if (file.labels.count == 0) {
-        [self configureMediaListWithFiles:@[file] indexToPlay:0];
-    } else {
-        MLLabel *folder = [file.labels anyObject];
-        NSArray *files = [folder sortedFolderItems];
-        int index = (int)[files indexOfObject:file];
-        [self configureMediaListWithFiles:files indexToPlay:index];
-    }
-}
-
-- (void)configureWithShowEpisode:(MLShowEpisode *)showEpisode
-{
-    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-    if (![defaults boolForKey:kVLCAutomaticallyPlayNextItem]) {
-        [self playMediaLibraryObject:showEpisode.files.anyObject];
-        return;
-    }
-
-    NSArray *episodes = [[showEpisode show] sortedEpisodes];
-    NSMutableArray *files = [NSMutableArray arrayWithCapacity:episodes.count];
-    for (MLShowEpisode *episode in episodes) {
-        MLFile *file = episode.files.anyObject;
-        if (file)
-            [files addObject:file];
-    }
-    int index = (int)[episodes indexOfObject:showEpisode];
-    [self configureMediaListWithFiles:files indexToPlay:index];
-}
-
-- (void)configureWithAlbumTrack:(MLAlbumTrack *)albumTrack
-{
-    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-    if (![defaults boolForKey:kVLCAutomaticallyPlayNextItem]) {
-        [self playMediaLibraryObject:albumTrack.anyFileFromTrack];
-        return;
-    }
-
-    NSArray *tracks = [[albumTrack album] sortedTracks];
-    NSMutableArray *files = [NSMutableArray arrayWithCapacity:tracks.count];
-    for (MLAlbumTrack *track in tracks) {
-        MLFile *file = track.anyFileFromTrack;
-        if (file)
-            [files addObject:file];
-    }
-    int index = (int)[tracks indexOfObject:albumTrack];
-    [self configureMediaListWithFiles:files indexToPlay:index];
-}
-
-- (void)configureMediaListWithFiles:(NSArray *)files indexToPlay:(int)index
-{
-    VLCMediaList *list = [[VLCMediaList alloc] init];
-    VLCMedia *media;
-    for (MLFile *file in files) {
-        media = [VLCMedia mediaWithURL:file.url];
-        [media addOptions:self.mediaOptionsDictionary];
-        [list addMedia:media];
-    }
-    [self configureMediaList:list atIndex:index];
-}
-
 - (void)configureMediaListWithMLMedia:(NSArray<VLCMLMedia *> *)mlMedia indexToPlay:(int)index {
     NSAssert(index >= 0, @"The index should never be negative");
     VLCMediaList *list = [[VLCMediaList alloc] init];

+ 5 - 0
Sources/VLCPlaybackController.h

@@ -25,8 +25,13 @@ extern NSString *const VLCPlaybackControllerPlaybackPositionUpdated;
 @class VLCPlaybackController;
 @class VLCMetaData;
 @class VLCDialogProvider;
+@class VLCMLMedia;
 
 @protocol VLCPlaybackControllerDelegate <NSObject>
+#if TARGET_OS_IOS
+- (void)savePlaybackState:(VLCPlaybackController *)controller;
+- (VLCMLMedia *_Nullable)mediaForPlayingMedia:(VLCMedia *)media;
+#endif
 @optional
 - (void)playbackPositionUpdated:(VLCPlaybackController *)controller;
 - (void)mediaPlayerStateChanged:(VLCMediaPlayerState)currentState

+ 40 - 134
Sources/VLCPlaybackController.m

@@ -293,7 +293,7 @@ typedef NS_ENUM(NSUInteger, VLCAspectRatio) {
         if (_mediaPlayer.media) {
             [_mediaPlayer pause];
 #if TARGET_OS_IOS
-            [self _savePlaybackState];
+            [_delegate savePlaybackState: self];
 #endif
             [_mediaPlayer stop];
         }
@@ -326,94 +326,13 @@ typedef NS_ENUM(NSUInteger, VLCAspectRatio) {
 
 - (void)restoreAudioAndSubtitleTrack
 {
-    MLFile *item = [MLFile fileForURL:_mediaPlayer.media.url].firstObject;
+    VLCMLMedia *media = [_delegate mediaForPlayingMedia:_mediaPlayer.media];
 
-    if (item) {
-        _mediaPlayer.currentAudioTrackIndex = item.lastAudioTrack.intValue;
-        _mediaPlayer.currentVideoSubTitleIndex = item.lastSubtitleTrack.intValue;
+    if (media) {
+        _mediaPlayer.currentAudioTrackIndex = (int) media.audioTrackIndex;
+        _mediaPlayer.currentVideoSubTitleIndex = (int) media.subtitleTrackIndex;
     }
 }
-
-- (void)_savePlaybackState
-{
-    @try {
-        [[MLMediaLibrary sharedMediaLibrary] save];
-    }
-    @catch (NSException *exception) {
-        APLog(@"saving playback state failed");
-    }
-
-    NSArray *files = [MLFile fileForURL:_mediaPlayer.media.url];
-    MLFile *fileItem = files.firstObject;
-
-    if (!fileItem) {
-        APLog(@"couldn't find file, not saving playback progress");
-        return;
-    }
-
-    @try {
-        float position = _mediaPlayer.position;
-        fileItem.lastPosition = @(position);
-        fileItem.lastAudioTrack = @(_mediaPlayer.currentAudioTrackIndex);
-        fileItem.lastSubtitleTrack = @(_mediaPlayer.currentVideoSubTitleIndex);
-
-        if (position > .95)
-            return;
-
-        if (_mediaPlayer.hasVideoOut) {
-            NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-            NSString *newThumbnailPath = [searchPaths.firstObject stringByAppendingPathComponent:@"VideoSnapshots"];
-            NSError *error;
-
-            [[NSFileManager defaultManager] createDirectoryAtPath:newThumbnailPath withIntermediateDirectories:YES attributes:nil error:&error];
-            if (error == nil) {
-                newThumbnailPath = [newThumbnailPath stringByAppendingPathComponent:fileItem.objectID.URIRepresentation.lastPathComponent];
-                [_mediaPlayer saveVideoSnapshotAt:newThumbnailPath withWidth:0 andHeight:0];
-                _recheckForExistingThumbnail = YES;
-                [self performSelector:@selector(_updateStoredThumbnailForFile:) withObject:fileItem afterDelay:.25];
-            }
-        }
-    }
-    @catch (NSException *exception) {
-        APLog(@"failed to save current media state - file removed?");
-    }
-}
-#endif
-
-#if TARGET_OS_IOS
-- (void)_updateStoredThumbnailForFile:(MLFile *)fileItem
-{
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-    NSString* newThumbnailPath = [searchPaths[0] stringByAppendingPathComponent:@"VideoSnapshots"];
-    newThumbnailPath = [newThumbnailPath stringByAppendingPathComponent:fileItem.objectID.URIRepresentation.lastPathComponent];
-
-    if (![fileManager fileExistsAtPath:newThumbnailPath]) {
-        if (_recheckForExistingThumbnail) {
-            [self performSelector:@selector(_updateStoredThumbnailForFile:) withObject:fileItem afterDelay:1.];
-            _recheckForExistingThumbnail = NO;
-        } else
-            return;
-    }
-
-    UIImage *newThumbnail = [UIImage imageWithContentsOfFile:newThumbnailPath];
-    if (!newThumbnail) {
-        if (_recheckForExistingThumbnail) {
-            [self performSelector:@selector(_updateStoredThumbnailForFile:) withObject:fileItem afterDelay:1.];
-            _recheckForExistingThumbnail = NO;
-        } else
-            return;
-    }
-
-    @try {
-        [fileItem setComputedThumbnailScaledForDevice:newThumbnail];
-    }
-    @catch (NSException *exception) {
-        APLog(@"updating thumbnail failed");
-    }
-
-    [fileManager removeItemAtPath:newThumbnailPath error:nil];
-}
 #endif
 
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
@@ -422,9 +341,7 @@ typedef NS_ENUM(NSUInteger, VLCAspectRatio) {
         _mediaWasJustStarted = NO;
 #if TARGET_OS_IOS
         if (self.mediaList) {
-            NSArray *matches = [MLFile fileForURL:_mediaPlayer.media.url];
-            MLFile *item = matches.firstObject;
-            [self _recoverLastPlaybackStateOfItem:item];
+            [self _recoverLastPlaybackState];
         }
 #else
         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
@@ -756,11 +673,6 @@ typedef NS_ENUM(NSUInteger, VLCAspectRatio) {
                 return;
             }
         } break;
-        case VLCMediaPlayerStateESAdded: {
-#if TARGET_OS_IOS
-            [self restoreAudioAndSubtitleTrack];
-#endif
-        } break;
         default:
             break;
     }
@@ -791,7 +703,7 @@ typedef NS_ENUM(NSUInteger, VLCAspectRatio) {
 {
     [_listPlayer pause];
 #if TARGET_OS_IOS
-    [self _savePlaybackState];
+    [_delegate savePlaybackState: self];
 #endif
     [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackControllerPlaybackDidPause object:self];
 }
@@ -1131,7 +1043,7 @@ typedef NS_ENUM(NSUInteger, VLCAspectRatio) {
         APLog(@"Pausing playback as previously connected external audio playback device was removed");
         [_mediaPlayer pause];
 #if TARGET_OS_IOS
-        [self _savePlaybackState];
+       [_delegate savePlaybackState: self];
 #endif
         [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackControllerPlaybackDidPause object:self];
     }
@@ -1173,46 +1085,40 @@ typedef NS_ENUM(NSUInteger, VLCAspectRatio) {
 }
 
 #if TARGET_OS_IOS
-- (void)_recoverLastPlaybackStateOfItem:(MLFile *)item
-{
-    if (item) {
-        CGFloat lastPosition = .0;
-        NSInteger duration = 0;
-
-        if (item.lastPosition) {
-            lastPosition = item.lastPosition.floatValue;
-        }
-        
-        duration = item.duration.intValue;
-
-        if (lastPosition < .95 && _mediaPlayer.position < lastPosition) {
-            NSInteger continuePlayback;
-            if ([item isAlbumTrack] || [item isSupportedAudioFile])
-                continuePlayback = [[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingContinueAudioPlayback] integerValue];
-            else
-                continuePlayback = [[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingContinuePlayback] integerValue];
-
-            if (continuePlayback == 1) {
-                [self setPlaybackPosition:lastPosition];
-            } else if (continuePlayback == 0) {
-                NSArray<VLCAlertButton *> *buttonsAction = @[[[VLCAlertButton alloc] initWithTitle: NSLocalizedString(@"BUTTON_CANCEL", nil)
-                                                                                             style: UIAlertActionStyleCancel
-                                                                                            action: nil],
-                                                             [[VLCAlertButton alloc] initWithTitle: NSLocalizedString(@"BUTTON_CONTINUE", nil)
-                                                                                            action: ^(UIAlertAction *action) {
-                                                                                                [self setPlaybackPosition:lastPosition];
-                                                                                            }]
-                                                             ];
-                UIViewController *presentingVC = [UIApplication sharedApplication].delegate.window.rootViewController;
-                presentingVC = presentingVC.presentedViewController ?: presentingVC;
-                [VLCAlertViewController alertViewManagerWithTitle:NSLocalizedString(@"CONTINUE_PLAYBACK", nil)
-                                                     errorMessage:[NSString stringWithFormat:NSLocalizedString(@"CONTINUE_PLAYBACK_LONG", nil), item.title]
-                                                   viewController:presentingVC
-                                                    buttonsAction:buttonsAction];
+- (void)_recoverLastPlaybackState
+{
+    VLCMLMedia *media = [_delegate mediaForPlayingMedia:_mediaPlayer.media];
+    if (!media) return;
+
+    CGFloat lastPosition = media.progress;
+    if (_mediaPlayer.position < lastPosition) {
+        NSInteger continuePlayback;
+        if (media.type == VLCMLMediaTypeAudio)
+            continuePlayback = [[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingContinueAudioPlayback] integerValue];
+        else
+            continuePlayback = [[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingContinuePlayback] integerValue];
+
+        if (continuePlayback == 1) {
+            [self setPlaybackPosition:lastPosition];
+        } else if (continuePlayback == 0) {
+            NSArray<VLCAlertButton *> *buttonsAction = @[[[VLCAlertButton alloc] initWithTitle: NSLocalizedString(@"BUTTON_CANCEL", nil)
+                                                                                         style: UIAlertActionStyleCancel
+                                                                                        action: nil],
+                                                         [[VLCAlertButton alloc] initWithTitle: NSLocalizedString(@"BUTTON_CONTINUE", nil)
+                                                                                        action: ^(UIAlertAction *action) {
+                                                                                            [self setPlaybackPosition:lastPosition];
+                                                                                        }]
+                                                         ];
+            UIViewController *presentingVC = [UIApplication sharedApplication].delegate.window.rootViewController;
+            presentingVC = presentingVC.presentedViewController ?: presentingVC;
+            [VLCAlertViewController alertViewManagerWithTitle:NSLocalizedString(@"CONTINUE_PLAYBACK", nil)
+                                                 errorMessage:[NSString stringWithFormat:NSLocalizedString(@"CONTINUE_PLAYBACK_LONG", nil), media.title]
+                                               viewController:presentingVC
+                                                buttonsAction:buttonsAction];
 
-            }
         }
     }
+    [self restoreAudioAndSubtitleTrack];
 }
 #endif
 
@@ -1253,7 +1159,7 @@ typedef NS_ENUM(NSUInteger, VLCAspectRatio) {
 - (void)applicationWillResignActive:(NSNotification *)aNotification
 {
 #if TARGET_OS_IOS
-    [self _savePlaybackState];
+    [_delegate savePlaybackState: self];
 #endif
     if (![self isPlayingOnExternalScreen]
         && ![[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingContinueAudioInBackgroundKey] boolValue]) {

+ 1 - 1
Sources/VLCPlayerDisplayController.m

@@ -275,7 +275,7 @@ static NSString *const VLCPlayerDisplayControllerDisplayModeKey = @"VLCPlayerDis
     if (needsShow) {
         if (!miniPlaybackView) {
             // Until VideoMiniPlayer is integrated, only AudioMiniPlayer is used.
-            self.miniPlaybackView = miniPlaybackView = [[VLCAudioMiniPlayer alloc] initWithFrame:CGRectZero];
+            self.miniPlaybackView = miniPlaybackView = [[VLCAudioMiniPlayer alloc] initWithService:_services.medialibraryService];
             miniPlaybackView.translatesAutoresizingMaskIntoConstraints = NO;
             miniPlaybackView.userInteractionEnabled = YES;
             [self.view addSubview:miniPlaybackView];

+ 1 - 1
Sources/VLCThumbnailsCache.h

@@ -11,7 +11,7 @@
  *
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
-
+@class NSManagedObject;
 @interface VLCThumbnailsCache : NSObject
 
 + (UIImage *)thumbnailForManagedObject:(NSManagedObject *)object;

+ 0 - 6
VLC.xcodeproj/project.pbxproj

@@ -361,7 +361,6 @@
 		DD490B171BE6BA580010F335 /* VLCIRTVTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = DD490B161BE6BA580010F335 /* VLCIRTVTapGestureRecognizer.m */; };
 		DD490B1F1BE95B5C0010F335 /* VLCSiriRemoteGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = DD490B1E1BE95B5C0010F335 /* VLCSiriRemoteGestureRecognizer.m */; };
 		DD510B701B14E564003BA71C /* VLCPlayerDisplayController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD510B6F1B14E564003BA71C /* VLCPlayerDisplayController.m */; };
-		DD7110F01AF38B2B00854776 /* MLMediaLibrary+playlist.m in Sources */ = {isa = PBXBuildFile; fileRef = DD7110EF1AF38B2B00854776 /* MLMediaLibrary+playlist.m */; };
 		DD8095D61BE3C3BA0065D8E1 /* VLCTransportBar.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8095D51BE3C3BA0065D8E1 /* VLCTransportBar.m */; };
 		DD8095DB1BE3C42F0065D8E1 /* VLCBufferingBar.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8095DA1BE3C42F0065D8E1 /* VLCBufferingBar.m */; };
 		DD8095E01BE3EFC20065D8E1 /* VLCPlaybackInfoTVViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8095DE1BE3EFC20065D8E1 /* VLCPlaybackInfoTVViewController.m */; };
@@ -979,8 +978,6 @@
 		DD490B1E1BE95B5C0010F335 /* VLCSiriRemoteGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCSiriRemoteGestureRecognizer.m; sourceTree = "<group>"; };
 		DD510B6E1B14E564003BA71C /* VLCPlayerDisplayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCPlayerDisplayController.h; path = Sources/VLCPlayerDisplayController.h; sourceTree = SOURCE_ROOT; };
 		DD510B6F1B14E564003BA71C /* VLCPlayerDisplayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCPlayerDisplayController.m; path = Sources/VLCPlayerDisplayController.m; sourceTree = SOURCE_ROOT; };
-		DD7110EE1AF38B2B00854776 /* MLMediaLibrary+playlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MLMediaLibrary+playlist.h"; sourceTree = "<group>"; };
-		DD7110EF1AF38B2B00854776 /* MLMediaLibrary+playlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MLMediaLibrary+playlist.m"; sourceTree = "<group>"; };
 		DD8095D41BE3C3BA0065D8E1 /* VLCTransportBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCTransportBar.h; sourceTree = "<group>"; };
 		DD8095D51BE3C3BA0065D8E1 /* VLCTransportBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCTransportBar.m; sourceTree = "<group>"; };
 		DD8095D91BE3C42F0065D8E1 /* VLCBufferingBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCBufferingBar.h; sourceTree = "<group>"; };
@@ -1732,8 +1729,6 @@
 				8DE1887221089AF200A091D2 /* MediaLibraryModel */,
 				7D37849C183A98DD009EE944 /* VLCThumbnailsCache.h */,
 				7D37849D183A98DD009EE944 /* VLCThumbnailsCache.m */,
-				DD7110EE1AF38B2B00854776 /* MLMediaLibrary+playlist.h */,
-				DD7110EF1AF38B2B00854776 /* MLMediaLibrary+playlist.m */,
 				8D66A47220AC61B900FA5B92 /* MediaLibraryService.swift */,
 			);
 			name = Library;
@@ -2968,7 +2963,6 @@
 				7DE56C1A1AD93F9100E8CA00 /* VLCPlaybackController.m in Sources */,
 				4152F1621FEF19BD00F1908B /* KeychainCoordinator.swift in Sources */,
 				41884A50214BE0D800D2C6B4 /* MediaCollectionViewCell.swift in Sources */,
-				DD7110F01AF38B2B00854776 /* MLMediaLibrary+playlist.m in Sources */,
 				7D5CAA891A4AD763003F2CBC /* VLCTrackSelectorTableViewCell.m in Sources */,
 				7D63C19018774B1700BD5256 /* VLCFirstStepsSecondPageViewController.m in Sources */,
 				8F91EC79195CEC7900F5BCBA /* VLCOpenInActivity.m in Sources */,