Skip to content

Commit

Permalink
feat(net): Added advanced type to filters (shaka-project#5006)
Browse files Browse the repository at this point in the history
This adds an optional parameter to request and response filters, of a
new enum called AdvancedRequestType.
This enum describes request types that are subtypes of the basic types.
For example, INIT_SEGMENT is a type of SEGMENT.
This gives users more information about the type of the request, while
maintaining backwards compatibility.

Closes shaka-project#4966
  • Loading branch information
theodab committed Feb 23, 2023
1 parent 25fc81e commit fbce38a
Show file tree
Hide file tree
Showing 24 changed files with 265 additions and 155 deletions.
3 changes: 2 additions & 1 deletion demo/common/asset.js
Expand Up @@ -372,7 +372,8 @@ const ShakaDemoAssetInfo = class {
networkingEngine.clearAllResponseFilters();

if (this.licenseRequestHeaders.size) {
const filter = (requestType, request) => {
/** @type {!shaka.extern.RequestFilter} */
const filter = (requestType, request, advType) => {
return this.addLicenseRequestHeaders_(this.licenseRequestHeaders,
requestType,
request);
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/ad_monetization.md
Expand Up @@ -203,7 +203,7 @@ default, so you should only need to set this if you've enabled it in other parts
your code.

```js
player.getNetworkingEngine().registerRequestFilter(function(type, request) {
player.getNetworkingEngine().registerRequestFilter(function(type, request, advType) {
if (type == shaka.net.NetworkingEngine.RequestType.MANIFEST ||
type == shaka.net.NetworkingEngine.RequestType.SEGMENT) {
request.withCredentials = false;
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/application-level-redirects.md
Expand Up @@ -36,7 +36,7 @@ const HTTP_IN_HEX = 0x68747470;

const RequestType = shaka.net.NetworkingEngine.RequestType;

player.getNetworkingEngine().registerResponseFilter(async (type, response) => {
player.getNetworkingEngine().registerResponseFilter(async (type, response, advType) => {
// NOTE: If the system requires an ALR for both manifests and segments,
// remove this RequestType check.
if (type != RequestType.MANIFEST) {
Expand Down
8 changes: 4 additions & 4 deletions docs/tutorials/fairplay.md
Expand Up @@ -90,7 +90,7 @@ or give the response in a different format. For more info, see the general
{@tutorial license-wrapping} tutorial:

```js
player.getNetworkingEngine().registerRequestFilter((type, request) => {
player.getNetworkingEngine().registerRequestFilter((type, request, advType) => {
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
return;
}
Expand All @@ -103,7 +103,7 @@ player.getNetworkingEngine().registerRequestFilter((type, request) => {
request.body = shaka.util.StringUtils.toUTF8(encodeURIComponent(params));
});

player.getNetworkingEngine().registerResponseFilter((type, response) => {
player.getNetworkingEngine().registerResponseFilter((type, response, advType) => {
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
return;
}
Expand Down Expand Up @@ -143,7 +143,7 @@ Note: If the url of the license server has to undergo any transformation
(eg: add the contentId), you would have to create your filter manually.

```js
player.getNetworkingEngine().registerRequestFilter((type, request) => {
player.getNetworkingEngine().registerRequestFilter((type, request, advType) => {
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
return;
}
Expand Down Expand Up @@ -175,7 +175,7 @@ Note: If the url of the license server has to undergo any transformation
(eg: add the contentId), you would have to create your filter manually.

```js
player.getNetworkingEngine().registerRequestFilter((type, request) => {
player.getNetworkingEngine().registerRequestFilter((type, request, advType) => {
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
return;
}
Expand Down
8 changes: 4 additions & 4 deletions docs/tutorials/license-server-auth.md
Expand Up @@ -62,7 +62,7 @@ arbitrary headers to Shaka's requests through a request filter callback.
Register the filter before calling `player.load()`:

```js
player.getNetworkingEngine().registerRequestFilter(function(type, request) {
player.getNetworkingEngine().registerRequestFilter(function(type, request, advType) {
// Only add headers to license requests:
if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
// This is the specific header name and value the server wants:
Expand Down Expand Up @@ -92,7 +92,7 @@ try to use it without setting the parameter, you will see `Error code 6007`
We can use a request filter to modify the URL and add the required parameter:

```js
player.getNetworkingEngine().registerRequestFilter(function(type, request) {
player.getNetworkingEngine().registerRequestFilter(function(type, request, advType) {
// Only add headers to license requests:
if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
// This is the specific parameter name and value the server wants:
Expand Down Expand Up @@ -140,7 +140,7 @@ Our `cookie_auth` endpoint sends back headers that allow credentialed requests,
so we set a flag in our request filter to send credentials cross-site:

```js
player.getNetworkingEngine().registerRequestFilter(function(type, request) {
player.getNetworkingEngine().registerRequestFilter(function(type, request, advType) {
if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
request.allowCrossSiteCredentials = true;
}
Expand Down Expand Up @@ -205,7 +205,7 @@ const authToken = null;
Now change the request filter:

```js
player.getNetworkingEngine().registerRequestFilter(function(type, request) {
player.getNetworkingEngine().registerRequestFilter(function(type, request, advType) {
// Only add headers to license requests:
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) return;

Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/license-wrapping.md
Expand Up @@ -65,7 +65,7 @@ will see `Error code 6007`, which means `LICENSE_REQUEST_FAILED`. To wrap the
license request, we must register a request filter:

```js
player.getNetworkingEngine().registerRequestFilter(function(type, request) {
player.getNetworkingEngine().registerRequestFilter(function(type, request, advType) {
// Alias some utilities provided by the library.
const StringUtils = shaka.util.StringUtils;
const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
Expand Down Expand Up @@ -136,7 +136,7 @@ Widevine CDM does not understand this wrapped format, so we must unwrap it first
using a request filter:

```js
player.getNetworkingEngine().registerResponseFilter(function(type, response) {
player.getNetworkingEngine().registerResponseFilter(function(type, response, advType) {
// Alias some utilities provided by the library.
const StringUtils = shaka.util.StringUtils;
const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
Expand Down
16 changes: 12 additions & 4 deletions externs/shaka/net.js
Expand Up @@ -202,12 +202,16 @@ shaka.extern.HeadersReceived;
/**
* Defines a filter for requests. This filter takes the request and modifies
* it before it is sent to the scheme plugin.
* The RequestType describes the basic type of the request (manifest, segment,
* etc). The optional AdvancedRequestType will be provided in the case of a
* sub-type of the basic type (playlist manifest, init segment, etc).
* A request filter can run asynchronously by returning a promise; in this case,
* the request will not be sent until the promise is resolved.
*
* @typedef {!function(shaka.net.NetworkingEngine.RequestType,
* shaka.extern.Request):
(Promise|undefined)}
* shaka.extern.Request,
* shaka.net.NetworkingEngine.AdvancedRequestType=):
* (Promise|undefined)}
* @exportDoc
*/
shaka.extern.RequestFilter;
Expand All @@ -216,11 +220,15 @@ shaka.extern.RequestFilter;
/**
* Defines a filter for responses. This filter takes the response and modifies
* it before it is returned.
* The RequestType describes the basic type of the request (manifest, segment,
* etc). The optional AdvancedRequestType will be provided in the case of a
* sub-type of the basic type (playlist manifest, init segment, etc).
* A response filter can run asynchronously by returning a promise.
*
* @typedef {!function(shaka.net.NetworkingEngine.RequestType,
* shaka.extern.Response):
(Promise|undefined)}
* shaka.extern.Response,
* shaka.net.NetworkingEngine.AdvancedRequestType=):
* (Promise|undefined)}
* @exportDoc
*/
shaka.extern.ResponseFilter;
24 changes: 15 additions & 9 deletions lib/dash/dash_parser.js
Expand Up @@ -222,6 +222,7 @@ shaka.dash.DashParser = class {
*/
async requestManifest_() {
const requestType = shaka.net.NetworkingEngine.RequestType.MANIFEST;
const advType = shaka.net.NetworkingEngine.AdvancedRequestType.MPD;
const request = shaka.net.NetworkingEngine.makeRequest(
this.manifestUris_, this.config_.retryParameters);
const networkingEngine = this.playerInterface_.networkingEngine;
Expand All @@ -230,7 +231,7 @@ shaka.dash.DashParser = class {
this.playerInterface_.modifyManifestRequest(request, {format: format});

const startTime = Date.now();
const operation = networkingEngine.request(requestType, request);
const operation = networkingEngine.request(requestType, request, advType);
this.operationManager_.manage(operation);

const response = await operation.promise;
Expand Down Expand Up @@ -1175,20 +1176,20 @@ shaka.dash.DashParser = class {
const isImage = contentType == ContentType.IMAGE;

try {
const requestInitSegment = (uris, startByte, endByte) => {
return this.requestInitSegment_(uris, startByte, endByte);
const requestSegment = (uris, startByte, endByte, isInit) => {
return this.requestSegment_(uris, startByte, endByte, isInit);
};
if (context.representation.segmentBase) {
streamInfo = shaka.dash.SegmentBase.createStreamInfo(
context, requestInitSegment);
context, requestSegment);
} else if (context.representation.segmentList) {
streamInfo = shaka.dash.SegmentList.createStreamInfo(
context, this.streamMap_);
} else if (context.representation.segmentTemplate) {
const hasManifest = !!this.manifest_;

streamInfo = shaka.dash.SegmentTemplate.createStreamInfo(
context, requestInitSegment, this.streamMap_, hasManifest,
context, requestSegment, this.streamMap_, hasManifest,
this.config_.dash.initialSegmentLimit, this.periodDurations_);
} else {
goog.asserts.assert(isText,
Expand Down Expand Up @@ -1830,11 +1831,15 @@ shaka.dash.DashParser = class {
* @param {!Array.<string>} uris
* @param {?number} startByte
* @param {?number} endByte
* @param {boolean} isInit
* @return {!Promise.<BufferSource>}
* @private
*/
async requestInitSegment_(uris, startByte, endByte) {
async requestSegment_(uris, startByte, endByte, isInit) {
const requestType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
const advType = isInit ?
shaka.net.NetworkingEngine.AdvancedRequestType.INIT_SEGMENT :
shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT;

const request = shaka.util.Networking.createSegmentRequest(
uris,
Expand All @@ -1843,7 +1848,7 @@ shaka.dash.DashParser = class {
this.config_.retryParameters);

const networkingEngine = this.playerInterface_.networkingEngine;
const operation = networkingEngine.request(requestType, request);
const operation = networkingEngine.request(requestType, request, advType);
this.operationManager_.manage(operation);
const response = await operation.promise;
return response.data;
Expand Down Expand Up @@ -1886,10 +1891,11 @@ shaka.dash.DashParser.MIN_UPDATE_PERIOD_ = 3;

/**
* @typedef {
* function(!Array.<string>, ?number, ?number):!Promise.<BufferSource>
* function(!Array.<string>, ?number, ?number, boolean):
* !Promise.<BufferSource>
* }
*/
shaka.dash.DashParser.RequestInitSegmentCallback;
shaka.dash.DashParser.RequestSegmentCallback;


/**
Expand Down
26 changes: 12 additions & 14 deletions lib/dash/segment_base.js
Expand Up @@ -70,11 +70,10 @@ shaka.dash.SegmentBase = class {
* Creates a new StreamInfo object.
*
* @param {shaka.dash.DashParser.Context} context
* @param {shaka.dash.DashParser.RequestInitSegmentCallback}
* requestInitSegment
* @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
* @return {shaka.dash.DashParser.StreamInfo}
*/
static createStreamInfo(context, requestInitSegment) {
static createStreamInfo(context, requestSegment) {
goog.asserts.assert(context.representation.segmentBase,
'Should only be called with SegmentBase');
// Since SegmentBase does not need updates, simply treat any call as
Expand Down Expand Up @@ -111,7 +110,7 @@ shaka.dash.SegmentBase = class {
return {
generateSegmentIndex: () => {
return SegmentBase.generateSegmentIndex_(
shallowCopyOfContext, requestInitSegment, initSegmentReference,
shallowCopyOfContext, requestSegment, initSegmentReference,
scaledPresentationTimeOffset);
},
};
Expand All @@ -121,8 +120,7 @@ shaka.dash.SegmentBase = class {
* Creates a SegmentIndex for the given URIs and context.
*
* @param {shaka.dash.DashParser.Context} context
* @param {shaka.dash.DashParser.RequestInitSegmentCallback}
* requestInitSegment
* @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
* @param {shaka.media.InitSegmentReference} initSegmentReference
* @param {!Array.<string>} uris
* @param {number} startByte
Expand All @@ -131,7 +129,7 @@ shaka.dash.SegmentBase = class {
* @return {!Promise.<shaka.media.SegmentIndex>}
*/
static async generateSegmentIndexFromUris(
context, requestInitSegment, initSegmentReference, uris, startByte,
context, requestSegment, initSegmentReference, uris, startByte,
endByte, scaledPresentationTimeOffset) {
// Unpack context right away, before we start an async process.
// This immunizes us against changes to the context object later.
Expand All @@ -143,16 +141,17 @@ shaka.dash.SegmentBase = class {
const containerType = context.representation.mimeType.split('/')[1];

// Create a local variable to bind to so we can set to null to help the GC.
let localRequest = requestInitSegment;
let localRequest = requestSegment;
let segmentIndex = null;

const responses = [
localRequest(uris, startByte, endByte),
localRequest(uris, startByte, endByte, /* isInit= */ false),
containerType == 'webm' ?
localRequest(
initSegmentReference.getUris(),
initSegmentReference.startByte,
initSegmentReference.endByte) :
initSegmentReference.endByte,
/* isInit= */ true) :
null,
];

Expand Down Expand Up @@ -327,15 +326,14 @@ shaka.dash.SegmentBase = class {
* Generate a SegmentIndex from a Context object.
*
* @param {shaka.dash.DashParser.Context} context
* @param {shaka.dash.DashParser.RequestInitSegmentCallback}
* requestInitSegment
* @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
* @param {shaka.media.InitSegmentReference} initSegmentReference
* @param {number} scaledPresentationTimeOffset
* @return {!Promise.<shaka.media.SegmentIndex>}
* @private
*/
static generateSegmentIndex_(
context, requestInitSegment, initSegmentReference,
context, requestSegment, initSegmentReference,
scaledPresentationTimeOffset) {
const SegmentBase = shaka.dash.SegmentBase;

Expand All @@ -344,7 +342,7 @@ shaka.dash.SegmentBase = class {
goog.asserts.assert(indexRange, 'Index range should not be null!');

return shaka.dash.SegmentBase.generateSegmentIndexFromUris(
context, requestInitSegment, initSegmentReference, indexUris,
context, requestSegment, initSegmentReference, indexUris,
indexRange.start, indexRange.end,
scaledPresentationTimeOffset);
}
Expand Down
14 changes: 6 additions & 8 deletions lib/dash/segment_template.js
Expand Up @@ -28,8 +28,7 @@ shaka.dash.SegmentTemplate = class {
* Updates the existing SegmentIndex, if any.
*
* @param {shaka.dash.DashParser.Context} context
* @param {shaka.dash.DashParser.RequestInitSegmentCallback}
* requestInitSegment
* @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
* @param {!Object.<string, !shaka.extern.Stream>} streamMap
* @param {boolean} isUpdate True if the manifest is being updated.
* @param {number} segmentLimit The maximum number of segments to generate for
Expand All @@ -38,7 +37,7 @@ shaka.dash.SegmentTemplate = class {
* @return {shaka.dash.DashParser.StreamInfo}
*/
static createStreamInfo(
context, requestInitSegment, streamMap, isUpdate, segmentLimit,
context, requestSegment, streamMap, isUpdate, segmentLimit,
periodDurationMap) {
goog.asserts.assert(context.representation.segmentTemplate,
'Should only be called with SegmentTemplate');
Expand All @@ -62,7 +61,7 @@ shaka.dash.SegmentTemplate = class {
return {
generateSegmentIndex: () => {
return SegmentTemplate.generateSegmentIndexFromIndexTemplate_(
shallowCopyOfContext, requestInitSegment, initSegmentReference,
shallowCopyOfContext, requestSegment, initSegmentReference,
info);
},
};
Expand Down Expand Up @@ -253,15 +252,14 @@ shaka.dash.SegmentTemplate = class {
* Generates a SegmentIndex from an index URL template.
*
* @param {shaka.dash.DashParser.Context} context
* @param {shaka.dash.DashParser.RequestInitSegmentCallback}
* requestInitSegment
* @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
* @param {shaka.media.InitSegmentReference} init
* @param {shaka.dash.SegmentTemplate.SegmentTemplateInfo} info
* @return {!Promise.<shaka.media.SegmentIndex>}
* @private
*/
static generateSegmentIndexFromIndexTemplate_(
context, requestInitSegment, init, info) {
context, requestSegment, init, info) {
const MpdUtils = shaka.dash.MpdUtils;
const ManifestParserUtils = shaka.util.ManifestParserUtils;

Expand All @@ -274,7 +272,7 @@ shaka.dash.SegmentTemplate = class {
context.representation.baseUris, [filledTemplate]);

return shaka.dash.SegmentBase.generateSegmentIndexFromUris(
context, requestInitSegment, init, resolvedUris, 0, null,
context, requestSegment, init, resolvedUris, 0, null,
info.scaledPresentationTimeOffset);
}

Expand Down

0 comments on commit fbce38a

Please sign in to comment.