Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/parsers/manifest/dash/js-parser/node_parsers/AdaptationSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {
import parseBaseURL from "./BaseURL.ts";
import parseContentComponent from "./ContentComponent.ts";
import parseContentProtection from "./ContentProtection.ts";
import parseDescriptor from "./Descriptor.ts";
import { createRepresentationIntermediateRepresentation } from "./Representation.ts";
import parseSegmentBase from "./SegmentBase.ts";
import parseSegmentList from "./SegmentList.ts";
Expand Down Expand Up @@ -88,9 +89,12 @@ function parseAdaptationSetChildren(
children.ContentComponent.push(parseContentComponent(currentNode));
break;

case "EssentialProperty":
children.EssentialProperty.push(parseScheme(currentNode));
case "EssentialProperty": {
const [descriptor, descriptorWarnings] = parseDescriptor(currentNode);
children.EssentialProperty.push(descriptor);
warnings.push(...descriptorWarnings);
break;
}

case "InbandEventStream":
children.InbandEventStream.push(parseScheme(currentNode));
Expand Down Expand Up @@ -118,9 +122,12 @@ function parseAdaptationSetChildren(
children.Role.push(parseScheme(currentNode));
break;

case "SupplementalProperty":
children.SupplementalProperty.push(parseScheme(currentNode));
case "SupplementalProperty": {
const [descriptor, descriptorWarnings] = parseDescriptor(currentNode);
children.SupplementalProperty.push(descriptor);
warnings.push(...descriptorWarnings);
break;
}

case "SegmentBase": {
const [segmentBase, segmentBaseWarnings] = parseSegmentBase(currentNode);
Expand Down
40 changes: 40 additions & 0 deletions src/parsers/manifest/dash/js-parser/node_parsers/Descriptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { ITNode } from "../../../../../utils/xml-parser.ts";
import type { IDescriptorIntermediateRepresentation } from "../../node_parser_types.ts";
import parseUrlQueryInfo from "./UrlQueryInfo.ts";
import { parseScheme } from "./utils.ts";

/**
* Parse an `<EssentialProperty>` or `<SupplementalProperty>` descriptor.
*/
export default function parseDescriptor(
root: ITNode,
): [IDescriptorIntermediateRepresentation, Error[]] {
const children: IDescriptorIntermediateRepresentation["children"] = {
UrlQueryInfo: [],
ExtUrlQueryInfo: [],
};
const property: IDescriptorIntermediateRepresentation = {
attributes: parseScheme(root).attributes,
children,
};
if (typeof root.attributes.id === "string") {
property.attributes.id = root.attributes.id;
}
const warnings: Error[] = [];
for (const child of root.children) {
if (typeof child === "string") {
continue;
}
// TODO Support other XML prefixes also linked to the `up` namespace.
if (child.tagName === "up:UrlQueryInfo") {
const [queryInfo, queryInfoWarnings] = parseUrlQueryInfo(child);
children.UrlQueryInfo.push(queryInfo);
warnings.push(...queryInfoWarnings);
} else if (child.tagName === "up:ExtUrlQueryInfo") {
const [queryInfo, queryInfoWarnings] = parseUrlQueryInfo(child);
children.ExtUrlQueryInfo.push(queryInfo);
warnings.push(...queryInfoWarnings);
}
}
return [property, warnings];
}
17 changes: 17 additions & 0 deletions src/parsers/manifest/dash/js-parser/node_parsers/MPD.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type {
} from "../../node_parser_types.ts";
import parseBaseURL from "./BaseURL.ts";
import parseContentProtection from "./ContentProtection.ts";
import parseDescriptor from "./Descriptor.ts";
import { createPeriodIntermediateRepresentation } from "./Period.ts";
import {
parseDateTime,
Expand All @@ -45,6 +46,8 @@ function parseMPDChildren(
): [IMPDChildren, Error[]] {
const ret: IMPDChildren = {
BaseURL: [],
EssentialProperty: [],
SupplementalProperty: [],
Location: [],
Period: [],
UTCTiming: [],
Expand All @@ -67,6 +70,20 @@ function parseMPDChildren(
break;
}

case "EssentialProperty": {
const [descriptor, descriptorWarnings] = parseDescriptor(currentNode);
ret.EssentialProperty.push(descriptor);
warnings.push(...descriptorWarnings);
break;
}

case "SupplementalProperty": {
const [descriptor, descriptorWarnings] = parseDescriptor(currentNode);
ret.SupplementalProperty.push(descriptor);
warnings.push(...descriptorWarnings);
break;
}

case "Location": {
ret.Location.push(parseLocation(currentNode));
break;
Expand Down
9 changes: 9 additions & 0 deletions src/parsers/manifest/dash/js-parser/node_parsers/Period.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type {
import { createAdaptationSetIntermediateRepresentation } from "./AdaptationSet.ts";
import parseBaseURL from "./BaseURL.ts";
import parseContentProtection from "./ContentProtection.ts";
import parseDescriptor from "./Descriptor.ts";
import { createEventStreamIntermediateRepresentation } from "./EventStream.ts";
import parseSegmentTemplate from "./SegmentTemplate.ts";
import { parseBoolean, parseDuration, ValueParser } from "./utils.ts";
Expand All @@ -42,6 +43,7 @@ function parsePeriodChildren(
AdaptationSet: [],
BaseURL: [],
ContentProtection: [],
SupplementalProperty: [],
SegmentTemplate: [],
EventStream: [],
};
Expand Down Expand Up @@ -98,6 +100,13 @@ function parsePeriodChildren(
}
break;
}

case "SupplementalProperty": {
const [descriptor, descriptorWarnings] = parseDescriptor(currentElement);
ret.SupplementalProperty.push(descriptor);
warnings.push(...descriptorWarnings);
break;
}
}
}

Expand Down
15 changes: 11 additions & 4 deletions src/parsers/manifest/dash/js-parser/node_parsers/Representation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {
} from "../../node_parser_types.ts";
import parseBaseURL from "./BaseURL.ts";
import parseContentProtection from "./ContentProtection.ts";
import parseDescriptor from "./Descriptor.ts";
import parseSegmentBase from "./SegmentBase.ts";
import parseSegmentList from "./SegmentList.ts";
import parseSegmentTemplate from "./SegmentTemplate.ts";
Expand Down Expand Up @@ -103,12 +104,18 @@ function parseRepresentationChildren(
}
break;
}
case "EssentialProperty":
children.EssentialProperty.push(parseScheme(currentElement));
case "EssentialProperty": {
const [descriptor, descriptorWarnings] = parseDescriptor(currentElement);
children.EssentialProperty.push(descriptor);
warnings.push(...descriptorWarnings);
break;
case "SupplementalProperty":
children.SupplementalProperty.push(parseScheme(currentElement));
}
case "SupplementalProperty": {
const [descriptor, descriptorWarnings] = parseDescriptor(currentElement);
children.SupplementalProperty.push(descriptor);
warnings.push(...descriptorWarnings);
break;
}
}
}
return [children, warnings];
Expand Down
37 changes: 37 additions & 0 deletions src/parsers/manifest/dash/js-parser/node_parsers/UrlQueryInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import isNullOrUndefined from "../../../../../utils/is_null_or_undefined.ts";
import type { ITNode } from "../../../../../utils/xml-parser.ts";
import type { IUrlQueryInfoIntermediateRepresentation } from "../../node_parser_types.ts";
import { parseBoolean, ValueParser } from "./utils.ts";

/** Parse a `<UrlQueryInfo>` or `<ExtUrlQueryInfo>` element. */
export default function parseUrlQueryInfo(
root: ITNode,
): [IUrlQueryInfoIntermediateRepresentation, Error[]] {
const attributes: IUrlQueryInfoIntermediateRepresentation["attributes"] = {};
const warnings: Error[] = [];
const parseValue = ValueParser(attributes, warnings);
for (const attributeName of Object.keys(root.attributes)) {
const attributeValue = root.attributes[attributeName];
if (isNullOrUndefined(attributeValue)) {
continue;
}
switch (attributeName) {
case "queryString":
attributes.queryString = attributeValue;
break;
case "queryTemplate":
attributes.queryTemplate = attributeValue;
break;
case "includeInRequests":
attributes.includeInRequests = attributeValue;
break;
case "useMPDUrlQuery":
parseValue(attributeValue, {
parser: parseBoolean,
name: "useMpdUrlQuery",
});
break;
}
}
return [{ attributes }, warnings];
}
37 changes: 33 additions & 4 deletions src/parsers/manifest/dash/node_parser_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export interface IMPDChildren {
* from the first encountered to the last encountered.
*/
BaseURL: IBaseUrlIntermediateRepresentation[];
/** Root-level `<EssentialProperty>` descriptors. */
EssentialProperty: IDescriptorIntermediateRepresentation[];
/** Root-level `<SupplementalProperty>` descriptors. */
SupplementalProperty: IDescriptorIntermediateRepresentation[];
/**
* Location(s) at which the Manifest can be refreshed.
*
Expand Down Expand Up @@ -143,6 +147,8 @@ export interface IPeriodChildren {
EventStream: IEventStreamIntermediateRepresentation[];
/** Encryption-related metadata. */
ContentProtection: IContentProtectionIntermediateRepresentation[];
/** Period-level `<SupplementalProperty>` descriptors. */
SupplementalProperty: IDescriptorIntermediateRepresentation[];
}

/* Intermediate representation for A Period node's attributes. */
Expand Down Expand Up @@ -192,10 +198,10 @@ export interface IAdaptationSetChildren {
ContentComponent: IContentComponentIntermediateRepresentation[];
/** Encryption-related metadata. */
ContentProtection: IContentProtectionIntermediateRepresentation[];
EssentialProperty: ISchemeIntermediateRepresentation[];
EssentialProperty: IDescriptorIntermediateRepresentation[];
InbandEventStream: ISchemeIntermediateRepresentation[];
Role: ISchemeIntermediateRepresentation[];
SupplementalProperty: ISchemeIntermediateRepresentation[];
SupplementalProperty: IDescriptorIntermediateRepresentation[];
SegmentBase: ISegmentBaseIntermediateRepresentation[];
SegmentList: ISegmentListIntermediateRepresentation[];
SegmentTemplate: ISegmentTemplateIntermediateRepresentation[];
Expand Down Expand Up @@ -251,8 +257,8 @@ export interface IRepresentationChildren {
SegmentBase: ISegmentBaseIntermediateRepresentation[];
SegmentList: ISegmentListIntermediateRepresentation[];
SegmentTemplate: ISegmentTemplateIntermediateRepresentation[];
SupplementalProperty: ISchemeIntermediateRepresentation[];
EssentialProperty: ISchemeIntermediateRepresentation[];
SupplementalProperty: IDescriptorIntermediateRepresentation[];
EssentialProperty: IDescriptorIntermediateRepresentation[];
}

/* Intermediate representation for A Representation node's attributes. */
Expand Down Expand Up @@ -438,6 +444,29 @@ export interface ISchemeIntermediateRepresentation {
attributes: ISchemeAttributes;
}

/** Shared intermediate representation for DASH descriptor elements. */
export interface IDescriptorIntermediateRepresentation {
attributes: IDescriptorAttributes;
children: {
UrlQueryInfo: IUrlQueryInfoIntermediateRepresentation[];
ExtUrlQueryInfo: IUrlQueryInfoIntermediateRepresentation[];
};
}

/** Parsed DASH Annex I URL query information. */
export interface IUrlQueryInfoIntermediateRepresentation {
attributes: {
queryString?: string | undefined;
queryTemplate?: string | undefined;
includeInRequests?: string | undefined;
useMpdUrlQuery?: boolean | undefined;
};
}

export interface IDescriptorAttributes extends ISchemeAttributes {
id?: string | undefined;
}

export interface ISchemeAttributes {
/**
* Content of the `schemeIdUri` attribute for that scheme.
Expand Down
11 changes: 11 additions & 0 deletions src/parsers/manifest/dash/wasm-parser/rs/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ pub enum TagName {

/// Indicate a `<Location>` node.
Location = 23,

/// Indicate a `<UrlQueryInfo>` node.
UrlQueryInfo = 24,

/// Indicate an `<ExtUrlQueryInfo>` node.
ExtUrlQueryInfo = 25,
}

#[derive(PartialEq, Clone, Copy)]
Expand Down Expand Up @@ -289,6 +295,11 @@ pub enum AttributeName {
EndNumber = 76, // f64

SupplementalCodecs = 77, // string

QueryTemplate = 81, // String
IncludeInRequests = 82, // String
UseMpdUrlQuery = 83, // Boolean
QueryString = 84, // String
}

impl TagName {
Expand Down
29 changes: 29 additions & 0 deletions src/parsers/manifest/dash/wasm-parser/rs/processor/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,35 @@ pub fn report_scheme_attrs(tag_bs: &quick_xml::events::BytesStart) {
}
}

pub fn report_descriptor_attrs(tag_bs: &quick_xml::events::BytesStart) {
for res_attr in tag_bs.attributes() {
match res_attr {
Ok(attr) => match attr.key.as_ref() {
b"id" => Id.try_report_as_string(&attr),
b"schemeIdUri" => SchemeIdUri.try_report_as_string(&attr),
b"value" => SchemeValue.try_report_as_string(&attr),
_ => {}
},
Err(err) => ParsingError::from(err).report_err(),
};
}
}

pub fn report_url_query_info_attrs(tag_bs: &quick_xml::events::BytesStart) {
for res_attr in tag_bs.attributes() {
match res_attr {
Ok(attr) => match attr.key.as_ref() {
b"queryTemplate" => QueryTemplate.try_report_as_string(&attr),
b"queryString" => QueryString.try_report_as_string(&attr),
b"includeInRequests" => IncludeInRequests.try_report_as_string(&attr),
b"useMPDUrlQuery" => UseMpdUrlQuery.try_report_as_bool(&attr),
_ => {}
},
Err(err) => ParsingError::from(err).report_err(),
};
}
}

pub fn report_segment_url_attrs(tag_bs: &quick_xml::events::BytesStart) {
for res_attr in tag_bs.attributes() {
match res_attr {
Expand Down
16 changes: 14 additions & 2 deletions src/parsers/manifest/dash/wasm-parser/rs/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl MPDProcessor {
}
b"EssentialProperty" => {
TagName::EssentialProperty.report_tag_open();
attributes::report_scheme_attrs(&tag);
attributes::report_descriptor_attrs(&tag);
}
b"InbandEventStream" => {
TagName::InbandEventStream.report_tag_open();
Expand All @@ -81,7 +81,7 @@ impl MPDProcessor {
}
b"SupplementalProperty" => {
TagName::SupplementalProperty.report_tag_open();
attributes::report_scheme_attrs(&tag);
attributes::report_descriptor_attrs(&tag);
}
b"SegmentBase" => {
TagName::SegmentBase.report_tag_open();
Expand Down Expand Up @@ -110,6 +110,16 @@ impl MPDProcessor {
attributes::report_scheme_attrs(&tag);
}

// TODO Support other XML prefixes also linked to the `up` namespace.
b"up:UrlQueryInfo" => {
TagName::UrlQueryInfo.report_tag_open();
attributes::report_url_query_info_attrs(&tag);
}
b"up:ExtUrlQueryInfo" => {
TagName::ExtUrlQueryInfo.report_tag_open();
attributes::report_url_query_info_attrs(&tag);
}

b"BaseURL" => {
TagName::BaseURL.report_tag_open();
attributes::report_base_url_attrs(&tag);
Expand Down Expand Up @@ -153,6 +163,8 @@ impl MPDProcessor {
b"SegmentTemplate" => TagName::SegmentTemplate.report_tag_close(),
b"Initialization" => TagName::Initialization.report_tag_close(),
b"UTCTiming" => TagName::UtcTiming.report_tag_close(),
b"up:UrlQueryInfo" => TagName::UrlQueryInfo.report_tag_close(),
b"up:ExtUrlQueryInfo" => TagName::ExtUrlQueryInfo.report_tag_close(),
_ => {}
},
Ok(Event::Eof) => {
Expand Down
Loading
Loading