Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
70ec155
Add JUCE audio recorder and fix FFmpegWriter FLAC duration
jonoomph May 28, 2026
3e9de94
Reverting changes to python detection in libopenshot, so we don't bre…
jonoomph May 29, 2026
8bae3af
Add Linux screen and camera capture readers
jonoomph Jun 16, 2026
5f49df8
Add Wayland screen capture backend
jonoomph Jun 17, 2026
1e75b9d
Refine Wayland portal capture handling
jonoomph Jun 17, 2026
9660b5c
Handle Wayland cropped window streams
jonoomph Jun 17, 2026
caae5b5
Request Wayland stream crop metadata
jonoomph Jun 17, 2026
1cde209
Add Windows capture backends for recording
jonoomph Jun 20, 2026
4eebfe8
Drop invalid Wayland PipeWire capture frames
jonoomph Jun 20, 2026
a8191a0
Fix recording build compatibility
jonoomph Jun 20, 2026
2034b34
Support older FFmpeg avdevice headers
jonoomph Jun 20, 2026
d1fbd83
Support older FFmpeg input format API
jonoomph Jun 20, 2026
4c100e0
Enumerate DirectShow cameras with COM
jonoomph Jun 20, 2026
ac3baf5
Fix Windows capture frame buffer cleanup
jonoomph Jun 20, 2026
325beed
Allow capture devices to use default modes
jonoomph Jun 21, 2026
2c18616
Enable macOS AVFoundation capture backends
jonoomph Jun 21, 2026
2abd35e
Harden macOS AVFoundation screen defaults
jonoomph Jun 21, 2026
9e8d226
Preserve live capture timing gaps
jonoomph Jun 22, 2026
b575dbb
Fix recording waveform and mac screen crop capture
jonoomph Jun 24, 2026
7a71278
Use full display size for mac crop capture
jonoomph Jun 24, 2026
b18c147
Interrupt blocking screen capture reads on close
jonoomph Jun 24, 2026
98f797d
Add timer effect
jonoomph Jun 26, 2026
d3e3c6b
Fix live screen capture startup on macOS
jonoomph Jun 26, 2026
60c4359
Add clip margin and corner radius support
jonoomph Jun 28, 2026
4898073
Preserve live capture timestamps
jonoomph Jun 28, 2026
3b6291f
Fix frame timestamp test compatibility
jonoomph Jun 28, 2026
46a5c2c
Add system audio to screen capture
jonoomph Jul 19, 2026
2547c82
Fix MinGW Core Audio GUID linking
jonoomph Jul 19, 2026
114f25a
Synchronize initial system audio capture
jonoomph Jul 19, 2026
a2709d5
Install FFmpeg avdevice in GitHub CI
jonoomph Jul 22, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
cmake swig doxygen graphviz curl lcov \
libasound2-dev \
qtbase5-dev qtbase5-dev-tools libqt5svg5-dev \
libfdk-aac-dev libavcodec-dev libavformat-dev \
libfdk-aac-dev libavcodec-dev libavdevice-dev libavformat-dev \
libavutil-dev libswscale-dev libswresample-dev \
libzmq3-dev libbabl-dev \
libopencv-dev libprotobuf-dev protobuf-compiler \
Expand Down
7 changes: 6 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ linux-builder:
- export LD_LIBRARY_PATH="$OPENCV_ROOT/lib:$LD_LIBRARY_PATH"
- export PATH="$OPENCV_ROOT/bin:$PATH"
- mkdir -p build; cd build;
- cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -D"OpenCV_DIR:PATH=$OpenCV_DIR" -D"PYTHON_MODULE_PATH=python" -D"RUBY_MODULE_PATH=ruby" -DCMAKE_BUILD_TYPE:STRING=Release -DAPPIMAGE_BUILD=1 -DUSE_SYSTEM_JSONCPP=0 ../
- pkg-config --exists libpipewire-0.3 libspa-0.2 gio-2.0 gio-unix-2.0 || echo "WARNING PipeWire Wayland capture dependencies are missing; building without Wayland capture support"
- cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -D"OpenCV_DIR:PATH=$OpenCV_DIR" -D"PYTHON_MODULE_PATH=python" -D"RUBY_MODULE_PATH=ruby" -DCMAKE_BUILD_TYPE:STRING=Release -DAPPIMAGE_BUILD=1 -DUSE_SYSTEM_JSONCPP=0 -DENABLE_WAYLAND_CAPTURE=ON ../
- cmake --build . --parallel $(nproc)
- make install
- ctest --output-on-failure -VV
Expand Down Expand Up @@ -104,6 +105,8 @@ windows-builder-x64:
- $env:OpenCV_DIR = "$env:OPENCV_ROOT\lib\cmake\opencv4"
- $env:Path = "$env:OPENCV_ROOT\bin;C:\msys64\mingw64\bin;C:\msys64\usr\bin;C:\msys64\usr\local\bin;" + $env:Path;
- $env:MSYSTEM = "MINGW64"
- ffmpeg -hide_banner -devices | findstr /I "gdigrab"
- ffmpeg -hide_banner -devices | findstr /I "dshow"
- cmake -B build -S . -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"babl_DIR=C:/msys64/mingw64" -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR\build\install-x64" -D"OpenShotAudio_ROOT=$CI_PROJECT_DIR\build\install-x64" -D"OpenCV_DIR:PATH=$env:OpenCV_DIR" -D"PYTHON_MODULE_PATH=python" -D"RUBY_MODULE_PATH=ruby" -G "MinGW Makefiles" -D"CMAKE_BUILD_TYPE:STRING=Release"
- cmake --build build --parallel $([Environment]::ProcessorCount)
- ctest --test-dir build --output-on-failure -VV
Expand Down Expand Up @@ -133,6 +136,8 @@ windows-builder-x86:
- $env:OpenCV_DIR = "$env:OPENCV_ROOT\lib\cmake\opencv4"
- $env:Path = "$env:OPENCV_ROOT\bin;C:\msys64\mingw32\bin;C:\msys64\usr\bin;C:\msys64\usr\local\bin;" + $env:Path;
- $env:MSYSTEM = "MINGW32"
- ffmpeg -hide_banner -devices | findstr /I "gdigrab"
- ffmpeg -hide_banner -devices | findstr /I "dshow"
- cmake -B build -S . -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"babl_DIR=C:/msys64/mingw32" -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR\build\install-x86" -D"OpenShotAudio_ROOT=$CI_PROJECT_DIR\build\install-x86" -D"OpenCV_DIR:PATH=$env:OpenCV_DIR" -D"PYTHON_MODULE_PATH=python" -D"RUBY_MODULE_PATH=ruby" -G "MinGW Makefiles" -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_CXX_FLAGS=-m32" -D"CMAKE_EXE_LINKER_FLAGS=-Wl,--large-address-aware" -D"CMAKE_C_FLAGS=-m32"
- cmake --build build --parallel $([Environment]::ProcessorCount)
- cmake --install build
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ option(USE_SYSTEM_JSONCPP "Use system installed JsonCpp, if found" ON)
option(DISABLE_BUNDLED_JSONCPP "Don't fall back to bundled JsonCpp" OFF)
option(ENABLE_MAGICK "Use ImageMagick, if available" ON)
option(ENABLE_OPENCV "Build with OpenCV algorithms (requires Boost, Protobuf 3)" ON)
option(ENABLE_WAYLAND_CAPTURE "Build Wayland screen capture support with xdg-desktop-portal and PipeWire (Linux only)" ON)
option(USE_HW_ACCEL "Enable hardware-accelerated encoding-decoding with FFmpeg 3.4+" ON)
option(ENABLE_VULKAN_BENCHMARK "Build the experimental Vulkan benchmark example" OFF)

Expand Down
1 change: 1 addition & 0 deletions bindings/java/openshot.i
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ typedef struct OpenShotByteBuffer {
%include "effects/Sharpen.h"
%include "effects/Shift.h"
%include "effects/SphericalProjection.cpp"
%include "effects/Timer.h"
%include "effects/DenoiseImage.h"
%include "effects/Wave.h"
#ifdef USE_OPENCV
Expand Down
19 changes: 5 additions & 14 deletions bindings/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,13 @@ if (POLICY CMP0086)
cmake_policy(SET CMP0086 NEW)
endif()

if (CMAKE_VERSION VERSION_LESS 3.12)
find_package(PythonInterp 3)
find_package(PythonLibs 3)
else()
find_package(Python3 3 COMPONENTS Interpreter Development)
if (Python3_FOUND)
set(PYTHON_EXECUTABLE "${Python3_EXECUTABLE}")
set(PYTHON_INCLUDE_PATH "${Python3_INCLUDE_DIRS}")
set(PYTHON_LIBRARIES "${Python3_LIBRARIES}")
set(PYTHON_VERSION_MAJOR "${Python3_VERSION_MAJOR}")
set(PYTHON_VERSION_MINOR "${Python3_VERSION_MINOR}")
set(PYTHONINTERP_FOUND TRUE)
set(PYTHONLIBS_FOUND TRUE)
endif()
if (POLICY CMP0148)
cmake_policy(SET CMP0148 OLD)
endif()

find_package(PythonInterp 3)
find_package(PythonLibs 3)

if (NOT PYTHONLIBS_FOUND OR NOT PYTHONINTERP_FOUND)
return()
endif()
Expand Down
7 changes: 7 additions & 0 deletions bindings/python/openshot.i
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ class QWidget;
#include "ReaderBase.h"
#include "WriterBase.h"
#include "AudioDevices.h"
#include "AudioRecorder.h"
#include "AudioWaveformer.h"
#include "CameraCaptureReader.h"
#include "CacheBase.h"
#include "CacheDisk.h"
#include "CacheMemory.h"
Expand All @@ -101,6 +103,7 @@ class QWidget;
#include "PlayerBase.h"
#include "Point.h"
#include "Profiles.h"
#include "ScreenCaptureReader.h"
#include "QtHtmlReader.h"
#include "QtImageReader.h"
#include "QtPlayer.h"
Expand Down Expand Up @@ -480,7 +483,9 @@ static int openshot_swig_is_qwidget(PyObject *obj) {
%include "ReaderBase.h"
%include "WriterBase.h"
%include "AudioDevices.h"
%include "AudioRecorder.h"
%include "AudioWaveformer.h"
%include "CameraCaptureReader.h"
%include "CacheBase.h"
%include "CacheDisk.h"
%include "CacheMemory.h"
Expand All @@ -506,6 +511,7 @@ static int openshot_swig_is_qwidget(PyObject *obj) {
%include "PlayerBase.h"
%include "Point.h"
%include "Profiles.h"
%include "ScreenCaptureReader.h"
%include "QtHtmlReader.h"
%include "QtImageReader.h"
%include "QtPlayer.h"
Expand Down Expand Up @@ -551,6 +557,7 @@ static int openshot_swig_is_qwidget(PyObject *obj) {
%include "effects/Sharpen.h"
%include "effects/Shift.h"
%include "effects/SphericalProjection.cpp"
%include "effects/Timer.h"
%include "effects/DenoiseImage.h"
%include "effects/Wave.h"
#ifdef USE_OPENCV
Expand Down
1 change: 1 addition & 0 deletions bindings/ruby/openshot.i
Original file line number Diff line number Diff line change
Expand Up @@ -297,5 +297,6 @@ typedef struct OpenShotByteBuffer {
%include "effects/Pixelate.h"
%include "effects/Saturation.h"
%include "effects/Shift.h"
%include "effects/Timer.h"
%include "effects/DenoiseImage.h"
%include "effects/Wave.h"
9 changes: 9 additions & 0 deletions doc/INSTALL-LINUX.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ list below to help distinguish between them.
* http://www.ffmpeg.org/ `(Library)`
* This library is used to decode and encode video, audio, and image files. It is also used to obtain information about media files, such as frame rate, sample rate, aspect ratio, and other common attributes.

### PipeWire and xdg-desktop-portal (libpipewire, libspa, GIO)
* https://pipewire.org/ `(Library)`
* https://flatpak.github.io/xdg-desktop-portal/ `(Runtime Service)`
* These libraries and services are used for Wayland screen capture. The development packages are needed at build time, and a desktop portal implementation must be available at runtime.

### ImageMagick++ (libMagick++, libMagickWand, libMagickCore)
* http://www.imagemagick.org/script/magick++.php `(Library)`
* This library is **optional**, and used to decode and encode images.
Expand Down Expand Up @@ -154,6 +159,8 @@ software packages available to download and install.
libjsoncpp-dev \
libmagick++-dev \
libopenshot-audio-dev \
libpipewire-0.3-dev \
libspa-0.2-dev \
libswscale-dev \
libunittest++-dev \
libxcursor-dev \
Expand All @@ -165,6 +172,8 @@ software packages available to download and install.
qtbase5-dev \
qtmultimedia5-dev \
swig \
xdg-desktop-portal \
xdg-desktop-portal-gtk \
python3-zmq \
python3-pyqt5.qtwebengine

Expand Down
21 changes: 21 additions & 0 deletions src/AudioDevices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,24 @@ AudioDeviceList AudioDevices::getNames() {
}
return m_devices;
}

// Build a list of audio input devices found, and return
AudioDeviceList AudioDevices::getInputNames() {
// A temporary device manager, used to scan device names.
// Its initialize() is never called, and devices are not opened.
std::unique_ptr<juce::AudioDeviceManager>
manager(new juce::AudioDeviceManager());

m_devices.clear();

auto &types = manager->getAvailableDeviceTypes();
for (auto* t : types) {
t->scanForDevices();
const auto names = t->getDeviceNames(true);
for (const auto& name : names) {
m_devices.emplace_back(
name.toStdString(), t->getTypeName().toStdString());
}
}
return m_devices;
}
3 changes: 3 additions & 0 deletions src/AudioDevices.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class AudioDevices
/// Return a vector of std::pair<> objects holding the
/// device name and type for each audio device detected
AudioDeviceList getNames();

/// Return only audio input devices, for recording workflows
AudioDeviceList getInputNames();
private:
AudioDeviceList m_devices;
};
Expand Down
Loading
Loading