Skip to content
Merged
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
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,13 @@ jobs:
if: ${{ runner.os == 'linux' }}
run: |
sudo apt update
sudo apt remove libzmq5 # See actions/virtual-environments#3317
sudo apt install \
cmake swig doxygen graphviz curl lcov \
libasound2-dev \
qtbase5-dev qtbase5-dev-tools libqt5svg5-dev \
libfdk-aac-dev libavcodec-dev libavdevice-dev libavformat-dev \
libavutil-dev libswscale-dev libswresample-dev \
libzmq3-dev libbabl-dev \
libbabl-dev \
libopencv-dev libprotobuf-dev protobuf-compiler \
cargo libomp5 libomp-dev

Expand Down
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ windows-builder-x64:
- Expand-Archive -Path artifacts.zip -DestinationPath .
- $env:OPENCV_ROOT = "C:\msys64\mingw64\opencv-4.13.0"
- $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:Path = "$env:OPENCV_ROOT\x64\mingw\bin;$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"
Expand Down
6 changes: 0 additions & 6 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ Libraries and executables have been labeled in the list below to help distinguis
apply image effects, and many other utility functions,
such as file system manipulation, high resolution timers, etc.

#### ZeroMQ (libzmq)
* <http://zeromq.org/> **(Library)**

* This library is used to communicate between libopenshot and other applications (publisher / subscriber).
Primarily used to send debug data from libopenshot.

#### OpenMP (`-fopenmp`)
* <http://openmp.org/wp/> **(Compiler Flag)**

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Please see [`doc/HW-ACCEL.md`](doc/HW-ACCEL.md) for more information.

## Documentation

See [Logging](doc/logging.rst) for file output, verbosity, and environment settings.

Beautiful HTML documentation can be generated using Doxygen.
```
make doc
Expand Down
4 changes: 2 additions & 2 deletions bindings/java/openshot.i
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ typedef struct OpenShotByteBuffer {
#include "TimelineBase.h"
#include "Timeline.h"
#include "Qt/VideoCacheThread.h"
#include "ZmqLogger.h"
#include "Logger.h"
%}

// Prevent SWIG from ever generating a wrapper for juce::Thread’s constructor (or run())
Expand Down Expand Up @@ -235,7 +235,7 @@ typedef struct OpenShotByteBuffer {
%include "TimelineBase.h"
%include "Qt/VideoCacheThread.h"
%include "Timeline.h"
%include "ZmqLogger.h"
%include "Logger.h"

#ifdef USE_IMAGEMAGICK
%include "ImageReader.h"
Expand Down
12 changes: 12 additions & 0 deletions bindings/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,15 @@ install(TARGETS ${_pyopenshot_target}
DESTINATION ${PYTHON_MODULE_PATH} )
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openshot.py
DESTINATION ${PYTHON_MODULE_PATH} )

if(BUILD_TESTING)
add_test(NAME Logger:PythonEnvironment
COMMAND ${CMAKE_COMMAND} -E env
"PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
"OPENSHOT_TEST_MODULE_DIR=$<TARGET_FILE_DIR:${_pyopenshot_target}>"
"OPENSHOT_TEST_DLL_DIR=$<TARGET_FILE_DIR:openshot>"
# The Windows build copies libopenshot-audio.dll into the tests directory.
"OPENSHOT_TEST_AUDIO_DLL_DIR=${PROJECT_BINARY_DIR}/tests"
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/test_logger.py")
set_tests_properties(Logger:PythonEnvironment PROPERTIES LABELS Logger)
endif()
9 changes: 7 additions & 2 deletions bindings/python/openshot.i
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class QWidget;
#include "TimelineBase.h"
#include "Timeline.h"
#include "Qt/VideoCacheThread.h"
#include "ZmqLogger.h"
#include "Logger.h"
#include <QtWidgets/QWidget>

static void *openshot_swig_pylong_as_ptr(PyObject *obj) {
Expand Down Expand Up @@ -523,7 +523,7 @@ static int openshot_swig_is_qwidget(PyObject *obj) {
%include "TimelineBase.h"
%include "Qt/VideoCacheThread.h"
%include "Timeline.h"
%include "ZmqLogger.h"
%include "Logger.h"

#ifdef USE_OPENCV
%include "ClipProcessingJobs.h"
Expand Down Expand Up @@ -566,3 +566,8 @@ static int openshot_swig_is_qwidget(PyObject *obj) {
%include "effects/ObjectDetection.h"
%include "effects/Outline.h"
#endif

%pythoncode %{
# Deprecated source compatibility alias (no networking).
ZmqLogger = Logger
%}
131 changes: 131 additions & 0 deletions bindings/python/test_logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# SPDX-FileCopyrightText: 2026 OpenShot Studios, LLC
# SPDX-License-Identifier: LGPL-3.0-or-later

"""Exercise native logger configuration in fresh processes through SWIG."""
import os
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest


class NativeLoggerTests(unittest.TestCase):
def run_logger(self, variables, body=''):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / 'native-é.log'
env = {key: value for key, value in os.environ.items()
if not key.startswith(('OPENSHOT_LOG_', 'LIBOPENSHOT_LOG_'))
and key != 'LIBOPENSHOT_DEBUG'}
env.update(variables, LIBOPENSHOT_LOG_FILE=str(path))
module_dir = env.get('OPENSHOT_TEST_MODULE_DIR')
if module_dir:
env['PYTHONPATH'] = module_dir + os.pathsep + env.get('PYTHONPATH', '')
if os.name == 'nt':
# Older MinGW Python uses PATH and ignores add_dll_directory().
dll_dirs = [env[key] for key in (
'OPENSHOT_TEST_DLL_DIR', 'OPENSHOT_TEST_AUDIO_DLL_DIR')
if env.get(key)]
env['PATH'] = os.pathsep.join(dll_dirs + [env.get('PATH', '')])
result = subprocess.run([sys.executable, '-c', '''
import os
_dll_handles = []
if os.name == 'nt' and hasattr(os, 'add_dll_directory'):
# Modern Python does not search PATH for extension-module dependencies.
# Include the project DLLs and the dependency directories supplied by CI.
_dll_dirs = [os.environ.get('OPENSHOT_TEST_DLL_DIR', ''),
os.environ.get('OPENSHOT_TEST_AUDIO_DLL_DIR', '')]
_dll_dirs.extend(os.environ.get('PATH', '').split(os.pathsep))
_seen = set()
for _directory in _dll_dirs:
_directory = _directory.strip('"')
if not _directory or not os.path.isdir(_directory):
continue
_directory = os.path.abspath(_directory)
_key = os.path.normcase(_directory)
if _key not in _seen:
_dll_handles.append(os.add_dll_directory(_directory))
_seen.add(_key)
import openshot
logger = openshot.Logger.Instance()
assert openshot.ZmqLogger is openshot.Logger
''' + body + '''
logger.Log("native-debug-record", openshot.Logger.LevelDebug)
logger.Log("native-info-record", openshot.Logger.LevelInfo)
logger.Log("native-warning-record", openshot.Logger.LevelWarning)
logger.Log("native-error-record", openshot.Logger.LevelError)
logger.Log("native-critical-record", openshot.Logger.LevelCritical)
logger.Close()
'''], env=env, text=True, capture_output=True, timeout=20)
self.assertEqual(result.returncode, 0, result.stderr)
return path.read_text(), result.stderr

def test_default_and_legacy_console(self):
for variables, debug_console in (({}, False), ({'LIBOPENSHOT_DEBUG': '0'}, True)):
with self.subTest(variables=variables):
file, console = self.run_logger(variables)
self.assertNotIn('native-debug-record', file)
self.assertEqual('native-debug-record' in console, debug_console)
self.assertIn('native-info-record', file)
self.assertIn('native-info-record', console)

def test_component_and_destination_precedence(self):
file, console = self.run_logger({
'OPENSHOT_LOG_FILE_LEVEL': 'off',
'LIBOPENSHOT_LOG_LEVEL': 'debug',
'LIBOPENSHOT_LOG_CONSOLE_LEVEL': 'error'})
self.assertIn('native-debug-record', file)
self.assertNotIn('native-info-record', console)
self.assertIn('native-error-record', console)

def test_invalid_level_fallback(self):
file, console = self.run_logger({
'OPENSHOT_LOG_LEVEL': 'error',
'LIBOPENSHOT_LOG_FILE_LEVEL': 'invalid',
'LIBOPENSHOT_DEBUG': '1'})
self.assertNotIn('native-info-record', file)
self.assertNotIn('native-debug-record', console)
self.assertIn('native-error-record', file)
self.assertEqual(console.count('ignoring invalid'), 1)

def test_every_environment_variable_filters_the_correct_output(self):
for prefix in ('OPENSHOT', 'LIBOPENSHOT'):
for suffix, debug_file, debug_console in (
('LEVEL', True, True), ('FILE_LEVEL', True, False),
('CONSOLE_LEVEL', False, True)):
variable = prefix + '_LOG_' + suffix
with self.subTest(variable=variable):
file, console = self.run_logger({variable: 'debug'})
self.assertEqual('native-debug-record' in file, debug_file)
self.assertEqual('native-debug-record' in console, debug_console)

def test_all_level_thresholds(self):
levels = ('debug', 'info', 'warning', 'error', 'critical', 'off')
for threshold, level in enumerate(levels):
with self.subTest(level=level):
file, console = self.run_logger({'LIBOPENSHOT_LOG_LEVEL': level})
for index, message_level in enumerate(levels[:-1]):
message = 'native-' + message_level + '-record'
self.assertEqual(message in file, index >= threshold)
self.assertEqual(message in console, index >= threshold)

def test_api_overrides_environment_and_preserves_crash_output(self):
file, console = self.run_logger({'LIBOPENSHOT_LOG_LEVEL': 'off'}, '''
logger.SetFileLevel("debug")
logger.SetConsoleLevel("error")
logger.LogToFile("---- Unhandled Exception: Stack Trace ----\\ncrash-evidence\\n---- End of Stack Trace ----\\n")
try:
logger.SetFileLevel("invalid")
except RuntimeError:
pass
else:
raise AssertionError("invalid level accepted")
''')
self.assertIn('native-debug-record', file)
self.assertIn('crash-evidence', file)
self.assertIn('native-error-record', console)
self.assertNotIn('native-debug-record', console)


if __name__ == '__main__':
unittest.main()
4 changes: 2 additions & 2 deletions bindings/ruby/openshot.i
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ typedef struct OpenShotByteBuffer {
#include "TimelineBase.h"
#include "Timeline.h"
#include "Qt/VideoCacheThread.h"
#include "ZmqLogger.h"
#include "Logger.h"

/* Move FFmpeg's RSHIFT to FF_RSHIFT, if present */
#ifdef RSHIFT
Expand Down Expand Up @@ -272,7 +272,7 @@ typedef struct OpenShotByteBuffer {
%include "TimelineBase.h"
%include "Qt/VideoCacheThread.h"
%include "Timeline.h"
%include "ZmqLogger.h"
%include "Logger.h"

#ifdef USE_IMAGEMAGICK
%include "ImageReader.h"
Expand Down
45 changes: 0 additions & 45 deletions cmake/Modules/FindZeroMQ.cmake

This file was deleted.

6 changes: 0 additions & 6 deletions doc/INSTALL-LINUX.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@ list below to help distinguish between them.
* https://github.com/unittest-cpp/ `(Library)`
* This library is used to execute unit tests for libopenshot. It contains many macros used to keep our unit testing code very clean and simple.

### ZeroMQ (libzmq)
* http://zeromq.org/ `(Library)`
* This library is used to communicate between libopenshot and other applications (publisher / subscriber). Primarily used to send debug data from libopenshot.

### OpenMP (-fopenmp)
* http://openmp.org/wp/ `(Compiler Flag)`
* If your compiler supports this flag (GCC, Clang, and most other compilers), it provides libopenshot with easy methods of using parallel programming techniques to improve performance and take advantage of multi-core processors.
Expand Down Expand Up @@ -166,15 +162,13 @@ software packages available to download and install.
libxcursor-dev \
libxinerama-dev \
libxrandr-dev \
libzmq3-dev \
pkg-config \
python3-dev \
qtbase5-dev \
qtmultimedia5-dev \
swig \
xdg-desktop-portal \
xdg-desktop-portal-gtk \
python3-zmq \
python3-pyqt5.qtwebengine

```
Expand Down
5 changes: 0 additions & 5 deletions doc/INSTALL-MAC.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ list below to help distinguish between them.
* https://github.com/unittest-cpp/ `(Library)`
* This library is used to execute unit tests for libopenshot. It contains many macros used to keep our unit testing code very clean and simple.

### ZeroMQ (libzmq)
* http://zeromq.org/ `(Library)`
* This library is used to communicate between libopenshot and other applications (publisher / subscriber). Primarily used to send debug data from libopenshot.

### OpenMP (-fopenmp)
* http://openmp.org/wp/ `(Compiler Flag)`
* If your compiler supports this flag (GCC, Clang, and most other compilers), it provides libopenshot with easy methods of using parallel programming techniques to improve performance and take advantage of multi-core processors.
Expand Down Expand Up @@ -151,7 +147,6 @@ brew install doxygen
brew install unittest-cpp --cc=gcc-4.8. You must specify the c++ compiler with the --cc flag to be 4.7 or 4.8.
brew install qt5
brew install cmake
brew install zeromq
brew install babl
```

Expand Down
Loading
Loading