I have used rodio crate for playing audio from local file, by going through docs, but not able to figure out how to play audio using url.
Asked
Active
Viewed 3,328 times
2
-
Try downloading the file before playing it with rodio? `reqwest` is a good crate for http downloading. – 8176135 Aug 18 '20 at 07:57
-
Thanks, but i have some audio links, and I want to stream those audo links from url, like MediapLayer does in android.I think Downloading every audio from link and playing will be cumbersome, and will also increase the space usage – Ritik Aug 18 '20 at 08:20
-
hi @Prime_Aqasix, I am just a beginner in rust, I also tried to get response as bytes from reqwest , but rodio doesn't seem to accept those bytes as trait std::io::Read is not satisfied. Help me. Thanks – Ritik Aug 18 '20 at 09:34
1 Answers
6
Here is a simple example using blocking reqwest. This downloads the entire audio file into memory before it starts playing.
use std::io::{Write, Read, Cursor};
use rodio::Source;
fn main() {
// Remember to add the "blocking" feature in the Cargo.toml for reqwest
let resp = reqwest::blocking::get("http://websrvr90va.audiovideoweb.com/va90web25003/companions/Foundations%20of%20Rock/13.01.mp3")
.unwrap();
let mut cursor = Cursor::new(resp.bytes().unwrap()); // Adds Read and Seek to the bytes via Cursor
let source = rodio::Decoder::new(cursor).unwrap(); // Decoder requires it's source to impl both Read and Seek
let device = rodio::default_output_device().unwrap();
rodio::play_raw(&device, source.convert_samples()); // Plays on a different thread
loop {} // Don't exit immediately, so we can hear the audio
}
If you want to implement actual streaming, where parts of the audio file is downloaded then played, and more gets fetched later as it is needed, it gets quite a bit more complicated. See this entry about partial downloads in the Rust Cookbook: https://rust-lang-nursery.github.io/rust-cookbook/web/clients/download.html#make-a-partial-download-with-http-range-headers
I believe it can also be done easier with async reqwest, but I am still experimenting with that myself.

8176135
- 3,755
- 3
- 19
- 42
-
Thanks, @Prime_Aqasix for this code snippet , It is working. Do you know to calculate the duration of songs on the length of bytes received by reqwest to know length of the song.Thanks for this answer :-) – Ritik Aug 18 '20 at 11:34
-
@RitikRaj a Decoder is a [Source](https://docs.rs/rodio/0.11.0/rodio/source/trait.Source.html), and sources provide a `total_duration`. Knowing a file's duration without parsing it is not possible, it might not even be doable without decoding the file depending on the format (e.g. VRB without metadata). Apparently rodio doesn't even bother with mp3s or oggs (these decoders always return a `total_duration` of `None`). – Masklinn Aug 18 '20 at 11:56
-
(rodio could provide the duration of CBR file using the bitrate in the header & data length, as well as estimates for ABR and VBR files, but so fat [nobody has stepped up to implement the method for other formats than flac and wav](https://github.com/RustAudio/rodio/issues/190)) – Masklinn Aug 18 '20 at 12:08