resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
-hls.js@^0.14.9:
- version "0.14.9"
- resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-0.14.9.tgz#e85be87d94385ed9947155716578f7c568957d15"
- integrity sha512-5j1ONTvIzcIxCtg2eafikFbZ3b/9fDhR6u871LmK7jZ44/Qdc2G4xaSBCwcVK61gz7kTyiobaAhB++2M4J58rQ==
+hls.js@^0.14.16:
+ version "0.14.16"
+ resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-0.14.16.tgz#4ff68a1fa7260a43d316270e9bc7f7bdf93c5731"
+ integrity sha512-VACiO99DQFBpflR4fI+6GVHUZn35R0SGGQo0XTDZOm2BUXbeuDHTghTC/k2/3wGln6KBmG8/bXIcDIzDsY2UEg==
dependencies:
eventemitter3 "^4.0.3"
url-toolkit "^2.1.6"
}
// For the logger
-morgan.token('remote-addr', req => {
+morgan.token('remote-addr', (req: express.Request) => {
if (CONFIG.LOG.ANONYMIZE_IP === true || req.get('DNT') === '1') {
return anonymize(req.ip, 16, 16)
}
return req.ip
})
-morgan.token('user-agent', req => {
+morgan.token('user-agent', (req: express.Request) => {
if (req.get('DNT') === '1') {
return useragent.parse(req.get('user-agent')).family
}
import * as ffmpeg from 'fluent-ffmpeg'
-import { readFile, remove, writeFile } from 'fs-extra'
+import { outputFile, readFile, remove, writeFile } from 'fs-extra'
import { dirname, join } from 'path'
import { VideoFileMetadata } from '@shared/models/videos/video-file-metadata'
import { getMaxBitrate, getTargetBitrate, VideoResolution } from '../../shared/models/videos'
}
async function hlsPlaylistToFragmentedMP4 (hlsDirectory: string, segmentFiles: string[], outputPath: string) {
- const concatFile = 'concat.txt'
- const concatFilePath = join(hlsDirectory, concatFile)
+ const concatFilePath = join(hlsDirectory, 'concat.txt')
+
+ function cleaner () {
+ remove(concatFilePath)
+ .catch(err => logger.error('Cannot remove concat file in %s.', hlsDirectory, { err }))
+ }
+
+ // First concat the ts files to a mp4 file
const content = segmentFiles.map(f => 'file ' + f)
.join('\n')
command.inputOption('-safe 0')
command.inputOption('-f concat')
- command.outputOption('-c copy')
+ command.outputOption('-c:v copy')
+ command.audioFilter('aresample=async=1:first_pts=0')
command.output(outputPath)
- command.run()
+ return runCommand(command, cleaner)
+}
- function cleaner () {
- remove(concatFilePath)
- .catch(err => logger.error('Cannot remove concat file in %s.', hlsDirectory, { err }))
- }
+async function runCommand (command: ffmpeg.FfmpegCommand, onEnd?: Function) {
+ command.run()
return new Promise<string>((res, rej) => {
command.on('error', err => {
- cleaner()
+ if (onEnd) onEnd()
rej(err)
})
command.on('end', () => {
- cleaner()
+ if (onEnd) onEnd()
res()
})
command.outputOption('-hls_flags delete_segments')
}
- command.outputOption(`-hls_segment_filename ${join(outPath, '%v-%d.ts')}`)
+ command.outputOption(`-hls_segment_filename ${join(outPath, '%v-%04d.ts')}`)
command.outputOption('-master_pl_name master.m3u8')
command.outputOption(`-f hls`)