Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use symphonia ReadOnlySource due to no seek support #580

Closed
yuvadm opened this issue May 31, 2024 · 5 comments
Closed

Cannot use symphonia ReadOnlySource due to no seek support #580

yuvadm opened this issue May 31, 2024 · 5 comments

Comments

@yuvadm
Copy link

yuvadm commented May 31, 2024

I'm trying to run a basic scenario of playing an MP3 stream from network by using a ReadOnlySource from symphonia.

This is my current usage:

use rodio::decoder::Decoder;
use rodio::OutputStream;
use symphonia::core::io::{MediaSourceStream, ReadOnlySource};

fn main() {
    let (_stream, stream_handle) = OutputStream::try_default().unwrap();
    let url = "http://example.com/stream.mp3";
    let response = reqwest::blocking::get(url).unwrap();
    let ros = ReadOnlySource::new(response);
    let source = MediaSourceStream::new(Box::new(ros), Default::default());
    let decoder = Decoder::new(source).unwrap();
    let sink = rodio::Sink::try_new(&stream_handle).unwrap();
    
    sink.append(decoder);
    sink.set_volume(1.0);
    // ...
}

While this does compile, it fails with:

$ cargo run
thread 'main' panicked at /home/yuval/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rodio-0.18.1/src/decoder/wav.rs:185:48:
called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "source does not support seeking" }

What would be the right way to use a non-seeking source? Ideally would like to use any available pre-existing traits from symphonia/rodio, but can also implement any custom traits as necessary.

@yuvadm
Copy link
Author

yuvadm commented May 31, 2024

Also, this is might be related to ongoing seek behavior changes i.e. #176 ?

@dvdsk
Copy link
Collaborator

dvdsk commented May 31, 2024

That's actually a different kind of seek :)

The problem is your MediaSourceStream does not implement the right IO traits. Instead of fixing that you might be better of using something like: https://github.com/aschey/stream-download-rs

If you want to do this yourself take a look at what the decoder needs. Basically you'll have to write a struct that wraps the reqwest output and implements the Read and Seek traits while it is also Send and Sync. Thats not easy as you want to download while playing so you need multiple threads.

Ive been working on something like this myself but its not fully done yet

@yuvadm
Copy link
Author

yuvadm commented May 31, 2024

@dvdsk thanks for the quick response! Would stream-download-rs be the right approach even if I'm doing blocking IO / threads? Generally speaking I don't require async, but I do want the easiest interface for hooking up a stream to rodio.

I've bumped into the recommendation in #439 but minimp3 seems to be a rather broken approach.

@dvdsk
Copy link
Collaborator

dvdsk commented May 31, 2024

I recommend you read through https://tokio.rs/tokio/topics/bridging. Almost all of rusts io-libs (reqwest::blocking in your code snippet above does the same as described in the article above. ) are async under the hood, even if the provide a blocking API. Once you get the whole bridging async and non-async code bit it isn't a big deal anymore.

@yuvadm
Copy link
Author

yuvadm commented May 31, 2024

Appreciate the clarification, indeed stream-download-rs does the job and has great useful examples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants