4

Is HTMLMediaElement.oncanplaythrough event expected to be dispatched multiple times at a single .oncanplaythrough or "canplaythrough" event handler attached to an HTMLMediaElement?

If yes,

  • What are the different state types dispatched at the expected multiple canplaythrough event?

  • How to properly create a condition within the oncanplay event handler to perform a task only when the last expected state type of the canplaythrough event evaluates to true?

guest271314
  • 1
  • 15
  • 104
  • 177
  • 3
    It can fire multiple times if you do change the `currentTime` of your element. However, I'm not sure if it's actually a consequence of buggy cache behavior with range requests, or if it is *expected*. Has to your points, it's a bit hard to get what you are trying to do... For a normal loading file, there is no way to tell so, your video file could be a 10hrs 1080p video, the browser won't keep everything in memory, so if you do change the currentTime, the `canplaythrough` event might fire again. But for small files, you can always `fetch` it entirely as a blob and display the blob. – Kaiido Feb 22 '17 at 02:52
  • @Kaiido The current context chromium 55 ` – guest271314 Feb 22 '17 at 03:01
  • @Kaiido Yes, was using `` to get `File` object, create `Blob URL`. Though have not tried setting a playback range at `Blob URL`. Can a playback range fragment be chained to the `Blob URL` and seek to the specified playback time at media? Came across this issue, looked through MDN first, though difficult to find details of the event there. Shared here, as presumed, evidently erroneously, that the `canplaythrough` event would be dispatched at most once. – guest271314 Feb 22 '17 at 03:17
  • 1
    Why can't you just remove the event listener once it has fired ? Also why are you waiting for the canplaythrough event for your recorder ? It does record a stream, so canplay should be enough. You could even listen for the `pause`, `stalled` or `suspend` events and pause your recorder then. Setting the range-time on blobURI does work in FF and chrome https://jsfiddle.net/qp3ng9sm/. – Kaiido Feb 22 '17 at 03:47
  • @Kaiido Yes. Have tried several different combinations, including `preload` and `autoplay`. Though present Question still stands, am not aware if `canplaythrough` is expected to be dispatched more than once? Just tried again, and the event was dispatched three times, the `.eventPhase` property appears to change at each event. Can probably draft workarounds; am more interested in the specification expected result of the event, both in general and at chromium. This is the present Question – guest271314 Feb 22 '17 at 03:53
  • 1
    But also note that when seeking, your stream that I guess you're getting from `captureStream` may fall in `muted` state. (not sure if it happens, but implementations are so young and with so much bugs...) The recorder will then stop. So you may want to add one step in your process : draw your video on a canvas, record the canvas stream instead. – Kaiido Feb 22 '17 at 03:53
  • @Kaiido Do you mean using `.addTrack()` to include audio at `canvas`? Using `canvas` can overcome the issues described? Have noticed that the playback is not synchronized at video and audio. Ultimately, need to convert `.ogg` to `.mp4` with as little issues as possible. Does not have to be perfect, though the lags should not be seconds. Can you draft and post an implementation which addresses the issues you mentioned? – guest271314 Feb 22 '17 at 03:58
  • 1
    And for your question here are [the specs](https://html.spec.whatwg.org/multipage/embedded-content.html#event-media-canplaythrough) which say *"The user agent **estimates** that [...] the media resource could be rendered **at the current playback rate** all the way to its end without having to stop for further buffering. "*. So first it is an estimation made by the browser. It assumes stable playbackRate and only talk about buffering. When you do change the currentTime, browsers are allowed to buffer your resource again. So yes it is expected that it **can** fire multiple times. – Kaiido Feb 22 '17 at 03:58
  • @Kaiido _"When you do change the currentTime, browsers are allowed to buffer your resource again."_ , _"So yes it is expected that it can fire multiple times."_ Do you mean when the playback itself changes `.currentTime`? Do not seek manually at `controls`, only `.play()` is called at `javascript`. – guest271314 Feb 22 '17 at 04:00
  • No when you seek. Not sure what happens in your chromium that makes it fire 3 times without it. Could you share a fiddle ? For mixing canvas and audio : http://stackoverflow.com/questions/39302814/mediastream-capture-canvas-and-audio-simultaneously/39302994#39302994 for a stable video recording stream : http://stackoverflow.com/questions/39874867/canvas-recording-using-capturestream-and-mediarecorder/39886559#39886559 and you could feed a WebAudio StreamSource with the video element to get a stable video + audio recording. – Kaiido Feb 22 '17 at 04:02
  • The above was performed locally. Will create a jsfiddle. Do you have link to an `.mp4` file server with CORS? Where does the specification state that the event is expected to be dispatched multiple times? – guest271314 Feb 22 '17 at 04:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136297/discussion-between-kaiido-and-guest271314). – Kaiido Feb 22 '17 at 04:10
  • @Kaiido is in right. I have same reasons. – Nikola Lukic May 13 '19 at 12:38

0 Answers0