Skip to content

Commit

Permalink
transports: remove assert from text track parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
peaBerberian committed Jun 21, 2021
1 parent e1d5012 commit 0796c0b
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 72 deletions.
108 changes: 65 additions & 43 deletions src/transports/dash/text_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@
* limitations under the License.
*/

import Manifest, {
Adaptation,
ISegment,
Period,
Representation,
} from "../../manifest";
import {
getMDHDTimescale,
getSegmentsFromSidx,
} from "../../parsers/containers/isobmff";
import { BaseRepresentationIndex } from "../../parsers/manifest/dash";
import assert from "../../utils/assert";
import {
strToUtf8,
utf8ToStr,
Expand All @@ -40,26 +45,38 @@ import {

/**
* Parse TextTrack data when it is embedded in an ISOBMFF file.
* @param {Object} infos
*
* @param {ArrayBuffer|Uint8Array|string} data - The segment data.
* @param {boolean} isChunked - If `true`, the `data` may contain only a
* decodable subpart of the full data in the linked segment.
* @param {Object} content - Object describing the context of the given
* segment's data: of which segment, `Representation`, `Adaptation`, `Period`,
* `Manifest` it is a part of etc.
* @param {number|undefined} initTimescale - `timescale` value - encountered
* in this linked initialization segment (if it exists) - that may also apply
* to that segment if no new timescale is defined in it.
* Can be `undefined` if no timescale was defined, if it is not known, or if
* no linked initialization segment was yet parsed.
* @param {boolean} __priv_patchLastSegmentInSidx - Enable ugly Canal+-specific
* fix for an issue people on the content-packaging side could not fix.
* For more information on that, look at the code using it.
* @returns {Observable.<Object>}
*/
function parseISOBMFFEmbeddedTextTrack(
{ response,
content,
initTimescale } : ISegmentParserArguments< Uint8Array |
ArrayBuffer |
string >,
data : Uint8Array | ArrayBuffer | string,
isChunked : boolean,
content : { manifest : Manifest;
period : Period;
adaptation : Adaptation;
representation : Representation;
segment : ISegment; },
initTimescale : number | undefined,
__priv_patchLastSegmentInSidx? : boolean
) : ISegmentParserParsedInitSegment<null> |
ISegmentParserParsedSegment<ITextTrackSegmentData | null>
{
const { period, representation, segment } = content;
const { isInit, indexRange } = segment;
const { data, isChunked } = response;

// Should already have been taken care of
// TODO better use TypeScript here?
assert(data !== null);

const chunkBytes = typeof data === "string" ? strToUtf8(data) :
data instanceof Uint8Array ? data :
Expand Down Expand Up @@ -116,15 +133,24 @@ function parseISOBMFFEmbeddedTextTrack(
}

/**
* Parse TextTrack data in plain text form.
* @param {Object} infos
* Parse TextTrack data when it is in plain text form.
*
* @param {ArrayBuffer|Uint8Array|string} data - The segment data.
* @param {boolean} isChunked - If `true`, the `data` may contain only a
* decodable subpart of the full data in the linked segment.
* @param {Object} content - Object describing the context of the given
* segment's data: of which segment, `Representation`, `Adaptation`, `Period`,
* `Manifest` it is a part of etc.
* @returns {Observable.<Object>}
*/
function parsePlainTextTrack(
{ response,
content } : ISegmentParserArguments< Uint8Array |
ArrayBuffer |
string >
data : Uint8Array | ArrayBuffer | string,
isChunked : boolean,
content : { manifest : Manifest;
period : Period;
adaptation : Adaptation;
representation : Representation;
segment : ISegment; }
) : ISegmentParserParsedInitSegment<null> |
ISegmentParserParsedSegment<ITextTrackSegmentData | null>
{
Expand All @@ -137,14 +163,8 @@ function parsePlainTextTrack(
initTimescale: undefined };
}

const { data, isChunked } = response;
let textTrackData : string;
if (typeof data !== "string") {

// Should already have been taken care of
// TODO better use TypeScript here?
assert(data !== null);

const bytesData = data instanceof Uint8Array ? data :
new Uint8Array(data);
textTrackData = utf8ToStr(bytesData);
Expand All @@ -161,6 +181,8 @@ function parsePlainTextTrack(
}

/**
* Generate a "segment parser" for DASH text tracks.
*
* @param {Object} config
* @returns {Function}
*/
Expand All @@ -183,21 +205,21 @@ export default function generateTextTrackParser(
ISegmentParserParsedSegment<ITextTrackSegmentData | null>
{
const { period, adaptation, representation, segment } = content;
const { timestampOffset = 0 } = segment;
const { data, isChunked } = response;
if (data === null) { // No data, just return empty infos
if (segment.isInit) {
return { segmentType: "init",
initializationData: null,
protectionDataUpdate: false,
initTimescale: undefined };
}
return { segmentType: "media",
chunkData: null,
chunkInfos: null,
chunkOffset: timestampOffset,
protectionDataUpdate: false,
appendWindow: [period.start, period.end] };

if (data === null) {
// No data, just return an empty placeholder object
return segment.isInit ? { segmentType: "init",
initializationData: null,
protectionDataUpdate: false,
initTimescale: undefined } :

{ segmentType: "media",
chunkData: null,
chunkInfos: null,
chunkOffset: segment.timestampOffset ?? 0,
protectionDataUpdate: false,
appendWindow: [period.start, period.end] };
}

const containerType = inferSegmentContainer(adaptation.type, representation);
Expand All @@ -207,12 +229,12 @@ export default function generateTextTrackParser(
// TODO Handle webm containers
throw new Error("Text tracks with a WEBM container are not yet handled.");
} else if (containerType === "mp4") {
return parseISOBMFFEmbeddedTextTrack({ response: { data, isChunked },
content,
initTimescale },
__priv_patchLastSegmentInSidx);
return parseISOBMFFEmbeddedTextTrack(data,
isChunked,
content,
initTimescale, __priv_patchLastSegmentInSidx);
} else {
return parsePlainTextTrack({ response: { data, isChunked }, content });
return parsePlainTextTrack(data, isChunked, content);
}
};
}
77 changes: 48 additions & 29 deletions src/transports/local/text_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@
* limitations under the License.
*/

import Manifest, {
Adaptation,
ISegment,
Period,
Representation,
} from "../../manifest";
import { getMDHDTimescale } from "../../parsers/containers/isobmff";
import assert from "../../utils/assert";
import {
strToUtf8,
utf8ToStr,
Expand All @@ -36,24 +41,34 @@ import {

/**
* Parse TextTrack data when it is embedded in an ISOBMFF file.
* @param {Object} infos
*
* @param {ArrayBuffer|Uint8Array|string} data - The segment data.
* @param {boolean} isChunked - If `true`, the `data` may contain only a
* decodable subpart of the full data in the linked segment.
* @param {Object} content - Object describing the context of the given
* segment's data: of which segment, `Representation`, `Adaptation`, `Period`,
* `Manifest` it is a part of etc.
* @param {number|undefined} initTimescale - `timescale` value - encountered
* in this linked initialization segment (if it exists) - that may also apply
* to that segment if no new timescale is defined in it.
* Can be `undefined` if no timescale was defined, if it is not known, or if
* no linked initialization segment was yet parsed.
* @returns {Observable.<Object>}
*/
function parseISOBMFFEmbeddedTextTrack(
{ response,
content,
initTimescale } : ISegmentParserArguments< Uint8Array |
ArrayBuffer |
string >
data : Uint8Array | ArrayBuffer | string,
isChunked : boolean,
content : { manifest : Manifest;
period : Period;
adaptation : Adaptation;
representation : Representation;
segment : ISegment; },
initTimescale : number | undefined,
__priv_patchLastSegmentInSidx? : boolean
) : ISegmentParserParsedInitSegment<null> |
ISegmentParserParsedSegment<ITextTrackSegmentData | null>
{
const { period, segment } = content;
const { data, isChunked } = response;

// Should already have been taken care of
// TODO better use TypeScript here?
assert(data !== null);

const chunkBytes = typeof data === "string" ? strToUtf8(data) :
data instanceof Uint8Array ? data :
Expand Down Expand Up @@ -83,15 +98,24 @@ function parseISOBMFFEmbeddedTextTrack(
}

/**
* Parse TextTrack data in plain text form.
* @param {Object} infos
* Parse TextTrack data when it is in plain text form.
*
* @param {ArrayBuffer|Uint8Array|string} data - The segment data.
* @param {boolean} isChunked - If `true`, the `data` may contain only a
* decodable subpart of the full data in the linked segment.
* @param {Object} content - Object describing the context of the given
* segment's data: of which segment, `Representation`, `Adaptation`, `Period`,
* `Manifest` it is a part of etc.
* @returns {Observable.<Object>}
*/
function parsePlainTextTrack(
{ response,
content } : ISegmentParserArguments< Uint8Array |
ArrayBuffer |
string >
data : Uint8Array | ArrayBuffer | string,
isChunked : boolean,
content : { manifest : Manifest;
period : Period;
adaptation : Adaptation;
representation : Representation;
segment : ISegment; }
) : ISegmentParserParsedInitSegment<null> |
ISegmentParserParsedSegment<ITextTrackSegmentData | null>
{
Expand All @@ -103,13 +127,8 @@ function parsePlainTextTrack(
protectionDataUpdate: false };
}

const { data, isChunked } = response;
let textTrackData : string;
if (typeof data !== "string") {
// Should already have been taken care of
// TODO better use TypeScript here?
assert(data !== null);

const bytesData = data instanceof Uint8Array ? data :
new Uint8Array(data);
textTrackData = utf8ToStr(bytesData);
Expand Down Expand Up @@ -143,14 +162,16 @@ export default function textTrackParser(
{
const { period, adaptation, representation, segment } = content;
const { data, isChunked } = response;
if (data === null) { // No data, just return empty infos

if (data === null) {
// No data, just return an empty placeholder object
if (segment.isInit) {
return { segmentType: "init",
initializationData: null,
protectionDataUpdate: false,
initTimescale: undefined };
}
const chunkOffset = takeFirstSet<number>(segment.timestampOffset, 0);
const chunkOffset = segment.timestampOffset ?? 0;
return { segmentType: "media",
chunkData: null,
chunkInfos: null,
Expand All @@ -166,10 +187,8 @@ export default function textTrackParser(
// TODO Handle webm containers
throw new Error("Text tracks with a WEBM container are not yet handled.");
} else if (containerType === "mp4") {
return parseISOBMFFEmbeddedTextTrack({ response: { data, isChunked },
content,
initTimescale });
return parseISOBMFFEmbeddedTextTrack(data, isChunked, content, initTimescale);
} else {
return parsePlainTextTrack({ response: { data, isChunked }, content });
return parsePlainTextTrack(data, isChunked, content);
}
}

0 comments on commit 0796c0b

Please sign in to comment.