Rodio Sink::get_pos() gives a pos beyond the duration of the audio file

⚓ Rust    📅 2025-07-09    👤 surdeus    👁️ 19      

surdeus

Warning

This post was published 166 days ago. The information described in this article may have changed.

Here's the repo

I'm creating tui audio player with ratatui, rodio and crossbeam_channel. No async.
I have brute forced my way in the queue part. I only load 1 source in sink at the given moment.
I have a seek functionality with binds for it. It skips 5 seconds forward or backward.
If i don't queue new audio i can infinitely seek forward even though sink is empty.
Here's the output:

Seeking forward. pos: 186.72, is_empty: false
Seeking forward. pos: 191.76, is_empty: false
Seeking forward. pos: 196.76, is_empty: false
Seeking forward. pos: 201.79, is_empty: false
Seeking forward. pos: 206.79, is_empty: false
Seeking forward. pos: 211.82, is_empty: false
Seeking forward. pos: 216.82, is_empty: false
Seeking forward. pos: 221.86, is_empty: false
Stopping sink
Seeking forward. pos: 226.86, is_empty: true
Stopping sink
Seeking forward. pos: 226.86, is_empty: true
Stopping sink
Seeking forward. pos: 226.86, is_empty: true
Stopping sink

And if i queue as soon as i get Message::TrackEnded from audio thread i'm trying to queue next audio from vector. If i do so the Sink::pos() always grows instead of becoming zero and then increment.
The output looks like this:

Seeking forward. pos: 232.16, is_empty: false
Seeking forward. pos: 237.18, is_empty: false
Seeking forward. pos: 242.22, is_empty: false
Seeking forward. pos: 247.22, is_empty: false
Seeking forward. pos: 252.25, is_empty: false // First audio ends here
Stopping sink
Seeking forward. pos: 257.25, is_empty: true
Stopping sink
Seeking forward. pos: 257.25, is_empty: false
Stopping sink
Seeking forward. pos: 262.25, is_empty: true
Stopping sink
Seeking forward. pos: 262.25, is_empty: false
Stopping sink
Seeking forward. pos: 267.25, is_empty: true
Stopping sink
Seeking forward. pos: 267.25, is_empty: false
Seeking forward. pos: 272.25, is_empty: true
Stopping sink
Seeking forward. pos: 272.25, is_empty: false
Stopping sink
Seeking forward. pos: 277.25, is_empty: true
Stopping sink
Seeking forward. pos: 277.25, is_empty: false
...

It goes on and on. One time it stopped output. I guess the audio thread crashed, but it didn't print anything in terminal and i couldn't reproduce it.

As i said i'm not using async. Maybe the problem is data races and blocking calls to Sink::try_seek.

If the pos is growing infinitely doesn't that mean that new audio is placed where prev one is ended, and prev one isn't cleared after being played? So i probably could crash the program with buffer overflow or not enough memory?

Do i need some kind of sync primitive to clear the sink and let it set its pos to 0?
I don't quite understand why it even behaves like this

1 post - 1 participant

Read full topic

🏷️ rust_feed