当 Chromium 上的自动播放为假时,不会在画布上绘制视频

Video is not drawn on canvas when autoplay is false on Chromium

提问人:Dante 提问时间:12/10/2022 最后编辑:Dante 更新时间:12/10/2022 访问量:67

问:

以下代码在 Firefox 上工作正常,无论是 true 还是 false,但在 Chromium 上则不然。我该如何解决?autoplay

编辑1:我发现我可以从 开始,然后暂停视频。autoplay = trueonloadeddatavideo.pause()

编辑2:发现了另一件有趣的事情。例如,您可以设置为 5 秒以捕获第 5 秒,如果视频的持续时间小于 5 秒,则最后一帧将绘制在画布上。然后,您可以在事件中将其设置回零。这很好,因为在大多数情况下,前几秒钟是黑色的。video.currentTimeonloadeddata

let inputFile = document.getElementById("files");
let container = document.getElementById("container");
inputFile.addEventListener("change", inputFileEventHandler);

function inputFileEventHandler() {
  for (const file of inputFile.files) {
    let canvas = document.createElement("canvas");
    canvas.style.border = "1px solid gray";
    canvas.style.padding = "16px";

    let video = document.createElement("video");
    video.style.width = "250px";
    video.style.height = "auto";
    video.style.border = "1px solid gray";
    video.style.padding = "16px";
    video.autoplay = false;
    video.src = URL.createObjectURL(file);

    container.append(video);
    container.append(canvas);

    video.onloadeddata = () => {
      canvas.getContext("2d").drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
    }
  }
}
<!DOCTYPE html>
<html>
  <body>
    <input type="file" id="files" name="files" multiple>
    <div id="container"></div>    
  </body>
</html>

JavaScript 火狐 -画布 HTML5 视频

评论

0赞 Konrad 12/10/2022
当媒体当前播放位置的帧完成加载时,将触发 loadeddata 事件,通常是第一帧。我猜它不会在 chrome 中加载第一帧,也 - 注意:如果在浏览器设置中打开了数据保护程序,则此事件不会在手机/平板电脑设备中触发。
0赞 Dante 12/10/2022
有什么解决方法吗?

答:

2赞 Konrad 12/10/2022 #1

我不知道问题出在哪里

似乎有帮助,但我不确定preload: auto

一次处理多个事件可以使其正常工作,但并非总是如此

let inputFile = document.getElementById("files");
let container = document.getElementById("container");
inputFile.addEventListener("change", inputFileEventHandler);

const events = `abort
canplay
canplaythrough
durationchange
loadeddata
suspend`.split('\n')

function inputFileEventHandler() {

  for (const file of inputFile.files) {
    const video = document.createElement("video");
    video.style.width = "250px";
    video.style.height = "auto";
    video.style.border = "1px solid gray";
    video.style.padding = "16px";
    video.autoplay = false;
    video.preload = 'auto';
    video.src = URL.createObjectURL(file);
    container.append(video);

    for (const event of events) {
      const canvas = document.createElement("canvas");
      canvas.style.border = "1px solid gray";
      canvas.style.padding = "16px";
      container.append(canvas);


      video.addEventListener(event, () => {
        console.log(event)
        const ctx = canvas.getContext("2d")
        ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
        ctx.font = "24px serif";
        ctx.fillText(event, 10, 50);
      })
    }
  }
}
<!DOCTYPE html>
<html>

<body>
  <input type="file" id="files" name="files" multiple>
  <div id="container"></div>
</body>

</html>

评论

1赞 Dante 12/10/2022
我不知道您的解决方案是否有效,但我喜欢您将事件附加到元素的方式:-)
0赞 Dante 12/10/2022
尽管这里提到了什么 - 如果存在自动播放,则忽略 preload 属性 - 您的解决方案有效。
1赞 Dante 12/10/2022
对不起,现在它不适用于Firefox:-D
1赞 Dante 12/10/2022
仅使用不带自动播放的 preload 属性在 Firefox 和 Chromium 上都有效,但 currentTime 在 Firefox 上不起作用。