audiorustrodio

Rust Rodio get a list of OutputDevices


I'm new to the rust and I've been playing around with the Rodio audio library. I can play an audio file on the default audio output device like this:

use std::fs::File;
use std::io::BufReader;
use rodio::{OutputStream, Sink};
fn main() {
   let (_stream, stream_handle) = OutputStream::try_default().unwrap();
   let sink = Sink::try_new(&stream_handle).unwrap();
   let file = File::open("m.mp3").unwrap();
   let source = rodio::Decoder::new(BufReader::new(file)).unwrap();
   sink.append(source);
   loop {}
}

I can see that Rodio provides a method to set the audio output device for a stream try_from_device(&Device) but I can't figure out how to get a list of available audio output devices and provide an arbitrary one to this function.

---- UPDATE ----

Based on E_net4's answer I made two simple functions to list host devices and create an OutputStream for a specific device and then use it anywhere I need to play an audio file on that device like this:

use std::fs::File;
use std::io::BufReader;
use rodio::*;
use rodio::cpal::traits::{HostTrait,DeviceTrait};

fn listHostDevices(){
   let host = cpal::default_host();
   let devices = host.output_devices().unwrap();
   for device in devices{ 
      let dev:rodio::Device = device.into();
      let devName:String=dev.name().unwrap();
      println!(" # Device : {}", devName);
   }
}

fn getOutputStream(device_name:&str) -> (OutputStream,OutputStreamHandle) {
   let host = cpal::default_host();
   let devices = host.output_devices().unwrap();
   let ( mut _stream, mut stream_handle) = OutputStream::try_default().unwrap();
   for device in devices{ 
      let dev:rodio::Device = device.into();
      let devName:String=dev.name().unwrap();
      if devName==device_name {
         println!("Device found: {}", devName);
         ( _stream, stream_handle) = OutputStream::try_from_device(&dev).unwrap();
      }
   }
   return (_stream,stream_handle);
}

And then I use the functions like this:

fn main() {
   listHostDevices();
   let (_stream, stream_handle) = getOutputStream("Speakers (Realtek(R) Audio)");
   let sink = Sink::try_new(&stream_handle).unwrap();
   let file = File::open("m.mp3").unwrap();
   let source = rodio::Decoder::new(BufReader::new(file)).unwrap();
   sink.append(source);
   
   loop {}
}

Solution

  • rodio uses cpal as the underlying audio library. This is where the concepts of host and device come from. Use the re-exported cpal module from rodio to get the system host and obtain a list of output devices.

    use rodio::cpal;
    
    let host = cpal::default_host();
    let devices = host.output_devices()?;
    
    for device in devices {
       // use device
    }
    

    The device values obtained will implement DeviceTrait, but rodio works with the dynamically polymorphic type rodio::Device instead. Fortunately, we can easily convert what we have via From or Into.

    let device: rodio::Device = device.into();
    
    // ...
    
    stream.try_from_device(&device)?;