1
votes

I have an m3u8 playlist for a feature-length film:

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:3
#EXTINF:2.987,
https://...segment0.ts
#EXTINF:2.987,
https://...segment1.ts
#EXTINF:2.987,
https://...segment2.ts
...

with the tag #EXT-X-PLAYLIST-TYPE:VOD, about which Apple says:

For Video on Demand (VOD) sessions, media files are available representing the entire duration of the presentation. The index file is static and contains a complete list of URLs to all media files created since the beginning of the presentation. This kind of session allows the client full access to the entire program.

When I stream this playlist to an iOS native player, or other custom iOS players, the player determines the total duration of the content and displays it.

Now I'm attempting to Cast this same media, and the Chromecast doesn't seem to know the total duration. I've hooked up a GCKUIMediaController and UILabels and all that jazz, but the player regards the playlist as a live stream, showing --:-- for the total duration.

How can I make the Chromecast read the total duration from the HLS playlist?

Here's how I'm loading this item in my iOS Sender App: (more or less)

let metadata = GCKMediaMetadata(metadataType: .movie)
metadata.setString("Blah", forKey: kGCKMetadataKeyTitle)

let mediaInfo = GCKMediaInformation(contentID: URL(string: "https://blah.m3u8"), streamType: GCKMediaStreamType.buffered, contentType: contentType, metadata: metadata, streamDuration: 0, mediaTracks: nil, textTrackStyle: GCKMediaTextTrackStyle.createDefault(), customData: nil)

let builder = GCKMediaQueueItemBuilder()
builder.mediaInformation = mediaInfo
builder.preloadTime = 10.0
builder.playbackDuration = .infinity

let item = builder.build()
item.clearItemID()

let rmc = GCKCastContext.sharedInstance().sessionManager.currentCastSession.remoteMediaClient
rmc.queueLoad([item], start: 0, playPosition: TimeInterval(0.0), repeatMode: .off, customData: nil)

Some docs I've found:

builder.playbackDuration = .infinity

The playback duration for the item, in seconds, or INFINITY if the stream's actual duration should be used. (So, should be set correctly.)

GCKMediaStreamType.buffered

A buffered stream type. (Not sure what this does, but I'm not setting it to .live at least.)

streamDuration: 0

The length of the stream, in seconds, or INFINITY if it is a live stream. Defaults to 0. Seems like the reverse of playbackDuration on the QueueItemBuilder? I set this to zero.

What setting am I missing to get the Chromecast reading the duration from my HLS-streamed video?

1

1 Answers

0
votes

The issue apparently lay in the Styled Media Receiver that I was using:

Version note: The Receiver API and Media Player Library are based on Cast SDK v2 and are compatible with both v2 and CAF senders.

When I switched to the Default Media Receiver this issue went away; I was able to see the duration on a VOD HLS stream.

I gather that this sort of information is exposed to the iOS Cast SDK by the Receiver Application running in the Chromecast device. I suppose the Styled Receiver doesn't have the capability built into it to calculate the duration of an HLS playlist.