繁体   English   中英

HTML5视频在Android Chrome上陷入canvas2D问题

[英]HTML5 video draw into canvas2D issue on Android Chrome

我正在使用JavaScript(无jQuery或其他框架)开发使用JavaScript的VR html5页面,该页面使用WebGL渲染球体,并具有将流视频渲染到的纹理。

所有这些在iPhone 6、6+上都可以正常工作,但是在Android上我遇到了麻烦-简而言之,视频没有被转换为纹理(gl.texSubImage2D)。 纹理保持黑色。 没有引发WebGL错误。

因此,我创建了一个没有WebGL的测试,该测试只是尝试播放视频并将其帧绘制到canvas2D中,因此我至少可以验证是否确实从流视频中提取了帧。

在用户交互(触摸)上播放视频,并且触发canplay事件时,我开始帧循环(window.requestAnimationFrame)将视频绘制到画布中(canvas.drawImage(video,0,0))

视频和画布在文档主体上都可见,彼此相邻。

结果:在桌面上它按预期方式工作,有两个屏幕,左边是带有本机控件的视频,右边是画布。 当我单击播放时,视频开始播放,并且画布同时刷新。 在Android Chrome 48.0.2564.106上,未绘制像素-画布完全为空。

我已经安装了Android Chrome Beta(50.0.2661.57),并且可以在其中运行,但在Android Chrome 48.0.2564.106上却无法运行。

设置视频和画布的代码:

<!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>

任何人都可以确认Chrome 48及更高版本上的canvas.drawImage是否不能接受视频作为绘图源吗? 考虑到WebGL一直以来都是Chrome的支持者,并且对视频纹理进行了大量的实验,这对我来说似乎是不可能的。

我尝试了将视频复制到WebGL纹理或Canvas2D中的其他示例,但它们无法正常工作。

我在这里想念什么吗?

经过深入研究,看来:

  1. 自2015年7月以来,Canvas2D.drawImage(video,0,0)在Android Chrome中已损坏(至少因为我发现从那时起的错误报告),并且有点像是“固定”,“不固定”,“又是又不是”已修复-但我可以确认该问题已在Android Chrome 49和Android Chrome 50(测试版)中修复。 从视频中解码像素以将其绘制到Canvas2D中的相同问题也影响了将视频绘制为WebGL纹理。

  2. 唯一的解决方法是:a)使用JavaScript中的Websocket + JPG序列流媒体(通过打开的websocket连接接收的图像)的定制视频流服务器,或b)JavaScript中的JPG序列流媒体(逐个下载图像并进行维护)正在加载新-删除旧)。

我选择了选项2.b,并插入了CDN,它对于1024x512视频尺寸确实非常有效,这是足够好的解决方案。

我将首先使用http请求预加载mp3文件,然后将其加载到Audio对象中。 完成此操作后,JPG流将启动,然后将使用声音currentTime值开始播放。 它与声音100%同步!

但是,Chrome 49和Chrome 50(测试版)中的问题已修复,因此这可能会在2-3个月内被淘汰。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM