This is a community contributed native extension, provided as-is. Community contributions to improve the extension are welcome. The Defold team will only provide limited support if bugs are encountered.
This extension captures video gameplay.
- Android 5.0 or later.
- iOS 11.0 or later.
- macOS x86_64.
- Linux x86_64.
- Windows x86_64.
- HTML5 (Chrome only).
macOS, Linux and Windows require OpenGL 3.0 or better video card.
- Android and iOS
- Encoder: H.264 codec in the MP4 container.
- Muxer: accepts MP4 video and AAC audio.
- macOS, Linux, Windows, HTML5
- Encoder: VP8 codec in the WEBM container.
- Muxer: accepts WEBM video and WEBM audio (Vorbis).
One of the key features of this extension is the ability to save just last N seconds of the gameplay. The extension maintains a circular buffer for encoded data and saves it when requested. On Android, macOS, Linux, Windows and HTML5 the circular encoder stores it's data in memory, on iOS the circular encoder saves to temporary video files and then joins them together to produce desired duration. The circular encoder is activated with the duration
parameter.
Audio capture is not implemented, however the extension provides a function to mux a prepared audio file with the captured video.
On iOS the extension uses Apple's ReplayKit API and captures the entire game screen. Additionally it can show a native preview window, where the user can edit the captured video and share it. To enable the preview window, specify enable_preview = true
parameter.
On other platforms the capture pipeline requires using a render target. First you render the content you wish to capture into a render target, then the extension passes the texture to the encoder. This way you can first render to a render target and then use it's texture for encoding and for displaying on the screen with a quad model like in the postprocessing tutorial.
It's important to take into account scaling of the captured texture and the render target. Very often screen size, render target size and video frame size don't match. To control aspect ratio and black borders around video frame you can specify x_scale
and y_scale
parameters. Except on iOS, on that platform you provide a predefined scaling algorithm using scale
parameter.
On desktop platforms if windows size is smaller than video frame size, it's important to upscale when rendering to a texture to fill the render target, otherwise a blank space will be visible on the video.
On Android the extension uses the MediaCodec API and the encoder accepts an EGL surface as an input. The extension internally renders to this surface without accessing pixel data directly.
On desktop platforms the extension internally renders to it's own OpenGL Frame Buffer Object and converts RGB image to YUV image, then passing this data to the VPX encoder.
In game.project
file add dependency https://github.com/defold/extension-screenrecorder/archive/master.zip
.
Copy screenrecorder.appmanifest
into your project and choose it in your game.project
under native_extension -> App Manifest
. This file disables Defold's internal record
library.
In render script prepare a render target, the size of the render target should be not smaller than desired video frame size. On mobiles the size also has to be one of the power of two numbers (e.g. 512, 1024, 2048). To compensate the extra space around the image on Android you have to render to the center of the render target and upscale with x_scale
and y_scale
.
Put screenrecorder.capture_frame()
somewhere in your render script's update()
method.
Before starting the capture the extension has to be initialized with screenrecorder.init(params)
function. And it has to be initialized each time after a recording is finished with screenrecorder.stop()
.
When the setup is done, just start the capture with screenrecorder.start()
.
To work with filenames on different platforms the directories extension is recommended. It can also download vide file from the browser to the computer.
Prepares the capture, sets up the encoder. Once setup is complete, an 'init'
event will be dispatched to the listener
function. All other events will also be directed to this function.
params
- table with parameters.
- iOS parameters:
enable_preview
-boolean
, iftrue
, enables showing a preview and edit window after a completed recording, default isfalse
. Incompatible withmux_audio_video()
method,duration
and other video params. iOS takes full control over the video.scaling
-constant
, scaling mode determines how frame is placed into specified width/height region. Default isscreenrecorder.SCALING_RESIZE_ASPECT
. Possible values:screenrecorder.SCALING_RESIZE
- crop to remove edge processing region; scale remainder to destination area. Does not preserve aspect ratio.screenrecorder.SCALING_RESIZE_ASPECT
- preserve aspect ratio of the source, and fill remaining areas with black to fit destination dimensions.screenrecorder.SCALING_RESIZE_ASPECT_FILL
- preserve aspect ratio of the source, and crop picture to fit destination dimensions.
- Desktop parameters:
async_encoding
-boolean
, experimental - iftrue
use a separate encoding thread. Might improve performance, might make it worse. Default isfalse
.
- Common parameters:
render_target
-render_target
, specifies a render target to work with, the extension uses it's internal texture to pass data into encoder. What is rendered into this target gets into the video file. Required on all platforms, except iOS.x_scale
-number
, horizontal scale of the render target's texture. Use it withy_scale
to maintain desired aspect ratio and frame fill. Default is1.0
.y_scale
-number
, vertical scale of the render target's texture. Default is1.0
.filename
-string
, path to the output video file. Required.width
-number
, width of the video frame. Default is1280
.height
-number
, height of the video frame. Default is720
.iframe
-number
, video keyframe interval in seconds. Default is1.0
.duration
-number
, if set, use circular encoder to record last N seconds. Default isnil
.fps
-number
, video framerate, Default is30
. On iOS fps is chosen by the OS and this setting has no effect.bitrate
-number
, video bitrate in bits per second. Default is2 * 1024 * 1024
.listener
-function
, this function receives various events from the extension. See Events section.
Parameters that are not available on iOS: render_target
, x_scale
, y_scale
, fps
.
Starts the capture process. The extension has to be initialized before calling this function. Once the recording is started, you can supply frames to encode with the screenrecorder.capture_frame()
function. If the encoder failed to start, an error event is dispatched.
Stops the capture process, finishes writing encoded data into the video file and closes it. Releases internal resorces and deinitializes the extension. screenrecorder.init()
has to be called again after stopping the recording. If an error occured during finalization, an error event is dispatched.
Captures the current frame and submits it to the encoder. Has no effect on iOS due to differnt capture approach. You must match the capture framerate and calls of this function, e.g. if your game is 60 fps and the recording is at 60 fps, then you call this function every frame. But if your recording is at 30 fps, you have to skip every other frame.
Returns true
if the extension is currently recording. false
otherwise.
Muxes one audio file and one video file into one combined file. The duration of the output file is matched to the video file. On desktop platforms this function accepts WEBM files, on mobiles - MP4 and AAC files. Once muxing is done, a 'muxed'
event is dispatched.
params
- table with parameters.
audio_filename
- string, path to the audio file. Required.video_filename
- string, path to the video file. Required.filename
- string, path to the output file. Required.
Returns true
if the extension has captured video with enabled preview on iOS and this preview is ready to show up. false
otherwise.
Shows a special window on iOS that lets the user to edit and share the recorded video.
The listener
function receives an event
table with information about succesful and failed operations.
event
table.
name
-string
,'screenrecorder'
. The name of the event.phase
-string
, the phase of the extension, corresponds to various calls. Phases:'init'
- initialization phase.'recorded'
- saving the recording phase.'muxed'
- muxing audio and video phase.
is_error
-boolean
, indicates if an error has occured.error_message
-string
, ifis_error
istrue
holds details about the error.
- Android
- iOS
- macOS, Linux, Windows, HTML5
Original extension code developed by @Lerg, with modifications by the Defold team.