Adding audio playback speed control, updating volume control UI, fix stream play for small streams

This commit is contained in:
Mark Cooper 2021-08-20 18:29:10 -05:00
parent 4bcb346365
commit be7e2576f1
13 changed files with 192 additions and 211 deletions

View file

@ -296,144 +296,12 @@ class Stream extends EventEmitter {
this.ffmpeg.on('end', (stdout, stderr) => {
Logger.info('[FFMPEG] Transcoding ended')
this.isTranscodeComplete = true
this.ffmpeg = null
})
this.ffmpeg.run()
}
async startConcat() {
Logger.info(`[STREAM] START STREAM - Num Segments: ${this.numSegments}`)
var concatOutput = null
if (this.tracks.length > 1) {
var start = Date.now()
await new Promise(async (resolve) => {
Logger.info('Concatenating here', this.tracks.length)
this.ffmpeg = Ffmpeg()
var trackExt = this.tracks[0].ext
concatOutput = Path.join(this.streamPath, `concat${trackExt}`)
Logger.info('Concat OUTPUT', concatOutput)
var trackPaths = this.tracks.map(t => {
var line = 'file ' + this.escapeSingleQuotes(t.fullPath) + '\n' + `duration ${t.duration}`
return line
})
var inputstr = trackPaths.join('\n\n')
await fs.writeFile(this.concatFilesPath, inputstr)
this.ffmpeg.addInput(this.concatFilesPath)
this.ffmpeg.inputFormat('concat')
this.ffmpeg.inputOption('-safe 0')
this.ffmpeg.addOption([
'-loglevel warning',
'-map 0:a',
'-c:a copy'
])
this.ffmpeg.output(concatOutput)
this.ffmpeg.on('start', (command) => {
Logger.info('[CONCAT] FFMPEG transcoding started with command: ' + command)
})
this.ffmpeg.on('error', (err, stdout, stderr) => {
Logger.info('[CONCAT] ERROR', err, stderr)
})
this.ffmpeg.on('end', (stdout, stderr) => {
Logger.info('[CONCAT] Concat is done')
resolve()
})
this.ffmpeg.run()
})
var elapsed = ((Date.now() - start) / 1000).toFixed(1)
Logger.info(`[CONCAT] Final elapsed is ${elapsed}s`)
} else {
concatOutput = this.tracks[0].fullPath
}
this.ffmpeg = Ffmpeg()
// var currTrackEnd = 0
// var startingTrack = this.tracks.find(t => {
// currTrackEnd += t.duration
// return this.startTime < currTrackEnd
// })
// var trackStartTime = currTrackEnd - startingTrack.duration
// var currInpoint = this.startTime - trackStartTime
// var tracksToInclude = this.tracks.filter(t => t.index >= startingTrack.index)
// var trackPaths = tracksToInclude.map(t => {
// var line = 'file ' + this.escapeSingleQuotes(t.fullPath) + '\n' + `duration ${t.duration}`
// if (t.index === startingTrack.index) {
// line += `\ninpoint ${currInpoint}`
// }
// return line
// })
// var inputstr = trackPaths.join('\n\n')
// await fs.writeFile(this.concatFilesPath, inputstr)
this.ffmpeg.addInput(concatOutput)
// this.ffmpeg.inputFormat('concat')
// this.ffmpeg.inputOption('-safe 0')
if (this.startTime > 0) {
Logger.info(`[STREAM] Starting Stream at startTime ${secondsToTimestamp(this.startTime)} and Segment #${this.segmentStartNumber}`)
this.ffmpeg.inputOption(`-ss ${this.startTime}`)
this.ffmpeg.inputOption('-noaccurate_seek')
}
this.ffmpeg.addOption([
'-loglevel warning',
'-map 0:a',
'-c:a copy'
])
this.ffmpeg.addOption([
'-f hls',
"-copyts",
"-avoid_negative_ts disabled",
"-max_delay 5000000",
"-max_muxing_queue_size 2048",
`-hls_time 6`,
"-hls_segment_type mpegts",
`-start_number ${this.segmentStartNumber}`,
"-hls_playlist_type vod",
"-hls_list_size 0",
"-hls_allow_cache 0"
])
var segmentFilename = Path.join(this.streamPath, this.segmentBasename)
this.ffmpeg.addOption(`-hls_segment_filename ${segmentFilename}`)
this.ffmpeg.output(this.playlistPath)
this.ffmpeg.on('start', (command) => {
Logger.info('[INFO] FFMPEG transcoding started with command: ' + command)
if (this.isResetting) {
setTimeout(() => {
Logger.info('[STREAM] Clearing isResetting')
this.isResetting = false
}, 500)
// For very small fast load
if (!this.isClientInitialized) {
this.isClientInitialized = true
Logger.info(`[STREAM] ${this.id} notifying client that stream is ready`)
this.socket.emit('stream_open', this.toJSON())
}
this.startLoop()
})
this.ffmpeg.on('stderr', (stdErrline) => {
Logger.info(stdErrline)
})
this.ffmpeg.on('error', (err, stdout, stderr) => {
if (err.message && err.message.includes('SIGKILL')) {
// This is an intentional SIGKILL
Logger.info('[FFMPEG] Transcode Killed')
this.ffmpeg = null
} else {
Logger.error('Ffmpeg Err', err.message)
}
})
this.ffmpeg.on('end', (stdout, stderr) => {
Logger.info('[FFMPEG] Transcoding ended')
this.isTranscodeComplete = true
this.ffmpeg = null
})