Compare commits

...

52 Commits

Author SHA1 Message Date
WarmUpTill
7b44c28767 Fix warnings 2022-09-01 13:20:35 -07:00
WarmUpTill
9bed6df2b5 Adjust macro list to new OBS layout changes 2022-09-01 13:20:35 -07:00
WarmUpTill
ad4c41c1dd Replace "\" with "/" 2022-09-01 13:20:35 -07:00
WarmUpTill
9e2ca1529c Save splitter positions on macro tab 2022-08-31 12:12:25 -07:00
WarmUpTill
e62504968c Move comment to correct line 2022-08-31 12:12:25 -07:00
WarmUpTill
97720a798c Waste less space in the UI
* Adjusted layout margins

   Nested layouts lead to lots of wasted space.
 * Removed unnecessary "Close" button

   Closing the settings dialog via "x" or the close button does not make
   a difference so it can savely be removed.
2022-08-31 12:12:25 -07:00
WarmUpTill
636630fdf3 Add splitter between macro list and macro edit area
This will make editing macros easier on smaller window sizes as the list
or edit area can be resized to the users needs
2022-08-31 12:12:25 -07:00
WarmUpTill
602622c841 Remove paths-ignore block
Didn't serve any purpose and is not allowed in combination with 'paths'
2022-08-31 07:58:24 -07:00
WarmUpTill
c3aa421bc5 Add option to split recording 2022-08-31 07:58:24 -07:00
WarmUpTill
c392004edf Remove duplicate line 2022-08-27 15:08:19 -07:00
WarmUpTill
9e4893abc3 Only run locale checks when locale was changed 2022-08-27 15:08:19 -07:00
WarmUpTill
54f940be0d Revert to old AppId for Windows installer and set new UUIDs for MacOS 2022-08-27 15:08:19 -07:00
WarmUpTill
046de4118f Rework curl helpers 2022-08-25 11:26:31 -07:00
WarmUpTill
c9177c4429 Add Http action 2022-08-25 11:26:31 -07:00
WarmUpTill
9704d5f1f4 Add AnimationFinished signal 2022-08-24 12:53:25 -07:00
WarmUpTill
5ce177bcd3 Add websocket files and dependencies 2022-08-24 12:53:25 -07:00
WarmUpTill
a7b6a4a67c Add websocket locale 2022-08-24 12:53:25 -07:00
WarmUpTill
1978b8f1a1 Save and load websocket connections 2022-08-24 12:53:25 -07:00
WarmUpTill
59cc37c90a Add websocket condition 2022-08-24 12:53:25 -07:00
WarmUpTill
866c49bffd Add websocket action 2022-08-24 12:53:25 -07:00
WarmUpTill
c9370c8929 Add websocket helper functions to receive and send messages 2022-08-24 12:53:25 -07:00
WarmUpTill
e97f41a356 Add connection-manager
Used to add, remove, and modify websocket connections
2022-08-24 12:53:25 -07:00
WarmUpTill
6c7ba4225b Add obs-websocket dependency 2022-08-24 12:53:25 -07:00
WarmUpTill
b694598d16 Disable the "Directory already exists" warning in Windows installer 2022-08-23 13:53:13 -07:00
WarmUpTill
954b634aa5 Update actions/cache from v2.1.7 to v3 2022-08-23 13:53:13 -07:00
WarmUpTill
c9820e77d8 Add option to check states of multiple macros at the same time 2022-08-23 11:31:48 -07:00
WarmUpTill
a268f98b73 Rework to use MacroList widget 2022-08-23 11:31:48 -07:00
WarmUpTill
700e75a2b5 Fix potential crashes when removing macros 2022-08-23 11:31:48 -07:00
WarmUpTill
19e79aff50 Add macro list widget 2022-08-23 11:31:48 -07:00
WarmUpTill
c8f684ce9f Add helper to get internal ref name 2022-08-23 11:31:48 -07:00
WarmUpTill
1027dda6f6 Enable inheriting from both MultiMacroRef* and MacroRef*
Initially to be used only for the "Macro" condition type
2022-08-23 11:31:48 -07:00
WarmUpTill
6f7bcc34af Add helper functions to save / load list of macro refs 2022-08-23 11:31:48 -07:00
WarmUpTill
face0f7f3c Add MultiMacroRefCondtition 2022-08-23 11:31:48 -07:00
WarmUpTill
7480e793b8 Adjust General tab layout for new Yami theme of OBS 28 2022-08-23 10:58:57 -07:00
WarmUpTill
bcdcaed136 Format example 2022-08-17 11:16:22 -07:00
WarmUpTill
85e715dc75 Update .gitignore 2022-08-17 11:08:53 -07:00
WarmUpTill
9e8e1a6e4d Set LINUX_PORTABLE to OFF to create valid .deb file 2022-08-17 11:08:53 -07:00
WarmUpTill
7fbfb7806b Add link to wiki and OBS forums 2022-08-17 11:08:53 -07:00
WarmUpTill
1556334c0e Update README.md and BUILDING.md
* Add "Contributing" section
 * Update build instructions
2022-08-17 11:08:53 -07:00
WarmUpTill
53a5fa6ff4 Restructure "src/" folder
Moving files from the "src/" folder into "src/legacy", "src/macro-core",
and "src/utils" was necessary as it was becoming a bit too cluttered.
2022-08-17 11:08:53 -07:00
WarmUpTill
5ae9e18044 Rework plugin to allow split into module and library part
This is mostly intended to allow easier bundling for MacOS but might
prove to be useful for other areas as well.
2022-08-17 11:08:53 -07:00
WarmUpTill
aef29d7d82 Update plugin build scripts
Based on OBS plugin template build scripts with some minor adjustments:

 * Adjust format check scripts to exclude ./deps folder
 * Adjust release scripts to only draft releases
 * Always build installers
 * Always upload build artefacts
 * Build opencv for Mac and Windows releases
2022-08-17 11:08:53 -07:00
WarmUpTill
f000758820 Add Qt version checks to support Qt5 2022-08-17 11:08:53 -07:00
WarmUpTill
786c9592a1 Fix depecrations and clean up backwards compatibility checks 2022-08-17 11:08:53 -07:00
WarmUpTill
5cb50821e0 Rewrite CMakeLists.txt to support new build system based on obs-plugintemplate 2022-08-17 11:08:53 -07:00
WarmUpTill
bcdfe79831 Add action to refresh sources 2022-08-03 11:35:06 -07:00
WarmUpTill
ec93babed6 Fix duration modifier of media conditions not saving 2022-08-03 11:34:25 -07:00
WarmUpTill
e075dcd4be Cleanup
Rename locale entry to match naming scheme
2022-06-28 11:25:50 -07:00
WarmUpTill
4113f94528 Add condition to check current profile 2022-06-28 11:25:50 -07:00
WarmUpTill
db3affc43d Set screenshot file extension to *.png
Files without any file extension are not properly loaded as an QImage and
thus pattern matching might not work
2022-06-28 11:25:38 -07:00
EliasDIPA
e11d882e87 Spanish translation of version 1.17.7 2022-06-28 11:24:57 -07:00
WarmUpTill
925729e6b8 Fix hotkeys not being registered for new macros 2022-06-22 14:13:34 -07:00
319 changed files with 10304 additions and 5459 deletions

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Help/Support
url: https://github.com/WarmUpTill/SceneSwitcher/wiki
about: For general questions about how to use and configure the plugin please have a look at the wiki (https://github.com/WarmUpTill/SceneSwitcher/wiki) or ask questions in the OBS forum (https://obsproject.com/forum/threads/advanced-scene-switcher.48264/)

77
.github/actions/build-plugin/action.yml vendored Normal file
View File

@@ -0,0 +1,77 @@
name: 'Setup and build plugin'
description: 'Builds the plugin for specified architecture and build config.'
inputs:
target:
description: 'Build target for dependencies'
required: true
config:
description: 'Build configuration'
required: false
default: 'Release'
codesign:
description: 'Enable codesigning (macOS only)'
required: false
default: 'false'
codesignIdent:
description: 'Developer ID for application codesigning (macOS only)'
required: false
default: '-'
visualStudio:
description: 'Visual Studio version (Windows only)'
required: false
default: 'Visual Studio 16 2019'
workingDirectory:
description: 'Working directory for packaging'
required: false
default: ${{ github.workspace }}
runs:
using: 'composite'
steps:
- name: Run macOS Build
if: ${{ runner.os == 'macOS' }}
shell: zsh {0}
env:
CODESIGN_IDENT: ${{ inputs.codesignIdent }}
run: |
build_args=(
-c ${{ inputs.config }}
-t macos-${{ inputs.target }}
)
if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(-s)
if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug)
${{ inputs.workingDirectory }}/.github/scripts/build-macos.zsh ${build_args}
- name: Run Linux Build
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
build_args=(
-c ${{ inputs.config }}
-t linux-${{ inputs.target }}
)
if [[ -n "${CI}" && -n "${RUNNER_DEBUG}" ]]; then
build_args+=(--debug)
fi
${{ inputs.workingDirectory }}/.github/scripts/build-linux.sh "${build_args[@]}"
- name: Run Windows Build
if: ${{ runner.os == 'Windows' }}
shell: pwsh
run: |
$BuildArgs = @{
Target = '${{ inputs.target }}'
Configuration = '${{ inputs.config }}'
CMakeGenerator = '${{ inputs.visualStudio }}'
}
if ( ( Test-Path env:CI ) -and ( Test-Path env:RUNNER_DEBUG ) ) {
$BuildArgs += @{
Debug = $true
}
}
${{ inputs.workingDirectory }}/.github/scripts/Build-Windows.ps1 @BuildArgs

View File

@@ -0,0 +1,99 @@
name: 'Package plugin'
description: 'Packages the plugin for specified architecture and build config.'
inputs:
target:
description: 'Build target for dependencies'
required: true
config:
description: 'Build configuration'
required: false
default: 'Release'
codesign:
description: 'Enable codesigning (macOS only)'
required: false
default: 'false'
notarize:
description: 'Enable notarization (macOS only)'
required: false
default: 'false'
codesignIdent:
description: 'Developer ID for application codesigning (macOS only)'
required: false
default: '-'
installerIdent:
description: 'Developer ID for installer package codesigning (macOS only)'
required: false
default: ''
codesignUser:
description: 'Apple ID username for notarization (macOS only)'
required: false
default: ''
codesignPass:
description: 'Apple ID password for notarization (macOS only)'
required: false
default: ''
createInstaller:
description: 'Create InnoSetup installer (Windows only)'
required: false
default: 'false'
workingDirectory:
description: 'Working directory for packaging'
required: false
default: ${{ github.workspace }}
runs:
using: 'composite'
steps:
- name: Run macOS packaging
if: ${{ runner.os == 'macOS' }}
shell: zsh {0}
env:
CODESIGN_IDENT: ${{ inputs.codesignIdent }}
CODESIGN_IDENT_INSTALLER: ${{ inputs.installerIdent }}
CODESIGN_IDENT_USER: ${{ inputs.codesignUser }}
CODESIGN_IDENT_PASS: ${{ inputs.codesignPass }}
run: |
package_args=(
-c ${{ inputs.config }}
-t macos-${{ inputs.target }}
)
if [[ '${{ inputs.codesign }}' == 'true' ]] package_args+=(-s)
if [[ '${{ inputs.notarize }}' == 'true' ]] package_args+=(-n)
if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug)
${{ inputs.workingDirectory }}/.github/scripts/package-macos.zsh ${package_args}
- name: Run Linux packaging
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
package_args=(
-c ${{ inputs.config }}
-t linux-${{ inputs.target }}
)
if [[ -n "${CI}" && -n "${RUNNER_DEBUG}" ]]; then
build_args+=(--debug)
fi
${{ inputs.workingDirectory }}/.github/scripts/package-linux.sh "${package_args[@]}"
- name: Run Windows packaging
if: ${{ runner.os == 'Windows' }}
shell: pwsh
run: |
$PackageArgs = @{
Target = '${{ inputs.target }}'
Configuration = '${{ inputs.config }}'
}
if ( '${{ inputs.createInstaller }}' -eq 'true' ) {
$PackageArgs += @{BuildInstaller = $true}
}
if ( ( Test-Path env:CI ) -and ( Test-Path env:RUNNER_DEBUG ) ) {
$BuildArgs += @{
Debug = $true
}
}
${{ inputs.workingDirectory }}/.github/scripts/Package-Windows.ps1 @PackageArgs

9
.github/scripts/.Aptfile vendored Normal file
View File

@@ -0,0 +1,9 @@
package 'cmake'
package 'ccache'
package 'curl'
package 'git'
package 'jq'
package 'ninja-build', bin: 'ninja'
package 'pkg-config'
package 'clang'
package 'clang-format-13'

6
.github/scripts/.Brewfile vendored Normal file
View File

@@ -0,0 +1,6 @@
brew "ccache"
brew "coreutils"
brew "cmake"
brew "git"
brew "jq"
brew "ninja"

3
.github/scripts/.Wingetfile vendored Normal file
View File

@@ -0,0 +1,3 @@
package '7zip.7zip', path: '7-zip', bin: '7z'
package 'cmake', path: 'Cmake\bin', bin: 'cmake'
package 'innosetup', path: 'Inno Setup 6', bin: 'iscc'

275
.github/scripts/.build.zsh vendored Executable file
View File

@@ -0,0 +1,275 @@
#!/usr/bin/env zsh
builtin emulate -L zsh
setopt EXTENDED_GLOB
setopt PUSHD_SILENT
setopt ERR_EXIT
setopt ERR_RETURN
setopt NO_UNSET
setopt PIPE_FAIL
setopt NO_AUTO_PUSHD
setopt NO_PUSHD_IGNORE_DUPS
setopt FUNCTION_ARGZERO
## Enable for script debugging
# setopt WARN_CREATE_GLOBAL
# setopt WARN_NESTED_VAR
# setopt XTRACE
autoload -Uz is-at-least && if ! is-at-least 5.2; then
print -u2 -PR "%F{1}${funcstack[1]##*/}:%f Running on Zsh version %B${ZSH_VERSION}%b, but Zsh %B5.2%b is the minimum supported version. Upgrade Zsh to fix this issue."
exit 1
fi
_trap_error() {
print -u2 -PR '%F{1} ✖︎ script execution error%f'
print -PR -e "
Callstack:
${(j:\n :)funcfiletrace}
"
exit 2
}
build() {
if (( ! ${+SCRIPT_HOME} )) typeset -g SCRIPT_HOME=${ZSH_ARGZERO:A:h}
local host_os=${${(s:-:)ZSH_ARGZERO:t:r}[2]}
local target="${host_os}-${CPUTYPE}"
local project_root=${SCRIPT_HOME:A:h:h}
local buildspec_file="${project_root}/buildspec.json"
trap '_trap_error' ZERR
fpath=("${SCRIPT_HOME}/utils.zsh" ${fpath})
autoload -Uz log_info log_error log_output set_loglevel check_${host_os} setup_${host_os} setup_obs setup_ccache
if [[ ! -r ${buildspec_file} ]] {
log_error \
'No buildspec.json found. Please create a build specification for your project.' \
'A buildspec.json.template file is provided in the repository to get you started.'
return 2
}
typeset -g -a skips=()
local -i _verbosity=1
local -r _version='1.0.0'
local -r -a _valid_targets=(
macos-x86_64
macos-arm64
macos-universal
linux-x86_64
)
local -r -a _valid_configs=(Debug RelWithDebInfo Release MinSizeRel)
if [[ ${host_os} == 'macos' ]] {
local -r -a _valid_generators=(Xcode Ninja 'Unix Makefiles')
local generator="${${CI:+Ninja}:-Xcode}"
} else {
local -r -a _valid_generators=(Ninja 'Unix Makefiles')
local generator='Ninja'
}
local -r _usage="
Usage: %B${functrace[1]%:*}%b <option> [<options>]
%BOptions%b:
%F{yellow} Build configuration options%f
-----------------------------------------------------------------------------
%B-t | --target%b Specify target - default: %B%F{green}${host_os}-${CPUTYPE}%f%b
%B-c | --config%b Build configuration - default: %B%F{green}RelWithDebInfo%f%b
%B-s | --codesign%b Enable codesigning (macOS only)
%B--generator%b Specify build system to generate - default: %B%F{green}Ninja%f%b
Available generators:
- Ninja
- Unix Makefiles
- Xcode (macOS only)
%F{yellow} Output options%f
-----------------------------------------------------------------------------
%B-q | --quiet%b Quiet (error output only)
%B-v | --verbose%b Verbose (more detailed output)
%B--skip-[all|build|deps|unpack]%b Skip all|building OBS|checking for dependencies|unpacking dependencies
%B--debug%b Debug (very detailed and added output)
%F{yellow} General options%f
-----------------------------------------------------------------------------
%B-h | --help%b Print this usage help
%B-V | --version%b Print script version information"
local -a args
while (( # )) {
case ${1} {
-t|--target|-c|--config|--generator)
if (( # == 1 )) || [[ ${2:0:1} == '-' ]] {
log_error "Missing value for option %B${1}%b"
log_output ${_usage}
exit 2
}
;;
}
case ${1} {
--)
shift
args+=($@)
break
;;
-t|--target)
if (( ! ${_valid_targets[(Ie)${2}]} )) {
log_error "Invalid value %B${2}%b for option %B${1}%b"
log_output ${_usage}
exit 2
}
target=${2}
shift 2
;;
-c|--config)
if (( ! ${_valid_configs[(Ie)${2}]} )) {
log_error "Invalid value %B${2}%b for option %B${1}%b"
log_output ${_usage}
exit 2
}
BUILD_CONFIG=${2}
shift 2
;;
-s|--codesign) CODESIGN=1; shift ;;
-q|--quiet) (( _verbosity -= 1 )) || true; shift ;;
-v|--verbose) (( _verbosity += 1 )); shift ;;
-h|--help) log_output ${_usage}; exit 0 ;;
-V|--version) print -Pr "${_version}"; exit 0 ;;
--debug) _verbosity=3; shift ;;
--generator)
if (( ! ${_valid_generators[(Ie)${2}]} )) {
log_error "Invalid value %B${2}%b for option %B${1}%b"
log_output ${_usage}
exit 2
}
generator=${2}
shift 2
;;
--skip-*)
local _skip="${${(s:-:)1}[-1]}"
local _check=(all deps unpack build)
(( ${_check[(Ie)${_skip}]} )) || log_warning "Invalid skip mode %B${_skip}%b supplied"
typeset -g -a skips=(${skips} ${_skip})
shift
;;
*) log_error "Unknown option: %B${1}%b"; log_output ${_usage}; exit 2 ;;
}
}
set -- ${(@)args}
set_loglevel ${_verbosity}
check_${host_os}
setup_ccache
typeset -g QT_VERSION
typeset -g DEPLOYMENT_TARGET
typeset -g OBS_DEPS_VERSION
setup_${host_os}
local product_name
local product_version
read -r product_name product_version <<< \
"$(jq -r '. | {name, version} | join(" ")' ${buildspec_file})"
local opencv_dir="${project_root}/deps/opencv"
local opencv_build_dir="${opencv_dir}/build_${target##*-}"
case ${host_os} {
macos)
sed -i '' \
"s/project(\(.*\) VERSION \(.*\))/project(${product_name} VERSION ${product_version})/" \
"${project_root}/CMakeLists.txt"
# Note: IPP must be set to OFF to avoid build failures on ARM architectures
local -a opencv_cmake_args=(
-DCMAKE_BUILD_TYPE=Release
-DBUILD_LIST=core,imgproc,objdetect
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
-DWITH_IPP=OFF
)
pushd ${opencv_dir}
log_info "Configure OpenCV ..."
cmake -S . -B ${opencv_build_dir} -G ${generator} ${opencv_cmake_args}
log_info "Building OpenCV ..."
cmake --build ${opencv_build_dir} --config Release
log_info "Installing OpenCV..."
cmake --install ${opencv_build_dir} --config Release --prefix ${opencv_build_dir}
popd
;;
linux)
sed -i'' \
"s/project(\(.*\) VERSION \(.*\))/project(${product_name} VERSION ${product_version})/"\
"${project_root}/CMakeLists.txt"
;;
}
setup_obs
pushd ${project_root}
if (( ! (${skips[(Ie)all]} + ${skips[(Ie)build]}) )) {
log_info "Configuring ${product_name}..."
local _plugin_deps="${project_root:h}/obs-build-dependencies/plugin-deps-${OBS_DEPS_VERSION}-qt${QT_VERSION}-${target##*-}"
local -a cmake_args=(
-DCMAKE_BUILD_TYPE=${BUILD_CONFIG:-RelWithDebInfo}
-DQT_VERSION=${QT_VERSION}
-DCMAKE_PREFIX_PATH="${_plugin_deps}"
)
if (( _loglevel == 0 )) cmake_args+=(-Wno_deprecated -Wno-dev --log-level=ERROR)
if (( _loglevel > 2 )) cmake_args+=(--debug-output)
local num_procs
case ${target} {
macos-*)
autoload -Uz read_codesign
if (( ${+CODESIGN} )) {
read_codesign
}
num_procs=$(( $(sysctl -n hw.ncpu) + 1 ))
cmake_args+=(
-DCMAKE_FRAMEWORK_PATH="${_plugin_deps}/Frameworks"
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
-DOBS_CODESIGN_LINKER=ON
-DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}"
-DOpenCV_DIR="${opencv_build_dir}"
)
;;
linux-*)
if (( ${+CI} )) {
cmake_args+=(
-DCMAKE_INSTALL_PREFIX=/usr
-DLINUX_PORTABLE=OFF
)
}
num_procs=$(( $(nproc) + 1 ))
;;
}
log_debug "Attempting to configure ${product_name} with CMake arguments: ${cmake_args}"
cmake -S . -B build_${target##*-} -G ${generator} ${cmake_args}
log_info "Building ${product_name}..."
local -a cmake_args=()
if (( _loglevel > 1 )) cmake_args+=(--verbose)
if [[ ${generator} == 'Unix Makefiles' ]] cmake_args+=(--parallel ${num_procs})
cmake --build build_${target##*-} --config ${BUILD_CONFIG:-RelWithDebInfo} ${cmake_args}
}
log_info "Installing ${product_name}..."
local -a cmake_args=()
if (( _loglevel > 1 )) cmake_args+=(--verbose)
cmake --install build_${target##*-} --config ${BUILD_CONFIG:-RelWithDebInfo} --prefix "${project_root}/release" ${cmake_args}
popd
}
build ${@}

192
.github/scripts/.package.zsh vendored Executable file
View File

@@ -0,0 +1,192 @@
#!/usr/bin/env zsh
builtin emulate -L zsh
setopt EXTENDED_GLOB
setopt PUSHD_SILENT
setopt ERR_EXIT
setopt ERR_RETURN
setopt NO_UNSET
setopt PIPE_FAIL
setopt NO_AUTO_PUSHD
setopt NO_PUSHD_IGNORE_DUPS
setopt FUNCTION_ARGZERO
## Enable for script debugging
# setopt WARN_CREATE_GLOBAL
# setopt WARN_NESTED_VAR
# setopt XTRACE
autoload -Uz is-at-least && if ! is-at-least 5.2; then
print -u2 -PR "%F{1}${funcstack[1]##*/}:%f Running on Zsh version %B${ZSH_VERSION}%b, but Zsh %B5.2%b is the minimum supported version. Upgrade Zsh to fix this issue."
exit 1
fi
_trap_error() {
print -u2 -PR '%F{1} ✖︎ script execution error%f'
print -PR -e "
Callstack:
${(j:\n :)funcfiletrace}
"
exit 2
}
package() {
if (( ! ${+SCRIPT_HOME} )) typeset -g SCRIPT_HOME=${ZSH_ARGZERO:A:h}
local host_os=${${(s:-:)ZSH_ARGZERO:t:r}[2]}
local target="${host_os}-${CPUTYPE}"
local project_root=${SCRIPT_HOME:A:h:h}
local buildspec_file="${project_root}/buildspec.json"
trap '_trap_error' ZERR
fpath=("${SCRIPT_HOME}/utils.zsh" ${fpath})
autoload -Uz set_loglevel log_info log_error log_output check_${host_os}
local -i _verbosity=1
local -r _version='1.0.0'
local -r -a _valid_targets=(
macos-x86_64
macos-arm64
macos-universal
linux-x86_64
)
local -r -a _valid_configs=(Debug RelWithDebInfo Release MinSizeRel)
local -r _usage="
Usage: %B${functrace[1]%:*}%b <option> [<options>]
%BOptions%b:
%F{yellow} Package configuration options%f
-----------------------------------------------------------------------------
%B-t | --target%b Specify target - default: %B%F{green}${host_os}-${CPUTYPE}%f%b
%B-c | --config%b Build configuration - default: %B%F{green}RelWithDebInfo%f%b
%B-s | --codesign%b Enable codesigning (macOS only)
%B-n | --notarize%b Enable notarization (macOS only)
%F{yellow} Output options%f
-----------------------------------------------------------------------------
%B-q | --quiet%b Quiet (error output only)
%B-v | --verbose%b Verbose (more detailed output)
%B--debug%b Debug (very detailed and added output)
%F{yellow} General options%f
-----------------------------------------------------------------------------
%B-h | --help%b Print this usage help
%B-V | --version%b Print script version information"
local -a args
while (( # )) {
case ${1} {
-t|--target|-c|--config)
if (( # == 1 )) || [[ ${2:0:1} == '-' ]] {
log_error "Missing value for option %B${1}%b"
log_output ${_usage}
exit 2
}
;;
}
case ${1} {
--)
shift
args+=($@)
break
;;
-t|--target)
if (( ! ${_valid_targets[(Ie)${2}]} )) {
log_error "Invalid value %B${2}%b for option %B${1}%b"
log_output ${_usage}
exit 2
}
target=${2}
shift 2
;;
-c|--config)
if (( ! ${_valid_configs[(Ie)${2}]} )) {
log_error "Invalid value %B${2}%b for option %B${1}%b"
log_output ${_usage}
exit 2
}
BUILD_CONFIG=${2}
shift 2
;;
-s|--codesign) typeset -g CODESIGN=1; shift ;;
-n|--notarize) typeset -g NOTARIZE=1; typeset -g CODESIGN=1; shift ;;
-q|--quiet) (( _verbosity -= 1 )) || true; shift ;;
-v|--verbose) (( _verbosity += 1 )); shift ;;
-h|--help) log_output ${_usage}; exit 0 ;;
-V|--version) print -Pr "${_version}"; exit 0 ;;
--debug) _verbosity=3; shift ;;
*) log_error "Unknown option: %B${1}%b"; log_output ${_usage}; exit 2 ;;
}
}
set -- ${(@)args}
set_loglevel ${_verbosity}
check_${host_os}
local product_name
local product_version
read -r product_name product_version <<< \
"$(jq -r '. | {name, version} | join(" ")' ${project_root}/buildspec.json)"
if [[ ${host_os} == 'macos' ]] {
autoload -Uz check_packages read_codesign read_codesign_installer read_codesign_pass
local output_name="${product_name}-${product_version}-${host_os}-${target##*-}.pkg"
if [[ ! -d ${project_root}/release/${product_name}.plugin ]] {
log_error 'No release artifact found. Run the build script or the CMake install procedure first.'
return 2
}
if [[ ! -f ${project_root}/build_${target##*-}/installer-macos.generated.pkgproj ]] {
log_error 'Packages project file not found. Run the build script or the CMake build and install procedures first.'
return 2
}
check_packages
log_info "Packaging ${product_name}..."
pushd ${project_root}
packagesbuild \
--build-folder ${project_root}/release \
${project_root}/build_${target##*-}/installer-macos.generated.pkgproj
if (( ${+CODESIGN} )) {
read_codesign_installer
productsign \
--sign "${CODESIGN_IDENT_INSTALLER}" \
"${project_root}/release/${product_name}.pkg" \
"${project_root}/release/${output_name}"
rm "${project_root}/release/${product_name}.pkg"
} else {
mv "${project_root}/release/${product_name}.pkg" \
"${project_root}/release/${output_name}"
}
if (( ${+CODESIGN} && ${+NOTARIZE} )) {
if [[ ! -f "${project_root}/release/${output_name}" ]] {
log_error "No package for notarization found."
return 2
}
read_codesign_installer
read_codesign_pass
xcrun notarytool submit "${project_root}/release/${output_name}" \
--keychain-profile "OBS-Codesign-Password" --wait
xcrun stapler staple "${project_root}/release/${output_name}"
}
popd
} elif [[ ${host_os} == 'linux' ]] {
local -a cmake_args=()
if (( _loglevel > 1 )) cmake_args+=(--verbose)
pushd ${project_root}
cmake --build build_${target##*-} --config ${BUILD_CONFIG:-RelWithDebInfo} -t package ${cmake_args}
popd
}
}
package ${@}

137
.github/scripts/Build-Windows.ps1 vendored Normal file
View File

@@ -0,0 +1,137 @@
[CmdletBinding()]
param(
[ValidateSet('Debug', 'RelWithDebInfo', 'Release', 'MinSizeRel')]
[string] $Configuration = 'RelWithDebInfo',
[ValidateSet('x86', 'x64')]
[string] $Target,
[ValidateSet('Visual Studio 17 2022', 'Visual Studio 16 2019')]
[string] $CMakeGenerator,
[switch] $SkipAll,
[switch] $SkipBuild,
[switch] $SkipDeps,
[switch] $SkipUnpack
)
$ErrorActionPreference = 'Stop'
if ( $DebugPreference -eq 'Continue' ) {
$VerbosePreference = 'Continue'
$InformationPreference = 'Continue'
}
if ( $PSVersionTable.PSVersion -lt '7.0.0' ) {
Write-Warning 'The obs-deps PowerShell build script requires PowerShell Core 7. Install or upgrade your PowerShell version: https://aka.ms/pscore6'
exit 2
}
function Build {
trap {
Pop-Location -Stack BuildTemp -ErrorAction 'SilentlyContinue'
Write-Error $_
exit 2
}
$ScriptHome = $PSScriptRoot
$ProjectRoot = Resolve-Path -Path "$PSScriptRoot/../.."
$BuildSpecFile = "${ProjectRoot}/buildspec.json"
$UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse
foreach($Utility in $UtilityFunctions) {
Write-Debug "Loading $($Utility.FullName)"
. $Utility.FullName
}
$BuildSpec = Get-Content -Path ${BuildSpecFile} -Raw | ConvertFrom-Json
$ProductName = $BuildSpec.name
$ProductVersion = $BuildSpec.version
$script:DepsVersion = ''
$script:QtVersion = '5'
$script:VisualStudioVersion = ''
$script:PlatformSDK = '10.0.18363.657'
Setup-Host
if ( $CmakeGenerator -eq '' ) {
$CmakeGenerator = $script:VisualStudioVersion
}
Push-Location -Stack BuildOpenCVTemp
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
Ensure-Location $ProjectRoot
$OpenCVPath = "${ProjectRoot}/deps/opencv"
$OpenCVBuildPath = "${OpenCVPath}/build"
$OpenCVCmakeArgs = @(
'-G', $CmakeGenerator
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
"-DCMAKE_BUILD_TYPE=Release"
"-DCMAKE_PREFIX_PATH:PATH=$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
"-DBUILD_LIST=core,imgproc,objdetect"
)
Log-Information "Configuring OpenCV..."
Invoke-External cmake -S ${OpenCVPath} -B ${OpenCVBuildPath} @OpenCVCmakeArgs
$OpenCVCmakeArgs = @(
'--config', "Release"
)
if ( $VerbosePreference -eq 'Continue' ) {
$OpenCVCmakeArgs+=('--verbose')
}
Log-Information "Building OpenCV..."
Invoke-External cmake --build "${OpenCVBuildPath}" @OpenCVCmakeArgs
}
Log-Information "Install OpenCV}..."
Invoke-External cmake --install "${OpenCVBuildPath}" --prefix "${OpenCVBuildPath}" @OpenCVCmakeArgs
(Get-Content -Path ${ProjectRoot}/CMakeLists.txt -Raw) `
-replace "project\((.*) VERSION (.*)\)", "project(${ProductName} VERSION ${ProductVersion})" `
| Out-File -Path ${ProjectRoot}/CMakeLists.txt
Setup-Obs
Push-Location -Stack BuildTemp
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
Ensure-Location $ProjectRoot
$OpenCVPath = "${ProjectRoot}/deps/opencv"
$OpenCVBuildPath = "${OpenCVPath}/build"
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
$CmakeArgs = @(
'-G', $CmakeGenerator
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
"-DCMAKE_BUILD_TYPE=${Configuration}"
"-DCMAKE_PREFIX_PATH:PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/${DepsPath}")"
"-DQT_VERSION=${script:QtVersion}"
"-DOpenCV_DIR=${OpenCVBuildPath}"
)
Log-Debug "Attempting to configure OBS with CMake arguments: $($CmakeArgs | Out-String)"
Log-Information "Configuring ${ProductName}..."
Invoke-External cmake -S . -B build_${script:Target} @CmakeArgs
$CmakeArgs = @(
'--config', "${Configuration}"
)
if ( $VerbosePreference -eq 'Continue' ) {
$CmakeArgs+=('--verbose')
}
Log-Information "Building ${ProductName}..."
Invoke-External cmake --build "build_${script:Target}" @CmakeArgs
}
Log-Information "Install ${ProductName}..."
Invoke-External cmake --install "build_${script:Target}" --prefix "${ProjectRoot}/release" @CmakeArgs
Pop-Location -Stack BuildTemp
}
Build

92
.github/scripts/Package-Windows.ps1 vendored Normal file
View File

@@ -0,0 +1,92 @@
[CmdletBinding()]
param(
[ValidateSet('Debug', 'RelWithDebInfo', 'Release', 'MinSizeRel')]
[string] $Configuration = 'RelWithDebInfo',
[ValidateSet('x86', 'x64', 'x86+x64')]
[string] $Target,
[switch] $BuildInstaller = $false
)
$ErrorActionPreference = 'Stop'
if ( $DebugPreference -eq 'Continue' ) {
$VerbosePreference = 'Continue'
$InformationPreference = 'Continue'
}
if ( $PSVersionTable.PSVersion -lt '7.0.0' ) {
Write-Warning 'The obs-deps PowerShell build script requires PowerShell Core 7. Install or upgrade your PowerShell version: https://aka.ms/pscore6'
exit 2
}
function Package {
trap {
Write-Error $_
exit 2
}
$ScriptHome = $PSScriptRoot
$ProjectRoot = Resolve-Path -Path "$PSScriptRoot/../.."
$BuildSpecFile = "${ProjectRoot}/buildspec.json"
$UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse
foreach( $Utility in $UtilityFunctions ) {
Write-Debug "Loading $($Utility.FullName)"
. $Utility.FullName
}
$BuildSpec = Get-Content -Path ${BuildSpecFile} -Raw | ConvertFrom-Json
$ProductName = $BuildSpec.name
$ProductVersion = $BuildSpec.version
$OutputName = "${ProductName}-${ProductVersion}-windows-${Target}"
Install-BuildDependencies -WingetFile "${ScriptHome}/.Wingetfile"
Log-Information "Packaging ${ProductName}..."
$RemoveArgs = @{
ErrorAction = 'SilentlyContinue'
Path = @(
"${ProjectRoot}/release/${ProductName}-*-windows-*.zip"
"${ProjectRoot}/release/${ProductName}-*-windows-*.exe"
)
}
Remove-Item @RemoveArgs
if ( ( $BuildInstaller ) ) {
if ( $Target -eq 'x86+x64' ) {
$IsccCandidates = Get-ChildItem -Recurse -Path '*.iss'
if ( $IsccCandidates.length -gt 0 ) {
$IsccFile = $IsccCandidates[0].FullName
} else {
$IsccFile = ''
}
} else {
$IsccFile = "${ProjectRoot}/build_${Target}/installer-Windows.generated.iss"
}
if ( ! ( Test-Path -Path $IsccFile ) ) {
throw 'InnoSetup install script not found. Run the build script or the CMake build and install procedures first.'
}
Log-Information 'Creating InnoSetup installer...'
Push-Location -Stack BuildTemp
Ensure-Location -Path "${ProjectRoot}/release"
Invoke-External iscc ${IsccFile} /O. /F"${OutputName}-Installer"
Pop-Location -Stack BuildTemp
}
$CompressArgs = @{
Path = (Get-ChildItem -Path "${ProjectRoot}/release" -Exclude "${OutputName}*.*")
CompressionLevel = 'Optimal'
DestinationPath = "${ProjectRoot}/release/${OutputName}.zip"
}
Compress-Archive -Force @CompressArgs
}
Package

13
.github/scripts/build-linux.sh vendored Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/sh
if ! type zsh > /dev/null 2>&1; then
echo ' => Installing script dependency Zsh.'
sudo apt-get -y update
sudo apt-get -y install zsh
fi
SCRIPT=$(readlink -f "${0}")
SCRIPT_DIR=$(dirname "${SCRIPT}")
zsh ${SCRIPT_DIR}/build-linux.zsh "${@}"

1
.github/scripts/build-linux.zsh vendored Symbolic link
View File

@@ -0,0 +1 @@
.build.zsh

1
.github/scripts/build-macos.zsh vendored Symbolic link
View File

@@ -0,0 +1 @@
.build.zsh

53
.github/scripts/check-cmake.sh vendored Executable file
View File

@@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -o errexit
set -o pipefail
if [ ${#} -eq 1 -a "${1}" = "VERBOSE" ]; then
VERBOSITY="-l debug"
else
VERBOSITY=""
fi
if [ "${CI}" ]; then
MODE="--check"
else
MODE="-i"
fi
# Runs the formatter in parallel on the code base.
# Return codes:
# - 1 there are files to be formatted
# - 0 everything looks fine
# Get CPU count
OS=$(uname)
NPROC=1
if [[ ${OS} = "Linux" ]] ; then
NPROC=$(nproc)
elif [[ ${OS} = "Darwin" ]] ; then
NPROC=$(sysctl -n hw.physicalcpu)
fi
# Discover clang-format
if ! type cmake-format 2> /dev/null ; then
echo "Required cmake-format not found"
exit 1
fi
find . -type d \( \
-path ./\*build -o \
-path ./deps/jansson -o \
-path ./plugins/decklink/\*/decklink-sdk -o \
-path ./plugins/enc-amf -o \
-path ./plugins/mac-syphon/syphon-framework -o \
-path ./plugins/obs-outputs/ftl-sdk -o \
-path ./plugins/obs-vst -o \
-path ./plugins/obs-browser -o \
-path ./plugins/win-dshow/libdshowcapture -o \
-path ./plugins/obs-websocket/deps -o \
-path ./deps \
\) -prune -false -type f -o \
-name 'CMakeLists.txt' -or \
-name '*.cmake' \
| xargs -L10 -P ${NPROC} cmake-format ${MODE} ${VERBOSITY}

60
.github/scripts/check-format.sh vendored Executable file
View File

@@ -0,0 +1,60 @@
#!/usr/bin/env bash
# Original source https://github.com/Project-OSRM/osrm-backend/blob/master/scripts/format.sh
set -o errexit
set -o pipefail
set -o nounset
if [ ${#} -eq 1 ]; then
VERBOSITY="--verbose"
else
VERBOSITY=""
fi
# Runs the Clang Formatter in parallel on the code base.
# Return codes:
# - 1 there are files to be formatted
# - 0 everything looks fine
# Get CPU count
OS=$(uname)
NPROC=1
if [[ ${OS} = "Linux" ]] ; then
NPROC=$(nproc)
elif [[ ${OS} = "Darwin" ]] ; then
NPROC=$(sysctl -n hw.physicalcpu)
fi
# Discover clang-format
if type clang-format-13 2> /dev/null ; then
CLANG_FORMAT=clang-format-13
elif type clang-format 2> /dev/null ; then
# Clang format found, but need to check version
CLANG_FORMAT=clang-format
V=$(clang-format --version)
if [[ $V != *"version 13.0"* ]]; then
echo "clang-format is not 13.0 (returned ${V})"
exit 1
fi
else
echo "No appropriate clang-format found (expected clang-format-13.0.0, or clang-format)"
exit 1
fi
find . -type d \( \
-path ./\*build -o \
-path ./cmake -o \
-path ./plugins/decklink/\*/decklink-sdk -o \
-path ./plugins/enc-amf -o \
-path ./plugins/mac-syphon/syphon-framework -o \
-path ./plugins/obs-outputs/ftl-sdk -o \
-path ./plugins/obs-websocket/deps -o \
-path ./deps \
\) -prune -false -type f -o \
-name '*.h' -or \
-name '*.hpp' -or \
-name '*.m' -or \
-name '*.mm' -or \
-name '*.c' -or \
-name '*.cpp' \
| xargs -L100 -P ${NPROC} "${CLANG_FORMAT}" ${VERBOSITY} -i -style=file -fallback-style=none

13
.github/scripts/package-linux.sh vendored Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/sh
if ! type zsh > /dev/null 2>&1; then
echo ' => Installing script dependency Zsh.'
sudo apt-get update
sudo apt-get install zsh
fi
SCRIPT=$(readlink -f "${0}")
SCRIPT_DIR=$(dirname "${SCRIPT}")
zsh ${SCRIPT_DIR}/package-linux.zsh "${@}"

1
.github/scripts/package-linux.zsh vendored Symbolic link
View File

@@ -0,0 +1 @@
.package.zsh

1
.github/scripts/package-macos.zsh vendored Symbolic link
View File

@@ -0,0 +1 @@
.package.zsh

View File

@@ -0,0 +1,25 @@
function Check-Git {
<#
.SYNOPSIS
Ensures available git executable on host system.
.DESCRIPTION
Checks whether a git command is available on the host system. If none is found,
Git is installed via winget.
.EXAMPLE
Check-Git
#>
if ( ! ( Test-Path function:Log-Info ) ) {
. $PSScriptRoot/Logger.ps1
}
Log-Information 'Checking for Git executable...'
if ( ! ( Get-Command git ) ) {
Log-Warning 'No Git executable found. Will try to install via winget.'
winget install git
} else {
Log-Debug "Git found at $(Get-Command git)."
Log-Status "Git found."
}
}

View File

@@ -0,0 +1,29 @@
function Ensure-Location {
<#
.SYNOPSIS
Ensures current location to be set to specified directory.
.DESCRIPTION
If specified directory exists, switch to it. Otherwise create it,
then switch.
.EXAMPLE
Ensure-Location "My-Directory"
Ensure-Location -Path "Path-To-My-Directory"
#>
param(
[Parameter(Mandatory)]
[string] $Path
)
if ( ! ( Test-Path $Path ) ) {
$_Params = @{
ItemType = "Directory"
Path = ${Path}
ErrorAction = "SilentlyContinue"
}
New-Item @_Params | Set-Location
} else {
Set-Location -Path ${Path}
}
}

View File

@@ -0,0 +1,70 @@
function Expand-ArchiveExt {
<#
.SYNOPSIS
Expands archive files.
.DESCRIPTION
Allows extraction of zip, 7z, gz, and xz archives.
Requires tar and 7-zip to be available on the system.
Archives ending with .zip but created using LZMA compression are
expanded using 7-zip as a fallback.
.EXAMPLE
Expand-ArchiveExt -Path <Path-To-Your-Archive>
Expand-ArchiveExt -Path <Path-To-Your-Archive> -DestinationPath <Expansion-Path>
#>
param(
[Parameter(Mandatory)]
[string] $Path,
[string] $DestinationPath = [System.IO.Path]::GetFileNameWithoutExtension($Path),
[switch] $Force
)
switch ( [System.IO.Path]::GetExtension($Path) ) {
.zip {
try {
Expand-Archive -Path $Path -DestinationPath $DestinationPath -Force:$Force
} catch {
if ( Get-Command 7z ) {
Invoke-External 7z x -y $Path "-o${DestinationPath}"
} else {
throw "Fallback utility 7-zip not found. Please install 7-zip first."
}
}
break
}
{ ( $_ -eq ".7z" ) -or ( $_ -eq ".exe" ) } {
if ( Get-Command 7z ) {
Invoke-External 7z x -y $Path "-o${DestinationPath}"
} else {
throw "Extraction utility 7-zip not found. Please install 7-zip first."
}
break
}
.gz {
try {
Invoke-External tar -x -o $DestinationPath -f $Path
} catch {
if ( Get-Command 7z ) {
Invoke-External 7z x -y $Path "-o${DestinationPath}"
} else {
throw "Fallback utility 7-zip not found. Please install 7-zip first."
}
}
break
}
.xz {
try {
Invoke-External tar -x -o $DestinationPath -f $Path
} catch {
if ( Get-Command 7z ) {
Invoke-External 7z x -y $Path "-o${DestinationPath}"
} else {
throw "Fallback utility 7-zip not found. Please install 7-zip first."
}
}
}
default {
throw "Unsupported archive extension provided."
}
}
}

View File

@@ -0,0 +1,60 @@
function Install-BuildDependencies {
<#
.SYNOPSIS
Installs required build dependencies.
.DESCRIPTION
Additional packages might be needed for successful builds. This module contains additional
dependencies available for installation via winget and, if possible, adds their locations
to the environment path for future invocation.
.EXAMPLE
Install-BuildDependencies
#>
param(
[string] $WingetFile = "$PSScriptRoot/.Wingetfile"
)
if ( ! ( Test-Path function:Log-Warning ) ) {
. $PSScriptRoot/Logger.ps1
}
$Host64Bit = [System.Environment]::Is64BitOperatingSystem
$Paths = $Env:Path -split [System.IO.Path]::PathSeparator
$WingetOptions = @('install', '--accept-package-agreements', '--accept-source-agreements')
if ( $script:Quiet ) {
$WingetOptions += '--silent'
}
Get-Content $WingetFile | ForEach-Object {
$_, $Package, $_, $Path, $_, $Binary = ([regex]::Split($_, " (?=(?:[^']|'[^']*')*$)")) -replace ',', '' -replace "'",''
(${Env:ProgramFiles(x86)}, $Env:ProgramFiles) | ForEach-Object {
$Prefix = $_
$FullPath = "${Prefix}\${Path}"
if ( ( Test-Path $FullPath ) -and ! ( $Paths -contains $FullPath ) ) {
$Paths += $FullPath
$Env:Path = $Paths -join [System.IO.Path]::PathSeparator
}
}
Log-Debug "Checking for command ${Binary}"
$Found = Get-Command -ErrorAction SilentlyContinue $Binary
if ( $Found ) {
Log-Status "Found dependency ${Binary} as $($Found.Source)"
} else {
Log-Status "Installing package ${Package}"
try {
$Params = $WingetOptions + $Package
winget @Params
} catch {
throw "Error while installing winget package ${Package}: $_"
}
}
}
}

View File

@@ -0,0 +1,40 @@
function Invoke-External {
<#
.SYNOPSIS
Invokes a non-PowerShell command.
.DESCRIPTION
Runs a non-PowerShell command, and captures its return code.
Throws an exception if the command returns non-zero.
.EXAMPLE
Invoke-External 7z x $MyArchive
#>
if ( $args.Count -eq 0 ) {
throw 'Invoke-External called without arguments.'
}
if ( ! ( Test-Path function:Log-Information ) ) {
. $PSScriptRoot/Logger.ps1
}
$Command = $args[0]
$CommandArgs = @()
if ( $args.Count -gt 1) {
$CommandArgs = $args[1..($args.Count - 1)]
}
$_EAP = $ErrorActionPreference
$ErrorActionPreference = "Continue"
Log-Debug "Invoke-External: ${Command} ${CommandArgs}"
& $command $commandArgs
$Result = $LASTEXITCODE
$ErrorActionPreference = $_EAP
if ( $Result -ne 0 ) {
throw "${Command} ${CommandArgs} exited with non-zero code ${Result}."
}
}

View File

@@ -0,0 +1,117 @@
function Set-GitConfig {
<#
.SYNOPSIS
Sets a git config value.
.DESCRIPTION
Allows setting single or multiple config values in a PowerShell-friendly fashion.
.EXAMPLE
Set-GitConfig advice.detachedHead false
#>
if ( $args.Count -lt 2 ) {
throw 'Set-GitConfig called without required arguments <OPTION> <VALUE>.'
}
Invoke-External git config @args
}
function Invoke-GitCheckout {
<#
.SYNOPSIS
Checks out a specified git repository.
.DESCRIPTION
Wraps the git executable with PowerShell syntax to check out
a specified Git repository with a given commit hash and branch,
or a GitHub pull request ID.
.EXAMPLE
Invoke-GitCheckout -Uri "My-Repo-Uri" -Commit "My-Commit-Hash"
Invoke-GitCheckout -Uri "My-Repo-Uri" -Commit "My-Commit-Hash" -Branch "main"
Invoke-GitCheckout -Uri "My-Repo-Uri" -Commit "My-Commit-Hash" -PullRequest 250
#>
param(
[Parameter(Mandatory)]
[string] $Uri,
[Parameter(Mandatory)]
[string] $Commit,
[string] $Path,
[string] $Branch = "master",
[string] $PullRequest
)
if ( ! ( $Uri -like "*github.com*" ) -and ( $PullRequest -ne "" ) ) {
throw 'Fetching pull requests is only supported with GitHub-based repositories.'
}
if ( ! ( Test-Path function:Log-Information ) ) {
. $PSScriptRoot/Logger.ps1
}
if ( ! ( Test-Path function:Invoke-External ) ) {
. $PSScriptRoot/Invoke-External.ps1
}
$RepositoryName = [System.IO.Path]::GetFileNameWithoutExtension($Uri)
if ( $Path -eq "" ) {
$Path = "$(Get-Location | Convert-Path)\${RepositoryName}"
}
Push-Location -Stack GitCheckoutTemp
if ( Test-Path $Path/.git ) {
Write-Information "Repository ${RepositoryName} found in ${Path}"
Set-Location $Path
Set-GitConfig advice.detachedHead false
Set-GitConfig remote.origin.url $Uri
Set-GitConfig remote.origin.tapOpt --no-tags
$Ref = "+refs/heads/{0}:refs/remotes/origin/{0}" -f $Branch
Set-GitConfig --replace-all remote.origin.fetch $Ref
if ( $PullRequest -ne "" ) {
try {
Invoke-External git show-ref --quiet --verify refs/heads/pr-$PullRequest
} catch {
Invoke-External git fetch origin $("pull/{0}/head:pull-{0}" -f $PullRequest)
} finally {
Invoke-External git checkout -f "pull-${PullRequest}"
}
}
try {
$null = Invoke-External git rev-parse -q --verify "${Commit}^{commit}"
} catch {
Invoke-External git fetch origin
}
Invoke-External git checkout -f $Commit -- | Log-Information
} else {
Invoke-External git clone $Uri $Path
Set-Location $Path
Set-GitConfig advice.detachedHead false
if ( $PullRequest -ne "" ) {
$Ref = "pull/{0}/head:pull-{0}" -f $PullRequest
$Branch = "pull-${PullRequest}"
Invoke-External git fetch origin $Ref
Invoke-External git checkout $Branch
}
Invoke-External git checkout -f $Commit
}
Log-Information "Checked out commit ${Commit} on branch ${Branch}"
if ( Test-Path ${Path}/.gitmodules ) {
Invoke-External git submodule foreach --recursive git submodule sync
Invoke-External git submodule update --init --recursive
}
Pop-Location -Stack GitCheckoutTemp
}

123
.github/scripts/utils.pwsh/Logger.ps1 vendored Normal file
View File

@@ -0,0 +1,123 @@
function Log-Debug {
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string[]] $Message
)
Process {
foreach($m in $Message) {
Write-Debug $m
}
}
}
function Log-Verbose {
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string[]] $Message
)
Process {
foreach($m in $Message) {
Write-Verbose $m
}
}
}
function Log-Warning {
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string[]] $Message
)
Process {
foreach($m in $Message) {
Write-Warning $m
}
}
}
function Log-Error {
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string[]] $Message
)
Process {
foreach($m in $Message) {
Write-Error $m
}
}
}
function Log-Information {
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string[]] $Message
)
Process {
if ( ! ( $script:Quiet ) ) {
$StageName = $( if ( $script:StageName -ne $null ) { $script:StageName } else { '' })
$Icon = ' =>'
foreach($m in $Message) {
Write-Host -NoNewLine -ForegroundColor Blue " ${StageName} $($Icon.PadRight(5)) "
Write-Host "${m}"
}
}
}
}
function Log-Status {
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string[]] $Message
)
Process {
if ( ! ( $script:Quiet ) ) {
$StageName = $( if ( $StageName -ne $null ) { $StageName } else { '' })
$Icon = ' >'
foreach($m in $Message) {
Write-Host -NoNewLine -ForegroundColor Green " ${StageName} $($Icon.PadRight(5)) "
Write-Host "${m}"
}
}
}
}
function Log-Output {
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string[]] $Message
)
Process {
if ( ! ( $script:Quiet ) ) {
$StageName = $( if ( $script:StageName -ne $null ) { $script:StageName } else { '' })
$Icon = ''
foreach($m in $Message) {
Write-Output " ${StageName} $($Icon.PadRight(5)) ${m}"
}
}
}
}
$Columns = (Get-Host).UI.RawUI.WindowSize.Width - 5

View File

@@ -0,0 +1,103 @@
function Setup-Host {
if ( ! ( Test-Path function:Log-Output ) ) {
. $PSScriptRoot/Logger.ps1
}
if ( ! ( Test-Path function:Ensure-Location ) ) {
. $PSScriptRoot/Ensure-Location.ps1
}
if ( ! ( Test-Path function:Install-BuildDependencies ) ) {
. $PSScriptRoot/Install-BuildDependencies.ps1
}
if ( ! ( Test-Path function:Expand-ArchiveExt ) ) {
. $PSScriptRoot/Expand-ArchiveExt.ps1
}
Install-BuildDependencies -WingetFile "${ScriptHome}/.Wingetfile"
if ( $script:Target -eq '' ) { $script:Target = $script:HostArchitecture }
$script:QtVersion = $BuildSpec.platformConfig."windows-${script:Target}".qtVersion
$script:VisualStudioVersion = $BuildSpec.platformConfig."windows-${script:Target}".visualStudio
$script:PlatformSDK = $BuildSpec.platformConfig."windows-${script:Target}".platformSDK
if ( ! ( ( $script:SkipAll ) -or ( $script:SkipDeps ) ) ) {
('prebuilt', "qt${script:QtVersion}") | ForEach-Object {
$_Dependency = $_
$_Version = $BuildSpec.dependencies."${_Dependency}".version
$_BaseUrl = $BuildSpec.dependencies."${_Dependency}".baseUrl
$_Label = $BuildSpec.dependencies."${_Dependency}".label
$_Hash = $BuildSpec.dependencies."${_Dependency}".hashes."windows-${script:Target}"
if ( $BuildSpec.dependencies."${_Dependency}".PSobject.Properties.Name -contains "pdb-hashes" ) {
$_PdbHash = $BuildSpec.dependencies."${_Dependency}".'pdb-hashes'."$windows-${script:Target}"
}
if ( $_Version -eq '' ) {
throw "No ${_Dependency} spec found in ${script:BuildSpecFile}."
}
Log-Information "Setting up ${_Label}..."
Push-Location -Stack BuildTemp
Ensure-Location -Path "$(Resolve-Path -Path "${ProjectRoot}/..")/obs-build-dependencies"
switch -wildcard ( $_Dependency ) {
prebuilt {
$_Filename = "windows-deps-${_Version}-${script:Target}.zip"
$_Uri = "${_BaseUrl}/${_Version}/${_Filename}"
$_Target = "plugin-deps-${_Version}-qt${script:QtVersion}-${script:Target}"
$script:DepsVersion = ${_Version}
}
"qt*" {
$_Filename = "windows-deps-qt${script:QtVersion}-${_Version}-${script:Target}.zip"
$_Uri = "${_BaseUrl}/${_Version}/${_Filename}"
$_Target = "plugin-deps-${_Version}-qt${script:QtVersion}-${script:Target}"
}
}
if ( ! ( Test-Path -Path $_Filename ) ) {
$Params = @{
UserAgent = 'NativeHost'
Uri = $_Uri
OutFile = $_Filename
UseBasicParsing = $true
ErrorAction = 'Stop'
}
Invoke-WebRequest @Params
Log-Status "Downloaded ${_Label} for ${script:Target}."
} else {
Log-Status "Found downloaded ${_Label}."
}
$_FileHash = Get-FileHash -Path $_Filename -Algorithm SHA256
if ( $_FileHash.Hash.ToLower() -ne $_Hash ) {
throw "Checksum of downloaded ${_Label} does not match specification. Expected '${_Hash}', 'found $(${_FileHash}.Hash.ToLower())'"
}
Log-Status "Checksum of downloaded ${_Label} matches."
if ( ! ( ( $script:SkipAll ) -or ( $script:SkipUnpack ) ) ) {
Push-Location -Stack BuildTemp
Ensure-Location -Path $_Target
Expand-ArchiveExt -Path "../${_Filename}" -DestinationPath . -Force
Pop-Location -Stack BuildTemp
}
Pop-Location -Stack BuildTemp
}
}
}
function Get-HostArchitecture {
$Host64Bit = [System.Environment]::Is64BitOperatingSystem
$HostArchitecture = ('x86', 'x64')[$Host64Bit]
return $HostArchitecture
}
$script:HostArchitecture = Get-HostArchitecture

View File

@@ -0,0 +1,84 @@
function Setup-Obs {
if ( ! ( Test-Path function:Log-Output ) ) {
. $PSScriptRoot/Logger.ps1
}
if ( ! ( Test-Path function:Check-Git ) ) {
. $PSScriptRoot/Check-Git.ps1
}
Check-Git
if ( ! ( Test-Path function:Ensure-Location ) ) {
. $PSScriptRoot/Ensure-Location.ps1
}
if ( ! ( Test-Path function:Invoke-GitCheckout ) ) {
. $PSScriptRoot/Invoke-GitCheckout.ps1
}
if ( ! ( Test-Path function:Invoke-External ) ) {
. $PSScriptRoot/Invoke-External.ps1
}
Log-Information 'Setting up OBS Studio...'
$ObsVersion = $BuildSpec.dependencies.'obs-studio'.version
$ObsRepository = $BuildSpec.dependencies.'obs-studio'.repository
$ObsBranch = $BuildSpec.dependencies.'obs-studio'.branch
$ObsHash = $BuildSpec.dependencies.'obs-studio'.hash
if ( $ObsVersion -eq '' ) {
throw 'No obs-studio version found in buildspec.json.'
}
Push-Location -Stack BuildTemp
Ensure-Location -Path "$(Resolve-Path -Path "${ProjectRoot}/../")/obs-studio"
if ( ! ( ( $script:SkipAll ) -or ( $script:SkipUnpack ) ) ) {
Invoke-GitCheckout -Uri $ObsRepository -Commit $ObsHash -Path . -Branch $ObsBranch
}
if ( ! ( ( $script:SkipAll ) -or ( $script:SkipBuild ) ) ) {
Log-Information 'Configuring OBS Studio...'
$NumProcessors = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors
if ( $NumProcessors -gt 1 ) {
$env:UseMultiToolTask = $true
$env:EnforceProcessCountAcrossBuilds = $true
}
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
$CmakeArgs = @(
'-G', $CmakeGenerator
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
"-DCMAKE_BUILD_TYPE=${script:Configuration}"
"-DQT_VERSION=${script:QtVersion}"
'-DENABLE_PLUGINS=OFF'
'-DENABLE_UI=OFF'
'-DENABLE_SCRIPTING=OFF'
"-DCMAKE_INSTALL_PREFIX:PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/${DepsPath}")"
"-DCMAKE_PREFIX_PATH:PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/${DepsPath}")"
)
Log-Debug "Attempting to configure OBS with CMake arguments: $($CmakeArgs | Out-String)"
Log-Information "Configuring OBS..."
Invoke-External cmake -S . -B plugin_build_${script:Target} @CmakeArgs
Log-Information 'Building libobs and obs-frontend-api...'
$CmakeArgs = @(
'--config', "$( if ( $script:Configuration -eq '' ) { 'RelWithDebInfo' } else { $script:Configuration })"
)
if ( $VerbosePreference -eq 'Continue' ) {
$CmakeArgs+=('--verbose')
}
Invoke-External cmake --build plugin_build_${script:Target} @CmakeArgs -t obs-frontend-api
Invoke-External cmake --install plugin_build_${script:Target} @CmakeArgs --component obs_libraries
}
Pop-Location -Stack BuildTemp
}

36
.github/scripts/utils.zsh/check_linux vendored Executable file
View File

@@ -0,0 +1,36 @@
autoload -Uz log_info log_status log_error log_debug log_warning
log_debug 'Checking for apt-get...'
if (( ! ${+commands[apt-get]} )) {
log_error 'No apt-get command found. Please install apt'
return 2
} else {
log_debug "Apt-get located at ${commands[apt-get]}"
}
local -a dependencies=("${(f)$(<${SCRIPT_HOME}/.Aptfile)}")
local -a install_list
local binary
for dependency (${dependencies}) {
local -a tokens=(${(s: :)dependency//(,|:|\')/})
if [[ ! ${tokens[1]} == 'package' ]] continue
if [[ ${#tokens} -gt 2 && ${tokens[3]} == 'bin' ]] {
binary=${tokens[4]}
} else {
binary=${tokens[2]}
}
if (( ! ${+commands[${binary}]} )) install_list+=(${tokens[2]})
}
local -a _quiet=('' '--quiet')
log_debug "List of dependencies to install: ${install_list}"
if (( ${#install_list} )) {
if (( ! ${+CI} )) log_warning 'Dependency installation via apt may require elevated privileges'
sudo apt-get -y install ${install_list} ${_quiet[(( (_loglevel == 0) + 1 ))]}
}

20
.github/scripts/utils.zsh/check_macos vendored Executable file
View File

@@ -0,0 +1,20 @@
autoload -Uz is-at-least log_info log_error log_status read_codesign
local macos_version=$(sw_vers -productVersion)
log_info 'Checking macOS version...'
if ! is-at-least 11.0 "${macos_version}"; then
log_error "Minimum required macOS version is 11.0, but running on macOS ${macos_version}"
return 2
else
log_status "macOS ${macos_version} is recent"
fi
log_info 'Checking for Homebrew...'
if (( ! ${+commands[brew]} )) {
log_error 'No Homebrew command found. Please install Homebrew (https://brew.sh)'
return 2
}
brew bundle --file "${SCRIPT_HOME}/.Brewfile"
rehash

52
.github/scripts/utils.zsh/check_packages vendored Executable file
View File

@@ -0,0 +1,52 @@
if (( ! ${+commands[packagesbuild]} )) {
autoload -Uz log_info log_status mkcd
if (( ! ${+commands[curl]} )) {
log_error 'curl not found. Please install curl.'
return 2
}
if (( ! ${+project_root} )) {
log_error "'project_root' not set. Please set before running ${0}."
return 2
}
local -a curl_opts=()
if (( ! ${+CI} )) {
curl_opts+=(--progress-bar)
} else {
curl_opts+=(--show-error --silent)
}
curl_opts+=(--location -O ${@})
log_info 'Installing Packages.app...'
pushd
mkcd ${project_root:h}/obs-build-dependencies
local packages_url='http://s.sudre.free.fr/Software/files/Packages.dmg'
local packages_hash='6afdd25386295974dad8f078b8f1e41cabebd08e72d970bf92f707c7e48b16c9'
if [[ ! -f Packages.dmg ]] {
log_status 'Download Packages.app'
curl ${curl_opts} ${packages_url}
}
local image_checksum
read -r image_checksum _ <<< "$(sha256sum Packages.dmg)"
if [[ ${packages_hash} != ${image_checksum} ]] {
log_error "Checksum mismatch of Packages.app download.
Expected : ${packages_hash}
Actual : ${image_checksum}"
return 2
}
hdiutil attach -noverify Packages.dmg &> /dev/null && log_status 'Packages.dmg image mounted.'
log_info 'Installing Packages.app...'
packages_volume=$(hdiutil info -plist | grep '<string>/Volumes/Packages' | sed 's/.*<string>\(\/Volumes\/[^<]*\)<\/string>/\1/')
sudo installer -pkg "${packages_volume}/packages/Packages.pkg" -target / && rehash
hdiutil detach ${packages_volume} &> /dev/null && log_status 'Packages.dmg image unmounted.'
}

3
.github/scripts/utils.zsh/log_debug vendored Executable file
View File

@@ -0,0 +1,3 @@
if (( ! ${+_loglevel} )) typeset -g _loglevel=1
if (( _loglevel > 2 )) print -PR -e -- "%F{220}DEBUG: ${@}%f"

3
.github/scripts/utils.zsh/log_error vendored Executable file
View File

@@ -0,0 +1,3 @@
local icon=' ✖︎ '
print -u2 -PR "%F{1} ${icon} %f ${@}"

7
.github/scripts/utils.zsh/log_info vendored Executable file
View File

@@ -0,0 +1,7 @@
if (( ! ${+_loglevel} )) typeset -g _loglevel=1
if (( _loglevel > 0 )) {
local icon=' =>'
print -PR "%F{4} ${(r:5:)icon}%f %B${@}%b"
}

7
.github/scripts/utils.zsh/log_output vendored Executable file
View File

@@ -0,0 +1,7 @@
if (( ! ${+_loglevel} )) typeset -g _loglevel=1
if (( _loglevel > 0 )) {
local icon=''
print -PR " ${(r:5:)icon} ${@}"
}

7
.github/scripts/utils.zsh/log_status vendored Executable file
View File

@@ -0,0 +1,7 @@
if (( ! ${+_loglevel} )) typeset -g _loglevel=1
if (( _loglevel > 0 )) {
local icon=' >'
print -PR "%F{2} ${(r:5:)icon}%f ${@}"
}

5
.github/scripts/utils.zsh/log_warning vendored Executable file
View File

@@ -0,0 +1,5 @@
if (( _loglevel > 0 )) {
local icon=' =>'
print -PR "%F{3} ${(r:5:)icon} ${@}%f"
}

1
.github/scripts/utils.zsh/mkcd vendored Executable file
View File

@@ -0,0 +1 @@
[[ -n ${1} ]] && mkdir -p ${1} && builtin cd ${1}

7
.github/scripts/utils.zsh/read_codesign vendored Executable file
View File

@@ -0,0 +1,7 @@
autoload -Uz log_info
if (( ! ${+CODESIGN_IDENT} )) {
typeset -g CODESIGN_IDENT
log_info 'Setting up identity for application codesigning...'
read CODESIGN_IDENT'?Apple Developer Application ID: '
}

View File

@@ -0,0 +1,7 @@
autoload -Uz log_info
if (( ! ${+CODESIGN_IDENT_INSTALLER} )) {
typeset -g CODESIGN_IDENT_INSTALLER
log_info 'Setting up identity for installer package codesigning...'
read CODESIGN_IDENT_INSTALLER'?Apple Developer Installer ID: '
}

33
.github/scripts/utils.zsh/read_codesign_pass vendored Executable file
View File

@@ -0,0 +1,33 @@
##############################################################################
# Apple Developer credentials necessary:
#
# + Signing for distribution and notarization require an active Apple
# Developer membership
# + An Apple Development identity is needed for code signing
# (i.e. 'Apple Development: YOUR APPLE ID (PROVIDER)')
# + Your Apple developer ID is needed for notarization
# + An app-specific password is necessary for notarization from CLI
# + This password will be stored in your macOS keychain under the identifier
# 'OBS-Codesign-Password'with access Apple's 'altool' only.
##############################################################################
autoload -Uz read_codesign read_codesign_user log_info
if (( ! ${+CODESIGN_IDENT} )) {
read_codesign
}
local codesign_ident_short=$(print "${CODESIGN_IDENT}" | /usr/bin/sed -En 's/.+\((.+)\)/\1/p')
if (( ! ${+CODESIGN_IDENT_USER} )) {
read_codesign_user
}
log_info 'Setting up password for notarization keychain...'
if (( ! ${+CODESIGN_IDENT_PASS} )) {
read -s CODESIGN_IDENT_PASS'?Apple Developer ID password: '
}
print ''
log_info 'Setting up notarization keychain...'
xcrun notarytool store-credentials 'OBS-Codesign-Password' --apple-id "${CODESIGN_IDENT_USER}" --team-id "${codesign_ident_short}" --password "${CODESIGN_IDENT_PASS}"

View File

@@ -0,0 +1,7 @@
autoload -Uz log_info
if (( ! ${+CODESIGN_IDENT_USER} )) {
typeset -g CODESIGN_IDENT_USER
log_info 'Setting up developer id for codesigning...'
read CODESIGN_IDENT_USER'?Apple Developer ID: '
}

17
.github/scripts/utils.zsh/set_loglevel vendored Executable file
View File

@@ -0,0 +1,17 @@
autoload -Uz log_debug log_error
local -r _usage="Usage: %B${0}%b <loglevel>
Set log level, following levels are supported: 0 (quiet), 1 (normal), 2 (verbose), 3 (debug)"
if (( ! # )); then
log_error 'Called without arguments.'
log_output ${_usage}
return 2
elif (( ${1} >= 4 )); then
log_error 'Called with loglevel > 3.'
log_output ${_usage}
fi
typeset -g -i -r _loglevel=${1}
log_debug "Log level set to '${1}'"

14
.github/scripts/utils.zsh/setup_ccache vendored Executable file
View File

@@ -0,0 +1,14 @@
autoload -Uz log_debug log_warning
if (( ${+commands[ccache]} )) {
log_debug "Found ccache at ${commands[ccache]}"
if (( ${+CI} )) {
ccache --set-config=cache_dir="${GITHUB_WORKSPACE:-${HOME}}/.ccache"
ccache --set-config=max_size="${CCACHE_SIZE:-500M}"
ccache --set-config=compression=true
ccache -z > /dev/null
}
} else {
log_warning "No ccache found on the system"
}

70
.github/scripts/utils.zsh/setup_linux vendored Executable file
View File

@@ -0,0 +1,70 @@
autoload -Uz log_error log_status log_info mkcd
if (( ! ${+project_root} )) {
log_error "'project_root' not set. Please set before running ${0}."
return 2
}
if (( ! ${+target} )) {
log_error "'target' not set. Please set before running ${0}."
return 2
}
pushd ${project_root}
typeset -g QT_VERSION
read -r QT_VERSION <<< \
"$(jq -r --arg target "${target}" \
'.platformConfig[$target] | { qtVersion } | join(" ")' \
${project_root}/buildspec.json)"
if (( ! (${skips[(Ie)all]} + ${skips[(Ie)deps]}) )) {
log_info 'Installing obs build dependencies...'
sudo apt-get install -y \
build-essential \
libcurl4-openssl-dev \
libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev \
libswresample-dev libswscale-dev \
libjansson-dev \
libx11-xcb-dev \
libgles2-mesa-dev \
libwayland-dev \
libpulse-dev
log_info 'Installing obs plugin dependencies...'
sudo apt-get install -y \
libxtst-dev \
libxss-dev \
libopencv-dev \
libprocps-dev
local -a _qt_packages=()
if (( QT_VERSION == 5 )) {
_qt_packages+=(
qtbase5-dev
libqt5svg5-dev
qtbase5-private-dev
libqt5x11extras5-dev
)
} elif (( QT_VERSION == 6 )) {
_qt_packages+=(
qt6-base-dev
libqt6svg6-dev
qt6-base-private-dev
)
} else {
log_error "Unsupported Qt version '${QT_VERSION}' specified."
return 2
}
sudo apt-get install -y ${_qt_packages}
}
local deps_version
read -r deps_version <<< \
"$(jq -r '.dependencies.prebuilt.version' ${buildspec_file})"
typeset -g OBS_DEPS_VERSION=${deps_version}

127
.github/scripts/utils.zsh/setup_macos vendored Executable file
View File

@@ -0,0 +1,127 @@
autoload -Uz log_error log_status log_info mkcd
if (( ! ${+commands[curl]} )) {
log_error 'curl not found. Please install curl.'
return 2
}
if (( ! ${+commands[jq]} )) {
log_error 'jq not found. Please install jq.'
return 2
}
if (( ! ${+project_root} )) {
log_error "'project_root' not set. Please set before running ${0}."
return 2
}
if (( ! ${+target} )) {
log_error "'target' not set. Please set before running ${0}."
return 2
}
local -a curl_opts=()
if (( ! ${+CI} )) {
curl_opts+=(--progress-bar)
} else {
curl_opts+=(--show-error --silent)
}
curl_opts+=(--location -O ${@})
pushd ${project_root}
local _qt_version
local _deployment_target
read -r _qt_version _deployment_target <<< \
"$(jq -r --arg target "${target}" \
'.platformConfig[$target] | { qtVersion, deploymentTarget } | join (" ")' \
${buildspec_file})"
typeset -g QT_VERSION=${_qt_version}
typeset -g DEPLOYMENT_TARGET=${_deployment_target}
if (( ! (${skips[(Ie)all]} + ${skips[(Ie)deps]}) )) {
mkdir -p ${project_root:h}/obs-build-dependencies
local dependency
local deps_version
local deps_baseurl
local deps_label
local deps_hash
local _filename
local _url
local _target
local artifact_checksum
for dependency ('prebuilt' "qt${QT_VERSION}") {
IFS=';' read -r deps_version deps_baseurl deps_label deps_hash <<< \
"$(jq -r --arg dependency "${dependency}" --arg target "${target}" \
'.dependencies[$dependency] | {version, baseUrl, "label", "hash": .hashes[$target]} | join(";")' \
${buildspec_file})"
if [[ -z "${deps_version}" ]] {
log_error "No ${dependency} spec found in ${buildspec_file}."
return 2
}
log_info "Setting up ${deps_label}..."
pushd ${project_root:h}/obs-build-dependencies
case ${dependency} {
prebuilt)
_filename="macos-deps-${deps_version}-${target##*-}.tar.xz"
_url="${deps_baseurl}/${deps_version}/${_filename}"
_target="plugin-deps-${deps_version}-qt${QT_VERSION}-${target##*-}"
typeset -g OBS_DEPS_VERSION=${deps_version}
;;
qt*)
if (( ${+CI} )) {
_filename="macos-deps-qt${QT_VERSION}-${deps_version}-universal.tar.xz"
deps_hash="$(jq -r --arg dependency "${dependency}" \
'.dependencies[$dependency].hashes["macos-universal"]' \
${buildspec_file})"
} else {
_filename="macos-deps-qt${QT_VERSION}-${deps_version}-${target##*-}.tar.xz"
}
_url="${deps_baseurl}/${deps_version}/${_filename}"
_target="plugin-deps-${deps_version}-qt${QT_VERSION}-${target##*-}"
;;
}
if [[ ! -f ${_filename} ]] {
log_debug "Running curl ${curl_opts} ${_url}"
curl ${curl_opts} ${_url} && \
log_status "Downloaded ${deps_label} for ${target}."
} else {
log_status "Found downloaded ${deps_label}"
}
read -r artifact_checksum _ <<< "$(sha256sum ${_filename})"
if [[ ${deps_hash} != ${artifact_checksum} ]] {
log_error "Checksum of downloaded ${deps_label} does not match specification.
Expected : ${deps_hash}
Actual : ${artifact_checksum}"
return 2
}
log_status "Checksum of downloaded ${deps_label} matches."
if (( ! (${skips[(Ie)all]} + ${skips[(Ie)unpack]}) )) {
mkdir -p ${_target} && pushd ${_target}
XZ_OPT=-T0 tar -xzf ../${_filename} && log_status "${deps_label} extracted."
popd
}
}
popd
pushd ${project_root:h}/obs-build-dependencies
xattr -r -d com.apple.quarantine *
log_status 'Removed quarantine flag from downloaded dependencies...'
popd
} else {
local deps_version
read -r deps_version <<< \
"$(jq -r '.dependencies.prebuilt.version' ${buildspec_file})"
typeset -g OBS_DEPS_VERSION=${deps_version}
}

122
.github/scripts/utils.zsh/setup_obs vendored Executable file
View File

@@ -0,0 +1,122 @@
autoload -Uz log_error log_info log_status
if (( ! ${+buildspec_file} )) {
log_error "'buildspec_file' not set. Please set before running ${0}."
return 2
}
if (( ! ${+commands[git]} )) {
log_error 'git not found. Please install git.'
return 2
}
if (( ! ${+commands[jq]} )) {
log_error 'jq not found. Please install jq.'
return 2
}
if (( ! ${+project_root} )) {
log_error "'project_root' not set. Please set before running ${0}."
return 2
}
if (( ! ${+target} )) {
log_error "'target' not set. Please set before running ${0}."
return 2
}
log_info 'Setting up OBS-Studio...'
local obs_version
local obs_repo
local obs_branch
local obs_hash
read -r obs_version obs_repo obs_branch obs_hash <<< \
"$(jq -r --arg key "obs-studio" \
'.dependencies[$key] | {version, repository, branch, hash} | join(" ")' \
${buildspec_file})"
if [[ -z ${obs_version} ]] {
log_error "No obs-studio version found in buildspec.json"
return 2
}
pushd
mkcd ${project_root:h}/obs-studio
if (( ! (${skips[(Ie)all]} + ${skips[(Ie)unpack]}) )) {
if [[ -d .git ]] {
git config advice.detachedHead false
git config remote.pluginbuild.url "${obs_repo:-https://github.com/obsproject/obs-studio.git}"
git config remote.pluginbuild.fetch "+refs/heads/${obs_branch:-master}:refs/remotes/origin/${obs_branch:-master}"
git rev-parse -q --verify "${obs_hash}^{commit}" > /dev/null || git fetch pluginbuild
git checkout ${obs_branch:-master} -B ${product_name}
git reset --hard "${obs_hash}"
log_status 'Found existing obs-studio repository.'
} else {
git clone "${obs_repo:-https://github.com/obsproject/obs-studio.git}" "${PWD}"
git config advice.detachedHead false
git checkout -f "${obs_hash}" --
git checkout ${obs_branch:-master} -b ${product_name}
log_status 'obs-studio checked out.'
}
git submodule foreach --recursive git submodule sync
git submodule update --init --recursive
}
if (( ! (${skips[(Ie)all]} + ${skips[(Ie)build]}) )) {
log_info 'Configuring obs-studio...'
local -a cmake_args=(
-DCMAKE_BUILD_TYPE=${BUILD_CONFIG:-Release}
-DQT_VERSION=${QT_VERSION}
-DENABLE_PLUGINS=OFF
-DENABLE_UI=OFF
-DENABLE_SCRIPTING=OFF
-DCMAKE_INSTALL_PREFIX="${project_root:h}/obs-build-dependencies/plugin-deps-${OBS_DEPS_VERSION}-qt${QT_VERSION}-${target##*-}"
-DCMAKE_PREFIX_PATH="${project_root:h}/obs-build-dependencies/plugin-deps-${OBS_DEPS_VERSION}-qt${QT_VERSION}-${target##*-}"
)
if (( _loglevel == 0 )) cmake_args+=(-Wno_deprecated -Wno-dev --log-level=ERROR)
if (( _loglevel > 2 )) cmake_args+=(--debug-output)
local num_procs
case ${target} {
macos-*)
autoload -Uz read_codesign
if (( ${+CODESIGN} )) {
read_codesign
}
cmake_args+=(
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
-DOBS_CODESIGN_LINKER=ON
-DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}"
)
num_procs=$(( $(sysctl -n hw.ncpu) + 1 ))
;;
linux-*)
cmake_args+=(
-DENABLE_PIPEWIRE=OFF
)
num_procs=$(( $(nproc) + 1 ))
;;
}
log_debug "Attempting to configure OBS with CMake arguments: ${cmake_args}"
cmake -S . -B plugin_build_${target##*-} -G ${generator} ${cmake_args}
log_info 'Building libobs and obs-frontend-api...'
local -a cmake_args=()
if (( _loglevel > 1 )) cmake_args+=(--verbose)
if [[ ${generator} == 'Unix Makefiles' ]] cmake_args+=(--parallel ${num_procs})
cmake --build plugin_build_${target##*-} --config ${BUILD_CONFIG:-Release} ${cmake_args} -t obs-frontend-api
cmake --install plugin_build_${target##*-} --config ${BUILD_CONFIG:-Release} --component obs_libraries ${cmake_args}
}
popd

View File

@@ -1,55 +0,0 @@
name: debian-build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: "recursive"
- name: check_libobs_revision
run: |
sudo apt update
sudo apt install libobs-dev
mkdir source
cd source
dpkg -l libobs-dev | tr -s " "| grep libobs | cut -d" " -f3 > libobs.rev
- name: install_frontend_header
run: |
[ -e /usr/include/obs/obs-frontend-api.h ] && { echo "ERROR: obs-frontend-api.h already in system. Maybe the package libobs-dev is installing it."; exit 1; }
cd source
LIBOBSREV=$(cat libobs.rev)
sudo apt update
sudo apt install devscripts
dget -u http://archive.ubuntu.com/ubuntu/pool/universe/o/obs-studio/obs-studio_$LIBOBSREV.dsc
cd ..
sudo find -name obs-frontend-api.h -exec cp {} /usr/include/obs/ \;
egrep '#include <obs.h>' /usr/include/obs/obs-frontend-api.h || { echo "ERROR: check if the sed commands are needed from now."; exit 1; }
sudo sed -i 's/#include <obs.h>/#include <obs\/obs.h>/' /usr/include/obs/obs-frontend-api.h
sudo sed -i 's/#include <util\/darray.h>/#include <obs\/util\/darray.h>/' /usr/include/obs/obs-frontend-api.h
- name: create_tarball
run: |
cd ..
tar --exclude=.git -cvzf obs-scene-switcher_0.1+testonly.orig.tar.gz SceneSwitcher
- name: create_debian_dir
run: |
cp -a CI/linux/debian .
- name: install_dependencies
run: |
# devscripts and libobs-dev are needed but they were already installed
# from check_libobs_revision and install_frontend_header sections.
sudo apt update
sudo apt install cmake debhelper libcurl4-openssl-dev libxss-dev libxtst-dev qtbase5-dev libopencv-dev libprocps-dev
- name: build
run: |
debuild --no-lintian --no-sign
mv ../*.deb .
- name: Publish
if: success()
uses: actions/upload-artifact@v2.2.1
with:
name: "obs-scene-switcher.deb"
path: ${{ github.workspace }}/*.deb

View File

@@ -1,380 +0,0 @@
name: build obs plugin
on: [push, pull_request, workflow_dispatch]
env:
PLUGIN_NAME: SceneSwitcher
LIB_NAME: advanced-scene-switcher
OBS_TAG: 27.2.0
jobs:
macos64:
name: "macOS 64-bit"
runs-on: [macos-latest]
env:
QT_VERSION: "5.15.2"
MACOS_DEPS_VERSION: "2020-12-11"
steps:
- name: Checkout
uses: actions/checkout@v2.3.4
with:
repository: obsproject/obs-studio
submodules: "recursive"
ref: "refs/tags/${{ env.OBS_TAG }}"
- name: "Checkout plugin"
uses: actions/checkout@v2.3.4
with:
path: UI/frontend-plugins/${{ env.PLUGIN_NAME }}
submodules: "recursive"
- name: Fetch Git Tags
run: |
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}
git fetch --prune --tags --unshallow
- name: "Install prerequisites (Homebrew)"
shell: bash
run: |
if [ -d /usr/local/opt/openssl@1.0.2t ]; then
brew uninstall openssl@1.0.2t
brew untap local/openssl
fi
if [ -d /usr/local/opt/python@2.7.17 ]; then
brew uninstall python@2.7.17
brew untap local/python2
fi
brew bundle --file ./CI/scripts/macos/Brewfile
- name: "Install prerequisite: Pre-built dependencies"
if: steps.deps-cache.outputs.cache-hit != 'true'
shell: bash
run: |
curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.MACOS_DEPS_VERSION }}/macos-deps-${{ env.MACOS_DEPS_VERSION }}.tar.gz
tar -xf ./macos-deps-${{ env.MACOS_DEPS_VERSION }}.tar.gz -C "/tmp"
- name: "Install prerequisite: Pre-built dependency Qt"
if: steps.deps-qt-cache.outputs.cache-hit != 'true'
shell: bash
run: |
curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.MACOS_DEPS_VERSION }}/macos-qt-${{ env.QT_VERSION }}-${{ env.MACOS_DEPS_VERSION }}.tar.gz
tar -xf ./macos-qt-${{ env.QT_VERSION }}-${{ env.MACOS_DEPS_VERSION }}.tar.gz -C "/tmp"
xattr -r -d com.apple.quarantine /tmp/obsdeps
- name: "Build prerequisite: OpenCV"
shell: bash
run: |
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}/deps/opencv
mkdir build
cd build
cmake -DBUILD_LIST="core,imgproc,objdetect" ..
make -j4
make install
- name: Configure
shell: bash
run: |
echo "add_subdirectory(${{ env.PLUGIN_NAME }})" >> UI/frontend-plugins/CMakeLists.txt
mkdir ./build
cd ./build
cmake -DBUILD_BROWSER=OFF -DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 -DDISABLE_PYTHON=ON -DDepsPath="/tmp/obsdeps" -DQTDIR="/tmp/obsdeps" ..
cd -
- name: Build
shell: bash
run: |
set -e
cd ./build
make -j4
cd -
- name: "Install prerequisite: Packages app"
if: success()
shell: bash
run: |
curl -L -O http://s.sudre.free.fr/Software/files/Packages.dmg
sudo hdiutil attach ./Packages.dmg
sudo installer -pkg /Volumes/Packages\ 1.2.10/Install\ Packages.pkg -target /
- name: Package
if: success()
shell: bash
run: |
fix_linker_paths() {
install_name_tool -change @rpath/libobs-frontend-api.dylib @executable_path/../Frameworks/libobs-frontend-api.dylib $1
install_name_tool -change @rpath/libobs.0.dylib @executable_path/../Frameworks/libobs.0.dylib $1
install_name_tool -change /tmp/obsdeps/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets $1
install_name_tool -change /tmp/obsdeps/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui $1
install_name_tool -change /tmp/obsdeps/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore $1
}
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}
fix_linker_paths ../../../build/UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
fix_linker_paths ../../../build/UI/frontend-plugins/SceneSwitcher/src/external-macro-modules/opencv/advanced-scene-switcher-opencv.so
FILE_DATE=$(date +%Y-%m-%d)
FILE_NAME=${{ env.PLUGIN_NAME }}-$FILE_DATE-${{ github.sha }}-macos.pkg
echo "FILE_NAME=${FILE_NAME}" >> $GITHUB_ENV
packagesbuild ./CI/macos/${{ env.PLUGIN_NAME }}.pkgproj
cd -
mkdir ./nightly
mv UI/frontend-plugins/${{ env.PLUGIN_NAME }}/${{ env.PLUGIN_NAME }}.pkg ./nightly/${FILE_NAME}
- name: Publish
if: success()
uses: actions/upload-artifact@v2.2.1
with:
name: "${{ env.FILE_NAME }}"
path: ./nightly/*.pkg
ubuntu64:
name: "Linux/Ubuntu 64-bit"
runs-on: [ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v2.3.4
with:
repository: obsproject/obs-studio
submodules: "recursive"
ref: "refs/tags/${{ env.OBS_TAG }}"
- name: "Checkout plugin"
uses: actions/checkout@v2.3.4
with:
path: UI/frontend-plugins/${{ env.PLUGIN_NAME }}
submodules: "recursive"
- name: Add plugin to obs cmake
shell: bash
run: echo "add_subdirectory(${{ env.PLUGIN_NAME }})" >> UI/frontend-plugins/CMakeLists.txt
- name: Fetch Git Tags
run: git fetch --prune --tags --unshallow
- name: Install prerequisites (Apt)
shell: bash
run: |
sudo dpkg --add-architecture amd64
sudo apt-get -qq update
sudo apt-get install -y \
build-essential \
checkinstall \
cmake \
libasound2-dev \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
libavformat-dev \
libavutil-dev \
libcurl4-openssl-dev \
libfdk-aac-dev \
libfontconfig-dev \
libfreetype6-dev \
libgl1-mesa-dev \
libjack-jackd2-dev \
libjansson-dev \
libluajit-5.1-dev \
libpulse-dev \
libqt5x11extras5-dev \
libspeexdsp-dev \
libswresample-dev \
libswscale-dev \
libudev-dev \
libv4l-dev \
libva-dev \
libvlc-dev \
libx11-dev \
libx264-dev \
libxcb-randr0-dev \
libxcb-shm0-dev \
libxcb-xinerama0-dev \
libxcomposite-dev \
libxinerama-dev \
libxtst-dev \
libmbedtls-dev \
pkg-config \
python3-dev \
qtbase5-dev \
qtbase5-private-dev \
libqt5svg5-dev \
swig \
libxss-dev \
libx11-xcb-dev \
libxcb-xfixes0-dev \
libopencv-dev \
libprocps-dev \
libpci-dev
- name: "Configure"
shell: bash
run: |
mkdir ./build
cd ./build
cmake -DENABLE_PIPEWIRE=OFF -DUNIX_STRUCTURE=0 -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/obs-studio-portable" -DWITH_RTMPS=OFF -DBUILD_BROWSER=OFF ..
- name: "Build"
shell: bash
working-directory: ${{ github.workspace }}/build
run: make -j4
- name: "Package"
shell: bash
run: |
FILE_DATE=$(date +%Y-%m-%d)
FILE_NAME=${{ env.PLUGIN_NAME }}-$FILE_DATE-${{ github.sha }}-linux64.tar.gz
echo "FILE_NAME=${FILE_NAME}" >> $GITHUB_ENV
mkdir -p ./${{ env.LIB_NAME }}/bin/64bit/
strip -d ./build/UI/frontend-plugins/${{ env.PLUGIN_NAME }}/${{ env.LIB_NAME }}.so
mv ./build/UI/frontend-plugins/${{ env.PLUGIN_NAME }}/${{ env.LIB_NAME }}.so ./${{ env.LIB_NAME }}/bin/64bit/${{ env.LIB_NAME }}.so
mv ./UI/frontend-plugins/${{ env.PLUGIN_NAME }}/data ./${{ env.LIB_NAME }}/data
# Macro modules
mkdir -p ./${{ env.LIB_NAME }}/bin/64bit/adv-ss-plugins
strip -d ./build/UI/frontend-plugins/${{ env.PLUGIN_NAME }}/src/external-macro-modules/opencv/advanced-scene-switcher-opencv.so
mv ./build/UI/frontend-plugins/${{ env.PLUGIN_NAME }}/src/external-macro-modules/opencv/advanced-scene-switcher-opencv.so ./${{ env.LIB_NAME }}/bin/64bit/adv-ss-plugins
tar -cvzf "${FILE_NAME}" ${{ env.LIB_NAME }}
- name: "Publish"
uses: actions/upload-artifact@v2.2.1
with:
name: "${{ env.FILE_NAME }}"
path: "*.tar.gz"
windows:
name: Windows
runs-on: [windows-latest]
strategy:
matrix:
arch: [32, 64]
env:
QT_VERSION: 5.15.2
CMAKE_GENERATOR: "Visual Studio 17 2022"
CMAKE_SYSTEM_VERSION: "10.0.18363.657"
WINDOWS_DEPS_VERSION: "2019"
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.2
- name: Checkout obs
uses: actions/checkout@v2.3.4
with:
repository: obsproject/obs-studio
submodules: "recursive"
ref: "refs/tags/${{ env.OBS_TAG }}"
- name: Checkout plugin
uses: actions/checkout@v2.3.4
with:
path: UI/frontend-plugins/${{ env.PLUGIN_NAME}}
submodules: "recursive"
- name: Add plugin to obs cmake
shell: cmd
run: echo add_subdirectory(${{ env.PLUGIN_NAME }}) >> UI/frontend-plugins/CMakeLists.txt
- name: Fetch Git Tags
run: git fetch --prune --tags --unshallow
- name: "Install prerequisite: QT"
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_${{ env.QT_VERSION }}.7z -f --retry 5 -C -
7z x Qt_${{ env.QT_VERSION }}.7z -o"${{ github.workspace }}/cmbuild/QT"
- name: "Install prerequisite: Pre-built dependencies"
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -f --retry 5 -C -
7z x dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -o"${{ github.workspace }}/cmbuild/deps"
- name: "Build prerequisite: OpenCV"
run: |
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}/deps/opencv
mkdir build
cd build
if ( ${{ matrix.arch }} -eq 32 )
{
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"Win32" -DBUILD_LIST="core,imgproc,objdetect" ..
}
else
{
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"x64" -DBUILD_LIST="core,imgproc,objdetect" ..
}
msbuild /m /p:Configuration=Release OpenCV.sln
msbuild INSTALL.vcxproj
- name: Configure
run: |
mkdir ./package
mkdir ./build${{ matrix.arch }}
cd ./build${{ matrix.arch }}
Get-Location
if ( ${{ matrix.arch }} -eq 32 )
{
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"Win32" -DOpenCV_DIR="${{ github.workspace }}/UI/frontend-plugins/SceneSwitcher/deps/opencv/build/" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DDepsPath="${{ github.workspace }}/cmbuild/deps/win32" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2019" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE ..
}
else
{
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"x64" -DOpenCV_DIR="${{ github.workspace }}/UI/frontend-plugins/SceneSwitcher/deps/opencv/build/" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DDepsPath="${{ github.workspace }}/cmbuild/deps/win64" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2019_64" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE ..
}
- name: Build
run: |
msbuild /m /p:Configuration=RelWithDebInfo .\build${{ matrix.arch }}\obs-studio.sln
- name: Package
if: success()
run: |
$env:FILE_DATE=(Get-Date -UFormat "%F")
$env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-windows"
echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV}
robocopy .\build${{ matrix.arch }}\rundir\RelWithDebInfo\obs-plugins\${{ matrix.arch }}bit\ .\package\obs-plugins\${{ matrix.arch }}bit ${{ env.LIB_NAME }}* /E /XF .gitignore
robocopy .\build${{ matrix.arch }}\rundir\RelWithDebInfo\obs-plugins\${{ matrix.arch }}bit\ .\package\obs-plugins\${{ matrix.arch }}bit adv-ss-plugins /E /XF .gitignore
robocopy .\build${{ matrix.arch }}\rundir\RelWithDebInfo\data\obs-plugins\${{ env.LIB_NAME }}\ .\package\data\obs-plugins\${{ env.LIB_NAME }}\ /E /XF .gitignore
cp UI/frontend-plugins/${{ env.PLUGIN_NAME }}/deps/opencv/build/bin/Release/*dll package/obs-plugins/${{ matrix.arch }}bit/adv-ss-plugins
cp UI/frontend-plugins/${{ env.PLUGIN_NAME }}/deps/openvr/bin/win${{ matrix.arch }}/*dll package/obs-plugins/${{ matrix.arch }}bit/adv-ss-plugins
exit 0
- name: Publish zip
if: success()
uses: actions/upload-artifact@v2.2.1
with:
name: "${{ env.FILE_NAME }}-${{ matrix.arch }}bit"
path: package/*
windows-installer:
needs: [windows]
name: "Create Windows Installer"
runs-on: [windows-latest]
steps:
- name: "Checkout plugin"
uses: actions/checkout@v2.3.4
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.2
- name: "Prepare innosetup"
run: |
curl "-kL" "https://files.jrsoftware.org/is/6/innosetup-6.0.3.exe" "-f" "--retry" "5" "-o" "inno.exe"
.\inno.exe /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART
mkdir build
cd build
cmake ..
continue-on-error: true
- name: Download artifacts
uses: actions/download-artifact@v2
with:
path: artifacts
- name: "Prepare package dir"
run: |
curl "-kL" "https://github.com/Xaymar/msvc-redist-helper/releases/download/0.1/msvc-redist-helper-64.exe" "-f" "--retry" "5" "-o" "msvc-redist-helper-64.exe"
curl "-kL" "https://github.com/Xaymar/msvc-redist-helper/releases/download/0.1/msvc-redist-helper-32.exe" "-f" "--retry" "5" "-o" "msvc-redist-helper-32.exe"
$env:FILE_DATE=(Get-Date -UFormat "%F")
$env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-windows"
echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV}
mkdir package
cd package
cp -r ../artifacts/${env:FILE_NAME}-32bit/* .
cp -r ../artifacts/${env:FILE_NAME}-64bit/obs-plugins/* obs-plugins
- name: "Compile"
run: |
& 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe' /Qp ".\build\CI\windows\setup.iss"
- name: "Publish"
if: success()
uses: actions/upload-artifact@v2.2.0
with:
name: "${{ env.FILE_NAME }}-installer"
path: build/CI/windows/Output/*.exe
release:
needs: [macos64, ubuntu64, windows, windows-installer]
name: "Create Release"
runs-on: [ubuntu-latest]
steps:
- name: "Checkout plugin"
uses: actions/checkout@v2.3.4
with:
path: plugin/${{ env.PLUGIN_NAME }}
- name: Download artifacts
uses: actions/download-artifact@v2
with:
path: artifacts
- name: "Package"
shell: bash
run: |
mkdir -p ${{ env.PLUGIN_NAME }}/Linux ${{ env.PLUGIN_NAME }}/MacOs ${{ env.PLUGIN_NAME }}/Windows
tar xf artifacts/${{ env.PLUGIN_NAME }}*-linux64.tar.gz/${{ env.PLUGIN_NAME }}*-linux64.tar.gz -C ${{ env.PLUGIN_NAME }}/Linux/
mv artifacts/${{ env.PLUGIN_NAME }}*-macos.pkg/${{ env.PLUGIN_NAME }}*-macos.pkg ${{ env.PLUGIN_NAME }}/MacOs/${{ env.PLUGIN_NAME }}.pkg
mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows-32bit/* ${{ env.PLUGIN_NAME }}/Windows/
mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows-64bit/obs-plugins/* ${{ env.PLUGIN_NAME }}/Windows/obs-plugins
mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows-installer/*.exe ${{ env.PLUGIN_NAME }}/Windows/
rm ${{ env.PLUGIN_NAME }}/Windows/obs-plugins/32bit/advanced-scene-switcher.pdb
rm ${{ env.PLUGIN_NAME }}/Windows/obs-plugins/64bit/advanced-scene-switcher.pdb
cp plugin/${{ env.PLUGIN_NAME }}/CI/release/README.txt ${{ env.PLUGIN_NAME }}/
FILE_NAME=${{ env.PLUGIN_NAME }}.zip
zip -r ${FILE_NAME} ${{ env.PLUGIN_NAME }}/
- name: Publish
if: success()
uses: actions/upload-artifact@v2.2.1
with:
name: "Release"
path: "*.zip"

View File

@@ -1,19 +0,0 @@
name: Clang Format Check
on: [push, pull_request]
jobs:
ubuntu64:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install clang format
run: |
sudo apt-get install -y clang-format-10
- name: Check the Formatting
run: |
./CI/formatcode.sh
./CI/check-format.sh

View File

@@ -1,13 +1,25 @@
name: Check locale
on: [push, pull_request]
on:
push:
branches:
- master
tags:
- '*'
paths:
- 'data/locale/**'
pull_request:
branches:
- master
paths:
- 'data/locale/**'
jobs:
ubuntu64:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Check locale files
run: |

394
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,394 @@
name: Plugin Build
on:
push:
paths-ignore:
- '**.md'
branches:
- master
tags:
- '*'
pull_request:
paths-ignore:
- '**.md'
branches:
- master
env:
PLUGIN_NAME: SceneSwitcher
LIB_NAME: advanced-scene-switcher
jobs:
clang_check:
name: 01 - Code Format Check
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: Install clang-format
run: sudo apt-get install -y clang-format-13
- name: Run clang-format
run: ./.github/scripts/check-format.sh && ./.github/scripts/check-changes.sh
- name: Install cmake-format
run: sudo pip install cmakelang
- name: Run cmake-format
run: ./.github/scripts/check-cmake.sh
macos_build:
name: 02 - macOS
runs-on: macos-12
strategy:
fail-fast: true
matrix:
arch: [x86_64, arm64, universal]
if: always()
needs: [clang_check]
outputs:
commitHash: ${{ steps.setup.outputs.commitHash }}
env:
CODESIGN_IDENT: '-'
CODESIGN_IDENT_INSTALLER: ''
MACOSX_DEPLOYMENT_TARGET: '10.15'
defaults:
run:
shell: zsh {0}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: plugin
submodules: recursive
- name: Checkout obs-studio
uses: actions/checkout@v3
with:
repository: 'obsproject/obs-studio'
path: obs-studio
fetch-depth: 0
submodules: recursive
- name: Setup Environment
id: setup
working-directory: ${{ github.workspace }}/plugin
run: |
## SETUP ENVIRONMENT SCRIPT
print '::group::Clean Homebrew Environment'
typeset -a to_remove=()
for formula (speexdsp curl php) {
if [[ -d ${HOMEBREW_PREFIX}/opt/${formula} ]] to_remove+=(${formula})
}
if (( #to_remove > 0 )) brew uninstall --ignore-dependencies ${to_remove}
print '::endgroup::'
print '::group::Set up code signing'
if [[ '${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}' != '' && \
'${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}' != '' && \
'${{ secrets.MACOS_SIGNING_CERT }}' != '' ]] {
print '::set-output name=haveCodesignIdent::true'
} else {
print '::set-output name=haveCodesignIdent::false'
}
if [[ '${{ secrets.MACOS_NOTARIZATION_USERNAME }}' != '' && \
'${{ secrets.MACOS_NOTARIZATION_PASSWORD }}' != '' ]] {
print '::set-output name=haveNotarizationUser::true'
} else {
print '::set-output name=haveNotarizationUser::false'
}
print '::endgroup::'
print "::set-output name=ccacheDate::$(date +"%Y-%m-%d")"
print "::set-output name=commitHash::${"$(git rev-parse HEAD)"[0,9]}"
echo "$PWD/.github/scripts" >> $GITHUB_PATH
- name: Restore Compilation Cache
id: ccache-cache
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/.ccache
key: macos-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
restore-keys: |
macos-${{ matrix.arch }}-ccache-plugin-
- name: Check for GitHub Labels
id: seekingTesters
if: ${{ github.event_name == 'pull_request' }}
run: |
if [[ -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')" ]] {
print '::set-output name=found::true'
} else {
print '::set-output name=found::false'
}
- name: Install Apple Developer Certificate
if: ${{ steps.setup.outputs.haveCodesignIdent == 'true' }}
uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
with:
keychain-password: ${{ github.run_id }}
p12-file-base64: ${{ secrets.MACOS_SIGNING_CERT }}
p12-password: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }}
- name: Set Signing Identity
if: ${{ steps.setup.outputs.haveCodesignIdent == 'true' }}
run: |
print "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" >> $GITHUB_ENV
print "CODESIGN_IDENT_INSTALLER=${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}" >> $GITHUB_ENV
- name: Build Plugin
uses: ./plugin/.github/actions/build-plugin
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
config: RelWithDebInfo
codesign: 'true'
codesignIdent: ${{ env.CODESIGN_IDENT }}
- name: Package Plugin
uses: ./plugin/.github/actions/package-plugin
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
config: RelWithDebInfo
codesign: ${{ steps.setup.outputs.haveCodesignIdent == 'true' }}
notarize: ${{ startsWith(github.ref, 'refs/tags/') && steps.setup.outputs.haveNotarizationUser == 'true' }}
codesignIdent: ${{ env.CODESIGN_IDENT }}
installerIdent: ${{ env.CODESIGN_IDENT_INSTALLER }}
codesignUser: ${{ secrets.MACOS_NOTARIZATION_USERNAME }}
codesignPass: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}
- name: Upload Build Artifact
if: ${{ success() }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.PLUGIN_NAME }}-macos-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}
path: ${{ github.workspace }}/plugin/release/${{ env.LIB_NAME }}-*-macos-${{ matrix.arch }}.pkg
linux_build:
name: 02 - Linux
runs-on: ubuntu-22.04
strategy:
fail-fast: true
matrix:
arch: [x86_64]
if: always()
needs: [clang_check]
outputs:
commitHash: ${{ steps.setup.outputs.commitHash }}
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: plugin
submodules: recursive
- name: Checkout obs-studio
uses: actions/checkout@v3
with:
repository: 'obsproject/obs-studio'
path: obs-studio
fetch-depth: 0
submodules: recursive
- name: Setup Environment
working-directory: ${{ github.workspace }}/plugin
id: setup
run: |
## SETUP ENVIRONMENT SCRIPT
echo "::set-output name=ccacheDate::$(date +"%Y-%m-%d")"
echo "::set-output name=commitHash::$(git rev-parse HEAD | cut -c1-9)"
echo "$PWD/.github/scripts" >> $GITHUB_PATH
- name: Restore Compilation Cache
id: ccache-cache
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/.ccache
key: linux-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
restore-keys: |
linux-${{ matrix.arch }}-ccache-plugin-
- name: Check for GitHub Labels
id: seekingTesters
if: ${{ github.event_name == 'pull_request' }}
run: |
## GITHUB LABEL SCRIPT
if [[ -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')" ]]; then
echo '::set-output name=found::true'
else
echo '::set-output name=found::false'
fi
- name: Build Plugin
uses: ./plugin/.github/actions/build-plugin
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
config: RelWithDebInfo
- name: Upload Build Artifact
if: ${{ success() }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.PLUGIN_NAME }}-linux-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}
path: ${{ github.workspace }}/plugin/release/*
- name: Package Plugin
uses: ./plugin/.github/actions/package-plugin
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
config: RelWithDebInfo
- name: Upload Package Artifact
if: ${{ success() }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.PLUGIN_NAME }}-linux-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}
path: ${{ github.workspace }}/plugin/release/${{ env.LIB_NAME }}-*-linux-${{ matrix.arch }}.*
windows_build:
name: 02 - Windows
runs-on: windows-2022
strategy:
fail-fast: true
matrix:
arch: [x86, x64]
if: always()
needs: [clang_check]
outputs:
commitHash: ${{ steps.setup.outputs.commitHash }}
defaults:
run:
shell: pwsh
steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: plugin
submodules: recursive
- name: Checkout obs-studio
uses: actions/checkout@v3
with:
repository: 'obsproject/obs-studio'
path: obs-studio
fetch-depth: 0
submodules: recursive
- name: Setup Environment
working-directory: ${{ github.workspace }}/plugin
id: setup
run: |
## SETUP ENVIRONMENT SCRIPT
$CommitHash = (git rev-parse HEAD)[0..8] -join ''
Write-Output "::set-output name=commitHash::${CommitHash}"
- name: Check for GitHub Labels
id: seekingTesters
working-directory: ${{ github.workspace }}/plugin
if: ${{ github.event_name == 'pull_request' }}
run: |
## GITHUB LABEL SCRIPT
$LabelFound = try {
$Params = @{
Authentication = 'Bearer'
Token = (ConvertTo-SecureString '${{ secrets.GITHUB_TOKEN }}' -AsPlainText)
Uri = '${{ github.event.pull_request.url }}'
UseBasicParsing = $true
}
(Invoke-RestMethod @Params).labels.name.contains('Seeking Testers')
} catch {
$false
}
Write-Output "::set-output name=found::$(([string]${LabelFound}).ToLower())"
- name: Build Plugin
uses: ./plugin/.github/actions/build-plugin
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
config: RelWithDebInfo
visualStudio: 'Visual Studio 17 2022'
- name: Package Plugin
uses: ./plugin/.github/actions/package-plugin
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
config: RelWithDebInfo
- name: Upload Build Artifact
if: ${{ success() }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.PLUGIN_NAME }}-windows-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}
path: ${{ github.workspace }}/plugin/release/${{ env.LIB_NAME }}-*.zip
- name: Package Plugin Installer
uses: ./plugin/.github/actions/package-plugin
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
config: RelWithDebInfo
createInstaller: true
- name: Upload Installer Artifact
uses: actions/upload-artifact@v3
with:
name: ${{ env.PLUGIN_NAME }}-windows-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}-installer
path: ${{ github.workspace }}/plugin/release/${{ env.LIB_NAME }}-*.exe
make-release:
name: 03 - Create and upload release
runs-on: ubuntu-22.04
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
needs: [macos_build, linux_build, windows_build]
defaults:
run:
shell: bash
steps:
- name: Get Metadata
id: metadata
run: |
## METADATA SCRIPT
echo "::set-output name=version::${GITHUB_REF/refs\/tags\//}"
- name: Download build artifacts
uses: actions/download-artifact@v3
- name: Generate Checksums
run: |
## CHECKSUM GENERATION SCRIPT
shopt -s extglob
echo "### Checksums" > ${{ github.workspace }}/CHECKSUMS.txt
for file in ${{ github.workspace }}/**/@(*.pkg|*.exe|*.deb|*.zip); do
echo " ${file##*/}: $(sha256sum "${file}" | cut -d " " -f 1)" >> ${{ github.workspace }}/CHECKSUMS.txt
done
- name: Create Release
id: create_release
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5
with:
draft: true
prerelease: true
tag_name: ${{ steps.metadata.outputs.version }}
name: "${{ env.PLUGIN_NAME }} ${{ steps.metadata.outputs.version }}"
body_path: ${{ github.workspace }}/CHECKSUMS.txt
files: |
${{ github.workspace }}/**/*.zip
${{ github.workspace }}/**/*.exe
${{ github.workspace }}/**/*.deb
${{ github.workspace }}/**/*.pkg

9
.gitignore vendored
View File

@@ -77,6 +77,8 @@ CTestTestfile.cmake_install
ehthumbs.db
Thumbs.db
*.directory
*.generated.*
**/.Brewfile.lock.json
# backup text files generated by an editor #
############################################
@@ -104,4 +106,9 @@ forms/advanced-scene-switcher.ui.autosave
# Directories #
###############
build/
*~
.DS_Store
/build/
/build_*/
/release/
/installer/Output/

3
.gitmodules vendored
View File

@@ -10,3 +10,6 @@
[submodule "deps/openvr"]
path = deps/openvr
url = https://github.com/ValveSoftware/openvr.git
[submodule "deps/obs-websocket"]
path = deps/obs-websocket
url = https://github.com/obsproject/obs-websocket.git

View File

@@ -4,11 +4,9 @@ You have the option to ...
- either add the plugin to the OBS source tree directly and build the plugin while building OBS itself. (**in tree**)
- or you can move the sources of this plugin outside of the OBS source tree and build it separately from OBS. (**out of tree**)
As both methods require you to have a working [OBS Studio development environment](https://obsproject.com/wiki/install-instructions), [Qt](https://download.qt.io/official_releases/qt/5.15/5.15.2/) and [CMake](https://cmake.org/download/) it is recommended to build the plugin in tree as it is easier to set up and will enable straightforward debugging.
As both methods require you to have a working [OBS Studio development environment](https://obsproject.com/wiki/Building-OBS-Studio) and [CMake](https://cmake.org/download/) it is recommended to build the plugin in tree as it is easier to set up and will enable straightforward debugging.
Note that your Qt install must include the QtConcurrent module.
## Compiling in tree (recommended)
## Compiling in tree (recommended for development)
Add the "SceneSwitcher" source directory to your obs-studio source directory under obs-studio/UI/frontend-plugins/:
```
cd obs-studio/UI/frontend-plugins/
@@ -20,7 +18,7 @@ Then modify the obs-studio/UI/frontend-plugins/CMakeLists.txt file and add an en
add_subdirectory(SceneSwitcher)
```
Now follow the [build instructions for obs-studio](https://obsproject.com/wiki/install-instructions) for your particular platform.
Now follow the [build instructions for obs-studio](https://obsproject.com/wiki/Building-OBS-Studio) for your particular platform.
Note that on Linux systems it might be necessary to additionally install the following packages to fulfill the dependencies to `XTest`, `XScreensaver` and `OpenCV` - exact command may differ:
```
@@ -32,121 +30,54 @@ sudo apt-get install \
## Compiling out of tree
### Prerequisites
You'll need [Qt](https://download.qt.io/official_releases/qt/5.15/5.15.2/), [CMake](https://cmake.org/download/) and a working [OBS Studio development environment](https://obsproject.com/wiki/install-instructions) installed on your computer.
Once you've set this up, do the following:
First you will need to clone the plugin sources by running the following command:
```
git clone --recursive https://github.com/WarmUpTill/SceneSwitcher.git
cd SceneSwitcher
```
You'll need [CMake](https://cmake.org/download/) and a working [OBS Studio development environment](https://obsproject.com/wiki/Building-OBS-Studio) installed on your computer.
The easiest way to set this up is to call the corresponding CI scripts, as they will automatically download all required dependencies and start build of the plugin:
| Platform | Command |
| ----------- | ----------- |
| Windows | `./.github/scripts/Build-Windows.ps1` |
| Linux | `./.github/scripts/build-linux.sh` |
| MacOS | `./.github/scripts/build-macos.zsh` |
Alternatively you can download the OBS dependencies from https://github.com/obsproject/obs-deps/releases and manually configure and start the build.
Start by creating a build directory:
```
mkdir build && cd build
```
### Windows
In cmake-gui, you'll have to set these CMake variables :
- **BUILD_OUT_OF_TREE** (bool) : true
- **LIBOBS_LIB** (filepath) : location of the obs.lib file
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
code of OBS Studio, located at [source_directory]/libobs/.
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the obs-frontend-api.lib file
(usually in the same place as LIBOBS_LIB)
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api
subfolder in the source code of OBS Studio, located at [source_directory]/UI/obs-frontend-api.
- **CURL_LIBRARY** (filepath) : location of the libcurl.lib file
(part of the dependencies2019/win64/bin folder used to build OBS)
- **CURL_INCLUDE_DIR** (path) : location of the curl
subfolder in OBS dependencies folder: ".../dependencies2019/win64/include/"
Assuming that you set up Qt via QT installer:
- **Qt5Core_DIR** (path) : C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Core
- **Qt5Gui_DIR** (path): C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Gui
- **Qt5Widgets_DIR** (path) : C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Widgets
Just keep hitting configure until all the vars are filled out. Then hit generate.
### Linux
Install dependencies `XTest`, `XScreensaver` and `OpenCV` - exact command may differ:
Next configure the build.
```
sudo apt-get install \
libxtst-dev \
libxss-dev \
libopencv-dev
cmake -DCMAKE_PREFIX_PATH=<path-to-obs-deps> -Dlibobs_DIR=<path-to-libobs-dir> -Dobs-frontend-api_DIR=<path-to-frontend-api-dir> ..
```
It might be necessary to provide additional variables depending on your build setup.
Finally, start the plugin build using your provided generator. (E.g. Ninja on Linux or a Visual Studio solution on Windows)
# Contributing
Contributions to the plugin are always welcome and if you need any assistance do not hesitate to reach out.
In general changes in the `src/legacy` folder should be avoided.
If you would like to expand upon the macro system by adding a new condition or action type have a loot at the examples in `src/macro-core`.
The key functions to add conditions or are the Register() functions.
```
MacroActionFactory::Register(
MacroActionExample::id, // Unique string identifying this action type
{
MacroActionExample::Create, // Function called to create the object performing the action
MacroActionExampleEdit::Create, // Function called to create the widget configure the action
"AdvSceneSwitcher.action.example" // User facing name of the action type
}
);
```
Most versions of Linux you can use cmake-gui or the command line.
**For the command line:**
```
# [...] are placeholders
cmake -DBUILD_OUT_OF_TREE=1 \
-DLIBOBS_INCLUDE_DIR=[...]/obs-studio/libobs/ \
-DLIBOBS_LIB=[...]/libobs.so \
-DLIBOBS_FRONTEND_INCLUDE_DIR=[...]/obs-studio/UI/obs-frontend-api/ \
-DLIBOBS_FRONTEND_API_LIB=[...]/libobs-frontend-api.so \
-DCMAKE_INSTALL_PREFIX=/usr ..
make -j4
sudo make install
```
For cmake-gui you'll have to set the following variables:
- **BUILD_OUT_OF_TREE** (bool) : true
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
code of OBS Studio, located at [source_directory]/libobs/.
- **LIBOBS_LIB** (filepath) : location of the libobs.so file (usually CMake finds
this, but if not it'll usually be in /usr/lib/libobs.so)
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the libobs-frontend-api.so
file (usually in the same place as LIBOBS_LIB)
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api
subfolder in the source code of OBS Studio, located at
[source_directory]/UI/obs-frontend-api.
Assuming that you installed Qt via your system package manager, it should be
found automatically. If not, then usually you'll find it in something like:
- **Qt5Core_DIR** (path) : /usr/lib64/cmake/Qt5Core
- **Qt5Gui_DIR** (path): /usr/lib64/cmake/Qt5Gui
- **Qt5Widgets_DIR** (path) : /usr/lib64/cmake/Qt5Widgets
Just keep hitting configure until all the vars are filled out. Then hit generate.
Then open a terminal in the build folder and type:
```
make -j4
sudo make install
```
NOTE: The Linux version of this plugin is dependent on libXScrnSaver, libcurl and libXtst.
### OS X
In cmake-gui, you'll have to set these CMake variables :
- **BUILD_OUT_OF_TREE** (bool) : true
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
code of OBS Studio, located at [source_directory]/libobs/.
- **LIBOBS_LIB** (filepath) : location of the libobs.0.dylib file (usually
in /Applications/OBS.app/Contents/Resources/bin/libobs.0.dylib)
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the libobs-frontend-api.0.dylib
file (usually in usually in /Applications/OBS.app/Contents/Resources/bin/libobs-frontend-api.0.dylib)
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api subfolder
in the source code of OBS Studio, located at [source_directory]/UI/obs-frontend-api.
Assuming that you installed Qt via the regular Qt App way:
- **Qt5Core_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5Core
- **Qt5Widgets_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5Widgets
- **Qt5MacExtras_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5MacExtras
Just keep hitting configure until all the vars are filled out. Then hit generate.
Open xcode (or a terminal, depending on the build type you chose), build and copy
the advanced-scene-switcher.so file to 'Library/Application Support/obs-studio/plugins/advanced-scene-switcher/bin/'
And the 'data' folder to 'Library/Application Support/obs-studio/plugins/advanced-scene-switcher/'.
Note that you might have to adjust the library search paths using the install_name_tool if you want the plugin to run on machines other than your build machine:
```
install_name_tool -change @rpath/libobs-frontend-api.dylib @executable_path/../Frameworks/libobs-frontend-api.dylib UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change @rpath/libobs.0.dylib @executable_path/../Frameworks/libobs.0.dylib UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
```
If your intention is to add macro functionality which depends on external libraries, which is likely not to exist on all user setups, try to follow the examples under `src/macro-external`.
These are basically plugins themselves that get attempted to be loaded on startup of the advanced scene switcher.

View File

@@ -1,35 +0,0 @@
#!/usr/bin/env bash
# Original source https://github.com/Project-OSRM/osrm-backend/blob/master/scripts/format.sh
set +x
set -o errexit
set -o pipefail
set -o nounset
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
# Runs the Clang Formatter in parallel on the code base.
# Return codes:
# - 1 there are files to be formatted
# - 0 everything looks fine
# Get CPU count
OS=$(uname)
NPROC=1
if [[ $OS = "Linux" || $OS = "Darwin" ]] ; then
NPROC=$(getconf _NPROCESSORS_ONLN)
fi
# Discover clang-format
if type clang-format-10 2> /dev/null ; then
CLANG_FORMAT=clang-format-10
elif type clang-format-8 2> /dev/null ; then
CLANG_FORMAT=clang-format-8
else
CLANG_FORMAT=clang-format
fi
find $SCRIPTPATH/.. -type d \( -path $SCRIPTPATH/../deps \
-o -path $SCRIPTPATH/../cmake \
-o -path $SCRIPTPATH/../build \) -prune -type f -o -name '*.h' -or -name '*.hpp' -or -name '*.m' -or -name '*.mm' -or -name '*.c' -or -name '*.cpp' \
| xargs -L100 -P${NPROC} ${CLANG_FORMAT} -i -style=file -fallback-style=none

View File

@@ -1,5 +0,0 @@
brew "jack"
brew "speexdsp"
brew "cmake"
brew "freetype"
brew "fdk-aac"

File diff suppressed because it is too large Load Diff

View File

@@ -1,64 +0,0 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "Advanced Scene Switcher"
#define MyAppVersion "@GIT_SHA1@"
#define MyAppURL "https://github.com/WarmUpTill/SceneSwitcher"
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{A4ADDF26-4426-4D2E-B26A-C7C878DA8FC9}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={code:GetDefaultDirectory}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
; Uncomment the following line to run in non administrative install mode (install for current user only.)
;PrivilegesRequired=lowest
OutputBaseFilename=AdvancedSceneSwitcherSetup
Compression=lzma
SolidCompression=yes
WizardStyle=modern
ArchitecturesInstallIn64BitMode=x64
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Files]
Source: "@ISS_MSVC_REDIST_HELPER_DIR@\msvc-redist-helper-64.exe"; DestDir: "{app}"; DestName: "msvc-redist-helper.exe"; Flags: ignoreversion dontcopy; Check: Is64BitInstallMode
Source: "@ISS_MSVC_REDIST_HELPER_DIR@\msvc-redist-helper-32.exe"; DestDir: "{app}"; DestName: "msvc-redist-helper.exe"; Flags: ignoreversion dontcopy; Check: not Is64BitInstallMode
Source: "@ISS_PLUGIN_FILES_DIR@\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
[Code]
function GetDefaultDirectory(Value: String): String;
var
sInstallPath: String;
begin
sInstallPath := Value;
if (sInstallPath = '') then
RegQueryStringValue(HKLM64, 'SOFTWARE\OBS Studio', '', sInstallPath);
if (sInstallPath = '') then
RegQueryStringValue(HKCU64, 'SOFTWARE\OBS Studio', '', sInstallPath);
if (sInstallPath = '') then
sInstallPath := ExpandConstant('{commonpf}\obs-studio');
Result := sInstallPath
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
ResultCode: Integer;
begin
if (CurStep=ssPostInstall) then
begin
ExtractTemporaryFile('msvc-redist-helper.exe');
Exec(ExpandConstant('{tmp}\msvc-redist-helper.exe'), '2019', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
end;
end;

View File

@@ -1,45 +1,27 @@
cmake_minimum_required(VERSION 3.14)
project(advanced-scene-switcher)
cmake_minimum_required(VERSION 3.21)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RELWITHDEBINFO)
project(advanced-scene-switcher VERSION 1.0.0)
set(LIB_NAME "${PROJECT_NAME}-lib")
add_library(${PROJECT_NAME} MODULE)
add_library(${LIB_NAME} SHARED)
set(PLUGIN_AUTHOR "WarmUpTill")
set(MACOS_BUNDLEID "com.warmuptill.${PROJECT_NAME}")
set(LINUX_MAINTAINER_EMAIL "noone@nothing.com")
set(MACOS_PACKAGE_UUID "3F0D2A6A-2583-11ED-861D-0242AC120002")
set(MACOS_INSTALLER_UUID "B7F15A6E-2583-11ED-861D-0242AC120002")
set(WINDOWS_INSTALLER_UUID "A4ADDF26-4426-4D2E-B26A-C7C878DA8FC9")
message(STATUS "CMAKE_PROJECT_NAME is ${CMAKE_PROJECT_NAME}")
if(${CMAKE_PROJECT_NAME} STREQUAL "obs-studio")
if(NOT DEFINED BUILD_OUT_OF_TREE)
message(STATUS "${PROJECT_NAME} configured for in-tree build")
endif()
else()
set(BUILD_OUT_OF_TREE ON)
message(STATUS "${PROJECT_NAME} configured for out-of-tree build")
endif()
# Compiler settings
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if(CMAKE_COMPILER_IS_GNUCC
OR CMAKE_COMPILER_IS_GNUCXX
OR CMAKE_COMPILER_IS_CLANG)
set(CMAKE_CXX_FLAGS
"-Wall -Wextra -Wvla -Wno-unused-function -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS} -fno-strict-aliasing"
)
set(CMAKE_C_FLAGS
"-Wall -Wextra -Wvla -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-braces -Wno-missing-field-initializers ${CMAKE_C_FLAGS} -std=gnu99 -fno-strict-aliasing"
)
option(USE_LIBC++ "Use libc++ instead of libstdc++" ${APPLE})
if(USE_LIBC++)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
elseif(MSVC)
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
# Disable pointless constant condition warnings
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} /wd4127 /wd4201 /wd4456 /wd4457 /wd4458 /wd4459 /wd4595"
)
add_definitions(-DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS
-D_CRT_NONSTDC_NO_WARNINGS)
endif()
# Generate version info
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
@@ -47,80 +29,338 @@ git_describe(GIT_TAG)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cpp.in"
"${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp" @ONLY)
# Windows installer
if(WIN32)
get_filename_component(ISS_PLUGIN_FILES_DIR
"${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE)
file(TO_NATIVE_PATH "${ISS_PLUGIN_FILES_DIR}" ISS_PLUGIN_FILES_DIR)
get_filename_component(ISS_MSVC_REDIST_HELPER_DIR "${CMAKE_BINARY_DIR}\\.."
ABSOLUTE)
file(TO_NATIVE_PATH "${ISS_MSVC_REDIST_HELPER_DIR}"
ISS_MSVC_REDIST_HELPER_DIR)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CI/windows/setup.iss.in"
"${CMAKE_CURRENT_BINARY_DIR}/CI/windows/setup.iss" @ONLY)
endif()
# --- Set target sources ---
# Module sources
target_sources(${PROJECT_NAME} PRIVATE src/advanced-scene-switcher-module.c)
# Generic sources
target_sources(
${LIB_NAME}
PRIVATE src/advanced-scene-switcher.cpp
src/advanced-scene-switcher.hpp
src/general.cpp
src/hotkey.cpp
src/hotkey.hpp
src/hotkey.hpp
src/platform-funcs.hpp
src/scene-group.cpp
src/scene-group.hpp
src/status-control.cpp
src/status-control.hpp
src/switcher-data-structs.cpp
src/switcher-data-structs.hpp
src/version.cpp
src/version.h)
# Legacy function sources
target_sources(
${LIB_NAME}
PRIVATE src/legacy/scene-trigger.cpp
src/legacy/scene-trigger.hpp
src/legacy/switch-audio.cpp
src/legacy/switch-audio.hpp
src/legacy/switch-executable.cpp
src/legacy/switch-executable.hpp
src/legacy/switch-file.cpp
src/legacy/switch-file.hpp
src/legacy/switch-generic.cpp
src/legacy/switch-generic.hpp
src/legacy/switch-idle.cpp
src/legacy/switch-idle.hpp
src/legacy/switch-media.cpp
src/legacy/switch-media.hpp
src/legacy/switch-network.cpp
src/legacy/switch-network.hpp
src/legacy/switch-pause.cpp
src/legacy/switch-pause.hpp
src/legacy/switch-priority.cpp
src/legacy/switch-random.cpp
src/legacy/switch-random.hpp
src/legacy/switch-screen-region.cpp
src/legacy/switch-screen-region.hpp
src/legacy/switch-sequence.cpp
src/legacy/switch-sequence.hpp
src/legacy/switch-time.cpp
src/legacy/switch-time.hpp
src/legacy/switch-transitions.cpp
src/legacy/switch-transitions.hpp
src/legacy/switch-video.cpp
src/legacy/switch-video.hpp
src/legacy/switch-window.cpp
src/legacy/switch-window.hpp)
# Maro sources
target_sources(
${LIB_NAME}
PRIVATE src/macro-core/macro-action-audio.cpp
src/macro-core/macro-action-audio.hpp
src/macro-core/macro-action-edit.cpp
src/macro-core/macro-action-edit.hpp
src/macro-core/macro-action-file.cpp
src/macro-core/macro-action-file.hpp
src/macro-core/macro-action-filter.cpp
src/macro-core/macro-action-filter.hpp
src/macro-core/macro-action-hotkey.cpp
src/macro-core/macro-action-hotkey.hpp
src/macro-core/macro-action-http.cpp
src/macro-core/macro-action-http.hpp
src/macro-core/macro-action-macro.cpp
src/macro-core/macro-action-macro.hpp
src/macro-core/macro-action-media.cpp
src/macro-core/macro-action-media.hpp
src/macro-core/macro-action-plugin-state.cpp
src/macro-core/macro-action-plugin-state.hpp
src/macro-core/macro-action-profile.cpp
src/macro-core/macro-action-profile.hpp
src/macro-core/macro-action-random.cpp
src/macro-core/macro-action-random.hpp
src/macro-core/macro-action-recording.cpp
src/macro-core/macro-action-recording.hpp
src/macro-core/macro-action-replay-buffer.cpp
src/macro-core/macro-action-replay-buffer.hpp
src/macro-core/macro-action-run.cpp
src/macro-core/macro-action-run.hpp
src/macro-core/macro-action-scene-collection.cpp
src/macro-core/macro-action-scene-collection.hpp
src/macro-core/macro-action-scene-order.cpp
src/macro-core/macro-action-scene-order.hpp
src/macro-core/macro-action-scene-switch.cpp
src/macro-core/macro-action-scene-switch.hpp
src/macro-core/macro-action-scene-transform.cpp
src/macro-core/macro-action-scene-transform.hpp
src/macro-core/macro-action-scene-visibility.cpp
src/macro-core/macro-action-scene-visibility.hpp
src/macro-core/macro-action-screenshot.cpp
src/macro-core/macro-action-screenshot.hpp
src/macro-core/macro-action-sequence.cpp
src/macro-core/macro-action-sequence.hpp
src/macro-core/macro-action-source.cpp
src/macro-core/macro-action-source.hpp
src/macro-core/macro-action-streaming.cpp
src/macro-core/macro-action-streaming.hpp
src/macro-core/macro-action-studio-mode.cpp
src/macro-core/macro-action-studio-mode.hpp
src/macro-core/macro-action-systray.cpp
src/macro-core/macro-action-systray.hpp
src/macro-core/macro-action-timer.cpp
src/macro-core/macro-action-timer.hpp
src/macro-core/macro-action-transition.cpp
src/macro-core/macro-action-transition.hpp
src/macro-core/macro-action-virtual-cam.cpp
src/macro-core/macro-action-virtual-cam.hpp
src/macro-core/macro-action-wait.cpp
src/macro-core/macro-action-wait.hpp
src/macro-core/macro-action-websocket.cpp
src/macro-core/macro-action-websocket.hpp
src/macro-core/macro-action.cpp
src/macro-core/macro-action.hpp
src/macro-core/macro-condition-audio.cpp
src/macro-core/macro-condition-audio.hpp
src/macro-core/macro-condition-cursor.cpp
src/macro-core/macro-condition-cursor.hpp
src/macro-core/macro-condition-date.cpp
src/macro-core/macro-condition-date.hpp
src/macro-core/macro-condition-edit.cpp
src/macro-core/macro-condition-edit.hpp
src/macro-core/macro-condition-file.cpp
src/macro-core/macro-condition-file.hpp
src/macro-core/macro-condition-filter.cpp
src/macro-core/macro-condition-filter.hpp
src/macro-core/macro-condition-hotkey.cpp
src/macro-core/macro-condition-hotkey.hpp
src/macro-core/macro-condition-idle.cpp
src/macro-core/macro-condition-idle.hpp
src/macro-core/macro-condition-macro.cpp
src/macro-core/macro-condition-macro.hpp
src/macro-core/macro-condition-media.cpp
src/macro-core/macro-condition-media.hpp
src/macro-core/macro-condition-obs-stats.cpp
src/macro-core/macro-condition-obs-stats.hpp
src/macro-core/macro-condition-plugin-state.cpp
src/macro-core/macro-condition-plugin-state.hpp
src/macro-core/macro-condition-process.cpp
src/macro-core/macro-condition-process.hpp
src/macro-core/macro-condition-profile.cpp
src/macro-core/macro-condition-profile.hpp
src/macro-core/macro-condition-recording.cpp
src/macro-core/macro-condition-recording.hpp
src/macro-core/macro-condition-replay-buffer.cpp
src/macro-core/macro-condition-replay-buffer.hpp
src/macro-core/macro-condition-scene-order.cpp
src/macro-core/macro-condition-scene-order.hpp
src/macro-core/macro-condition-scene-transform.cpp
src/macro-core/macro-condition-scene-transform.hpp
src/macro-core/macro-condition-scene-visibility.cpp
src/macro-core/macro-condition-scene-visibility.hpp
src/macro-core/macro-condition-scene.cpp
src/macro-core/macro-condition-scene.hpp
src/macro-core/macro-condition-source.cpp
src/macro-core/macro-condition-source.hpp
src/macro-core/macro-condition-streaming.cpp
src/macro-core/macro-condition-streaming.hpp
src/macro-core/macro-condition-studio-mode.cpp
src/macro-core/macro-condition-studio-mode.hpp
src/macro-core/macro-condition-timer.cpp
src/macro-core/macro-condition-timer.hpp
src/macro-core/macro-condition-transition.cpp
src/macro-core/macro-condition-transition.hpp
src/macro-core/macro-condition-virtual-cam.cpp
src/macro-core/macro-condition-virtual-cam.hpp
src/macro-core/macro-condition-websocket.cpp
src/macro-core/macro-condition-websocket.hpp
src/macro-core/macro-condition-window.cpp
src/macro-core/macro-condition-window.hpp
src/macro-core/macro-condition.cpp
src/macro-core/macro-condition.hpp
src/macro-core/macro-list-entry-widget.cpp
src/macro-core/macro-list-entry-widget.hpp
src/macro-core/macro-properties.cpp
src/macro-core/macro-properties.hpp
src/macro-core/macro-ref.cpp
src/macro-core/macro-ref.hpp
src/macro-core/macro-segment-list.cpp
src/macro-core/macro-segment-list.hpp
src/macro-core/macro-segment.cpp
src/macro-core/macro-segment.hpp
src/macro-core/macro-selection.cpp
src/macro-core/macro-selection.hpp
src/macro-core/macro-tab.cpp
src/macro-core/macro.cpp
src/macro-core/macro.hpp)
# Utility function sources
target_sources(
${LIB_NAME}
PRIVATE src/utils/connection-manager.cpp
src/utils/connection-manager.hpp
src/utils/curl-helper.cpp
src/utils/curl-helper.hpp
src/utils/duration-control.cpp
src/utils/duration-control.hpp
src/utils/file-selection.cpp
src/utils/file-selection.hpp
src/utils/macro-list.cpp
src/utils/macro-list.hpp
src/utils/name-dialog.cpp
src/utils/name-dialog.hpp
src/utils/resizing-text-edit.cpp
src/utils/resizing-text-edit.hpp
src/utils/scene-item-selection.cpp
src/utils/scene-item-selection.hpp
src/utils/scene-selection.cpp
src/utils/scene-selection.hpp
src/utils/screenshot-helper.cpp
src/utils/screenshot-helper.hpp
src/utils/section.cpp
src/utils/section.hpp
src/utils/transition-selection.cpp
src/utils/transition-selection.hpp
src/utils/utility.cpp
src/utils/utility.hpp
src/utils/volume-control.cpp
src/utils/websocket-helpers.cpp
src/utils/websocket-helpers.hpp
src/utils/volume-control.hpp)
# --- End of section ---
target_link_libraries(${PROJECT_NAME} PUBLIC ${LIB_NAME})
# Out of tree specific settings
if(BUILD_OUT_OF_TREE)
set(CMAKE_PREFIX_PATH "${QTDIR}")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(LibObs)
find_package(LibObs-frontend-api)
if(LibObs_FOUND)
set(LIBOBS_LIB ${LIBOBS_LIBRARIES})
set(LIBOBS_INCLUDE_DIR ${LIBOBS_INCLUDE_DIRS})
endif()
if(LibObs-frontend-api_FOUND)
set(LIBOBS_FRONTEND_API_LIB ${LIBOBS-FRONTEND-API_LIBRARIES})
set(LIBOBS_FRONTEND_INCLUDE_DIR ${LIBOBS-FRONTEND-API_INCLUDE_DIR})
endif()
if(NOT LIBOBS_LIB)
message(FATAL_ERROR "obs library not found - please set LIBOBS_LIB")
endif()
if(NOT LIBOBS_FRONTEND_API_LIB)
message(
FATAL_ERROR
"libobs frontend-api library not found - please set LIBOBS_FRONTEND_API_LIB"
)
endif()
if(NOT LIBOBS_INCLUDE_DIR)
message(
FATAL_ERROR "obs.hpp header not found - please set LIBOBS_INCLUDE_DIR")
endif()
if(NOT LIBOBS_FRONTEND_INCLUDE_DIR)
message(
FATAL_ERROR
" obs-frontend-api.h not found - please set LIBOBS_FRONTEND_INCLUDE_DIR"
)
endif()
include_directories("${LIBOBS_INCLUDE_DIR}" "${LIBOBS_FRONTEND_INCLUDE_DIR}"
${Qt5Core_INCLUDES} ${Qt5Widgets_INCLUDES})
find_package(CURL REQUIRED)
include_directories("${CURL_INCLUDE_DIRS}")
find_package(libobs REQUIRED)
find_package(obs-frontend-api REQUIRED)
include(cmake/ObsPluginHelpers.cmake)
target_link_libraries(${LIB_NAME} PUBLIC OBS::libobs OBS::obs-frontend-api)
else()
find_package(Libcurl REQUIRED)
include_directories("${LIBCURL_INCLUDE_DIRS}")
add_definitions(-DVCAM_SUPPORTED)
add_definitions(-DREPLAYBUFFER_SUPPORTED)
add_definitions(-DVISIBILITY_TRANSITIONS_SUPPORTED)
target_link_libraries(${LIB_NAME} PUBLIC OBS::libobs OBS::frontend-api)
endif()
# Platform specific settings
if(APPLE)
set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
find_library(COCOA Cocoa)
if(BUILD_OUT_OF_TREE)
find_package(Qt5MacExtras REQUIRED)
find_qt(COMPONENTS Widgets Core)
target_link_libraries(${LIB_NAME} PUBLIC Qt::Core Qt::Widgets)
include(cmake/AdvSSHelpers.cmake)
# --- Platform-independent build settings ---
target_include_directories(
${LIB_NAME}
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_SOURCE_DIR}/src/legacy"
"${CMAKE_CURRENT_SOURCE_DIR}/src/macro-core"
"${CMAKE_CURRENT_SOURCE_DIR}/src/utils"
"${CMAKE_CURRENT_BINARY_DIR}/forms")
set_target_properties(
${LIB_NAME}
PROPERTIES AUTOMOC ON
AUTOUIC ON
AUTORCC ON
AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/forms")
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
target_compile_features(${LIB_NAME} PUBLIC cxx_std_17)
add_definitions(-DASIO_STANDALONE)
target_include_directories(
${LIB_NAME}
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib")
# --- End of section ---
# --- Windows-specific build settings and tasks ---
if(OS_WINDOWS)
configure_file(cmake/bundle/windows/installer-Windows.iss.in
${CMAKE_CURRENT_BINARY_DIR}/installer-Windows.generated.iss)
if(MSVC)
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267)
endif()
include_directories(${COCOA})
endif()
target_sources(${LIB_NAME} PRIVATE src/win/advanced-scene-switcher-win.cpp)
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
set_property(TARGET ${LIB_NAME} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS true)
# --- End of section ---
# -- macOS specific build settings and tasks --
elseif(OS_MACOS)
configure_file(cmake/bundle/macos/installer-macos.pkgproj.in
${CMAKE_CURRENT_BINARY_DIR}/installer-macos.generated.pkgproj)
set(MACOSX_PLUGIN_GUI_IDENTIFIER "${MACOS_BUNDLEID}")
set(MACOSX_PLUGIN_BUNDLE_VERSION "${PROJECT_VERSION}")
set(MACOSX_PLUGIN_SHORT_VERSION_STRING "1")
target_compile_options(
${LIB_NAME} PRIVATE -Wall -Wextra -Werror-implicit-function-declaration
-stdlib=libc++ -fvisibility=default)
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "" SUFFIX ".so")
find_library(COCOA Cocoa)
target_include_directories(${LIB_NAME} PRIVATE ${COCOA})
target_sources(${LIB_NAME} PRIVATE src/osx/advanced-scene-switcher-osx.mm)
set_source_files_properties(advanced-scene-switcher-osx.mm
PROPERTIES COMPILE_FLAGS "-fobjc-arc")
set("${PROJECT_NAME}_PLATFORM_LIBS" ${COCOA})
find_package(CURL)
find_package(Libcurl)
if(CURL_FOUND)
target_include_directories(${LIB_NAME} PRIVATE "${CURL_INCLUDE_DIRS}")
elseif(Libcurl_FOUND)
target_include_directories(${LIB_NAME} PRIVATE "${LIBCURL_INCLUDE_DIRS}")
else()
message(FATAL_ERROR "Couldn't find CURL or Libcurl - abort")
endif()
# --- End of section ---
# --- Linux-specific build settings and tasks ---
else()
target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra)
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED COMPONENTS Xtst Xss)
find_path(PROCPS_INCLUDE_DIR NAMES proc/procps.h)
if(NOT PROCPS_INCLUDE_DIR)
@@ -132,319 +372,53 @@ if(UNIX AND NOT APPLE)
if(NOT PROCPS_LIBRARY)
message(FATAL_ERROR "procps lib not found - please set PROCPS_LIBRARY")
endif()
link_libraries(${X11_LIBRARIES} ${procps_LIBRARIES})
include_directories("${X11_INCLUDE_DIR}" "${X11_Xtst_INCLUDE_PATH}"
"${X11_Xss_INCLUDE_PATH}" "${PROCPS_INCLUDE_DIR}")
endif()
if(WIN32)
set(advanced-scene-switcher_PLATFORM_SOURCES
src/win/advanced-scene-switcher-win.cpp)
elseif(APPLE)
set(advanced-scene-switcher_PLATFORM_SOURCES
src/osx/advanced-scene-switcher-osx.mm)
set_source_files_properties(advanced-scene-switcher-osx.mm
PROPERTIES COMPILE_FLAGS "-fobjc-arc")
set(advanced-scene-switcher_PLATFORM_LIBS ${COCOA})
else()
set(advanced-scene-switcher_PLATFORM_SOURCES
src/linux/advanced-scene-switcher-nix.cpp)
set(advanced-scene-switcher_PLATFORM_LIBS Xss ${PROCPS_LIBRARY})
endif()
# asio and websocketpp
add_definitions(-DASIO_STANDALONE)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp")
if(WIN32)
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
endif()
# Setup QT tools
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/forms")
set(advanced-scene-switcher_UI ${advanced-scene-switcher_UI}
forms/advanced-scene-switcher.ui)
qt5_wrap_ui(advanced-scene-switcher_UI_HEADERS ${advanced-scene-switcher_UI}
${advanced-scene-switcher_PLATFORM_UI})
# The plugin sources
set(advanced-scene-switcher_HEADERS
${advanced-scene-switcher_HEADERS}
src/headers/advanced-scene-switcher.hpp
src/headers/switcher-data-structs.hpp
src/headers/scene-group.hpp
src/headers/scene-trigger.hpp
src/headers/switch-audio.hpp
src/headers/switch-executable.hpp
src/headers/switch-file.hpp
src/headers/switch-idle.hpp
src/headers/switch-media.hpp
src/headers/switch-network.hpp
src/headers/switch-pause.hpp
src/headers/switch-random.hpp
src/headers/switch-screen-region.hpp
src/headers/switch-time.hpp
src/headers/switch-transitions.hpp
src/headers/switch-window.hpp
src/headers/switch-sequence.hpp
src/headers/switch-video.hpp
src/headers/switch-generic.hpp
src/headers/macro-action.hpp
src/headers/macro-action-edit.hpp
src/headers/macro-action-audio.hpp
src/headers/macro-action-file.hpp
src/headers/macro-action-filter.hpp
src/headers/macro-action-hotkey.hpp
src/headers/macro-action-macro.hpp
src/headers/macro-action-media.hpp
src/headers/macro-action-plugin-state.hpp
src/headers/macro-action-profile.hpp
src/headers/macro-action-random.hpp
src/headers/macro-action-recording.hpp
src/headers/macro-action-replay-buffer.hpp
src/headers/macro-action-run.hpp
src/headers/macro-action-scene-collection.hpp
src/headers/macro-action-scene-order.hpp
src/headers/macro-action-scene-switch.hpp
src/headers/macro-action-scene-transform.hpp
src/headers/macro-action-scene-visibility.hpp
src/headers/macro-action-screenshot.hpp
src/headers/macro-action-sequence.hpp
src/headers/macro-action-source.hpp
src/headers/macro-action-streaming.hpp
src/headers/macro-action-studio-mode.hpp
src/headers/macro-action-systray.hpp
src/headers/macro-action-timer.hpp
src/headers/macro-action-transition.hpp
src/headers/macro-action-virtual-cam.hpp
src/headers/macro-action-wait.hpp
src/headers/macro-condition.hpp
src/headers/macro-condition-edit.hpp
src/headers/macro-condition-audio.hpp
src/headers/macro-condition-cursor.hpp
src/headers/macro-condition-date.hpp
src/headers/macro-condition-file.hpp
src/headers/macro-condition-filter.hpp
src/headers/macro-condition-hotkey.hpp
src/headers/macro-condition-idle.hpp
src/headers/macro-condition-macro.hpp
src/headers/macro-condition-media.hpp
src/headers/macro-condition-obs-stats.hpp
src/headers/macro-condition-plugin-state.hpp
src/headers/macro-condition-process.hpp
src/headers/macro-condition-recording.hpp
src/headers/macro-condition-replay-buffer.hpp
src/headers/macro-condition-scene-order.hpp
src/headers/macro-condition-scene-transform.hpp
src/headers/macro-condition-scene-visibility.hpp
src/headers/macro-condition-scene.hpp
src/headers/macro-condition-source.hpp
src/headers/macro-condition-streaming.hpp
src/headers/macro-condition-studio-mode.hpp
src/headers/macro-condition-timer.hpp
src/headers/macro-condition-transition.hpp
src/headers/macro-condition-virtual-cam.hpp
src/headers/macro-condition-window.hpp
src/headers/macro.hpp
src/headers/macro-ref.hpp
src/headers/macro-list-entry-widget.hpp
src/headers/macro-properties.hpp
src/headers/macro-segment.hpp
src/headers/macro-segment-list.hpp
src/headers/macro-selection.hpp
src/headers/curl-helper.hpp
src/headers/hotkey.hpp
src/headers/scene-item-selection.hpp
src/headers/scene-selection.hpp
src/headers/screenshot-helper.hpp
src/headers/transition-selection.hpp
src/headers/name-dialog.hpp
src/headers/duration-control.hpp
src/headers/file-selection.hpp
src/headers/section.hpp
src/headers/status-control.hpp
src/headers/platform-funcs.hpp
src/headers/resizing-text-edit.hpp
src/headers/utility.hpp
src/headers/volume-control.hpp
src/headers/version.h)
set(advanced-scene-switcher_SOURCES
${advanced-scene-switcher_SOURCES}
src/advanced-scene-switcher.cpp
src/advanced-scene-switcher-module.c
src/switcher-data-structs.cpp
src/scene-group.cpp
src/scene-trigger.cpp
src/switch-transitions.cpp
src/switch-screen-region.cpp
src/switch-priority.cpp
src/switch-executable.cpp
src/switch-idle.cpp
src/switch-sequence.cpp
src/switch-file.cpp
src/switch-window.cpp
src/switch-media.cpp
src/switch-network.cpp
src/file-selection.cpp
src/hotkey.cpp
src/general.cpp
src/switch-pause.cpp
src/switch-random.cpp
src/switch-time.cpp
src/switch-audio.cpp
src/switch-video.cpp
src/switch-generic.cpp
src/macro-action.cpp
src/macro-action-edit.cpp
src/macro-action-audio.cpp
src/macro-action-file.cpp
src/macro-action-filter.cpp
src/macro-action-hotkey.cpp
src/macro-action-macro.cpp
src/macro-action-media.cpp
src/macro-action-plugin-state.cpp
src/macro-action-profile.cpp
src/macro-action-random.cpp
src/macro-action-recording.cpp
src/macro-action-replay-buffer.cpp
src/macro-action-run.cpp
src/macro-action-scene-collection.cpp
src/macro-action-scene-order.cpp
src/macro-action-scene-switch.cpp
src/macro-action-scene-transform.cpp
src/macro-action-scene-visibility.cpp
src/macro-action-screenshot.cpp
src/macro-action-sequence.cpp
src/macro-action-source.cpp
src/macro-action-streaming.cpp
src/macro-action-studio-mode.cpp
src/macro-action-systray.cpp
src/macro-action-timer.cpp
src/macro-action-transition.cpp
src/macro-action-virtual-cam.cpp
src/macro-action-wait.cpp
src/macro-condition.cpp
src/macro-condition-edit.cpp
src/macro-condition-audio.cpp
src/macro-condition-cursor.cpp
src/macro-condition-date.cpp
src/macro-condition-file.cpp
src/macro-condition-filter.cpp
src/macro-condition-hotkey.cpp
src/macro-condition-idle.cpp
src/macro-condition-macro.cpp
src/macro-condition-media.cpp
src/macro-condition-obs-stats.cpp
src/macro-condition-plugin-state.cpp
src/macro-condition-process.cpp
src/macro-condition-recording.cpp
src/macro-condition-replay-buffer.cpp
src/macro-condition-scene-order.cpp
src/macro-condition-scene-transform.cpp
src/macro-condition-scene-visibility.cpp
src/macro-condition-scene.cpp
src/macro-condition-source.cpp
src/macro-condition-streaming.cpp
src/macro-condition-studio-mode.cpp
src/macro-condition-timer.cpp
src/macro-condition-transition.cpp
src/macro-condition-virtual-cam.cpp
src/macro-condition-window.cpp
src/macro.cpp
src/macro-ref.cpp
src/macro-list-entry-widget.cpp
src/macro-properties.cpp
src/macro-segment.cpp
src/macro-segment-list.cpp
src/macro-selection.cpp
src/macro-tab.cpp
src/curl-helper.cpp
src/scene-item-selection.cpp
src/scene-selection.cpp
src/screenshot-helper.cpp
src/transition-selection.cpp
src/name-dialog.cpp
src/resizing-text-edit.cpp
src/duration-control.cpp
src/status-control.cpp
src/section.cpp
src/utility.cpp
src/volume-control.cpp
src/version.cpp)
# Backwards compatability checks with older OBS versions
if(DEFINED LibObs_VERSION_MAJOR)
if(LibObs_VERSION_MAJOR GREATER_EQUAL 27)
add_definitions(-DVCAM_SUPPORTED)
add_definitions(-DVISIBILITY_TRANSITIONS_SUPPORTED)
target_link_libraries(${LIB_NAME} PRIVATE ${X11_LIBRARIES}
${procps_LIBRARIES})
target_include_directories(
${LIB_NAME} PRIVATE "${X11_INCLUDE_DIR}" "${X11_Xtst_INCLUDE_PATH}"
"${X11_Xss_INCLUDE_PATH}" "${PROCPS_INCLUDE_DIR}")
target_sources(${LIB_NAME} PRIVATE src/linux/advanced-scene-switcher-nix.cpp)
set("${PROJECT_NAME}_PLATFORM_LIBS" Xss ${PROCPS_LIBRARY})
find_package(CURL)
find_package(Libcurl)
if(CURL_FOUND)
target_include_directories(${LIB_NAME} PRIVATE "${CURL_INCLUDE_DIRS}")
elseif(Libcurl_FOUND)
target_include_directories(${LIB_NAME} PRIVATE "${LIBCURL_INCLUDE_DIRS}")
else()
message(
WARNING
"OBS version ${LibObs_VERSION_MAJOR} found - disabling virtual camera and hide/show transition functionality"
)
endif()
if(LibObs_VERSION_MAJOR GREATER_EQUAL 26)
add_definitions(-DREPLAYBUFFER_SUPPORTED)
else()
message(
WARNING
"OBS version ${LibObs_VERSION_MAJOR} found - disabling replay buffer and screenshot functionality"
)
list(REMOVE_ITEM advanced-scene-switcher_SOURCES
src/macro-action-screenshot.cpp)
list(REMOVE_ITEM advanced-scene-switcher_HEADERS
src/headers/macro-action-screenshot.hpp)
message(FATAL_ERROR "Couldn't find CURL or Libcurl - abort")
endif()
endif()
# --- End of section ---
add_library(
advanced-scene-switcher SHARED
${advanced-scene-switcher_HEADERS}
${advanced-scene-switcher_SOURCES}
${advanced-scene-switcher_UI_HEADERS}
${advanced-scene-switcher_PLATFORM_SOURCES}
${advanced-scene-switcher_PLATFORM_HEADERS})
target_link_libraries(${LIB_NAME} PUBLIC ${${PROJECT_NAME}_PLATFORM_LIBS})
setup_plugin_target(${PROJECT_NAME})
install_advss_lib(${LIB_NAME})
# Out of tree build
if(BUILD_OUT_OF_TREE)
target_link_libraries(
advanced-scene-switcher ${advanced-scene-switcher_PLATFORM_LIBS}
${LIBOBS_LIB} ${LIBOBS_FRONTEND_API_LIB} Qt5::Core Qt5::Widgets)
# --- Helpers for debian package creation ---
if(DEB_INSTALL)
# Additional commands to install the module in the correct place. Find all the
# translation files so we can copy them to the correct place later on.
file(GLOB ASS_TRANSLATION_FILES "data/locale/*.ini")
# OSX
if(APPLE)
set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "")
endif()
# Linux
if(UNIX AND NOT APPLE)
if(NOT LIB_OUT_DIR)
set(LIB_OUT_DIR "/lib/obs-plugins")
endif()
if(NOT DATA_OUT_DIR)
set(DATA_OUT_DIR "/share/obs/obs-plugins/advanced-scene-switcher")
set(DATA_OUT_DIR "/share/obs/obs-plugins/${PROJECT_NAME}")
endif()
set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "")
install(TARGETS advanced-scene-switcher
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR})
install(DIRECTORY data/locale
DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR})
install(DIRECTORY data/res
DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR})
endif()
else()
# In tree build
target_link_libraries(
advanced-scene-switcher ${advanced-scene-switcher_PLATFORM_LIBS}
obs-frontend-api Qt5::Widgets libobs)
install_obs_plugin_with_data(advanced-scene-switcher data)
endif()
add_subdirectory(src/external-macro-modules)
# --- End of section ---
add_subdirectory(src/macro-external)

View File

@@ -1,5 +1,5 @@
# SceneSwitcher
An automated scene switcher for OBS Studio.
An automation plugin for OBS Studio.
More information can be found on https://obsproject.com/forum/resources/automatic-scene-switching.395/.
@@ -9,23 +9,28 @@ Binaries for Windows, MacOS, and Linux are available in the [Releases](https://g
## Installing the plugin
For the Windows and MacOS platforms, it is recommended to run the provided installers.
For the **Windows** and **MacOS** platforms, it is recommended to run the provided installers.
For Linux the Snap package manager offers an OBS Studio installation which is bundled with the plugin:
For **Linux** the **Snap** package manager offers an OBS Studio installation which is bundled with the plugin:
```
sudo snap install obs-studio
```
The plugin is also available via the Flatpak package manager for users who installed OBS via Flatpak:
The plugin is also available via the **Flatpak** package manager for users who installed OBS via Flatpak:
```
flatpak install com.obsproject.Studio.Plugin.SceneSwitcher
```
If that is not an option you will have to ...
1. Copy the library to the plugins folder of you obs installation.
2. Copy the contents of the data directory to its respective folders of your obs installation.
Also note that the Linux version of this plugin has the following dependencies to `XTest`, `XScreensaver` and optionally `OpenCV`.
If `apt` is supported on your system they can be installed using:
```
sudo apt-get install \
libxtst-dev \
libxss-dev \
libopencv-dev
```
Unfortunately the exact location of these folders may vary from system to system.
## Contributing
## Compiling the plugin
- If you wish to contribute code to the project, have a look at this [section](BUILDING.md) describing how to compile the plugin.
- If you wish to contribute translations, feel free to submit pull requests for the corresponding files under `data/locale`.
See the [build instructions](BUILDING.md).

83
buildspec.json Normal file
View File

@@ -0,0 +1,83 @@
{
"dependencies": {
"obs-studio": {
"version": "28.0.0-beta1",
"repository": "https://github.com/obsproject/obs-studio.git",
"branch": "master",
"hash": "43a49dca47344a5170159ef99b86b97f90d4e4ad"
},
"prebuilt": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built obs-deps",
"hashes": {
"macos-x86_64": "7637e52305e6fc53014b5aabd583f1a4490b1d97450420e977cae9a336a29525",
"macos-arm64": "755e0fa69b17a3ae444e1befa9d91d77e3cafe628fbd1c6333686091826595cd",
"macos-universal": "de057e73e6fe0825664c258ca2dd6798c41ae580bf4d896e1647676a4941934a",
"windows-x64": "2192d8ce780c4281b807cd457994963669e5202659ecd92f19b54c3e7d0c1915",
"windows-x86": "9f8582ab5891b000869d6484ea591add9fbac9f1c91b56c7b85fdfd56a261c1b"
}
},
"qt5": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built Qt5",
"hashes": {
"macos-x86_64": "3d0381a52b0e4d49967936c4357f79ac711f43564329304a6db5c90edadd2697",
"macos-arm64": "f4b32548c0530f121956bf0a9a70c36ecbbfca81073d39c396a1759baf2a05c3",
"macos-universal": "9a6cf3b9a6c9efee6ba10df649202e8075e99f3c54ae88dc9a36dbc9d7471c1e",
"windows-x64": "6488a33a474f750d5a4a268a5e20c78bb40799d99136a1b7ce3365a843cb2fd7",
"windows-x86": "a916e09b0a874036801deab2c8a7ec14fdf5d268aa5511eac5bf40727e0c4e33"
},
"pdb-hashes": {
"windows-x64": "e0e5070143fcad9311a68ce5685d8ba8f34f581ed6942b7a92d360f94ca1ba11",
"windows-x86": "36642d1052aa461964f46c17610477b0d9b9defbe2d745ccaacb85f805c1bec2"
}
},
"qt6": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built Qt6",
"hashes": {
"macos-x86_64": "a83f72a11023b03b6cb2dc365f0a66ad9df31163bbb4fe2df32d601856a9fad3",
"macos-arm64": "2f30af90c049670a5660656adbb440668aa1b0567f75a5f29e1def9108928403",
"macos-universal": "252e6684f43ab9c6f262c73af739e2296ce391b998da2c4ee04c254aaa07db18",
"windows-x64": "e5509b54196a3f935250cc4b9c54160c8e588fd0f92bc078a2a64f9d9e2e4e93",
"windows-x86": "24fc03bef153a0e027c1479e42eb08097a4ea1d70a4710825be0783d0626cb0d"
},
"pdb-hashes": {
"windows-x64": "60e5b1d2bc4d7c431bc05f14e3b1e85e088788c372fa85f58717cd6c49555a46",
"windows-x86": "f34d1a89fc85d92913bd6c7f75ec5c28471d74db708c98161100bc8b75f8fc63"
}
}
},
"platformConfig": {
"macos-x86_64": {
"qtVersion": 6,
"deploymentTarget": "10.15"
},
"macos-arm64": {
"qtVersion": 6,
"deploymentTarget": "11.0"
},
"macos-universal": {
"qtVersion": 6,
"deploymentTarget": "10.15"
},
"windows-x64": {
"qtVersion": 6,
"visualStudio": "Visual Studio 17 2022",
"platformSDK": "10.0.20348.0"
},
"windows-x86": {
"qtVersion": 6,
"visualStudio": "Visual Studio 17 2022",
"platformSDK": "10.0.20348.0"
},
"linux-x86_64": {
"qtVersion": 6
}
},
"name": "advanced-scene-switcher",
"version": "1.0.0"
}

270
cmake/AdvSSHelpers.cmake Normal file
View File

@@ -0,0 +1,270 @@
# --- Helper functions ---#
# Subfolder for advanced scene switcher plugins
set(_PLUGIN_FOLDER "adv-ss-plugins")
# --- MACOS section ---
if(OS_MACOS)
set(ADVSS_BUNDLE_DIR "${CMAKE_INSTALL_PREFIX}/advanced-scene-switcher.plugin")
set(ADVSS_BUNDLE_MODULE_DIR "${ADVSS_BUNDLE_DIR}/Contents/MacOS")
set(ADVSS_BUNDLE_PLUGIN_DIR ${ADVSS_BUNDLE_MODULE_DIR}/${_PLUGIN_FOLDER})
function(resign_advss target)
set(_COMMAND "codesign --force --deep --sign - ${ADVSS_BUNDLE_DIR}")
install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")")
endfunction()
function(install_advss_lib_helper target where)
install(
TARGETS ${target}
RUNTIME DESTINATION "${where}" COMPONENT advss_plugins
LIBRARY DESTINATION "${where}" COMPONENT advss_plugins
FRAMEWORK DESTINATION "${where}" COMPONENT advss_plugins)
resign_advss(${target})
endfunction()
function(install_advss_lib target)
install_advss_lib_helper(${target} "${ADVSS_BUNDLE_MODULE_DIR}")
set(_COMMAND
"${CMAKE_INSTALL_NAME_TOOL} \\
-change @rpath/advanced-scene-switcher-lib.so @loader_path/advanced-scene-switcher-lib.so \\
\\\"${ADVSS_BUNDLE_MODULE_DIR}/advanced-scene-switcher\\\"")
install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")"
COMPONENT obs_plugins)
endfunction()
function(install_advss_plugin target)
install_advss_lib_helper(${target} "${ADVSS_BUNDLE_PLUGIN_DIR}")
endfunction()
function(install_advss_plugin_dependency_target target dep)
install(
IMPORTED_RUNTIME_ARTIFACTS
${dep}
RUNTIME
DESTINATION
"${ADVSS_BUNDLE_PLUGIN_DIR}"
COMPONENT
${dep}_Runtime
LIBRARY
DESTINATION
"${ADVSS_BUNDLE_PLUGIN_DIR}"
COMPONENT
${dep}_Runtime
NAMELINK_COMPONENT
${dep}_Development)
resign_advss(${target})
endfunction()
function(install_advss_plugin_dependency_file ${target} dep)
target_sources(advanced-scene-switcher PRIVATE ${dep})
set_source_files_properties(${dep} PROPERTIES MACOSX_PACKAGE_LOCATION
${ADVSS_BUNDLE_PLUGIN_DIR})
resign_advss(${target})
endfunction()
# --- End of section ---
else()
# --- Windows / Linux section ---
function(plugin_install_helper what where where_deb)
install(
TARGETS ${what}
RUNTIME DESTINATION "${where}" COMPONENT ${what}_Runtime
LIBRARY DESTINATION "${where}"
COMPONENT ${what}_Runtime
NAMELINK_COMPONENT ${what}_Development)
install(
FILES $<TARGET_FILE:${what}>
DESTINATION $<CONFIG>/${where}
COMPONENT ${what}_rundir
EXCLUDE_FROM_ALL)
if(OS_WINDOWS)
install(
FILES $<TARGET_PDB_FILE:${what}>
CONFIGURATIONS "RelWithDebInfo" "Debug"
DESTINATION ${where}
COMPONENT ${what}_Runtime
OPTIONAL)
install(
FILES $<TARGET_PDB_FILE:${what}>
CONFIGURATIONS "RelWithDebInfo" "Debug"
DESTINATION $<CONFIG>/${where}
COMPONENT ${what}_rundir
OPTIONAL EXCLUDE_FROM_ALL)
endif()
add_custom_command(
TARGET ${what}
POST_BUILD
COMMAND
"${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_OUTPUT_DIR}
-DCMAKE_INSTALL_COMPONENT=${what}_rundir
-DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
COMMENT "Installing ${what} to plugin rundir ${OBS_OUTPUT_DIR}/${where}\n"
VERBATIM)
if(OS_POSIX AND DEB_INSTALL)
if(NOT LIB_OUT_DIR)
set(LIB_OUT_DIR "/lib/obs-plugins")
endif()
install(
TARGETS ${what}
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR}/${where_deb})
endif()
endfunction()
function(install_advss_lib target)
plugin_install_helper("${target}" "${OBS_PLUGIN_DESTINATION}" "")
endfunction()
function(install_advss_plugin target)
plugin_install_helper(
"${target}" "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
"${_PLUGIN_FOLDER}")
message(STATUS "ADVSS: ENABLED PLUGIN ${target}")
endfunction()
function(install_advss_plugin_dependency_target target dep)
install(
IMPORTED_RUNTIME_ARTIFACTS
${dep}
RUNTIME
DESTINATION
"${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
COMPONENT
${dep}_Runtime
LIBRARY
DESTINATION
"${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
COMPONENT
${dep}_Runtime
NAMELINK_COMPONENT
${dep}_Development)
install(
IMPORTED_RUNTIME_ARTIFACTS
${dep}
RUNTIME
DESTINATION
"${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
COMPONENT
obs_${dep}
EXCLUDE_FROM_ALL
LIBRARY
DESTINATION
"${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
COMPONENT
obs_${dep}
EXCLUDE_FROM_ALL)
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND
"${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_${dep} >
"$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
COMMENT "Installing ${dep} to OBS rundir\n"
VERBATIM)
endfunction()
function(install_advss_plugin_dependency_file target dep)
get_filename_component(_FILENAME ${dep} NAME)
string(REGEX REPLACE "\\.[^.]*$" "" _FILENAMENOEXT ${_FILENAME})
set(_DEP_NAME "${target}-${_FILENAMENOEXT}")
install(
FILES "${dep}"
DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
COMPONENT ${_DEP_NAME}_Runtime
DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
COMPONENT ${_DEP_NAME}_Runtime
NAMELINK_COMPONENT ${_DEP_NAME}_Development)
install(
FILES "${dep}"
DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
COMPONENT obs_${_DEP_NAME}
EXCLUDE_FROM_ALL
DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
COMPONENT obs_${_DEP_NAME}
EXCLUDE_FROM_ALL)
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND
"${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_${_DEP_NAME} >
"$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
COMMENT "Installing ${_DEP_NAME} to OBS rundir\n"
VERBATIM)
endfunction()
endif()
# --- End of section ---
function(setup_advss_plugin target)
if(BUILD_OUT_OF_TREE)
target_link_libraries(${target} PUBLIC OBS::libobs OBS::obs-frontend-api)
else()
target_link_libraries(${target} PUBLIC OBS::libobs OBS::frontend-api)
endif()
find_qt(COMPONENTS Widgets Core)
target_link_libraries(${target} PRIVATE Qt::Core Qt::Widgets)
set_target_properties(
${target}
PROPERTIES AUTOMOC ON
AUTOUIC ON
AUTORCC ON)
target_link_libraries(${target} PRIVATE advanced-scene-switcher-lib)
get_target_property(ADVSS_SOURCE_DIR advanced-scene-switcher-lib SOURCE_DIR)
get_target_property(ADVSS_BINARY_DIR advanced-scene-switcher-lib BINARY_DIR)
if(OS_MACOS)
set(_INSTALL_RPATH "@loader_path" "@loader_path/..")
set_target_properties(${target} PROPERTIES INSTALL_RPATH
"${_INSTALL_RPATH}")
endif()
# Set up include directories for headers generated by Qt
target_include_directories(
${target}
PRIVATE "${ADVSS_BINARY_DIR}/advanced-scene-switcher-lib_autogen/include")
foreach(_CONF Release RelWithDebInfo Debug MinSizeRe)
target_include_directories(
${target}
PRIVATE
"${ADVSS_BINARY_DIR}/advanced-scene-switcher-lib_autogen/include_${_CONF}"
)
endforeach()
# General includes
target_include_directories(
${target}
PRIVATE "${ADVSS_SOURCE_DIR}/src" "${ADVSS_SOURCE_DIR}/src/legacy"
"${ADVSS_SOURCE_DIR}/src/macro-core"
"${ADVSS_SOURCE_DIR}/src/utils" "${ADVSS_SOURCE_DIR}/forms")
endfunction()
function(install_advss_plugin_dependency)
cmake_parse_arguments(PARSED_ARGS "" "TARGET" "DEPENDENCIES" ${ARGN})
if(NOT PARSED_ARGS_TARGET)
message(FATAL_ERROR "You must provide a target")
endif()
set(_PLUGIN_FOLDER "adv-ss-plugins")
foreach(_DEPENDENCY ${PARSED_ARGS_DEPENDENCIES})
if(EXISTS ${_DEPENDENCY})
install_advss_plugin_dependency_file(${PARSED_ARGS_TARGET} ${_DEPENDENCY})
else()
install_advss_plugin_dependency_target(${PARSED_ARGS_TARGET}
${_DEPENDENCY})
endif()
endforeach()
endfunction()

View File

@@ -1,279 +1,269 @@
# - Returns a version string from Git
# * Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
# These functions force a re-configure on each git commit so that you can trust
# the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git
# describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
# Returns the results of git describe on the source tree, and adjusting the
# output so that it tests false if an error occurs.
#
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the working tree (--dirty option),
# and adjusting the output so that it tests false if an error occurs.
# Returns the results of git describe on the working tree (--dirty option), and
# adjusting the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
# Returns the results of git describe --exact-match on the source tree, and
# adjusting the output so that it tests false if there was no exact matching
# tag.
#
# git_local_changes(<var>)
# git_local_changes(<var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. Uses
# the return code of "git diff-index --quiet HEAD --". Does not regard untracked
# files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Original Author: 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com>
# <abiryan@ryand.net> http://academic.cleardefinition.com
#
# Copyright 2009-2013, Iowa State University.
# Copyright 2013-2020, Ryan Pavlik
# Copyright 2013-2020, Contributors
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Copyright 2009-2013, Iowa State University. Copyright 2013-2020, Ryan Pavlik
# Copyright 2013-2020, Contributors SPDX-License-Identifier: BSL-1.0 Distributed
# under the Boost Software License, Version 1.0. (See accompanying file
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
# We must run the following at "include" time, not at function call time, to
# find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
# Function _git_find_closest_git_dir finds the next closest .git directory
# that is part of any directory in the path defined by _start_dir.
# The result is returned in the parent scope variable whose name is passed
# as variable _git_dir_var. If no .git directory can be found, the
# function returns an empty string via _git_dir_var.
# Function _git_find_closest_git_dir finds the next closest .git directory that
# is part of any directory in the path defined by _start_dir. The result is
# returned in the parent scope variable whose name is passed as variable
# _git_dir_var. If no .git directory can be found, the function returns an empty
# string via _git_dir_var.
#
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
# neither foo nor bar contain a file/directory .git. This wil return
# C:/bla/.git
# neither foo nor bar contain a file/directory .git. This wil return C:/bla/.git
#
function(_git_find_closest_git_dir _start_dir _git_dir_var)
set(cur_dir "${_start_dir}")
set(git_dir "${_start_dir}/.git")
while(NOT EXISTS "${git_dir}")
# .git dir not found, search parent directories
set(git_previous_parent "${cur_dir}")
get_filename_component(cur_dir ${cur_dir} DIRECTORY)
if(cur_dir STREQUAL git_previous_parent)
# We have reached the root directory, we are not in git
set(${_git_dir_var}
""
PARENT_SCOPE)
return()
endif()
set(git_dir "${cur_dir}/.git")
endwhile()
set(${_git_dir_var}
"${git_dir}"
PARENT_SCOPE)
set(cur_dir "${_start_dir}")
set(git_dir "${_start_dir}/.git")
while(NOT EXISTS "${git_dir}")
# .git dir not found, search parent directories
set(git_previous_parent "${cur_dir}")
get_filename_component(cur_dir ${cur_dir} DIRECTORY)
if(cur_dir STREQUAL git_previous_parent)
# We have reached the root directory, we are not in git
set(${_git_dir_var}
""
PARENT_SCOPE)
return()
endif()
set(git_dir "${cur_dir}/.git")
endwhile()
set(${_git_dir_var}
"${git_dir}"
PARENT_SCOPE)
endfunction()
function(get_git_head_revision _refspecvar _hashvar)
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
if(NOT "${GIT_DIR}" STREQUAL "")
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
"${GIT_DIR}")
if("${_relative_to_source_dir}" MATCHES "[.][.]")
# We've gone above the CMake root dir.
set(GIT_DIR "")
endif()
if(NOT "${GIT_DIR}" STREQUAL "")
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
"${GIT_DIR}")
if("${_relative_to_source_dir}" MATCHES "[.][.]")
# We've gone above the CMake root dir.
set(GIT_DIR "")
endif()
if("${GIT_DIR}" STREQUAL "")
set(${_refspecvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
set(${_hashvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# Check if the current source dir is a git submodule or a worktree.
# In both cases .git is a file instead of a directory.
#
if(NOT IS_DIRECTORY ${GIT_DIR})
# The following git command will return a non empty string that
# points to the super project working tree if the current
# source dir is inside a git submodule.
# Otherwise the command will return an empty string.
#
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse
--show-superproject-working-tree
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT "${out}" STREQUAL "")
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
${submodule})
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
ABSOLUTE)
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
else()
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
file(READ ${GIT_DIR} worktree_ref)
# The .git directory contains a path to the worktree information directory
# inside the parent git repo of the worktree.
#
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
${worktree_ref})
string(STRIP ${git_worktree_dir} git_worktree_dir)
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
endif()
else()
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake" @ONLY)
include("${GIT_DATA}/grabRef.cmake")
endif()
if("${GIT_DIR}" STREQUAL "")
set(${_refspecvar}
"${HEAD_REF}"
"GITDIR-NOTFOUND"
PARENT_SCOPE)
set(${_hashvar}
"${HEAD_HASH}"
"GITDIR-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# Check if the current source dir is a git submodule or a worktree. In both
# cases .git is a file instead of a directory.
#
if(NOT IS_DIRECTORY ${GIT_DIR})
# The following git command will return a non empty string that points to
# the super project working tree if the current source dir is inside a git
# submodule. Otherwise the command will return an empty string.
#
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse --show-superproject-working-tree
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT "${out}" STREQUAL "")
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE ${submodule})
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
ABSOLUTE)
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
else()
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
file(READ ${GIT_DIR} worktree_ref)
# The .git directory contains a path to the worktree information directory
# inside the parent git repo of the worktree.
#
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
${worktree_ref})
string(STRIP ${git_worktree_dir} git_worktree_dir)
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
endif()
else()
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake" @ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar}
"${HEAD_REF}"
PARENT_SCOPE)
set(${_hashvar}
"${HEAD_HASH}"
PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"${out}"
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# TODO sanitize if((${ARGN}" MATCHES "&&") OR (ARGN MATCHES "||") OR (ARGN
# MATCHES "\\;")) message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with
# git_describe! Passed arguments ${ARGN}") endif()
# message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_describe_working_tree _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"${out}"
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var}
"${out}"
PARENT_SCOPE)
git_describe(out --exact-match ${ARGN})
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var}
"CLEAN"
PARENT_SCOPE)
else()
set(${_var}
"DIRTY"
PARENT_SCOPE)
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var}
"CLEAN"
PARENT_SCOPE)
else()
set(${_var}
"DIRTY"
PARENT_SCOPE)
endif()
endfunction()

View File

@@ -0,0 +1,487 @@
if(POLICY CMP0087)
cmake_policy(SET CMP0087 NEW)
endif()
set(OBS_STANDALONE_PLUGIN_DIR ${CMAKE_SOURCE_DIR}/release)
set(INCLUDED_LIBOBS_CMAKE_MODULES ON)
include(GNUInstallDirs)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(OS_MACOS ON)
set(OS_POSIX ON)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD")
set(OS_POSIX ON)
string(TOUPPER "${CMAKE_SYSTEM_NAME}" _SYSTEM_NAME_U)
set(OS_${_SYSTEM_NAME_U} ON)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(OS_WINDOWS ON)
set(OS_POSIX OFF)
endif()
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND (OS_WINDOWS OR OS_MACOS))
set(CMAKE_INSTALL_PREFIX
${OBS_STANDALONE_PLUGIN_DIR}
CACHE STRING "Directory to install OBS plugin after building" FORCE)
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE
"RelWithDebInfo"
CACHE STRING
"OBS build type [Release, RelWithDebInfo, Debug, MinSizeRel]" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Release RelWithDebInfo
Debug MinSizeRel)
endif()
if(NOT QT_VERSION)
set(QT_VERSION
AUTO
CACHE STRING "OBS Qt version [AUTO, 5, 6]" FORCE)
set_property(CACHE QT_VERSION PROPERTY STRINGS AUTO 5 6)
endif()
macro(find_qt)
set(multiValueArgs COMPONENTS COMPONENTS_WIN COMPONENTS_MAC COMPONENTS_LINUX)
cmake_parse_arguments(FIND_QT "" "${oneValueArgs}" "${multiValueArgs}"
${ARGN})
set(QT_NO_CREATE_VERSIONLESS_TARGETS ON)
find_package(
Qt5
COMPONENTS Core
QUIET)
find_package(
Qt6
COMPONENTS Core
QUIET)
if(NOT _QT_VERSION AND QT_VERSION STREQUAL AUTO)
if(TARGET Qt6::Core)
set(_QT_VERSION
6
CACHE INTERNAL "")
elseif(TARGET Qt5::Core)
set(_QT_VERSION
5
CACHE INTERNAL "")
endif()
message(STATUS "Qt version: ${_QT_VERSION}")
elseif(NOT _QT_VERSION)
if(TARGET Qt${QT_VERSION}::Core)
set(_QT_VERSION
${QT_VERSION}
CACHE INTERNAL "")
else()
if(QT_VERSION EQUAL 6)
set(FALLBACK_QT_VERSION 5)
else()
set(FALLBACK_QT_VERSION 6)
endif()
message(
WARNING
"Qt${QT_VERSION} was not found, falling back to Qt${FALLBACK_QT_VERSION}"
)
if(TARGET Qt${FALLBACK_QT_VERSION}::Core)
set(_QT_VERSION
${FALLBACK_QT_VERSION}
CACHE INTERNAL "")
endif()
endif()
message(STATUS "Qt version: ${_QT_VERSION}")
endif()
set(QT_NO_CREATE_VERSIONLESS_TARGETS OFF)
if(NOT _QT_VERSION)
message(FATAL_ERROR "Neither Qt5 or Qt6 were found")
endif()
if(OS_WINDOWS)
find_package(
Qt${_QT_VERSION}
COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_WIN}
REQUIRED)
elseif(OS_MACOS)
find_package(
Qt${_QT_VERSION}
COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_MAC}
REQUIRED)
else()
find_package(
Qt${_QT_VERSION}
COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_LINUX}
REQUIRED)
endif()
list(APPEND FIND_QT_COMPONENTS "Core")
if("Gui" IN_LIST FIND_QT_COMPONENTS_LINUX)
list(APPEND FIND_QT_COMPONENTS_LINUX "GuiPrivate")
endif()
foreach(_COMPONENT IN LISTS FIND_QT_COMPONENTS FIND_QT_COMPONENTS_WIN
FIND_QT_COMPONENTS_MAC FIND_QT_COMPONENTS_LINUX)
if(NOT TARGET Qt::${_COMPONENT} AND TARGET Qt${_QT_VERSION}::${_COMPONENT})
add_library(Qt::${_COMPONENT} INTERFACE IMPORTED)
set_target_properties(
Qt::${_COMPONENT} PROPERTIES INTERFACE_LINK_LIBRARIES
"Qt${_QT_VERSION}::${_COMPONENT}")
endif()
endforeach()
endmacro()
file(RELATIVE_PATH RELATIVE_INSTALL_PATH ${CMAKE_SOURCE_DIR}
${CMAKE_INSTALL_PREFIX})
file(RELATIVE_PATH RELATIVE_BUILD_PATH ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
# Set up OS-specific environment and helper functions
if(OS_POSIX)
find_program(CCACHE_PROGRAM "ccache")
set(CCACHE_SUPPORT
ON
CACHE BOOL "Enable ccache support")
mark_as_advanced(CCACHE_PROGRAM)
if(CCACHE_PROGRAM AND CCACHE_SUPPORT)
set(CMAKE_CXX_COMPILER_LAUNCHER
${CCACHE_PROGRAM}
CACHE INTERNAL "")
set(CMAKE_C_COMPILER_LAUNCHER
${CCACHE_PROGRAM}
CACHE INTERNAL "")
set(CMAKE_OBJC_COMPILER_LAUNCHER
${CCACHE_PROGRAM}
CACHE INTERNAL "")
set(CMAKE_OBJCXX_COMPILER_LAUNCHER
${CCACHE_PROGRAM}
CACHE INTERNAL "")
set(CMAKE_CUDA_COMPILER_LAUNCHER
${CCACHE_PROGRAM}
CACHE INTERNAL "") # CMake 3.9+
endif()
endif()
if(OS_MACOS)
set(CMAKE_OSX_ARCHITECTURES
"x86_64"
CACHE STRING
"OBS build architecture for macOS - x86_64 required at least")
set_property(CACHE CMAKE_OSX_ARCHITECTURES PROPERTY STRINGS x86_64 arm64
"x86_64;arm64")
set(CMAKE_OSX_DEPLOYMENT_TARGET
"10.15"
CACHE STRING "OBS deployment target for macOS - 10.15+ required")
set_property(CACHE CMAKE_OSX_DEPLOYMENT_TARGET PROPERTY STRINGS 10.15 11.0
12.0 13.0)
set(OBS_BUNDLE_CODESIGN_IDENTITY
"-"
CACHE STRING "OBS code signing identity for macOS")
set(OBS_CODESIGN_ENTITLEMENTS
${CMAKE_SOURCE_DIR}/cmake/bundle/macos/entitlements.plist
CACHE INTERNAL "Path to codesign entitlements plist")
set(OBS_CODESIGN_LINKER
ON
CACHE BOOL "Enable linker code-signing on macOS (macOS 11+ required)")
# Xcode configuration
if(XCODE)
# Tell Xcode to pretend the linker signed binaries so that editing with
# install_name_tool preserves ad-hoc signatures. This option is supported by
# codesign on macOS 11 or higher. See CMake Issue 21854:
# https://gitlab.kitware.com/cmake/cmake/-/issues/21854
set(CMAKE_XCODE_GENERATE_SCHEME ON)
if(OBS_CODESIGN_LINKER)
set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "-o linker-signed")
endif()
endif()
# Set default options for bundling on macOS
set(CMAKE_MACOSX_RPATH ON)
set(CMAKE_SKIP_BUILD_RPATH OFF)
set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks/")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF)
function(setup_plugin_target target)
if(NOT DEFINED MACOSX_PLUGIN_GUI_IDENTIFIER)
message(
FATAL_ERROR
"No 'MACOSX_PLUGIN_GUI_IDENTIFIER' set, but is required to build plugin bundles on macOS - example: 'com.yourname.pluginname'"
)
endif()
if(NOT DEFINED MACOSX_PLUGIN_BUNDLE_VERSION)
message(
FATAL_ERROR
"No 'MACOSX_PLUGIN_BUNDLE_VERSION' set, but is required to build plugin bundles on macOS - example: '25'"
)
endif()
if(NOT DEFINED MACOSX_PLUGIN_SHORT_VERSION_STRING)
message(
FATAL_ERROR
"No 'MACOSX_PLUGIN_SHORT_VERSION_STRING' set, but is required to build plugin bundles on macOS - example: '1.0.2'"
)
endif()
set(MACOSX_PLUGIN_BUNDLE_NAME
"${target}"
PARENT_SCOPE)
set(MACOSX_PLUGIN_BUNDLE_VERSION
"${MACOSX_BUNDLE_BUNDLE_VERSION}"
PARENT_SCOPE)
set(MACOSX_PLUGIN_SHORT_VERSION_STRING
"${MACOSX_BUNDLE_SHORT_VERSION_STRING}"
PARENT_SCOPE)
set(MACOSX_PLUGIN_EXECUTABLE_NAME
"${target}"
PARENT_SCOPE)
set(MACOSX_PLUGIN_BUNDLE_TYPE
"BNDL"
PARENT_SCOPE)
install(
TARGETS ${target}
LIBRARY DESTINATION "."
COMPONENT obs_plugins
NAMELINK_COMPONENT ${target}_Development)
if(${QT_VERSION} EQUAL 5)
set(_QT_FW_VERSION "${QT_VERSION}")
else()
set(_QT_FW_VERSION "A")
endif()
set(_COMMAND
"${CMAKE_INSTALL_NAME_TOOL} \\
-change ${CMAKE_PREFIX_PATH}/lib/QtWidgets.framework/Versions/${QT_VERSION}/QtWidgets @rpath/QtWidgets.framework/Versions/${_QT_FW_VERSION}/QtWidgets \\
-change ${CMAKE_PREFIX_PATH}/lib/QtCore.framework/Versions/${QT_VERSION}/QtCore @rpath/QtCore.framework/Versions/${_QT_FW_VERSION}/QtCore \\
-change ${CMAKE_PREFIX_PATH}/lib/QtGui.framework/Versions/${QT_VERSION}/QtGui @rpath/QtGui.framework/Versions/${_QT_FW_VERSION}/QtGui \\
\\\"\${CMAKE_INSTALL_PREFIX}/${target}.plugin/Contents/MacOS/${target}\\\""
)
install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")"
COMPONENT obs_plugins)
unset(_QT_FW_VERSION)
if(NOT XCODE)
set(_COMMAND
"/usr/bin/codesign --force \\
--sign \\\"${OBS_BUNDLE_CODESIGN_IDENTITY}\\\" \\
--options runtime \\
--entitlements \\\"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/bundle/macOS/entitlements.plist\\\" \\
\\\"\${CMAKE_INSTALL_PREFIX}/${target}.plugin\\\"")
install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")"
COMPONENT obs_plugins)
endif()
set_target_properties(
${target}
PROPERTIES
BUNDLE ON
BUNDLE_EXTENSION "plugin"
OUTPUT_NAME ${target}
MACOSX_BUNDLE_INFO_PLIST
"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/bundle/macOS/Plugin-Info.plist.in"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER
"${MACOSX_PLUGIN_GUI_IDENTIFIER}"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${OBS_BUNDLE_CODESIGN_IDENTITY}"
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS
"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/bundle/macOS/entitlements.plist")
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND
/bin/sh -c
"codesign --force --sign \"-\" $<$<BOOL:${OBS_CODESIGN_LINKER}>:--options linker-signed >\"$<TARGET_BUNDLE_DIR:${target}>\""
COMMENT "Codesigning ${target}"
VERBATIM)
install_bundle_resources(${target})
endfunction()
function(install_bundle_resources target)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/data)
file(GLOB_RECURSE _DATA_FILES "${CMAKE_CURRENT_SOURCE_DIR}/data/*")
foreach(_DATA_FILE IN LISTS _DATA_FILES)
file(RELATIVE_PATH _RELATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/data/
${_DATA_FILE})
get_filename_component(_RELATIVE_PATH ${_RELATIVE_PATH} PATH)
target_sources(${target} PRIVATE ${_DATA_FILE})
set_source_files_properties(
${_DATA_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION
Resources/${_RELATIVE_PATH})
string(REPLACE "\\" "\\\\" _GROUP_NAME ${_RELATIVE_PATH})
source_group("Resources\\${_GROUP_NAME}" FILES ${_DATA_FILE})
endforeach()
endif()
endfunction()
else()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_ARCH_SUFFIX 64)
else()
set(_ARCH_SUFFIX 32)
endif()
set(OBS_OUTPUT_DIR ${CMAKE_BINARY_DIR}/rundir)
if(OS_POSIX)
option(LINUX_PORTABLE "Build portable version (Linux)" ON)
if(NOT LINUX_PORTABLE)
set(OBS_LIBRARY_DESTINATION ${CMAKE_INSTALL_LIBDIR})
set(OBS_PLUGIN_DESTINATION ${OBS_LIBRARY_DESTINATION}/obs-plugins)
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
set(OBS_DATA_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/obs)
else()
set(OBS_LIBRARY_DESTINATION bin/${_ARCH_SUFFIX}bit)
set(OBS_PLUGIN_DESTINATION obs-plugins/${_ARCH_SUFFIX}bit)
set(CMAKE_INSTALL_RPATH
"$ORIGIN/" "${CMAKE_INSTALL_PREFIX}/${OBS_LIBRARY_DESTINATION}")
set(OBS_DATA_DESTINATION "data")
endif()
if(OS_LINUX)
set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${LINUX_MAINTAINER_EMAIL}")
set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}")
set(CPACK_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-linux-x86_64")
set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_DEPENDS
"obs-studio (>= 27.0.0), libqt5core5a (>= 5.9.0~beta), libqt5gui5 (>= 5.3.0), libqt5widgets5 (>= 5.7.0)"
)
set(CPACK_OUTPUT_FILE_PREFIX ${CMAKE_SOURCE_DIR}/release)
if(NOT LINUX_PORTABLE)
set(CPACK_SET_DESTDIR ON)
endif()
include(CPack)
endif()
else()
set(OBS_LIBRARY_DESTINATION "bin/${_ARCH_SUFFIX}bit")
set(OBS_LIBRARY32_DESTINATION "bin/32bit")
set(OBS_LIBRARY64_DESTINATION "bin/64bit")
set(OBS_PLUGIN_DESTINATION "obs-plugins/${_ARCH_SUFFIX}bit")
set(OBS_PLUGIN32_DESTINATION "obs-plugins/32bit")
set(OBS_PLUGIN64_DESTINATION "obs-plugins/64bit")
set(OBS_DATA_DESTINATION "data")
endif()
function(setup_plugin_target target)
set_target_properties(${target} PROPERTIES PREFIX "")
install(
TARGETS ${target}
RUNTIME DESTINATION "${OBS_PLUGIN_DESTINATION}"
COMPONENT ${target}_Runtime
LIBRARY DESTINATION "${OBS_PLUGIN_DESTINATION}"
COMPONENT ${target}_Runtime
NAMELINK_COMPONENT ${target}_Development)
install(
FILES $<TARGET_FILE:${target}>
DESTINATION $<CONFIG>/${OBS_PLUGIN_DESTINATION}
COMPONENT obs_rundir
EXCLUDE_FROM_ALL)
if(OS_WINDOWS)
install(
FILES $<TARGET_PDB_FILE:${target}>
CONFIGURATIONS "RelWithDebInfo" "Debug"
DESTINATION ${OBS_PLUGIN_DESTINATION}
COMPONENT ${target}_Runtime
OPTIONAL)
install(
FILES $<TARGET_PDB_FILE:${target}>
CONFIGURATIONS "RelWithDebInfo" "Debug"
DESTINATION $<CONFIG>/${OBS_PLUGIN_DESTINATION}
COMPONENT obs_rundir
OPTIONAL EXCLUDE_FROM_ALL)
endif()
if(MSVC)
target_link_options(
${target}
PRIVATE
"LINKER:/OPT:REF"
"$<$<NOT:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>>:LINKER\:/SAFESEH\:NO>"
"$<$<CONFIG:DEBUG>:LINKER\:/INCREMENTAL:NO>"
"$<$<CONFIG:RELWITHDEBINFO>:LINKER\:/INCREMENTAL:NO>")
endif()
setup_target_resources(${target} obs-plugins/${target})
if(OS_WINDOWS AND DEFINED OBS_BUILD_DIR)
setup_target_for_testing(${target} obs-plugins/${target})
endif()
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND
"${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_OUTPUT_DIR}
-DCMAKE_INSTALL_COMPONENT=obs_rundir
-DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
COMMENT "Installing to plugin rundir"
VERBATIM)
endfunction()
function(setup_target_resources target destination)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/data)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/
DESTINATION ${OBS_DATA_DESTINATION}/${destination}
USE_SOURCE_PERMISSIONS
COMPONENT obs_plugins)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data
DESTINATION $<CONFIG>/${OBS_DATA_DESTINATION}/${destination}
USE_SOURCE_PERMISSIONS
COMPONENT obs_rundir
EXCLUDE_FROM_ALL)
endif()
endfunction()
if(OS_WINDOWS)
function(setup_target_for_testing target destination)
install(
FILES $<TARGET_FILE:${target}>
DESTINATION $<CONFIG>/${OBS_PLUGIN_DESTINATION}
COMPONENT obs_testing
EXCLUDE_FROM_ALL)
install(
FILES $<TARGET_PDB_FILE:${target}>
CONFIGURATIONS "RelWithDebInfo" "Debug"
DESTINATION $<CONFIG>/${OBS_PLUGIN_DESTINATION}
COMPONENT obs_testing
OPTIONAL EXCLUDE_FROM_ALL)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/
DESTINATION $<CONFIG>/${OBS_DATA_DESTINATION}/${destination}
USE_SOURCE_PERMISSIONS
COMPONENT obs_testing
EXCLUDE_FROM_ALL)
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND
"${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_BUILD_DIR}/rundir
-DCMAKE_INSTALL_COMPONENT=obs_testing
-DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
COMMENT "Installing to OBS test directory"
VERBATIM)
endfunction()
endif()
endif()

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>${MACOSX_PLUGIN_BUNDLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_PLUGIN_GUI_IDENTIFIER}</string>
<key>CFBundleVersion</key>
<string>${MACOSX_PLUGIN_BUNDLE_VERSION}</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_PLUGIN_SHORT_VERSION_STRING}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_PLUGIN_EXECUTABLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>${MACOSX_PLUGIN_BUNDLE_TYPE}</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
</dict>
</plist>

View File

@@ -0,0 +1,17 @@
<!--?xml version="1.0" encoding="UTF-8"?-->
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<!-- Allows @executable_path to load libaries from within the .app bundle. -->
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,920 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PACKAGES</key>
<array>
<dict>
<key>MUST-CLOSE-APPLICATION-ITEMS</key>
<array/>
<key>MUST-CLOSE-APPLICATIONS</key>
<false/>
<key>PACKAGE_FILES</key>
<dict>
<key>DEFAULT_INSTALL_LOCATION</key>
<string>/</string>
<key>HIERARCHY</key>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Applications</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>509</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>BUNDLE_CAN_DOWNGRADE</key>
<false/>
<key>BUNDLE_POSTINSTALL_PATH</key>
<dict>
<key>PATH_TYPE</key>
<integer>0</integer>
</dict>
<key>BUNDLE_PREINSTALL_PATH</key>
<dict>
<key>PATH_TYPE</key>
<integer>0</integer>
</dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>../@RELATIVE_INSTALL_PATH@/@CMAKE_PROJECT_NAME@.plugin</string>
<key>PATH_TYPE</key>
<integer>1</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>3</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>plugins</string>
<key>PATH_TYPE</key>
<integer>2</integer>
<key>PERMISSIONS</key>
<integer>509</integer>
<key>TYPE</key>
<integer>2</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>obs-studio</string>
<key>PATH_TYPE</key>
<integer>2</integer>
<key>PERMISSIONS</key>
<integer>509</integer>
<key>TYPE</key>
<integer>2</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Application Support</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Automator</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Documentation</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Extensions</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Filesystems</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Frameworks</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Input Methods</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Internet Plug-Ins</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>LaunchAgents</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>LaunchDaemons</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>PreferencePanes</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Preferences</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Printers</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>PrivilegedHelperTools</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>1005</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>QuickLook</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>QuickTime</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Screen Savers</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Scripts</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Services</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Widgets</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Library</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Shared</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>1023</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Users</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>/</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<key>PAYLOAD_TYPE</key>
<integer>0</integer>
<key>PRESERVE_EXTENDED_ATTRIBUTES</key>
<false/>
<key>SHOW_INVISIBLE</key>
<false/>
<key>SPLIT_FORKS</key>
<true/>
<key>TREAT_MISSING_FILES_AS_WARNING</key>
<false/>
<key>VERSION</key>
<integer>5</integer>
</dict>
<key>PACKAGE_SCRIPTS</key>
<dict>
<key>POSTINSTALL_PATH</key>
<dict>
<key>PATH_TYPE</key>
<integer>0</integer>
</dict>
<key>PREINSTALL_PATH</key>
<dict>
<key>PATH_TYPE</key>
<integer>0</integer>
</dict>
<key>RESOURCES</key>
<array/>
</dict>
<key>PACKAGE_SETTINGS</key>
<dict>
<key>AUTHENTICATION</key>
<integer>0</integer>
<key>CONCLUSION_ACTION</key>
<integer>0</integer>
<key>FOLLOW_SYMBOLIC_LINKS</key>
<false/>
<key>IDENTIFIER</key>
<string>@MACOS_BUNDLEID@</string>
<key>LOCATION</key>
<integer>0</integer>
<key>NAME</key>
<string>@CMAKE_PROJECT_NAME@</string>
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>PAYLOAD_SIZE</key>
<integer>-1</integer>
<key>REFERENCE_PATH</key>
<string></string>
<key>RELOCATABLE</key>
<false/>
<key>USE_HFS+_COMPRESSION</key>
<false/>
<key>VERSION</key>
<string>@CMAKE_PROJECT_VERSION@</string>
</dict>
<key>TYPE</key>
<integer>0</integer>
<key>UUID</key>
<string>@MACOS_PACKAGE_UUID@</string>
</dict>
</array>
<key>PROJECT</key>
<dict>
<key>PROJECT_COMMENTS</key>
<dict>
<key>NOTES</key>
<data>
</data>
</dict>
<key>PROJECT_PRESENTATION</key>
<dict>
<key>BACKGROUND</key>
<dict>
<key>APPAREANCES</key>
<dict>
<key>DARK_AQUA</key>
<dict/>
<key>LIGHT_AQUA</key>
<dict/>
</dict>
<key>SHARED_SETTINGS_FOR_ALL_APPAREANCES</key>
<true/>
</dict>
<key>INSTALLATION TYPE</key>
<dict>
<key>HIERARCHIES</key>
<dict>
<key>INSTALLER</key>
<dict>
<key>LIST</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>DESCRIPTION</key>
<array/>
<key>OPTIONS</key>
<dict>
<key>HIDDEN</key>
<false/>
<key>STATE</key>
<integer>1</integer>
</dict>
<key>PACKAGE_UUID</key>
<string>@MACOS_PACKAGE_UUID@</string>
<key>TITLE</key>
<array/>
<key>TYPE</key>
<integer>0</integer>
<key>UUID</key>
<string>@MACOS_INSTALLER_UUID@</string>
</dict>
</array>
<key>REMOVED</key>
<dict/>
</dict>
</dict>
<key>MODE</key>
<integer>0</integer>
</dict>
<key>INSTALLATION_STEPS</key>
<array>
<dict>
<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
<string>ICPresentationViewIntroductionController</string>
<key>INSTALLER_PLUGIN</key>
<string>Introduction</string>
<key>LIST_TITLE_KEY</key>
<string>InstallerSectionTitle</string>
</dict>
<dict>
<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
<string>ICPresentationViewReadMeController</string>
<key>INSTALLER_PLUGIN</key>
<string>ReadMe</string>
<key>LIST_TITLE_KEY</key>
<string>InstallerSectionTitle</string>
</dict>
<dict>
<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
<string>ICPresentationViewLicenseController</string>
<key>INSTALLER_PLUGIN</key>
<string>License</string>
<key>LIST_TITLE_KEY</key>
<string>InstallerSectionTitle</string>
</dict>
<dict>
<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
<string>ICPresentationViewDestinationSelectController</string>
<key>INSTALLER_PLUGIN</key>
<string>TargetSelect</string>
<key>LIST_TITLE_KEY</key>
<string>InstallerSectionTitle</string>
</dict>
<dict>
<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
<string>ICPresentationViewInstallationTypeController</string>
<key>INSTALLER_PLUGIN</key>
<string>PackageSelection</string>
<key>LIST_TITLE_KEY</key>
<string>InstallerSectionTitle</string>
</dict>
<dict>
<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
<string>ICPresentationViewInstallationController</string>
<key>INSTALLER_PLUGIN</key>
<string>Install</string>
<key>LIST_TITLE_KEY</key>
<string>InstallerSectionTitle</string>
</dict>
<dict>
<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
<string>ICPresentationViewSummaryController</string>
<key>INSTALLER_PLUGIN</key>
<string>Summary</string>
<key>LIST_TITLE_KEY</key>
<string>InstallerSectionTitle</string>
</dict>
</array>
<key>INTRODUCTION</key>
<dict>
<key>LOCALIZATIONS</key>
<array/>
</dict>
<key>LICENSE</key>
<dict>
<key>LOCALIZATIONS</key>
<array/>
<key>MODE</key>
<integer>0</integer>
</dict>
<key>README</key>
<dict>
<key>LOCALIZATIONS</key>
<array/>
</dict>
<key>SUMMARY</key>
<dict>
<key>LOCALIZATIONS</key>
<array/>
</dict>
<key>TITLE</key>
<dict>
<key>LOCALIZATIONS</key>
<array/>
</dict>
</dict>
<key>PROJECT_REQUIREMENTS</key>
<dict>
<key>LIST</key>
<array>
<dict>
<key>BEHAVIOR</key>
<integer>3</integer>
<key>DICTIONARY</key>
<dict>
<key>IC_REQUIREMENT_OS_DISK_TYPE</key>
<integer>1</integer>
<key>IC_REQUIREMENT_OS_DISTRIBUTION_TYPE</key>
<integer>0</integer>
<key>IC_REQUIREMENT_OS_MINIMUM_VERSION</key>
<integer>101300</integer>
</dict>
<key>IC_REQUIREMENT_CHECK_TYPE</key>
<integer>0</integer>
<key>IDENTIFIER</key>
<string>fr.whitebox.Packages.requirement.os</string>
<key>MESSAGE</key>
<array/>
<key>NAME</key>
<string>Operating System</string>
<key>STATE</key>
<true/>
</dict>
</array>
<key>RESOURCES</key>
<array/>
<key>ROOT_VOLUME_ONLY</key>
<true/>
</dict>
<key>PROJECT_SETTINGS</key>
<dict>
<key>ADVANCED_OPTIONS</key>
<dict>
<key>installer-script.domains:enable_currentUserHome</key>
<integer>1</integer>
</dict>
<key>BUILD_FORMAT</key>
<integer>0</integer>
<key>BUILD_PATH</key>
<dict>
<key>PATH</key>
<string>../@RELATIVE_BUILD_PATH@</string>
<key>PATH_TYPE</key>
<integer>1</integer>
</dict>
<key>EXCLUDED_FILES</key>
<array>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.DS_Store</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Remove .DS_Store files</string>
<key>PROXY_TOOLTIP</key>
<string>Remove ".DS_Store" files created by the Finder.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.pbdevelopment</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Remove .pbdevelopment files</string>
<key>PROXY_TOOLTIP</key>
<string>Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>CVS</string>
<key>TYPE</key>
<integer>1</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.cvsignore</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.cvspass</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.svn</string>
<key>TYPE</key>
<integer>1</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.git</string>
<key>TYPE</key>
<integer>1</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.gitignore</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Remove SCM metadata</string>
<key>PROXY_TOOLTIP</key>
<string>Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>classes.nib</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>designable.db</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>info.nib</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Optimize nib files</string>
<key>PROXY_TOOLTIP</key>
<string>Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>Resources Disabled</string>
<key>TYPE</key>
<integer>1</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Remove Resources Disabled folders</string>
<key>PROXY_TOOLTIP</key>
<string>Remove "Resources Disabled" folders.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>SEPARATOR</key>
<true/>
</dict>
</array>
<key>NAME</key>
<string>@CMAKE_PROJECT_NAME@</string>
<key>PAYLOAD_ONLY</key>
<false/>
<key>TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING</key>
<false/>
</dict>
</dict>
<key>TYPE</key>
<integer>0</integer>
<key>VERSION</key>
<integer>2</integer>
</dict>
</plist>

View File

@@ -0,0 +1,64 @@
#define MyAppName "@CMAKE_PROJECT_NAME@"
#define MyAppVersion "@CMAKE_PROJECT_VERSION@"
#define MyAppPublisher "@PLUGIN_AUTHOR@"
#define MyAppURL "http://www.mywebsite.com"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{@WINDOWS_INSTALLER_UUID@}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={code:GetDirName}
DefaultGroupName={#MyAppName}
OutputBaseFilename={#MyAppName}-{#MyAppVersion}-Windows-Installer
Compression=lzma
SolidCompression=yes
DirExistsWarning=no
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Files]
Source: "..\release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\LICENSE"; Flags: dontcopy
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
[Code]
procedure InitializeWizard();
var
GPLText: AnsiString;
Page: TOutputMsgMemoWizardPage;
begin
ExtractTemporaryFile('LICENSE');
LoadStringFromFile(ExpandConstant('{tmp}\LICENSE'), GPLText);
Page := CreateOutputMsgMemoPage(wpWelcome,
'License Information', 'Please review the license terms before installing {#MyAppName}',
'Press Page Down to see the rest of the agreement. Once you are aware of your rights, click Next to continue.',
String(GPLText)
);
end;
// credit where it's due :
// following function come from https://github.com/Xaymar/obs-studio_amf-encoder-plugin/blob/master/%23Resources/Installer.in.iss#L45
function GetDirName(Value: string): string;
var
InstallPath: string;
begin
// initialize default path, which will be returned when the following registry
// key queries fail due to missing keys or for some different reason
Result := '{autopf}\obs-studio';
// query the first registry value; if this succeeds, return the obtained value
if RegQueryStringValue(HKLM32, 'SOFTWARE\OBS Studio', '', InstallPath) then
Result := InstallPath
end;

View File

@@ -1,4 +1,4 @@
#include "src/headers/version.h"
#include "version.h"
#define GIT_SHA1 "@GIT_SHA1@"
#define GIT_TAG "@GIT_TAG@"
const char g_GIT_SHA1[] = GIT_SHA1;

View File

@@ -31,6 +31,7 @@ AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="Save window position
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="Show system tray notifications"
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Disable UI hints"
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
AdvSceneSwitcher.generalTab.priority="Priority"
AdvSceneSwitcher.generalTab.priority.description="Switching methods priority (Highest priority is at the top)"
AdvSceneSwitcher.generalTab.priority.threadPriority="Use thread priority"
@@ -84,6 +85,10 @@ AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of curre
AdvSceneSwitcher.macroTab.highlightPerformedActions="Highlight recently performed actions of currently selected macro"
AdvSceneSwitcher.macroTab.disableHotkeys="Register hotkeys to control pause state of selected macro"
; Macro List
AdvSceneSwitcher.macroList.deleted="deleted"
AdvSceneSwitcher.macroList.duplicate="\"%1\" is alreay selected!"
; Macro Logic
AdvSceneSwitcher.logic.none="Ignore entry"
AdvSceneSwitcher.logic.and="And"
@@ -204,13 +209,18 @@ AdvSceneSwitcher.condition.timer.reset="Reset"
AdvSceneSwitcher.condition.macro="Macro"
AdvSceneSwitcher.condition.macro.type.count="Count"
AdvSceneSwitcher.condition.macro.type.state="State"
AdvSceneSwitcher.condition.macro.type.multiState="Multiple states"
AdvSceneSwitcher.condition.macro.type.selection="Condition type: {{types}}"
AdvSceneSwitcher.condition.macro.count.type.below="Less than"
AdvSceneSwitcher.condition.macro.count.type.above="More than"
AdvSceneSwitcher.condition.macro.count.type.equal="Exactly"
AdvSceneSwitcher.condition.macro.state.type.below="Less than"
AdvSceneSwitcher.condition.macro.state.type.above="More than"
AdvSceneSwitcher.condition.macro.state.type.equal="Exactly"
AdvSceneSwitcher.condition.macro.count.reset="Reset"
AdvSceneSwitcher.condition.macro.pausedWarning="Selected macro is currently paused!"
AdvSceneSwitcher.condition.macro.state.entry="Conditions of {{macros}} are true"
AdvSceneSwitcher.condition.macro.multistate.entry="Conditions of {{multiStateConditions}}{{multiStateCount}} of the following macros are true:"
AdvSceneSwitcher.condition.macro.count.entry.line1="{{macros}} was executed {{conditions}} {{count}} times"
AdvSceneSwitcher.condition.macro.count.entry.line2="Current count: {{currentCount}} {{resetCount}}"
AdvSceneSwitcher.condition.source="Source"
@@ -299,7 +309,7 @@ AdvSceneSwitcher.condition.studioMode.state.notActive="Studio mode is not active
AdvSceneSwitcher.condition.studioMode.state.previewScene="Preview scene is"
AdvSceneSwitcher.condition.studioMode.entry="{{conditions}}{{scenes}}"
AdvSceneSwitcher.condition.openvr="OpenVR"
AdvSceneSwitcher.condition.errorStatus="OpenVR error: "
AdvSceneSwitcher.condition.openvr.errorStatus="OpenVR error: "
AdvSceneSwitcher.condition.openvr.entry.line1="HMD is in ..."
AdvSceneSwitcher.condition.openvr.entry.line2="{{controls}}"
AdvSceneSwitcher.condition.openvr.entry.line3="HMD is currently at {{xPos}} x {{yPos}} x {{zPos}}"
@@ -322,6 +332,11 @@ AdvSceneSwitcher.condition.stats.condition.equals="equal to"
AdvSceneSwitcher.condition.stats.condition.below="below"
AdvSceneSwitcher.condition.stats.dockHint="You can open the \"Stats\" dock to view the current status"
AdvSceneSwitcher.condition.stats.entry="{{stats}} is {{condition}} {{value}}"
AdvSceneSwitcher.condition.profile="Profile"
AdvSceneSwitcher.condition.profile.entry="Current active profile is {{profiles}}"
AdvSceneSwitcher.condition.websocket="Websocket"
AdvSceneSwitcher.condition.websocket.useRegex="Use regular expressions"
AdvSceneSwitcher.condition.websocket.entry="Message was received:"
; Macro Actions
AdvSceneSwitcher.action.switchScene="Switch scene"
@@ -349,8 +364,10 @@ AdvSceneSwitcher.action.recording.type.stop="Stop recording"
AdvSceneSwitcher.action.recording.type.start="Start recording"
AdvSceneSwitcher.action.recording.type.pause="Pause recording"
AdvSceneSwitcher.action.recording.type.unpause="Unpause recording"
AdvSceneSwitcher.action.recording.type.split="Split recording file"
AdvSceneSwitcher.action.recording.pause.hint="Note that depending on your recording settings you might not be able to pause recording"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}"
AdvSceneSwitcher.action.recording.split.hint="Make sure to enable automatic file splitting in the OBS settings first!"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
AdvSceneSwitcher.action.replay="Replay buffer"
AdvSceneSwitcher.action.replay.saveWarn="Warning: Saving too frequently might result in the replay buffer not actually being saved!"
AdvSceneSwitcher.action.replay.type.stop="Stop replay buffer"
@@ -382,6 +399,8 @@ AdvSceneSwitcher.action.source="Source"
AdvSceneSwitcher.action.source.type.enable="Enable"
AdvSceneSwitcher.action.source.type.disable="Disable"
AdvSceneSwitcher.action.source.type.settings="Set settings"
AdvSceneSwitcher.action.source.type.refreshSettings="Refresh source settings"
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="Can be used to refresh browser, media, etc. sources"
AdvSceneSwitcher.action.source.entry="{{actions}} {{sources}}"
AdvSceneSwitcher.action.source.warning="Warning: Enabling and disabling sources globally cannot be controlled by the OBS UI"
AdvSceneSwitcher.action.source.getSettings="Get current settings"
@@ -475,6 +494,14 @@ AdvSceneSwitcher.action.sequence.status="Last executed macro: %1 - Next macro to
AdvSceneSwitcher.action.sequence.status.none="none"
AdvSceneSwitcher.action.sequence.restart="Restart from beginning once end of list is reached"
AdvSceneSwitcher.action.sequence.continueFrom="Continue with selected item"
AdvSceneSwitcher.action.websocket="Websocket"
AdvSceneSwitcher.action.websocket.entry="Send scene switcher message via {{connection}}"
AdvSceneSwitcher.action.http="Http"
AdvSceneSwitcher.action.http.type.get="GET"
AdvSceneSwitcher.action.http.type.post="POST"
AdvSceneSwitcher.action.http.entry.line1="Send {{method}} to {{url}}"
AdvSceneSwitcher.action.http.entry.line2="Timeout: {{timeout}} seconds"
; Transition Tab
AdvSceneSwitcher.transitionTab.title="Transition"
@@ -730,6 +757,28 @@ AdvSceneSwitcher.askForMacro="Select macro {{macroSelection}}"
AdvSceneSwitcher.close="Close"
AdvSceneSwitcher.browse="Browse"
AdvSceneSwitcher.connection.select="--select connection--"
AdvSceneSwitcher.connection.add="Add new connection"
AdvSceneSwitcher.connection.rename="Rename"
AdvSceneSwitcher.connection.remove="Remove"
AdvSceneSwitcher.connection.properties="Properties"
AdvSceneSwitcher.connection.newName="New name:"
AdvSceneSwitcher.connection.emptyName="Empty name not allowed!"
AdvSceneSwitcher.connection.nameNotAvailable="Name not available!"
AdvSceneSwitcher.connection.nameReserved="Name reserved!"
AdvSceneSwitcher.connection.name="Name:"
AdvSceneSwitcher.connection.address="Address:"
AdvSceneSwitcher.connection.port="Port:"
AdvSceneSwitcher.connection.password="Password:"
AdvSceneSwitcher.connection.reconnect="Reconnect automatically:"
AdvSceneSwitcher.connection.reconnectDelay="Automatically reconnect after:"
AdvSceneSwitcher.connection.connectOnStart="Connect on startup:"
AdvSceneSwitcher.connection.test="Test connection"
AdvSceneSwitcher.connection.status.disconnected="Disconnected"
AdvSceneSwitcher.connection.status.connecting="Connecting"
AdvSceneSwitcher.connection.status.connected="Connected, but not authenticated"
AdvSceneSwitcher.connection.status.authenticated="Connected and authenticated"
AdvSceneSwitcher.selectScene="--select scene--"
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
AdvSceneSwitcher.selectCurrentScene="Current Scene"
@@ -751,6 +800,7 @@ AdvSceneSwitcher.selectProfile="--select profile--"
AdvSceneSwitcher.selectSceneCollection="--select scene collection--"
AdvSceneSwitcher.enterPath="--enter path--"
AdvSceneSwitcher.enterText="--enter text--"
AdvSceneSwitcher.enterURL="--enter URL--"
AdvSceneSwitcher.invaildEntriesWillNotBeSaved="invalid entries will not be saved"
AdvSceneSwitcher.selectWindowTip="Use \"OBS\" to specify OBS window\nUse \"Task Switching\"to specify ALT + TAB"
AdvSceneSwitcher.sceneItemSelection.all="All"

View File

@@ -82,6 +82,7 @@ AdvSceneSwitcher.macroTab.minimize="Minimizar"
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Resaltar macros ejecutadas recientemente"
AdvSceneSwitcher.macroTab.highlightTrueConditions="Resaltar condiciones de la macro seleccionada, que se evaluaron como verdaderas recientemente"
AdvSceneSwitcher.macroTab.highlightPerformedActions="Resaltar acciones realizadas recientemente de la macro seleccionada actualmente"
AdvSceneSwitcher.macroTab.disableHotkeys="Registre teclas de acceso rápido para controlar el estado de pausa de la macro seleccionada"
; Lógica de macros
AdvSceneSwitcher.logic.none="Omitir entrada"
@@ -115,6 +116,7 @@ AdvSceneSwitcher.condition.scene.type.previous="La escena anterior es"
AdvSceneSwitcher.condition.scene.type.changed="Escena cambiada"
AdvSceneSwitcher.condition.scene.type.notChanged="La escena no ha cambiado"
AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="Durante la transición, verifique la escena de destino de la transición"
AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="Durante la transición, verifique la escena de origen de la transición"
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}} {{scenes}}"
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
AdvSceneSwitcher.condition.window="Ventana"
@@ -127,7 +129,7 @@ AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDat
AdvSceneSwitcher.condition.media="Medios"
AdvSceneSwitcher.condition.media.anyOnScene="Cualquier fuente multimedia activada"
AdvSceneSwitcher.condition.media.allOnScene="Todas las fuentes de medios activadas"
AdvSceneSwitcher.condition.media.matchOnChange="Solo coincidir con el cambio (Nota: esta opción se eliminará en una versión futura; utilice las restricciones de tiempo en su lugar)"
AdvSceneSwitcher.condition.media.matchOnChange="Solo coincidir con el cambio (Nota: esta opción se eliminará en una versión futura; use modificadores de duración en su lugar)"
AdvSceneSwitcher.condition.media.inconsistencyInfo="Desafortunadamente, no todos los tipos de fuentes de medios se comportan de la misma manera (p. ej., fuente de medios frente a estado \"Detenido\" de fuente de video VLC).\n¡Así que experimente lo que funciona para su configuración!"
AdvSceneSwitcher.condition.media.entry="El estado de {{mediaSources}}{{scenes}} es {{states}} y {{timeRestrictions}} {{time}}"
AdvSceneSwitcher.condition.video="Video"
@@ -348,8 +350,9 @@ AdvSceneSwitcher.action.recording.type.start="Iniciar grabación"
AdvSceneSwitcher.action.recording.type.pause="Pausar grabación"
AdvSceneSwitcher.action.recording.type.unpause="Reanudar grabación"
AdvSceneSwitcher.action.recording.pause.hint="Tenga en cuenta que, dependiendo de la configuración de grabación, es posible que no pueda pausar la grabación"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
AdvSceneSwitcher.action.replay="Búfer de reproducción"
AdvSceneSwitcher.action.replay.saveWarn="Advertencia: ¡Guardar con demasiada frecuencia puede hacer que el búfer de reproducción no se guarde realmente!"
AdvSceneSwitcher.action.replay.type.stop="Detener el búfer de reproducción"
AdvSceneSwitcher.action.replay.type.start="Iniciar búfer de reproducción"
AdvSceneSwitcher.action.replay.type.save="Guardar búfer de reproducción"
@@ -434,11 +437,18 @@ AdvSceneSwitcher.action.file="Archivo"
AdvSceneSwitcher.action.file.type.write="Escribir"
AdvSceneSwitcher.action.file.type.append="Agregar"
AdvSceneSwitcher.action.file.entry="{{actions}} a {{filePath}}:"
AdvSceneSwitcher.action.previewScene="Cambiar escena de vista previa"
AdvSceneSwitcher.action.previewScene.entry="Cambiar escena de vista previa a {{scenes}}"
AdvSceneSwitcher.action.SceneSwap="Cambiar escena (modo Estudio)"
AdvSceneSwitcher.action.SceneSwap.entry="Intercambiar Vista Previa y Programa en Modo Estudio"
AdvSceneSwitcher.action.studioMode="Modo estudio"
AdvSceneSwitcher.action.studioMode.type.swap="Intercambiar vista previa y escena del programa"
AdvSceneSwitcher.action.studioMode.type.setScene="Establecer escena de vista previa en"
AdvSceneSwitcher.action.studioMode.type.enable="Activar modo estudio"
AdvSceneSwitcher.action.studioMode.type.disable="Deshabilitar el modo de estudio"
AdvSceneSwitcher.action.studioMode.entry="{{actions}}{{scenes}}"
AdvSceneSwitcher.action.transition="Transición"
AdvSceneSwitcher.action.transition.type.scene="transición de escena"
AdvSceneSwitcher.action.transition.type.sceneOverride="anulación de transición de escena"
AdvSceneSwitcher.action.transition.type.sourceShow="transición del programa de origen"
AdvSceneSwitcher.action.transition.type.sourceHide="fuente ocultar transición"
AdvSceneSwitcher.action.transition.entry.line1="Modificar {{type}}{{scenes}}{{sources}}"
AdvSceneSwitcher.action.transition.entry.line2="{{setTransition}}Establecer el tipo de transición en {{transitions}}"
AdvSceneSwitcher.action.transition.entry.line3="{{setDuration}}Establecer la duración de la transición en {{duration}}segundos"
AdvSceneSwitcher.action.timer="Temporizador"
@@ -586,6 +596,7 @@ AdvSceneSwitcher.timeTab.afterstart="Empezar al iniciar emisión/grabación"
AdvSceneSwitcher.timeTab.afterstart.tip="Se utilizará el tiempo relativo al inicio de la transmisión / grabación"
AdvSceneSwitcher.timeTab.entry="{{triggers}} a las {{time}} cambiar a {{scenes}} usando {{transitions}}"
AdvSceneSwitcher.timeTab.help="Esta pestaña te permitirá cambiar automáticamente a una escena diferente en función de la hora local actual.\n\nTen en cuenta que el selector de escenas solo cambiará de escena a la hora exacta que especificaste.\nAsegúrate de haber configurado los ajustes de prioridad en la pestaña General a tu gusto para que no se pierda el punto de tiempo seleccionado debido a que otros métodos de cambio tengan una prioridad más alta.\n\nHaz clic en el símbolo más resaltado para continuar."
; Idle Tab
AdvSceneSwitcher.idleTab.title="Inactividad"
AdvSceneSwitcher.idleTab.enable="Habilitar la detección de inactividad"
@@ -615,6 +626,7 @@ AdvSceneSwitcher.audioTab.title="Audio"
AdvSceneSwitcher.audioTab.condition.above="por encima del"
AdvSceneSwitcher.audioTab.condition.below="por debajo del"
AdvSceneSwitcher.audioTab.ignoreInactiveSource="a menos que la fuente esté inactiva"
AdvSceneSwitcher.audioTab.entry="Cuando el volumen de {{audioSources}} es {{condition}} {{volumeWidget}} durante {{duration}} segundos, cambie a {{scenes}} usando {{transitions}} {{ignoreInactiveSource}}"
AdvSceneSwitcher.audioTab.multiMatchfallbackCondition="Si múltiples entradas coinciden ..."
AdvSceneSwitcher.audioTab.multiMatchfallback="... durante {{duration}} cambiar a {{scenes}} usando {{transitions}}"
AdvSceneSwitcher.audioTab.help="Esta pestaña te permitirá cambiar de escena según el volumen de las fuentes.\nPor ejemplo, podrías cambiar automáticamente a una escena diferente si el volumen de su micrófono alcanza un cierto umbral.\n\nHaz clic en el símbolo más resaltado para continuar."
@@ -741,7 +753,6 @@ AdvSceneSwitcher.enterPath="--ingrese la ruta--"
AdvSceneSwitcher.enterText="--ingresar texto--"
AdvSceneSwitcher.invaildEntriesWillNotBeSaved="las entradas no válidas no se guardarán"
AdvSceneSwitcher.selectWindowTip="Usa \"OBS \" para especificar la ventana de OBS\nUsa \"Cambiar de tarea \" para especificar ALT + TAB"
AdvSceneSwitcher.sceneItemSelection.all="Todos"
AdvSceneSwitcher.sceneItemSelection.any="Cualquiera"
@@ -762,5 +773,6 @@ AdvSceneSwitcher.duration.condition.none="Sin límite de tiempo"
AdvSceneSwitcher.duration.condition.more="Al menos durante"
AdvSceneSwitcher.duration.condition.equal="Para exactamente"
AdvSceneSwitcher.duration.condition.less="Para como máximo"
AdvSceneSwitcher.duration.condition.within="Dentro de los últimos"
;Traducido por: @EliasDipa
;Traducido por: @EliasDipa

View File

@@ -132,7 +132,7 @@ AdvSceneSwitcher.action.recording.type.start="Начать запись"
AdvSceneSwitcher.action.recording.type.pause="Пауза записи"
AdvSceneSwitcher.action.recording.type.unpause="Снять запись с паузы"
AdvSceneSwitcher.action.recording.pause.hint="Обратите внимание, что в зависимости от настроек записи вы можете не иметь возможности приостановить запись"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
AdvSceneSwitcher.action.replay="Буфер воспроизведения"
AdvSceneSwitcher.action.replay.type.stop="Остановить буфер воспроизведения"
AdvSceneSwitcher.action.replay.type.start="Начать воспроизведение буфера"

View File

@@ -280,7 +280,7 @@ AdvSceneSwitcher.action.recording.type.start="Kayıt Başlat"
AdvSceneSwitcher.action.recording.type.pause="Kayıt Duraklat"
AdvSceneSwitcher.action.recording.type.unpause="Kayıt Duraklatma"
AdvSceneSwitcher.action.recording.pause.hint="Kayıt ayarlarınıza bağlı olarak kaydı duraklatamayabileceğinizi unutmayın."
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
AdvSceneSwitcher.action.replay="Tekrar arabelleği"
AdvSceneSwitcher.action.replay.type.stop="Tekrar arabelleğini durdur"
AdvSceneSwitcher.action.replay.type.start="Tekrar arabelleğini başlat"

View File

@@ -323,7 +323,7 @@ AdvSceneSwitcher.action.recording.type.start="开始录制"
AdvSceneSwitcher.action.recording.type.pause="暂停录制"
AdvSceneSwitcher.action.recording.type.unpause="取消录制暂停"
AdvSceneSwitcher.action.recording.pause.hint="请注意,根据您的录制设置,您可能无法暂停录制"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}"
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
AdvSceneSwitcher.action.replay="回放缓冲区"
AdvSceneSwitcher.action.replay.type.stop="停止回放缓冲区"
AdvSceneSwitcher.action.replay.type.start="启动回放缓冲区"

1
deps/obs-websocket vendored Submodule

Submodule deps/obs-websocket added at a25427c7cc

2
deps/opencv vendored

File diff suppressed because it is too large Load Diff

View File

@@ -4,13 +4,21 @@
OBS_DECLARE_MODULE()
OBS_MODULE_USE_DEFAULT_LOCALE("advanced-scene-switcher", "en-US")
void InitSceneSwitcher();
typedef const char *(*translateFunc)(const char *);
void InitSceneSwitcher(obs_module_t *, translateFunc);
void RegisterWebsocketVendor();
void FreeSceneSwitcher();
void obs_module_post_load(void)
{
RegisterWebsocketVendor();
}
bool obs_module_load(void)
{
obs_frontend_push_ui_translation(obs_module_get_string);
InitSceneSwitcher();
InitSceneSwitcher(obs_current_module(), obs_module_text);
return true;
}

View File

@@ -8,11 +8,21 @@
#include <obs-module.h>
#include <obs-frontend-api.h>
#include "headers/advanced-scene-switcher.hpp"
#include "headers/status-control.hpp"
#include "headers/curl-helper.hpp"
#include "headers/utility.hpp"
#include "headers/version.h"
#include "advanced-scene-switcher.hpp"
#include "status-control.hpp"
#include "curl-helper.hpp"
#include "utility.hpp"
#include "version.h"
const char *obs_module_text(const char *text)
{
return switcher->translate(text);
}
obs_module_t *obs_current_module()
{
return switcher->modulePtr;
}
SwitcherData *switcher = nullptr;
SwitcherData *GetSwitcher()
@@ -66,9 +76,6 @@ void AdvSceneSwitcher::loadUI()
(void)DisplayMessage(msg);
}
#if __APPLE__
setMinimumHeight(700);
#endif
setupGeneralTab();
setupTitleTab();
setupExecutableTab();
@@ -220,6 +227,8 @@ void SwitcherData::Thread()
}
}
websocketMessages.clear();
// After this point we will call frontend functions like
// obs_frontend_set_current_scene() and
// obs_frontend_set_current_transition()
@@ -478,14 +487,6 @@ bool SwitcherData::anySceneTransitionStarted()
******************************************************************************/
extern "C" void FreeSceneSwitcher()
{
if (loaded_curl_lib) {
if (switcher->curl && f_curl_cleanup) {
f_curl_cleanup(switcher->curl);
}
delete loaded_curl_lib;
loaded_curl_lib = nullptr;
}
PlatformCleanup();
delete switcher;
@@ -628,11 +629,9 @@ static void OBSEvent(enum obs_frontend_event event, void *switcher)
case OBS_FRONTEND_EVENT_STREAMING_STOPPED:
resetLiveTime();
break;
#ifdef REPLAYBUFFER_SUPPORTED
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVED:
setReplayBufferSaved();
break;
#endif
case OBS_FRONTEND_EVENT_TRANSITION_STOPPED:
setTranstionEnd();
break;
@@ -675,16 +674,14 @@ void LoadPlugins()
}
}
extern "C" void InitSceneSwitcher()
extern "C" void InitSceneSwitcher(obs_module_t *m, translateFunc t)
{
blog(LOG_INFO, "version: %s", g_GIT_TAG);
blog(LOG_INFO, "version: %s", g_GIT_SHA1);
switcher = new SwitcherData;
if (loadCurl() && f_curl_init) {
switcher->curl = f_curl_init();
}
switcher->modulePtr = m;
switcher->translate = t;
PlatformInit();
LoadPlugins();

View File

@@ -1,15 +1,10 @@
#pragma once
#ifdef BUILD_OUT_OF_TREE
#include "../../forms/ui_advanced-scene-switcher.h"
#elif defined ADVSS_MODULE
#include "../../../ui_advanced-scene-switcher.h"
#else
#include "ui_advanced-scene-switcher.h"
#endif
#include "macro-segment-list.hpp"
#include "switcher-data-structs.hpp"
#include "platform-funcs.hpp"
#include <macro-segment-list.hpp>
#include <ui_advanced-scene-switcher.h>
#define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__)
#define vblog(level, msg, ...) \
if (switcher->verbose) { \
@@ -97,6 +92,9 @@ signals:
void SceneGroupAdded(const QString &name);
void SceneGroupRemoved(const QString &name);
void SceneGroupRenamed(const QString &oldName, const QString newName);
void ConnectionAdded(const QString &);
void ConnectionRenamed(const QString &oldName, const QString &newName);
void ConnectionRemoved(const QString &);
public slots:
void on_windowUp_clicked();
@@ -298,8 +296,6 @@ public slots:
void updateScreenRegionCursorPos();
void on_close_clicked();
private:
bool MacroTabIsInFocus();

View File

@@ -1,59 +0,0 @@
# Helper function to install plugins to correct location
function(install_advss_plugin target)
set(plugin_folder "adv-ss-plugins")
if(APPLE)
set(_bit_suffix "")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_bit_suffix "64bit/")
else()
set(_bit_suffix "32bit/")
endif()
set_target_properties(${target} PROPERTIES PREFIX "")
install(
TARGETS ${target}
LIBRARY DESTINATION "${OBS_PLUGIN_DESTINATION}/${plugin_folder}"
RUNTIME DESTINATION "${OBS_PLUGIN_DESTINATION}/${plugin_folder}")
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND
"${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:${target}>"
"${OBS_OUTPUT_DIR}/$<CONFIGURATION>/obs-plugins/${_bit_suffix}/${plugin_folder}/$<TARGET_FILE_NAME:${target}>"
VERBATIM)
if(DEFINED ENV{obsInstallerTempDir})
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND
"${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:${target}>"
"$ENV{obsInstallerTempDir}/${OBS_PLUGIN_DESTINATION}/${plugin_folder}/$<TARGET_FILE_NAME:${target}>"
VERBATIM)
endif()
if(MSVC)
obs_debug_copy_helper(
${target}
"${OBS_OUTPUT_DIR}/$<CONFIGURATION>/obs-plugins/${_bit_suffix}/${plugin_folder}"
)
if(DEFINED ENV{obsInstallerTempDir})
obs_debug_copy_helper(
${target}
"$ENV{obsInstallerTempDir}/${OBS_PLUGIN_DESTINATION}/${plugin_folder}")
endif()
install(
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pdbs/"
DESTINATION "${OBS_PLUGIN_DESTINATION}/${plugin_folder}"
CONFIGURATIONS Debug RelWithDebInfo)
endif()
endfunction()
# Add macro conditions or actions which have dependencies to external libraries
# or other components which might potentially not be fulfilled by the user and
# thus cause issues.
add_subdirectory(opencv)
add_subdirectory(openvr)

View File

@@ -1,63 +0,0 @@
cmake_minimum_required(VERSION 3.14)
project(advanced-scene-switcher-opencv)
add_definitions(-DADVSS_MODULE)
find_package(OpenCV)
if(OpenCV_FOUND)
include_directories("${OpenCV_INCLUDE_DIRS}")
else()
set(OpenCV_LIBRARIES "")
message(
WARNING
"OpenCV not found! Functionality relying on OpenCV will be disabled!\nOpenCV sources are available under: ${CMAKE_CURRENT_SOURCE_DIR}/deps/opencv"
)
return()
endif()
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../headers")
set(module_SOURCES
area-selection.cpp
area-selection.hpp
macro-condition-video.cpp
macro-condition-video.hpp
opencv-helpers.cpp
opencv-helpers.hpp
preview-dialog.cpp
preview-dialog.hpp
threshold-slider.cpp
threshold-slider.hpp
video-selection.cpp
video-selection.hpp)
add_library(advanced-scene-switcher-opencv MODULE ${module_SOURCES})
if(BUILD_OUT_OF_TREE)
target_link_libraries(
advanced-scene-switcher-opencv
advanced-scene-switcher
${LIBOBS_LIB}
${LIBOBS_FRONTEND_API_LIB}
${OpenCV_LIBRARIES}
Qt5::Core
Qt5::Widgets)
if(UNIX AND NOT APPLE)
if(NOT LIB_OUT_DIR)
set(LIB_OUT_DIR "/lib/obs-plugins")
endif()
set_target_properties(advanced-scene-switcher-opencv PROPERTIES PREFIX "")
install(
TARGETS advanced-scene-switcher-opencv
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR}/adv-ss-plugins)
endif()
else()
target_link_libraries(
advanced-scene-switcher-opencv
advanced-scene-switcher
obs-frontend-api
${OpenCV_LIBRARIES}
Qt5::Core
Qt5::Widgets
libobs)
install_advss_plugin(advanced-scene-switcher-opencv)
endif()

View File

@@ -1,16 +1,11 @@
#include "headers/advanced-scene-switcher.hpp"
#include "headers/status-control.hpp"
#include "headers/utility.hpp"
#include "headers/version.h"
#include "advanced-scene-switcher.hpp"
#include "status-control.hpp"
#include "utility.hpp"
#include "version.h"
#include <QFileDialog>
#include <QStandardPaths>
void AdvSceneSwitcher::on_close_clicked()
{
close();
}
void AdvSceneSwitcher::reject()
{
close();
@@ -152,7 +147,10 @@ void AdvSceneSwitcher::closeEvent(QCloseEvent *)
}
switcher->windowPos = this->pos();
switcher->windowSize = this->size();
switcher->macroActionConditionSplitterPosition =
ui->macroActionConditionSplitter->sizes();
switcher->macroListMacroEditSplitterPosition =
ui->macroListMacroEditSplitter->sizes();
obs_frontend_save();
}
@@ -194,7 +192,8 @@ void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state)
bool isLegacyTab(const QString &name)
{
return name == obs_module_text(
return name == obs_module_text("AdvSceneSwitcher.networkTab.title") ||
name == obs_module_text(
"AdvSceneSwitcher.transitionTab.title") ||
name == obs_module_text(
"AdvSceneSwitcher.windowTitleTab.title") ||
@@ -501,8 +500,11 @@ void SwitcherData::loadSettings(obs_data_t *obj)
return;
}
// Needs to be loaded before any entries which might rely on scene group
// selections to be available.
loadSceneGroups(obj);
loadMacros(obj);
loadConnections(obj);
loadWindowTitleSwitches(obj);
loadScreenRegionSwitches(obj);
loadPauseSwitches(obj);
@@ -520,6 +522,7 @@ void SwitcherData::loadSettings(obs_data_t *obj)
loadSceneTriggers(obj);
loadGeneralSettings(obj);
loadHotkeys(obj);
loadUISettings(obj);
// Reset on startup and scene collection change
switcher->lastOpenedTab = -1;
@@ -531,11 +534,9 @@ void SwitcherData::saveSettings(obs_data_t *obj)
return;
}
// Needs to be loaded before any entries which might rely on scene group
// selections to be available.
saveSceneGroups(obj);
saveMacros(obj);
saveConnections(obj);
saveWindowTitleSwitches(obj);
saveScreenRegionSwitches(obj);
savePauseSwitches(obj);
@@ -553,6 +554,7 @@ void SwitcherData::saveSettings(obs_data_t *obj)
saveSceneTriggers(obj);
saveGeneralSettings(obj);
saveHotkeys(obj);
saveUISettings(obj);
saveVersion(obj, g_GIT_SHA1);
}
@@ -593,31 +595,6 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
obs_data_set_int(obj, "priority10", functionNamesByPriority[10]);
obs_data_set_int(obj, "threadPriority", threadPriority);
obs_data_set_int(obj, "generalTabPos", tabOrder[0]);
obs_data_set_int(obj, "macroTabPos", tabOrder[1]);
obs_data_set_int(obj, "transitionTabPos", tabOrder[2]);
obs_data_set_int(obj, "pauseTabPos", tabOrder[3]);
obs_data_set_int(obj, "titleTabPos", tabOrder[4]);
obs_data_set_int(obj, "exeTabPos", tabOrder[5]);
obs_data_set_int(obj, "regionTabPos", tabOrder[6]);
obs_data_set_int(obj, "mediaTabPos", tabOrder[7]);
obs_data_set_int(obj, "fileTabPos", tabOrder[8]);
obs_data_set_int(obj, "randomTabPos", tabOrder[9]);
obs_data_set_int(obj, "timeTabPos", tabOrder[10]);
obs_data_set_int(obj, "idleTabPos", tabOrder[11]);
obs_data_set_int(obj, "sequenceTabPos", tabOrder[12]);
obs_data_set_int(obj, "audioTabPos", tabOrder[13]);
obs_data_set_int(obj, "videoTabPos", tabOrder[14]);
obs_data_set_int(obj, "networkTabPos", tabOrder[15]);
obs_data_set_int(obj, "sceneGroupTabPos", tabOrder[16]);
obs_data_set_int(obj, "triggerTabPos", tabOrder[17]);
obs_data_set_bool(obj, "saveWindowGeo", saveWindowGeo);
obs_data_set_int(obj, "windowPosX", windowPos.x());
obs_data_set_int(obj, "windowPosY", windowPos.y());
obs_data_set_int(obj, "windowWidth", windowSize.width());
obs_data_set_int(obj, "windowHeight", windowSize.height());
}
void SwitcherData::loadGeneralSettings(obs_data_t *obj)
@@ -693,7 +670,68 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
obs_data_set_default_int(obj, "threadPriority",
QThread::NormalPriority);
threadPriority = obs_data_get_int(obj, "threadPriority");
}
void saveSplitterPos(QList<int> &sizes, obs_data_t *obj, const std::string name)
{
auto array = obs_data_array_create();
for (int i = 0; i < sizes.count(); ++i) {
obs_data_t *array_obj = obs_data_create();
obs_data_set_int(array_obj, "pos", sizes[i]);
obs_data_array_push_back(array, array_obj);
obs_data_release(array_obj);
}
obs_data_set_array(obj, name.c_str(), array);
obs_data_array_release(array);
}
void loadSplitterPos(QList<int> &sizes, obs_data_t *obj, const std::string name)
{
obs_data_array_t *array = obs_data_get_array(obj, name.c_str());
size_t count = obs_data_array_count(array);
for (size_t i = 0; i < count; i++) {
obs_data_t *item = obs_data_array_item(array, i);
sizes << obs_data_get_int(item, "pos");
obs_data_release(item);
}
obs_data_array_release(array);
}
void SwitcherData::saveUISettings(obs_data_t *obj)
{
obs_data_set_int(obj, "generalTabPos", tabOrder[0]);
obs_data_set_int(obj, "macroTabPos", tabOrder[1]);
obs_data_set_int(obj, "transitionTabPos", tabOrder[2]);
obs_data_set_int(obj, "pauseTabPos", tabOrder[3]);
obs_data_set_int(obj, "titleTabPos", tabOrder[4]);
obs_data_set_int(obj, "exeTabPos", tabOrder[5]);
obs_data_set_int(obj, "regionTabPos", tabOrder[6]);
obs_data_set_int(obj, "mediaTabPos", tabOrder[7]);
obs_data_set_int(obj, "fileTabPos", tabOrder[8]);
obs_data_set_int(obj, "randomTabPos", tabOrder[9]);
obs_data_set_int(obj, "timeTabPos", tabOrder[10]);
obs_data_set_int(obj, "idleTabPos", tabOrder[11]);
obs_data_set_int(obj, "sequenceTabPos", tabOrder[12]);
obs_data_set_int(obj, "audioTabPos", tabOrder[13]);
obs_data_set_int(obj, "videoTabPos", tabOrder[14]);
obs_data_set_int(obj, "networkTabPos", tabOrder[15]);
obs_data_set_int(obj, "sceneGroupTabPos", tabOrder[16]);
obs_data_set_int(obj, "triggerTabPos", tabOrder[17]);
obs_data_set_bool(obj, "saveWindowGeo", saveWindowGeo);
obs_data_set_int(obj, "windowPosX", windowPos.x());
obs_data_set_int(obj, "windowPosY", windowPos.y());
obs_data_set_int(obj, "windowWidth", windowSize.width());
obs_data_set_int(obj, "windowHeight", windowSize.height());
saveSplitterPos(macroActionConditionSplitterPosition, obj,
"macroActionConditionSplitterPosition");
saveSplitterPos(macroListMacroEditSplitterPosition, obj,
"macroListMacroEditSplitterPosition");
}
void SwitcherData::loadUISettings(obs_data_t *obj)
{
obs_data_set_default_int(obj, "generalTabPos", 0);
obs_data_set_default_int(obj, "macroTabPos", 1);
obs_data_set_default_int(obj, "networkTabPos", 13);
@@ -742,6 +780,10 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
(int)obs_data_get_int(obj, "windowPosY")};
windowSize = {(int)obs_data_get_int(obj, "windowWidth"),
(int)obs_data_get_int(obj, "windowHeight")};
loadSplitterPos(macroActionConditionSplitterPosition, obj,
"macroActionConditionSplitterPosition");
loadSplitterPos(macroListMacroEditSplitterPosition, obj,
"macroListMacroEditSplitterPosition");
}
bool SwitcherData::tabOrderValid()

View File

@@ -1,26 +0,0 @@
#pragma once
#include <curl/curl.h>
#include <QLibrary>
#if defined(WIN32)
constexpr auto curl_library_name = "libcurl.dll";
#elif __APPLE__
constexpr auto curl_library_name = "libcurl.4.dylib";
#else
constexpr auto curl_library_name = "libcurl.so.4";
#endif
typedef CURL *(*initFunction)(void);
typedef CURLcode (*setOptFunction)(CURL *, CURLoption, ...);
typedef CURLcode (*performFunction)(CURL *);
typedef void (*cleanupFunction)(CURL *);
extern initFunction f_curl_init;
extern setOptFunction f_curl_setopt;
extern performFunction f_curl_perform;
extern cleanupFunction f_curl_cleanup;
extern QLibrary *loaded_curl_lib;
bool resolveCurl();
bool loadCurl();

View File

@@ -1,23 +0,0 @@
#pragma once
#include <string>
#include <QString>
#include <obs-module.h>
class Macro;
class MacroRef {
public:
MacroRef(){};
MacroRef(std::string name);
void UpdateRef();
void UpdateRef(std::string name);
void UpdateRef(QString name);
void Save(obs_data_t *obj);
void Load(obs_data_t *obj);
Macro *get();
Macro *operator->();
private:
std::string _name = "";
Macro *_ref = nullptr;
};

View File

@@ -1,5 +1,5 @@
#include "headers/hotkey.hpp"
#include "headers/advanced-scene-switcher.hpp"
#include "hotkey.hpp"
#include "advanced-scene-switcher.hpp"
#include <obs-module.h>
#include <fstream>
#include <regex>

View File

@@ -1,7 +1,7 @@
#include <thread>
#include "headers/advanced-scene-switcher.hpp"
#include "headers/utility.hpp"
#include "advanced-scene-switcher.hpp"
#include "utility.hpp"
bool SceneTrigger::pause = false;
static QMetaObject::Connection addPulse;
@@ -185,22 +185,18 @@ void frontEndActionThread(sceneTriggerAction action, double delay)
case sceneTriggerAction::STOP_STREAMING:
obs_frontend_streaming_stop();
break;
#ifdef REPLAYBUFFER_SUPPORTED
case sceneTriggerAction::START_REPLAY_BUFFER:
obs_frontend_replay_buffer_start();
break;
case sceneTriggerAction::STOP_REPLAY_BUFFER:
obs_frontend_replay_buffer_stop();
break;
#endif
#ifdef VCAM_SUPPORTED
case sceneTriggerAction::START_VCAM:
obs_frontend_start_virtualcam();
break;
case sceneTriggerAction::STOP_VCAM:
obs_frontend_stop_virtualcam();
break;
#endif
default:
blog(LOG_WARNING, "ignoring unexpected frontend action '%d'",
static_cast<int>(action));

View File

@@ -1,8 +1,8 @@
#include <float.h>
#include "headers/advanced-scene-switcher.hpp"
#include "headers/volume-control.hpp"
#include "headers/utility.hpp"
#include "advanced-scene-switcher.hpp"
#include "volume-control.hpp"
#include "utility.hpp"
bool AudioSwitch::pause = false;
static QMetaObject::Connection addPulse;

View File

@@ -1,5 +1,5 @@
#include "headers/advanced-scene-switcher.hpp"
#include "headers/utility.hpp"
#include "advanced-scene-switcher.hpp"
#include "utility.hpp"
bool ExecutableSwitch::pause = false;
static QMetaObject::Connection addPulse;

View File

@@ -1,12 +1,14 @@
#include <QtGlobal>
#include <QFileDialog>
#include <QTextStream>
#include <QDateTime>
#include <functional>
#include <regex>
#include <curl/curl.h>
#include "headers/advanced-scene-switcher.hpp"
#include "headers/curl-helper.hpp"
#include "headers/utility.hpp"
#include "advanced-scene-switcher.hpp"
#include "curl-helper.hpp"
#include "utility.hpp"
bool FileSwitch::pause = false;
static QMetaObject::Connection addPulse;
@@ -113,7 +115,11 @@ void SwitcherData::writeToStatusFile(const QString &msg)
QFile file(QString::fromStdString(fileIO.writePath));
if (file.open(QIODevice::ReadWrite)) {
QTextStream stream(&file);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
stream << msg << endl;
#else
stream << msg << Qt::endl;
#endif
}
file.close();
}
@@ -168,21 +174,18 @@ static std::string getRemoteData(std::string &url)
{
std::string readBuffer;
if (switcher->curl && f_curl_setopt && f_curl_perform) {
f_curl_setopt(switcher->curl, CURLOPT_URL, url.c_str());
f_curl_setopt(switcher->curl, CURLOPT_WRITEFUNCTION,
WriteCallback);
f_curl_setopt(switcher->curl, CURLOPT_WRITEDATA, &readBuffer);
switcher->curl.SetOpt(CURLOPT_URL, url.c_str());
switcher->curl.SetOpt(CURLOPT_WRITEFUNCTION, WriteCallback);
switcher->curl.SetOpt(CURLOPT_WRITEDATA, &readBuffer);
// Set timeout to at least one second
int timeout = switcher->interval / 1000;
if (timeout == 0) {
timeout = 1;
}
f_curl_setopt(switcher->curl, CURLOPT_TIMEOUT, 1);
f_curl_perform(switcher->curl);
// Set timeout to at least one second
int timeout = switcher->interval / 1000;
if (timeout == 0) {
timeout = 1;
}
switcher->curl.SetOpt(CURLOPT_TIMEOUT, 1);
switcher->curl.Perform();
return readBuffer;
}
@@ -197,8 +200,12 @@ bool matchFileContent(QString &filedata, FileSwitch &s)
}
if (s.useRegex) {
QRegExp rx(QString::fromStdString(s.text));
return rx.exactMatch(filedata);
try {
std::regex expr(s.text);
return std::regex_match(filedata.toStdString(), expr);
} catch (const std::regex_error &) {
return false;
}
}
QString text = QString::fromStdString(s.text);
@@ -412,7 +419,7 @@ void AdvSceneSwitcher::setupFileTab()
obs_module_text("AdvSceneSwitcher.fileTab.remoteFileWarning2"));
ui->remoteFileWarningLabel->hide();
if (switcher->curl) {
if (switcher->curl.Initialized()) {
ui->libcurlWarning->setVisible(false);
}

View File

@@ -1,5 +1,5 @@
#include "headers/advanced-scene-switcher.hpp"
#include "headers/utility.hpp"
#include "advanced-scene-switcher.hpp"
#include "utility.hpp"
static inline bool SceneGroupValid(SceneGroup *group)
{

View File

@@ -1,7 +1,7 @@
#include <regex>
#include "headers/advanced-scene-switcher.hpp"
#include "headers/utility.hpp"
#include "advanced-scene-switcher.hpp"
#include "utility.hpp"
bool IdleData::pause = false;
IdleWidget *idleWidget = nullptr;

Some files were not shown because too many files have changed in this diff Show More