From 426d42eb7194aa75a539a946791f92f1ecfb0986 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Tue, 27 Aug 2024 23:01:20 -0400 Subject: [PATCH] Measure time. Experiment with switching sinks --- .../server/src/bin/enumerate-audio-sinks.rs | 4 +- gm-dash/server/src/bin/play-track.rs | 90 ++++++++++++++++--- 2 files changed, 82 insertions(+), 12 deletions(-) diff --git a/gm-dash/server/src/bin/enumerate-audio-sinks.rs b/gm-dash/server/src/bin/enumerate-audio-sinks.rs index 7ef8632..e278934 100644 --- a/gm-dash/server/src/bin/enumerate-audio-sinks.rs +++ b/gm-dash/server/src/bin/enumerate-audio-sinks.rs @@ -10,8 +10,10 @@ fn main() -> Result<(), Box> { .add_listener_local() .global(|global| { if global.props.and_then(|p| p.get("media.class")) == Some("Audio/Sink"){ + // println!("{:?}", global.props.map(|p| p)); println!( - "\t{:?} {:?}", + "\t{:?} {:?} {:?}", + global.props.and_then(|p| p.get("node.name")), global.props.and_then(|p| p.get("node.description")), global.props.and_then(|p| p.get("media.class")) ); diff --git a/gm-dash/server/src/bin/play-track.rs b/gm-dash/server/src/bin/play-track.rs index 8330474..a2e0a63 100644 --- a/gm-dash/server/src/bin/play-track.rs +++ b/gm-dash/server/src/bin/play-track.rs @@ -1,4 +1,6 @@ -use gstreamer::{prelude::*, Element, Pad}; +use std::time::Duration; + +use gstreamer::{prelude::*, Element, MessageType, MessageView, Pad}; use pipewire::{context::Context, main_loop::MainLoop}; fn main() { @@ -11,10 +13,7 @@ fn main() { .unwrap() .create() .name("source") - .property( - "location", - "/home/savanni/Music/tavern-music.ogg", - ) + .property("location", "/home/savanni/Music/tavern-music.ogg") // .property( // "location", // "/home/savanni/Music/Night at Work _ Instrumental Chill Music Mix [n9Y2Eb4BaSg].m4a", @@ -29,12 +28,15 @@ fn main() { .name("decoder") .build() .unwrap(); - let sink = gstreamer::ElementFactory::find("autoaudiosink") + let sinkfactory = gstreamer::ElementFactory::find("pulsesink") .unwrap() .load() - .unwrap() + .unwrap(); + let defaultsink = sinkfactory.create().name("sink").build().unwrap(); + let btsink = sinkfactory .create() .name("sink") + .property("device", "bluez_output.0C_A6_94_75_6E_8F.1") .build() .unwrap(); let convert = gstreamer::ElementFactory::find("audioconvert") @@ -56,17 +58,20 @@ fn main() { let pipeline = gstreamer::Pipeline::new(); pipeline.add(&source).unwrap(); - pipeline.add(&sink).unwrap(); + pipeline.add(&defaultsink).unwrap(); pipeline.add(&decoder).unwrap(); pipeline.add(&convert).unwrap(); pipeline.add(&resample).unwrap(); source.link(&decoder).unwrap(); convert.link(&resample).unwrap(); - resample.link(&sink).unwrap(); + resample.link(&defaultsink).unwrap(); decoder.connect_pad_added(move |element, pad| handle_pad_added(element, pad, &convert)); + // println!("Sink target: {:?}", sink.property::("current-device")); + // println!("Sink target: {:?}", sink.property::("device-name")); + /* println!("source: {:?}", source); source.foreach_pad(|_, pad| { @@ -81,14 +86,77 @@ fn main() { // source.link(&convert).unwrap(); pipeline.set_state(gstreamer::State::Playing).unwrap(); + let pipeline_object = pipeline.clone().upcast::(); + + /* + std::thread::sleep(Duration::from_secs(5)); + println!("switching audio outputs"); + + pipeline.set_state(gstreamer::State::Paused).unwrap(); + resample.unlink(&defaultsink); + pipeline.remove(&defaultsink).unwrap(); + pipeline.add(&btsink).unwrap(); + resample.link(&btsink).unwrap(); + pipeline.set_state(gstreamer::State::Playing).unwrap(); + println!("switch complete"); + */ let bus = pipeline.bus().unwrap(); // let msg = bus.timed_pop_filtered( // gstreamer::ClockTime::NONE, // &[gstreamer::MessageType::Error, gstreamer::MessageType::Eos], // ); - while let Some(msg) = bus.timed_pop(gstreamer::ClockTime::NONE) { - println!("message: {:?}", msg); + /* + */ + /* + std::thread::spawn({ + let pipeline = pipeline.clone(); + move || { + std::thread::sleep(Duration::new(1, 0)); + println!("{:?}", pipeline); + } + }); + */ + + let mut playing = false; + + loop { + if let Some(msg) = bus.timed_pop_filtered( + gstreamer::ClockTime::from_mseconds(100), + &[ + MessageType::Error, + MessageType::Eos, + MessageType::Progress, + MessageType::StateChanged, + MessageType::StructureChange, + ], + ) { + match msg.view() { + MessageView::Progress(prog) => { + println!("progress: {:?}", prog); + } + MessageView::StateChanged(st) => { + if msg.src() == Some(&pipeline_object) { + println!("State changed from {:?} to {:?}", st.old(), st.current()); + playing = st.current() == gstreamer::State::Playing; + } + } + MessageView::StructureChange(change) => { + println!("structure change: {:?}", change); + } + _ => { + println!("{:?}", msg); + } + } + } else { + if playing { + let mut q = gstreamer::query::Position::new(gstreamer::Format::Time); + pipeline.query(&mut q); + println!("Position result: {:?}", q.result()); + } else { + break; + } + } } pipeline.set_state(gstreamer::State::Null).unwrap();