playing_videos.rst 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. .. _doc_playing_videos:
  2. Playing videos
  3. ==============
  4. Godot supports video playback with the :ref:`class_VideoStreamPlayer` node.
  5. Supported playback formats
  6. --------------------------
  7. The only supported format in core is **Ogg Theora** (not to be confused with
  8. Ogg Vorbis audio) with optional Ogg Vorbis audio tracks. It's possible for
  9. extensions to bring support for additional formats.
  10. H.264 and H.265 cannot be supported in core Godot, as they are both encumbered
  11. by software patents. AV1 is royalty-free, but it remains slow to decode on the
  12. CPU and hardware decoding support isn't readily available on all GPUs in use
  13. yet.
  14. WebM was supported in core in Godot 3.x, but support for it was removed in 4.0
  15. as it was too buggy and difficult to maintain.
  16. .. note::
  17. You may find videos with an ``.ogg`` or ``.ogx`` extensions, which are generic
  18. extensions for data within an Ogg container.
  19. Renaming these file extensions to ``.ogv`` *may* allow the videos to be
  20. imported in Godot. However, not all files with ``.ogg`` or ``.ogx``
  21. extensions are videos - some of them may only contain audio.
  22. Setting up VideoStreamPlayer
  23. ----------------------------
  24. 1. Create a VideoStreamPlayer node using the Create New Node dialog.
  25. 2. Select the VideoStreamPlayer node in the scene tree dock, go to the inspector
  26. and load an ``.ogv`` file in the Stream property.
  27. - If you don't have your video in Ogg Theora format yet, jump to
  28. :ref:`doc_playing_videos_recommended_theora_encoding_settings`.
  29. 3. If you want the video to play as soon as the scene is loaded, check
  30. **Autoplay** in the inspector. If not, leave **Autoplay** disabled and call
  31. ``play()`` on the VideoStreamPlayer node in a script to start playback when
  32. desired.
  33. Handling resizing and different aspect ratios
  34. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  35. By default in Godot 4.0, the VideoStreamPlayer will automatically be resized to match
  36. the video's resolution. You can make it follow usual :ref:`class_Control` sizing
  37. by enabling **Expand** on the VideoStreamPlayer node.
  38. To adjust how the VideoStreamPlayer node resizes depending on window size,
  39. adjust the anchors using the **Layout** menu at the top of the 2D editor
  40. viewport. However, this setup may not be powerful enough to handle all use
  41. cases, such as playing fullscreen videos without distorting the video (but with
  42. empty space on the edges instead). For more control, you can use an
  43. :ref:`class_AspectRatioContainer` node, which is designed to handle this kind of
  44. use case:
  45. Add an AspectRatioContainer node. Make sure it is not a child of any other
  46. container node. Select the AspectRatioContainer node, then set its **Layout** at
  47. the top of the 2D editor to **Full Rect**. Set **Ratio** in the
  48. AspectRatioContainer node to match your video's aspect ratio. You can use math
  49. formulas in the inspector to help yourself. Remember to make one of the operands
  50. a float. Otherwise, the division's result will always be an integer.
  51. .. figure:: img/playing_videos_aspect_ratio_container.png
  52. :figclass: figure-w480
  53. :align: center
  54. :alt: AspectRatioContainer's Ratio property being modified in the editor inspector
  55. This will evaluate to (approximately) 1.777778
  56. Once you've configured the AspectRatioContainer, reparent your VideoStreamPlayer
  57. node to be a child of the AspectRatioContainer node. Make sure **Expand** is
  58. enabled on the VideoStreamPlayer. Your video should now scale automatically
  59. to fit the whole screen while avoiding distortion.
  60. .. seealso::
  61. See :ref:`doc_multiple_resolutions` for more tips on supporting multiple
  62. aspect ratios in your project.
  63. Displaying a video on a 3D surface
  64. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  65. Using a VideoStreamPlayer node as a child of a :ref:`class_SubViewport` node,
  66. it's possible to display any 2D node on a 3D surface. For example, this can be
  67. used to display animated billboards when frame-by-frame animation would require
  68. too much memory.
  69. This can be done with the following steps:
  70. 1. Create a :ref:`class_SubViewport` node. Set its size to match your video's size
  71. in pixels.
  72. 2. Create a VideoStreamPlayer node *as a child of the SubViewport node* and specify
  73. a video path in it. Make sure **Expand** is disabled, and enable **Autoplay** if needed.
  74. 3. Create a MeshInstance3D node with a PlaneMesh or QuadMesh resource in its Mesh property.
  75. Resize the mesh to match the video's aspect ratio (otherwise, it will appear distorted).
  76. 4. Create a new StandardMaterial3D resource in the **Material Override** property
  77. in the GeometryInstance3D section.
  78. 5. Enable **Local To Scene** in the StandardMaterial3D's Resource section (at the bottom).
  79. This is *required* before you can use a ViewportTexture in its Albedo Texture property.
  80. 6. In the StandardMaterial3D, set the **Albedo > Texture** property to **New ViewportTexture**.
  81. Edit the new resource by clicking it, then specify the path to the SubViewport node
  82. in the **Viewport Path** property.
  83. 7. Enable **Albedo Texture Force sRGB** in the StandardMaterial3D to prevent colors
  84. from being washed out.
  85. 8. If the billboard is supposed to emit its own light,
  86. set **Shading Mode** to **Unshaded** to improve rendering performance.
  87. See :ref:`doc_viewports` and the
  88. `GUI in 3D demo <https://github.com/godotengine/godot-demo-projects/tree/master/viewport/gui_in_3d>`__
  89. for more information on setting this up.
  90. Looping a video
  91. ~~~~~~~~~~~~~~~
  92. For looping a video, the **Loop** property can be enabled. This will seamlessly
  93. restart the video when it reaches its end.
  94. Note that setting the project setting **Video Delay Compensation** to a non-zero
  95. value might cause your loop to not be seamless, because the synchronization of
  96. audio and video takes place at the start of each loop causing occasional missed
  97. frames. Set **Video Delay Compensation** in your project settings to **0** to
  98. avoid frame drop issues.
  99. Video decoding conditions and recommended resolutions
  100. -----------------------------------------------------
  101. Video decoding is performed on the CPU, as GPUs don't have hardware acceleration
  102. for decoding Theora videos. Modern desktop CPUs can decode Ogg Theora videos at
  103. 1440p @ 60 FPS or more, but low-end mobile CPUs will likely struggle with
  104. high-resolution videos.
  105. To ensure your videos decode smoothly on varied hardware:
  106. - When developing games for desktop platforms, it's recommended to encode in
  107. 1080p at most (preferably at 30 FPS). Most people are still using 1080p or
  108. lower resolution displays, so encoding higher-resolution videos may not be
  109. worth the increased file size and CPU requirements.
  110. - When developing games for mobile or web platforms, it's recommended to encode
  111. in 720p at most (preferably at 30 FPS or even lower). The visual difference
  112. between 720p and 1080p videos on a mobile device is usually not that
  113. noticeable.
  114. Playback limitations
  115. --------------------
  116. There are several limitations with the current implementation of video playback in Godot:
  117. - Seeking a video to a certain point is not supported.
  118. - Changing playback speed is not supported. VideoStreamPlayer also won't follow
  119. :ref:`Engine.time_scale<class_Engine_property_time_scale>`.
  120. - Streaming a video from a URL is not supported.
  121. - Only mono and stereo audio output is supported.
  122. .. _doc_playing_videos_recommended_theora_encoding_settings:
  123. Recommended Theora encoding settings
  124. ------------------------------------
  125. A word of advice is to **avoid relying on built-in Ogg Theora exporters** (most of the time).
  126. There are 2 reasons you may want to favor using an external program to encode your video:
  127. - Some programs such as Blender can render to Ogg Theora. However, the default
  128. quality presets are usually very low by today's standards. You may be able to
  129. increase the quality options in the software you're using, but you may find
  130. the output quality to remain less than ideal (given the increased file size).
  131. This usually means that the software only supports encoding to constant bit
  132. rate (CBR), instead of variable bit rate (VBR). VBR encoding should be
  133. preferred in most scenarios as it provides a better quality to file size
  134. ratio.
  135. - Some other programs can't render to Ogg Theora at all.
  136. In this case, you can **render the video to an intermediate high-quality format**
  137. (such as a high-bitrate H.264 video) then re-encode it to Ogg Theora. Ideally,
  138. you should use a lossless or uncompressed format as an intermediate format to
  139. maximize the quality of the output Ogg Theora video, but this can require a lot
  140. of disk space.
  141. `FFmpeg <https://ffmpeg.org/>`__ (CLI) is a popular open source tool
  142. for this purpose. FFmpeg has a steep learning curve, but it's powerful tool.
  143. Here are example FFmpeg commands to convert an MP4 video to Ogg Theora. Since
  144. FFmpeg supports a lot of input formats, you should be able to use the commands
  145. below with almost any input video format (AVI, MOV, WebM, …).
  146. .. note::
  147. Make sure your copy of FFmpeg is compiled with libtheora and libvorbis support.
  148. You can check this by running ``ffmpeg`` without any arguments, then looking
  149. at the ``configuration:`` line in the command output.
  150. .. UPDATE: When the FFmpeg bugfixes for https://trac.ffmpeg.org/ticket/11451 and
  151. .. https://trac.ffmpeg.org/ticket/11454 are included in a stable FFmpeg release,
  152. .. this note can be removed. That will likely be FFmpeg 7.2 or 8.0, and will
  153. .. likely happen during the Godot 4.5 or 4.6 release cycle.
  154. .. warning::
  155. All FFmpeg releases before Feb 20th, 2025 could produce bad video streams
  156. due to a couple of bugs. It's highly recommended to use one of the latest
  157. static daily builds, or build FFmpeg from their master branch where they're
  158. already fixed.
  159. Balancing quality and file size
  160. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  161. The **video quality** level (``-q:v``) must be between ``1`` and ``10``. Quality
  162. ``6`` is a good compromise between quality and file size. If encoding at a high
  163. resolution (such as 1440p or 4K), you will probably want to decrease ``-q:v`` to
  164. ``5`` to keep file sizes reasonable. Since pixel density is higher on a 1440p or
  165. 4K video, lower quality presets at higher resolutions will look as good or
  166. better compared to low-resolution videos.
  167. The **audio quality** level (``-q:a``) must be between ``-1`` and ``10``. Quality
  168. ``6`` provides a good compromise between quality and file size. In contrast to
  169. video quality, increasing audio quality doesn't increase the output file size
  170. nearly as much. Therefore, if you want the cleanest audio possible, you can
  171. increase this to ``9`` to get *perceptually lossless* audio. This is especially
  172. valuable if your input file already uses lossy audio compression. Higher quality
  173. audio does increase the CPU usage of the decoder, so it might lead to audio
  174. dropouts in case of high system load. See
  175. `this page <https://wiki.hydrogenaud.io/index.php?title=Recommended_Ogg_Vorbis#Recommended_Encoder_Settings>`__
  176. for a table listing Ogg Vorbis audio quality presets and their respective
  177. variable bitrates.
  178. The **GOP (Group of Pictures) size** (``-g:v``) is the max interval between
  179. keyframes. Increasing this value can improve compression with almost no impact
  180. on quality. The valid range goes from ``0`` to ``2,147,483,648``, although
  181. compression benefits will fade away and even be reversed as the GOP size
  182. increases. The default size (``12``) is too low for most types of content, it's
  183. therefore recommended to test higher GOP sizes before reducing video quality.
  184. Values between ``64`` and ``512`` usually give the best compression.
  185. FFmpeg: Convert while preserving original video resolution
  186. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  187. The following command converts the video while keeping its original resolution.
  188. The video and audio's bitrate will be variable to maximize quality while saving
  189. space in parts of the video/audio that don't require a high bitrate (such as
  190. static scenes).
  191. ::
  192. ffmpeg -i input.mp4 -q:v 6 -q:a 6 -g:v 64 output.ogv
  193. FFmpeg: Resize the video then convert it
  194. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  195. The following command resizes a video to be 720 pixels tall (720p), while
  196. preserving its existing aspect ratio. This helps decrease the file size
  197. significantly if the source is recorded at a higher resolution than 720p:
  198. ::
  199. ffmpeg -i input.mp4 -vf "scale=-1:720" -q:v 6 -q:a 6 -g:v 64 output.ogv
  200. .. Chroma Key Functionality Documentation
  201. Chroma Key Videos
  202. -----------------
  203. Chroma key, commonly known as the "green screen" or "blue screen" effect, allows you to remove a specific color from an image or video and replace it with another background. This effect is widely used in video production to composite different elements together seamlessly.
  204. .. image:: img/chroma_key_video.webp
  205. We will achieve the chroma key effect by writing a custom shader in GDScript and using a `VideoStreamPlayer` node to display the video content.
  206. Scene Setup
  207. ~~~~~~~~~~~
  208. 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.
  209. .. image:: img/chroma_key_scene.webp
  210. Writing the Custom Shader
  211. ~~~~~~~~~~~~~~~~~~~~~~~~~
  212. To implement the chroma key effect, follow these steps:
  213. 1. Select the `VideoStreamPlayer` node in the scene and go to its properties. Under `CanvasItem > Material`, create a new shader named "ChromaKeyShader.gdshader."
  214. 2. In the "ChromaKeyShader.gdshader" file, write the custom shader code as shown below:
  215. .. code-block:: glsl
  216. shader_type canvas_item;
  217. // Uniform variables for chroma key effect
  218. uniform vec3 chroma_key_color : source_color = vec3(0.0, 1.0, 0.0);
  219. uniform float pickup_range : hint_range(0.0, 1.0) = 0.1;
  220. uniform float fade_amount : hint_range(0.0, 1.0) = 0.1;
  221. void fragment() {
  222. // Get the color from the texture at the given UV coordinates
  223. vec4 color = texture(TEXTURE, UV);
  224. // Calculate the distance between the current color and the chroma key color
  225. float distance = length(color.rgb - chroma_key_color);
  226. // If the distance is within the pickup range, discard the pixel
  227. // the lesser the distance more likely the colors are
  228. if (distance <= pickup_range) {
  229. discard;
  230. }
  231. // Calculate the fade factor based on the pickup range and fade amount
  232. float fade_factor = smoothstep(pickup_range, pickup_range + fade_amount, distance);
  233. // Set the output color with the original RGB values and the calculated fade factor
  234. COLOR = vec4(color.rgb, fade_factor);
  235. }
  236. The shader uses the distance calculation to identify pixels close to the chroma key color and discards them,
  237. effectively removing the selected color. Pixels that are slightly further away from the chroma key color are
  238. faded based on the fade_factor, blending them smoothly with the surrounding colors.
  239. This process creates the desired chroma key effect, making it appear as if the background has been replaced with
  240. another image or video.
  241. The code above represents a simple demonstration of the Chroma Key shader,
  242. and users can customize it according to their specific requirements.
  243. UI Controls
  244. ~~~~~~~~~~~
  245. 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:
  246. .. tabs::
  247. .. code-tab:: gdscript
  248. extends Control
  249. func _on_color_picker_button_color_changed(color):
  250. # Update the "chroma_key_color" shader parameter of the VideoStreamPlayer's material.
  251. $VideoStreamPlayer.material.set("shader_parameter/chroma_key_color", color)
  252. func _on_h_slider_value_changed(value):
  253. # Update the "pickup_range" shader parameter of the VideoStreamPlayer's material.
  254. $VideoStreamPlayer.material.set("shader_parameter/pickup_range", value)
  255. func _on_h_slider_2_value_changed(value):
  256. # Update the "fade_amount" shader parameter of the VideoStreamPlayer's material.
  257. $VideoStreamPlayer.material.set("shader_parameter/fade_amount", value)
  258. func _on_video_stream_player_finished():
  259. # Restart the video playback when it's finished.
  260. $VideoStreamPlayer.play()
  261. .. code-tab:: csharp
  262. using Godot;
  263. public partial class MyControl : Control
  264. {
  265. private VideoStreamPlayer _videoStreamPlayer;
  266. public override void _Ready()
  267. {
  268. _videoStreamPlayer = GetNode<VideoStreamPlayer>("VideoStreamPlayer");
  269. }
  270. private void OnColorPickerButtonColorChanged(Color color)
  271. {
  272. // Update the "chroma_key_color" shader parameter of the VideoStreamPlayer's material.
  273. _videoStreamPlayer.Material.Set("shader_parameter/chroma_key_color", color);
  274. }
  275. private void OnHSliderValueChanged(double value)
  276. {
  277. // Update the "pickup_range" shader parameter of the VideoStreamPlayer's material.
  278. _videoStreamPlayer.Material.Set("shader_parameter/pickup_range", value);
  279. }
  280. private void OnHSlider2ValueChanged(double value)
  281. {
  282. // Update the "fade_amount" shader parameter of the VideoStreamPlayer's material.
  283. _videoStreamPlayer.Material.Set("shader_parameter/fade_amount", value);
  284. }
  285. private void OnVideoStreamPlayerFinished()
  286. {
  287. // Restart the video playback when it's finished.
  288. _videoStreamPlayer.Play();
  289. }
  290. }
  291. also make sure that the range of the sliders are appropriate, our settings are :
  292. .. image:: img/slider_range.webp
  293. Signal Handling
  294. ~~~~~~~~~~~~~~~
  295. Connect the appropriate signal from the UI elements to the `Control` node's script.
  296. you created in the `Control` node's script to control the chroma key effect.
  297. These signal handlers will update the shader's uniform variables
  298. in response to user input.
  299. Save and run the scene to see the chroma key effect in action! With the provided UI controls,
  300. you can now adjust the chroma key color, pickup range, and fade amount in real-time, achieving the desired
  301. chroma key functionality for your video content.