I'm currently facing an issue in Chromecast related to the management of alternate audio and text tracks.
I'm trying to differentiate media tracks (both audio and text) with the same language, but with different roles. According to Cast SDK's documentation, we can determine this through the roles
attribute: main
and alternate
, subtitle
and caption
.
When loading HLS manifests with multiple media tracks, however, the roles
attribute is always returned as undefined, so we can't determine if the role of an audio track is main or alternate, neither can we identify if the role of a text track is subtitle or caption. This error does not occur when loading DASH manifests.
Is there any other way of identifying whether an audio track's role is main or alternate in an HLS media? Following that, is there any other way of identifying whether a text track present in an HLS media is subtitle or caption?
I've created an issue on Google's IssueTracker related to this problem, but I've yet to receive any return regarding this.
Below, a demonstration of the problem. The manifests being used have two audio tracks, one main
and another alternate
, and two text tracks, one subtitle
and the other caption
. The manifest is in accordance with HTTP Live Streaming 2nd Edition.
HLS
Manifest
#EXTM3U
#EXT-X-VERSION:4
(version=1.11.14-26090)
# AUDIO groups
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-128",LANGUAGE="pt",NAME="Portuguese",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2",URI="9645657-tst007-manifest-audio_por=128000.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-128",LANGUAGE="pt",NAME="Portuguese (describes-video)",AUTOSELECT=YES,CHARACTERISTICS="public.accessibility.describes-video",CHANNELS="2",URI="9645657-tst007-manifest-audio_por_1=128000.m3u8"
# SUBTITLES groups
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="textstream",LANGUAGE="pt",NAME="Portuguese (caption)",DEFAULT=YES,AUTOSELECT=YES,CHARACTERISTICS="public.accessibility.describes-spoken-dialog,public.accessibility.describes-music-and-sound",URI="9645657-tst007-manifest-textstream_por=1000.m3u8"
# variants
#EXT-X-STREAM-INF:BANDWIDTH=1294000,CODECS="mp4a.40.2,avc1.64001F",RESOLUTION=854x480,AUDIO="audio-aacl-128",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
9645657-tst007-manifest-video_por=1097000.m3u8
# keyframes
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=146000,CODECS="avc1.64001F",RESOLUTION=854x480,URI="keyframes/9645657-tst007-manifest-video_por=1097000.m3u8"
Audio Tracks
# Calling Receiver.playerManager.AudioTracksManager.getTracks()
{
{
assocLanguage:undefined,
customData: undefined,
forced: undefined,
isInband: undefined,
language: "pt",
name: "Português"›
roles: undefined,
subtype: undefined,
trackContentId: undefined,
trackContentType: "audio/mp4",
trackId: 2,
type: "AUDIO"
},
{
assocLanguage: undefined,
customData: undefined,
forced: undefined,
isInband: undefined,
language: "pt",
name: "Português"›
roles: undefined,
subtype: undefined,
trackContentId: undefined,
trackContentType: "audio/mp4",
trackId: 3,
type: "AUDIO"
}
}
Text Tracks
# Calling Receiver.playerManager.TextTracksManager.getTracks()
{
{
assocLanguage: null,
customData: undefined,
forced: false,
isInband: undefined,
language: "pt",
name: "Português"›
roles: undefined,
subtype: undefined,
trackContentId: undefined,
trackContentType: "text/vtt",
trackId: 4,
type: "TEXT"
},
{
assocLanguage: null,
customData: undefined,
forced: false,
isInband: undefined,
language: "pt",
name: "Português"›
roles: undefined,
subtype: undefined,
trackContentId: undefined,
trackContentType: "text/vtt",
trackId: 5,
type: "TEXT"
}
}
DASH
Audio Tracks
# Calling Receiver.playerManager.AudioTracksManager.getTracks()
{
{
assocLanguage:undefined,
customData: undefined,
forced: undefined,
isInband: undefined,
language: "pt",
name: "Português"›
roles: ["alternate"],
subtype: undefined,
trackContentId: undefined,
trackContentType: "mp4a.40.2",
trackId: 1,
type: "AUDIO"
},
{
assocLanguage: undefined,
customData: undefined,
forced: undefined,
isInband: undefined,
language: "pt",
name: "Português"›
roles: ["main"],
subtype: undefined,
trackContentId: undefined,
trackContentType: "mp4a.40.2",
trackId: 2,
type: "AUDIO"
}
}
Text Tracks
# When calling Receiver.playerManager.TextTracksManager.getTracks()
{
{
assocLanguage:undefined,
customData: undefined,
forced: undefined,
isInband: undefined,
language: "pt",
name: "Português"›
roles: ["subtitle"],
subtype: "SUBTITLE",
trackContentId: undefined,
trackContentType: "application/mp4",
trackId: 3,
type: "TEXT"
},
{
assocLanguage: undefined,
customData: undefined,
forced: undefined,
isInband: undefined,
language: "pt",
name: "Português"›
roles: ["caption", "subtitle"],
subtype: "SUBTITLE",
trackContentId: undefined,
trackContentType: "application/mp4",
trackId: 4,
type: "TEXT"
}
}