mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-05-20 18:31:30 +00:00
feat: implement smart speed phase 3 silence compression
This commit is contained in:
parent
ebff884562
commit
4299fdce59
5 changed files with 568 additions and 7 deletions
89
client/players/smart-speed/TimeMapper.js
Normal file
89
client/players/smart-speed/TimeMapper.js
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
class TimeMapper {
|
||||
constructor(silenceRegions = [], compressionRatio = 1.0) {
|
||||
this.ratio = compressionRatio
|
||||
// Only keep regions >= 200ms
|
||||
this.regions = silenceRegions.filter(r => (r.end - r.start) >= 200)
|
||||
|
||||
// Calculate compressed durations and cumulative time saved
|
||||
this.processedRegions = []
|
||||
let accumulatedSaved = 0
|
||||
|
||||
for (const r of this.regions) {
|
||||
const originalDuration = r.end - r.start
|
||||
const compressedDuration = this.ratio === 0 ? 0 : originalDuration / this.ratio
|
||||
const saved = originalDuration - compressedDuration
|
||||
|
||||
this.processedRegions.push({
|
||||
...r,
|
||||
originalDuration,
|
||||
compressedDuration,
|
||||
saved,
|
||||
accumulatedSavedBefore: accumulatedSaved
|
||||
})
|
||||
|
||||
accumulatedSaved += saved
|
||||
}
|
||||
|
||||
this._totalTimeSaved = accumulatedSaved
|
||||
}
|
||||
|
||||
wallClockToAudio(wallMs) {
|
||||
if (this.ratio === 1.0 || this.regions.length === 0) return wallMs
|
||||
|
||||
let audioMs = wallMs
|
||||
|
||||
for (const r of this.processedRegions) {
|
||||
// The start time of this region in wall-clock time
|
||||
const regionWallStart = r.start - r.accumulatedSavedBefore
|
||||
|
||||
if (wallMs < regionWallStart) {
|
||||
// Before this region, no more accumulated saved to add
|
||||
break
|
||||
}
|
||||
|
||||
const regionWallEnd = regionWallStart + r.compressedDuration
|
||||
|
||||
if (wallMs <= regionWallEnd) {
|
||||
// Inside the compressed region
|
||||
const timeSpentInRegionWall = wallMs - regionWallStart
|
||||
const timeSpentInRegionAudio = timeSpentInRegionWall * this.ratio
|
||||
return r.start + timeSpentInRegionAudio
|
||||
}
|
||||
|
||||
// After this region, we add the total time saved by this region
|
||||
audioMs = wallMs + (r.accumulatedSavedBefore + r.saved)
|
||||
}
|
||||
|
||||
return audioMs
|
||||
}
|
||||
|
||||
audioToWallClock(audioMs) {
|
||||
if (this.ratio === 1.0 || this.regions.length === 0) return audioMs
|
||||
|
||||
let wallMs = audioMs
|
||||
|
||||
for (const r of this.processedRegions) {
|
||||
if (audioMs < r.start) {
|
||||
break
|
||||
}
|
||||
|
||||
if (audioMs <= r.end) {
|
||||
// Inside the region
|
||||
const timeSpentInRegionAudio = audioMs - r.start
|
||||
const timeSpentInRegionWall = timeSpentInRegionAudio / this.ratio
|
||||
return r.start - r.accumulatedSavedBefore + timeSpentInRegionWall
|
||||
}
|
||||
|
||||
// After the region
|
||||
wallMs = audioMs - (r.accumulatedSavedBefore + r.saved)
|
||||
}
|
||||
|
||||
return wallMs
|
||||
}
|
||||
|
||||
totalTimeSaved() {
|
||||
return this._totalTimeSaved
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TimeMapper
|
||||
Loading…
Add table
Add a link
Reference in a new issue