如何在 canplay 事件中设置 HTMLMediaElement 的 .currentTime,调用 play 并避免调度 pause 事件?

Posted

技术标签:

【中文标题】如何在 canplay 事件中设置 HTMLMediaElement 的 .currentTime,调用 play 并避免调度 pause 事件?【英文标题】:How to set .currentTime of HTMLMediaElement within canplay event, call play and avoid dispatching pause event? 【发布时间】:2018-02-28 19:19:26 【问题描述】:

在调用 .play() 之前在 canplay 事件中设置 htmlMediaElement.currentTime 时,将调度 pause 事件。

在设置.currentTime 后尝试在canplay 事件中调用.play() 并引发错误

DOMException: The play() request was interrupted by a call to pause().

如何在HTMLMediaElementHTMLMediaElementcanplaycanplaythrough 事件中设置.currentTime 而不调度pause 事件,或者如何从pause 事件处理程序中调用.play() 以从该集合开始媒体播放.currentTime?

<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <video preload="auto" controls></video>
  <span></span>
  <script>
    const url = "https://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm#t=10,15";

    const video = document.querySelector("video");

    let cursor = 10.5;

    video.oncanplay = e => 
      video.oncanplay = null;
      video.currentTime = cursor;
      console.log(e, video.currentTime, video.buffered.end(0));
      video.play().catch(err => document.querySelector("span").textContent = err.message);
    

    video.onpause = e => 
      console.log(e, video.currentTime);
    

    video.src = url;
  </script>
</body>

</html>

【问题讨论】:

【参考方案1】:

这是你遇到的一个非常奇怪的错误,我不确定它来自哪里,也不知道你遇到它的几率是多少。

如果我没记错的话,当您设置currentTime 属性时,chrome 将不再支持src 的时间范围#t=start,end 参数。

所以他们会有点忘记它,并表现得好像您通过了end 阈值并因此暂停视频。

但真正奇怪的地方在于,在尝试编写测试用例时,我发现这仅发生在 canplay 事件中,仅在此视频中发生,并且仅在时间范围设置为 10,15 时发生.

将其设置为 #t=10.0,15它可以工作。 将其设置为 #t=10,15.0它可以工作。 将其设置为任何其他值,它似乎可以工作 (不,我没有测试所有可能的值)。 在另一个视频上将其设置为 #t=10,15它可以工作。 在同一视频上将其设置为 #t=10,15,但由其他服务器提供,不起作用...

  // changed the #t parameter
  const url = "https://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm#t=10.0,15";

    const video = document.querySelector("video");

    let cursor = 10.5;

    video.oncanplay = e => 
      video.oncanplay = null;
      video.currentTime = cursor;
      console.log(e, video.currentTime, video.buffered.end(0));
      video.play().catch(err => document.querySelector("span").textContent = err.message);
    

    video.onpause = e => 
      console.log(e, video.currentTime);
    

    video.src = url;
  <video preload="auto" controls></video>
  <span></span>

所以对于真正的修复,我认为https://bugs.chromium.org/p/chromium/issues/ 仍然是最好的方法,但我不确定他们会告诉你什么,因为这似乎与视频文件本身高度相关。

【讨论】:

为了它的价值,我得到了 FFmpegVideoDecoder: avcodec_decode_video2(): Invalid data found when processing input, at timestamp: 10009000 duration: 41000 size: 502 side_data_size: 0 is_key_frame: 0 encrypted : 0 discard_padding (ms): (0, 0) in chrome://media-internals. 铬问题bugs.chromium.org/p/chromium/issues/detail?id=767163

以上是关于如何在 canplay 事件中设置 HTMLMediaElement 的 .currentTime,调用 play 并避免调度 pause 事件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Webflux / WebClient 中设置事件循环池大小?

如何在 React 子组件中设置事件处理程序

如何在lua中设置事件之间的时间间隔

如何通过 Google Tag Manager 在 Intercom 中设置事件跟踪

html5 音频:更改 currentTime 会触发多个 canplay 事件

Firefox 不会调用 HTML5 视频的 canplay/canplaythrough 事件。为啥?