VLCMetadata.m 5.43 KB
Newer Older
1 2 3
/*****************************************************************************
 * VLC for iOS
 *****************************************************************************
4
 * Copyright (c) 2017-2018 VideoLAN. All rights reserved.
5 6 7 8 9 10
 * $Id$
 *
 * Authors: Carola Nitz <caro # videolan.org>
 *
 * Refer to the COPYING file of the official project for license.
 *****************************************************************************/
11 12 13 14 15 16

#import "VLCMetadata.h"
#import <MediaPlayer/MediaPlayer.h>
#import "VLCPlaybackController.h"

#if TARGET_OS_IOS
17
#import "VLC-Swift.h"
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#import "VLCThumbnailsCache.h"
#endif

@implementation VLCMetaData

- (instancetype)init
{
    self = [super init];
    if (self) {
    }
    return self;
}

- (void)updateMetadataFromMediaPlayer:(VLCMediaPlayer *)mediaPlayer;
{
33 34 35 36 37 38
    self.trackNumber = nil;
    self.title = @"";
    self.artist = @"";
    self.albumName = @"";
    self.artworkImage = nil;
    self.isAudioOnly = NO;
39 40 41 42 43 44 45 46 47 48 49
#if TARGET_OS_IOS
    [self updateMetadataFromMediaPlayerForiOS:mediaPlayer];
#else
    [self updateMetadataFromMediaPlayerFortvOS:mediaPlayer];
#endif
}

#if TARGET_OS_IOS
- (void)updateMetadataFromMediaPlayerForiOS:(VLCMediaPlayer *)mediaPlayer
{
    MLFile *item;
50

51
    if ([VLCPlaybackController sharedInstance].mediaList) {
52
        item = [MLFile fileForURL:mediaPlayer.media.url].firstObject;
53 54 55 56 57 58 59 60 61 62 63 64 65
    }

    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 {
66 67 68 69
        [self fillFromMetaDict:mediaPlayer];
    }

    [self checkIsAudioOnly:mediaPlayer];
70

71 72 73 74 75 76 77 78
    if (self.isAudioOnly) {
        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];
79
        }
80 81
        if (self.title.length < 1)
            self.title = [[mediaPlayer.media url] lastPathComponent];
82
    }
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    [self updatePlaybackRate:mediaPlayer];

    if ([VLCKeychainCoordinator passcodeLockEnabled]) return;

    [self populateInfoCenterFromMetadata];
}
#else

- (void)updateMetadataFromMediaPlayerFortvOS:(VLCMediaPlayer *)mediaPlayer
{
    [self fillFromMetaDict:mediaPlayer];
    [self checkIsAudioOnly:mediaPlayer];

    if (self.isAudioOnly) {
        if (self.title.length < 1)
            self.title = [[mediaPlayer.media url] lastPathComponent];
    }
    [self updatePlaybackRate:mediaPlayer];
    [self populateInfoCenterFromMetadata];
}
103
#endif
104 105 106 107 108 109 110
- (void)updatePlaybackRate:(VLCMediaPlayer *)mediaPlayer
{
    self.playbackDuration = @(mediaPlayer.media.length.intValue / 1000.);
    self.playbackRate = @(mediaPlayer.rate);
    self.elapsedPlaybackTime = @(mediaPlayer.time.value.floatValue / 1000.);
    [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackControllerPlaybackMetadataDidChange object:self];
}
111

112 113
- (void)checkIsAudioOnly:(VLCMediaPlayer *)mediaPlayer
{
114 115 116 117 118 119 120 121 122 123 124 125 126 127
    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;
            }
        }
    }
128
}
129

130 131 132
- (void)fillFromMetaDict:(VLCMediaPlayer *)mediaPlayer
{
    NSDictionary *metaDict = mediaPlayer.media.metaDictionary;
133

134 135 136 137 138
    if (metaDict) {
        self.title = metaDict[VLCMetaInformationNowPlaying] ?: metaDict[VLCMetaInformationTitle];
        self.artist = metaDict[VLCMetaInformationArtist];
        self.albumName = metaDict[VLCMetaInformationAlbum];
        self.trackNumber = metaDict[VLCMetaInformationTrackNumber];
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    }
}

- (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