157 lines
4.6 KiB
QML
157 lines
4.6 KiB
QML
pragma Singleton
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Commons
|
|
import qs.Services
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
readonly property var settings: Settings.data.screenRecorder
|
|
property bool isRecording: false
|
|
property bool isPending: false
|
|
property string outputPath: ""
|
|
property bool isAvailable: false
|
|
|
|
Component.onCompleted: {
|
|
checkAvailability()
|
|
}
|
|
|
|
function checkAvailability() {
|
|
// Detect native or Flatpak gpu-screen-recorder
|
|
availabilityCheckProcess.command = ["sh", "-c", "command -v gpu-screen-recorder >/dev/null 2>&1 || (command -v flatpak >/dev/null 2>&1 && flatpak list --app | grep -q 'com.dec05eba.gpu_screen_recorder')"]
|
|
availabilityCheckProcess.running = true
|
|
}
|
|
|
|
// Start or Stop recording
|
|
function toggleRecording() {
|
|
(isRecording || isPending) ? stopRecording() : startRecording()
|
|
}
|
|
|
|
// Start screen recording using Quickshell.execDetached
|
|
function startRecording() {
|
|
if (!isAvailable) {
|
|
return
|
|
}
|
|
if (isRecording || isPending) {
|
|
return
|
|
}
|
|
isPending = true
|
|
|
|
var filename = Time.getFormattedTimestamp() + ".mp4"
|
|
var videoDir = settings.directory
|
|
if (videoDir && !videoDir.endsWith("/")) {
|
|
videoDir += "/"
|
|
}
|
|
outputPath = videoDir + filename
|
|
var flags = `-w ${settings.videoSource} -f ${settings.frameRate} -ac ${settings.audioCodec} -k ${settings.videoCodec} -a ${settings.audioSource} -q ${settings.quality} -cursor ${settings.showCursor ? "yes" : "no"} -cr ${settings.colorRange} -o ${outputPath}`
|
|
var command = `
|
|
_gpuscreenrecorder_flatpak_installed() {
|
|
flatpak list --app | grep -q "com.dec05eba.gpu_screen_recorder"
|
|
}
|
|
if command -v gpu-screen-recorder >/dev/null 2>&1; then
|
|
gpu-screen-recorder ${flags}
|
|
elif command -v flatpak >/dev/null 2>&1 && _gpuscreenrecorder_flatpak_installed; then
|
|
flatpak run --command=gpu-screen-recorder --file-forwarding com.dec05eba.gpu_screen_recorder ${flags}
|
|
else
|
|
notify-send "gpu-screen-recorder not installed!" -u critical
|
|
fi`
|
|
|
|
// Use Process instead of execDetached so we can monitor it
|
|
recorderProcess.exec({
|
|
"command": ["sh", "-c", command]
|
|
})
|
|
|
|
// Start monitoring - if process ends quickly, it was likely cancelled
|
|
pendingTimer.running = true
|
|
}
|
|
|
|
// Stop recording using Quickshell.execDetached
|
|
function stopRecording() {
|
|
if (!isRecording && !isPending) {
|
|
return
|
|
}
|
|
|
|
Quickshell.execDetached(["sh", "-c", "pkill -SIGINT -f 'gpu-screen-recorder' || pkill -SIGINT -f 'com.dec05eba.gpu_screen_recorder'"])
|
|
|
|
isRecording = false
|
|
isPending = false
|
|
pendingTimer.running = false
|
|
monitorTimer.running = false
|
|
|
|
// Just in case, force kill after 3 seconds
|
|
killTimer.running = true
|
|
}
|
|
|
|
// Process to run and monitor gpu-screen-recorder
|
|
Process {
|
|
id: recorderProcess
|
|
onExited: function (exitCode, exitStatus) {
|
|
if (isPending) {
|
|
// Process ended while we were pending - likely cancelled or error
|
|
isPending = false
|
|
pendingTimer.running = false
|
|
} else if (isRecording) {
|
|
// Process ended normally while recording
|
|
isRecording = false
|
|
monitorTimer.running = false
|
|
}
|
|
}
|
|
}
|
|
|
|
// Availability check process
|
|
Process {
|
|
id: availabilityCheckProcess
|
|
command: ["sh", "-c", "true"]
|
|
onExited: function (exitCode, exitStatus) {
|
|
// exitCode 0 means available, non-zero means unavailable
|
|
root.isAvailable = (exitCode === 0)
|
|
}
|
|
stdout: StdioCollector {}
|
|
stderr: StdioCollector {}
|
|
}
|
|
|
|
Timer {
|
|
id: pendingTimer
|
|
interval: 2000 // Wait 2 seconds to see if process stays alive
|
|
running: false
|
|
repeat: false
|
|
onTriggered: {
|
|
if (isPending && recorderProcess.running) {
|
|
// Process is still running after 2 seconds - assume recording started successfully
|
|
isPending = false
|
|
isRecording = true
|
|
monitorTimer.running = true
|
|
} else if (isPending) {
|
|
// Process not running anymore - was cancelled or failed
|
|
isPending = false
|
|
}
|
|
}
|
|
}
|
|
|
|
// Monitor timer to periodically check if we're still recording
|
|
Timer {
|
|
id: monitorTimer
|
|
interval: 2000
|
|
running: false
|
|
repeat: true
|
|
onTriggered: {
|
|
if (!recorderProcess.running && isRecording) {
|
|
isRecording = false
|
|
running = false
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: killTimer
|
|
interval: 3000
|
|
running: false
|
|
repeat: false
|
|
onTriggered: {
|
|
Quickshell.execDetached(["sh", "-c", "pkill -9 -f 'gpu-screen-recorder' 2>/dev/null || pkill -9 -f 'com.dec05eba.gpu_screen_recorder' 2>/dev/null || true"])
|
|
}
|
|
}
|
|
}
|