From 2ff4e620bbf0c9d912f633177223254a6249f869 Mon Sep 17 00:00:00 2001
From: Mitchell
Date: Sat, 20 Jun 2026 14:22:15 -0500
Subject: [PATCH] chore: default to a lower audio bit rate
- Update readme.
- Add path information back to install script.
---
README.md | 73 ++++++++++---------
install.sh | 11 +++
src/audio/audio_encoder.zig | 2 +-
.../video/linux/pipewire/pipewire_video.zig | 6 +-
.../pipewire/vulkan_image_buffer_chan.zig | 1 +
src/vulkan/vulkan_image_buffer.zig | 2 +
6 files changed, 57 insertions(+), 38 deletions(-)
diff --git a/README.md b/README.md
index 69ce0a0..bd11a6c 100644
--- a/README.md
+++ b/README.md
@@ -3,21 +3,21 @@
Spacecap
-A hardware accelerated screen recording/replay application focused on performance.
-Currently only supports Linux. Still in early development (see roadmap below).
+A hardware accelerated screen recording tool for Linux. _Still in development
+(see features/roadmap below)_.
-- Written in [Zig](https://ziglang.org/).
+- Written in [Zig](https://ziglang.org/) (0.16.0).
- Video encoding with Vulkan Video ([vulkan-zig](https://github.com/Snektron/vulkan-zig)).
- UI built with [imgui](https://github.com/ocornut/imgui)/[SDL3](https://github.com/allyourcodebase/SDL3).
- Muxing/Audio encoding with [FFmpeg](https://www.ffmpeg.org/).
----
-

## Installation
```sh
+# Spacecap will be installed to ~/.local/bin/spacecap
+
# Install
curl -LsSf https://spacecap.org/install | sh
@@ -39,27 +39,44 @@ curl -LsSf https://spacecap.org/install | sh -s -- --uninstall
- Video player/editor.
- Simple video editor (trim start/end).
- File browser to select videos to edit.
-- Additional video output formats (mp4, mov, mkv, gif, etc.).
- Windows support.
## Requirements
-- A GPU that supports Vulkan Video.
+- A GPU that supports Vulkan Video encoding.
-**NOTE:** Only tested on an Nvidia GPU (RTX 3080) so far. AMD will be supported, I just
-have no way of testing at this time.
+**NOTE:** So far this has only been tested on an Nvidia GPU (RTX 3080). AMD will
+be supported, I just have no way of testing at this time.
### Linux
-- vulkan
-- pipewire
-- pipewire-pulse
+- Wayland
+- Pipewire
-#### Global Keybinds
+### Windows
-If your version of Linux supports [xdg-desktop-portal global shortcuts](https://wiki.archlinux.org/title/XDG_Desktop_Portal#List_of_backends_and_interfaces)
-then they can be configured that way. Alternatively, Spacecap runs an IPC
-server, which can be communicated with via Spacecap CLI.
+- Windows is not yet supported. Spacecap is architected in such a way that it
+ can be cross platform. For Windows support, the audio/video capture interfaces
+ need to be implemented. It's on the roadmap, but is not currently a priority.
+
+## Global Keybinds
+
+### Linux
+
+[xdg-desktop-portal global
+shortcuts](https://wiki.archlinux.org/title/XDG_Desktop_Portal#List_of_backends_and_interfaces)
+can be used if your desktop environment supports it, otherwise the Spacecap CLI
+can be used to send commands.
+
+e.g.
+
+```sh
+# Save replay
+spacecap -s save-replay
+
+# List available commands
+spacecap -h
+```
For example, here is what a config in [niri](https://github.com/YaLTeR/niri) would look like:
@@ -69,20 +86,9 @@ binds {
}
```
-Use `spacecap -h` to see available commands.
-
-### Windows
-
-Windows is not yet supported. Spacecap is architected in such a way
-that it can be cross platform. For Windows support, the audio/video capture
-interfaces need to be implemented. It's on the roadmap, but is not currently
-a priority.
-
## Development
-[Nix](https://nixos.org/download/#download-nix) is required for development,
-unless you want to install all dependencies manually. See `flake.nix` if you'd
-like to do so.
+[Nix](https://nixos.org/download/#download-nix) is required for development.
```sh
# Build
@@ -98,15 +104,10 @@ nix develop -c zig build test -Dnix
## Logging
By default, Spacecap only writes error logs to `error.log`. Set the
-`SPACECAP_LOG_LEVEL` environment variable to one of the following to change this
-behavior:
-
-- debug
-- info
-- warning
-- error
+`SPACECAP_LOG_LEVEL` environment variable to `debug`, `info`, `warning`, or
+`error`.
-Crash logs are written to `crash.log`. This happens when a panic occurs.
+Crash logs are written to `crash.log`, which happens when a panic occurs.
#### Log Location
diff --git a/install.sh b/install.sh
index 508cec3..8167aac 100755
--- a/install.sh
+++ b/install.sh
@@ -152,3 +152,14 @@ else
fi
echo "Installed the desktop entry to $DESKTOP_PATH."
echo "Installed the app icon to $ICON_PATH."
+
+case ":$PATH:" in
+ *:"$INSTALL_DIR":*)
+ ;;
+ *)
+ echo
+ echo "$INSTALL_DIR is not on your PATH."
+ echo "To use the Spacecap CLI, add it to your shell profile, then restart your shell:"
+ echo " export PATH=\"$INSTALL_DIR:\$PATH\""
+ ;;
+esac
diff --git a/src/audio/audio_encoder.zig b/src/audio/audio_encoder.zig
index 695c1ef..8f7bb75 100644
--- a/src/audio/audio_encoder.zig
+++ b/src/audio/audio_encoder.zig
@@ -5,7 +5,7 @@ const ffmpeg = @import("../ffmpeg.zig").ffmpeg;
const checkErr = @import("../ffmpeg.zig").check_err;
// TODO: Make this a user setting.
-const AUDIO_BIT_RATE: i64 = 320_000;
+const AUDIO_BIT_RATE: i64 = 128_000;
pub const EncodedAudioPacketNode = struct {
data: [*c]const ffmpeg.AVPacket,
diff --git a/src/capture/video/linux/pipewire/pipewire_video.zig b/src/capture/video/linux/pipewire/pipewire_video.zig
index 2da021a..e86952f 100644
--- a/src/capture/video/linux/pipewire/pipewire_video.zig
+++ b/src/capture/video/linux/pipewire/pipewire_video.zig
@@ -464,7 +464,11 @@ pub const PipewireVideo = struct {
if (copy_data.vulkan_image_buffer) |vulkan_image_buffer| {
self.vulkan_image_buffer_chan.drain();
self.vulkan_image_buffer_chan.send(vulkan_image_buffer.clone()) catch |err| {
- log.err("[stream_process_callback] vulkan image buffer chan send err: {}", .{err});
+ if (err == ChanError.Closed) {
+ log.debug("[stream_process_callback] vulkan image buffer chan closed", .{});
+ } else {
+ log.err("[stream_process_callback] vulkan image buffer chan send err: {}", .{err});
+ }
};
}
}
diff --git a/src/capture/video/linux/pipewire/vulkan_image_buffer_chan.zig b/src/capture/video/linux/pipewire/vulkan_image_buffer_chan.zig
index 2e122db..22c06ad 100644
--- a/src/capture/video/linux/pipewire/vulkan_image_buffer_chan.zig
+++ b/src/capture/video/linux/pipewire/vulkan_image_buffer_chan.zig
@@ -30,6 +30,7 @@ pub const VulkanImageBufferChan = struct {
/// Increment the buffer ref count, set to in use, then send on the channel.
/// On send error, release the buffer and return the error.
+ /// Takes ownership of vulkan_image_buffer. Clone before passing in.
pub fn send(self: *Self, vulkan_image_buffer: Arc(VulkanImageBuffer)) ChanError!void {
defer vulkan_image_buffer.deinit();
errdefer vulkan_image_buffer.as_ptr().in_use.store(false, .release);
diff --git a/src/vulkan/vulkan_image_buffer.zig b/src/vulkan/vulkan_image_buffer.zig
index feddef0..b970b62 100644
--- a/src/vulkan/vulkan_image_buffer.zig
+++ b/src/vulkan/vulkan_image_buffer.zig
@@ -26,6 +26,8 @@ pub const VulkanImageBuffer = struct {
width: u32,
height: u32,
+ /// This should be true until the image buffer has been released from the
+ /// encode pipeline.
in_use: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
pub const InitArgs = struct {