From f25752cd3b83f1dc151d95c0710003a19f7189b5 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 18 Jul 2022 23:50:38 +0200 Subject: [PATCH] Add a page on playing videos using VideoPlayer This includes documentation on supported formats, along with setting up a VideoPlayer node for 2D and 3D usage. This also features encoding recommendations to find a balance between quality and file size (as the defaults in many programs are less than ideal). --- .../playing_videos_aspect_ratio_container.png | Bin 0 -> 4830 bytes tutorials/animation/index.rst | 1 + tutorials/animation/playing_videos.rst | 234 ++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 tutorials/animation/img/playing_videos_aspect_ratio_container.png create mode 100644 tutorials/animation/playing_videos.rst diff --git a/tutorials/animation/img/playing_videos_aspect_ratio_container.png b/tutorials/animation/img/playing_videos_aspect_ratio_container.png new file mode 100644 index 0000000000000000000000000000000000000000..bc9dd2de3233ec129ec39de673c2fc620b775927 GIT binary patch literal 4830 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 Ef~~iOTmS$7 literal 0 HcmV?d00001 diff --git a/tutorials/animation/index.rst b/tutorials/animation/index.rst index c61d7373f..2cfabcfff 100644 --- a/tutorials/animation/index.rst +++ b/tutorials/animation/index.rst @@ -9,3 +9,4 @@ Animation cutout_animation 2d_skeletons animation_tree + playing_videos diff --git a/tutorials/animation/playing_videos.rst b/tutorials/animation/playing_videos.rst new file mode 100644 index 000000000..9d2b6ca47 --- /dev/null +++ b/tutorials/animation/playing_videos.rst @@ -0,0 +1,234 @@ +.. _doc_playing_videos: + +Playing videos +============== + +Godot supports video playback with the :ref:`class_VideoPlayer` node. + +Supported playback formats +-------------------------- + +The only supported format in core is **Ogg Theora** (not to be confused with Ogg +Vorbis audio). It's possible for extensions to bring support for additional +formats, but no such extensions exist yet as of July 2022. + +H.264 and H.265 cannot be supported in core Godot, as they are both encumbered +by software patents. AV1 is royalty-free, but it remains slow to decode on the +CPU and hardware decoding support isn't readily available on all GPUs in use +yet. + +WebM is supported in core in Godot 3.x, but support for it will be removed in 4.0 +as it proved to be too buggy and difficult to maintain. +Therefore, **using WebM is not recommended**. + +.. note:: + + You may find videos with an ``.ogg`` or ``.ogx`` extensions, which are generic + extensions for data within an Ogg container. + + Renaming these file extensions to ``.ogv`` *may* allow the videos to be + imported in Godot. However, not all files with ``.ogg`` or ``.ogx`` + extensions are videos - some of them may only contain audio. + +Setting up VideoPlayer +---------------------------- + +1. Create a VideoPlayer node using the Create New Node dialog. +2. Select the VideoPlayer node in the scene tree dock, go to the inspector + and load an ``.ogv`` file in the Stream property. + + - If you don't have your video in Ogg Theora format yet, jump to + :ref:`doc_playing_videos_recommended_theora_encoding_settings`. + +3. If you want the video to play as soon as the scene is loaded, check + **Autoplay** in the inspector. If not, leave **Autoplay** disabled and call + ``play()`` on the VideoPlayer node in a script to start playback when + desired. + +Handling resizing and different aspect ratios +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default in Godot 4.0, the VideoPlayer will automatically be resized to match +the video's resolution. You can make it follow usual :ref:`class_Control` sizing +by enabling **Expand** on the VideoPlayer node. + +To adjust how the VideoPlayer node resizes depending on window size, +adjust the anchors using the **Layout** menu at the top of the 2D editor +viewport. However, this setup may not be powerful enough to handle all use +cases, such as playing fullscreen videos without distorting the video (but with +empty space on the edges instead). For more control, you can use an +:ref:`class_AspectRatioContainer` node, which is designed to handle this kind of +use case: + +Add an AspectRatioContainer node. Make sure it is not a child of any other +container node. Select the AspectRatioContainer node, then set its **Layout** at +the top of the 2D editor to **Full Rect**. Set **Ratio** in the +AspectRatioContainer node to match your video's aspect ratio. You can use math +formulas in the inspector to help yourself. Remember to make one of the operands +a float. Otherwise, the division's result will always be an integer. + +.. figure:: img/playing_videos_aspect_ratio_container.png + :figclass: figure-w480 + :align: center + :alt: AspectRatioContainer's Ratio property being modified in the editor inspector + + This will evaluate to (approximately) 1.777778 + +Once you've configured the AspectRatioContainer, reparent your VideoPlayer +node to be a child of the AspectRatioContainer node. Make sure **Expand** is +disabled on the VideoPlayer. Your video should now scale automatically +to fit the whole screen while avoiding distortion. + +.. seealso:: + + See :ref:`doc_multiple_resolutions` for more tips on supporting multiple + aspect ratios in your project. + +Displaying a video on a 3D surface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Using a VideoPlayer node as a child of a :ref:`class_Viewport` node, +it's possible to display any 2D node on a 3D surface. For example, this can be +used to display animated billboards when frame-by-frame animation would require +too much memory. + +This can be done with the following steps: + +1. Create a :ref:`class_Viewport` node. Set its size to match your video's size + in pixels. +2. Create a VideoPlayer node *as a child of the Viewport node* and specify + a video path in it. Make sure **Expand** is disabled, and enable **Autoplay** if needed. +3. Create a MeshInstance node with a PlaneMesh or QuadMesh resource in its Mesh property. + Resize the mesh to match the video's aspect ratio (otherwise, it will appear distorted). +4. Create a new SpatialMaterial resource in the **Material Override** property + in the GeometryInstance section. +5. Enable **Local To Scene** in the SpatialMaterial's Resource section (at the bottom). + This is *required* before you can use a ViewportTexture in its Albedo Texture property. +6. In the SpatialMaterial, set the **Albedo > Texture** property to **New ViewportTexture**. + Edit the new resource by clicking it, then specify the path to the Viewport node + in the **Viewport Path** property. +7. Enable **Albedo Tex Force sRGB** in the SpatialMaterial to prevent colors + from being washed out. +8. If the billboard is supposed to emit its own light, enable + **Flags > Unshaded** to improve rendering performance. + +See :ref:`doc_viewports` and the +`GUI in 3D demo `__ +for more information on setting this up. + +Video decoding conditions and recommended resolutions +----------------------------------------------------- + +Video decoding is performed on the CPU, as GPUs don't have hardware acceleration +for decoding Theora videos. Modern desktop CPUs can decode Ogg Theora videos at +1440p @ 60 FPS or more, but low-end mobile CPUs will likely struggle with +high-resolution videos. + +To ensure your videos decode smoothly on varied hardware: + +- When developing games for desktop platforms, it's recommended to encode in + 1080p at most (preferably at 30 FPS). Most people are still using 1080p or + lower resolution displays, so encoding higher-resolution videos may not be + worth the increased file size and CPU requirements. +- When developing games for mobile or web platforms, it's recommended to encode + in 720p at most (preferably at 30 FPS or even lower). The visual difference + between 720p and 1080p videos on a mobile device is usually not that + noticeable. + +Playback limitations +-------------------- + +There are several limitations with the current implementation of video playback in Godot: + +- Seeking a video to a certain point is not supported. +- Changing playback speed is not supported. VideoPlayer also won't follow + :ref:`Engine.time_scale`. +- Looping is not supported, but you can connect a VideoPlayer's + :ref:`finished ` signal to a function + that plays the video again. However, this will cause a black frame to be + visible when the video restarts. This can be worked around by adding a fade to + black in the video file before the video ends, or by hiding the video for one + frame and displaying a TextureRect with a screenshot of the first frame of the + video until the video is restarted. +- Streaming a video from a URL is not supported. + +.. _doc_playing_videos_recommended_theora_encoding_settings: + +Recommended Theora encoding settings +------------------------------------ + +A word of advice is to **avoid relying on built-in Ogg Theora exporters** (most of the time). +There are 2 reasons you may want to favor using an external program to encode your video: + +- Some programs such as Blender can render to Ogg Theora. However, the default + quality presets are usually very low by today's standards. You may be able to + increase the quality options in the software you're using, but you may find + the output quality to remain less than ideal (given the increased file size). + This usually means that the software only supports encoding to constant bit + rate (CBR), instead of variable bit rate (VBR). VBR encoding should be + preferred in most scenarios as it provides a better quality to file size + ratio. +- Some other programs can't render to Ogg Theora at all. + +In this case, you can **render the video to an intermediate high-quality format** +(such as a high-bitrate H.264 video) then re-encode it to Ogg Theora. Ideally, +you should use a lossless or uncompressed format as an intermediate format to +maximize the quality of the output Ogg Theora video, but this can require a lot +of disk space. + +`HandBrake `__ +(GUI) and `FFmpeg `__ (CLI) are popular open source tools +for this purpose. FFmpeg has a steeper learning curve, but it's more powerful. + +Here are example FFmpeg commands to convert a MP4 video to Ogg Theora. Since +FFmpeg supports a lot of input formats, you should be able to use the commands +below with almost any input video format (AVI, MOV, WebM, …). + +.. note:: + + Make sure your copy of FFmpeg is compiled with libtheora and libvorbis support. + You can check this by running ``ffmpeg`` without any arguments, then looking + at the ``configuration:`` line in the command output. + +Balancing quality and file size +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The **video quality** level (``-q:v``) must be between ``1`` and ``10``. Quality +``6`` is a good compromise between quality and file size. If encoding at a high +resolution (such as 1440p or 4K), you will probably want to decrease ``-q:v`` to +``5`` to keep file sizes reasonable. Since pixel density is higher on a 1440p or +4K video, lower quality presets at higher resolutions will look as good or +better compared to low-resolution videos. + +The **audio quality** level (``-q:a``) must be between ``-1`` and ``10``. Quality +``6`` provides a good compromise between quality and file size. In contrast to +video quality, increasing audio quality doesn't increase the output file size +nearly as much. Therefore, if you want the cleanest audio possible, you can +increase this to ``9`` to get *perceptually lossless* audio. This is especially +valuable if your input file already uses lossy audio compression. See +`this page `__ +for a table listing Ogg Vorbis audio quality presets and their respective +variable bitrates. + +FFmpeg: Convert while preserving original video resolution +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following command converts the video while keeping its original resolution. +The video and audio's bitrate will be variable to maximize quality while saving +space in parts of the video/audio that don't require a high bitrate (such as +static scenes). + +:: + + ffmpeg -i input.mp4 -q:v 6 -q:a 6 output.ogv + +FFmpeg: Resize the video then convert it +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following command resizes a video to be 720 pixels tall (720p), while +preserving its existing aspect ratio. This helps decrease the file size +significantly if the source is recorded at a higher resolution than 720p: + +:: + + ffmpeg -i input.mp4 -f:v "scale=-1:720" -q:v 6 -q:a 6 output.ogv