Skip to content

Commit 29d05a8

Browse files
authored
library: add Camera Entry (#375)
1 parent 5a71dbe commit 29d05a8

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

src/Library/demos/Camera/main.blp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Gtk 4.0;
2+
using Adw 1;
3+
4+
Adw.StatusPage {
5+
title: _("Camera");
6+
description: _("Access the Camera");
7+
margin-top: 48;
8+
9+
Box {
10+
orientation: vertical;
11+
halign: center;
12+
13+
Picture output {
14+
margin-bottom: 30;
15+
width-request: 360;
16+
height-request: 240;
17+
}
18+
19+
Button button {
20+
label: _("Access Camera");
21+
margin-bottom: 42;
22+
halign: center;
23+
styles ["suggested-action"]
24+
}
25+
26+
LinkButton {
27+
label: "API Reference";
28+
uri: "https://libportal.org/method.Portal.access_camera.html";
29+
}
30+
}
31+
}
32+
33+

src/Library/demos/Camera/main.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import Gio from "gi://Gio";
2+
import Xdp from "gi://Xdp";
3+
import XdpGtk from "gi://XdpGtk4";
4+
import GObject from "gi://GObject";
5+
import Gst from "gi://Gst";
6+
7+
Gst.init(null);
8+
Gio._promisify(Xdp.Portal.prototype, "access_camera", "access_camera_finish");
9+
10+
const portal = new Xdp.Portal();
11+
const parent = XdpGtk.parent_new_gtk(workbench.window);
12+
13+
const output = workbench.builder.get_object("output");
14+
const button = workbench.builder.get_object("button");
15+
16+
button.connect("clicked", () => {
17+
accessCamera().catch(logError);
18+
});
19+
20+
async function accessCamera() {
21+
if (!portal.is_camera_present()) {
22+
console.log("No Camera detected");
23+
return;
24+
}
25+
26+
const success = await portal.access_camera(
27+
parent,
28+
Xdp.CameraFlags.NONE,
29+
null,
30+
);
31+
32+
if (!success) {
33+
console.log("Permission denied");
34+
return;
35+
}
36+
37+
await handleCamera();
38+
}
39+
40+
async function handleCamera() {
41+
const fd_pipewire_remote = portal.open_pipewire_remote_for_camera();
42+
console.log("Pipewire remote opened for camera");
43+
44+
// Create the pipeline
45+
const pipeline = new Gst.Pipeline();
46+
47+
// Create elements
48+
const source = Gst.ElementFactory.make("pipewiresrc", "source");
49+
const queue = Gst.ElementFactory.make("queue", "queue"); // add a queue element
50+
const paintable_sink = Gst.ElementFactory.make(
51+
"gtk4paintablesink",
52+
"paintable_sink",
53+
);
54+
const glsinkbin = Gst.ElementFactory.make("glsinkbin", "glsinkbin");
55+
56+
// Set up and Link Pipeline
57+
source.set_property("fd", fd_pipewire_remote); // fd_pipewire_remote is the file descriptor obtained from libportal
58+
glsinkbin.set_property("sink", paintable_sink);
59+
60+
pipeline.add(source);
61+
pipeline.add(queue);
62+
pipeline.add(glsinkbin);
63+
source.link(queue);
64+
queue.link(glsinkbin);
65+
66+
const paintable = new GObject.Value();
67+
paintable_sink.get_property("paintable", paintable);
68+
output.paintable = paintable.get_object();
69+
70+
// Start the pipeline
71+
pipeline.set_state(Gst.State.PLAYING);
72+
73+
// Handle cleanup on application exit
74+
output.connect("destroy", () => {
75+
pipeline.set_state(Gst.State.NULL);
76+
});
77+
78+
// Set up the bus
79+
const bus = pipeline.get_bus();
80+
bus.add_signal_watch();
81+
bus.connect("message", (self, message) => {
82+
// Check the message type
83+
const message_type = message.type;
84+
85+
// Handle different message types
86+
switch (message_type) {
87+
case Gst.MessageType.ERROR: {
88+
const errorMessage = message.parse_error();
89+
console.error(errorMessage[0].toString());
90+
break;
91+
}
92+
case Gst.MessageType.EOS: {
93+
console.log("End of stream");
94+
break;
95+
}
96+
}
97+
});
98+
}

src/Library/demos/Camera/main.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "Camera",
3+
"category": "platform",
4+
"description": "Access the Camera",
5+
"panels": [
6+
"code",
7+
"preview"
8+
],
9+
"autorun": true
10+
}

0 commit comments

Comments
 (0)