rugdealer rugdealer - 10 months ago 58
Swift Question

How to add Navigation Markers as Chapters for my video in tvOS?


I'm trying to understand (the madness) on how to add navigation markers to my video in tvOS.

Logically it shouldn't be complicated. Specify a list of markers with a chapter starting point, a chapter title, and a thumbnail for that specific video point.

However, I'm having a hard time grasping how to implement this.

What I've tried:

This is what I believe is the minimum for this to be implemented, however I have no idea why I need all this for it to work. I also have no idea how I'm supposed to set the information.

//In my AVPlayerViewController
let metadataItem = AVMetadataItem()

let metadataItemList = [metadataItem]

let cmTimeStart = CMTimeMake(0, 0)
let cmTimeDuration = CMTimeMake(10, 1)

let timeRange = CMTimeRange(start: cmTimeStart, duration: cmTimeDuration)

let timedMetadataGroup = AVTimedMetadataGroup(items: metadataItemList, timeRange: timeRange)
let timedMetadataGroupList = [timedMetadataGroup]
let navigationMarkersGroup = AVNavigationMarkersGroup(title: "Chapters", timedNavigationMarkers: timedMetadataGroupList)

//Already previously initialized avPlayerItem

(The goal with the code above is to have one chapter shown for my video.)


I'm seeking clarity on how to implement the Navigation Markers as "Chapters" in my video in tvOS. A detailed explanation on what each part is supposed to accomplish would equally be very helpful.

Answer Source


To be able to add chapters the concept isn't as complicated as I had originally thought. You'll need to use the following main classes:

  • AVMetadataItem
  • AVMutableMetadataItem
  • AVTimedMetadataGroup
  • AVNavigationMarkersGroup

Part 1: Creating a chapter generating method

To simplify the work, we'll create a method that generates a "chapter" or as you'll see a AVTimedMetadataGroup that consists of a title, a description, and a start time.

The main issue I had was that in Swift2 we could specify the identifier type directly with AVMetadataItem (EDIT: This is factually wrong, in their examples they created a custom class called AVMettadataItem that used AVMutableMetadataItem to generate what they wanted) which isn't possible anymore with Swift3. However, this can be solved with AVMutableMetadataItem

For example this is how we create a AVMutableMetadataItem for the title of the chapter:

let titleItem =  AVMutableMetadataItem()
titleItem.identifier = AVMetadataCommonIdentifierTitle
titleItem.value = title as (NSCopying & NSObjectProtocol)?

Each of these items needs to be added to a list that we'll call "items" ( [AVMetadataItem] )

Once your list is completed, you'll want to create the AVTimedMetadataGroup with the list you just created and the timeRange that will be applied to your video (aka: Where you chapter will start and how long it lasts)

In my case, chapter duration isn't a big deal so I set it to a fixed time (10 seconds).

The thing that you need to watch out for is, if the CMTime is not valid, the chapter does not show up in the list.

private func setupNavigationMarker(title: String, description: String, timeStart: Int64)-> AVTimedMetadataGroup {

    let timeRange = CMTimeRange(start: CMTimeMake(timeStart, 1), duration: CMTimeMake(10, 1))

    var items: [AVMetadataItem] = []
    let titleItem =  AVMutableMetadataItem()
    titleItem.identifier = AVMetadataCommonIdentifierTitle
    titleItem.value = title as (NSCopying & NSObjectProtocol)?

    let descriptionItem = AVMutableMetadataItem()
    descriptionItem.identifier = AVMetadataCommonIdentifierDescription
    descriptionItem.value = description as (NSCopying & NSObjectProtocol)?

    return AVTimedMetadataGroup(items: items, timeRange: timeRange)


Part 2: Add your chapter to your AVNavigationMarkerGroup

Then somewhere in your AVPlayerViewController (like ViewDidLoad):

var timedMetadataGroupList = [AVTimedMetadataGroup]()

timedMetadataGroupList.append(self.setupNavigationMarker(title: "test1", description: "description test1" , timeStart: 100))
timedMetadataGroupList.append(self.setupNavigationMarker(title: "test2", description: "description test2" , timeStart: 200))
timedMetadataGroupList.append(self.setupNavigationMarker(title: "test3", description: "description test3" , timeStart: 300))

let navigationMarkersGroup = AVNavigationMarkersGroup(title: "Chapters", timedNavigationMarkers: timedMetadataGroupList)


Part 3: Add images to your chapters

Coming soon...