+ const videoUUID = videoLive.Video.uuid
+ const tsWatcher = chokidar.watch(outPath + '/*.ts')
+
+ const updateSegment = segmentPath => this.segmentsSha256Queue.push({ operation: 'update', segmentPath, videoUUID })
+
+ const addHandler = segmentPath => {
+ updateSegment(segmentPath)
+
+ if (this.isDurationConstraintValid(startStreamDateTime) !== true) {
+ this.stopSessionOf(videoLive.videoId)
+ }
+
+ if (videoLive.saveReplay === true) {
+ stat(segmentPath)
+ .then(segmentStat => {
+ currentUserLive.size += segmentStat.size
+ })
+ .then(() => this.isQuotaConstraintValid(user, videoLive))
+ .then(quotaValid => {
+ if (quotaValid !== true) {
+ this.stopSessionOf(videoLive.videoId)
+ }
+ })
+ .catch(err => logger.error('Cannot stat %s or check quota of %d.', segmentPath, user.id, { err }))
+ }
+ }
+
+ const deleteHandler = segmentPath => this.segmentsSha256Queue.push({ operation: 'delete', segmentPath, videoUUID })
+
+ tsWatcher.on('add', p => addHandler(p))
+ tsWatcher.on('change', p => updateSegment(p))
+ tsWatcher.on('unlink', p => deleteHandler(p))
+
+ const masterWatcher = chokidar.watch(outPath + '/master.m3u8')
+ masterWatcher.on('add', async () => {
+ try {
+ const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoLive.videoId)
+
+ video.state = VideoState.PUBLISHED
+ await video.save()
+ videoLive.Video = video
+
+ await federateVideoIfNeeded(video, false)
+
+ PeerTubeSocket.Instance.sendVideoLiveNewState(video)
+ } catch (err) {
+ logger.error('Cannot federate video %d.', videoLive.videoId, { err })
+ } finally {
+ masterWatcher.close()
+ .catch(err => logger.error('Cannot close master watcher of %s.', outPath, { err }))
+ }
+ })
+