AIR 及 Flv Encoder 初体验

作为一个 AS 起手的 Coder,代码写来写去还是 AS3 写起来最舒服,只是由于不能文件操作等问题,再加上现在做网页前端也基本用不到 Flash 了,便荒废了很久. 这次终于把录了半年的 Rain Stops, Goodbye (音频部分)杀青了,着手做 PV ,却又不想像以前那样用 Windows Live Movie Maker 随便做做了事,所以就想到用 as3 来动态生成一些内容最终做成视频.

其中涉及到的一个重要的问题就是视频编码,我稍稍 Google 了一圈,能找到的现成的编码器不多,其中 zero point nine 的 Flv Encoder 感觉还不错:第一,这是无损编码;第二,它支持在AIR环境下直接把视频写入硬盘.

AIR 环境算是让 AS3 摆脱了一些束缚,使其能作为一门常规的语言来开发,或者说终于能用 AS3 写软件了. 而且只要把运行环境改成 AIR 就可以直接使用原来的 Flash. 但是有一点要注意,在 Windows 下不能将源文件和发布的文件保存在中文路径下,不然会提示“Test Movie terminated. application descriptor not found”. 建议发布的时候选 Application with runtime embedded 不然的话还要很二地“安装”完才能用. 我用 Flash Builder 的时候就觉得这个设定很二,为何不干脆一点生成个能直接运行的二进制文件,真要搞什么安装可以作为可选附件.

Flv Encoder 的使用很简单,基本上把作者提供的 Example 改一改就能用了,基本没有其他需要翻文档的地方. FlvEncoder.addFrame() 是 Flv Encoder 用来写入帧的函数,第一个参数是图像数据(bitmapData),第二个参数是音频数据(ByteArray). 图像数据只要创建一个 ENTER_FRAME 的事件,每帧用 bitmapData.draw() 把舞台上的东西截下来就行了. 音频数据则比较复杂:作者提供的 Demo 做的是一个记录摄像头的工具,音频来自于输入设备;而我是要从本地读取 mp3 再读出每一帧之间的采样点.

关键的问题就在于“每一帧之间的采样点”. 一开始我试图使用 SoundMixer.computeSpectrum() 来获取,但最终音频不能正常输入,视频也不能正常播放. 然后我尝试了一下 SampleDataEvent 却发现这个事件纯粹是为了输出动态生成的音频用的. 最后我的思路是通过记录 SoundChannel 的 position 属性来定位采样点的位置,然后利用 Sound.extract() 方法来获取两个 position 之间的采样点. 这里有个注意点:SoundChannel 的 position 单位是毫秒,而 Sound.extract() 的参数中 position 的单位却是采样点的个数. 我将其转换过来以后发现无论帧之间空了多久,永远每次只采样 2048 个采样点,并且 SoundChannel.position 其实是根据采样点的数量换算得出的.

我在 30fps 下播放一个 mp3 音频,并将每帧之间的 SoundChannel.position 之差 trace() 出来,发现采样点要么是 0 ,要么是 2048 ,最后出现的 4096 应该是由于强行中断运行造成的

最终,我放弃了音频编码,毕竟音频对我而言不是很重要,一方面 Flash 原生只支持 mp3 而不支持 wav,但我最后出视频的时候还会再转码,为了避免二压肯定会用 wav 作为外部轨道,另一方面这样输出的视频可以作为蒙版给其他软件使用,有无音频根本无所谓.

Demo

发表评论?

0 条评论。

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">