mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-07-05 15:04:56 +02:00
Adding audio playback speed control, updating volume control UI, fix stream play for small streams
This commit is contained in:
parent
506f16c431
commit
744aacbb4b
13 changed files with 192 additions and 211 deletions
142
server/Stream.js
142
server/Stream.js
|
@ -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
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue