mirror of
https://github.com/Heretek-Games/flatpark.git
synced 2026-10-12 02:05:52 +00:00
feat(openshot): add OpenShot Video Editor (org.openshot.OpenShot) (#293)
OpenShot ships its Linux build only as an AppImage — no .deb, .rpm or plain tarball — which FlatPark's playbook has so far treated as a hard stop. It is not one: a type-2 AppImage is an ELF stub with a SquashFS image appended, and that image unpacks directly without the AppImage ever being executed or FUSE-mounted. This is the first app to use that route. Packaging: - extra-data, org.freedesktop.Platform//25.08. The AppImage is fully self-contained (its own Python 3.8, PyQt5, libopenshot, FFmpeg, Blender), so no KDE/GNOME runtime is needed — verified nothing in the bundle resolves against the runtime's Qt/Python, and the bundle ships no libGL/EGL/fontconfig to shadow it. - Second extra-data source: flatpark/prebuilt's appimage-tools-v1 (appimage-offset + unsquashfs, 54 KB). apply_extra computes the SquashFS offset from the ELF header and unpacks with unsquashfs -o; the AppImage and the extractor are deleted afterwards. Passes check-apply-extra.sh (root, all caps dropped, offline, /usr + /app/extra only). - Wrapper execs the AppDir's own usr/bin/openshot-qt-launch and pins QT_QPA_PLATFORM=xcb: the bundle ships the Qt5 wayland plugins but not the libQt5WaylandClient.so.5 they link, so wayland cannot initialise and Qt does not fall back on its own. Runs through XWayland. Sandbox: ipc, x11, dri, pulseaudio, network (update check / title templates / AI model download), xdg-videos/pictures/music/download for project footage, and --persist=.openshot_qt so OpenShot's state dir lands in the per-app directory rather than tmpfs or the real home. No --filesystem=home. dangerous_permissions is empty. OpenShot is on Flathub (currently 3.5.1, behind upstream's 4.0.0); this entry is primarily the AppImage-extraction mechanism proven end to end. Claude-Session: https://claude.ai/code/session_016F22CmZ197QR9hW3qiVxQC Co-authored-by: Claude Sonnet 5 <[email protected]>
This commit is contained in:
+58
@@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Runs offline at install time inside org.freedesktop.Platform. Upstream ships
|
||||
# OpenShot for Linux ONLY as an AppImage — no .deb, no .rpm, no plain tarball —
|
||||
# so this repackages that. An AppImage is not a special format: a type-2 one is
|
||||
# an ELF stub with a SquashFS filesystem concatenated after it. It never has to
|
||||
# be executed or FUSE-mounted to read it; the appended filesystem is unpacked
|
||||
# directly.
|
||||
#
|
||||
# Two tools do that, both from the appimage-tools extra-data fetched alongside
|
||||
# the AppImage:
|
||||
# appimage-offset prints the byte offset where the SquashFS begins
|
||||
# unsquashfs unpacks from that offset (gzip/xz/lz4/zstd; OpenShot's is
|
||||
# gzip)
|
||||
#
|
||||
# The result is the AppDir, staged whole at a stable path the wrapper execs:
|
||||
# /app/extra/openshot. Its layout is AppRun + usr/, and usr/bin holds a
|
||||
# self-contained tree — the openshot-qt launcher, its bundled Python/PyQt5/
|
||||
# libopenshot/FFmpeg .so files, Qt plugins, and openshot-qt-launch, the vendor's
|
||||
# own wrapper that sets LD_LIBRARY_PATH / QT_PLUGIN_PATH relative to itself.
|
||||
#
|
||||
# The desktop file, icon, MIME definition and AppStream metainfo are shipped by
|
||||
# the manifest at *build* time — extra-data is fetched later on the user's
|
||||
# machine, so anything Flatpak must export cannot come from here.
|
||||
|
||||
extra_root="${EXTRA_ROOT:-/app/extra}"
|
||||
cd "$extra_root"
|
||||
|
||||
[ -f openshot.AppImage ] || { echo "missing extra-data: openshot.AppImage" >&2; exit 1; }
|
||||
[ -f appimage-tools.tar.xz ] || { echo "missing extra-data: appimage-tools.tar.xz" >&2; exit 1; }
|
||||
|
||||
# --no-same-owner: on a system-wide install Flatpak runs apply_extra as root
|
||||
# with every capability dropped, so restoring an archive's recorded uid/gid
|
||||
# fails and aborts the unpack even though every member extracted fine. Both the
|
||||
# tarball below and unsquashfs (via -no-xattrs, and it never chowns) are safe
|
||||
# under that constraint.
|
||||
bsdtar --no-same-owner -xf appimage-tools.tar.xz
|
||||
tools="$extra_root/appimage-tools/bin"
|
||||
[ -x "$tools/appimage-offset" ] && [ -x "$tools/unsquashfs" ] \
|
||||
|| { echo "appimage-tools stack incomplete" >&2; exit 1; }
|
||||
|
||||
offset="$("$tools/appimage-offset" openshot.AppImage)"
|
||||
case "$offset" in
|
||||
''|*[!0-9]*) echo "appimage-offset did not return a number: '$offset'" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
rm -rf openshot
|
||||
# -no-xattrs: the apply_extra sandbox has all capabilities dropped and cannot
|
||||
# set security xattrs; -d writes straight to the final path, no rename needed.
|
||||
"$tools/unsquashfs" -no-xattrs -o "$offset" -d openshot openshot.AppImage
|
||||
|
||||
[ -x openshot/usr/bin/openshot-qt-launch ] || { echo "openshot-qt-launch missing after unpack" >&2; exit 1; }
|
||||
[ -x openshot/usr/bin/openshot-qt ] || { echo "openshot-qt binary missing after unpack" >&2; exit 1; }
|
||||
|
||||
# Drop the 254 MB AppImage and the extractor now that the tree is staged —
|
||||
# otherwise both sit on the user's disk for the life of the install.
|
||||
rm -rf openshot.AppImage appimage-tools.tar.xz appimage-tools
|
||||
@@ -0,0 +1,23 @@
|
||||
id: org.openshot.OpenShot
|
||||
name: OpenShot Video Editor
|
||||
summary: An easy to use, quick to learn, and surprisingly powerful video editor
|
||||
website: https://www.openshot.org/
|
||||
source_url: https://github.com/OpenShot/openshot-qt
|
||||
build:
|
||||
manifest: org.openshot.OpenShot.yml
|
||||
branch: stable
|
||||
mode: extra-data
|
||||
catalog:
|
||||
category: AudioVideo
|
||||
upstream_approved: false
|
||||
tags:
|
||||
- Video
|
||||
- Editor
|
||||
- Movie
|
||||
- Timeline
|
||||
update:
|
||||
command: ./resolve-update.sh
|
||||
policy:
|
||||
proprietary: false
|
||||
extra_data_first: true
|
||||
dangerous_permissions: []
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
# OpenShot's AppImage already carries the right launch logic in
|
||||
# usr/bin/openshot-qt-launch: it sets LD_LIBRARY_PATH and QT_PLUGIN_PATH to the
|
||||
# bundled tree, selects the xdg-desktop-portal platform theme for native file
|
||||
# dialogs, and points OPENSSL_CONF at /dev/null (the bundle's OpenSSL predates
|
||||
# the host config format). Repackaging only has to call it.
|
||||
#
|
||||
# realpath inside that script resolves to /app/extra/openshot/usr/bin, so the
|
||||
# bundled Python, PyQt5, libopenshot and Qt plugins are all found there without
|
||||
# anything set here.
|
||||
#
|
||||
# QT_QPA_PLATFORM=xcb: the bundle ships the Qt 5 wayland plugins without the
|
||||
# libQt5WaylandClient.so.5 they need, so "wayland" cannot initialise and Qt does
|
||||
# not fall back on its own — it just exits. Pinning xcb runs it through XWayland.
|
||||
# Respect an explicit override so someone who has supplied the missing library
|
||||
# can still try wayland.
|
||||
: "${QT_QPA_PLATFORM:=xcb}"
|
||||
export QT_QPA_PLATFORM
|
||||
|
||||
exec /app/extra/openshot/usr/bin/openshot-qt-launch "$@"
|
||||
@@ -0,0 +1,15 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=OpenShot Video Editor
|
||||
GenericName=Video Editor
|
||||
Comment=Create and edit amazing videos and movies
|
||||
Exec=openshot-qt %F
|
||||
Icon=org.openshot.OpenShot
|
||||
Terminal=false
|
||||
Categories=AudioVideo;AudioVideoEditing;Video;
|
||||
Keywords=video;editor;movie;clip;film;timeline;
|
||||
StartupNotify=true
|
||||
StartupWMClass=openshot-qt
|
||||
X-GNOME-UsesNotifications=true
|
||||
MimeType=application/vnd.openshot-qt-project;
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>org.openshot.OpenShot</id>
|
||||
<launchable type="desktop-id">org.openshot.OpenShot.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0-or-later</project_license>
|
||||
<name>OpenShot Video Editor</name>
|
||||
<summary>An easy to use, quick to learn, and surprisingly powerful video editor</summary>
|
||||
<developer id="org.openshot">
|
||||
<name>OpenShot Studios, LLC</name>
|
||||
</developer>
|
||||
<url type="homepage">https://www.openshot.org/</url>
|
||||
<url type="bugtracker">https://github.com/OpenShot/openshot-qt/issues</url>
|
||||
<url type="help">https://www.openshot.org/user-guide/</url>
|
||||
<url type="donation">https://www.openshot.org/donate/</url>
|
||||
<url type="vcs-browser">https://github.com/OpenShot/openshot-qt</url>
|
||||
<description>
|
||||
<p>This is a community package of OpenShot, maintained independently and unaffiliated with the OpenShot project. It repackages the official upstream AppImage unmodified — extracted at install time, not rebuilt — and follows upstream releases automatically.</p>
|
||||
<p>OpenShot Video Editor is a free, open-source video editor with an easy-to-use interface and a broad feature set for cutting, compositing and animating video.</p>
|
||||
<ul>
|
||||
<li>Supports most video, audio and image formats (based on FFmpeg).</li>
|
||||
<li>Advanced timeline with drag and drop, snapping, scrolling, panning and zooming.</li>
|
||||
<li>Clip trimming, alpha, scaling, rotation, shearing and curve-based keyframe animation (linear, Bézier, constant).</li>
|
||||
<li>Compositing, image overlays, watermarks and transparency, with unlimited tracks and layers.</li>
|
||||
<li>Video transitions, masks and wipes; brightness, gamma, hue and chroma-key effects.</li>
|
||||
<li>Animated 3D titles via a bundled Blender, plus editable SVG titles and credits.</li>
|
||||
<li>Audio mixing, waveforms and editing; time mapping and speed changes.</li>
|
||||
<li>Hardware-accelerated encode and decode; EDL and Final Cut Pro import/export.</li>
|
||||
</ul>
|
||||
<p>Permissions: this package grants read-write access to your Videos, Pictures, Music and Downloads folders, because an OpenShot project (.osp) references its source clips by absolute path and they have to stay reachable when the project is reopened — per-file portal access cannot carry a project across sessions. App state (settings, caches, project backups) stays inside the sandbox. Footage kept elsewhere needs an <code>flatpak override</code>:</p>
|
||||
<ul>
|
||||
<li>Footage or projects in a dedicated folder under home: <code>flatpak override --user --filesystem=~/Projects org.openshot.OpenShot</code> (name your own folder), or <code>--filesystem=home</code> for all of it.</li>
|
||||
<li>Footage on an external drive or another mount point: <code>flatpak override --user --filesystem=/run/media/$USER org.openshot.OpenShot</code> (use the path your system mounts removable media under).</li>
|
||||
<li>Work fully offline with no update check or template/model downloads: <code>flatpak override --user --unshare=network org.openshot.OpenShot</code></li>
|
||||
</ul>
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://www.openshot.org/static/img/gallery/ui-example.jpg</image>
|
||||
<caption>Editing a project on the OpenShot timeline</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://www.openshot.org/static/img/gallery/title-editor.jpg</image>
|
||||
<caption>The title editor</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<categories>
|
||||
<category>AudioVideo</category>
|
||||
<category>AudioVideoEditing</category>
|
||||
</categories>
|
||||
<keywords>
|
||||
<keyword>video</keyword>
|
||||
<keyword>editor</keyword>
|
||||
<keyword>movie</keyword>
|
||||
<keyword>film</keyword>
|
||||
<keyword>timeline</keyword>
|
||||
<keyword>FFmpeg</keyword>
|
||||
</keywords>
|
||||
<releases>
|
||||
<release version="4.0.0" date="2026-07-25"/>
|
||||
</releases>
|
||||
</component>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="application/vnd.openshot-qt-project">
|
||||
<comment>OpenShot project</comment>
|
||||
<glob pattern="*.osp"/>
|
||||
<generic-icon name="openshot-qt-doc"/>
|
||||
</mime-type>
|
||||
</mime-info>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 135 KiB |
@@ -0,0 +1,115 @@
|
||||
id: org.openshot.OpenShot
|
||||
runtime: org.freedesktop.Platform
|
||||
runtime-version: "25.08"
|
||||
sdk: org.freedesktop.Sdk
|
||||
command: openshot-qt
|
||||
separate-locales: false
|
||||
build-options:
|
||||
no-debuginfo: true
|
||||
finish-args:
|
||||
# OpenShot's Linux build is a fully self-contained AppImage: it brings its own
|
||||
# Python 3.8, PyQt5, libopenshot, a complete FFmpeg, and a bundled Blender for
|
||||
# the 3D title templates. Nothing Qt or Python comes from the runtime, so this
|
||||
# is the freedesktop base rather than a KDE or GNOME one. Verified against the
|
||||
# bundle's NEEDED set: everything it does not carry — the display, GL, X11 /
|
||||
# Wayland, fontconfig, NSS and audio stacks — org.freedesktop.Platform 25.08
|
||||
# provides, and the bundle deliberately does NOT ship libGL / libEGL / libgbm
|
||||
# / fontconfig, so there is nothing to shadow the runtime's.
|
||||
- --share=ipc
|
||||
# X11 only. OpenShot's AppImage ships the Qt 5 wayland platform plugins but
|
||||
# not the libQt5WaylandClient.so.5 they link, so the bundle can only bring up
|
||||
# the xcb platform; the wrapper pins QT_QPA_PLATFORM=xcb and it runs through
|
||||
# XWayland on a Wayland session. --socket=fallback-x11 would withhold the X
|
||||
# socket whenever a compositor is present, which is exactly when it is needed
|
||||
# here, so this is a plain --socket=x11.
|
||||
- --socket=x11
|
||||
# A Wayland host session exports QT_QPA_PLATFORM=wayland, which flatpak
|
||||
# forwards into the sandbox and which would beat the wrapper's xcb default.
|
||||
# Drop it here; the wrapper then sets xcb, and `flatpak override
|
||||
# --env=QT_QPA_PLATFORM=…` still wins for anyone who wants to try otherwise.
|
||||
- --unset-env=QT_QPA_PLATFORM
|
||||
# Real-time video preview and the OpenGL compositor; also VA-API / NVDEC for
|
||||
# hardware-accelerated decode and encode.
|
||||
- --device=dri
|
||||
# Preview playback and audio scrubbing.
|
||||
- --socket=pulseaudio
|
||||
# Update check, downloadable title templates, and the model download for the
|
||||
# AI effects (object detection / motion tracking). OpenShot is otherwise a
|
||||
# local editor; withholding this only disables those.
|
||||
- --share=network
|
||||
# OpenShot edits a *project*: an .osp file plus source clips (video, audio,
|
||||
# images) referenced by absolute path, so re-opening a project needs
|
||||
# persistent read access to wherever that footage lives — the file-chooser
|
||||
# portal's per-file grants cannot carry a project across sessions. These are
|
||||
# the standard media locations; footage kept elsewhere (a dedicated projects
|
||||
# folder, an external drive) is an opt-in `flatpak override` documented in the
|
||||
# metainfo. NOT --filesystem=home: OpenShot writes all of its own state to
|
||||
# ~/.openshot_qt (classes/info.py: USER_PATH = expanduser("~") +
|
||||
# "/.openshot_qt"), and granting home or host would repoint $HOME at the real
|
||||
# home and create that directory there instead of in the sandbox. With only
|
||||
# these xdg subdirectories granted, $HOME stays the per-app directory and the
|
||||
# state lives under ~/.var/app/org.openshot.OpenShot.
|
||||
- --filesystem=xdg-videos
|
||||
- --filesystem=xdg-pictures
|
||||
- --filesystem=xdg-music
|
||||
- --filesystem=xdg-download
|
||||
# Flatpak does not redirect $HOME — it stays /home/<user> and, with no home
|
||||
# grant, is a tmpfs that is discarded on exit. OpenShot puts everything under
|
||||
# ~/.openshot_qt (expanduser("~") in classes/info.py), so without this its
|
||||
# settings, keyframe presets, project backups and the autosave file would not
|
||||
# survive a restart. --persist binds ~/.openshot_qt to
|
||||
# ~/.var/app/org.openshot.OpenShot/.openshot_qt — persistent, and inside the
|
||||
# sandbox rather than in the user's real home. (This works precisely because
|
||||
# no broader --filesystem=home mount is present to shadow it.)
|
||||
- --persist=.openshot_qt
|
||||
# "Export complete" / error notifications.
|
||||
- --talk-name=org.freedesktop.Notifications
|
||||
modules:
|
||||
- name: openshot
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- install -Dm755 apply_extra.sh /app/bin/apply_extra
|
||||
- install -Dm755 openshot-wrapper /app/bin/openshot-qt
|
||||
- install -Dm644 org.openshot.OpenShot.desktop /app/share/applications/org.openshot.OpenShot.desktop
|
||||
- install -Dm644 org.openshot.OpenShot.metainfo.xml /app/share/metainfo/org.openshot.OpenShot.metainfo.xml
|
||||
# OpenShot's own MIME definition for .osp projects, so the exported desktop
|
||||
# entry can match them on the host.
|
||||
- install -Dm644 org.openshot.OpenShot.mime.xml /app/share/mime/packages/org.openshot.OpenShot.xml
|
||||
- install -Dm644 org.openshot.OpenShot.png /app/share/icons/hicolor/512x512/apps/org.openshot.OpenShot.png
|
||||
sources:
|
||||
# The two-tool stack that lets apply_extra open the AppImage offline with
|
||||
# no libfuse: appimage-offset prints the appended-SquashFS byte offset and
|
||||
# unsquashfs unpacks from it. Fetched next to the AppImage into /app/extra
|
||||
# rather than staged at /app/bin, because a system-wide install runs
|
||||
# apply_extra in a sandbox that binds only the runtime /usr and /app/extra
|
||||
# (scripts/check-apply-extra.sh reproduces this). Kept OUTSIDE the managed
|
||||
# block: update-pins.mjs rebuilds that block from the resolver output and
|
||||
# would drop anything else in it.
|
||||
- type: extra-data
|
||||
filename: appimage-tools.tar.xz
|
||||
only-arches:
|
||||
- x86_64
|
||||
url: https://github.com/flatpark/prebuilt/releases/download/appimage-tools-v1/appimage-tools-appimage-tools-v1-fd-25.08-x86_64.tar.xz
|
||||
sha256: fdbaf3b8dfa1e9705c644dafeb25b6afcd7890af36ae23744e58130beb48396b
|
||||
size: 54752
|
||||
# BEGIN MANAGED EXTRA-DATA
|
||||
- type: extra-data
|
||||
filename: openshot.AppImage
|
||||
only-arches:
|
||||
- x86_64
|
||||
url: https://github.com/OpenShot/openshot-qt/releases/download/v4.0.0/OpenShot-v4.0.0-x86_64.AppImage
|
||||
sha256: 277b27aae97080a1dae8831be8c6d2c576377292f559fb1b94675f6db24aa70f
|
||||
size: 254457024
|
||||
# END MANAGED EXTRA-DATA
|
||||
- type: file
|
||||
path: apply_extra.sh
|
||||
- type: file
|
||||
path: openshot-wrapper
|
||||
- type: file
|
||||
path: org.openshot.OpenShot.desktop
|
||||
- type: file
|
||||
path: org.openshot.OpenShot.metainfo.xml
|
||||
- type: file
|
||||
path: org.openshot.OpenShot.mime.xml
|
||||
- type: file
|
||||
path: org.openshot.OpenShot.png
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Update resolver for OpenShot.
|
||||
#
|
||||
# Prints the current version + the Linux x86_64 AppImage as JSON on stdout:
|
||||
# { "version": "4.0.0", "releaseDate": "YYYY-MM-DD",
|
||||
# "sources": [ { "filename": "openshot.AppImage", "url": "..." } ] }
|
||||
# Logs go to stderr. No hashing, no manifest rewriting — FlatPark downloads the
|
||||
# URL and computes the extra-data sha256/size at build time. The version is
|
||||
# compared against the latest <release> in the AppStream metainfo.
|
||||
#
|
||||
# Only openshot.AppImage is resolved here; appimage-tools.tar.xz is pinned
|
||||
# by hand outside the managed block in the manifest.
|
||||
set -euo pipefail
|
||||
|
||||
repo="OpenShot/openshot-qt"
|
||||
|
||||
need() { command -v "$1" >/dev/null 2>&1 || { echo "missing command: $1" >&2; exit 1; }; }
|
||||
need curl; need jq
|
||||
|
||||
# releases/latest excludes prereleases and drafts, so this tracks the stable
|
||||
# channel OpenShot publishes its AppImage on.
|
||||
rel="$(curl -fsSL ${GITHUB_TOKEN:+-H "Authorization: Bearer $GITHUB_TOKEN"} \
|
||||
"https://api.github.com/repos/$repo/releases/latest")"
|
||||
|
||||
version="$(jq -r '.tag_name | ltrimstr("v")' <<<"$rel")"
|
||||
date="$(jq -r '.published_at' <<<"$rel" | cut -c1-10)"
|
||||
# The lone x86_64 AppImage asset: OpenShot-v<version>-x86_64.AppImage (the other
|
||||
# assets are the .exe / .dmg installers and the .torrent / .sha256sum sidecars).
|
||||
url="$(jq -r '.assets[] | select(.name | test("-x86_64\\.AppImage$")) | .browser_download_url' <<<"$rel" | head -n1)"
|
||||
|
||||
[ -n "$version" ] && [ -n "$url" ] || { echo "failed to resolve openshot release" >&2; exit 1; }
|
||||
echo "resolved openshot $version ($date): $url" >&2
|
||||
|
||||
jq -n --arg v "$version" --arg d "$date" --arg u "$url" \
|
||||
'{version:$v, releaseDate:$d, sources:[{filename:"openshot.AppImage", url:$u}]}'
|
||||
Reference in New Issue
Block a user