Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/build-linux-packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Build Linux packages (.deb / .tar.xz)

on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Release version to package (e.g. 2.5.1)'
required: true

permissions:
contents: write

jobs:
build-linux-packages:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install packaging tools
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq unzip xz-utils dpkg-dev

- name: Resolve version
id: version
run: |
VERSION="${{ inputs.version }}"
if [ -z "$VERSION" ]; then
VERSION="${GITHUB_REF_NAME#v}"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Download official Linux zip
run: |
VERSION="${{ steps.version.outputs.version }}"
mkdir -p /tmp/droidcam
URL="$(gh api repos/dev47apps/droidcam-obs-plugin/releases/tags/$VERSION \
--jq '.assets[] | select(.name | test("linux")) | .browser_download_url' \
2>/dev/null | head -1)"
if [ -z "$URL" ]; then
URL="https://github.com/dev47apps/droidcam-obs-plugin/releases/download/$VERSION/droidcam_obs_${VERSION}_linux_x86_64.zip"
fi
echo "Downloading $URL"
for i in 1 2 3 4 5 6; do
if curl -fsSL -o /tmp/droidcam/plugin.zip "$URL"; then
break
fi
echo "download attempt $i failed, retrying in 20s"
sleep 20
done
test -s /tmp/droidcam/plugin.zip || {
echo "error: failed to download the official Linux zip"
exit 1
}
ls -lh /tmp/droidcam/plugin.zip

- name: Unpack and build packages
run: |
VERSION="${{ steps.version.outputs.version }}"
mkdir -p /tmp/droidcam/unpacked
unzip -o /tmp/droidcam/plugin.zip -d /tmp/droidcam/unpacked
packaging/build-linux.sh /tmp/droidcam/unpacked "$VERSION"

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: droidcam-obs-linux-packages
path: dist/*

- name: Attach to GitHub Release
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
with:
files: dist/*
40 changes: 40 additions & 0 deletions packaging/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Linux packaging (.deb / .tar.xz)

Repackages the official DroidCam OBS Linux zip into a Debian package and a
generic .tar.xz, without compiling anything.

## How it works

The workflow triggers when a GitHub Release is published (or manually, with a
version input), downloads the official Linux zip from the release assets,
unpacks it, and runs `packaging/build-linux.sh`:

- `droidcam-obs_<version>_amd64.deb` installs the plugin into the system OBS
plugin directories (binary in `/usr/lib/x86_64-linux-gnu/obs-plugins`, data
in `/usr/share/obs/obs-plugins/droidcam-obs`).
- `droidcam-obs-<version>-linux-x86_64.tar.xz` mirrors the zip layout plus
`install.sh`, `README.TXT` and `LICENSE` when present.

Because the artifacts are built from the official release binary, there are no
compiler dependencies, no library name pinning, and no risk of the built
plugin silently diverging from what the maintainers tested. If upstream ever
renames or drops the Linux zip, the workflow fails loudly at the download
step.

## Building locally

No build dependencies are required. Download the official zip, unpack it, and
run the script from the repo root:

curl -LO https://github.com/dev47apps/droidcam-obs-plugin/releases/download/2.5.1/droidcam_obs_2.5.1_linux_x86_64.zip
unzip -o droidcam_obs_2.5.1_linux_x86_64.zip -d unpacked
packaging/build-linux.sh unpacked 2.5.1

Artifacts are written to `dist/`.

## Notes

- The plugin is a library that OBS loads from its plugins directory, not a
standalone application, so AppImage is not a natural format for it.
- Fedora ships its own RPM (`obs-studio-plugin-droidcam`) and Arch has AUR
packages, so this packaging targets Debian/Ubuntu plus a manual fallback.
87 changes: 87 additions & 0 deletions packaging/build-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash
#
# Repackages the official DroidCam OBS Linux zip into a Debian package (.deb)
# and a generic .tar.xz. No compilation is involved.
#
# Usage: packaging/build-linux.sh <extracted-zip-dir> <version>
# <extracted-zip-dir> directory that contains droidcam-obs/ with
# bin/64bit/droidcam-obs.so and data/
# <version> release version, e.g. 2.5.1
#
# Outputs are written to ./dist/ (relative to the current directory):
# droidcam-obs_<version>_amd64.deb
# droidcam-obs-<version>-linux-x86_64.tar.xz

set -euo pipefail

ZIP_DIR="${1:?usage: build-linux.sh <extracted-zip-dir> <version>}"
VERSION="${2:?usage: build-linux.sh <extracted-zip-dir> <version>}"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PKG_NAME="droidcam-obs"
ARCH="amd64"
PLUGIN_DIR="$ZIP_DIR/droidcam-obs"
PLUGIN_SO="$PLUGIN_DIR/bin/64bit/droidcam-obs.so"
DATA_DIR="$PLUGIN_DIR/data"
LIB_DIR="/usr/lib/x86_64-linux-gnu/obs-plugins"
DATA_INSTALL_DIR="/usr/share/obs/obs-plugins/$PKG_NAME"
DOC_DIR="/usr/share/doc/$PKG_NAME"

if [[ ! -f "$PLUGIN_SO" ]]; then
echo "error: $PLUGIN_SO not found (did you unpack the official Linux zip?)" >&2
exit 1
fi
if [[ ! -d "$DATA_DIR" ]]; then
echo "error: $DATA_DIR not found" >&2
exit 1
fi

OUT_DIR="$PWD/dist"
STAGE="$(mktemp -d)"
trap 'rm -rf "$STAGE"' EXIT

DEB_ROOT="$STAGE/deb"
TXZ_ROOT="$STAGE/txz/droidcam-obs-$VERSION"

mkdir -p "$DEB_ROOT/DEBIAN" "$DEB_ROOT$LIB_DIR" "$DEB_ROOT$DATA_INSTALL_DIR/locale" "$DEB_ROOT$DOC_DIR" "$TXZ_ROOT/droidcam-obs/bin/64bit" "$TXZ_ROOT/droidcam-obs/data"

# Binary plugin
cp "$PLUGIN_SO" "$DEB_ROOT$LIB_DIR/droidcam-obs.so"
cp "$PLUGIN_SO" "$TXZ_ROOT/droidcam-obs/bin/64bit/droidcam-obs.so"

# Plugin data (icons, locale)
cp -R "$DATA_DIR/." "$DEB_ROOT$DATA_INSTALL_DIR/"
cp -R "$DATA_DIR/." "$TXZ_ROOT/droidcam-obs/data/"

# Keep the generic tarball self-contained, mirroring the official zip
for f in install.sh README.TXT LICENSE; do
if [[ -f "$ZIP_DIR/$f" ]]; then
cp "$ZIP_DIR/$f" "$TXZ_ROOT/"
fi
done

# Debian metadata
{
echo "droidcam-obs ($VERSION) unstable; urgency=medium"
echo ""
echo " * $VERSION release package."
echo " - Installs droidcam-obs.so into the system OBS plugins directory"
echo " - Installs plugin data (icons, locale) into /usr/share/obs/obs-plugins"
echo ""
echo " -- DroidCam OBS Plugin contributors <support@dev47apps.com> $(date -R)"
} > "$DEB_ROOT$DOC_DIR/changelog"
gzip -9n "$DEB_ROOT$DOC_DIR/changelog"
cp "$SCRIPT_DIR/debian/copyright" "$DEB_ROOT$DOC_DIR/copyright"
sed "s/@VERSION@/$VERSION/" "$SCRIPT_DIR/debian/control.in" > "$DEB_ROOT/DEBIAN/control"

# Normalize package permissions (dpkg-deb otherwise preserves the build umask)
find "$DEB_ROOT" -type d -exec chmod 755 {} +
find "$DEB_ROOT" -type f ! -name 'droidcam-obs.so' -exec chmod 644 {} +
chmod 755 "$DEB_ROOT$LIB_DIR/droidcam-obs.so"

mkdir -p "$OUT_DIR"
dpkg-deb --build --root-owner-group "$DEB_ROOT" "$OUT_DIR/${PKG_NAME}_${VERSION}_${ARCH}.deb" >/dev/null
tar -C "$STAGE/txz" -cJf "$OUT_DIR/${PKG_NAME}-${VERSION}-linux-x86_64.tar.xz" "droidcam-obs-$VERSION"

echo "Built:"
ls -lh "$OUT_DIR"
12 changes: 12 additions & 0 deletions packaging/debian/control.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Package: droidcam-obs
Version: @VERSION@
Section: video
Priority: optional
Architecture: amd64
Maintainer: DroidCam OBS Plugin contributors <support@dev47apps.com>
Depends: obs-studio (>= 30.0), libstdc++6
Recommends: adb, usbmuxd
Description: Use your phone as a camera source in OBS Studio
DroidCam turns your Android or iOS phone into a wireless or USB camera
for OBS Studio, with support for HD video at up to 4K.
Homepage: https://droidcam.app/obs/
22 changes: 22 additions & 0 deletions packaging/debian/copyright
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: DroidCam OBS Plugin
Source: https://github.com/dev47apps/droidcam-obs-plugin

Files: *
Copyright: 2022 DEV47APPS
License: GPL-2.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

The complete text of the GNU General Public License version 2 can be
found in /usr/share/common-licenses/GPL-2.