videojs / http-streaming

HLS, DASH, and future HTTP streaming protocols library for video.js
https://videojs-http-streaming.netlify.app/
Other
2.49k stars 421 forks source link

Cannot perform Construct on a detached ArrayBuffer #1276

Open wg-daniel opened 2 years ago

wg-daniel commented 2 years ago

Description

We are encountering some errors that we cannot place (or reproduce for that matter). Not sure if it's a bug or even an end-user problem at all. :shrug: Main question is, if anyone can place what is happening here and has an idea of what the impact can be.

Steps to reproduce

Unkown

Results

Error output

TypeError: Cannot perform Construct on a detached ArrayBuffer
  at new Uint8Array(<anonymous>)
  at apply(./node_modules/video.js/dist/video.cjs.js:41390:25)
  at Worker.i(./node_modules/@sentry/browser/esm/helpers.js:73:23)

Additional Information

Please include any additional information necessary here. Including the following:

versions

videojs

7.17.0

browsers

Chromium-based browsers (Chrome, Chrome mobile, Edge, Samsung Internet)

OSes

Android, Windows, Mac OSx

plugins

None

welcome[bot] commented 2 years ago

👋 Thanks for opening your first issue here! 👋

If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can. To help make it easier for us to investigate your issue, please follow the contributing guidelines.

welcome[bot] commented 2 years ago

👋 Thanks for opening your first issue here! 👋

If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can. To help make it easier for us to investigate your issue, please follow the contributing guidelines.

misteroneill commented 2 years ago

I see at Worker.i in there - does that mean this is attempting to run in a Web Worker? That class name doesn't appear to come from Sentry, but it does come from Web Workers.

If so, Media Source Extensions does not currently work in Web Workers. There appears to be ongoing discussion in the W3C on if/how to enable this.

wg-daniel commented 2 years ago

@misteroneill Thanks for your reply! I expect that Sentry is somehow leveraging Web Workers?

Did some more searching in the issues and found this checklist mentioning ID3 que data and Uint8Array.

Since we are injecting ID3 tags into our hls stream, I expect this to be the cause.

kylekirkby commented 2 years ago

We've also just had this error with Sentry.

TypeError: Cannot perform Construct on a detached ArrayBuffer
  at new Uint8Array(<anonymous>)
  at apply(./node_modules/@videojs/http-streaming/dist/videojs-http-streaming.es.js:13161:25)
  at Worker.i(./node_modules/@sentry/browser/esm/helpers.js:73:23)
wg-daniel commented 2 years ago

@kylekirkby Are you using ID3 tags as well (that you are aware of?)

Sorry for cross-tagging you here, @mister-ben. I saw that you mentioned ID3 que data as a fix for a new major version. As it seems quite hard to replicate the issue, can you perhaps give an idea of what actual impact there is in these situations?

kylekirkby commented 2 years ago

@wg-daniel we are processing our videos with AWS MediaConvert utilising some of the defaults that amplify-video has given us for our MediaConvert templates. I've just done a search in the repo and found this config which suggests we are using Id3 tags:

                "OutputGroupSettings": {
                    "Type": "HLS_GROUP_SETTINGS",
                    "HlsGroupSettings": {
                        "ManifestDurationFormat": "INTEGER",
                        "SegmentLength": 10,
                        "TimedMetadataId3Period": 10,
                        "CaptionLanguageSetting": "OMIT",
                        "TimedMetadataId3Frame": "PRIV",
                        "CodecSpecification": "RFC_4281",
                        "OutputSelection": "MANIFESTS_AND_SEGMENTS",
                        "ProgramDateTimePeriod": 600,
                        "MinSegmentLength": 0,
                        "MinFinalSegmentLength": 0,
                        "DirectoryStructure": "SINGLE_DIRECTORY",
                        "ProgramDateTime": "EXCLUDE",
                        "SegmentControl": "SEGMENTED_FILES",
                        "ManifestCompression": "NONE",
                        "ClientCache": "ENABLED",
                        "StreamInfResolution": "INCLUDE"
                    }
                }

https://docs.aws.amazon.com/mediaconvert/latest/apireference/jobs-id.html

mister-ben commented 2 years ago

My comment about ID3 would be a red herring here. It's about doing presenting them more like Safari's native tracks, so you wouldn't have to convert from the Uint8Array that's returned at that point. A convenience when reading the cues from the texttrack, a good step removed from whatever is happening here.

misteroneill commented 2 years ago

We can keep this open for the time being, but I believe it may be a VHS issue.

@wg-daniel Do you have any idea of the impact? In other words, is this happening to a lot of users or just some?

phloxic commented 2 years ago

May be related, I just ran into 'Uncaught TypeError: attempting to access detached ArrayBuffer' after upgrading to 7.19.0 (maybe I did not notice it before). No id3 tags, but hls subtitles, Firefox MacOS - so, yes, possibly VHS. Can't reproduce it so far, sorry.

wg-daniel commented 2 years ago

@mister-ben Thanks for your reply. Much appreciated!

@misteroneill It's hard to reproduce indeed. We have about 4 users a day experiencing this mid-stream. It's hard to define impact since I'm not sure anything breaks from a user perspective.

Since you think this might me a VHS issue, does that mean this issue needs to be moved to that repository to make them aware?

misteroneill commented 2 years ago

@wg-daniel Yeah, I think that's best. If you don't mind creating the issue here, that would be a big help!

Fair warning on this, it will probably be a while before anyone has a chance to look into it.

schw4rzlicht commented 2 years ago

I have seen this in Sentry today as well, impacting one user so far.

Windows 10, Chrome 100.0.4896

nuevodevel commented 2 years ago

I have found this error "Cannot perform Construct on a detached ArrayBuffer" when fast scrubbing through video (usually scrubbing back). The only thing I could do was to enclose the line of code:

event.data.data = new Uint8Array(event.data.data, options.byteOffset || 0, options.byteLength || event.data.data.byteLength);

into try-catch statement:

try{event.data.data = new Uint8Array(event.data.data, options.byteOffset || 0, options.byteLength || event.data.data.byteLength);}catch(e){}

The error is gone forever, playback and scrubbing performance do not change.

ryan-berger commented 2 years ago

@misteroneill Our company is also having this issue on VideoJS 7.17.0 and 7.20.2. We are also using Amazon's Elastic Encoder to encode all our videos.

We've been able to reproduce on Windows 10 with Chrome. Sentry's error boundary seems to be catching the issue, and the player doesn't seem to crash.

We're receiving a couple of thousand of these a week, so it would be nice to have it resolved.

As @nuevodevel said, we seem to have the issue when we are scrubbing mostly backwards, but sometimes forwards. It takes a bit of patience to get the scrubbing to trigger it, but we can reliably reproduce it doing this.

We see a pattern of duplicate segments being fetched, and after they all resolve, this error pops up.

I'm wondering if this is some sort of race condition causing multiple workerCallbacks to come back, and one of them is winning over the others meaning that the callback runs with stale data.

We are also receiving this extra info on Chrome for iOS on iPads at the exact same line: TypeError: Underlying ArrayBuffer has been detached from the view

And although I don't understand VideoJS enough for this to mean anything to me, this seems like a callback is run with stale data or something of the sort. We are using React, which may be of some use if we are re-rendering somehow causing the callback to use stale data, but I'm not a React dev, and I don't understand these things.

bettysteger commented 1 year ago

any news? we've got the same issue and i think some users are not getting the 'ended' event when this happens...

ssimonitch commented 6 months ago

This is still occurring for me as well. I can replicate on MacOS Chrome while fast scrubbing back and forth on an HLS stream.

wg-daniel commented 2 months ago

For anyone that wants this error gone from their error reporting systems. :wave:

We used patch-package to simply wrap the culprit in a try catch. As far as we know, there are no complaints on a broken experience. We just want to silence it and not impact the billing on our error reporting. :money_with_wings:

patches/video.js+8.6.1.patch

diff --git a/node_modules/video.js/dist/video.es.js b/node_modules/video.js/dist/video.es.js
index 296da64..6eedec6 100644
--- a/node_modules/video.js/dist/video.es.js
+++ b/node_modules/video.js/dist/video.es.js
@@ -38922,7 +38922,12 @@ const workerCallback = function (options) {
     transmuxer.removeEventListener('message', listenForEndEvent); // transfer ownership of bytes back to us.

     if (event.data.data) {
-      event.data.data = new Uint8Array(event.data.data, options.byteOffset || 0, options.byteLength || event.data.data.byteLength);
+      try {
+        event.data.data = new Uint8Array(event.data.data, options.byteOffset || 0, options.byteLength || event.data.data.byteLength);
+      } catch (e) {
+        console.warning(e);
+      }
+
       if (options.data) {
         options.data = event.data.data;
       }