import { close, ensureDir, move, open, outputJSON, read, readFile, remove, stat, writeFile } from 'fs-extra'
-import { flatten, uniq } from 'lodash'
+import { flatten } from 'lodash'
import PQueue from 'p-queue'
import { basename, dirname, join } from 'path'
import { MStreamingPlaylist, MStreamingPlaylistFilesVideo, MVideo } from '@server/types/models'
+import { uniqify } from '@shared/core-utils'
import { sha256 } from '@shared/extra-utils'
import { VideoStorage } from '@shared/models'
import { getAudioStreamCodec, getVideoStreamCodec, getVideoStreamDimensionsInfo } from '../helpers/ffmpeg'
import { sequelizeTypescript } from '../initializers/database'
import { VideoFileModel } from '../models/video/video-file'
import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist'
-import { storeHLSFile } from './object-storage'
+import { storeHLSFileFromFilename } from './object-storage'
import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename, getHlsResolutionPlaylistFilename } from './paths'
import { VideoPathManager } from './video-path-manager'
}
async function updatePlaylistAfterFileChange (video: MVideo, playlist: MStreamingPlaylist) {
- let playlistWithFiles = await updateMasterHLSPlaylist(video, playlist)
- playlistWithFiles = await updateSha256VODSegments(video, playlist)
-
- // Refresh playlist, operations can take some time
- playlistWithFiles = await VideoStreamingPlaylistModel.loadWithVideoAndFiles(playlist.id)
- playlistWithFiles.assignP2PMediaLoaderInfoHashes(video, playlistWithFiles.VideoFiles)
- await playlistWithFiles.save()
-
- video.setHLSPlaylist(playlistWithFiles)
+ try {
+ let playlistWithFiles = await updateMasterHLSPlaylist(video, playlist)
+ playlistWithFiles = await updateSha256VODSegments(video, playlist)
+
+ // Refresh playlist, operations can take some time
+ playlistWithFiles = await VideoStreamingPlaylistModel.loadWithVideoAndFiles(playlist.id)
+ playlistWithFiles.assignP2PMediaLoaderInfoHashes(video, playlistWithFiles.VideoFiles)
+ await playlistWithFiles.save()
+
+ video.setHLSPlaylist(playlistWithFiles)
+ } catch (err) {
+ logger.info('Cannot update playlist after file change. Maybe due to concurrent transcoding', { err })
+ }
}
// ---------------------------------------------------------------------------
await writeFile(masterPlaylistPath, masterPlaylists.join('\n') + '\n')
if (playlist.storage === VideoStorage.OBJECT_STORAGE) {
- playlist.playlistUrl = await storeHLSFile(playlist, playlist.playlistFilename)
+ playlist.playlistUrl = await storeHLSFileFromFilename(playlist, playlist.playlistFilename)
await remove(masterPlaylistPath)
}
// ---------------------------------------------------------------------------
-async function updateSha256VODSegments (video: MVideo, playlistArg: MStreamingPlaylist): Promise<MStreamingPlaylistFilesVideo> {
+function updateSha256VODSegments (video: MVideo, playlistArg: MStreamingPlaylist): Promise<MStreamingPlaylistFilesVideo> {
return playlistFilesQueue.add(async () => {
const json: { [filename: string]: { [range: string]: string } } = {}
await outputJSON(outputPath, json)
if (playlist.storage === VideoStorage.OBJECT_STORAGE) {
- playlist.segmentsSha256Url = await storeHLSFile(playlist, playlist.segmentsSha256Filename)
+ playlist.segmentsSha256Url = await storeHLSFileFromFilename(playlist, playlist.segmentsSha256Filename)
await remove(outputPath)
}
const subPlaylistUrls = await fetchUniqUrls(playlistUrl)
const subRequests = subPlaylistUrls.map(u => fetchUniqUrls(u))
- const fileUrls = uniq(flatten(await Promise.all(subRequests)))
+ const fileUrls = uniqify(flatten(await Promise.all(subRequests)))
logger.debug('Will download %d HLS files.', fileUrls.length, { fileUrls })
return `${dirname(playlistUrl)}/${url}`
})
- return uniq(urls)
+ return uniqify(urls)
}
}