mirror of
https://github.com/video-dev/hls.js.git
synced 2026-06-16 13:34:44 +00:00
fix(eme-controller): unhandled type error depending on promise state
This commit is contained in:
committed by
Rob Walch
parent
f633b56e0e
commit
97f8d8d3c9
@@ -308,6 +308,7 @@ class EMEController extends Logger implements ComponentAPI {
|
||||
);
|
||||
});
|
||||
return keySystemAccess.then((mediaKeySystemAccess) => {
|
||||
this.throwIfDestroyed();
|
||||
this.log(
|
||||
`Access for key-system "${mediaKeySystemAccess.keySystem}" obtained`,
|
||||
);
|
||||
@@ -1778,6 +1779,9 @@ class EMEController extends Logger implements ComponentAPI {
|
||||
`Selecting key-system from session-keys ${keyFormats.join(', ')}`,
|
||||
);
|
||||
this.keyFormatPromise = this.getKeyFormatPromise(keyFormats);
|
||||
// Until onMediaEncrypted is called this promise is unhandled, add a catch to prevent unhandled rejection
|
||||
// when result is not used.
|
||||
this.keyFormatPromise.catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,12 @@ type EMEControllerTestable = Omit<EMEController, 'hls' | 'mediaKeySessions'> & {
|
||||
data: MediaAttachedData,
|
||||
) => void;
|
||||
onMediaDetached: () => void;
|
||||
onManifestLoaded: (
|
||||
event: Events.MANIFEST_LOADED,
|
||||
data: { sessionKeys: LevelKey[] },
|
||||
) => void;
|
||||
media: HTMLMediaElement | null;
|
||||
keyFormatPromise: Promise<KeySystemFormats> | null;
|
||||
getKeyStatuses: (mediaKeySessionContext: MediaKeySessionContext) => {
|
||||
[keyId: string]: MediaKeyStatus;
|
||||
};
|
||||
@@ -582,6 +587,112 @@ describe('EMEController', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject pending session-key key-system selection with invalid state when destroyed', function () {
|
||||
let resolveKeySystemAccess!: (value: MediaKeySystemAccess) => void;
|
||||
const keySystemAccessPromise = new Promise<MediaKeySystemAccess>(
|
||||
(resolve) => {
|
||||
resolveKeySystemAccess = resolve;
|
||||
},
|
||||
);
|
||||
const createMediaKeysSpy = sinon.spy(() =>
|
||||
Promise.resolve(new MediaKeysMock()),
|
||||
);
|
||||
const reqMediaKsAccessSpy = sinon.spy(() => keySystemAccessPromise);
|
||||
|
||||
setupEach({
|
||||
emeEnabled: true,
|
||||
requestMediaKeySystemAccessFunc: reqMediaKsAccessSpy,
|
||||
drmSystems: {
|
||||
'com.apple.fps': {},
|
||||
},
|
||||
});
|
||||
|
||||
const levelKey = getParsedLevelKey();
|
||||
|
||||
emeController.onManifestLoaded(Events.MANIFEST_LOADED, {
|
||||
sessionKeys: [levelKey],
|
||||
});
|
||||
|
||||
const keyFormatPromise = emeController.keyFormatPromise;
|
||||
if (!keyFormatPromise) {
|
||||
throw new Error('Expected pending key-system selection');
|
||||
}
|
||||
|
||||
emeController.destroy();
|
||||
const mediaKeySystemAccess: MediaKeySystemAccess = {
|
||||
keySystem: KeySystems.FAIRPLAY,
|
||||
createMediaKeys: createMediaKeysSpy,
|
||||
getConfiguration: () => ({}),
|
||||
};
|
||||
resolveKeySystemAccess(mediaKeySystemAccess);
|
||||
|
||||
return keyFormatPromise.then(
|
||||
() => {
|
||||
throw new Error('Expected key-system selection to reject');
|
||||
},
|
||||
(error) => {
|
||||
expect(error).to.be.instanceOf(Error);
|
||||
expect(error.message).to.equal('invalid state');
|
||||
expect(createMediaKeysSpy).not.to.have.been.called;
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle unused session-key key-system selection rejections', function () {
|
||||
let rejectKeySystemAccess!: (error: Error) => void;
|
||||
const keySystemAccessPromise = new Promise<MediaKeySystemAccess>(
|
||||
(resolve, reject) => {
|
||||
rejectKeySystemAccess = reject;
|
||||
},
|
||||
);
|
||||
let unhandledRejection: PromiseRejectionEvent | null = null;
|
||||
const onUnhandledRejection = (event: PromiseRejectionEvent) => {
|
||||
unhandledRejection = event;
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
self.addEventListener('unhandledrejection', onUnhandledRejection);
|
||||
|
||||
setupEach({
|
||||
emeEnabled: true,
|
||||
requestMediaKeySystemAccessFunc: () => keySystemAccessPromise,
|
||||
drmSystems: {
|
||||
'com.apple.fps': {},
|
||||
},
|
||||
});
|
||||
|
||||
emeController.onManifestLoaded(Events.MANIFEST_LOADED, {
|
||||
sessionKeys: [getParsedLevelKey()],
|
||||
});
|
||||
|
||||
const keyFormatPromise = emeController.keyFormatPromise;
|
||||
if (!keyFormatPromise) {
|
||||
throw new Error('Expected key-system selection promise');
|
||||
}
|
||||
|
||||
rejectKeySystemAccess(new Error('key-system access failed'));
|
||||
|
||||
return new Promise<void>((resolve) => {
|
||||
self.setTimeout(resolve, 0);
|
||||
})
|
||||
.then(() => {
|
||||
expect(unhandledRejection).to.equal(null);
|
||||
expect(emeController.hls.trigger).not.to.have.been.called;
|
||||
return keyFormatPromise.then(
|
||||
() => {
|
||||
throw new Error('Expected key-system selection to reject');
|
||||
},
|
||||
(error) => {
|
||||
expect(error).to.be.instanceOf(Error);
|
||||
expect(error.message).to.equal('key-system access failed');
|
||||
},
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
self.removeEventListener('unhandledrejection', onUnhandledRejection);
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove media property when media is detached', function () {
|
||||
const reqMediaKsAccessSpy = sinon.spy(function () {
|
||||
return Promise.resolve({
|
||||
|
||||
Reference in New Issue
Block a user