Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

播放视频

Godot 通过 VideoStreamPlayer 节点支持视频的播放。

支持的播放格式

核心中仅支持 Ogg Theora 格式(请勿与 Ogg Vorbis 音频混淆)。扩展可以支持额外的格式,但是截止到 2022 年 7 月,还没有这种扩展存在。

Godot 核心无法支持 H.264 和 H.265,因为它们都被软件专利所限。AV1 不需要授权,但 CPU 解码仍然很慢,也不是所有 GPU 都已支持硬件解码。

Godot 3.x 核心中支持 WebM,但是会在 4.0 中移除支持,因为 bug 很多且难以维护。

备注

你的视频可能使用的是 .ogg 或者 .ogx 扩展名,这是带有数据的 Ogg 容器的通用扩展名。

将这些文件扩展名修改为 .ogv可能可以让视频在 Godot 中导入。不过,并不是所有 .ogg.ogx 扩展名的文件都是视频——有些可能只包含音频。

设置 VideoStreamPlayer

  1. 使用“新建 Node”对话框创建 VideoStreamPlayer 节点。

  2. 在场景树面板上选中 VideoStreamPlayer 节点,到检查器中为 Stream 属性加载 .ogv 文件。

  3. 如果你希望在场景加载时立即播放视频,请在检查器中勾选 Autoplay。否则,请保持 Autoplay 关闭,并在需要时在脚本中调用 VideoStreamPlayer 节点的 play() 开始播放。

处理大小变化及不同的纵横比

Godot 4.0 中在默认情况下,VideoStreamPlayer 会自动调整到与视频分辨率相匹配的大小。你可以让它遵循普通的 Control 大小规则,启用 VideoStreamPlayer 节点的 Expand 即可。

要调整 VideoStreamPlayer 节点的大小随窗口大小改变的方式,请通过 2D 编辑器视口顶部的布局按钮调整锚点。不过,这种设置可能不足以处理所有可能的情况,例如全屏播放视频但不造成形变(需要在边界处留白)。要进行精确的控制,你可以使用专为处理这种情况设计的 AspectRatioContainer 节点:

添加一个 AspectRatioContainer 节点。请确保它不是任何其他容器节点的子节点。选中该 AspectRatioContainer 节点,然后在 2D 编辑器的顶部将布局设置为整个矩形。将 AspectRatioContainer 节点的 Ratio(比例)设置为与你的视频的长宽比匹配的比例。你可以在检查器里直接输入数学公式。请记住要将其中的一个操作数写成浮点形式,否则会得到整数的商。

在编辑器检查器中修改 AspectRatioContainer 的 Ratio 属性

求值会得到(大约)1.777778

配置好 AspectRatioContainer 之后,请将你的 VideoStreamPlayer 节点调整为该 AspectRatioContainer 节点的子节点。请确保禁用了该 VideoPlayer 的 Expand。你的视频现在应该就会自动适应到全屏的大小,不产生变形。

参见

更多在项目中支持不同的长宽比的技巧,请参阅 多分辨率

在 3D 表面上显示视频

使用 VideoStreamPlayer 节点作为 SubViewport 节点的子节点,就可以在 3D 表面上显示任何 2D 节点。例如,可以用于显示动态的广告板,帧动画可能花费太多的内存。

可以使用以下步骤实现:

  1. 创建一个 SubViewport 节点。将其设置为与你的视频大小相匹配的像素大小。

  2. 创建一个 VideoStreamPlayer 节点作为该 SubViewport 节点的子节点,并为其指定一个视频的路径。请确保禁用了 Expand,需要时启用 Autoplay

  3. 创建一个 MeshInstance3D 节点,将其 Mesh 属性设为 PlaneMesh 或 QuadMesh。将该网格的大小调整到与视频的长宽比一致(否则看上去就会变形)。

  4. 在 GeometryInstance3D 部分的 Material Override 属性中新建一个 StandardMaterial3D 资源。

  5. 在该 StandardMaterial3D(底部)的 Resource 部分启用 Local To Scene。这是在 Albedo Texture 属性中使用 ViewportTexture 所必须的

  6. 在该 StandardMaterial3D中,将 Albedo > Texture 属性设置为新建 ViewportTexture。点击编辑这个新的资源,在 Viewport Path 属性中指定指向 SubViewport 节点的路径。

  7. 在该 StandardMaterial3D 中启用 Albedo Texture Force sRGB,防止颜色变化。

  8. 如果广告板需要自发光,请将 着色模式 设置为 无阴着色 以提高渲染性能。

更多关于设置的信息,请参阅 使用 Viewport3D GUI 演示

循环视频

要循环视频,可以启用 Loop 属性。这样视频在抵达末尾时就会无缝重启。

Note that setting the project setting Video Delay Compensation to a non-zero value might cause your loop to not be seamless, because the synchronization of audio and video takes place at the start of each loop causing occasional missed frames. Set Video Delay Compensation in your project settings to 0 to avoid frame drop issues.

播放限制

Godot 中目前的视频播放实现有一些限制:

  • 不支持将视频跳跃到特定的时间点。

  • 不支持修改播放速度。VideoStreamPlayer 也不会遵循 Engine.time_scale

  • 不支持从 URL 播放视频流。

色键视频

色键(Chroma Key)也就是常说的“绿幕”“蓝幕”效果,能够移除图像或视频中的特定颜色,替换为其他背景。这种效果在视频制作领域广泛使用,可以将不同的元素无缝合成到一起。

../../_images/chroma_key_video.webp

We will achieve the chroma key effect by writing a custom shader in GDScript and using a VideoStreamPlayer node to display the video content.

场景设置

Ensure that the scene contains a VideoStreamPlayer node to play the video and a Control node to hold the UI elements for controlling the chroma key effect.

../../_images/chroma_key_scene.webp

编写自定义着色器

To implement the chroma key effect, follow these steps:

  1. Select the VideoStreamPlayer node in the scene and go to its properties. Under CanvasItem > Material, create a new shader named "ChromaKeyShader.gdshader."

  2. In the "ChromaKeyShader.gdshader" file, write the custom shader code as shown below:

shader_type canvas_item;

# Uniform variables for chroma key effect
uniform vec3 chroma_key_color : source_color = vec3(0.0, 1.0, 0.0);
uniform float pickup_range : hint_range(0.0, 1.0) = 0.1;
uniform float fade_amount : hint_range(0.0, 1.0) = 0.1;

void fragment() {
    # Get the color from the texture at the given UV coordinates
    vec4 color = texture(TEXTURE, UV);

    # Calculate the distance between the current color and the chroma key color
    float distance = length(color.rgb - chroma_key_color);

    # If the distance is within the pickup range, discard the pixel
    # the lesser the distance more likely the colors are
    if (distance <= pickup_range) {
        discard;
    }

    # Calculate the fade factor based on the pickup range and fade amount
    float fade_factor = smoothstep(pickup_range, pickup_range + fade_amount, distance);

    # Set the output color with the original RGB values and the calculated fade factor
    COLOR = vec4(color.rgb, fade_factor);
}

The shader uses the distance calculation to identify pixels close to the chroma key color and discards them, effectively removing the selected color. Pixels that are slightly further away from the chroma key color are faded based on the fade_factor, blending them smoothly with the surrounding colors. This process creates the desired chroma key effect, making it appear as if the background has been replaced with another image or video.

The code above represents a simple demonstration of the Chroma Key shader, and users can customize it according to their specific requirements.

UI 控件

To allow users to manipulate the chroma key effect in real-time, we created sliders in the Control node. The Control node's script contains the following functions:

extends Control

func _on_color_picker_button_color_changed(color):
    # Update the "chroma_key_color" shader parameter of the VideoStreamPlayer's material
    $VideoStreamPlayer.material.set("shader_parameter/chroma_key_color", color)

func _on_h_slider_value_changed(value):
    # Update the "pickup_range" shader parameter of the VideoStreamPlayer's material
    $VideoStreamPlayer.material.set("shader_parameter/pickup_range", value)

func _on_h_slider_2_value_changed(value):
    # Update the "fade_amount" shader parameter of the VideoStreamPlayer's material
    $VideoStreamPlayer.material.set("shader_parameter/fade_amount", value)

func _on_video_stream_player_finished():
    # Restart the video playback when it's finished
    $VideoStreamPlayer.play()

also make sure that the range of the sliders are appropriate, our settings are :

../../_images/slider_range.webp

信号处理

Connect the appropriate signal from the UI elements to the Control node's script. you created in the Control node's script to control the chroma key effect. These signal handlers will update the shader's uniform variables in response to user input.

Save and run the scene to see the chroma key effect in action! With the provided UI controls, you can now adjust the chroma key color, pickup range, and fade amount in real-time, achieving the desired chroma key functionality for your video content.