+async function saveReplayToExternalVideo (options: {
+ liveVideo: MVideo
+ liveSession: MVideoLiveSession
+ publishedAt: string
+ replayDirectory: string
+}) {
+ const { liveVideo, liveSession, publishedAt, replayDirectory } = options
+
+ const video = new VideoModel({
+ name: `${liveVideo.name} - ${new Date(publishedAt).toLocaleString()}`,
+ isLive: false,
+ state: VideoState.TO_TRANSCODE,
+ duration: 0,
+
+ remote: liveVideo.remote,
+ category: liveVideo.category,
+ licence: liveVideo.licence,
+ language: liveVideo.language,
+ commentsEnabled: liveVideo.commentsEnabled,
+ downloadEnabled: liveVideo.downloadEnabled,
+ waitTranscoding: true,
+ nsfw: liveVideo.nsfw,
+ description: liveVideo.description,
+ support: liveVideo.support,
+ privacy: liveVideo.privacy,
+ channelId: liveVideo.channelId
+ }) as MVideoWithAllFiles
+
+ video.Thumbnails = []
+ video.VideoFiles = []
+ video.VideoStreamingPlaylists = []
+
+ video.url = getLocalVideoActivityPubUrl(video)
+
+ await video.save()
+
+ liveSession.replayVideoId = video.id
+ await liveSession.save()
+
+ // If live is blacklisted, also blacklist the replay
+ const blacklist = await VideoBlacklistModel.loadByVideoId(liveVideo.id)
+ if (blacklist) {
+ await VideoBlacklistModel.create({
+ videoId: video.id,
+ unfederated: blacklist.unfederated,
+ reason: blacklist.reason,
+ type: blacklist.type
+ })
+ }
+
+ await assignReplayFilesToVideo({ video, replayDirectory })
+
+ await remove(replayDirectory)
+
+ for (const type of [ ThumbnailType.MINIATURE, ThumbnailType.PREVIEW ]) {
+ const image = await generateVideoMiniature({ video, videoFile: video.getMaxQualityFile(), type })
+ await video.addAndSaveThumbnail(image)
+ }