mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-15 16:06:41 +03:00
3a67802ce2
It turns out that, on some browsers, incomplete XML does not properly parse. This means the parseFirstCue tests did not work on those platforms. This modifies those tests on platforms that do not support partial XML; when no support is detected, it instead tries to get the first cue from a non-partial segment. This also modifies the HLS parser to only load partial text segments if the text parser supports it; otherwise, the hls parser will load full captions in order to extract start times. b/137945635 Issue #2037 Change-Id: I58112864a818baf155b365a65fba1c8a56eb9520
132 lines
3.6 KiB
JavaScript
132 lines
3.6 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2016 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
goog.provide('shaka.text.Mp4TtmlParser');
|
|
|
|
goog.require('shaka.text.TextEngine');
|
|
goog.require('shaka.text.TtmlTextParser');
|
|
goog.require('shaka.util.Error');
|
|
goog.require('shaka.util.Mp4Parser');
|
|
|
|
|
|
/**
|
|
* @implements {shaka.extern.TextParser}
|
|
*/
|
|
shaka.text.Mp4TtmlParser = class {
|
|
constructor() {
|
|
/**
|
|
* @type {!shaka.extern.TextParser}
|
|
* @private
|
|
*/
|
|
this.parser_ = new shaka.text.TtmlTextParser();
|
|
|
|
/** @private {boolean} */
|
|
this.supportsPartial_ = false;
|
|
try {
|
|
const parser = new DOMParser();
|
|
const parsed = parser.parseFromString('<tag></t', 'text/xml');
|
|
this.supportsPartial_ = parsed.getElementsByTagName('tag').length > 0;
|
|
} catch (e) {}
|
|
}
|
|
|
|
/** @override **/
|
|
parseInit(data) {
|
|
const Mp4Parser = shaka.util.Mp4Parser;
|
|
|
|
let sawSTPP = false;
|
|
|
|
new Mp4Parser()
|
|
.box('moov', Mp4Parser.children)
|
|
.box('trak', Mp4Parser.children)
|
|
.box('mdia', Mp4Parser.children)
|
|
.box('minf', Mp4Parser.children)
|
|
.box('stbl', Mp4Parser.children)
|
|
.fullBox('stsd', Mp4Parser.sampleDescription)
|
|
.box('stpp', (box) => {
|
|
sawSTPP = true;
|
|
box.parser.stop();
|
|
}).parse(data);
|
|
|
|
if (!sawSTPP) {
|
|
throw new shaka.util.Error(
|
|
shaka.util.Error.Severity.CRITICAL,
|
|
shaka.util.Error.Category.TEXT,
|
|
shaka.util.Error.Code.INVALID_MP4_TTML);
|
|
}
|
|
}
|
|
|
|
/** @override */
|
|
parseFirstCue(data, time) {
|
|
return this.parseMediaInternal_(data, time, /* partial= */ true)[0];
|
|
}
|
|
|
|
/** @override **/
|
|
parseMedia(data, time) {
|
|
return this.parseMediaInternal_(data, time, /* partial= */ false);
|
|
}
|
|
|
|
/** @override */
|
|
supportsPartial() {
|
|
return this.supportsPartial_;
|
|
}
|
|
|
|
/**
|
|
* @param {!Uint8Array} data
|
|
* @param {shaka.extern.TextParser.TimeContext} time
|
|
* @param {boolean} partial
|
|
* @return {!Array.<!shaka.extern.Cue>}
|
|
* @throws {shaka.util.Error}
|
|
* @private
|
|
*/
|
|
parseMediaInternal_(data, time, partial) {
|
|
const Mp4Parser = shaka.util.Mp4Parser;
|
|
|
|
let sawMDAT = false;
|
|
let payload = [];
|
|
|
|
const parser = new Mp4Parser()
|
|
.box('mdat', Mp4Parser.allData((data) => {
|
|
sawMDAT = true;
|
|
if (partial) {
|
|
// Ignore any future MDAT boxes, if a cue has been found.
|
|
payload = [this.parser_.parseFirstCue(data, time)];
|
|
parser.stop();
|
|
} else {
|
|
// Join this to any previous payload, in case the mp4 has multiple
|
|
// mdats.
|
|
payload = payload.concat(this.parser_.parseMedia(data, time));
|
|
}
|
|
}));
|
|
parser.parse(data, partial);
|
|
|
|
if (!sawMDAT) {
|
|
throw new shaka.util.Error(
|
|
shaka.util.Error.Severity.CRITICAL,
|
|
shaka.util.Error.Category.TEXT,
|
|
shaka.util.Error.Code.INVALID_MP4_TTML);
|
|
}
|
|
|
|
return payload;
|
|
}
|
|
};
|
|
|
|
|
|
shaka.text.TextEngine.registerParser(
|
|
'application/mp4; codecs="stpp"', shaka.text.Mp4TtmlParser);
|
|
shaka.text.TextEngine.registerParser(
|
|
'application/mp4; codecs="stpp.TTML.im1t"', shaka.text.Mp4TtmlParser);
|