VLCMetadata.m 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*****************************************************************************
  2. * VLC for iOS
  3. *****************************************************************************
  4. * Copyright (c) 2017-2018 VideoLAN. All rights reserved.
  5. * $Id$
  6. *
  7. * Authors: Carola Nitz <caro # videolan.org>
  8. *
  9. * Refer to the COPYING file of the official project for license.
  10. *****************************************************************************/
  11. #import "VLCMetadata.h"
  12. #import <MediaPlayer/MediaPlayer.h>
  13. #import "VLCPlaybackController.h"
  14. #if TARGET_OS_IOS
  15. #import "VLC-Swift.h"
  16. #import "VLCThumbnailsCache.h"
  17. #endif
  18. @implementation VLCMetaData
  19. - (instancetype)init
  20. {
  21. self = [super init];
  22. if (self) {
  23. }
  24. return self;
  25. }
  26. - (void)updateMetadataFromMediaPlayer:(VLCMediaPlayer *)mediaPlayer;
  27. {
  28. self.trackNumber = nil;
  29. self.title = @"";
  30. self.artist = @"";
  31. self.albumName = @"";
  32. self.artworkImage = nil;
  33. self.isAudioOnly = NO;
  34. #if TARGET_OS_IOS
  35. [self updateMetadataFromMediaPlayerForiOS:mediaPlayer];
  36. #else
  37. [self updateMetadataFromMediaPlayerFortvOS:mediaPlayer];
  38. #endif
  39. }
  40. #if TARGET_OS_IOS
  41. - (void)updateMetadataFromMediaPlayerForiOS:(VLCMediaPlayer *)mediaPlayer
  42. {
  43. MLFile *item;
  44. if ([VLCPlaybackController sharedInstance].mediaList) {
  45. item = [MLFile fileForURL:mediaPlayer.media.url].firstObject;
  46. }
  47. if (item) {
  48. if (item.isAlbumTrack) {
  49. self.title = item.albumTrack.title;
  50. self.artist = item.albumTrack.artist;
  51. self.albumName = item.albumTrack.album.name;
  52. } else
  53. self.title = item.title;
  54. /* MLKit knows better than us if this thing is audio only or not */
  55. self.isAudioOnly = [item isSupportedAudioFile];
  56. } else {
  57. [self fillFromMetaDict:mediaPlayer];
  58. }
  59. [self checkIsAudioOnly:mediaPlayer];
  60. if (self.isAudioOnly) {
  61. self.artworkImage = [VLCThumbnailsCache thumbnailForManagedObject:item];
  62. if (self.artworkImage) {
  63. if (self.artist)
  64. self.title = [self.title stringByAppendingFormat:@" — %@", self.artist];
  65. if (self.albumName)
  66. self.title = [self.title stringByAppendingFormat:@" — %@", self.albumName];
  67. }
  68. if (self.title.length < 1)
  69. self.title = [[mediaPlayer.media url] lastPathComponent];
  70. }
  71. [self updatePlaybackRate:mediaPlayer];
  72. if ([VLCKeychainCoordinator passcodeLockEnabled]) return;
  73. [self populateInfoCenterFromMetadata];
  74. }
  75. #else
  76. - (void)updateMetadataFromMediaPlayerFortvOS:(VLCMediaPlayer *)mediaPlayer
  77. {
  78. [self fillFromMetaDict:mediaPlayer];
  79. [self checkIsAudioOnly:mediaPlayer];
  80. if (self.isAudioOnly) {
  81. if (self.title.length < 1)
  82. self.title = [[mediaPlayer.media url] lastPathComponent];
  83. }
  84. [self updatePlaybackRate:mediaPlayer];
  85. [self populateInfoCenterFromMetadata];
  86. }
  87. #endif
  88. - (void)updatePlaybackRate:(VLCMediaPlayer *)mediaPlayer
  89. {
  90. self.playbackDuration = @(mediaPlayer.media.length.intValue / 1000.);
  91. self.playbackRate = @(mediaPlayer.rate);
  92. self.elapsedPlaybackTime = @(mediaPlayer.time.value.floatValue / 1000.);
  93. [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackControllerPlaybackMetadataDidChange object:self];
  94. }
  95. - (void)checkIsAudioOnly:(VLCMediaPlayer *)mediaPlayer
  96. {
  97. if (!self.isAudioOnly) {
  98. /* either what we are playing is not a file known to MLKit or
  99. * MLKit fails to acknowledge that it is audio-only.
  100. * Either way, do a more expensive check to see if it is really audio-only */
  101. NSArray *tracks = mediaPlayer.media.tracksInformation;
  102. NSUInteger trackCount = tracks.count;
  103. self.isAudioOnly = YES;
  104. for (NSUInteger x = 0 ; x < trackCount; x++) {
  105. if ([[tracks[x] objectForKey:VLCMediaTracksInformationType] isEqualToString:VLCMediaTracksInformationTypeVideo]) {
  106. self.isAudioOnly = NO;
  107. break;
  108. }
  109. }
  110. }
  111. }
  112. - (void)fillFromMetaDict:(VLCMediaPlayer *)mediaPlayer
  113. {
  114. NSDictionary *metaDict = mediaPlayer.media.metaDictionary;
  115. if (metaDict) {
  116. self.title = metaDict[VLCMetaInformationNowPlaying] ?: metaDict[VLCMetaInformationTitle];
  117. self.artist = metaDict[VLCMetaInformationArtist];
  118. self.albumName = metaDict[VLCMetaInformationAlbum];
  119. self.trackNumber = metaDict[VLCMetaInformationTrackNumber];
  120. }
  121. }
  122. - (void)populateInfoCenterFromMetadata
  123. {
  124. NSMutableDictionary *currentlyPlayingTrackInfo = [NSMutableDictionary dictionary];
  125. currentlyPlayingTrackInfo[MPMediaItemPropertyPlaybackDuration] = self.playbackDuration;
  126. currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = self.elapsedPlaybackTime;
  127. currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyPlaybackRate] = self.playbackRate;
  128. currentlyPlayingTrackInfo[MPMediaItemPropertyTitle] = self.title;
  129. currentlyPlayingTrackInfo[MPMediaItemPropertyArtist] = self.artist;
  130. currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTitle] = self.albumName;
  131. if ([self.trackNumber intValue] > 0)
  132. currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTrackNumber] = self.trackNumber;
  133. #if TARGET_OS_IOS
  134. if (self.artworkImage) {
  135. MPMediaItemArtwork *mpartwork = [[MPMediaItemArtwork alloc] initWithImage:self.artworkImage];
  136. currentlyPlayingTrackInfo[MPMediaItemPropertyArtwork] = mpartwork;
  137. }
  138. #endif
  139. [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = currentlyPlayingTrackInfo;
  140. }
  141. @end