Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(net): Added advanced type to filters #5006

Merged
merged 3 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion demo/common/asset.js
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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;
16 changes: 11 additions & 5 deletions lib/hls/hls_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1925,7 +1925,7 @@ shaka.hls.HlsParser = class {
const downloadSegmentIndex = async (abortSignal) => {
// Download the actual manifest.
const response = await this.requestManifest_(
streamInfo.absoluteMediaPlaylistUri);
streamInfo.absoluteMediaPlaylistUri, /* isPlaylist= */ true);
if (abortSignal.aborted) {
return;
}
Expand Down Expand Up @@ -3260,10 +3260,11 @@ shaka.hls.HlsParser = class {
* with the resulting data.
*
* @param {string} absoluteUri
* @param {boolean=} isPlaylist
* @return {!Promise.<!shaka.extern.Response>}
* @private
*/
requestManifest_(absoluteUri) {
requestManifest_(absoluteUri, isPlaylist) {
const requestType = shaka.net.NetworkingEngine.RequestType.MANIFEST;

const request = shaka.net.NetworkingEngine.makeRequest(
Expand All @@ -3272,7 +3273,10 @@ shaka.hls.HlsParser = class {
const format = shaka.util.CmcdManager.StreamingFormat.HLS;
this.playerInterface_.modifyManifestRequest(request, {format: format});

return this.makeNetworkRequest_(request, requestType);
const advType = isPlaylist ?
shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST :
undefined;
return this.makeNetworkRequest_(request, requestType, advType);
}

/**
Expand Down Expand Up @@ -3372,18 +3376,20 @@ shaka.hls.HlsParser = class {
*
* @param {shaka.extern.Request} request
* @param {shaka.net.NetworkingEngine.RequestType} type
* @param {shaka.net.NetworkingEngine.AdvancedRequestType=} advType
* @return {!Promise.<shaka.extern.Response>}
* @private
*/
makeNetworkRequest_(request, type) {
makeNetworkRequest_(request, type, advType) {
if (!this.operationManager_) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.PLAYER,
shaka.util.Error.Code.OPERATION_ABORTED);
}

const op = this.playerInterface_.networkingEngine.request(type, request);
const op = this.playerInterface_.networkingEngine.request(
type, request, advType);
this.operationManager_.manage(op);

return op.promise;
Expand Down
17 changes: 12 additions & 5 deletions lib/media/streaming_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -1687,7 +1687,8 @@ shaka.media.StreamingEngine = class {
shaka.log.v1(logPrefix, 'fetching init segment');

const fetchInit =
this.fetch_(mediaState, reference.initSegmentReference);
this.fetch_(mediaState, reference.initSegmentReference,
/* streamDataCallback= */ undefined, /* isInit= */ true);
const append = async () => {
try {
const initSegment = await fetchInit;
Expand Down Expand Up @@ -2068,12 +2069,13 @@ shaka.media.StreamingEngine = class {
* @param {(!shaka.media.InitSegmentReference|!shaka.media.SegmentReference)}
* reference
* @param {?function(BufferSource):!Promise=} streamDataCallback
* @param {boolean=} isInit
*
* @return {!Promise.<BufferSource>}
* @private
* @suppress {strictMissingProperties}
*/
async fetch_(mediaState, reference, streamDataCallback) {
async fetch_(mediaState, reference, streamDataCallback, isInit) {
let op = null;
if (
mediaState.segmentPrefetch &&
Expand All @@ -2083,7 +2085,7 @@ shaka.media.StreamingEngine = class {
}
if (!op) {
op = this.dispatchFetch_(
reference, mediaState.stream, streamDataCallback,
reference, mediaState.stream, streamDataCallback, isInit,
);
}

Expand All @@ -2100,12 +2102,16 @@ shaka.media.StreamingEngine = class {
* @param {(!shaka.media.InitSegmentReference|!shaka.media.SegmentReference)}
* reference
* @param {?function(BufferSource):!Promise=} streamDataCallback
* @param {boolean=} isInit
*
* @return {!shaka.net.NetworkingEngine.PendingRequest}
* @private
*/
dispatchFetch_(reference, stream, streamDataCallback) {
dispatchFetch_(reference, stream, streamDataCallback, isInit) {
const requestType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
const advType = isInit ?
shaka.net.NetworkingEngine.AdvancedRequestType.INIT_SEGMENT :
undefined;

const request = shaka.util.Networking.createSegmentRequest(
reference.getUris(),
Expand All @@ -2131,7 +2137,8 @@ shaka.media.StreamingEngine = class {
bandwidth: stream.bandwidth,
},
);
return this.playerInterface_.netEngine.request(requestType, request);
return this.playerInterface_.netEngine.request(
requestType, request, advType);
}

/**
Expand Down
32 changes: 25 additions & 7 deletions lib/net/networking_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,11 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
*
* @param {shaka.net.NetworkingEngine.RequestType} type
* @param {shaka.extern.Request} request
* @param {shaka.net.NetworkingEngine.AdvancedRequestType=} advType
* @return {!shaka.net.NetworkingEngine.PendingRequest}
* @export
*/
request(type, request) {
request(type, request, advType) {
const ObjectUtils = shaka.util.ObjectUtils;
const numBytesRemainingObj =
new shaka.net.NetworkingEngine.NumBytesRemainingClass();
Expand Down Expand Up @@ -285,12 +286,12 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
request.uris = ObjectUtils.cloneObject(request.uris);

// Apply the registered filters to the request.
const requestFilterOperation = this.filterRequest_(type, request);
const requestFilterOperation = this.filterRequest_(type, request, advType);
const requestOperation = requestFilterOperation.chain(
() => this.makeRequestWithRetry_(type, request, numBytesRemainingObj));
const responseFilterOperation = requestOperation.chain(
(responseAndGotProgress) =>
this.filterResponse_(type, responseAndGotProgress));
this.filterResponse_(type, responseAndGotProgress, advType));

// Keep track of time spent in filters.
const requestFilterStartTime = Date.now();
Expand Down Expand Up @@ -341,10 +342,11 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
/**
* @param {shaka.net.NetworkingEngine.RequestType} type
* @param {shaka.extern.Request} request
* @param {shaka.net.NetworkingEngine.AdvancedRequestType=} advType
* @return {!shaka.util.AbortableOperation.<undefined>}
* @private
*/
filterRequest_(type, request) {
filterRequest_(type, request, advType) {
let filterOperation = shaka.util.AbortableOperation.completed(undefined);

for (const requestFilter of this.requestFilters_) {
Expand All @@ -358,7 +360,7 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
// copying buffers if this is a partial view.
request.body = shaka.util.BufferUtils.toArrayBuffer(request.body);
}
return requestFilter(type, request);
return requestFilter(type, request, advType);
});
}

Expand Down Expand Up @@ -607,11 +609,12 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
* @param {shaka.net.NetworkingEngine.RequestType} type
* @param {shaka.net.NetworkingEngine.ResponseAndGotProgress}
* responseAndGotProgress
* @param {shaka.net.NetworkingEngine.AdvancedRequestType=} advType
* @return {!shaka.extern.IAbortableOperation.<
* shaka.net.NetworkingEngine.ResponseAndGotProgress>}
* @private
*/
filterResponse_(type, responseAndGotProgress) {
filterResponse_(type, responseAndGotProgress, advType) {
let filterOperation = shaka.util.AbortableOperation.completed(undefined);
for (const responseFilter of this.responseFilters_) {
// Response filters are run sequentially.
Expand All @@ -621,7 +624,7 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
// TODO: See TODO in filterRequest_.
resp.data = shaka.util.BufferUtils.toArrayBuffer(resp.data);
}
return responseFilter(type, resp);
return responseFilter(type, resp, advType);
});
}
// If successful, return the filtered response with whether it got
Expand Down Expand Up @@ -752,6 +755,21 @@ shaka.net.NetworkingEngine.RequestType = {
'KEY': 6,
};

/**
* A more advanced form of the RequestType structure, meant to describe
* sub-types of basic request types.
* For example, an INIT_SEGMENT is a sub-type of SEGMENT.
* This is meant to allow for more specificity to be added to the request type
* data, without breaking backwards compatibility.
*
* @enum {number}
* @export
*/
shaka.net.NetworkingEngine.AdvancedRequestType = {
'INIT_SEGMENT': 0,
'MEDIA_PLAYLIST': 1,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have MEDIA_PLAYLIST, we should have MASTER_PLAYLIST and MPD.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, now that it occurs to me, when playing an HLS media playlist directly, we don't know until the playlist is already downloaded...
Well, it's probably fine to say that the request is a master playlist request if we don't know.

};


/**
* Priority level for network scheme plugins.
Expand Down
Loading