mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-19 16:47:01 +03:00
1e12873fb7
Previously, when the text engine tried to load the start time of a segment, it would parse every cue in that segment, then check the time of the first cue. This was judged to not be a significant performance issue, as parsing cues is a fast operation. However, it did have an unintended side-effect: in some situations, this method was being passed partial segments; notably, the HLS parser would load the first 2048kb of the stream's texts to extract timing data. If the caption parsers tried to actually parse an incomplete caption, they would error. This gives the text parsers "parseFirstCue" methods, and uses those methods when it only needs the first cue anyway. Fixes #2037 Change-Id: I2a1fb2f1a96d98967f0c6e6a5c277914a28b42ad
119 lines
3.3 KiB
JavaScript
119 lines
3.3 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();
|
|
}
|
|
|
|
/** @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);
|
|
}
|
|
|
|
/**
|
|
* @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);
|