记一次canvas画出video第一帧出现的灾难

首页说出现的问题:根据video的loadeddata事件的触发来绘制第一帧,但是绘制出来总是黑屏

  • 解决:后来发现video加上preload属性等于auto就可以绘制成功了。
  • 代码:
    window.onload = function () {
        var url = "http://1257092661.vod2.myqcloud.com/0d1bb4cevodtransgzp1257092661/bf15d8205285890807073233140/v.f30.mp4";
        // var url = "http://imgshop.woojia.com/newimages/s-20200421/100/45552b258e8c8c723930046033e368b5.mp4";
    // var imgUrl = "http://imgshop.woojia.com/newimages/s-20200821/36/9faceee175b8e1b5d35cb6e4f8ce8797.jpeg";
    var resolve = getVideoBase64(url);
    console.log("resolve:",resolve);
    resolve.then(dataURL => {
        console.log("dataURL:",dataURL);
    });
function getVideoBase64(url) {
    return new Promise(function (resolve, reject) {
        var dataURL = '';
        const video = document.createElement("video");
        video.setAttribute('crossOrigin', 'anonymous');	//处理跨域
        video.setAttribute('src', url);
        video.setAttribute('width', 400);
        video.setAttribute('height', 400);
        video.setAttribute("preload", "auto");	// 就是加上预加载之后绘制就成功了
        // document.body.append(video);
        video.addEventListener('loadeddata', function () {
                var canvas = document.createElement("canvas"),
                    width = video.width, //canvas的尺寸和图片一样
                    height = video.height;
                canvas.width = width;
                canvas.height = height;
                canvas.getContext("2d").drawImage(video, 0, 0, width, height); //绘制canvas
                dataURL = canvas.toDataURL('image/jpeg'); //转换为base64
                resolve(dataURL);
                // document.body.append(canvas);
        });
    })
}
  • 原因:
    preload=auto:指页面开始加载的时候就可以开始加载视频。
    preload=metadata: 指当页面加载后仅加载元数据。
    preload=none: 页面加载时视频不加载。
     虽然设置了onloadeddata事件才去画它的第一帧,按理说应该视频已经加载出了第一帧了,但是由于没有设置preload=auto并没有截图到第一帧。(好像不管有没有preload都会执行onloadeddata)
     所以要想截图第一帧就必须让它自动加载。因为各浏览器对preload不设置时的默认值可能不同还是手动设置一下比较好。

onloadeddata事件:当媒介数据已加载时才会执行的回调

  • 尝试过的方法
  1. 以为onloadeddata事件执行时视频还没有加载出第一帧。
     更换了事件发现不行;
     给onloadeddata加延时结果神奇的发现有时候可以有时候又不行;
  2. 以为drawImage也会因为绘制大的数据的而导致失败(比较傻)。
     所以给绘制的图片减少过像素,结果是刚减少过可以了,试了几次又失败了。

最后附上base64转blob的方法

/**
* @param dataUrl base64 数据
* File接口基于Blob,继承了Blob的功能并进行了扩展,故blob对象也可以当作file对象一样当作文件上传。
*/
function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while(n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr],{type:mime});
};
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值