VLCMetadata.m 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. self.trackNumber = nil;
  24. self.title = @"";
  25. self.artist = @"";
  26. self.albumName = @"";
  27. self.artworkImage = nil;
  28. self.isAudioOnly = NO;
  29. }
  30. return self;
  31. }
  32. #if TARGET_OS_TV
  33. - (void)updateMetadataFromMediaPlayer:(VLCMediaPlayer *)mediaPlayer;
  34. {
  35. [self updateMetadataFromMediaPlayerFortvOS:mediaPlayer];
  36. }
  37. #endif
  38. #if TARGET_OS_IOS
  39. - (void)updateMetadataFromMedia:(VLCMLMedia *)media mediaPlayer:(VLCMediaPlayer*)mediaPlayer
  40. {
  41. if (media) {
  42. self.title = media.title;
  43. self.artist = media.albumTrack.artist.name;
  44. self.trackNumber = @(media.albumTrack.trackNumber);
  45. self.albumName = media.albumTrack.album.title;
  46. self.artworkImage = [media thumbnailImage];
  47. self.isAudioOnly = [media subtype] == VLCMLMediaSubtypeAlbumTrack;
  48. } else { // We're streaming something
  49. self.artworkImage = nil;
  50. self.trackNumber = nil;
  51. self.artist = nil;
  52. self.albumName = nil;
  53. [self fillFromMetaDict:mediaPlayer];
  54. self.title = [[mediaPlayer.media url] lastPathComponent];
  55. }
  56. [self updatePlaybackRate:mediaPlayer];
  57. //Down here because we still need to populate the miniplayer
  58. if ([VLCKeychainCoordinator passcodeLockEnabled]) return;
  59. [self populateInfoCenterFromMetadata];
  60. }
  61. #else
  62. - (void)updateMetadataFromMediaPlayerFortvOS:(VLCMediaPlayer *)mediaPlayer
  63. {
  64. [self fillFromMetaDict:mediaPlayer];
  65. [self checkIsAudioOnly:mediaPlayer];
  66. if (self.isAudioOnly) {
  67. if (self.title.length < 1)
  68. self.title = [[mediaPlayer.media url] lastPathComponent];
  69. }
  70. [self updatePlaybackRate:mediaPlayer];
  71. [self populateInfoCenterFromMetadata];
  72. }
  73. #endif
  74. - (void)updatePlaybackRate:(VLCMediaPlayer *)mediaPlayer
  75. {
  76. self.playbackDuration = @(mediaPlayer.media.length.intValue / 1000.);
  77. self.playbackRate = @(mediaPlayer.rate);
  78. self.elapsedPlaybackTime = @(mediaPlayer.time.value.floatValue / 1000.);
  79. [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackControllerPlaybackMetadataDidChange object:self];
  80. }
  81. - (void)checkIsAudioOnly:(VLCMediaPlayer *)mediaPlayer
  82. {
  83. if (!self.isAudioOnly) {
  84. /* either what we are playing is not a file known to MLKit or
  85. * MLKit fails to acknowledge that it is audio-only.
  86. * Either way, do a more expensive check to see if it is really audio-only */
  87. NSArray *tracks = mediaPlayer.media.tracksInformation;
  88. NSUInteger trackCount = tracks.count;
  89. self.isAudioOnly = YES;
  90. for (NSUInteger x = 0 ; x < trackCount; x++) {
  91. if ([[tracks[x] objectForKey:VLCMediaTracksInformationType] isEqualToString:VLCMediaTracksInformationTypeVideo]) {
  92. self.isAudioOnly = NO;
  93. break;
  94. }
  95. }
  96. }
  97. }
  98. - (void)fillFromMetaDict:(VLCMediaPlayer *)mediaPlayer
  99. {
  100. NSDictionary *metaDict = mediaPlayer.media.metaDictionary;
  101. if (metaDict) {
  102. self.title = metaDict[VLCMetaInformationNowPlaying] ?: metaDict[VLCMetaInformationTitle];
  103. self.artist = metaDict[VLCMetaInformationArtist];
  104. self.albumName = metaDict[VLCMetaInformationAlbum];
  105. self.trackNumber = metaDict[VLCMetaInformationTrackNumber];
  106. }
  107. }
  108. - (void)populateInfoCenterFromMetadata
  109. {
  110. NSMutableDictionary *currentlyPlayingTrackInfo = [NSMutableDictionary dictionary];
  111. currentlyPlayingTrackInfo[MPMediaItemPropertyPlaybackDuration] = self.playbackDuration;
  112. currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = self.elapsedPlaybackTime;
  113. currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyPlaybackRate] = self.playbackRate;
  114. currentlyPlayingTrackInfo[MPMediaItemPropertyTitle] = self.title;
  115. currentlyPlayingTrackInfo[MPMediaItemPropertyArtist] = self.artist;
  116. currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTitle] = self.albumName;
  117. if ([self.trackNumber intValue] > 0)
  118. currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTrackNumber] = self.trackNumber;
  119. #if TARGET_OS_IOS
  120. if (self.artworkImage) {
  121. MPMediaItemArtwork *mpartwork = [[MPMediaItemArtwork alloc] initWithImage:self.artworkImage];
  122. currentlyPlayingTrackInfo[MPMediaItemPropertyArtwork] = mpartwork;
  123. }
  124. #endif
  125. [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = currentlyPlayingTrackInfo;
  126. }
  127. @end