Allow to programmatically make recordings of gameplay

The idea is to save a certain part of gameplay into a recording and then use that recording as a video inside widgets (Gameface: Video support) during the game (for example to replay moment how opponent shooted you) or save it for longer storage to later use in game page (see Allow creators to use videos besides supporting images ).

This will allow to “sort of” guarantee that game page shows actual gameplay (not video uploaded by creator) - there is no need to additionally moderate video. Possibly saving to long storage could be limited to recordings from editor/preview (though allowing to do it during actual game, could also enable interesting features, f.e. replay all important moments for your player in the last week or something like this).

I think unreal engine have something called sequencer, which could do this?

API could look like this:

self.recorder = GetWorld():StartRecorder()

--- ... later 

-- this is async in case if recoding takes time 
self.recorder:TakeLastSeconds(30, function(recording) 
    -- recording should correspond to last 30 (first parameter) 
    -- seconds before the moment of call to get snapshot

    -- could render video from different cameras.
    -- rendering probably would take some time, so this have to be async
    recording:RenderVideo(user:GetCamera(), function(video)
       local url = video.url
       -- could now send url to widget to replay it, should be available for gameface

    GetWorld():SaveRecording(recording) -- this saves recording in the limited storage per game 
    user:SaveRecording(recording)  -- could also save for per-user/per-game maybe?


-- another approach is to specifically set starting point
-- , but this might complicate certain applications, f.e. to show how opponent
-- shooted the player, since starting point is uknown until hit happens 
-- , however this approach more convenient for other cases, f.e. to make recording
-- for game page, when starting point and ending point are clear, but length is unknown beforehand
-- another use case for this to replay how player went through the race
local handle = self.recorder:StartRecording(function(recording)
  -- this should be called at the point when recording buffer is full and recorder produced first X seconds of interval
  -- `recording` should have same :RenderVideo and accepted in :SaveRecording

self.recorder:TakeRecording(handle, function(recording, isTruncated)
  -- this should be the last X seconds of recording in case if it was truncated because of buffer overflow
  -- isTruncated is set in case if buffer was overflown
  -- `recording` should have same :RenderVideo and accepted in :SaveRecording
-- approach with two callbacks allows creater to choose which of two recordings to use:
-- the first X seconds or last X seconds, where X might be dynamic and depend on size of buffer (and probably how many stuff in the game)

GetWorld():GetRecordings() -- self explanatory
user:GetRecordings() -- same, could use timestamp of recording for key in the table

for _, storedRecording in pairs(GetWorld():GetRecordings()) do 
  -- should be able to do same storedRecording:RenderVideo() as above
  -- should also be able to retrieve metadata, such as
  local users = storedRecording:GetUsers()
  local camera = storedRecording:GetCamera("camera1") -- pass here name of entity like for GetWorld():Find

  -- these two needed to be able to select from cameras available in recording, f.e:
  storedRecording:RenderVideo(camera, function(video) 
       local url = video.url
  for _, user in pairs(users) do 
    storedRecording:RenderVideo(user:GetCamera(), function(video) 
         local url = video.url
         -- could use this now to f.e show same event from several perspectives


-- one more feature could look like this:
self.recorder:StreamVideo(user:GetCamera(), function(video)
  local url = video.url
  -- this could be used to get unfinished (streaming video) to show 
  -- with <video> tag inside of widget.
  -- There could be different applications for this - show user a 'mirror' in racing games, 
  -- or to simulate surveillance system using in-world widget on top of screen mesh

At least per-game recordings saved through SaveRecording should also be available in editor to select for game page (in hub and other places possibly) and to clean them out if needed.