微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

画布捕获的第一帧输出到img后变成全黑

如何解决画布捕获的第一帧输出到img后变成全黑

尝试了很多文章方法解决不了,希望得到一点提示

那么英语不是我的母语,抱歉

  var video = document.getElementById('video');
  var canvas = document.createElement('canvas');
  var videobg = document.getElementById('bgc');

  video.addEventListener('loadeddata',function() {
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d');
    var img = new Image;
    img.onload = function() {
      ctx.drawImage(video,video.videoWidth,video.videoHeight);
    }
    var imgurL = canvas.toDataURL('image/jpeg');
    img.setAttribute('src',imgurL);
    videobg.appendChild(img);
  })
}
  <div class="flexbord">
    <div id="bgc" class="bgc">
      <video id="video" src="https://kwibao-video.s3.ap-northeast-1.amazonaws.com/h7C886i3HFJs98SVUQG5_video_1626853820000.mp4" type="mp4" autoplay muted loop></video>
    </div>
    <div class="qwe"></div>
  </div>

解决方法

您在这里混合了几段代码...

img.onload 部分适用于您想在画布上绘制 img 的情况。在这里,您不是在这种情况下,您想要绘制 video,然后(可能)使用从画布中提取的图像填充 img

所以在这种情况下,您不需要等待图像加载,您可以直接将视频绘制到画布上。 但是,loadeddata 并不意味着帧已经呈现给视频元素,因此您可能更愿意等待其他事件,例如 playing

var video = document.getElementById('video');
var canvas = document.createElement('canvas');
var videobg = document.getElementById('bgc');
var ctx = canvas.getContext("2d");
video.addEventListener('playing',function() {
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  canvas.getContext('2d');
  // draw the video directly
  ctx.drawImage(video,video.videoWidth,video.videoHeight);
  var img = new Image;
  // now this represents the canvas,when the video has been drawn on it
  var imgURL = canvas.toDataURL('image/jpeg');
  img.setAttribute('src',imgURL);
  videobg.appendChild(img);
},{
  once: true
});
.bgc { display: flex; }
<div class="flexbord">
  <div id="bgc" class="bgc">
    <!-- don't forget to set the crossorigin attribute -->
    <video id="video" src="https://kwibao-video.s3.ap-northeast-1.amazonaws.com/h7C886i3HFJs98SVUQG5_video_1626853820000.mp4" crossorigin type="mp4" autoplay muted loop></video>
  </div>
  <div class="qwe"></div>
</div>

不过,您最好避免使用 toDataURL 而更喜欢 toBlob,因为它使用的内存要少得多

var video = document.getElementById('video');
var canvas = document.createElement('canvas');
var videobg = document.getElementById('bgc');
var ctx = canvas.getContext("2d");
video.addEventListener('playing',video.videoHeight);
  var img = new Image;
  canvas.toBlob(async(blob) => {
    img.src = URL.createObjectURL(blob);
    await img.decode(); // wait for the image is loaded
    URL.revokeObjectURL(img.src);
    videobg.appendChild(img);
  },'image/jpeg');
},{
  once: true
});
.bgc { display: flex; }
<div class="flexbord">
  <div id="bgc" class="bgc">
    <!-- don't forget to set the crossorigin attribute -->
    <video id="video" src="https://kwibao-video.s3.ap-northeast-1.amazonaws.com/h7C886i3HFJs98SVUQG5_video_1626853820000.mp4" crossorigin type="mp4" autoplay muted loop></video>
  </div>
  <div class="qwe"></div>
</div>

或者,由于您显然只是“呈现”此框架,因此直接附加 <canvas>,这在记忆方面会更好:

var video = document.getElementById('video');
var canvas = document.createElement('canvas');
var videobg = document.getElementById('bgc');
var ctx = canvas.getContext("2d");
video.addEventListener('playing',video.videoHeight);
  // show the canvas
  videobg.appendChild(canvas);
},{
  once: true
});
.bgc { display: flex; }
<div class="flexbord">
  <div id="bgc" class="bgc">
    <!-- don't forget to set the crossorigin attribute -->
    <video id="video" src="https://kwibao-video.s3.ap-northeast-1.amazonaws.com/h7C886i3HFJs98SVUQG5_video_1626853820000.mp4" crossorigin type="mp4" autoplay muted loop></video>
  </div>
  <div class="qwe"></div>
</div>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。