将未压缩的视频写入FLV文件的可行性

时间:2018-12-04 07:40:26

标签: c binary-data flv video-codecs flash-video

我很有可能为此走毫无意义的道路,因此,如果这浪费时间,我深表歉意。我一直试图将未压缩的视频写入FLV文件,但不确定是否可以。

根据Wikipedia,有效的视频编码选项为0,表示“ RGB”视频编码:https://en.wikipedia.org/wiki/Flash_Video#Packets。但是,我在Adobe文档中看不到此Codec ID选项。既不是“视频文件格式规范版本10”,也不是“ Adob​​e Flash视频文件格式规范版本10.1”。

我假设允许使用0 / RGB编解码器ID。我用C编写了一个无符号字符数组的硬编码,并使用fwrite将以下Double / Number元数据写入新的二进制FLV文件中(坦率地说,我假设我编写正确):

  • 持续时间:4(秒)
  • 宽度:16(像素)
  • 高度:16(像素)
  • 视频数据速率:6(Kbps)
  • 帧频:1(fps)
  • 视频编解码器:0
  • 文件大小:3323(字节)

然后我添加了4个VIDEODATA标签,对于我希望写入的每个RGB帧,添加1个。它们的时间戳是0、1000、2000和3000(毫秒)。它们全部具有769字节的有效负载:用于指定它的第一个字节是编解码器ID为0的关键帧,其余的768表示16x16x3(RGB)图像。我为所有值写了255 / 0xFF,希望能看到一个小的白色屏幕显示4秒钟。

当我担心,在VLC Media Player中无法正常播放时,我尝试为每帧使用RGBA颜色。我还将videodatarate和fileize元数据分别更改为Number值8(Kbps)和4347(字节)。

不幸的是,这也不在VLC Media Player中播放。我想知道是否有人确定FLV文件中的未压缩视频是否可能?如果是这样,我很好奇视频数据应采用哪种格式(RGB,RGBA,多个VIDEODATA标签,仅一个VIDEODATA标签等)?

我的C代码主要是一个巨大的无符号字符数组,但是如果有人希望看到它,我可以尝试添加它。任何建议都将不胜感激。

谢谢

米切尔A

2 个答案:

答案 0 :(得分:1)

根据SirDarius所说,“维基百科页面上列出的视频编码类型并非来自官方来源。我不建议依赖这些类型。”鉴于Adobe本身的FLV格式文档没有提及视频编码的未压缩RGB选项,因此这是有道理的。

我一直希望维基百科的编辑者和其他人知道FLV格式的一些未记录的复活节彩蛋,但我现在坚信事实并非如此。

答案 1 :(得分:1)

  

“ ... Adob​​e的FLV格式文档本身未提及视频编码的未压缩
RGB选项。”

对于RGB(原始位图数据),您必须使用Screen 1编解码器(id = 3)。

奇怪的是,它隐藏在SWF Format documentation中(不是FLV格式文档中)。
请参阅第14章(第204页)的“视频”部分...

  • 您要特别说明第Screen Video编解码器的第208页。

  • 选中this example code(AS3),将RGB编码为屏幕视频。

应用逻辑,尤其是函数videoData(),可以对其进行调整以读取像素uint(通过某些getPixel类型调用)或仅从Array读取。

示例:

for (var x2:int = 0; x2 < xLimit; x2++) 
{
    var px:int = (x1 * blockWidth) + x2;
    var py:int = frameHeight - ((y1 * blockHeight) + y2); // (flv's save image from bottom to top)

    var p:uint = YOUR_INPUT_BITMAP.getPixel(px, py); // sample a pixel's RGB (3-bytes unsigned int) 

    //# IF reading from Pixel's uint value
    block.writeByte( p & 0xff );        // blue 
    block.writeByte( p >> 8 & 0xff );   // green
    block.writeByte( p >> 16 );         // red

    //# ELSE IF reading from Array of R-G-B values(FLV writes in BGR format)
    block.writeByte( myRGB_Array[x+2] );        // blue 
    block.writeByte( myRGB_Array[x+1] );    // green
    block.writeByte( myRGB_Array[x] );  // red

}