use crate::priv_prelude::*; #[derive(Debug, Clone)] #[repr(transparent)] pub struct Playbin3 { pub(crate) inner: gstreamer::Element, } impl Drop for Playbin3 { fn drop(&mut self) { let _ = self .inner .set_state(gstreamer::State::Null) .inspect_err(|e| { tracing::error!("Failed to set playbin3 to Null state on drop: {:?}", e) }); } } impl Playbin3 { pub fn new(name: impl AsRef) -> Result { use gstreamer::prelude::*; gstreamer::ElementFactory::make("playbin3") .name(name.as_ref()) .build() .map(|element| Playbin3 { inner: element }) .change_context(Error) } pub fn with_uri(self, uri: impl AsRef) -> Self { use gstreamer::prelude::*; self.inner.set_property("uri", uri.as_ref()); self } pub fn with_video_sink(self, video_sink: &impl IsElement) -> Self { use gstreamer::prelude::*; self.inner .set_property("video-sink", &video_sink.as_element().inner); self } pub fn with_text_sink(self, text_sink: &impl IsElement) -> Self { use gstreamer::prelude::*; self.inner .set_property("text-sink", &text_sink.as_element().inner); self } pub fn with_audio_sink(self, audio_sink: &impl IsElement) -> Self { use gstreamer::prelude::*; self.inner .set_property("audio-sink", &audio_sink.as_element().inner); self } pub fn set_volume(&self, volume: f64) { use gstreamer::prelude::*; self.inner.set_property("volume", volume.clamp(1.0, 100.0)) } pub fn get_volume(&self) -> f64 { use gstreamer::prelude::*; self.inner.property::("volume") } // pub fn play(&self) -> Result<()> { // use gstreamer::prelude::*; // self.inner // .set_state(gstreamer::State::Playing) // .change_context(Error) // .attach("Failed to set playbin3 to Playing state")?; // Ok(()) // } // // pub fn pause(&self) -> Result<()> { // use gstreamer::prelude::*; // self.inner // .set_state(gstreamer::State::Paused) // .change_context(Error) // .attach("Failed to set playbin3 to Paused state")?; // Ok(()) // } // // pub fn bus(&self) -> Result { // let bus = self // .inner // .bus() // .ok_or(Error) // .attach("Failed to get bus from playbin3")?; // Ok(Bus { bus }) // } } // #[test] // fn test_playbin3() { // use gstreamer::prelude::*; // use tracing_subscriber::prelude::*; // tracing_subscriber::registry() // .with( // tracing_subscriber::fmt::layer() // .with_thread_ids(true) // .with_file(true), // ) // .init(); // tracing::info!("Linking videoconvert to appsink"); // Gst::new(); // let playbin3 = Playbin3::new("pppppppppppppppppppppppppppppp").unwrap().with_uri("https://jellyfin.tsuba.darksailor.dev/Items/6010382cf25273e624d305907010d773/Download?api_key=036c140222464878862231ef66a2bc9c"); // // let video_convert = plugins::videoconvertscale::VideoConvert::new("vcvcvcvcvcvcvcvcvcvcvcvcvc") // .expect("Create videoconvert"); // let appsink = // autodetect::AutoVideoSink::new("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").expect("Create appsink"); // // let mut video_sink = video_convert // .link(&appsink) // .expect("Link videoconvert to appsink"); // // let playbin3 = playbin3.with_video_sink(&video_sink); // let bus = playbin3.bus().unwrap(); // playbin3.play().expect("Play playbin3"); // std::thread::spawn(move || loop { // std::thread::sleep(std::time::Duration::from_secs(15)); // playbin3.play(); // tracing::info!("Played"); // }); // for msg in bus.iter_timed(None) { // match msg.view() { // gstreamer::MessageView::Eos(..) => { // tracing::info!("End of stream reached"); // break; // } // gstreamer::MessageView::Error(err) => { // tracing::error!( // "Error from {:?}: {} ({:?})", // err.src().map(|s| s.path_string()), // err.error(), // err.debug() // ); // break; // } // gstreamer::MessageView::StateChanged(state) => { // eprintln!( // "State changed from {:?} to \x1b[33m{:?}\x1b[0m for {:?}", // state.old(), // state.current(), // state.src().map(|s| s.path_string()) // ); // } // _ => {} // } // // tracing::info!("{:#?}", &msg.view()); // } // // std::thread::sleep(std::time::Duration::from_secs(5)); // }