HTML5 Android Chrome 上的视频绘制成 canvas2D 问题
HTML5 video draw into canvas2D issue on Android Chrome
我正在 javascript(没有 jQuery 或其他框架)中开发 VR html5 页面,该页面使用 WebGL 渲染球体并具有流视频渲染到的纹理。
在 iPhone 6、6+ 上一切正常,但是在 Android 上我遇到了困难 - 简单地说,视频没有被传输到纹理 (gl.texSubImage2D)。纹理保持黑色。没有抛出 WebGL 错误。
所以我创建了一个没有 WebGL 的测试,它只是尝试播放视频并将其帧绘制成 canvas2D,因此我至少可以验证帧确实是从流视频中提取的。
视频在用户交互(触摸)时播放,当 canplay 事件被触发时,我开始帧循环(window.requestAnimationFrame)将视频绘制到 canvas (canvas.drawImage( 视频, 0,0 ))
视频和 canvas 在文档正文中可见,彼此相邻。
结果:在桌面上它按预期工作,两个屏幕,左边是带有本机控件的视频,右边是 canvas。当我点击播放时,视频开始播放,canvas 同时刷新。在 Android Chrome 48.0.2564.106 上没有绘制像素 - canvas 完全是空的。
我已经安装了 Android Chrome Beta (50.0.2661.57) 并且它在那里工作,但是在 Android Chrome 48.0.2564.106 上它不工作。
设置视频的代码和canvas:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone-no" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Video Canvas Test</title>
<script>
var video;
var canvas;
var ctx;
var info;
var pass = 0;
window.onload = function()
{
video = document.createElement("video");
video.oncanplay = function(){ initializeCanvas(); }
video.onerror = function(e){ console.error("video problem"); }
video.loop = true;
video.controls = "true";
video.src = "video/big-buck-bunny_trailer.webm";
video.style.width = "400px";
video.style.height = "300px";
video.style.position = "absolute";
video.style.left = "20px";
video.style.top = "20px";
video.style.backgroundColor = "#8080FF";
canvas = document.createElement("canvas");
canvas.style.backgroundColor = "#8080FF";
canvas.style.width = "400px";
canvas.style.height = "300px";
canvas.style.position = "absolute";
canvas.style.left = "420px";
canvas.style.top = "20px";
ctx = canvas.getContext("2d");
info = document.createElement("p");
info.innerHTML = window.navigator.userAgent;
info.style.position = "absolute";
info.style.width = "200px";
info.style.height = "auto";
info.style.position = "absolute";
info.style.left = "20px";
info.style.top = "320px";
document.body.appendChild(video);
document.body.appendChild(canvas);
document.body.appendChild(info);
}
function initializeCanvas()
{
console.log("Video ready to play. Init canvas.");
ctx.canvas.width = 640; // I am 100% sure this is correct video size.
ctx.canvas.height = 360;
console.log("Video size: " + video.videoWidth + "x" + video.videoHeight);
ctx.font = "30px Arial";
updateCanvas();
}
function updateCanvas()
{
pass ++;
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.drawImage(video,0,0);
ctx.fillText("Pass: " + pass,30,120);
window.requestAnimationFrame( updateCanvas );
}
</script>
</head>
<body>
</body>
</html>
谁能确认canvas.drawImage Chrome 48 岁及以上是否不能接受视频作为绘图源?考虑到 WebGL 已经支持 Chrome 多年,并且有大量的视频纹理实验,这对我来说似乎是不可能的。
我已经尝试过将视频复制到 WebGL 纹理或 Canvas2D 中的其他示例,但效果不佳。
这里有什么我遗漏的吗?
经过深入研究后发现:
Canvas2D.drawImage( video, 0,0 ) 自 2015 年 7 月起在 Android [=33= 中被破坏(至少我发现了那个日期的错误报告) ] 并且有点固定-不固定-固定-再次固定-但我可以确认它在 Android Chrome 49 和 Android Chrome 50(测试版)。将视频中的解码像素绘制到 Canvas2D 中的相同问题影响了将视频绘制到 WebGL 纹理中。
唯一的解决方法是:a) 在 JavaScript 中使用 Websocket + JPG sequence streamer 的定制视频流服务器(通过打开的 websocket 连接接收的图像)或 b) JPG JavaScript 中的序列流媒体(一张一张地下载图像并负责加载新的 - 删除旧的)。
我选择了 2.b 选项,并启用了 CDN,它非常适合 1024x512 视频大小,这是一个足够好的解决方案。
我会先使用 http 请求预加载 mp3 文件,然后将其加载到 Audio 对象中。完成后,JPG 流媒体将启动,然后使用声音 currentTime 值开始播放。与声音100%同步!
但是,问题已在 Chrome 49 和 Chrome 50(测试版)中修复,因此这可能会在 2-3 个月内过时。
我正在 javascript(没有 jQuery 或其他框架)中开发 VR html5 页面,该页面使用 WebGL 渲染球体并具有流视频渲染到的纹理。
在 iPhone 6、6+ 上一切正常,但是在 Android 上我遇到了困难 - 简单地说,视频没有被传输到纹理 (gl.texSubImage2D)。纹理保持黑色。没有抛出 WebGL 错误。
所以我创建了一个没有 WebGL 的测试,它只是尝试播放视频并将其帧绘制成 canvas2D,因此我至少可以验证帧确实是从流视频中提取的。
视频在用户交互(触摸)时播放,当 canplay 事件被触发时,我开始帧循环(window.requestAnimationFrame)将视频绘制到 canvas (canvas.drawImage( 视频, 0,0 ))
视频和 canvas 在文档正文中可见,彼此相邻。
结果:在桌面上它按预期工作,两个屏幕,左边是带有本机控件的视频,右边是 canvas。当我点击播放时,视频开始播放,canvas 同时刷新。在 Android Chrome 48.0.2564.106 上没有绘制像素 - canvas 完全是空的。
我已经安装了 Android Chrome Beta (50.0.2661.57) 并且它在那里工作,但是在 Android Chrome 48.0.2564.106 上它不工作。
设置视频的代码和canvas:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone-no" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Video Canvas Test</title>
<script>
var video;
var canvas;
var ctx;
var info;
var pass = 0;
window.onload = function()
{
video = document.createElement("video");
video.oncanplay = function(){ initializeCanvas(); }
video.onerror = function(e){ console.error("video problem"); }
video.loop = true;
video.controls = "true";
video.src = "video/big-buck-bunny_trailer.webm";
video.style.width = "400px";
video.style.height = "300px";
video.style.position = "absolute";
video.style.left = "20px";
video.style.top = "20px";
video.style.backgroundColor = "#8080FF";
canvas = document.createElement("canvas");
canvas.style.backgroundColor = "#8080FF";
canvas.style.width = "400px";
canvas.style.height = "300px";
canvas.style.position = "absolute";
canvas.style.left = "420px";
canvas.style.top = "20px";
ctx = canvas.getContext("2d");
info = document.createElement("p");
info.innerHTML = window.navigator.userAgent;
info.style.position = "absolute";
info.style.width = "200px";
info.style.height = "auto";
info.style.position = "absolute";
info.style.left = "20px";
info.style.top = "320px";
document.body.appendChild(video);
document.body.appendChild(canvas);
document.body.appendChild(info);
}
function initializeCanvas()
{
console.log("Video ready to play. Init canvas.");
ctx.canvas.width = 640; // I am 100% sure this is correct video size.
ctx.canvas.height = 360;
console.log("Video size: " + video.videoWidth + "x" + video.videoHeight);
ctx.font = "30px Arial";
updateCanvas();
}
function updateCanvas()
{
pass ++;
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.drawImage(video,0,0);
ctx.fillText("Pass: " + pass,30,120);
window.requestAnimationFrame( updateCanvas );
}
</script>
</head>
<body>
</body>
</html>
谁能确认canvas.drawImage Chrome 48 岁及以上是否不能接受视频作为绘图源?考虑到 WebGL 已经支持 Chrome 多年,并且有大量的视频纹理实验,这对我来说似乎是不可能的。
我已经尝试过将视频复制到 WebGL 纹理或 Canvas2D 中的其他示例,但效果不佳。
这里有什么我遗漏的吗?
经过深入研究后发现:
Canvas2D.drawImage( video, 0,0 ) 自 2015 年 7 月起在 Android [=33= 中被破坏(至少我发现了那个日期的错误报告) ] 并且有点固定-不固定-固定-再次固定-但我可以确认它在 Android Chrome 49 和 Android Chrome 50(测试版)。将视频中的解码像素绘制到 Canvas2D 中的相同问题影响了将视频绘制到 WebGL 纹理中。
唯一的解决方法是:a) 在 JavaScript 中使用 Websocket + JPG sequence streamer 的定制视频流服务器(通过打开的 websocket 连接接收的图像)或 b) JPG JavaScript 中的序列流媒体(一张一张地下载图像并负责加载新的 - 删除旧的)。
我选择了 2.b 选项,并启用了 CDN,它非常适合 1024x512 视频大小,这是一个足够好的解决方案。
我会先使用 http 请求预加载 mp3 文件,然后将其加载到 Audio 对象中。完成后,JPG 流媒体将启动,然后使用声音 currentTime 值开始播放。与声音100%同步!
但是,问题已在 Chrome 49 和 Chrome 50(测试版)中修复,因此这可能会在 2-3 个月内过时。