├── source-record.h ├── .github ├── scripts │ ├── build-linux.zsh │ ├── build-macos.zsh │ ├── package-linux.zsh │ ├── package-macos.zsh │ ├── utils.zsh │ │ ├── mkcd │ │ ├── log_error │ │ ├── log_warning │ │ ├── log_debug │ │ ├── log_output │ │ ├── log_status │ │ ├── log_info │ │ ├── read_codesign │ │ ├── read_codesign_user │ │ ├── read_codesign_installer │ │ ├── setup_ccache │ │ ├── set_loglevel │ │ ├── check_macos │ │ ├── check_linux │ │ ├── read_codesign_pass │ │ ├── setup_linux │ │ ├── check_packages │ │ ├── setup_obs │ │ └── setup_macos │ ├── .Brewfile │ ├── .Wingetfile │ ├── .Aptfile │ ├── check-changes.sh │ ├── build-linux.sh │ ├── package-linux.sh │ ├── utils.pwsh │ │ ├── Check-Git.ps1 │ │ ├── Ensure-Location.ps1 │ │ ├── Invoke-External.ps1 │ │ ├── Install-BuildDependencies.ps1 │ │ ├── Expand-ArchiveExt.ps1 │ │ ├── Logger.ps1 │ │ ├── Setup-Obs.ps1 │ │ ├── Invoke-GitCheckout.ps1 │ │ └── Setup-Host.ps1 │ ├── check-cmake.sh │ ├── check-format.sh │ ├── Package-Windows.ps1 │ ├── Build-Windows.ps1 │ ├── .package.zsh │ └── .build.zsh ├── FUNDING.yml ├── actions │ ├── build-plugin │ │ └── action.yml │ └── package-plugin │ │ └── action.yml └── workflows │ └── build.yml ├── media ├── icon.ico └── logo.png ├── .gitignore ├── version.h.in ├── README.md ├── cmake ├── Bundle │ └── macos │ │ ├── entitlements.plist │ │ ├── Plugin-Info.plist.in │ │ └── installer-macos.pkgproj.in └── ObsPluginHelpers.cmake ├── data └── locale │ ├── zh-CN.ini │ ├── ja-JP.ini │ ├── en-US.ini │ ├── tr-TR.ini │ ├── pt-BR.ini │ └── de-DE.ini ├── resource.rc.in ├── CMakeLists.txt ├── installer.iss.in ├── LICENSE └── CI └── macos └── source-record.pkgproj /source-record.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/scripts/build-linux.zsh: -------------------------------------------------------------------------------- 1 | .build.zsh -------------------------------------------------------------------------------- /.github/scripts/build-macos.zsh: -------------------------------------------------------------------------------- 1 | .build.zsh -------------------------------------------------------------------------------- /.github/scripts/package-linux.zsh: -------------------------------------------------------------------------------- 1 | .package.zsh -------------------------------------------------------------------------------- /.github/scripts/package-macos.zsh: -------------------------------------------------------------------------------- 1 | .package.zsh -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: exeldro 2 | custom: "https://www.paypal.me/exeldro" -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/mkcd: -------------------------------------------------------------------------------- 1 | [[ -n ${1} ]] && mkdir -p ${1} && builtin cd ${1} 2 | -------------------------------------------------------------------------------- /media/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ujifgc/obs-source-record/master/media/icon.ico -------------------------------------------------------------------------------- /media/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ujifgc/obs-source-record/master/media/logo.png -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/log_error: -------------------------------------------------------------------------------- 1 | local icon=' ✖︎ ' 2 | 3 | print -u2 -PR "%F{1} ${icon} %f ${@}" 4 | -------------------------------------------------------------------------------- /.github/scripts/.Brewfile: -------------------------------------------------------------------------------- 1 | brew "ccache" 2 | brew "coreutils" 3 | brew "cmake" 4 | brew "git" 5 | brew "jq" 6 | brew "ninja" 7 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/log_warning: -------------------------------------------------------------------------------- 1 | if (( _loglevel > 0 )) { 2 | local icon=' =>' 3 | 4 | print -PR "%F{3} ${(r:5:)icon} ${@}%f" 5 | } 6 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/log_debug: -------------------------------------------------------------------------------- 1 | if (( ! ${+_loglevel} )) typeset -g _loglevel=1 2 | 3 | if (( _loglevel > 2 )) print -PR -e -- "%F{220}DEBUG: ${@}%f" 4 | -------------------------------------------------------------------------------- /.github/scripts/.Wingetfile: -------------------------------------------------------------------------------- 1 | package '7zip.7zip', path: '7-zip', bin: '7z' 2 | package 'cmake', path: 'Cmake\bin', bin: 'cmake' 3 | package 'innosetup', path: 'Inno Setup 6', bin: 'iscc' 4 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/log_output: -------------------------------------------------------------------------------- 1 | if (( ! ${+_loglevel} )) typeset -g _loglevel=1 2 | 3 | if (( _loglevel > 0 )) { 4 | local icon='' 5 | 6 | print -PR " ${(r:5:)icon} ${@}" 7 | } 8 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/log_status: -------------------------------------------------------------------------------- 1 | if (( ! ${+_loglevel} )) typeset -g _loglevel=1 2 | 3 | if (( _loglevel > 0 )) { 4 | local icon=' >' 5 | 6 | print -PR "%F{2} ${(r:5:)icon}%f ${@}" 7 | } 8 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/log_info: -------------------------------------------------------------------------------- 1 | if (( ! ${+_loglevel} )) typeset -g _loglevel=1 2 | 3 | if (( _loglevel > 0 )) { 4 | local icon=' =>' 5 | 6 | print -PR "%F{4} ${(r:5:)icon}%f %B${@}%b" 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | /build/ 4 | /build_*/ 5 | /release/ 6 | /installer/Output/ 7 | 8 | .vscode 9 | .idea 10 | 11 | # ignore generated files 12 | *.generated.* 13 | **/.Brewfile.lock.json 14 | -------------------------------------------------------------------------------- /.github/scripts/.Aptfile: -------------------------------------------------------------------------------- 1 | package 'cmake' 2 | package 'ccache' 3 | package 'curl' 4 | package 'git' 5 | package 'jq' 6 | package 'ninja-build', bin: 'ninja' 7 | package 'pkg-config' 8 | package 'clang' 9 | package 'clang-format-13' 10 | -------------------------------------------------------------------------------- /version.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define PROJECT_VERSION "${PROJECT_VERSION}" 4 | #define PROJECT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} 5 | #define PROJECT_VERSION_MINOR ${PROJECT_VERSION_MINOR} 6 | #define PROJECT_VERSION_PATCH ${PROJECT_VERSION_PATCH} -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/read_codesign: -------------------------------------------------------------------------------- 1 | autoload -Uz log_info 2 | 3 | if (( ! ${+CODESIGN_IDENT} )) { 4 | typeset -g CODESIGN_IDENT 5 | log_info 'Setting up identity for application codesigning...' 6 | read CODESIGN_IDENT'?Apple Developer Application ID: ' 7 | } 8 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/read_codesign_user: -------------------------------------------------------------------------------- 1 | autoload -Uz log_info 2 | 3 | if (( ! ${+CODESIGN_IDENT_USER} )) { 4 | typeset -g CODESIGN_IDENT_USER 5 | log_info 'Setting up developer id for codesigning...' 6 | read CODESIGN_IDENT_USER'?Apple Developer ID: ' 7 | } 8 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/read_codesign_installer: -------------------------------------------------------------------------------- 1 | autoload -Uz log_info 2 | 3 | if (( ! ${+CODESIGN_IDENT_INSTALLER} )) { 4 | typeset -g CODESIGN_IDENT_INSTALLER 5 | log_info 'Setting up identity for installer package codesigning...' 6 | read CODESIGN_IDENT_INSTALLER'?Apple Developer Installer ID: ' 7 | } 8 | -------------------------------------------------------------------------------- /.github/scripts/check-changes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | dirty=$(git ls-files --modified) 3 | 4 | set +x 5 | if [[ $dirty ]]; then 6 | echo "=================================" 7 | echo "Files were not formatted properly" 8 | echo "$dirty" 9 | echo "=================================" 10 | exit 1 11 | fi -------------------------------------------------------------------------------- /.github/scripts/build-linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if ! type zsh > /dev/null 2>&1; then 4 | echo ' => Installing script dependency Zsh.' 5 | 6 | sudo apt-get -y update 7 | sudo apt-get -y install zsh 8 | fi 9 | 10 | SCRIPT=$(readlink -f "${0}") 11 | SCRIPT_DIR=$(dirname "${SCRIPT}") 12 | 13 | zsh ${SCRIPT_DIR}/build-linux.zsh "${@}" 14 | -------------------------------------------------------------------------------- /.github/scripts/package-linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if ! type zsh > /dev/null 2>&1; then 4 | echo ' => Installing script dependency Zsh.' 5 | 6 | sudo apt-get update 7 | sudo apt-get install zsh 8 | fi 9 | 10 | SCRIPT=$(readlink -f "${0}") 11 | SCRIPT_DIR=$(dirname "${SCRIPT}") 12 | 13 | zsh ${SCRIPT_DIR}/package-linux.zsh "${@}" 14 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/setup_ccache: -------------------------------------------------------------------------------- 1 | autoload -Uz log_debug log_warning 2 | 3 | if (( ${+commands[ccache]} )) { 4 | log_debug "Found ccache at ${commands[ccache]}" 5 | 6 | if (( ${+CI} )) { 7 | ccache --set-config=cache_dir="${GITHUB_WORKSPACE:-${HOME}}/.ccache" 8 | ccache --set-config=max_size="${CCACHE_SIZE:-500M}" 9 | ccache --set-config=compression=true 10 | ccache -z > /dev/null 11 | } 12 | } else { 13 | log_warning "No ccache found on the system" 14 | } 15 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/set_loglevel: -------------------------------------------------------------------------------- 1 | autoload -Uz log_debug log_error 2 | 3 | local -r _usage="Usage: %B${0}%b 4 | 5 | Set log level, following levels are supported: 0 (quiet), 1 (normal), 2 (verbose), 3 (debug)" 6 | 7 | if (( ! # )); then 8 | log_error 'Called without arguments.' 9 | log_output ${_usage} 10 | return 2 11 | elif (( ${1} >= 4 )); then 12 | log_error 'Called with loglevel > 3.' 13 | log_output ${_usage} 14 | fi 15 | 16 | typeset -g -i -r _loglevel=${1} 17 | log_debug "Log level set to '${1}'" 18 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/check_macos: -------------------------------------------------------------------------------- 1 | autoload -Uz is-at-least log_info log_error log_status read_codesign 2 | 3 | local macos_version=$(sw_vers -productVersion) 4 | 5 | log_info 'Checking macOS version...' 6 | if ! is-at-least 11.0 "${macos_version}"; then 7 | log_error "Minimum required macOS version is 11.0, but running on macOS ${macos_version}" 8 | return 2 9 | else 10 | log_status "macOS ${macos_version} is recent" 11 | fi 12 | 13 | log_info 'Checking for Homebrew...' 14 | if (( ! ${+commands[brew]} )) { 15 | log_error 'No Homebrew command found. Please install Homebrew (https://brew.sh)' 16 | return 2 17 | } 18 | 19 | brew bundle --file "${SCRIPT_HOME}/.Brewfile" 20 | rehash 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Source Record filter for OBS Studio 2 | 3 | Plugin for OBS Studio to make sources available to record via a filter 4 | 5 | # Download 6 | 7 | https://obsproject.com/forum/resources/source-record.1285/ 8 | 9 | # Build 10 | 1. In-tree build 11 | - Build OBS Studio: https://obsproject.com/wiki/Install-Instructions 12 | - Check out this repository to plugins/source-record 13 | - Add `add_subdirectory(source-record)` to plugins/CMakeLists.txt 14 | - Rebuild OBS Studio 15 | 16 | 1. Stand-alone build (Linux only) 17 | - Verify that you have package with development files for OBS 18 | - Check out this repository and run `cmake -S . -B build -DBUILD_OUT_OF_TREE=On && cmake --build build` 19 | 20 | # Donations 21 | https://www.paypal.me/exeldro 22 | -------------------------------------------------------------------------------- /cmake/Bundle/macos/entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.device.camera 8 | 9 | com.apple.security.device.audio-input 10 | 11 | com.apple.security.cs.disable-library-validation 12 | 13 | 14 | com.apple.security.cs.allow-dyld-environment-variables 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.github/scripts/utils.pwsh/Check-Git.ps1: -------------------------------------------------------------------------------- 1 | function Check-Git { 2 | <# 3 | .SYNOPSIS 4 | Ensures available git executable on host system. 5 | .DESCRIPTION 6 | Checks whether a git command is available on the host system. If none is found, 7 | Git is installed via winget. 8 | .EXAMPLE 9 | Check-Git 10 | #> 11 | 12 | if ( ! ( Test-Path function:Log-Info ) ) { 13 | . $PSScriptRoot/Logger.ps1 14 | } 15 | 16 | Log-Information 'Checking for Git executable...' 17 | 18 | if ( ! ( Get-Command git ) ) { 19 | Log-Warning 'No Git executable found. Will try to install via winget.' 20 | winget install git 21 | } else { 22 | Log-Debug "Git found at $(Get-Command git)." 23 | Log-Status "Git found." 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.github/scripts/utils.pwsh/Ensure-Location.ps1: -------------------------------------------------------------------------------- 1 | function Ensure-Location { 2 | <# 3 | .SYNOPSIS 4 | Ensures current location to be set to specified directory. 5 | .DESCRIPTION 6 | If specified directory exists, switch to it. Otherwise create it, 7 | then switch. 8 | .EXAMPLE 9 | Ensure-Location "My-Directory" 10 | Ensure-Location -Path "Path-To-My-Directory" 11 | #> 12 | 13 | param( 14 | [Parameter(Mandatory)] 15 | [string] $Path 16 | ) 17 | 18 | if ( ! ( Test-Path $Path ) ) { 19 | $_Params = @{ 20 | ItemType = "Directory" 21 | Path = ${Path} 22 | ErrorAction = "SilentlyContinue" 23 | } 24 | 25 | New-Item @_Params | Set-Location 26 | } else { 27 | Set-Location -Path ${Path} 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /data/locale/zh-CN.ini: -------------------------------------------------------------------------------- 1 | SourceRecord="源录像" 2 | Record="录像" 3 | Stream="直播" 4 | RecordMode="录像模式:" 5 | StreamMode="直播模式:" 6 | None="无" 7 | Always="总是" 8 | Streaming="直播" 9 | Recording="录像" 10 | StreamingOrRecording="直播或者录制" 11 | VirtualCamera="虚拟摄像机" 12 | Server="服务器" 13 | Key="密匙" 14 | ReplayBuffer="重新播送缓冲器" 15 | Duration="区间" 16 | SaveReplay="保存重播" 17 | Path="储存路径" 18 | FilenameFormatting="文件命名格式" 19 | RecFormat="文件储存格式" 20 | Encoder="编码器" 21 | Software="软件(x264)" 22 | QSV.H264="硬件(QSV,H.264)" 23 | QSV.AV1="硬件(QSV,AV1)" 24 | AMD.H264="硬件(AMD,H.264)" 25 | AMD.HEVC="硬件(AMD,HEVC)" 26 | AMD.AV1="硬件(AMD,AV1)" 27 | NVENC.H264="硬件(NVENC,H.264)" 28 | NVENC.AV1="硬件 (NVENC, AV1)" 29 | NVENC.HEVC="硬件 (NVENC,HEVC)" 30 | Apple.H264="硬件(苹果,H.264)" 31 | Apple.HEVC="硬件(苹果,HEVC)" 32 | DifferentAudio="不同的音频" 33 | Source="源" 34 | SourceRecordEnable="原记录启用" 35 | SourceRecordDisable="原纪录关闭" 36 | AudioTrack="音轨" 37 | Track="轨道" 38 | -------------------------------------------------------------------------------- /cmake/Bundle/macos/Plugin-Info.plist.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleName 6 | ${MACOSX_PLUGIN_BUNDLE_NAME} 7 | CFBundleIdentifier 8 | ${MACOSX_PLUGIN_GUI_IDENTIFIER} 9 | CFBundleVersion 10 | ${MACOSX_PLUGIN_BUNDLE_VERSION} 11 | CFBundleShortVersionString 12 | ${MACOSX_PLUGIN_SHORT_VERSION_STRING} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleExecutable 16 | ${MACOSX_PLUGIN_EXECUTABLE_NAME} 17 | CFBundlePackageType 18 | ${MACOSX_PLUGIN_BUNDLE_TYPE} 19 | CFBundleSupportedPlatforms 20 | 21 | MacOSX 22 | 23 | LSMinimumSystemVersion 24 | 10.13 25 | 26 | 27 | -------------------------------------------------------------------------------- /data/locale/ja-JP.ini: -------------------------------------------------------------------------------- 1 | SourceRecord="Source Record" 2 | Record="録画" 3 | Stream="配信" 4 | RecordMode="録画モード" 5 | StreamMode="配信モード" 6 | None="なし" 7 | Always="常に" 8 | Streaming="配信時" 9 | Recording="録画時" 10 | StreamingOrRecording="配信時か録画時" 11 | VirtualCamera="仮想カメラ" 12 | Server="サーバー" 13 | Key="キー" 14 | ReplayBuffer="リプレイバッファ" 15 | Duration="リプレイ時間" 16 | SaveReplay="リプレイを保存" 17 | Path="パス" 18 | FilenameFormatting="ファイル名書式設定" 19 | RecFormat="録画フォーマット" 20 | Encoder="エンコーダー" 21 | Software="ソフトウェア (x264)" 22 | QSV.H264="ハードウェア (QSV, H.264)" 23 | QSV.AV1="ハードウェア (QSV, AV1)" 24 | AMD.H264="ハードウェア (AMD, H.264)" 25 | AMD.HEVC="ハードウェア (AMD, HEVC)" 26 | AMD.AV1="ハードウェア (AMD, AV1)" 27 | NVENC.H264="ハードウェア (NVENC, H.264)" 28 | NVENC.AV1="ハードウェア (NVENC, AV1)" 29 | NVENC.HEVC="ハードウェア (NVENC, HEVC)" 30 | Apple.H264="ハードウェア (Apple, H.264)" 31 | Apple.HEVC="ハードウェア (Apple, HEVC)" 32 | DifferentAudio="別の音声" 33 | Source="ソース" 34 | SourceRecordEnable="Source Record 有効化" 35 | SourceRecordDisable="Source Record 無効化" 36 | AudioTrack="音声トラック" 37 | Track="トラック" 38 | Background="背景" 39 | BackgroundColor="背景色" 40 | -------------------------------------------------------------------------------- /resource.rc.in: -------------------------------------------------------------------------------- 1 | 1 VERSIONINFO 2 | FILEVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},0 3 | PRODUCTVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},0 4 | FILEFLAGSMASK 0x0L 5 | #ifdef _DEBUG 6 | FILEFLAGS 0x1L 7 | #else 8 | FILEFLAGS 0x0L 9 | #endif 10 | FILEOS 0x0L 11 | FILETYPE 0x2L 12 | FILESUBTYPE 0x0L 13 | BEGIN 14 | BLOCK "StringFileInfo" 15 | BEGIN 16 | BLOCK "040904b0" 17 | BEGIN 18 | VALUE "CompanyName", "Exeldro" 19 | VALUE "FileDescription", "${PROJECT_FULL_NAME}" 20 | VALUE "FileVersion", "${PROJECT_VERSION}" 21 | VALUE "InternalName", "${PROJECT_NAME}" 22 | VALUE "LegalCopyright", "(C) Exeldro" 23 | VALUE "OriginalFilename", "${PROJECT_NAME}" 24 | VALUE "ProductName", "${PROJECT_FULL_NAME}" 25 | VALUE "ProductVersion", "${PROJECT_VERSION}" 26 | END 27 | END 28 | BLOCK "VarFileInfo" 29 | BEGIN 30 | VALUE "Translation", 0x409, 1200 31 | END 32 | END 33 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/check_linux: -------------------------------------------------------------------------------- 1 | autoload -Uz log_info log_status log_error log_debug log_warning 2 | 3 | log_debug 'Checking for apt-get...' 4 | if (( ! ${+commands[apt-get]} )) { 5 | log_error 'No apt-get command found. Please install apt' 6 | return 2 7 | } else { 8 | log_debug "Apt-get located at ${commands[apt-get]}" 9 | } 10 | 11 | local -a dependencies=("${(f)$(<${SCRIPT_HOME}/.Aptfile)}") 12 | local -a install_list 13 | local binary 14 | 15 | for dependency (${dependencies}) { 16 | local -a tokens=(${(s: :)dependency//(,|:|\')/}) 17 | 18 | if [[ ! ${tokens[1]} == 'package' ]] continue 19 | 20 | if [[ ${#tokens} -gt 2 && ${tokens[3]} == 'bin' ]] { 21 | binary=${tokens[4]} 22 | } else { 23 | binary=${tokens[2]} 24 | } 25 | 26 | if (( ! ${+commands[${binary}]} )) install_list+=(${tokens[2]}) 27 | } 28 | 29 | local -a _quiet=('' '--quiet') 30 | 31 | log_debug "List of dependencies to install: ${install_list}" 32 | if (( ${#install_list} )) { 33 | if (( ! ${+CI} )) log_warning 'Dependency installation via apt may require elevated privileges' 34 | 35 | sudo apt-get -y install ${install_list} ${_quiet[(( (_loglevel == 0) + 1 ))]} 36 | } 37 | -------------------------------------------------------------------------------- /.github/scripts/utils.pwsh/Invoke-External.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-External { 2 | <# 3 | .SYNOPSIS 4 | Invokes a non-PowerShell command. 5 | .DESCRIPTION 6 | Runs a non-PowerShell command, and captures its return code. 7 | Throws an exception if the command returns non-zero. 8 | .EXAMPLE 9 | Invoke-External 7z x $MyArchive 10 | #> 11 | 12 | if ( $args.Count -eq 0 ) { 13 | throw 'Invoke-External called without arguments.' 14 | } 15 | 16 | if ( ! ( Test-Path function:Log-Information ) ) { 17 | . $PSScriptRoot/Logger.ps1 18 | } 19 | 20 | $Command = $args[0] 21 | $CommandArgs = @() 22 | 23 | if ( $args.Count -gt 1) { 24 | $CommandArgs = $args[1..($args.Count - 1)] 25 | } 26 | 27 | $_EAP = $ErrorActionPreference 28 | $ErrorActionPreference = "Continue" 29 | 30 | Log-Debug "Invoke-External: ${Command} ${CommandArgs}" 31 | 32 | & $command $commandArgs 33 | $Result = $LASTEXITCODE 34 | 35 | $ErrorActionPreference = $_EAP 36 | 37 | if ( $Result -ne 0 ) { 38 | throw "${Command} ${CommandArgs} exited with non-zero code ${Result}." 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /data/locale/en-US.ini: -------------------------------------------------------------------------------- 1 | SourceRecord="Source Record" 2 | Record="Record" 3 | Stream="Stream" 4 | RecordMode="Record Mode" 5 | StreamMode="Stream Mode" 6 | None="None" 7 | Always="Always" 8 | Streaming="Streaming" 9 | Recording="Recording" 10 | StreamingOrRecording="Streaming or Recording" 11 | VirtualCamera="Virtual Camera" 12 | Server="Server" 13 | Key="Key" 14 | ReplayBuffer="Replay Buffer" 15 | Duration="Duration" 16 | SaveReplay="Save Replay" 17 | Path="Path" 18 | FilenameFormatting="Filename Formatting" 19 | RecFormat="Rec Format" 20 | Encoder="Encoder" 21 | Software="Software (x264)" 22 | QSV.H264="Hardware (QSV, H.264)" 23 | QSV.AV1="Hardware (QSV, AV1)" 24 | AMD.H264="Hardware (AMD, H.264)" 25 | AMD.HEVC="Hardware (AMD, HEVC)" 26 | AMD.AV1="Hardware (AMD, AV1)" 27 | NVENC.H264="Hardware (NVENC, H.264)" 28 | NVENC.AV1="Hardware (NVENC, AV1)" 29 | NVENC.HEVC="Hardware (NVENC, HEVC)" 30 | Apple.H264="Hardware (Apple, H.264)" 31 | Apple.HEVC="Hardware (Apple, HEVC)" 32 | DifferentAudio="Different Audio" 33 | Source="Source" 34 | SourceRecordEnable="Source Record Enable" 35 | SourceRecordDisable="Source Record Disable" 36 | AudioTrack="Audio Track" 37 | Track="Track" 38 | Background="Background" 39 | BackgroundColor="Background Color" 40 | -------------------------------------------------------------------------------- /data/locale/tr-TR.ini: -------------------------------------------------------------------------------- 1 | SourceRecord="Kaynak Kaydı" 2 | Record="Kayıt" 3 | Stream="Akış" 4 | RecordMode="Kayıt Modu" 5 | StreamMode="Yayın Modu" 6 | None="Hiçbiri" 7 | Always="Her zaman" 8 | Streaming="Canlı Yayın" 9 | Recording="Kayıt" 10 | StreamingOrRecording="Canlı Yayın veya Kayıt" 11 | VirtualCamera="Sanal Kamera" 12 | Server="Sunucu" 13 | Key="Anahtar" 14 | ReplayBuffer="Replay Buffer" 15 | Duration="Süre" 16 | SaveReplay="Tekrar Oynatmayı Kaydet" 17 | Path="Yol" 18 | FilenameFormatting="Dosya Adı Biçimlendir" 19 | RecFormat="Kayıt Biçimi" 20 | Encoder="Kodlayıcı" 21 | Software="Yazılım (x264)" 22 | QSV.H264="Donanım (QSV, H.264)" 23 | QSV.AV1="Donanım (QSV, AV1)" 24 | AMD.H264="Donanım (AMD, H.264)" 25 | AMD.HEVC="Donanım (AMD, HEVC)" 26 | AMD.AV1="Donanım (AMD, AV1)" 27 | NVENC.H264="Donanım (NVENC, H.264)" 28 | NVENC.AV1="Donanım (NVENC, AV1)" 29 | NVENC.HEVC="Donanım (NVENC, HEVC)" 30 | Apple.H264="Donanım (Apple, H.264)" 31 | Apple.HEVC="Donanım (Apple, HEVC)" 32 | DifferentAudio="Farklı Ses" 33 | Source="Kaynak" 34 | SourceRecordEnable="Kaynak Kaydını Etkinleştir" 35 | SourceRecordDisable="Kaynak Kaydını Devre Dışı Bırak" 36 | AudioTrack="Ses İzleği" 37 | Track="İzleği" 38 | Background="Arka Plan" 39 | BackgroundColor="Arka Plan Rengi" -------------------------------------------------------------------------------- /data/locale/pt-BR.ini: -------------------------------------------------------------------------------- 1 | SourceRecord="Gravar Fonte" 2 | Record="Gravação" 3 | Stream="Stream" 4 | RecordMode="Modo de Gravação" 5 | StreamMode="Modo de Stream" 6 | None="Nenhum" 7 | Always="Sempre" 8 | Streaming="Streaming" 9 | Recording="Gravação" 10 | StreamingOrRecording="Streaming ou Gravação" 11 | VirtualCamera="Câmera Virtual" 12 | Server="Servidor" 13 | Key="Chave" 14 | ReplayBuffer="Repetir Buffer" 15 | Duration="Duração" 16 | SaveReplay="Salvar Replay" 17 | Path="Caminho" 18 | FilenameFormatting="Padrão do Arquivo" 19 | RecFormat ="Formato" 20 | Encoder="Codificação" 21 | Software="Software (x264)" 22 | QSV.H264="Hardware (QSV, H.264)" 23 | QSV.AV1="Hardware (QSV, AV1)" 24 | AMD.H264="Hardware (AMD, H.264)" 25 | AMD.HEVC="Hardware (AMD, HEVC)" 26 | AMD.AV1="Hardware (AMD, AV1)" 27 | NVENC.H264="Hardware (NVENC, H.264)" 28 | NVENC.AV1="Hardware (NVENC, AV1)" 29 | NVENC.HEVC="Hardware (NVENC, HEVC)" 30 | Apple.H264="Hardware (Apple, H.264)" 31 | Apple.HEVC="Hardware (Apple, HEVC)" 32 | DifferentAudio="Áudio Distinto" 33 | Source="Fonte" 34 | SourceRecordEnable="Habilitar Gravação de Fonte" 35 | SourceRecordDisable="Desabilitar Gravação de Fonte" 36 | AudioTrack="Trilha de Áudio" 37 | Track="Trilha" 38 | Background="Fundo" 39 | BackgroundColor="Cor de Fundo" 40 | -------------------------------------------------------------------------------- /data/locale/de-DE.ini: -------------------------------------------------------------------------------- 1 | SourceRecord="Source Record" 2 | Record="Aufnahme" 3 | Stream="Stream" 4 | RecordMode="Aufnahme Modus" 5 | StreamMode="Stream Modus" 6 | None="Keine" 7 | Always="Immer" 8 | Streaming="Streaming" 9 | Recording="Aufnahme" 10 | StreamingOrRecording="Streaming oder Aufnahme" 11 | VirtualCamera="Virtuelle Kamera" 12 | Server="Server" 13 | Key="Key" 14 | ReplayBuffer="Wiederholungs-Buffer" 15 | Duration="Dauer" 16 | SaveReplay="Speichere Wiederholung" 17 | Path="Pfad" 18 | FilenameFormatting="Dateiformatierung" 19 | RecFormat="Aufnahme Format" 20 | Encoder="Encoder" 21 | Software="Software (x264)" 22 | QSV.H264="Hardware (QSV, H.264)" 23 | QSV.AV1="Hardware (QSV, AV1)" 24 | AMD.H264="Hardware (AMD, H.264)" 25 | AMD.HEVC="Hardware (AMD, HEVC)" 26 | AMD.AV1="Hardware (AMD, AV1)" 27 | NVENC.H264="Hardware (NVENC, H.264)" 28 | NVENC.AV1="Hardware (NVENC, AV1)" 29 | NVENC.HEVC="Hardware (NVENC, HEVC)" 30 | Apple.H264="Hardware (Apple, H.264)" 31 | Apple.HEVC="Hardware (Apple, HEVC)" 32 | DifferentAudio="Unterschiedliche Audio" 33 | Source="Quelle" 34 | SourceRecordEnable="Source Record aktivieren" 35 | SourceRecordDisable="Source Record deaktivieren" 36 | AudioTrack="Audio Track" 37 | Track="Track" 38 | Background="Hintergrund" 39 | BackgroundColor="Hintergrund Farbe" 40 | -------------------------------------------------------------------------------- /.github/scripts/check-cmake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | 6 | if [ ${#} -eq 1 -a "${1}" = "VERBOSE" ]; then 7 | VERBOSITY="-l debug" 8 | else 9 | VERBOSITY="" 10 | fi 11 | 12 | if [ "${CI}" ]; then 13 | MODE="--check" 14 | else 15 | MODE="-i" 16 | fi 17 | 18 | # Runs the formatter in parallel on the code base. 19 | # Return codes: 20 | # - 1 there are files to be formatted 21 | # - 0 everything looks fine 22 | 23 | # Get CPU count 24 | OS=$(uname) 25 | NPROC=1 26 | if [[ ${OS} = "Linux" ]] ; then 27 | NPROC=$(nproc) 28 | elif [[ ${OS} = "Darwin" ]] ; then 29 | NPROC=$(sysctl -n hw.physicalcpu) 30 | fi 31 | 32 | # Discover clang-format 33 | if ! type cmake-format 2> /dev/null ; then 34 | echo "Required cmake-format not found" 35 | exit 1 36 | fi 37 | 38 | find . -type d \( \ 39 | -path ./\*build\* -o \ 40 | -path ./release -o \ 41 | -path ./deps/jansson -o \ 42 | -path ./plugins/decklink/\*/decklink-sdk -o \ 43 | -path ./plugins/enc-amf -o \ 44 | -path ./plugins/mac-syphon/syphon-framework -o \ 45 | -path ./plugins/obs-outputs/ftl-sdk -o \ 46 | -path ./plugins/obs-vst -o \ 47 | -path ./plugins/obs-browser -o \ 48 | -path ./plugins/win-dshow/libdshowcapture -o \ 49 | -path ./plugins/obs-websocket/deps \ 50 | \) -prune -false -type f -o \ 51 | -name 'CMakeLists.txt' -or \ 52 | -name '*.cmake' \ 53 | | xargs -L10 -P ${NPROC} cmake-format ${MODE} ${VERBOSITY} 54 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/read_codesign_pass: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Apple Developer credentials necessary: 3 | # 4 | # + Signing for distribution and notarization require an active Apple 5 | # Developer membership 6 | # + An Apple Development identity is needed for code signing 7 | # (i.e. 'Apple Development: YOUR APPLE ID (PROVIDER)') 8 | # + Your Apple developer ID is needed for notarization 9 | # + An app-specific password is necessary for notarization from CLI 10 | # + This password will be stored in your macOS keychain under the identifier 11 | # 'OBS-Codesign-Password'with access Apple's 'altool' only. 12 | ############################################################################## 13 | 14 | autoload -Uz read_codesign read_codesign_user log_info 15 | 16 | if (( ! ${+CODESIGN_IDENT} )) { 17 | read_codesign 18 | } 19 | 20 | local codesign_ident_short=$(print "${CODESIGN_IDENT}" | /usr/bin/sed -En 's/.+\((.+)\)/\1/p') 21 | 22 | if (( ! ${+CODESIGN_IDENT_USER} )) { 23 | read_codesign_user 24 | } 25 | 26 | log_info 'Setting up password for notarization keychain...' 27 | if (( ! ${+CODESIGN_IDENT_PASS} )) { 28 | read -s CODESIGN_IDENT_PASS'?Apple Developer ID password: ' 29 | } 30 | 31 | print '' 32 | log_info 'Setting up notarization keychain...' 33 | xcrun notarytool store-credentials 'OBS-Codesign-Password' --apple-id "${CODESIGN_IDENT_USER}" --team-id "${codesign_ident_short}" --password "${CODESIGN_IDENT_PASS}" 34 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/setup_linux: -------------------------------------------------------------------------------- 1 | autoload -Uz log_error log_status log_info mkcd 2 | 3 | if (( ! ${+project_root} )) { 4 | log_error "'project_root' not set. Please set before running ${0}." 5 | return 2 6 | } 7 | 8 | if (( ! ${+target} )) { 9 | log_error "'target' not set. Please set before running ${0}." 10 | return 2 11 | } 12 | 13 | pushd ${project_root} 14 | 15 | typeset -g QT_VERSION 16 | read -r QT_VERSION <<< \ 17 | "$(jq -r --arg target "${target}" \ 18 | '.platformConfig[$target] | { qtVersion } | join(" ")' \ 19 | ${project_root}/buildspec.json)" 20 | 21 | if (( ! (${skips[(Ie)all]} + ${skips[(Ie)deps]}) )) { 22 | log_info 'Installing obs build dependencies...' 23 | 24 | sudo apt-get install -y \ 25 | build-essential \ 26 | libcurl4-openssl-dev \ 27 | libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev \ 28 | libswresample-dev libswscale-dev \ 29 | libjansson-dev \ 30 | libx11-xcb-dev \ 31 | libgles2-mesa-dev \ 32 | libwayland-dev \ 33 | libpulse-dev 34 | 35 | local -a _qt_packages=() 36 | 37 | if (( QT_VERSION == 5 )) { 38 | _qt_packages+=( 39 | qtbase5-dev 40 | libqt5svg5-dev 41 | qtbase5-private-dev 42 | libqt5x11extras5-dev 43 | ) 44 | } elif (( QT_VERSION == 6 )) { 45 | _qt_packages+=( 46 | qt6-base-dev 47 | libqt6svg6-dev 48 | qt6-base-private-dev 49 | ) 50 | } else { 51 | log_error "Unsupported Qt version '${QT_VERSION}' specified." 52 | return 2 53 | } 54 | 55 | sudo apt-get install -y ${_qt_packages} 56 | } 57 | 58 | local deps_version 59 | read -r deps_version <<< \ 60 | "$(jq -r '.dependencies.prebuilt.version' ${buildspec_file})" 61 | 62 | typeset -g OBS_DEPS_VERSION=${deps_version} 63 | -------------------------------------------------------------------------------- /.github/scripts/utils.zsh/check_packages: -------------------------------------------------------------------------------- 1 | if (( ! ${+commands[packagesbuild]} )) { 2 | autoload -Uz log_info log_status mkcd 3 | 4 | if (( ! ${+commands[curl]} )) { 5 | log_error 'curl not found. Please install curl.' 6 | return 2 7 | } 8 | 9 | if (( ! ${+project_root} )) { 10 | log_error "'project_root' not set. Please set before running ${0}." 11 | return 2 12 | } 13 | 14 | local -a curl_opts=() 15 | if (( ! ${+CI} )) { 16 | curl_opts+=(--progress-bar) 17 | } else { 18 | curl_opts+=(--show-error --silent) 19 | } 20 | curl_opts+=(--location -O ${@}) 21 | 22 | log_info 'Installing Packages.app...' 23 | 24 | pushd 25 | mkcd ${project_root:h}/obs-build-dependencies 26 | 27 | local packages_url='http://s.sudre.free.fr/Software/files/Packages.dmg' 28 | local packages_hash='6afdd25386295974dad8f078b8f1e41cabebd08e72d970bf92f707c7e48b16c9' 29 | 30 | if [[ ! -f Packages.dmg ]] { 31 | log_status 'Download Packages.app' 32 | curl ${curl_opts} ${packages_url} 33 | } 34 | 35 | local image_checksum 36 | read -r image_checksum _ <<< "$(sha256sum Packages.dmg)" 37 | 38 | if [[ ${packages_hash} != ${image_checksum} ]] { 39 | log_error "Checksum mismatch of Packages.app download. 40 | Expected : ${packages_hash} 41 | Actual : ${image_checksum}" 42 | return 2 43 | } 44 | 45 | hdiutil attach -noverify Packages.dmg &> /dev/null && log_status 'Packages.dmg image mounted.' 46 | 47 | log_info 'Installing Packages.app...' 48 | packages_volume=$(hdiutil info -plist | grep '/Volumes/Packages' | sed 's/.*\(\/Volumes\/[^<]*\)<\/string>/\1/') 49 | 50 | sudo installer -pkg "${packages_volume}/packages/Packages.pkg" -target / && rehash 51 | hdiutil detach ${packages_volume} &> /dev/null && log_status 'Packages.dmg image unmounted.' 52 | } 53 | -------------------------------------------------------------------------------- /.github/scripts/check-format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Original source https://github.com/Project-OSRM/osrm-backend/blob/master/scripts/format.sh 3 | 4 | set -o errexit 5 | set -o pipefail 6 | set -o nounset 7 | 8 | if [ ${#} -eq 1 ]; then 9 | VERBOSITY="--verbose" 10 | else 11 | VERBOSITY="" 12 | fi 13 | 14 | # Runs the Clang Formatter in parallel on the code base. 15 | # Return codes: 16 | # - 1 there are files to be formatted 17 | # - 0 everything looks fine 18 | 19 | # Get CPU count 20 | OS=$(uname) 21 | NPROC=1 22 | if [[ ${OS} = "Linux" ]] ; then 23 | NPROC=$(nproc) 24 | elif [[ ${OS} = "Darwin" ]] ; then 25 | NPROC=$(sysctl -n hw.physicalcpu) 26 | fi 27 | 28 | # Discover clang-format 29 | if type clang-format-13 2> /dev/null ; then 30 | CLANG_FORMAT=clang-format-13 31 | elif type clang-format 2> /dev/null ; then 32 | # Clang format found, but need to check version 33 | CLANG_FORMAT=clang-format 34 | V=$(clang-format --version) 35 | if [[ $V != *"version 13.0"* ]]; then 36 | echo "clang-format is not 13.0 (returned ${V})" 37 | exit 1 38 | fi 39 | else 40 | echo "No appropriate clang-format found (expected clang-format-13.0.0, or clang-format)" 41 | exit 1 42 | fi 43 | 44 | find . -type d \( \ 45 | -path ./\*build\* -o \ 46 | -path ./release -o \ 47 | -path ./cmake -o \ 48 | -path ./plugins/decklink/\*/decklink-sdk -o \ 49 | -path ./plugins/enc-amf -o \ 50 | -path ./plugins/mac-syphon/syphon-framework -o \ 51 | -path ./plugins/obs-outputs/ftl-sdk -o \ 52 | -path ./plugins/obs-websocket/deps \ 53 | \) -prune -false -type f -o \ 54 | -name '*.h' -or \ 55 | -name '*.hpp' -or \ 56 | -name '*.m' -or \ 57 | -name '*.mm' -or \ 58 | -name '*.c' -or \ 59 | -name '*.cpp' \ 60 | | xargs -L100 -P ${NPROC} "${CLANG_FORMAT}" ${VERBOSITY} -i -style=file -fallback-style=none 61 | -------------------------------------------------------------------------------- /.github/scripts/utils.pwsh/Install-BuildDependencies.ps1: -------------------------------------------------------------------------------- 1 | function Install-BuildDependencies { 2 | <# 3 | .SYNOPSIS 4 | Installs required build dependencies. 5 | .DESCRIPTION 6 | Additional packages might be needed for successful builds. This module contains additional 7 | dependencies available for installation via winget and, if possible, adds their locations 8 | to the environment path for future invocation. 9 | .EXAMPLE 10 | Install-BuildDependencies 11 | #> 12 | 13 | param( 14 | [string] $WingetFile = "$PSScriptRoot/.Wingetfile" 15 | ) 16 | 17 | if ( ! ( Test-Path function:Log-Warning ) ) { 18 | . $PSScriptRoot/Logger.ps1 19 | } 20 | 21 | $Host64Bit = [System.Environment]::Is64BitOperatingSystem 22 | 23 | $Paths = $Env:Path -split [System.IO.Path]::PathSeparator 24 | 25 | $WingetOptions = @('install', '--accept-package-agreements', '--accept-source-agreements') 26 | 27 | if ( $script:Quiet ) { 28 | $WingetOptions += '--silent' 29 | } 30 | 31 | Get-Content $WingetFile | ForEach-Object { 32 | $_, $Package, $_, $Path, $_, $Binary = ([regex]::Split($_, " (?=(?:[^']|'[^']*')*$)")) -replace ',', '' -replace "'",'' 33 | 34 | (${Env:ProgramFiles(x86)}, $Env:ProgramFiles) | ForEach-Object { 35 | $Prefix = $_ 36 | $FullPath = "${Prefix}\${Path}" 37 | if ( ( Test-Path $FullPath ) -and ! ( $Paths -contains $FullPath ) ) { 38 | $Paths += $FullPath 39 | $Env:Path = $Paths -join [System.IO.Path]::PathSeparator 40 | } 41 | } 42 | 43 | Log-Debug "Checking for command ${Binary}" 44 | $Found = Get-Command -ErrorAction SilentlyContinue $Binary 45 | 46 | if ( $Found ) { 47 | Log-Status "Found dependency ${Binary} as $($Found.Source)" 48 | } else { 49 | Log-Status "Installing package ${Package}" 50 | 51 | try { 52 | $Params = $WingetOptions + $Package 53 | 54 | winget @Params 55 | } catch { 56 | throw "Error while installing winget package ${Package}: $_" 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.github/actions/build-plugin/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Setup and build plugin' 2 | description: 'Builds the plugin for specified architecture and build config.' 3 | inputs: 4 | target: 5 | description: 'Build target for dependencies' 6 | required: true 7 | config: 8 | description: 'Build configuration' 9 | required: false 10 | default: 'Release' 11 | codesign: 12 | description: 'Enable codesigning (macOS only)' 13 | required: false 14 | default: 'false' 15 | codesignIdent: 16 | description: 'Developer ID for application codesigning (macOS only)' 17 | required: false 18 | default: '-' 19 | visualStudio: 20 | description: 'Visual Studio version (Windows only)' 21 | required: false 22 | default: 'Visual Studio 16 2019' 23 | workingDirectory: 24 | description: 'Working directory for packaging' 25 | required: false 26 | default: ${{ github.workspace }} 27 | runs: 28 | using: 'composite' 29 | steps: 30 | - name: Run macOS Build 31 | if: ${{ runner.os == 'macOS' }} 32 | shell: zsh {0} 33 | env: 34 | CODESIGN_IDENT: ${{ inputs.codesignIdent }} 35 | run: | 36 | build_args=( 37 | -c ${{ inputs.config }} 38 | -t macos-${{ inputs.target }} 39 | ) 40 | 41 | if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(-s) 42 | if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug) 43 | 44 | ${{ inputs.workingDirectory }}/.github/scripts/build-macos.zsh ${build_args} 45 | 46 | - name: Run Linux Build 47 | if: ${{ runner.os == 'Linux' }} 48 | shell: bash 49 | run: | 50 | build_args=( 51 | -c ${{ inputs.config }} 52 | -t linux-${{ inputs.target }} 53 | ) 54 | 55 | if [[ -n "${CI}" && -n "${RUNNER_DEBUG}" ]]; then 56 | build_args+=(--debug) 57 | fi 58 | 59 | ${{ inputs.workingDirectory }}/.github/scripts/build-linux.sh "${build_args[@]}" 60 | 61 | - name: Run Windows Build 62 | if: ${{ runner.os == 'Windows' }} 63 | shell: pwsh 64 | run: | 65 | $BuildArgs = @{ 66 | Target = '${{ inputs.target }}' 67 | Configuration = '${{ inputs.config }}' 68 | CMakeGenerator = '${{ inputs.visualStudio }}' 69 | } 70 | 71 | if ( ( Test-Path env:CI ) -and ( Test-Path env:RUNNER_DEBUG ) ) { 72 | $BuildArgs += @{ 73 | Debug = $true 74 | } 75 | } 76 | 77 | ${{ inputs.workingDirectory }}/.github/scripts/Build-Windows.ps1 @BuildArgs 78 | -------------------------------------------------------------------------------- /.github/scripts/utils.pwsh/Expand-ArchiveExt.ps1: -------------------------------------------------------------------------------- 1 | function Expand-ArchiveExt { 2 | <# 3 | .SYNOPSIS 4 | Expands archive files. 5 | .DESCRIPTION 6 | Allows extraction of zip, 7z, gz, and xz archives. 7 | Requires tar and 7-zip to be available on the system. 8 | Archives ending with .zip but created using LZMA compression are 9 | expanded using 7-zip as a fallback. 10 | .EXAMPLE 11 | Expand-ArchiveExt -Path 12 | Expand-ArchiveExt -Path -DestinationPath 13 | #> 14 | 15 | param( 16 | [Parameter(Mandatory)] 17 | [string] $Path, 18 | [string] $DestinationPath = [System.IO.Path]::GetFileNameWithoutExtension($Path), 19 | [switch] $Force 20 | ) 21 | 22 | switch ( [System.IO.Path]::GetExtension($Path) ) { 23 | .zip { 24 | try { 25 | Expand-Archive -Path $Path -DestinationPath $DestinationPath -Force:$Force 26 | } catch { 27 | if ( Get-Command 7z ) { 28 | Invoke-External 7z x -y $Path "-o${DestinationPath}" 29 | } else { 30 | throw "Fallback utility 7-zip not found. Please install 7-zip first." 31 | } 32 | } 33 | break 34 | } 35 | { ( $_ -eq ".7z" ) -or ( $_ -eq ".exe" ) } { 36 | if ( Get-Command 7z ) { 37 | Invoke-External 7z x -y $Path "-o${DestinationPath}" 38 | } else { 39 | throw "Extraction utility 7-zip not found. Please install 7-zip first." 40 | } 41 | break 42 | } 43 | .gz { 44 | try { 45 | Invoke-External tar -x -o $DestinationPath -f $Path 46 | } catch { 47 | if ( Get-Command 7z ) { 48 | Invoke-External 7z x -y $Path "-o${DestinationPath}" 49 | } else { 50 | throw "Fallback utility 7-zip not found. Please install 7-zip first." 51 | } 52 | } 53 | break 54 | } 55 | .xz { 56 | try { 57 | Invoke-External tar -x -o $DestinationPath -f $Path 58 | } catch { 59 | if ( Get-Command 7z ) { 60 | Invoke-External 7z x -y $Path "-o${DestinationPath}" 61 | } else { 62 | throw "Fallback utility 7-zip not found. Please install 7-zip first." 63 | } 64 | } 65 | } 66 | default { 67 | throw "Unsupported archive extension provided." 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # --- Detect if the plugin is build out of tree or not --- 2 | if(CMAKE_PROJECT_NAME STREQUAL "obs-studio") 3 | set(BUILD_OUT_OF_TREE OFF) 4 | else() 5 | set(BUILD_OUT_OF_TREE ON) 6 | cmake_minimum_required(VERSION 3.18) 7 | endif() 8 | 9 | project(source-record VERSION 0.3.2) 10 | set(PROJECT_FULL_NAME "Source Record") 11 | 12 | # Set new UUIDs when you start to create a new plugin. 13 | set(MACOS_PACKAGE_UUID "3EC43C98-466F-4B74-8CB4-17B90EB0B29F") 14 | set(MACOS_INSTALLER_UUID "599A0945-8DDB-4E81-8A4D-C399D04BCCC5") 15 | 16 | add_library(${PROJECT_NAME} MODULE) 17 | 18 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/version.h) 19 | 20 | target_sources(${PROJECT_NAME} PRIVATE 21 | source-record.c 22 | source-record.h) 23 | 24 | 25 | if(BUILD_OUT_OF_TREE) 26 | find_package(libobs REQUIRED) 27 | find_package(obs-frontend-api REQUIRED) 28 | include(cmake/ObsPluginHelpers.cmake) 29 | set(OBS_FRONTEND_API_NAME "obs-frontend-api") 30 | else() 31 | set(OBS_FRONTEND_API_NAME "frontend-api") 32 | endif() 33 | 34 | if(OS_WINDOWS) 35 | get_filename_component(ISS_FILES_DIR "${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE) 36 | file(TO_NATIVE_PATH "${ISS_FILES_DIR}" ISS_FILES_DIR) 37 | get_filename_component(ISS_PACKAGE_DIR "${CMAKE_PACKAGE_PREFIX}\\.." ABSOLUTE) 38 | file(TO_NATIVE_PATH "${ISS_PACKAGE_DIR}" ISS_PACKAGE_DIR) 39 | get_filename_component(ISS_SOURCE_DIR "${PROJECT_SOURCE_DIR}" ABSOLUTE) 40 | file(TO_NATIVE_PATH "${ISS_SOURCE_DIR}" ISS_SOURCE_DIR) 41 | configure_file("installer.iss.in" 42 | "${PROJECT_BINARY_DIR}/installer.iss" 43 | ) 44 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resource.rc.in ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.rc) 45 | target_sources(${PROJECT_NAME} PRIVATE 46 | ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.rc) 47 | target_link_libraries(${PROJECT_NAME} 48 | w32-pthreads) 49 | elseif(OS_MACOS) 50 | set(MACOS_BUNDLEID "com.exeldro.${PROJECT_NAME}") 51 | set(MACOSX_PLUGIN_GUI_IDENTIFIER "${MACOS_BUNDLEID}") 52 | set(MACOSX_PLUGIN_BUNDLE_VERSION "${PROJECT_VERSION}") 53 | set(MACOSX_PLUGIN_SHORT_VERSION_STRING "1") 54 | configure_file(cmake/bundle/macos/installer-macos.pkgproj.in ${CMAKE_BINARY_DIR}/installer-macos.generated.pkgproj) 55 | target_compile_options(${PROJECT_NAME} PRIVATE -Wall) 56 | endif() 57 | 58 | target_link_libraries(${PROJECT_NAME} 59 | OBS::${OBS_FRONTEND_API_NAME} 60 | OBS::libobs) 61 | 62 | if(BUILD_OUT_OF_TREE) 63 | if(NOT LIB_OUT_DIR) 64 | set(LIB_OUT_DIR "/lib/obs-plugins") 65 | endif() 66 | if(NOT DATA_OUT_DIR) 67 | set(DATA_OUT_DIR "/share/obs/obs-plugins/${PROJECT_NAME}") 68 | endif() 69 | set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") 70 | install(TARGETS ${PROJECT_NAME} 71 | LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR}) 72 | install(DIRECTORY data/locale 73 | DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR}) 74 | else() 75 | target_include_directories(${PROJECT_NAME} PRIVATE 76 | "${CMAKE_SOURCE_DIR}/UI/obs-frontend-api") 77 | set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "plugins/exeldro") 78 | endif() 79 | setup_plugin_target(${PROJECT_NAME}) 80 | -------------------------------------------------------------------------------- /.github/scripts/Package-Windows.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [ValidateSet('Debug', 'RelWithDebInfo', 'Release', 'MinSizeRel')] 4 | [string] $Configuration = 'RelWithDebInfo', 5 | [ValidateSet('x86', 'x64', 'x86+x64')] 6 | [string] $Target, 7 | [switch] $BuildInstaller = $false 8 | ) 9 | 10 | $ErrorActionPreference = 'Stop' 11 | 12 | if ( $DebugPreference -eq 'Continue' ) { 13 | $VerbosePreference = 'Continue' 14 | $InformationPreference = 'Continue' 15 | } 16 | 17 | if ( $PSVersionTable.PSVersion -lt '7.0.0' ) { 18 | Write-Warning 'The obs-deps PowerShell build script requires PowerShell Core 7. Install or upgrade your PowerShell version: https://aka.ms/pscore6' 19 | exit 2 20 | } 21 | 22 | function Package { 23 | trap { 24 | Write-Error $_ 25 | exit 2 26 | } 27 | 28 | $ScriptHome = $PSScriptRoot 29 | $ProjectRoot = Resolve-Path -Path "$PSScriptRoot/../.." 30 | $BuildSpecFile = "${ProjectRoot}/buildspec.json" 31 | 32 | $UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse 33 | 34 | foreach( $Utility in $UtilityFunctions ) { 35 | Write-Debug "Loading $($Utility.FullName)" 36 | . $Utility.FullName 37 | } 38 | 39 | $BuildSpec = Get-Content -Path ${BuildSpecFile} -Raw | ConvertFrom-Json 40 | $ProductName = $BuildSpec.name 41 | $ProductVersion = $BuildSpec.version 42 | 43 | $OutputName = "${ProductName}-${ProductVersion}-windows-${Target}" 44 | 45 | Install-BuildDependencies -WingetFile "${ScriptHome}/.Wingetfile" 46 | 47 | Log-Information "Packaging ${ProductName}..." 48 | 49 | $RemoveArgs = @{ 50 | ErrorAction = 'SilentlyContinue' 51 | Path = @( 52 | "${ProjectRoot}/release/${ProductName}-*-windows-*.zip" 53 | "${ProjectRoot}/release/${ProductName}-*-windows-*.exe" 54 | ) 55 | } 56 | 57 | Remove-Item @RemoveArgs 58 | 59 | if ( ( $BuildInstaller ) ) { 60 | if ( $Target -eq 'x86+x64' ) { 61 | $IsccCandidates = Get-ChildItem -Recurse -Path '*.iss' 62 | 63 | if ( $IsccCandidates.length -gt 0 ) { 64 | $IsccFile = $IsccCandidates[0].FullName 65 | } else { 66 | $IsccFile = '' 67 | } 68 | } else { 69 | $IsccFile = "${ProjectRoot}/build_${Target}/installer-Windows.generated.iss" 70 | } 71 | 72 | if ( ! ( Test-Path -Path $IsccFile ) ) { 73 | throw 'InnoSetup install script not found. Run the build script or the CMake build and install procedures first.' 74 | } 75 | 76 | Log-Information 'Creating InnoSetup installer...' 77 | Push-Location -Stack BuildTemp 78 | Ensure-Location -Path "${ProjectRoot}/release" 79 | Invoke-External iscc ${IsccFile} /O. /F"${OutputName}-Installer" 80 | Pop-Location -Stack BuildTemp 81 | } 82 | 83 | $CompressArgs = @{ 84 | Path = (Get-ChildItem -Path "${ProjectRoot}/release" -Exclude "${OutputName}*.*") 85 | CompressionLevel = 'Optimal' 86 | DestinationPath = "${ProjectRoot}/release/${OutputName}.zip" 87 | } 88 | 89 | Compress-Archive -Force @CompressArgs 90 | } 91 | 92 | Package 93 | -------------------------------------------------------------------------------- /.github/scripts/utils.pwsh/Logger.ps1: -------------------------------------------------------------------------------- 1 | function Log-Debug { 2 | [CmdletBinding()] 3 | param( 4 | [Parameter(Mandatory,ValueFromPipeline)] 5 | [ValidateNotNullOrEmpty()] 6 | [string[]] $Message 7 | ) 8 | 9 | Process { 10 | foreach($m in $Message) { 11 | Write-Debug $m 12 | } 13 | } 14 | } 15 | 16 | function Log-Verbose { 17 | [CmdletBinding()] 18 | param( 19 | [Parameter(Mandatory,ValueFromPipeline)] 20 | [ValidateNotNullOrEmpty()] 21 | [string[]] $Message 22 | ) 23 | 24 | Process { 25 | foreach($m in $Message) { 26 | Write-Verbose $m 27 | } 28 | } 29 | } 30 | 31 | function Log-Warning { 32 | [CmdletBinding()] 33 | param( 34 | [Parameter(Mandatory,ValueFromPipeline)] 35 | [ValidateNotNullOrEmpty()] 36 | [string[]] $Message 37 | ) 38 | 39 | Process { 40 | foreach($m in $Message) { 41 | Write-Warning $m 42 | } 43 | } 44 | } 45 | 46 | function Log-Error { 47 | [CmdletBinding()] 48 | param( 49 | [Parameter(Mandatory,ValueFromPipeline)] 50 | [ValidateNotNullOrEmpty()] 51 | [string[]] $Message 52 | ) 53 | 54 | Process { 55 | foreach($m in $Message) { 56 | Write-Error $m 57 | } 58 | } 59 | } 60 | 61 | function Log-Information { 62 | [CmdletBinding()] 63 | param( 64 | [Parameter(Mandatory,ValueFromPipeline)] 65 | [ValidateNotNullOrEmpty()] 66 | [string[]] $Message 67 | ) 68 | 69 | Process { 70 | if ( ! ( $script:Quiet ) ) { 71 | $StageName = $( if ( $script:StageName -ne $null ) { $script:StageName } else { '' }) 72 | $Icon = ' =>' 73 | 74 | foreach($m in $Message) { 75 | Write-Host -NoNewLine -ForegroundColor Blue " ${StageName} $($Icon.PadRight(5)) " 76 | Write-Host "${m}" 77 | } 78 | } 79 | } 80 | } 81 | 82 | function Log-Status { 83 | [CmdletBinding()] 84 | param( 85 | [Parameter(Mandatory,ValueFromPipeline)] 86 | [ValidateNotNullOrEmpty()] 87 | [string[]] $Message 88 | ) 89 | 90 | Process { 91 | if ( ! ( $script:Quiet ) ) { 92 | $StageName = $( if ( $StageName -ne $null ) { $StageName } else { '' }) 93 | $Icon = ' >' 94 | 95 | foreach($m in $Message) { 96 | Write-Host -NoNewLine -ForegroundColor Green " ${StageName} $($Icon.PadRight(5)) " 97 | Write-Host "${m}" 98 | } 99 | } 100 | } 101 | } 102 | 103 | function Log-Output { 104 | [CmdletBinding()] 105 | param( 106 | [Parameter(Mandatory,ValueFromPipeline)] 107 | [ValidateNotNullOrEmpty()] 108 | [string[]] $Message 109 | ) 110 | 111 | Process { 112 | if ( ! ( $script:Quiet ) ) { 113 | $StageName = $( if ( $script:StageName -ne $null ) { $script:StageName } else { '' }) 114 | $Icon = '' 115 | 116 | foreach($m in $Message) { 117 | Write-Output " ${StageName} $($Icon.PadRight(5)) ${m}" 118 | } 119 | } 120 | } 121 | } 122 | 123 | $Columns = (Get-Host).UI.RawUI.WindowSize.Width - 5 124 | -------------------------------------------------------------------------------- /.github/scripts/utils.pwsh/Setup-Obs.ps1: -------------------------------------------------------------------------------- 1 | function Setup-Obs { 2 | if ( ! ( Test-Path function:Log-Output ) ) { 3 | . $PSScriptRoot/Logger.ps1 4 | } 5 | 6 | if ( ! ( Test-Path function:Check-Git ) ) { 7 | . $PSScriptRoot/Check-Git.ps1 8 | } 9 | 10 | Check-Git 11 | 12 | if ( ! ( Test-Path function:Ensure-Location ) ) { 13 | . $PSScriptRoot/Ensure-Location.ps1 14 | } 15 | 16 | if ( ! ( Test-Path function:Invoke-GitCheckout ) ) { 17 | . $PSScriptRoot/Invoke-GitCheckout.ps1 18 | } 19 | 20 | if ( ! ( Test-Path function:Invoke-External ) ) { 21 | . $PSScriptRoot/Invoke-External.ps1 22 | } 23 | 24 | Log-Information 'Setting up OBS Studio...' 25 | 26 | $ObsVersion = $BuildSpec.dependencies.'obs-studio'.version 27 | $ObsRepository = $BuildSpec.dependencies.'obs-studio'.repository 28 | $ObsBranch = $BuildSpec.dependencies.'obs-studio'.branch 29 | $ObsHash = $BuildSpec.dependencies.'obs-studio'.hash 30 | 31 | if ( $ObsVersion -eq '' ) { 32 | throw 'No obs-studio version found in buildspec.json.' 33 | } 34 | 35 | Push-Location -Stack BuildTemp 36 | Ensure-Location -Path "$(Resolve-Path -Path "${ProjectRoot}/../")/obs-studio" 37 | 38 | if ( ! ( ( $script:SkipAll ) -or ( $script:SkipUnpack ) ) ) { 39 | Invoke-GitCheckout -Uri $ObsRepository -Commit $ObsHash -Path . -Branch $ObsBranch 40 | } 41 | 42 | if ( ! ( ( $script:SkipAll ) -or ( $script:SkipBuild ) ) ) { 43 | Log-Information 'Configuring OBS Studio...' 44 | 45 | $NumProcessors = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors 46 | 47 | if ( $NumProcessors -gt 1 ) { 48 | $env:UseMultiToolTask = $true 49 | $env:EnforceProcessCountAcrossBuilds = $true 50 | } 51 | 52 | $DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}" 53 | 54 | $CmakeArgs = @( 55 | '-G', $CmakeGenerator 56 | "-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}" 57 | "-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })" 58 | "-DCMAKE_BUILD_TYPE=${script:Configuration}" 59 | "-DQT_VERSION=${script:QtVersion}" 60 | '-DENABLE_PLUGINS=OFF' 61 | '-DENABLE_UI=OFF' 62 | '-DENABLE_SCRIPTING=OFF' 63 | "-DCMAKE_INSTALL_PREFIX:PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/${DepsPath}")" 64 | "-DCMAKE_PREFIX_PATH:PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/${DepsPath}")" 65 | ) 66 | 67 | Log-Debug "Attempting to configure OBS with CMake arguments: $($CmakeArgs | Out-String)" 68 | Log-Information "Configuring OBS..." 69 | Invoke-External cmake -S . -B plugin_build_${script:Target} @CmakeArgs 70 | 71 | Log-Information 'Building libobs and obs-frontend-api...' 72 | $CmakeArgs = @( 73 | '--config', "$( if ( $script:Configuration -eq '' ) { 'RelWithDebInfo' } else { $script:Configuration })" 74 | ) 75 | 76 | if ( $VerbosePreference -eq 'Continue' ) { 77 | $CmakeArgs+=('--verbose') 78 | } 79 | 80 | Invoke-External cmake --build plugin_build_${script:Target} @CmakeArgs -t obs-frontend-api 81 | Invoke-External cmake --install plugin_build_${script:Target} @CmakeArgs --component obs_libraries 82 | } 83 | Pop-Location -Stack BuildTemp 84 | } 85 | -------------------------------------------------------------------------------- /.github/actions/package-plugin/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Package plugin' 2 | description: 'Packages the plugin for specified architecture and build config.' 3 | inputs: 4 | target: 5 | description: 'Build target for dependencies' 6 | required: true 7 | config: 8 | description: 'Build configuration' 9 | required: false 10 | default: 'Release' 11 | codesign: 12 | description: 'Enable codesigning (macOS only)' 13 | required: false 14 | default: 'false' 15 | notarize: 16 | description: 'Enable notarization (macOS only)' 17 | required: false 18 | default: 'false' 19 | codesignIdent: 20 | description: 'Developer ID for application codesigning (macOS only)' 21 | required: false 22 | default: '-' 23 | installerIdent: 24 | description: 'Developer ID for installer package codesigning (macOS only)' 25 | required: false 26 | default: '' 27 | codesignUser: 28 | description: 'Apple ID username for notarization (macOS only)' 29 | required: false 30 | default: '' 31 | codesignPass: 32 | description: 'Apple ID password for notarization (macOS only)' 33 | required: false 34 | default: '' 35 | createInstaller: 36 | description: 'Create InnoSetup installer (Windows only)' 37 | required: false 38 | default: 'false' 39 | workingDirectory: 40 | description: 'Working directory for packaging' 41 | required: false 42 | default: ${{ github.workspace }} 43 | runs: 44 | using: 'composite' 45 | steps: 46 | - name: Run macOS packaging 47 | if: ${{ runner.os == 'macOS' }} 48 | shell: zsh {0} 49 | env: 50 | CODESIGN_IDENT: ${{ inputs.codesignIdent }} 51 | CODESIGN_IDENT_INSTALLER: ${{ inputs.installerIdent }} 52 | CODESIGN_IDENT_USER: ${{ inputs.codesignUser }} 53 | CODESIGN_IDENT_PASS: ${{ inputs.codesignPass }} 54 | run: | 55 | package_args=( 56 | -c ${{ inputs.config }} 57 | -t macos-${{ inputs.target }} 58 | ) 59 | 60 | if [[ '${{ inputs.codesign }}' == 'true' ]] package_args+=(-s) 61 | if [[ '${{ inputs.notarize }}' == 'true' ]] package_args+=(-n) 62 | if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug) 63 | 64 | ${{ inputs.workingDirectory }}/.github/scripts/package-macos.zsh ${package_args} 65 | 66 | - name: Run Linux packaging 67 | if: ${{ runner.os == 'Linux' }} 68 | shell: bash 69 | run: | 70 | package_args=( 71 | -c ${{ inputs.config }} 72 | -t linux-${{ inputs.target }} 73 | ) 74 | if [[ -n "${CI}" && -n "${RUNNER_DEBUG}" ]]; then 75 | build_args+=(--debug) 76 | fi 77 | 78 | ${{ inputs.workingDirectory }}/.github/scripts/package-linux.sh "${package_args[@]}" 79 | 80 | - name: Run Windows packaging 81 | if: ${{ runner.os == 'Windows' }} 82 | shell: pwsh 83 | run: | 84 | $PackageArgs = @{ 85 | Target = '${{ inputs.target }}' 86 | Configuration = '${{ inputs.config }}' 87 | } 88 | 89 | if ( '${{ inputs.createInstaller }}' -eq 'true' ) { 90 | $PackageArgs += @{BuildInstaller = $true} 91 | } 92 | 93 | if ( ( Test-Path env:CI ) -and ( Test-Path env:RUNNER_DEBUG ) ) { 94 | $BuildArgs += @{ 95 | Debug = $true 96 | } 97 | } 98 | 99 | ${{ inputs.workingDirectory }}/.github/scripts/Package-Windows.ps1 @PackageArgs 100 | -------------------------------------------------------------------------------- /.github/scripts/Build-Windows.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [ValidateSet('Debug', 'RelWithDebInfo', 'Release', 'MinSizeRel')] 4 | [string] $Configuration = 'RelWithDebInfo', 5 | [ValidateSet('x86', 'x64')] 6 | [string] $Target, 7 | [ValidateSet('Visual Studio 17 2022', 'Visual Studio 16 2019')] 8 | [string] $CMakeGenerator, 9 | [switch] $SkipAll, 10 | [switch] $SkipBuild, 11 | [switch] $SkipDeps, 12 | [switch] $SkipUnpack 13 | ) 14 | 15 | $ErrorActionPreference = 'Stop' 16 | 17 | if ( $DebugPreference -eq 'Continue' ) { 18 | $VerbosePreference = 'Continue' 19 | $InformationPreference = 'Continue' 20 | } 21 | 22 | if ( $PSVersionTable.PSVersion -lt '7.0.0' ) { 23 | Write-Warning 'The obs-deps PowerShell build script requires PowerShell Core 7. Install or upgrade your PowerShell version: https://aka.ms/pscore6' 24 | exit 2 25 | } 26 | 27 | function Build { 28 | trap { 29 | Pop-Location -Stack BuildTemp -ErrorAction 'SilentlyContinue' 30 | Write-Error $_ 31 | exit 2 32 | } 33 | 34 | $ScriptHome = $PSScriptRoot 35 | $ProjectRoot = Resolve-Path -Path "$PSScriptRoot/../.." 36 | $BuildSpecFile = "${ProjectRoot}/buildspec.json" 37 | 38 | $UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse 39 | 40 | foreach($Utility in $UtilityFunctions) { 41 | Write-Debug "Loading $($Utility.FullName)" 42 | . $Utility.FullName 43 | } 44 | 45 | $BuildSpec = Get-Content -Path ${BuildSpecFile} -Raw | ConvertFrom-Json 46 | $ProductName = $BuildSpec.name 47 | $ProductVersion = $BuildSpec.version 48 | 49 | $script:DepsVersion = '' 50 | $script:QtVersion = '5' 51 | $script:VisualStudioVersion = '' 52 | $script:PlatformSDK = '10.0.18363.657' 53 | 54 | Setup-Host 55 | 56 | if ( $CmakeGenerator -eq '' ) { 57 | $CmakeGenerator = $script:VisualStudioVersion 58 | } 59 | 60 | (Get-Content -Path ${ProjectRoot}/CMakeLists.txt -Raw) ` 61 | -replace "project\((.*) VERSION (.*)\)", "project(${ProductName} VERSION ${ProductVersion})" ` 62 | | Out-File -Path ${ProjectRoot}/CMakeLists.txt 63 | 64 | Setup-Obs 65 | 66 | Push-Location -Stack BuildTemp 67 | if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) { 68 | Ensure-Location $ProjectRoot 69 | 70 | $DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}" 71 | $CmakeArgs = @( 72 | '-G', $CmakeGenerator 73 | "-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}" 74 | "-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })" 75 | "-DCMAKE_BUILD_TYPE=${Configuration}" 76 | "-DCMAKE_PREFIX_PATH:PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/${DepsPath}")" 77 | "-DQT_VERSION=${script:QtVersion}" 78 | ) 79 | 80 | Log-Debug "Attempting to configure OBS with CMake arguments: $($CmakeArgs | Out-String)" 81 | Log-Information "Configuring ${ProductName}..." 82 | Invoke-External cmake -S . -B build_${script:Target} @CmakeArgs 83 | 84 | $CmakeArgs = @( 85 | '--config', "${Configuration}" 86 | ) 87 | 88 | if ( $VerbosePreference -eq 'Continue' ) { 89 | $CmakeArgs+=('--verbose') 90 | } 91 | 92 | Log-Information "Building ${ProductName}..." 93 | Invoke-External cmake --build "build_${script:Target}" @CmakeArgs 94 | } 95 | Log-Information "Install ${ProductName}..." 96 | Invoke-External cmake --install "build_${script:Target}" --prefix "${ProjectRoot}/release" @CmakeArgs 97 | 98 | Pop-Location -Stack BuildTemp 99 | } 100 | 101 | Build 102 | -------------------------------------------------------------------------------- /.github/scripts/utils.pwsh/Invoke-GitCheckout.ps1: -------------------------------------------------------------------------------- 1 | function Set-GitConfig { 2 | <# 3 | .SYNOPSIS 4 | Sets a git config value. 5 | .DESCRIPTION 6 | Allows setting single or multiple config values in a PowerShell-friendly fashion. 7 | .EXAMPLE 8 | Set-GitConfig advice.detachedHead false 9 | #> 10 | 11 | if ( $args.Count -lt 2 ) { 12 | throw 'Set-GitConfig called without required arguments