Speed::try_seek incorrectly multiplies seek position by speed factor
Dieses Issue hat noch niemand übernommen.
- #881 von @FrogSnot — ohne Merge geschlossen
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 35/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Veraltet
- Tech-Stack
- rust
- Bereich
- audio-video-rtc
Rechercherichtung
Read src/source/speed.rs and compare Speed::try_seek with the seek behavior of Amplify and Stoppable. Check the seek path for a speed other than 1x, especially the 215-second file example seeking to 150 seconds. Done means the inner source receives the requested position unchanged and seeking no longer reaches EOF prematurely.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Hey, I found this while debugging a really frustrating issue in my music player (Sunder). When playing audio at non-1x speeds and seeking via the progress bar, tracks would immediately end as if the file was over.
After a lot of head-scratching, I traced it down to Speed::try_seek in src/source/speed.rs:
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
/* TODO: This might be wrong, I do not know how speed achieves its speedup
* so I can not reason about the correctness.
* <dvdsk [email protected]> */
// even after 24 hours of playback f32 has enough precision
let pos_accounting_for_speedup = pos.mul_f32(self.factor);
self.input.try_seek(pos_accounting_for_speedup)
}
The multiplication causes the inner decoder to receive a position that's factor times larger than intended. Since Speed achieves its speedup by modifying sample_rate() (not by resampling or skipping), the inner source still operates in source-time. Multiplying the position overshoots the actual file duration and the source immediately hits EOF.
Example:
215-second audio file, speed set to 2x
User seeks to the 150s mark: sink.try_seek(Duration::from_secs(150))
Speed::try_seek multiplies: 150 * 2.0 = 300s
The decoder receives try_seek(300s) on a 215s file, past EOF
sink.empty() returns true immediately, track skips
This happens for any seek past duration / speed. At 1x the bug is invisible since multiplying by 1.0 is a no-op, which is probably why it went unnoticed.
The TODO comment in the code already notes the uncertainty here, so I figured this was worth reporting.
Suggested fix:
Pass the position through unchanged, like Amplify, Stoppable, and all other sources that don't alter the time domain:
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
self.input.try_seek(pos)
}
Current workaround:
Pre-divide the seek position by the speed factor before calling try_seek:
let seek_pos = source_secs / speed as f64;
sink.try_seek(Duration::from_secs_f64(seek_pos));
- Vorherrschende Sprache
- Rust
- Sterne
- 2.5k
- Forks
- 338
- Ø Merge
- 1 T. 3 Std.
- Gemergte PRs (30 T.)
- 1
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus RustAudio/rodio
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 73/100
-
Schwierigkeit 3/5 Ein halber Tag Anfängerfreundlichkeit 58/100
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 62/100
-
WavDecoder::size_hint underflows (u32 wrap, ~4.29e9) after EOF, causes multi-GB Vec::collect() allocationEvtl. vergeben @marin-m hat das vor 7 Tagen übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 72/100
Alle Issues in RustAudio/rodio
Ähnliche Issues
-
r-bug
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 88/100
servo/rust-smallvec#844 ·
Maintainer antworten meist innerhalb von 1 Tag
-
enhancement
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
farion1231/cc-switch#9122 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
lbjlaq/Antigravity-Manager#3801 ·
Maintainer antworten meist innerhalb von 1 Tag
-
LIMIT inputs are named MIN/MAX instead of the standard MN/MX, so LIMIT(MN := ...) does not resolveOffen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
Maintainer antworten meist innerhalb von 1 Tag
-
Published SDL drops input-field default values: a non-null field with a default renders as requiredOffen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
Maintainer antworten meist innerhalb von 1 Tag