Measure time. Experiment with switching sinks
This commit is contained in:
parent
04a6e607a3
commit
426d42eb71
|
@ -10,8 +10,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.add_listener_local()
|
.add_listener_local()
|
||||||
.global(|global| {
|
.global(|global| {
|
||||||
if global.props.and_then(|p| p.get("media.class")) == Some("Audio/Sink"){
|
if global.props.and_then(|p| p.get("media.class")) == Some("Audio/Sink"){
|
||||||
|
// println!("{:?}", global.props.map(|p| p));
|
||||||
println!(
|
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("node.description")),
|
||||||
global.props.and_then(|p| p.get("media.class"))
|
global.props.and_then(|p| p.get("media.class"))
|
||||||
);
|
);
|
||||||
|
|
|
@ -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};
|
use pipewire::{context::Context, main_loop::MainLoop};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -11,10 +13,7 @@ fn main() {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.create()
|
.create()
|
||||||
.name("source")
|
.name("source")
|
||||||
.property(
|
.property("location", "/home/savanni/Music/tavern-music.ogg")
|
||||||
"location",
|
|
||||||
"/home/savanni/Music/tavern-music.ogg",
|
|
||||||
)
|
|
||||||
// .property(
|
// .property(
|
||||||
// "location",
|
// "location",
|
||||||
// "/home/savanni/Music/Night at Work _ Instrumental Chill Music Mix [n9Y2Eb4BaSg].m4a",
|
// "/home/savanni/Music/Night at Work _ Instrumental Chill Music Mix [n9Y2Eb4BaSg].m4a",
|
||||||
|
@ -29,12 +28,15 @@ fn main() {
|
||||||
.name("decoder")
|
.name("decoder")
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let sink = gstreamer::ElementFactory::find("autoaudiosink")
|
let sinkfactory = gstreamer::ElementFactory::find("pulsesink")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.load()
|
.load()
|
||||||
.unwrap()
|
.unwrap();
|
||||||
|
let defaultsink = sinkfactory.create().name("sink").build().unwrap();
|
||||||
|
let btsink = sinkfactory
|
||||||
.create()
|
.create()
|
||||||
.name("sink")
|
.name("sink")
|
||||||
|
.property("device", "bluez_output.0C_A6_94_75_6E_8F.1")
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let convert = gstreamer::ElementFactory::find("audioconvert")
|
let convert = gstreamer::ElementFactory::find("audioconvert")
|
||||||
|
@ -56,17 +58,20 @@ fn main() {
|
||||||
|
|
||||||
let pipeline = gstreamer::Pipeline::new();
|
let pipeline = gstreamer::Pipeline::new();
|
||||||
pipeline.add(&source).unwrap();
|
pipeline.add(&source).unwrap();
|
||||||
pipeline.add(&sink).unwrap();
|
pipeline.add(&defaultsink).unwrap();
|
||||||
pipeline.add(&decoder).unwrap();
|
pipeline.add(&decoder).unwrap();
|
||||||
pipeline.add(&convert).unwrap();
|
pipeline.add(&convert).unwrap();
|
||||||
pipeline.add(&resample).unwrap();
|
pipeline.add(&resample).unwrap();
|
||||||
|
|
||||||
source.link(&decoder).unwrap();
|
source.link(&decoder).unwrap();
|
||||||
convert.link(&resample).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));
|
decoder.connect_pad_added(move |element, pad| handle_pad_added(element, pad, &convert));
|
||||||
|
|
||||||
|
// println!("Sink target: {:?}", sink.property::<String>("current-device"));
|
||||||
|
// println!("Sink target: {:?}", sink.property::<String>("device-name"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
println!("source: {:?}", source);
|
println!("source: {:?}", source);
|
||||||
source.foreach_pad(|_, pad| {
|
source.foreach_pad(|_, pad| {
|
||||||
|
@ -81,14 +86,77 @@ fn main() {
|
||||||
// source.link(&convert).unwrap();
|
// source.link(&convert).unwrap();
|
||||||
|
|
||||||
pipeline.set_state(gstreamer::State::Playing).unwrap();
|
pipeline.set_state(gstreamer::State::Playing).unwrap();
|
||||||
|
let pipeline_object = pipeline.clone().upcast::<gstreamer::Object>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 bus = pipeline.bus().unwrap();
|
||||||
// let msg = bus.timed_pop_filtered(
|
// let msg = bus.timed_pop_filtered(
|
||||||
// gstreamer::ClockTime::NONE,
|
// gstreamer::ClockTime::NONE,
|
||||||
// &[gstreamer::MessageType::Error, gstreamer::MessageType::Eos],
|
// &[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();
|
pipeline.set_state(gstreamer::State::Null).unwrap();
|
||||||
|
|
Loading…
Reference in New Issue