如何(功能)检测浏览器是不是支持 WebM alpha 透明度?

Posted

技术标签:

【中文标题】如何(功能)检测浏览器是不是支持 WebM alpha 透明度?【英文标题】:How to (feature) detect if browser supports WebM alpha transparency?如何(功能)检测浏览器是否支持 WebM alpha 透明度? 【发布时间】:2015-06-07 14:56:01 【问题描述】:

我正在集成具有 Alpha 透明度的 *.webm 视频。目前,仅 Chrome 和 Opera 支持透明度。 (演示:http://simpl.info/videoalpha/)例如 Firefox 播放视频,因为它支持 WebM 格式,但不是透明度,而是黑色背景。

如果浏览器不支持 Alpha 透明度,我的计划是显示视频海报图像而不是视频。因此,只有在浏览器支持 WebM alpha 透明度的情况下,视频才应该播放。我知道如何检测浏览器或渲染引擎,从而播放视频(见下面的代码)——但有没有“特征检测”的方式?

var supportsAlphaVideo = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor) || (/OPR/.test (navigator.userAgent));
if (supportsAlphaVideo) 
document.querySelector(".js-video").play();

另见http://updates.html5rocks.com/2013/07/Alpha-transparency-in-Chrome-video

【问题讨论】:

您可以使用 Modernizer 一个 javascript 库来检测用户浏览器中的 HTML5 和 CSS3 功能。 在我看来,使用modernizr 无法检测webm 编解码器中的特定功能。 【参考方案1】:

这是一个在 WebM 中测试 alpha 支持的有效解决方案。

我基本上结合了Capture first frame of an embedded video和check_webp_feature

用于测试的视频是经过 base64 编码的源。它实际上是一个很小的 ​​VP9 WebM 视频,使用以下代码进行编码:

ffmpeg -i alpha.png -c:v libvpx-vp9 alpha.webm

如果您想测试 VP8 alpha 支持,只需编码您自己的并删除 -vp9。 alpha.png 是一个 64x64 像素、100% 透明的 PNG 图像。

var supportsWebMAlpha = function(callback)

    var vid = document.createElement('video');
    vid.autoplay = false;
    vid.loop = false;
    vid.style.display = "none";
    vid.addEventListener("loadeddata", function()
    
        document.body.removeChild(vid);
        // Create a canvas element, this is what user sees.
        var canvas = document.createElement("canvas");

        //If we don't support the canvas, we definitely don't support webm alpha video.
        if (!(canvas.getContext && canvas.getContext('2d')))
        
            callback(false);
            return;
        

        // Get the drawing context for canvas.
        var ctx = canvas.getContext("2d");

        // Draw the current frame of video onto canvas.
        ctx.drawImage(vid, 0, 0);
        if (ctx.getImageData(0, 0, 1, 1).data[3] === 0)
        
            callback(true);
        
        else
        
            callback(false);
        

    , false);
    vid.addEventListener("error", function()
    
        document.body.removeChild(vid);
        callback(false);
    );

    vid.addEventListener("stalled", function()
    
        document.body.removeChild(vid);
        callback(false);
    );

    //Just in case
    vid.addEventListener("abort", function()
    
        document.body.removeChild(vid);
        callback(false);
    );

    var source = document.createElement("source");
    source.src="data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch4ECQoWBAhhTgGcBAAAAAAACBRFNm3RALE27i1OrhBVJqWZTrIHlTbuMU6uEFlSua1OsggEjTbuMU6uEHFO7a1OsggHo7AEAAAAAAACqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAADIq17GDD0JATYCNTGF2ZjU3LjU3LjEwMFdBjUxhdmY1Ny41Ny4xMDBEiYhARAAAAAAAABZUrmsBAAAAAAAARq4BAAAAAAAAPdeBAXPFgQGcgQAitZyDdW5khoVWX1ZQOYOBASPjg4QCYloA4AEAAAAAAAARsIFAuoFAmoECU8CBAVSygQQfQ7Z1AQAAAAAAAGfngQCgAQAAAAAAAFuhooEAAACCSYNCAAPwA/YAOCQcGFQAADBgAABnP///NXgndmB1oQEAAAAAAAAtpgEAAAAAAAAk7oEBpZ+CSYNCAAPwA/YAOCQcGFQAADBgAABnP///Vttk7swAHFO7awEAAAAAAAARu4+zgQC3iveBAfGCAXXwgQM=";
    source.addEventListener("error", function()
    
       document.body.removeChild(vid);
       callback(false);
    );
    vid.appendChild(source);

    //This is required for IE
    document.body.appendChild(vid);
;

supportsWebMAlpha(function(result)

   if (result)
   
       alert('Supports WebM Alpha');
   
   else 
   
       alert('Doesn\'t support WebM Alpha');
   
);

【讨论】:

我发现某些版本的 IE11 倾向于回退 ctx.getImageData(0, 0, 1, 1).data 到数组 [0, 0, 0, 0] 因此通过了测试。我制作了另一个版本的 1pixel 视频,它具有半透明的 data[3] === 128。不幸的是,它不适合子评论,我不想从中创建单独的评论,所以:pastebin.com/swzkRpsw @Luixo:在 1x1 时,一些旧版本的 webkit 在支持 alpha 时无法通过测试。 64x64 是似乎适用于所有视频的最小尺寸。 你有确切的 webkit 引擎版本吗?我应该检查一下。 很遗憾,我很久以前就做过这项研究。对不起:(【参考方案2】:

没有公开任何属性以提供有关视频及其频道的任何信息。

这样做的唯一方法是:

提前了解,将该知识与数据结合起来,并在请求视频作为元数据时将其提供给浏览器 使用画布分析图像数据 将文件加载为二进制数据,然后手动解析 webm 格式以提取此信息。可行但非常不方便,因为必须下载完整的文件,当然还必须制作解析器。

如果您事先不知道,或者无法提供元数据,那么画布是您的最佳选择。

画布

您可以使用画布来测试实际透明度,但是,这确实有 CORS 要求(视频必须在同一台服务器上,或者外部服务器需要接受跨域使用)。

此外,您必须实际开始加载视频,这当然会对带宽和性能产生影响。您可能希望使用动态创建的视频和画布标签来执行此操作。

从那里开始,它是相当直接的。

创建一个小画布 在其中画一个框架(应该有一个 Alpha 通道) 提取像素(此处为 CORS 要求) 使用 Uint32Array 视图循环遍历缓冲区并检查 alpha 通道中的值是否小于 255 (pixel & 0xff000000 !== 0xff000000)。

这样做相当快,您可以使用一半甚至更小的帧大小。

【讨论】:

对不起,我的回答迟了。感谢您提出的解决方案,使用画布检测 alpha 透明度是分析视频内容的一种巧妙方法。

以上是关于如何(功能)检测浏览器是不是支持 WebM alpha 透明度?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建 WebM 视频文件?

如何检测浏览器是不是支持暗模式

如何检测浏览器是不是支持鼠标悬停事件?

如何在浏览器中检测对 VML 或 SVG 的支持

JavaCV音视频开发宝典:录制vp8和vp9编码的webm格式视频,以mp4转webm为例

JavaCV音视频开发宝典:录制vp8和vp9编码的webm格式视频,以mp4转webm为例