跳到主要内容

使用视频节点

VideoNode 是 Dora SSR 引擎中的节点类,允许您在游戏场景中播放视频文件。它继承自 Sprite,这意味着您可以使用所有精灵节点可用的属性和方法,例如定位、缩放、旋转等。一旦 VideoNode 被挂载到游戏场景中,它将自动开始播放视频,并持续播放直到节点从场景中移除。

本教程将指导您如何使用 VideoNode,包括如何准备正确格式的视频文件以及如何在游戏中使用 VideoNode。

1. 视频格式要求

VideoNode 接受包含 Theora 视频流的 Ogg 容器。文件统一通过 Dora Content 读取,因此打包资源和挂载归档使用与其它资源相同的路径规则。

1.1 支持的视频格式

  • 容器:Ogg(.ogv
  • 视频编码:Theora
  • 色彩格式:支持 Theora 4:2:0、4:2:2 和 4:4:4,并在渲染前转换为 RGBA
  • 音频:VideoNode 只渲染视频;Love Video 可另外通过 Dora SoLoud 同步音频 Source
  • 分辨率/性能
    • 4K 和高码率流在纯软件解码时可能会占用大量 CPU
    • 为了在中等性能设备上流畅播放,推荐使用 720p/1080p 和适中的码率

1.2 使用 FFmpeg 转换视频

可使用带 libtheora 编码器的 FFmpeg 生成 Ogg/Theora 文件:

将 MP4 转换为 Ogg/Theora

# 基本转换
ffmpeg -i input.mp4 -c:v libtheora -q:v 7 -pix_fmt yuv420p -an output.ogv

# 指定分辨率和码率(推荐以获得更好的性能)
ffmpeg -i input.mp4 -c:v libtheora -q:v 7 -pix_fmt yuv420p -s 1280x720 -r 30 -an output.ogv

# 1080p 视频
ffmpeg -i input.mp4 -c:v libtheora -q:v 7 -pix_fmt yuv420p -s 1920x1080 -r 30 -an output.ogv

参数说明:

  • -c:v libtheora:使用 Theora 编码器
  • -q:v 7:设置视频质量(可按体积与画质需求调整)
  • -pix_fmt yuv420p:设置像素格式为 YUV 4:2:0
  • -s 1280x720:设置分辨率(可选,根据需要调整)
  • -r 30:设置帧率为 30 fps(可选,根据需要调整)
  • -an:移除音频轨道

转换其他格式

# 从 AVI 转换
ffmpeg -i input.avi -c:v libtheora -q:v 7 -pix_fmt yuv420p -an output.ogv

# 从 MOV 转换
ffmpeg -i input.mov -c:v libtheora -q:v 7 -pix_fmt yuv420p -an output.ogv
提示

转换后请保留 .ogv 扩展名,并将文件放入项目的 Content 资源树。

2. 创建 VideoNode 实例

要创建 VideoNode,您需要提供视频文件的路径。VideoNode 构造函数接受两个参数:

  • filename:Ogg/Theora 视频的 Content 路径(通常为 .ogv
  • looped:(可选)视频是否循环播放。默认为 false
local VideoNode <const> = require("VideoNode")

-- 创建一个播放一次的 VideoNode
local video = VideoNode("assets/video.ogv")

-- 创建一个循环播放的 VideoNode
local loopingVideo = VideoNode("assets/video.ogv", true)
重要提示

如果视频文件无法加载或格式不正确,VideoNode() 将返回 nil(在 TypeScript 中为 null)。在使用之前,请务必检查节点是否创建成功。

3. 将 VideoNode 挂载到场景

创建 VideoNode 实例后,您需要将其挂载到游戏场景中才能显示并开始播放。当 VideoNode 被挂载到场景时,它将自动开始播放视频,并持续播放直到节点从场景中移除。

local VideoNode <const> = require("VideoNode")
local Vec2 <const> = require("Vec2")

-- 创建一个 VideoNode
local video = VideoNode("assets/video.ogv")

if video then
-- 设置位置
video.position = Vec2(400, 300)

-- 挂载到场景(视频将自动开始播放)
-- 只要节点在场景中,视频就会持续播放
end
自动播放

一旦 VideoNode 被挂载到游戏场景,它将自动开始播放视频。只要节点保留在场景树中,视频就会逐帧持续播放。如果您将 looped 设置为 true,视频在播放到结尾时会自动从头开始重新播放。

4. 控制视频播放

由于 VideoNode 继承自 Sprite,您可以使用所有精灵属性和方法来控制视频显示:

local VideoNode <const> = require("VideoNode")
local Vec2 <const> = require("Vec2")
local Scale <const> = require("Scale")

local video = VideoNode("assets/video.ogv", true) -- 启用循环

if video then
-- 定位视频
video.position = Vec2(400, 300)

-- 缩放视频
video.scaleX = 0.5
video.scaleY = 0.5

-- 旋转视频
video.angle = 45

-- 设置透明度
video.opacity = 0.8

-- 或使用动作来动画化
video:perform(Scale(2.0, 0.5, 1.0)) -- 在 1 秒内从 0.5 缩放到 2.0
end

5. 从场景中移除 VideoNode

要停止视频播放,只需从场景中移除 VideoNode:

-- 从父节点移除视频节点(停止播放)
video:removeFromParent()

6. 完整示例

以下是一个完整示例,演示如何创建 VideoNode、定位它并在游戏场景中处理它:

local VideoNode <const> = require("VideoNode")
local Vec2 <const> = require("Vec2")
local Size <const> = require("Size")

-- 创建一个循环播放的视频节点
local video = VideoNode("assets/background_video.ogv", true)

if video then
-- 如果需要,缩放到适合屏幕
local visualSize = App.visualSize
local videoSize = video.size
local scaleX = visualSize.width / videoSize.width
local scaleY = visualSize.height / videoSize.height
local scale = math.min(scaleX, scaleY)
video.scaleX = scale
video.scaleY = scale

-- 视频在挂载到场景时会自动开始播放
-- 只要节点在场景中,它就会持续播放并循环
end

7. 性能考虑

使用 VideoNode 时,请注意以下性能提示:

  1. 分辨率:为目标设备使用适当的分辨率(720p 或 1080p)。更高的分辨率需要更多的 CPU 资源进行解码。

  2. 码率:适中的码率可以在质量和性能之间取得良好的平衡。非常高的码率可能导致低端设备出现卡顿。

  3. 帧率:推荐使用恒定帧率(CFR)。可变帧率可能导致时序问题。

  4. 多个视频:同时播放多个视频可能会占用大量 CPU。考虑限制并发 VideoNode 的数量。

  5. 后台处理:VideoNode 使用后台线程进行解码,这有助于保持流畅的游戏体验,但仍需要 CPU 资源。

8. 总结

在本教程中,您学习了如何:

  • 使用 FFmpeg 将视频文件准备为正确的 Ogg/Theora 格式
  • 创建 VideoNode 实例
  • 将 VideoNode 挂载到游戏场景(会自动开始播放)
  • 使用 Sprite 属性控制视频显示
  • 处理视频循环

请记住,VideoNode 在挂载到场景时会自动开始播放,只要它保留在场景树中就会持续播放。这使得它非常适合背景视频、过场动画或任何需要在游戏中连续播放视频的场景。

有关 VideoNode 的更多信息,请参阅 VideoNode API 文档