【问题标题】:How to render dynamic bitmap stream to canvas?如何将动态位图流渲染到画布?
【发布时间】:2011-02-20 19:47:54
【问题描述】:

我已经编写了一个 OpenGL 游戏,我想允许通过画布元素远程玩游戏。输入很容易,但视频很难。

我现在正在做的是通过 node.js 启动游戏,并在我的渲染循环中向标准输出发送代表当前帧的位图数据的 base64 编码流。 base64 帧通过 websocket 发送到客户端页面,并逐像素渲染(非常缓慢)。这显然是站不住脚的。

我一直在尝试生成视频流的想法,然后我可以通过标签轻松地将其渲染到画布上(ala http://mrdoob.github.com/three.js/examples/materials_video.html)。

我对这个想法的问题是我对编解码器/流媒体的了解不够,无法从高层次上确定这是否真的可行?我不确定编解码器是否是我需要担心的部分,我需要担心能够动态更改内容,并且可能会提前渲染几帧。

我的其他想法:

  • 尝试从 base64 框架创建 HTMLImageElement
  • 尝试优化压缩/重绘区域以降低像素带宽(实现我需要获得 20+fps 的那种性能似乎不切实际)。

然后总是可以选择使用闪光灯……但我真的更愿意避免使用它。我正在寻找一些关于要追求的技术、想法的意见?

【问题讨论】:

    标签: javascript html canvas video-streaming


    【解决方案1】:

    尝试在 YCbCr 颜色空间中转换 RGB 并将像素值流式化为:

    Y1 Y2 Y3 Y4 Y5 .... Cb1 Cb2 Cb3 Cb4 Cb5 .... Cr1 Cr2 Cr3 Cr4 Cr5 ...
    

    会有很多重复的模式,所以任何压缩算法都会比 RGBRGBRBG 序列压缩得更好。

    http://en.wikipedia.org/wiki/YCbCr

    【讨论】:

    • 另外,请检查github.com/pkrumins/node-video。看来这个库可以用视频编码做所有脏活。
    • 真的会比 RRRRRGGGGGBBBBB 压缩得更好吗?
    • 刚刚使用 1920x1080 PNG 真实照片进行了测试。压缩后的 RGB..RGB 大小为 392kb,YCbCr..YCbCr 为 309kb。压缩后的 RR..GG..BB 为 409kb,YY..CbCb..CrCr 为 218kb。真的更好:) 你也可以尝试将图像分割成 M 像素边的 N 个正方形,并为每个正方形线性编写 YY..CbCb..CrCr 序列,我认为它会更好地压缩,稍后再检查。但不要忘记,您可以在 YCbCr 中丢失一些颜色信息 - 查看 wiki 以获取详细信息。很抱歉回答迟了;)
    【解决方案2】:
    1. 为什么要对数据进行 base64 编码?我认为您可以通过 WebSocket 推送原始字节

    2. 如果您有一个格式正确的 RGBA 值线性数组,您可以将它们直接转储到 ImageData 对象中,以供后续通过单个 ctx.putImageData() 调用使用。

    【讨论】:

    • 1.谷歌搜索似乎表明并非如此,但我从未尝试过(因为我在尝试之前用谷歌搜索过)。 2. 现在我想起来了..你是对的,结合重绘区域/压缩可能已经足够快了。我会尝试一下。
    • 是的,进一步认为 WebSocket 可能会接收原始字符串,但您仍然必须将其解压缩到本地数组中才能与 putImageData() 一起使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 2012-08-15
    • 2014-06-25
    • 2018-05-05
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多