Skip to content

Commit

Permalink
Expose Roles of Audio Tracks
Browse files Browse the repository at this point in the history
This change is to expose an audio track's role in order to differentiate
among a main / caption / commentary track that shares the same
language.

Issue #767.

Change-Id: I05d38cba2170d0005611cf160b7ae45996fe77dd
  • Loading branch information
michellezhuogg committed May 26, 2017
1 parent dbbbbd1 commit afb0ded
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 28 deletions.
7 changes: 5 additions & 2 deletions externs/shaka/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ shakaExtern.GetSegmentReferenceFunction;
* type: string,
* primary: boolean,
* trickModeVideo: ?shakaExtern.Stream,
* containsEmsgBoxes: boolean
* containsEmsgBoxes: boolean,
* roles: !Array.<string>
* }}
*
* @description
Expand Down Expand Up @@ -389,7 +390,9 @@ shakaExtern.GetSegmentReferenceFunction;
* <i>Defaults to false.</i><br>
* Whether the stream contains embedded 'emsg' boxes that should result in
* Player events.
*
* @property {!Array.<string>} roles
* The roles of the stream as they appear on the manifest,
* e.g. 'main', 'caption', or 'commentary'.
* @exportDoc
*/
shakaExtern.Stream;
5 changes: 4 additions & 1 deletion externs/shaka/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ shakaExtern.Stats;
* codecs: ?string,
* audioCodec: ?string,
* videoCodec: ?string,
* primary: boolean
* primary: boolean,
* roles: !Array.<string>
* }}
*
* @description
Expand Down Expand Up @@ -187,6 +188,8 @@ shakaExtern.Stats;
* This can be a useful hint about which language should be the default, and
* indicates which track Shaka will use when the user's language preference
* cannot be satisfied.
* @property {!Array.<string>} roles
* The roles of the track, e.g. 'main', 'caption', or 'commentary'.
* @exportDoc
*/
shakaExtern.Track;
Expand Down
22 changes: 14 additions & 8 deletions lib/dash/dash_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -897,24 +897,28 @@ shaka.dash.DashParser.prototype.createVariants_ =
*/
shaka.dash.DashParser.prototype.parseAdaptationSet_ = function(context, elem) {
var XmlUtils = shaka.util.XmlUtils;
var Functional = shaka.util.Functional;
var ManifestParserUtils = shaka.util.ManifestParserUtils;
context.adaptationSet = this.createFrame_(elem, context.period, null);

var main = false;
var roles = XmlUtils.findChildren(elem, 'Role');
var roleElements = XmlUtils.findChildren(elem, 'Role');
var roleValues = roleElements.map(function(role) {
return role.getAttribute('value');
}).filter(Functional.isNotNull);

// Default kind for text streams is 'subtitle' if unspecified in the manifest.
var kind = undefined;
if (context.adaptationSet.contentType == ManifestParserUtils.ContentType.TEXT)
kind = ManifestParserUtils.TextStreamKind.SUBTITLE;

for (var i = 0; i < roles.length; i++) {
var scheme = roles[i].getAttribute('schemeIdUri');
for (var i = 0; i < roleElements.length; i++) {
var scheme = roleElements[i].getAttribute('schemeIdUri');
if (scheme == null || scheme == 'urn:mpeg:dash:role:2011') {
// These only apply for the given scheme, but allow them to be specified
// if there is no scheme specified.
// See: DASH section 5.8.5.5
var value = roles[i].getAttribute('value');
var value = roleElements[i].getAttribute('value');
switch (value) {
case 'main':
main = true;
Expand Down Expand Up @@ -964,8 +968,8 @@ shaka.dash.DashParser.prototype.parseAdaptationSet_ = function(context, elem) {
// Parse Representations into Streams.
var representations = XmlUtils.findChildren(elem, 'Representation');
var streams = representations
.map(this.parseRepresentation_.bind(
this, context, contentProtection, kind, language, label, main))
.map(this.parseRepresentation_.bind(this, context, contentProtection,
kind, language, label, main, roleValues))
.filter(function(s) { return !!s; });

if (streams.length == 0) {
Expand Down Expand Up @@ -1024,14 +1028,15 @@ shaka.dash.DashParser.prototype.parseAdaptationSet_ = function(context, elem) {
* @param {string} language
* @param {string} label
* @param {boolean} isPrimary
* @param {!Array.<string>} roles
* @param {!Element} node
* @return {?shakaExtern.Stream} The Stream, or null when there is a
* non-critical parsing error.
* @throws shaka.util.Error When there is a parsing error.
* @private
*/
shaka.dash.DashParser.prototype.parseRepresentation_ = function(
context, contentProtection, kind, language, label, isPrimary, node) {
context, contentProtection, kind, language, label, isPrimary, roles, node) {
var XmlUtils = shaka.util.XmlUtils;
var ContentType = shaka.util.ManifestParserUtils.ContentType;

Expand Down Expand Up @@ -1114,7 +1119,8 @@ shaka.dash.DashParser.prototype.parseRepresentation_ = function(
type: context.adaptationSet.contentType,
primary: isPrimary,
trickModeVideo: null,
containsEmsgBoxes: context.representation.containsEmsgBoxes
containsEmsgBoxes: context.representation.containsEmsgBoxes,
roles: roles
};
};

Expand Down
3 changes: 2 additions & 1 deletion lib/hls/hls_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,8 @@ shaka.hls.HlsParser.prototype.createStreamInfo_ =
frameRate: undefined,
width: undefined,
height: undefined,
bandwidth: undefined
bandwidth: undefined,
roles: []
};

this.streamsToIndexMap_[stream.id] = segmentIndex;
Expand Down
3 changes: 2 additions & 1 deletion lib/offline/offline_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ shaka.offline.OfflineUtils.createStream_ = function(streamDb) {
primary: streamDb.primary,
trickModeVideo: null,
// TODO(modmaker): Store offline?
containsEmsgBoxes: false
containsEmsgBoxes: false,
roles: []
};
};

Expand Down
3 changes: 2 additions & 1 deletion lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -1471,7 +1471,8 @@ shaka.Player.prototype.addTextTrack = function(
type: ContentType.TEXT,
primary: false,
trickModeVideo: null,
containsEmsgBoxes: false
containsEmsgBoxes: false,
roles: []
};

// Add the stream to the loading list to ensure it isn't switched to while it
Expand Down
11 changes: 9 additions & 2 deletions lib/util/stream_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ goog.require('shaka.log');
goog.require('shaka.media.DrmEngine');
goog.require('shaka.media.MediaSourceEngine');
goog.require('shaka.media.TextEngine');
goog.require('shaka.util.ArrayUtils');
goog.require('shaka.util.LanguageUtils');
goog.require('shaka.util.ManifestParserUtils');

Expand Down Expand Up @@ -247,6 +248,10 @@ shaka.util.StreamUtils.getVariantTracks =
if (variant.audio) kind = variant.audio.kind;
else if (variant.video) kind = variant.video.kind;

var audioRoles = variant.audio ? variant.audio.roles : [];
var videoRoles = variant.video ? variant.video.roles : [];
var roles = shaka.util.ArrayUtils.removeDuplicates(
audioRoles.concat(videoRoles));
return {
id: variant.id,
active: isActive,
Expand All @@ -262,7 +267,8 @@ shaka.util.StreamUtils.getVariantTracks =
codecs: codecs,
audioCodec: audioCodec,
videoCodec: videoCodec,
primary: variant.primary
primary: variant.primary,
roles: roles
};
});

Expand Down Expand Up @@ -290,7 +296,8 @@ shaka.util.StreamUtils.getTextTracks = function(period, activeStreamId) {
codecs: stream.codecs || null,
audioCodec: null,
videoCodec: null,
primary: stream.primary
primary: stream.primary,
roles: stream.roles
};
});
};
Expand Down
3 changes: 3 additions & 0 deletions test/dash/dash_parser_manifest_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ describe('DashParser Manifest', function() {
.presentationTimeOffset(0)
.mime('audio/mp4', 'mp4a.40.29')
.primary()
.roles(['main'])
.addVariant(jasmine.any(Number))
.language('en')
.bandwidth(150)
Expand All @@ -174,6 +175,7 @@ describe('DashParser Manifest', function() {
.presentationTimeOffset(0)
.mime('audio/mp4', 'mp4a.40.29')
.primary()
.roles(['main'])
.addTextStream(jasmine.any(Number))
.language('es')
.label('spanish')
Expand All @@ -184,6 +186,7 @@ describe('DashParser Manifest', function() {
.mime('text/vtt')
.bandwidth(100)
.kind('caption')
.roles(['caption', 'main'])
.build());
});

Expand Down
4 changes: 3 additions & 1 deletion test/offline/offline_utils_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ describe('OfflineUtils', function() {
type: streamDb.contentType,
primary: streamDb.primary,
trickModeVideo: null,
containsEmsgBoxes: false
containsEmsgBoxes: false,
roles: []

};
expect(stream).toEqual(expectedStream);

Expand Down
9 changes: 6 additions & 3 deletions test/offline/storage_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ describe('Storage', function() {
mimeType: 'video/mp4',
codecs: 'avc1.4d401f',
primary: false,
segments: []
segments: [],
roles: []
},
{
id: 1,
Expand All @@ -105,7 +106,8 @@ describe('Storage', function() {
mimeType: 'audio/mp4',
codecs: 'vorbis',
primary: true,
segments: []
segments: [],
roles: []
}
]
}],
Expand Down Expand Up @@ -142,7 +144,8 @@ describe('Storage', function() {
primary: true,
codecs: 'avc1.4d401f, vorbis',
audioCodec: 'vorbis',
videoCodec: 'avc1.4d401f'
videoCodec: 'avc1.4d401f',
roles: []
}
];
Promise
Expand Down
21 changes: 14 additions & 7 deletions test/player_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,8 @@ describe('Player', function() {
codecs: 'avc1.4d401f, mp4a.40.2',
audioCodec: 'mp4a.40.2',
videoCodec: 'avc1.4d401f',
primary: false
primary: false,
roles: []
},
{
id: 2,
Expand All @@ -810,7 +811,8 @@ describe('Player', function() {
codecs: 'avc1.4d401f, mp4a.40.2',
audioCodec: 'mp4a.40.2',
videoCodec: 'avc1.4d401f',
primary: false
primary: false,
roles: []
},
{
id: 3,
Expand All @@ -827,7 +829,8 @@ describe('Player', function() {
codecs: 'avc1.4d401f, mp4a.40.2',
audioCodec: 'mp4a.40.2',
videoCodec: 'avc1.4d401f',
primary: false
primary: false,
roles: []
},
{
id: 4,
Expand All @@ -844,7 +847,8 @@ describe('Player', function() {
codecs: 'avc1.4d401f, mp4a.40.2',
audioCodec: 'mp4a.40.2',
videoCodec: 'avc1.4d401f',
primary: false
primary: false,
roles: []
},
{
id: 5,
Expand All @@ -861,7 +865,8 @@ describe('Player', function() {
codecs: 'avc1.4d401f, mp4a.40.2',
audioCodec: 'mp4a.40.2',
videoCodec: 'avc1.4d401f',
primary: false
primary: false,
roles: []
}
];

Expand All @@ -876,7 +881,8 @@ describe('Player', function() {
codecs: null,
audioCodec: null,
videoCodec: null,
primary: false
primary: false,
roles: []
},
{
id: 7,
Expand All @@ -888,7 +894,8 @@ describe('Player', function() {
codecs: null,
audioCodec: null,
videoCodec: null,
primary: false
primary: false,
roles: []
}
];
});
Expand Down
15 changes: 14 additions & 1 deletion test/test/util/manifest_generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,8 @@ shaka.test.ManifestGenerator.prototype.createStream_ =
type: type,
primary: false,
trickModeVideo: null,
containsEmsgBoxes: false
containsEmsgBoxes: false,
roles: []
};
stream.createSegmentIndex.and.callFake(
function() { return Promise.resolve(); });
Expand Down Expand Up @@ -692,6 +693,18 @@ shaka.test.ManifestGenerator.prototype.frameRate = function(frameRate) {
};


/**
* Sets the roles of the current stream.
* @param {!Array.<string>} roles
* @return {!shaka.test.ManifestGenerator}
*/
shaka.test.ManifestGenerator.prototype.roles = function(roles) {
var stream = this.currentStream_();
stream.roles = roles;
return this;
};


/**
* Sets the key ID of the current stream.
*
Expand Down

0 comments on commit afb0ded

Please sign in to comment.