Closed Shihab-Github closed 1 week ago
I have a video streaming web application and I've used hlsjs for playing video. It can play drm protected videos on web browser but it fails to play drm protected video on Samsung Tizen tv.
You can contribute to DRM work-in-progress by building, testing, and providing feedback on #4930
If you'd like to report this as a bug, please fill out the Bug Report Template as part of your issue, making sure to include:
If the issue is related to your stream, and you cannot share the stream, please include all the information we would need to reproduce the issue. This includes how to generate a stream that reproduces the issue.
Any reason you don't use Samsungs build-in AVPlay ? It supports a lot more Codecs than HLS.js https://developer.samsung.com/smarttv/develop/api-references/samsung-product-api-references/avplay-api.html
Hi @Shihab-Github,
What happens is, the app does not throw any error but it just gets stuck in the player. I am using widevine drm.
There's also #5018 which may address error handling for your use-case. You can test these changes using the netlify/hls-js-dev/deploy-preview checks at the bottom of the PR.
Hi @robwalch, I've ran into a potentially related issue, but it seems to be limited to Tizen 2017 Widevine only. (Although it being this specific might be why this couldn't be reproduced before).
I think it's been introduced as part of this PR, which was merged a few weeks before this issue got raised: https://github.com/video-dev/hls.js/pull/4861
From what I've found so far it seems like there is a deadlock in the player at this Promise.all()
call:
https://github.com/video-dev/hls.js/blob/5705fe26c81848fbfda3e0a8b2df7724f1e2e120/src/controller/base-stream-controller.ts#L874
Tizen 2017 doesn't seem to fire the keystatuseschange
event until any video is buffered, which causes the keyLoadingPromise
promise to hang, which holds back the video from being buffered.
https://sample-videos-zyrkp2nj.s3.eu-west-1.amazonaws.com/test-20240828/index.html https://sample-videos-zyrkp2nj.s3.eu-west-1.amazonaws.com/test-20240828/index.fixed.html I've created two sample pages with latest (1.5.11) hls.js version with this slight difference, and the TV is now able to play the stream.
Could you provide some context as to why we need to await the keyLoadingPromise
prior to pushing the video, and if you have any potential solutions?
Thank you!
Edit: I realize this issue currently lacks the necessary fields from Bug Report Template, but one of the Checklist items was to make sure to no duplicate issues that already exist here. Would you like me to raise a separate issue with all the required info?
Hi @grabofus,
Would you like me to raise a separate issue with all the required info?
No worries. Your description fits the title and gives the issue something we can act on so unless @Shihab-Github responds with reproduction steps, we can proceed here.
I've created two sample pages with latest (1.5.11) hls.js version with this slight difference, and the TV is now able to play the stream.
The latest release is 1.5.15. Have you tried it? There are some improvements for playlists and media with Widevine and PlayReady keys.
We do not want to change or reverse the changes made in #4861 to process keys and segments in parallel.
The keyLoadingPromise
Promise is blocked by the keyUsablePromise
in eme-controller:
A change will be needed to eme-controller in loadKey
to return a promise that resolves earlier or a larger change to generateRequestWithPreferredKeySession: Promise<MediaKeySessionContext> | never
and parts of the controller that that would impact to handle key-status changes outside of the the session context promise.
A change will be needed to eme-controller in loadKey to return a promise that resolves earlier
Here's an example:
diff --git a/src/controller/eme-controller.ts b/src/controller/eme-controller.ts
index dfa30d249..c76ca89de 100644
--- a/src/controller/eme-controller.ts
+++ b/src/controller/eme-controller.ts
@@ -426,38 +426,41 @@ class EMEController extends Logger implements ComponentAPI {
this.log(`Starting session for key ${keyDetails}`);
- let keySessionContextPromise = this.keyIdToKeySessionPromise[keyId];
- if (!keySessionContextPromise) {
- keySessionContextPromise = this.keyIdToKeySessionPromise[keyId] =
- this.getKeySystemForKeyPromise(decryptdata).then(
- ({ keySystem, mediaKeys }) => {
+ let keyContextPromise = this.keyIdToKeySessionPromise[keyId];
+ if (!keyContextPromise) {
+ keyContextPromise = this.getKeySystemForKeyPromise(decryptdata).then(
+ ({ keySystem, mediaKeys }) => {
+ this.throwIfDestroyed();
+ this.log(
+ `Handle encrypted media sn: ${data.frag.sn} ${data.frag.type}: ${data.frag.level} using key ${keyDetails}`,
+ );
+
+ return this.attemptSetMediaKeys(keySystem, mediaKeys).then(() => {
this.throwIfDestroyed();
- this.log(
- `Handle encrypted media sn: ${data.frag.sn} ${data.frag.type}: ${data.frag.level} using key ${keyDetails}`,
- );
-
- return this.attemptSetMediaKeys(keySystem, mediaKeys).then(() => {
- this.throwIfDestroyed();
- const keySessionContext = this.createMediaKeySessionContext({
- keySystem,
- mediaKeys,
- decryptdata,
- });
- const scheme = 'cenc';
- return this.generateRequestWithPreferredKeySession(
- keySessionContext,
- scheme,
- decryptdata.pssh,
- 'playlist-key',
- );
+ return this.createMediaKeySessionContext({
+ keySystem,
+ mediaKeys,
+ decryptdata,
});
- },
- );
+ });
+ },
+ );
+
+ const keySessionContextPromise = (this.keyIdToKeySessionPromise[keyId] =
+ keyContextPromise.then((keySessionContext) => {
+ const scheme = 'cenc';
+ return this.generateRequestWithPreferredKeySession(
+ keySessionContext,
+ scheme,
+ decryptdata.pssh,
+ 'playlist-key',
+ );
+ }));
keySessionContextPromise.catch((error) => this.handleError(error));
}
- return keySessionContextPromise;
+ return keyContextPromise;
}
private throwIfDestroyed(message = 'Invalid state'): void | never {
Does this resolve the issue for you?
The latest release is 1.5.15. Have you tried it? There are some improvements for playlists and media with Widevine and PlayReady keys.
You're right, my comment was incorrect. The demo page I've provided uses 1.5.15 and the issue is reproducible there.
I'll try the suggested change out soon
@robwalch your proposed change works on the TV! 🚀 thank you for the quick response!
@robwalch your proposed change works on the TV! 🚀 thank you for the quick response!
Hi @grabofus. Great! Would you mind submitting a PR with the change so that we can get that in v1.6?
PR raised ~
What do you want to do with Hls.js?
I have a video streaming web application and I've used hlsjs for playing video. It can play drm protected videos on web browser but it fails to play drm protected video on Samsung Tizen tv. What happens is, the app does not throw any error but it just gets stuck in the player. I am using widevine drm.
What have you tried so far?
I have followed the code from hls documentation. It looks like this:
getDrmLicense(single_movie, function () {
PLAYER.player_options.emeEnabled = true;
PLAYER.player_options.widevineLicenseUrl = drm_license_url;
PLAYER.start(url, bongo_id, true);
});