周三晚上,Codename One的仓库连着收到了三个合并请求。对平时只用这套框架写写表单的开发者来说,这三个PR可能有点陌生——但它们合在一起,等于把整个多媒体处理管线塞进了同一个Java项目里。在这之前,Codename One的媒体API只是一个播放器,能放文件,但没法生成文件。现在不一样了。
事情要从PR #5315说起。这个提交给框架加了一个新模块,叫VideoIO。它不是一个简单的录像接口,而是一个跨平台的视频子系统,能把手绘的每一帧画面和音频流按标准视频文件格式写进磁盘。反过来,也能把已有视频精确解码成RGBA图像帧和无损的PCM音频。对同时维护iOS、Android、桌面和Web四端应用的团队来说,以前要么放弃在App里生成视频,要么给每个平台单独写原生代码。VideoIO尝试把这条路打通。
![]()
最先被关注的是编码能力。和Codename One其他可选平台API一样,VideoIO的调用被一个功能开关保护着:调用VideoIO.isSupported()先判断设备是否支持。一旦确认支持,开发者就可以像搭积木一样构造一个VideoWriter。帧的来源很自由:可以是当前UI的截图,可以是游戏循环里的渲染结果,也可以是动画编辑器里的某一帧,或者图表库动态生成的图形。这些帧都是普通的Image对象,不需要专门的数据格式。
在构建写入器的时候,输出的容器格式、视频长宽、帧率、编码器、码率全都可以显式指定。一个典型的配置是用720×1280分辨率、30fps帧率、H.264视频编码、4Mbps码率,音频部分用AAC编码、44100Hz采样率和双声道。如果设备不支持H.264,可以退回到其他编码器。VideoIO还提供了getAvailableEncoders()和getAvailableDecoders()两个方法,可以直接查询当前设备上到底有哪些硬解加速方案可用,避免开发者猜测。
写入循环的代码非常简单。比如要生成3秒的动画,就是循环90次,每帧附上基于帧序号计算的时间戳,然后把画面抛给writer.writeFrame()。音频轨道则是提前渲染成一整段short数组,调用writer.writeAudio()一次性写进去。合成结束关闭writer,一个完整的MP4文件就出现在App的本地目录里了。这种流程对已经熟悉游戏帧渲染或自定义绘制的开发者来说,几乎没有额外的学习成本。
但Codename One这次更新真正让早期用户兴奋的,是视频读取侧提供的能力。旧API的播放器也能seek,但跳转的精度通常受限于关键帧。如果你想生成一段视频的精确缩略图、验证刚渲染的动画每一帧是否正确、或者从视频里抽取中间帧做图像处理,关键帧级别的seek根本不够用。VideoReader.frameAt(millis)直接解决了这个问题:传一个毫秒值进去,它返回那个时间点精确的一帧。
这一帧不止是画面。返回的VideoFrame对象里同时包括了RGBA图像数据和在时间线上的位置,用来做测试回放验证非常方便。更进一步,readFrames方法可以让你以固定间隔重采样整个视频,每一帧都交给回调去处理,适合批量导出或逐帧分析。如果设备底层支持,readAudio()还能把整个音频轨读出一个AudioBuffer,里面是解码后的PCM音频数据。
需要注意的是,各个平台的支持进度还不完全一致。JavaScript端已经支持帧解码和全编码,但解码后的音频提取还没有接通。电视、手表和车载平台由于环境限制,暂时不会暴露VideoIO的能力。不过对手机、桌面和Web三个主要目标来说,这套接口已经可以跑通完整的视频生成和精确解码链路。
PR #5317紧接着引入了AudioMixer。这是一个非常精简的PCM混音模块,设计目标只有一个:把多轨归一化到[-1,1]区间的浮点PCM数据,在同一个采样时钟下混合。虽然功能轻量,但采样级精度意味着它可以胜任那些对音画同步要求极高的场景——比如短视频编辑、游戏内过场动画的音效叠加、或者多轨旁白合成。混音时只需要创建对应的AudioBuffer,指定采样率和声道数拷入数据,AudioMixer就会在内部按统一的时钟把它们混合输出。
同批合并的PR #5319给这次的媒体管线补上了最后一块拼图:带时间戳的Whisper转录片段。Codename One现在可以直接对音频调用Whisper模型,返回的并不是一段纯文本,而是切分好的、每个片段都带着起止时间码的结果,并且可以直接导出为SRT或VTT字幕格式。这三项更新放在一起看,就形成了一个完整的制作闭环:先在App里用VideoIO把画面和音频合成视频文件,用AudioMixer处理多轨音频,然后跑一次Whisper转录做字幕,最终导出一个带字幕文件的成品视频。
过去很多开发者之所以不在跨平台框架里做视频生成,只是因为它「做不到」。Codename One这次更新,等于说「现在可以了」。而这个能力并没有牺牲框架原本的跨平台特性。VideoIO遵循其他可选API的一贯设计,背后根据平台自动选用原生的MediaCodec、VideoToolbox或WebCodecs,但暴露给开发者的是同一套Java接口。这意味着一旦写好生成逻辑,它就能原样运行在多个平台上。
从社区早期反馈来看,大家对精确帧解码和AudioMixer的兴趣甚至超过了视频生成本身。有开发者已经在尝试把VideoIO用在自动化测试里:先让程序把特定场景的动画渲染成视频,然后用frameAt逐帧对比预期结果,发现像素级差异立刻报错。这在以前需要依赖外部分析工具,现在全部可以留在Codename One项目内部完成。这或许说明,框架提供的不仅仅是几个新API,而是让原本只能在外围工具链里完成的流程,回归到了代码仓库里。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.