使用canvas检测HTML5视频解码错误

简介:

乍一看这标题,有点吊炸天的赶脚,canvas跟<video>能有什么联系?不过请放心我不是标题党。事情是这样的:

  HTML5的<video>标签所支持的视频格式确实有限,mp4文件必须是H264编码的才行,若不是H264编码,在chrome下会只有声音没有画面,在FireFox下直接连声音也没有,而且控制台会显示警告:

  因为浏览器使用的解码器也是H264的。如果用户在本地可以观看的mp4视频上传后却无法正常播放,这种体验是相当糟糕的。

  我尝试在文件上传阶段进行检测,然而HTML5的FILE API能力也是有限的,只能获取文件名称、大小、MIME类型,对于视频的编码却无法检测到。

  既然无法从上传阶段阻止用户,那么退一步讲,在视频无法播放的时候,我们希望可以检测到,并且给用户一个提示“视频解码错误”,这样他就不会有疑惑“我的视频为什么无法播放呢?”。

  首先想到的是video的API,video有onerror事件,但是此事件只能在src地址错误或其他原因加载不到视频资源时触发,当加载到视频发生解码错误时,并不会触发。略蛋疼。这么看来按照标准的东西是无法检测到了,所以必须另辟蹊径了。答案就是:

  canvas读取图片像素点的能力

  前些天看了前端手记的这篇文章印象颇深,http://www.cssha.com/video2txt-canvas。利用canvas读取图片像素点,进而转化为文本图片。更厉害的是canvas的drawImage方法还可以传入视频,获取到视频某一帧的像素点。于是一个想法在脑中萦绕,解码错误的视频是没有画面的黑屏,我可以用canvas绘制视频,根据所绘制的内容来判断画面是不是在动,遂想到如下思路:

  1. 在视频开始播放时,每隔一定时间用canvas绘制一次视频画面
  2. 对每次canvas绘制的图片进行像素点采样,存入数组
  3. 扫描几次后,比较每次采样的像素点rgb值是否相同,即检测画面是否变化了
  4. 根据画面是否在“运动”来检测是否解码成功了

  这种办法当然也有局限,下面是几个注意事项:

  1. canvas绘制视频画面的次数控制。绘制图片并采样获取像素点是消耗性能的,所以这个扫描过程不应该伴随视频播放的整个时间段。只需在开始播放的几秒内进行检测即可。
  2. 若恰巧有某个视频,开始的几秒内就是一个静止的画面,那检测就出错了。

  局限归局限,先把想法写成代码试试,于是有如下代码:

  View Code

  当我怀着激动的心情开始测试时,发现事实真不是想象的那样。Chrome下,当一个视频无法解码时,drawImage方法直接无法执行,会报错。完了,美好的想法泡汤了。。。

  不过转而一想,视频解码错误,drawImage方法就报错,如果写在try catch语句中,不就可以捕捉到了吗?看来还没到死路,这样连像素点采样都省了,可以直接检测到了。于是乎代码就简化成了下面这样:

复制代码
//检测视频是否解码错误
function checkVideoParseError(){
    var videos = $('video');
    if(videos.length>0){
        var can = $('<canvas id="canvas" style="display:none"></canvas>').appendTo('body');
        var canvas = can.get(0);
        var ctxt = canvas.getContext('2d');
        var scanImg = function(video){
            try{
                ctxt.drawImage(video, 0, 0);    
            }
            catch(e){
                alert('视频解码错误,请使用H264编码的mp4文件!');
            }
        }

        videos.on('play',function(){
            var _this = this;
            scanImg(_this);
            setTimeout(function(){scanImg(_this);},1000);
        })
    }
}
复制代码

  在1秒后的绘制图片动作会捕捉到异常。没想到,竟然这样成功了!

  该方法纯属个人想出来的,还有诸多不完善之处,遇到同样问题的同学可以试试这个思路~


本文转自吕大豹博客园博客,原文链接:http://www.cnblogs.com/lvdabao/p/3414038.html,如需转载请自行联系原作者

相关文章
|
2月前
|
前端开发 JavaScript API
2024 新年HTML5+Canvas制作3D烟花特效(附源码)
2024 新年HTML5+Canvas制作3D烟花特效(附源码)
50 0
|
2月前
|
存储 移动开发 前端开发
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
46 0
|
6月前
|
Web App开发 移动开发 JavaScript
【前端用法】HTML5 Video标签如何屏蔽右键视频另存为的js代码以及如何禁用浏览器控件,Video 禁止鼠标右键下载
【前端用法】HTML5 Video标签如何屏蔽右键视频另存为的js代码以及如何禁用浏览器控件,Video 禁止鼠标右键下载
168 0
|
1月前
|
前端开发 JavaScript 容器
编程笔记 html5&css&js 032 HTML Canvas
编程笔记 html5&css&js 032 HTML Canvas
|
1月前
|
Web App开发 前端开发 安全
编程笔记 html5&css&js 031 HTML视频
编程笔记 html5&css&js 031 HTML视频
|
2月前
|
数据采集 数据安全/隐私保护
高效网络采集实践:使用 Haskell 和 html-conduit 下载 www.baidu.com 视频完整教程
网络采集在当今信息时代中发挥着关键作用,用于从互联网上获取数据并进行分析。本文将介绍如何使用 Haskell 进行网络编程,从数据采集到图片分析,为你提供一个清晰的指南。我们将探讨如何使用爬虫代理来确保高效、可靠的数据获取,并使用 Haskell 的强大功能来分析和处理数据。
|
2月前
|
移动开发 HTML5 容器
HTML5——周技能检测——菜单编辑——2022年11月22日(考完)
HTML5——周技能检测——菜单编辑——2022年11月22日(考完)
19 0
|
3月前
|
移动开发 前端开发 JavaScript
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
127 0
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
|
3月前
|
存储 移动开发 前端开发
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)(下)
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
29 0
|
3月前
|
XML 移动开发 前端开发
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)(上)
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
29 0