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

Async implementation of ProtectionController stop() and reset() to ov… #4478

Draft
wants to merge 1 commit into
base: v4_development
Choose a base branch
from
Draft
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
52 changes: 38 additions & 14 deletions src/streaming/MediaPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ import CustomParametersModel from './models/CustomParametersModel';

/**
* The media types
* @typedef {("video" | "audio" | "text" | "image")} MediaType
* @typedef {('video' | 'audio' | 'text' | 'image')} MediaType
*/

/**
Expand Down Expand Up @@ -1435,10 +1435,13 @@ function MediaPlayer() {
}

if (playbackInitialized) { //Reset if we have been playing before, so this is a new element.
_resetPlaybackControllers();
_resetPlaybackControllers()
.then(() => {
_initializePlayback(providedStartTime);
})
} else {
_initializePlayback(providedStartTime);
}

_initializePlayback(providedStartTime);
}

/**
Expand Down Expand Up @@ -1899,9 +1902,16 @@ function MediaPlayer() {
source = urlOrManifest;

if (streamingInitialized || playbackInitialized) {
_resetPlaybackControllers();
_resetPlaybackControllers()
.then(() => {
_initializePlaybackIfReady()
})
} else {
_initializePlaybackIfReady()
}
}

function _initializePlaybackIfReady() {
if (isReady()) {
_initializePlayback(providedStartTime);
}
Expand Down Expand Up @@ -2150,18 +2160,32 @@ function MediaPlayer() {
abrController.reset();
mediaController.reset();
segmentBaseController.reset();
if (protectionController) {
if (settings.get().streaming.protection.keepProtectionMediaKeys) {
protectionController.stop();
} else {
protectionController.reset();
protectionController = null;
_detectProtection();
}
}
textController.reset();
cmcdModel.reset();
cmsdModel.reset();
return _resetProtectionController()
}

function _resetProtectionController() {
return new Promise((resolve) => {
if (!protectionController) {
resolve()
return
}
if (settings.get().streaming.protection.keepProtectionMediaKeys) {
protectionController.stop()
.finally(() => {
resolve()
})
} else {
protectionController.reset()
.finally(() => {
protectionController = null;
_detectProtection();
resolve()
})
}
})
}

function _createPlaybackControllers() {
Expand Down
42 changes: 27 additions & 15 deletions src/streaming/protection/controllers/ProtectionController.js
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,9 @@ function ProtectionController(config) {
function stop() {
_abortLicenseRequest();
if (protectionModel) {
protectionModel.stop();
return protectionModel.stop();
}
return Promise.resolve;
}

/**
Expand All @@ -585,27 +586,38 @@ function ProtectionController(config) {
* associated with a HTMLMediaElement, it will be detached from that element.
*
* @memberof module:ProtectionController
* @instance
* @ignore
*/
* @instanceignore
*
**/
function reset() {
eventBus.off(events.INTERNAL_KEY_MESSAGE, _onKeyMessage, instance);
eventBus.off(events.INTERNAL_KEY_STATUS_CHANGED, _onKeyStatusChanged, instance);
return new Promise((resolve) => {
eventBus.off(events.INTERNAL_KEY_MESSAGE, _onKeyMessage, instance);
eventBus.off(events.INTERNAL_KEY_STATUS_CHANGED, _onKeyStatusChanged, instance);

checkConfig();
checkConfig();

_abortLicenseRequest();
_abortLicenseRequest();

setMediaElement(null);
setMediaElement(null);

selectedKeySystem = null;
keySystemSelectionInProgress = false;
selectedKeySystem = null;
keySystemSelectionInProgress = false;

if (protectionModel) {
protectionModel.reset();
protectionModel = null;
}
if (protectionModel) {
protectionModel.reset()
.then(() => {
protectionModel = null;
_resetVariablesAfterReset();
resolve();
})
} else {
_resetVariablesAfterReset()
resolve();
}
})
}

function _resetVariablesAfterReset() {
needkeyRetries.forEach(retryTimeout => clearTimeout(retryTimeout));
needkeyRetries = [];

Expand Down
67 changes: 46 additions & 21 deletions src/streaming/protection/models/ProtectionModel_21Jan2015.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,24 @@ function ProtectionModel_21Jan2015(config) {
}

function reset() {
const numSessions = sessions.length;
let session;
return new Promise((resolve, reject) => {
if (sessions.length === 0) {
eventBus.trigger(events.TEARDOWN_COMPLETE);
resolve();
return;
}

if (numSessions !== 0) {
// Called when we are done closing a session. Success or fail
const promises = [];
for (let i = sessions.length - 1; i >= 0; i--) {
promises.push(_resetSingleSession(sessions[i]));
}

return Promise.all(promises);
})
}

function _resetSingleSession(session) {
return new Promise((resolve) => {
const done = function (session) {
removeSession(session);
if (sessions.length === 0) {
Expand All @@ -96,28 +109,36 @@ function ProtectionModel_21Jan2015(config) {
}
}
};
for (let i = 0; i < numSessions; i++) {
session = sessions[i];
(function (s) {
_closeKeySessionInternal(session)
done(s);
})(session);
}
} else {
eventBus.trigger(events.TEARDOWN_COMPLETE);
}

_closeKeySessionInternal(session)
.finally(() => {
done(session);
resolve();
})
})
}

function stop() {
// Close and remove not usable sessions
let session;
for (let i = 0; i < sessions.length; i++) {
session = sessions[i];
const promises = []
for (let i = sessions.length - 1; i >= 0; i--) {
promises.push(_stopSingleSession(sessions[i]));
}

return Promise.all(promises)
}

function _stopSingleSession(session) {
return new Promise((resolve) => {
if (!session.getUsable()) {
_closeKeySessionInternal(session)
removeSession(session);
.finally(() => {
removeSession(session);
resolve();
})
} else {
resolve()
}
}
})
}

function getAllInitData() {
Expand Down Expand Up @@ -413,7 +434,11 @@ function ProtectionModel_21Jan2015(config) {
session.removeEventListener('message', sessionToken);

// Send our request to the key session
return session.close();
return Promise.race([
session.close(),
new Promise((resolve, reject) => {
setTimeout(reject, 500)
})]);
}

// This is our main event handler for all desired HTMLMediaElement events
Expand Down