making obs scene switching more coherent, but still not functional
This commit is contained in:
parent
c96f188c70
commit
00fcf565ef
5 changed files with 133 additions and 46 deletions
2
TODO.org
2
TODO.org
|
@ -67,6 +67,8 @@ Once the model of OBS scenes is created, we can select a scene to add it to the
|
||||||
*** TODO This should be ported to slides rather than service_items.
|
*** TODO This should be ported to slides rather than service_items.
|
||||||
Since sometimes in a presentation you'd possibly want different obs scenes, lets instead make these changes on the slides rather than on the service_items. That way each slide can have an associated obs scene and do some trickerydo to determine if we need to change it.
|
Since sometimes in a presentation you'd possibly want different obs scenes, lets instead make these changes on the slides rather than on the service_items. That way each slide can have an associated obs scene and do some trickerydo to determine if we need to change it.
|
||||||
|
|
||||||
|
I need to properly update them yet, it would seem I never assigned the obs scene to the slides and then obs wouldn't have anything to change to. I'm trying to change it now.
|
||||||
|
|
||||||
*** TODO OBWS setting scenes
|
*** TODO OBWS setting scenes
|
||||||
This has been really tricky since there is something of a bug when using =runtime.block_on()= rather than having a single cohesive tokio runtime. So, perhaps I need to figure out if I can't make a runtime that works for the whole app so that I can manage these a little better.
|
This has been really tricky since there is something of a bug when using =runtime.block_on()= rather than having a single cohesive tokio runtime. So, perhaps I need to figure out if I can't make a runtime that works for the whole app so that I can manage these a little better.
|
||||||
|
|
||||||
|
|
|
@ -314,7 +314,7 @@ Controls.Page {
|
||||||
editMode = false;
|
editMode = false;
|
||||||
refocusPresentation();
|
refocusPresentation();
|
||||||
footerFirstText = presenting ? "Presenting..." : "Presentation Preview";
|
footerFirstText = presenting ? "Presenting..." : "Presentation Preview";
|
||||||
footerSecondText = "";
|
footerSecondText = ObsModel.currentProgramScene;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
videoEditor.visible = false;
|
videoEditor.visible = false;
|
||||||
|
@ -327,7 +327,7 @@ Controls.Page {
|
||||||
editMode = false;
|
editMode = false;
|
||||||
refocusPresentation();
|
refocusPresentation();
|
||||||
footerFirstText = presenting ? "Presenting..." : "Presentation Preview"
|
footerFirstText = presenting ? "Presenting..." : "Presentation Preview"
|
||||||
footerSecondText = "";
|
footerSecondText = ObsModel.currentProgramScene;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ Item {
|
||||||
implicitHeight: Kirigami.Units.gridUnit * 6.5
|
implicitHeight: Kirigami.Units.gridUnit * 6.5
|
||||||
implicitWidth: Kirigami.Units.gridUnit * 9
|
implicitWidth: Kirigami.Units.gridUnit * 9
|
||||||
property bool showVidBG
|
property bool showVidBG
|
||||||
|
property var rootModel: model
|
||||||
/* property var previewSlidesList: parent */
|
/* property var previewSlidesList: parent */
|
||||||
/* Component.onCompleted: { */
|
/* Component.onCompleted: { */
|
||||||
/* if (model.videoBackground != "") */
|
/* if (model.videoBackground != "") */
|
||||||
|
@ -75,14 +76,23 @@ Item {
|
||||||
|
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
id: obsSceneLabel
|
id: obsSceneLabel
|
||||||
width: previewHighlight.width
|
anchors.top: previewHighlight.top
|
||||||
anchors.top: previewHighlight.bottom
|
anchors.right: previewHighlight.right
|
||||||
anchors.left: previewHighlight.left
|
|
||||||
anchors.topMargin: Kirigami.Units.smallSpacing
|
anchors.topMargin: Kirigami.Units.smallSpacing
|
||||||
anchors.rightMargin: Kirigami.Units.smallSpacing * 2
|
anchors.rightMargin: Kirigami.Units.smallSpacing
|
||||||
elide: Text.ElideRight
|
/* elide: Text.ElideRight */
|
||||||
text: model.obsScene
|
background: Rectangle {
|
||||||
font.bold: true
|
visible: model.obsScene.length > 0
|
||||||
|
color: Qt.lighter(Kirigami.Theme.backgroundColor, 1.2)
|
||||||
|
radius: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
text: model.obsScene.length > 0 ? "OBS Scene: " + model.obsScene : ""
|
||||||
|
font.pointSize: 8
|
||||||
|
rightPadding: 4
|
||||||
|
leftPadding: 4
|
||||||
|
color: Kirigami.Theme.highlightColor
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
@ -101,9 +111,9 @@ Item {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
propagateComposedEvents: true
|
propagateComposedEvents: true
|
||||||
|
|
||||||
Controls.ToolTip {
|
/* Controls.ToolTip { */
|
||||||
text: model.obsScene
|
/* text: model.obsScene.length > 0 ? "OBS Scene: " + model.obsScene : "" */
|
||||||
}
|
/* } */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,10 +129,10 @@ Item {
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
text: modelData
|
text: modelData
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
Utils.dbg("setting: " + modelData)
|
Utils.dbg("setting: " + modelData + " on index: " + rootModel.index);
|
||||||
Utils.dbg(model.obsScene);
|
Utils.dbg(rootModel.obsScene);
|
||||||
SlideModel.updateObsScene(modelData);
|
SlideModel.updateObsScene(rootModel.index, modelData);
|
||||||
/* ObsModel.setScene(modelData); */
|
ObsModel.setScene(modelData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onObjectAdded: obsMenu.insertAction(index, object)
|
onObjectAdded: obsMenu.insertAction(index, object)
|
||||||
|
|
|
@ -75,31 +75,33 @@ impl Obs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_scene(
|
pub fn set_scene(
|
||||||
self,
|
&self,
|
||||||
scene: String,
|
scene: String,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
debug!("Starting function");
|
// debug!("Starting function");
|
||||||
if let Some(client) = self.client {
|
if let Some(client) = &self.client {
|
||||||
debug!("Starting to set");
|
debug!(scene, "setting scene in obs");
|
||||||
let runtime =
|
|
||||||
tokio::runtime::Builder::new_current_thread()
|
|
||||||
.thread_keep_alive(Duration::from_secs(1))
|
|
||||||
.enable_all()
|
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
let client = make_client();
|
let client = make_client();
|
||||||
let handle = runtime.spawn(async move {
|
let runtime = tokio::runtime::Runtime::new()?;
|
||||||
debug!(scene, "working in thread");
|
let handle = runtime.spawn(async move {
|
||||||
client.scenes()
|
debug!("in spawn: before setting");
|
||||||
.set_current_program_scene(&scene)
|
let res = client.scenes().set_current_program_scene(&scene).await;
|
||||||
.await
|
match res {
|
||||||
});
|
Ok(o) => debug!("in spawn: after setting: success"),
|
||||||
loop {
|
Err(e) => error!(?e, "in spawn: after setting")
|
||||||
sleep(Duration::from_millis(100));
|
|
||||||
if handle.is_finished() {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
debug!("after spawn");
|
||||||
|
|
||||||
|
// loop {
|
||||||
|
// sleep(Duration::from_millis(100));
|
||||||
|
// if handle.is_finished() {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err("There is no client".to_owned())?
|
Err("There is no client".to_owned())?
|
||||||
|
@ -180,13 +182,13 @@ impl obs_model::ObsModel {
|
||||||
tokio::runtime::Runtime::new().unwrap().block_on(async {
|
tokio::runtime::Runtime::new().unwrap().block_on(async {
|
||||||
match Obs::new().await {
|
match Obs::new().await {
|
||||||
Ok(o) => {
|
Ok(o) => {
|
||||||
|
if let Some(scene) = &o.current_program_scene {
|
||||||
|
let scene = QString::from(scene);
|
||||||
|
self.as_mut().set_current_program_scene(scene);
|
||||||
|
}
|
||||||
self.as_mut().set_connected(true);
|
self.as_mut().set_connected(true);
|
||||||
self.as_mut().rust_mut().obs = Some(o);
|
self.as_mut().rust_mut().obs = Some(o);
|
||||||
self.as_mut().update_scenes();
|
self.as_mut().update_scenes();
|
||||||
if let Some(scene) = o.current_program_scene {
|
|
||||||
let scene = QString::from(&scene);
|
|
||||||
self.as_mut().set_current_program_scene(scene);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(e);
|
error!(e);
|
||||||
|
@ -220,6 +222,11 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_obs_setting_scene() {
|
pub fn test_obs_setting_scene() {
|
||||||
assert_eq!(true, true)
|
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
let future = Client::connect("localhost", 4455, Some(""));
|
||||||
|
let client = runtime.block_on(future).unwrap();
|
||||||
|
let scene = String::from("me");
|
||||||
|
let res = runtime.block_on(client.scenes().set_current_program_scene(&scene));
|
||||||
|
debug_assert!(res.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ mod slide_model {
|
||||||
VideoStartTime,
|
VideoStartTime,
|
||||||
VideoEndTime,
|
VideoEndTime,
|
||||||
Html,
|
Html,
|
||||||
|
ObsScene,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
|
@ -123,6 +124,13 @@ mod slide_model {
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
fn activate(self: Pin<&mut SlideModel>, index: i32) -> bool;
|
fn activate(self: Pin<&mut SlideModel>, index: i32) -> bool;
|
||||||
|
|
||||||
|
#[qinvokable]
|
||||||
|
fn update_obs_scene(
|
||||||
|
self: Pin<&mut SlideModel>,
|
||||||
|
index: i32,
|
||||||
|
obs_scene: QString,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl cxx_qt::Threading for SlideModel {}
|
impl cxx_qt::Threading for SlideModel {}
|
||||||
|
@ -271,7 +279,7 @@ impl Default for Slide {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SlideModelRust {
|
pub struct SlideModelRust {
|
||||||
id: i32,
|
id: i32,
|
||||||
slides: Vec<Slide>,
|
slides: Vec<Slide>,
|
||||||
|
@ -279,6 +287,28 @@ pub struct SlideModelRust {
|
||||||
count: i32,
|
count: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Default for SlideModelRust {
|
||||||
|
fn default() -> Self {
|
||||||
|
let obs =
|
||||||
|
tokio::runtime::Runtime::new().unwrap().block_on(async {
|
||||||
|
match Obs::new().await {
|
||||||
|
Ok(o) => Some(o),
|
||||||
|
Err(e) => {
|
||||||
|
error!(e);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
id: 0,
|
||||||
|
slides: Vec::new(),
|
||||||
|
obs,
|
||||||
|
count: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl slide_model::SlideModel {
|
impl slide_model::SlideModel {
|
||||||
pub fn add_video_thumbnail(
|
pub fn add_video_thumbnail(
|
||||||
mut self: Pin<&mut Self>,
|
mut self: Pin<&mut Self>,
|
||||||
|
@ -1154,25 +1184,26 @@ impl slide_model::SlideModel {
|
||||||
slide.active = false;
|
slide.active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let obs = self.as_mut().obs.clone();
|
|
||||||
|
|
||||||
if let Some(slide) =
|
if let Some(slide) =
|
||||||
self.as_mut().rust_mut().slides.get_mut(index as usize)
|
self.as_mut().rust_mut().slides.get_mut(index as usize)
|
||||||
{
|
{
|
||||||
debug!(
|
debug!(
|
||||||
slide = index,
|
slide = index,
|
||||||
service_item = slide.service_item_id,
|
service_item = slide.service_item_id,
|
||||||
|
obs = slide.obs_scene.to_string(),
|
||||||
"This slide is activating"
|
"This slide is activating"
|
||||||
);
|
);
|
||||||
let obs_scene = slide.obs_scene.to_string();
|
let obs_scene = slide.obs_scene.to_string();
|
||||||
slide.active = true;
|
slide.active = true;
|
||||||
self.as_mut().data_changed(tl, br, &vector_roles);
|
self.as_mut().data_changed(tl, br, &vector_roles);
|
||||||
|
|
||||||
if let Some(obs) = obs {
|
if let Some(obs) = self.as_ref().obs.clone() {
|
||||||
match obs.set_scene(obs_scene) {
|
match obs.set_scene(obs_scene) {
|
||||||
Ok(()) => debug!("Successfully set scene"),
|
Ok(()) => debug!("Successfully set scene"),
|
||||||
Err(e) => error!(e),
|
Err(e) => error!(e),
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
debug!("Obs isn't connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use this signal generated by our signals enum to tell QML that
|
// We use this signal generated by our signals enum to tell QML that
|
||||||
|
@ -1184,6 +1215,24 @@ impl slide_model::SlideModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_obs_scene(
|
||||||
|
mut self: Pin<&mut Self>,
|
||||||
|
index: i32,
|
||||||
|
obs_scene: QString,
|
||||||
|
) {
|
||||||
|
let rc = self.as_ref().count() - 1;
|
||||||
|
let tl = &self.as_ref().index(0, 0, &QModelIndex::default());
|
||||||
|
let br = &self.as_ref().index(rc, 0, &QModelIndex::default());
|
||||||
|
let mut vector_roles = QVector_i32::default();
|
||||||
|
vector_roles.append(self.get_role(SlideRoles::ObsScene));
|
||||||
|
if let Some(slide) =
|
||||||
|
self.as_mut().rust_mut().slides.get_mut(index as usize)
|
||||||
|
{
|
||||||
|
slide.obs_scene = obs_scene;
|
||||||
|
self.as_mut().data_changed(tl, br, &vector_roles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_role(&self, role: SlideRoles) -> i32 {
|
fn get_role(&self, role: SlideRoles) -> i32 {
|
||||||
match role {
|
match role {
|
||||||
SlideRoles::Text => 1,
|
SlideRoles::Text => 1,
|
||||||
|
@ -1193,6 +1242,8 @@ impl slide_model::SlideModel {
|
||||||
SlideRoles::VideoThumbnail => 15,
|
SlideRoles::VideoThumbnail => 15,
|
||||||
SlideRoles::VideoStartTime => 16,
|
SlideRoles::VideoStartTime => 16,
|
||||||
SlideRoles::VideoEndTime => 17,
|
SlideRoles::VideoEndTime => 17,
|
||||||
|
SlideRoles::Html => 18,
|
||||||
|
SlideRoles::ObsScene => 19,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1247,6 +1298,9 @@ impl slide_model::SlideModel {
|
||||||
QVariant::from(&slide.video_end_time)
|
QVariant::from(&slide.video_end_time)
|
||||||
}
|
}
|
||||||
SlideRoles::Html => QVariant::from(&slide.html),
|
SlideRoles::Html => QVariant::from(&slide.html),
|
||||||
|
SlideRoles::ObsScene => {
|
||||||
|
QVariant::from(&slide.obs_scene)
|
||||||
|
}
|
||||||
_ => QVariant::default(),
|
_ => QVariant::default(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1325,6 +1379,10 @@ impl slide_model::SlideModel {
|
||||||
QByteArray::from("videoEndTime"),
|
QByteArray::from("videoEndTime"),
|
||||||
);
|
);
|
||||||
roles.insert(SlideRoles::Html.repr, QByteArray::from("html"));
|
roles.insert(SlideRoles::Html.repr, QByteArray::from("html"));
|
||||||
|
roles.insert(
|
||||||
|
SlideRoles::ObsScene.repr,
|
||||||
|
QByteArray::from("obsScene"),
|
||||||
|
);
|
||||||
roles
|
roles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1334,3 +1392,13 @@ impl slide_model::SlideModel {
|
||||||
cnt
|
cnt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_obs_setting_scene() {
|
||||||
|
assert_eq!(true, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue