一个可独立使用的 Godot 3.x GDNative 音视频解码器:通过 Windows Media Foundation 把 H.264 MP4 逐帧解码成 RGBA8,并以 Float PCM 流式输出音频。
是。这个项目已经从 godot_vap_3x 中抽离,核心类是 MP4Decoder。它完全不知道 Tencent VAP、透明通道或动态融合,只提供普通视频解码能力:
MP4 文件
↓ Windows Media Foundation
├─ 独立视频 SourceReader → RGB32 → RGBA8 → ImageTexture
└─ 独立音频 SourceReader → Float PCM → AudioStreamGenerator
godot_vap_3x 只是这个 addon 的一个使用方。
| 功能 | 状态 |
|---|---|
| 打开本地 MP4 | ✅ |
| 顺序解码视频帧 | ✅ |
输出 RGBA8 PoolByteArray |
✅ |
| 宽度、高度、帧率、估算帧数 | ✅ |
| seek 到视频开头 | ✅ |
| Windows Unicode 路径 | ✅ |
| MP4 音频流式播放 | ✅ |
| 音频时间戳 seek | ✅ |
| 视频任意时间戳随机 seek | ❌ |
| Linux/macOS/Android 二进制 | ❌ |
godot_mp4_decoder_3x/
├── addons/godot_mp4_decoder/ 可直接复制到项目的 addon
│ ├── native/mp4_decoder.gdns
│ └── bin/windows/
├── native_src/ C++ 与可复现构建环境
│ ├── src/mp4_decoder.cpp
│ ├── godot-cpp/ Godot 3.5 分支
│ └── SConstruct
├── demo/video.mp4
└── main.gd 最小播放器 demo
- Windows x86_64。
- Godot 3.x;预编译 DLL 已在 3.5.3 验证。
- Windows Media Foundation(Windows 系统自带)。
libwinpthread-1.dll,已经放在 addon 的bin/windows中。- 不依赖 FFmpeg,不需要安装 codec、proto 或其他全局工具。
复制:
addons/godot_mp4_decoder
到目标项目的 addons 下,再在插件设置中启用 Godot MP4 Decoder 3.x。
extends TextureRect
const MP4Decoder = preload("res://addons/godot_mp4_decoder/native/mp4_decoder.gdns")
var decoder
var frame_texture
func _ready():
decoder = MP4Decoder.new()
var path = ProjectSettings.globalize_path("res://video/demo.mp4")
if not decoder.open(path):
push_error(decoder.get_last_error())
return
print(decoder.get_width(), "x", decoder.get_height(), " @ ", decoder.get_fps())
func _process(_delta):
if not decoder.decode_next_frame():
return
var image = Image.new()
image.create_from_data(
decoder.get_width(),
decoder.get_height(),
false,
Image.FORMAT_RGBA8,
decoder.get_frame_rgba()
)
if frame_texture == null:
frame_texture = ImageTexture.new()
frame_texture.create_from_image(image, 0)
else:
frame_texture.set_data(image)
texture = frame_texture真实播放器应按 1.0 / get_fps() 控制调用频率。完整实现见本项目的 main.gd。
| 方法 | 返回 | 说明 |
|---|---|---|
open(absolute_path) |
bool |
打开 MP4,只接受本机路径 |
close() |
— | 释放 SourceReader 和帧数据 |
decode_next_frame() |
bool |
解码下一视频帧;EOF 返回 false |
seek_start() |
bool |
回到视频开头 |
decode_audio_frames(max_frames) |
PoolVector2Array |
增量解码双声道 Float PCM;单声道会复制到左右声道 |
seek_audio(seconds) |
bool |
音频定位到指定秒数 |
seek_audio_start() |
bool |
音频回到开头 |
has_audio() |
bool |
是否发现可解码音轨 |
get_audio_sample_rate() |
int |
音频采样率 |
get_audio_channels() |
int |
源音轨声道数 |
is_open() |
bool |
是否已打开 |
get_width() / get_height() |
int |
解码尺寸 |
get_fps() |
float |
流声明帧率 |
get_frame_count() |
int |
根据 duration × fps 估算 |
get_current_frame() |
int |
当前顺序帧编号,从 0 开始 |
get_frame_rgba() |
PoolByteArray |
width × height × 4 字节 |
get_last_error() |
String |
最近一次错误 |
当前源码树已经带有 godot-cpp 3.5 bindings 和生成好的 Media Foundation import library。Windows 下使用 MinGW/SCons:
$env:PATH = 'D:\env\mingw64\bin;' + $env:PATH
Set-Location D:\code\project\godot-vap\godot_mp4_decoder_3x\native_src
D:\env\Anaconda3\miniconda3\python.exe -m SCons -j4输出:
addons/godot_mp4_decoder/bin/windows/mp4_decoder_native.dll
若要面向其他 Godot 3.x 小版本构建,切换 native_src/godot-cpp 和 godot-headers 到对应兼容分支,重新生成 bindings 和静态库,再编译本 DLL。
用 Godot 3.5.3 打开本目录运行即可。Demo 会循环播放 demo/video.mp4 的画面和音轨,并显示尺寸、帧率与当前帧。
- 当前只交付 Windows x86_64。
- 音视频各自持有一个 Media Foundation
SourceReader,避免在同一个顺序读取器上抢流;同步以同时启动和相同 seek 时间点为基础,不包含长视频级动态漂移校正。 - 每帧经 CPU 转 RGBA,再上传 Godot 纹理;适合短动画、工具预览和兼容层,不适合 4K 长视频播放器。
get_frame_count()是估算值;VFR 视频不保证逐帧编号与时间轴完全等价。- 视频当前只实现
seek_start(),没有任意时间戳 seek;音频支持seek_audio(seconds)。
- 本项目原生实现可按仓库许可使用。
godot-cpp使用 MIT License,许可文本见native_src/godot-cpp/LICENSE.md。- Windows Media Foundation 属于 Windows 系统 API,不随本项目分发其实现。