Compare commits

..

No commits in common. "2bc71a8168159643e2bbd7b211518a9d88504a8c" and "bc5f0ba614fa489be9e52f3cf91519c3753e5f41" have entirely different histories.

View File

@ -5,7 +5,7 @@ use zbus::{
dbus_proxy, dbus_proxy,
export::futures_util::TryStreamExt, export::futures_util::TryStreamExt,
zvariant::{ObjectPath, OwnedObjectPath, Structure, Value}, zvariant::{ObjectPath, OwnedObjectPath, Structure, Value},
Connection, MessageStream, MessageType, Result, Connection, MessageStream, MessageType, Result
}; };
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -20,7 +20,7 @@ pub enum RecordTypes {
pub enum CursorModeTypes { pub enum CursorModeTypes {
Default, Default,
Hidden, Hidden,
Show, Show
} }
#[dbus_proxy( #[dbus_proxy(
@ -54,12 +54,8 @@ pub struct WaylandRecorder {
impl WaylandRecorder { impl WaylandRecorder {
pub async fn new() -> Self { pub async fn new() -> Self {
let connection = Connection::session() let connection = Connection::session().await.expect("failed to connect to session bus");
.await let screen_cast_proxy = ScreenCastProxy::new(&connection).await.expect("failed to create dbus proxy for screen-cast");
.expect("failed to connect to session bus");
let screen_cast_proxy = ScreenCastProxy::new(&connection)
.await
.expect("failed to create dbus proxy for screen-cast");
gst::init().expect("failed to initialize gstreamer"); gst::init().expect("failed to initialize gstreamer");
WaylandRecorder { WaylandRecorder {
@ -71,37 +67,24 @@ impl WaylandRecorder {
} }
} }
pub async fn start( pub async fn start(&mut self, filename: String, record_type: RecordTypes, cursor_mode_type: CursorModeTypes) -> bool {
&mut self, self.screen_cast_proxy.create_session(HashMap::from([
filename: String, ("handle_token", Value::from("blue_recorder_1")),
record_type: RecordTypes, ("session_handle_token", Value::from("blue_recorder_1")),
cursor_mode_type: CursorModeTypes, ]))
) -> bool { .await.expect("failed to create session");
self.screen_cast_proxy
.create_session(HashMap::from([
("handle_token", Value::from("blue_recorder_1")),
("session_handle_token", Value::from("blue_recorder_1")),
]))
.await
.expect("failed to create session");
let mut message_stream = MessageStream::from(self.connection.clone()); let mut message_stream = MessageStream::from(self.connection.clone());
self.filename = filename.clone(); self.filename = filename.clone();
while let Some(msg) = message_stream while let Some(msg) = message_stream.try_next().await.expect("failed to get message") {
.try_next()
.await
.expect("failed to get message")
{
match msg.message_type() { match msg.message_type() {
MessageType::Signal => { MessageType::Signal => {
let (response_num, response) = msg let (response_num, response) = msg.body::<(u32, HashMap<&str, Value>)>().expect("failed to get body");
.body::<(u32, HashMap<&str, Value>)>()
.expect("failed to get body");
if response_num > 0 { if response_num > 0 {
return false; return false;
} }
if response.len() == 0 { if response.len() == 0 {
@ -113,17 +96,14 @@ impl WaylandRecorder {
self.screen_cast_proxy.clone(), self.screen_cast_proxy.clone(),
response.clone(), response.clone(),
record_type, record_type,
cursor_mode_type, cursor_mode_type
) )
.await .await.expect("failed to handle session");
.expect("failed to handle session");
continue; continue;
} }
if response.contains_key("streams") { if response.contains_key("streams") {
self.record_screen_cast(response.clone()) self.record_screen_cast(response.clone()).await.expect("failed to record screen cast");
.await
.expect("failed to record screen cast");
break; break;
} }
} }
@ -144,21 +124,8 @@ impl WaylandRecorder {
} }
if self.session_path.len() > 0 { if self.session_path.len() > 0 {
println!( println!("Closing session...: {:?}", self.session_path.replace("request", "session"));
"Closing session...: {:?}", self.connection.clone().call_method(Some("org.freedesktop.portal.Desktop"), self.session_path.clone().replace("request", "session"), Some("org.freedesktop.portal.Session"), "Close", &()).await.expect("failed to close session");
self.session_path.replace("request", "session")
);
self.connection
.clone()
.call_method(
Some("org.freedesktop.portal.Desktop"),
self.session_path.clone().replace("request", "session"),
Some("org.freedesktop.portal.Session"),
"Close",
&(),
)
.await
.expect("failed to close session");
self.session_path = String::new(); self.session_path = String::new();
} }
} }
@ -168,7 +135,7 @@ impl WaylandRecorder {
screen_cast_proxy: ScreenCastProxy<'_>, screen_cast_proxy: ScreenCastProxy<'_>,
response: HashMap<&str, Value<'_>>, response: HashMap<&str, Value<'_>>,
record_type: RecordTypes, record_type: RecordTypes,
cursor_mode_type: CursorModeTypes, cursor_mode_type: CursorModeTypes
) -> Result<()> { ) -> Result<()> {
let response_session_handle = response let response_session_handle = response
.get("session_handle") .get("session_handle")
@ -224,13 +191,13 @@ impl WaylandRecorder {
.clone() .clone()
.downcast::<Vec<Value>>() .downcast::<Vec<Value>>()
.expect("cannot down cast streams to vec array") .expect("cannot down cast streams to vec array")
.first() .get(0)
.expect("cannot get first object from streams array") .expect("cannot get first object from streams array")
.clone() .clone()
.downcast::<Structure>() .downcast::<Structure>()
.expect("cannot down cast first object to structure") .expect("cannot down cast first object to structure")
.fields() .fields()
.first() .get(0)
.expect("cannot get first field from structure") .expect("cannot get first field from structure")
.clone() .clone()
.downcast::<u32>() .downcast::<u32>()
@ -239,7 +206,7 @@ impl WaylandRecorder {
// launch gstreamer pipeline // launch gstreamer pipeline
let gst_element: gst::Element = gst::parse_launch(&format!( let gst_element: gst::Element = gst::parse_launch(&format!(
"pipewiresrc path={stream_node_id} ! videorate ! video/x-raw,framerate=30/1 ! videoconvert chroma-mode=none dither=none matrix-mode=output-only ! vp8enc max-quantizer=17 deadline=1 keyframe-mode=disabled buffer-size=20000 ! webmmux ! filesink location={filename}", "pipewiresrc path={stream_node_id} ! videorate ! video/x-raw,framerate=30/1 ! videoconvert chroma-mode=none dither=none matrix-mode=output-only ! vp8enc max-quantizer=17 deadline=1 keyframe-mode=disabled buffer-size=20000 ! webmmux ! filesink location={filename}",
filename = self.filename filename = self.filename
)).expect("failed to launch gstreamer pipeline"); )).expect("failed to launch gstreamer pipeline");
// start pipeline // start pipeline
@ -256,4 +223,4 @@ impl WaylandRecorder {
println!("Recording Wayland screen cast..."); println!("Recording Wayland screen cast...");
Ok(()) Ok(())
} }
} }