11

In the built in apps for tvOS when you watch a video it shows information about that video when you swipe down. I can't find any information on how a developer can do this same thing. I'm sure it is designed to be possible as it says "Swipe down for info" Has anybody figured this out? I'm using AVPlayerViewController. Thanks.

Brian F Leighty
  • 922
  • 11
  • 22
  • If you check the logs, when the "info" view is appearing after you swipe down, a warning appears : Presenting view controllers on detached view controllers is discouraged . So it seems that they are using a detached view controller ! – Sylverb Oct 27 '15 at 13:51
  • I can't get the "Info" section to appear of that "swipe down" pane to appear. It only shows the "Audio" section. For each of my `AVPlayerItem`s I'm appending `AVMutableMetadataItem`s to the `externalMetadata` array but it still doesn't show up. Apple says it's possible here: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVPlayerViewController_Class/ under "External Metadata". See also https://developer.apple.com/library/prerelease/tvos/documentation/AVFoundation/Reference/AVPlayerItem_Class/index.html#//apple_ref/occ/instp/AVPlayerItem/externalMetadata – Jeff Bowen Oct 27 '15 at 22:45
  • Figured it out. See my answer. – Jeff Bowen Oct 28 '15 at 14:50

5 Answers5

18

To get the "Info" section to show up in the "Swipe down for info" pane in AVPlayerViewController you create AVMutableMetadataItems with the AVMetadataKeySpaceCommon keyspace and any of the following keys:

AVMetadataCommonKeyTitle
AVMetadataCommonKeyDescription
AVMetadataiTunesMetadataKeyContentRating
AVMetadataQuickTimeMetadataKeyGenre

and add them to the AVPlayerItem's externalMetadata array. In order for each AVMutableMetadataItem to show up you must at least set the identifier, extendedLanguageTag, and value properties. Here's an example:

let mediaItem = AVPlayerItem(URL: mediaURL)

let titleMetadataItem = AVMutableMetadataItem()
titleMetadataItem.locale = NSLocale.currentLocale()
titleMetadataItem.key = AVMetadataCommonKeyTitle
titleMetadataItem.keySpace = AVMetadataKeySpaceCommon
titleMetadataItem.value = "The Title"

let descriptionMetadataItem = AVMutableMetadataItem()
descriptionMetadataItem.locale = NSLocale.currentLocale()
descriptionMetadataItem.key = AVMetadataCommonKeyDescription
descriptionMetadataItem.keySpace = AVMetadataKeySpaceCommon
descriptionMetadataItem.value = "This is the description"

mediaItem.externalMetadata.append(titleMetadataItem)
mediaItem.externalMetadata.append(descriptionMetadataItem)

This isn't well-documented. This forum post was critical to figuring this out.


Objective-C example for @JenelEjercitoMyers:

AVPlayerItem *mediaItem = [[AVPlayerItem alloc] initWithURL:mediaURL];

AVMutableMetadataItem *titleMetadataItem = [[AVMutableMetadataItem alloc] init];
titleMetadataItem.locale = NSLocale.currentLocale;
titleMetadataItem.key = AVMetadataCommonKeyTitle;  
titleMetadataItem.keySpace = AVMetadataKeySpaceCommon;  
titleMetadataItem.value = @"The Title";

NSArray *externalMetadata = [[NSArray alloc] initWithObjects:titleMetadataItem, nil];

mediaItem.externalMetadata = externalMetadata;
Jeff Bowen
  • 5,904
  • 1
  • 28
  • 41
  • Thanks. couldn't find how to do this anywhere. Thanks for sharing. – Brian F Leighty Oct 29 '15 at 12:46
  • No problem, @BrianFLeighty. Glad to help. I had the same question. – Jeff Bowen Oct 29 '15 at 13:38
  • I am having an issue where the "info"/metadata fades out after it loads on the "Swipe down for info" view. Any idea what would do that? – Serenade X Nov 10 '15 at 21:28
  • @SerenadeX, I believe it's a bug with the Simulator. I see the same thing. However, testing on an actual device, I don't have that problem. – Jeff Bowen Nov 11 '15 at 05:27
  • could you write this example in objective c pleaaaseee @JeffBowen (: – Jenel Ejercito Myers Nov 12 '15 at 17:59
  • Added an Objective-C example, @JenelEjercitoMyers. – Jeff Bowen Nov 12 '15 at 19:35
  • @JeffBowen thank you! I am getting an error no visible interface for NSArray declares the selector 'addObject'? when dispolaying the movie, I use _player.player = [AVPlayer playerWithURL:[NSURL URLWithString:mediaURL]]; so in the last part of the code I did : [_player.player.currentItem.externalMetadata addObject:titleMetadataItem]; (to grab the instance of the current AVPlayerItem. Could you please tell me what I am doing wrong? (: – Jenel Ejercito Myers Nov 12 '15 at 19:50
  • Updated my example, @JenelEjercitoMyers. Sorry, haven't done Objective-C in a while. – Jeff Bowen Nov 12 '15 at 20:04
  • @JeffBowen mahalo nui loa for the answer! It worked (: – Jenel Ejercito Myers Nov 12 '15 at 20:10
  • @JenelEjercitoMyers, glad to hear it! – Jeff Bowen Nov 12 '15 at 20:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/94974/discussion-between-jenel-ejercito-myers-and-jeff-bowen). – Jenel Ejercito Myers Nov 12 '15 at 20:39
  • I'm getting this compilation error: "Property 'externalMetadata' not found on object of type 'AVPlayerItem *' - Using tvOS 9.1 with the very latest XCode 7.2. Any ideas? – Luis Artola Dec 14 '15 at 08:35
  • @LuisArtola, are you certain your target is tvOS? I saw this error when I first tried to access `externalMetadata` in my iOS target. – Jeff Bowen Dec 14 '15 at 18:46
  • @JeffBowen yeap, it's tvos, it's running on an actual Apple TV. I got it to compile but not to work completely. I discovered that just by importing modules does not automatically link the right frameworks. I had to do @@import AVKit AND still add AVKit frawework in project settings. Now it compiles and runs. But, when I swipe down on the remote my custom title and description do not show up. – Luis Artola Dec 15 '15 at 14:19
  • What is the purpose of AVMetadataQuickTimeMetadataKeyGenre? – Ruchi Jul 04 '16 at 12:38
2

The accepted answer is correct. We can use AVMutableMetadataItem to provide video related information.

But if you need to have more options in player menu, it is better to create a UIViewController with custom information and settings option [based on your requirement] and set it as AVPlayerViewController's customInfoViewController.

This is available from tvOS 11.0

enter image description here

Official apple docs on this: Apple Docs Link

abhimuralidharan
  • 5,752
  • 5
  • 46
  • 70
1

In addition to Jeff's answer, this is the function I use to avoid repetivity:

private func setupMetadata(data: String, key: (NSCopying & NSObjectProtocol))->AVMutableMetadataItem{

    let metadataItem = AVMutableMetadataItem()
    metadataItem.locale = NSLocale.current
    metadataItem.key = key
    metadataItem.keySpace = AVMetadataKeySpaceCommon
    metadataItem.value = data as (NSCopying & NSObjectProtocol)?

    return metadataItem

}

and in use:

    //in AVPlayerViewControler
    //Suppose you have an already initialized avPlayerItem
    avPlayerItem.externalMetadata.append(self.setupMetadata(data: "title of video", key: AVMetadataCommonKeyTitle as (NSCopying & NSObjectProtocol)))
    avPlayerItem.externalMetadata.append(self.setupMetadata(data: "RugDealer", key: AVMetadataCommonKeyAuthor as (NSCopying & NSObjectProtocol)))
    avPlayerItem.externalMetadata.append(self.setupMetadata(data: "Description of the video", key: AVMetadataCommonKeyDescription as (NSCopying & NSObjectProtocol)))
kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131
1

In addition to the above answers, I also wanted to add artwork, genres and content rating to the top shelf. This being slightly different from whats mentioned. They can be added as follows to the externalMetadata array.

//Sets the content rating on the top shelf
AVMutableMetadataItem *ratingInfo = [[AVMutableMetadataItem alloc] init];
ratingInfo.key = AVMetadataiTunesMetadataKeyContentRating;
ratingInfo.keySpace = AVMetadataKeySpaceiTunes;
ratingInfo.locale = [NSLocale currentLocale];
ratingInfo.value = @"PG-13"; //Rating of the video
ratingInfo.extendedLanguageTag = @"und";
[externalMetadata addObject:ratingInfo];

//Sets the thumbnail on the shelf
AVMutableMetadataItem *artwork1 = [[AVMutableMetadataItem alloc] init];
artwork1.key = AVMetadataCommonKeyArtwork;
artwork1.keySpace = AVMetadataKeySpaceCommon;
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:artworkAddress]];
artwork1.value = imageData;
artwork1.locale = [NSLocale currentLocale];
[externalMetadata addObject:artwork1];

//Sets the Genre on the shelf
AVMutableMetadataItem *genresInfo = [[AVMutableMetadataItem alloc] init];
genresInfo.key = AVMetadataQuickTimeMetadataKeyGenre;
genresInfo.keySpace = AVMetadataKeySpaceQuickTimeMetadata;
genresInfo.locale = [NSLocale currentLocale];
genresInfo.value = @"Drama, Medical";
[externalMetadata addObject:genresInfo];
Vinay Kini
  • 41
  • 1
  • Careful using dataWithContentsOfURL since that's a synchronous call – Brian F Leighty Jan 26 '17 at 15:06
  • Thanks @BrianFLeighty, hadn't taken that into consideration. This can cause issues with high quality images. But most likely these artwork are smaller in size. Thanks though. – Vinay Kini Jan 30 '17 at 20:19
0

FYI, I couldn't get this to show up on a simulator running tvOS 12.2 or 13 (beta). What finally got it working was adding metadataItem.locale = NSLocale.current. Comment that out, it doesn't appear.

Tim Schmidt
  • 1,855
  • 3
  • 21
  • 21