如何(功能)检测浏览器是否支持 WebM alpha 透明度?
How to (feature) detect if browser supports WebM alpha transparency?
我正在集成具有 alpha 透明度的 *.webm 视频。目前,只有 Chrome 和 Opera 支持透明度。 (演示:http://simpl.info/videoalpha/)例如,Firefox 播放视频,因为它支持 WebM 格式,但没有透明度,而是黑色背景。
如果浏览器不支持 alpha 透明度,我的计划是显示视频海报图像而不是视频。所以视频应该只播放,如果浏览器支持 WebM alpha 透明度。我知道如何检测浏览器或渲染引擎并因此播放视频(请参阅下面的代码)-但是有 "feature detection" 方法吗?
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
没有公开的属性提供有关视频及其频道的任何信息。
唯一的方法是:
- 预先知道,将这些知识与数据结合起来,并在请求视频作为元数据时将其提供给浏览器
- 使用canvas分析图像数据
- 将文件加载为二进制数据,然后手动解析 webm 格式以提取此信息。可以,但是很不方便,必须下载完整的文件,当然还得做解析器。
如果您事先不知道,或者无法提供元数据,那么 canvas 是您的最佳选择。
Canvas
您可以使用canvas来测试实际透明度,但是,这确实有 CORS 要求(视频必须在同一服务器上,否则外部服务器需要接受跨域使用)。
此外,您必须实际开始加载视频,这当然会对带宽和性能产生影响。您可能希望使用动态创建的视频和 canvas 标签来执行此操作。
从那里开始,它相当简单。
- 创建小canvas
- 在其中绘制一个帧(预期具有 alpha 通道的帧)
- 提取像素(此处要求CORS)
- 使用 Uint32Array 视图遍历缓冲区并检查值 < 255 的 alpha 通道 (
pixel & 0xff000000 !== 0xff000000
)。
这样做相当快,您可以使用一半或更小的帧大小。
这是一个测试 WebM 中的 alpha 支持的有效解决方案。
我基本结合了Capture first frame of an embedded video and 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');
}
});
我正在集成具有 alpha 透明度的 *.webm 视频。目前,只有 Chrome 和 Opera 支持透明度。 (演示:http://simpl.info/videoalpha/)例如,Firefox 播放视频,因为它支持 WebM 格式,但没有透明度,而是黑色背景。
如果浏览器不支持 alpha 透明度,我的计划是显示视频海报图像而不是视频。所以视频应该只播放,如果浏览器支持 WebM alpha 透明度。我知道如何检测浏览器或渲染引擎并因此播放视频(请参阅下面的代码)-但是有 "feature detection" 方法吗?
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
没有公开的属性提供有关视频及其频道的任何信息。
唯一的方法是:
- 预先知道,将这些知识与数据结合起来,并在请求视频作为元数据时将其提供给浏览器
- 使用canvas分析图像数据
- 将文件加载为二进制数据,然后手动解析 webm 格式以提取此信息。可以,但是很不方便,必须下载完整的文件,当然还得做解析器。
如果您事先不知道,或者无法提供元数据,那么 canvas 是您的最佳选择。
Canvas
您可以使用canvas来测试实际透明度,但是,这确实有 CORS 要求(视频必须在同一服务器上,否则外部服务器需要接受跨域使用)。
此外,您必须实际开始加载视频,这当然会对带宽和性能产生影响。您可能希望使用动态创建的视频和 canvas 标签来执行此操作。
从那里开始,它相当简单。
- 创建小canvas
- 在其中绘制一个帧(预期具有 alpha 通道的帧)
- 提取像素(此处要求CORS)
- 使用 Uint32Array 视图遍历缓冲区并检查值 < 255 的 alpha 通道 (
pixel & 0xff000000 !== 0xff000000
)。
这样做相当快,您可以使用一半或更小的帧大小。
这是一个测试 WebM 中的 alpha 支持的有效解决方案。
我基本结合了Capture first frame of an embedded video and 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');
}
});