Making videos for the web with Godot 4’s Movie Writer
Normally I use OBS for screen recording, but there are cases where it makes sense to use Godot’s built-in movie writer that was recently announced.
For example, if you have a slow PC or really demanding game, OBS will skip frames. It makes sense since OBS is just recording what’s on the screen in real time, while Godot has to do most of the work running the game. Recording with Godot directly will slow down the action at recording time, and you cannot hear any audio while that happens. But the video playback will end up being buttery smooth at 60 fps and include audio. It will also result in huge files. 321MB for 8 seconds, at 1280x800px (also Steam Deck’s native 16:10 resolution). Still, that’s not a video file I want to embed into any webpage or wherever as-is.
The best tool for converting video from the command line or programmatically is still ffmpeg. I’m running this on Windows in WSL2, on Ubuntu 22.04.
The best option for .webm seems to be the VP9 codec. Their docs provide some examples. I’ve tested a few parameters. For two-pass targeting an average bitrate, the target bitrate is specified with the -b:v switch:
# will take longer but smaller fileffmpeg-itilemap.avi-c:vlibvpx-vp9-b:v2M-pass1-an-fnull/dev/null&&\ffmpeg-itilemap.avi-c:vlibvpx-vp9-b:v2M-pass2-c:alibopustilemap-average.webm
This is what the output looks like:
gray@Battlestation:/mnt/c/Users/gray/godot/arpg$ffmpeg-itilemap.avi-c:vlibvpx-vp9-b:v2M-pass1-an-fnull/dev/null&&\ffmpeg-itilemap.avi-c:vlibvpx-vp9-b:v2M-pass2-c:alibopustilemap-average.webmffmpegversion4.4.2-0ubuntu0.22.04.1Copyright (c) 2000-2021 the FFmpeg developersbuiltwithgcc11 (Ubuntu 11.2.0-19ubuntu1)configuration:--prefix=/usr--extra-version=0ubuntu0.22.04.1--toolchain=hardened--libdir=/usr/lib/x86_64-linux-gnu--incdir=/usr/include/x86_64-linux-gnu--arch=amd64--enable-gpl--disable-stripping--enable-gnutls--enable-ladspa--enable-libaom--enable-libass--enable-libbluray--enable-libbs2b--enable-libcaca--enable-libcdio--enable-libcodec2--enable-libdav1d--enable-libflite--enable-libfontconfig--enable-libfreetype--enable-libfribidi--enable-libgme--enable-libgsm--enable-libjack--enable-libmp3lame--enable-libmysofa--enable-libopenjpeg--enable-libopenmpt--enable-libopus--enable-libpulse--enable-librabbitmq--enable-librubberband--enable-libshine--enable-libsnappy--enable-libsoxr--enable-libspeex--enable-libsrt--enable-libssh--enable-libtheora--enable-libtwolame--enable-libvidstab--enable-libvorbis--enable-libvpx--enable-libwebp--enable-libx265--enable-libxml2--enable-libxvid--enable-libzimg--enable-libzmq--enable-libzvbi--enable-lv2--enable-omx--enable-openal--enable-opencl--enable-opengl--enable-sdl2--enable-pocketsphinx--enable-librsvg--enable-libmfx--enable-libdc1394--enable-libdrm--enable-libiec61883--enable-chromaprint--enable-frei0r--enable-libx264--enable-sharedWARNING:libraryconfigurationmismatchavcodecconfiguration:--prefix=/usr--extra-version=0ubuntu0.22.04.1--toolchain=hardened--libdir=/usr/lib/x86_64-linux-gnu--incdir=/usr/include/x86_64-linux-gnu--arch=amd64--enable-gpl--disable-stripping--enable-gnutls--enable-ladspa--enable-libaom--enable-libass--enable-libbluray--enable-libbs2b--enable-libcaca--enable-libcdio--enable-libcodec2--enable-libdav1d--enable-libflite--enable-libfontconfig--enable-libfreetype--enable-libfribidi--enable-libgme--enable-libgsm--enable-libjack--enable-libmp3lame--enable-libmysofa--enable-libopenjpeg--enable-libopenmpt--enable-libopus--enable-libpulse--enable-librabbitmq--enable-librubberband--enable-libshine--enable-libsnappy--enable-libsoxr--enable-libspeex--enable-libsrt--enable-libssh--enable-libtheora--enable-libtwolame--enable-libvidstab--enable-libvorbis--enable-libvpx--enable-libwebp--enable-libx265--enable-libxml2--enable-libxvid--enable-libzimg--enable-libzmq--enable-libzvbi--enable-lv2--enable-omx--enable-openal--enable-opencl--enable-opengl--enable-sdl2--enable-pocketsphinx--enable-librsvg--enable-libmfx--enable-libdc1394--enable-libdrm--enable-libiec61883--enable-chromaprint--enable-frei0r--enable-libx264--enable-shared--enable-version3--disable-doc--disable-programs--enable-libaribb24--enable-libopencore_amrnb--enable-libopencore_amrwb--enable-libtesseract--enable-libvo_amrwbenc--enable-libsmbclientlibavutil56.70.100/56.70.100libavcodec58.134.100/58.134.100libavformat58.76.100/58.76.100libavdevice58.13.100/58.13.100libavfilter7.110.100/7.110.100libswscale5.9.100/5.9.100libswresample3.9.100/3.9.100libpostproc55.9.100/55.9.100GuessedChannelLayoutforInputStream#0.1 : stereoInput#0, avi, from 'tilemap.avi':Duration:N/A,start:0.000000,bitrate:N/AStream#0:0: Video: mjpeg (Baseline) (MJPG / 0x47504A4D), yuvj420p(pc, bt470bg/unknown/unknown), 1280x800 [SAR 1:1 DAR 8:5], 60 fps, 60 tbr, 60 tbn, 60 tbcStream#0:1: Audio: pcm_s32le ([1][0][0][0] / 0x0001), 48000 Hz, stereo, s32, 3072 kb/sStreammapping:Stream#0:0 -> #0:0 (mjpeg (native) -> vp9 (libvpx-vp9))Press [q] to stop, [?]for help[swscaler @ 0x55932cefff40] deprecated pixel format used, make sure you did set range correctly[libvpx-vp9 @ 0x55932cee54c0] v1.11.0Output#0, null, to '/dev/null':Metadata:encoder:Lavf58.76.100Stream#0:0: Video: vp9, yuv420p(tv, bt470bg/unknown/unknown, progressive), 1280x800 [SAR 1:1 DAR 8:5], q=2-31, 2000 kb/s, 60 fps, 60 tbnMetadata:encoder:Lavc58.134.100libvpx-vp9Sidedata:cpb:bitratemax/min/avg:0/0/2000000buffersize:0vbv_delay:N/Aframe=533fps=35q=0.0Lsize=N/Atime=00:00:00.00bitrate=N/Aspeed=0xvideo:0kBaudio:0kBsubtitle:0kBotherstreams:0kBglobalheaders:0kBmuxingoverhead:unknownOutputfileisempty,nothingwasencodedffmpegversion4.4.2-0ubuntu0.22.04.1Copyright (c) 2000-2021 the FFmpeg developersbuiltwithgcc11 (Ubuntu 11.2.0-19ubuntu1)configuration:--prefix=/usr--extra-version=0ubuntu0.22.04.1--toolchain=hardened--libdir=/usr/lib/x86_64-linux-gnu--incdir=/usr/include/x86_64-linux-gnu--arch=amd64--enable-gpl--disable-stripping--enable-gnutls--enable-ladspa--enable-libaom--enable-libass--enable-libbluray--enable-libbs2b--enable-libcaca--enable-libcdio--enable-libcodec2--enable-libdav1d--enable-libflite--enable-libfontconfig--enable-libfreetype--enable-libfribidi--enable-libgme--enable-libgsm--enable-libjack--enable-libmp3lame--enable-libmysofa--enable-libopenjpeg--enable-libopenmpt--enable-libopus--enable-libpulse--enable-librabbitmq--enable-librubberband--enable-libshine--enable-libsnappy--enable-libsoxr--enable-libspeex--enable-libsrt--enable-libssh--enable-libtheora--enable-libtwolame--enable-libvidstab--enable-libvorbis--enable-libvpx--enable-libwebp--enable-libx265--enable-libxml2--enable-libxvid--enable-libzimg--enable-libzmq--enable-libzvbi--enable-lv2--enable-omx--enable-openal--enable-opencl--enable-opengl--enable-sdl2--enable-pocketsphinx--enable-librsvg--enable-libmfx--enable-libdc1394--enable-libdrm--enable-libiec61883--enable-chromaprint--enable-frei0r--enable-libx264--enable-sharedWARNING:libraryconfigurationmismatchavcodecconfiguration:--prefix=/usr--extra-version=0ubuntu0.22.04.1--toolchain=hardened--libdir=/usr/lib/x86_64-linux-gnu--incdir=/usr/include/x86_64-linux-gnu--arch=amd64--enable-gpl--disable-stripping--enable-gnutls--enable-ladspa--enable-libaom--enable-libass--enable-libbluray--enable-libbs2b--enable-libcaca--enable-libcdio--enable-libcodec2--enable-libdav1d--enable-libflite--enable-libfontconfig--enable-libfreetype--enable-libfribidi--enable-libgme--enable-libgsm--enable-libjack--enable-libmp3lame--enable-libmysofa--enable-libopenjpeg--enable-libopenmpt--enable-libopus--enable-libpulse--enable-librabbitmq--enable-librubberband--enable-libshine--enable-libsnappy--enable-libsoxr--enable-libspeex--enable-libsrt--enable-libssh--enable-libtheora--enable-libtwolame--enable-libvidstab--enable-libvorbis--enable-libvpx--enable-libwebp--enable-libx265--enable-libxml2--enable-libxvid--enable-libzimg--enable-libzmq--enable-libzvbi--enable-lv2--enable-omx--enable-openal--enable-opencl--enable-opengl--enable-sdl2--enable-pocketsphinx--enable-librsvg--enable-libmfx--enable-libdc1394--enable-libdrm--enable-libiec61883--enable-chromaprint--enable-frei0r--enable-libx264--enable-shared--enable-version3--disable-doc--disable-programs--enable-libaribb24--enable-libopencore_amrnb--enable-libopencore_amrwb--enable-libtesseract--enable-libvo_amrwbenc--enable-libsmbclientlibavutil56.70.100/56.70.100libavcodec58.134.100/58.134.100libavformat58.76.100/58.76.100libavdevice58.13.100/58.13.100libavfilter7.110.100/7.110.100libswscale5.9.100/5.9.100libswresample3.9.100/3.9.100libpostproc55.9.100/55.9.100GuessedChannelLayoutforInputStream#0.1 : stereoInput#0, avi, from 'tilemap.avi':Duration:N/A,start:0.000000,bitrate:N/AStream#0:0: Video: mjpeg (Baseline) (MJPG / 0x47504A4D), yuvj420p(pc, bt470bg/unknown/unknown), 1280x800 [SAR 1:1 DAR 8:5], 60 fps, 60 tbr, 60 tbn, 60 tbcStream#0:1: Audio: pcm_s32le ([1][0][0][0] / 0x0001), 48000 Hz, stereo, s32, 3072 kb/sStreammapping:Stream#0:0 -> #0:0 (mjpeg (native) -> vp9 (libvpx-vp9))Stream#0:1 -> #0:1 (pcm_s32le (native) -> opus (libopus))Press [q] to stop, [?]for help[swscaler @ 0x562739e33040] deprecated pixel format used, make sure you did set range correctly[libvpx-vp9 @ 0x562739e14040] v1.11.0[libopus @ 0x562739e165c0] No bit rate set. Defaulting to 96000 bps.Output#0, webm, to 'tilemap-average.webm':Metadata:encoder:Lavf58.76.100Stream#0:0: Video: vp9, yuv420p(tv, bt470bg/unknown/unknown, progressive), 1280x800 [SAR 1:1 DAR 8:5], q=2-31, 2000 kb/s, 60 fps, 1k tbnMetadata:encoder:Lavc58.134.100libvpx-vp9Sidedata:cpb:bitratemax/min/avg:0/0/2000000buffersize:0vbv_delay:N/AStream#0:1: Audio: opus, 48000 Hz, stereo, flt, 96 kb/sMetadata:encoder:Lavc58.134.100libopusframe=533fps=3.2q=0.0Lsize=2600kBtime=00:00:08.86bitrate=2401.8kbits/sspeed=0.054xvideo:2479kBaudio:114kBsubtitle:0kBotherstreams:0kBglobalheaders:0kBmuxingoverhead:0.289294%
And on this ancient i7-4790K, it runs dog slow. It processed the 8.86-second-long video at 5% speed, dragging it out to almost three minutes. But the payoff is worth it. Instead of 321MB, the video file is down to 2.6MB:
Once I found out about the Steam Deck’s Desktop Mode, it got even more interesting. Steam Deck’s Gaming Mode vs Desktop Mode You see, the Steam Deck defaults to an analog of Big Picture mode on PC. It runs full screen in “Steam Deck gaming console” mode. But underneath all that is a Linux system …
It’s not Far Cry, nor Crysis, but it could be. The Realistic Jungle Demo demonstrates that Godot is capable of impressive visuals. If you want to run it yourself, download it from https://wrobot.itch.io/jungledemo. It was announced in this Reddit post. Update: The source code was released (with the commercial assets removed).
It’s been a while, but it was worth the wait. The latest version of the Inventory System is now available, with a long list of features, improvements, fixes, and documentation. This time the focus is on multiplayer. Let’s cover the features first: Bug fixes:
This release improves weight management. Inventories can now configure an option weight limit, and item stacking and item transfer strategies are weight-aware. The crafting demo and crafting mechanic in the inventory tour have been improved. Auto-crafting is limited to the crafting slide, so that items don’t automatically and unexpectedly get crafted while stepping through the …
Making videos for the web with Godot 4’s Movie Writer
Normally I use OBS for screen recording, but there are cases where it makes sense to use Godot’s built-in movie writer that was recently announced.
For example, if you have a slow PC or really demanding game, OBS will skip frames. It makes sense since OBS is just recording what’s on the screen in real time, while Godot has to do most of the work running the game. Recording with Godot directly will slow down the action at recording time, and you cannot hear any audio while that happens. But the video playback will end up being buttery smooth at 60 fps and include audio. It will also result in huge files. 321MB for 8 seconds, at 1280x800px (also Steam Deck’s native 16:10 resolution). Still, that’s not a video file I want to embed into any webpage or wherever as-is.
The best tool for converting video from the command line or programmatically is still ffmpeg. I’m running this on Windows in WSL2, on Ubuntu 22.04.
The best option for .webm seems to be the VP9 codec. Their docs provide some examples. I’ve tested a few parameters. For two-pass targeting an average bitrate, the target bitrate is specified with the -b:v switch:
This is what the output looks like:
And on this ancient i7-4790K, it runs dog slow. It processed the 8.86-second-long video at 5% speed, dragging it out to almost three minutes. But the payoff is worth it. Instead of 321MB, the video file is down to 2.6MB:
Related Posts
Godot Engine on the Steam Deck – Developing games on the go?
Once I found out about the Steam Deck’s Desktop Mode, it got even more interesting. Steam Deck’s Gaming Mode vs Desktop Mode You see, the Steam Deck defaults to an analog of Big Picture mode on PC. It runs full screen in “Steam Deck gaming console” mode. But underneath all that is a Linux system …
The Godot Jungle Demo
It’s not Far Cry, nor Crysis, but it could be. The Realistic Jungle Demo demonstrates that Godot is capable of impressive visuals. If you want to run it yourself, download it from https://wrobot.itch.io/jungledemo. It was announced in this Reddit post. Update: The source code was released (with the commercial assets removed).
Inventory System v1.13 available
It’s been a while, but it was worth the wait. The latest version of the Inventory System is now available, with a long list of features, improvements, fixes, and documentation. This time the focus is on multiplayer. Let’s cover the features first: Bug fixes:
Inventory System 2 Alpha 3 available
This release improves weight management. Inventories can now configure an option weight limit, and item stacking and item transfer strategies are weight-aware. The crafting demo and crafting mechanic in the inventory tour have been improved. Auto-crafting is limited to the crafting slide, so that items don’t automatically and unexpectedly get crafted while stepping through the …