commit 438b2bada30696afeaae03d4640b9371737d3278 Author: evan.liu <583229071@qq.com> Date: Fri Sep 18 06:08:44 2026 +0800 2026-09-18 OBS开源第一个版本 diff --git a/obs-studio/.clang-format b/obs-studio/.clang-format new file mode 100644 index 0000000..ee64042 --- /dev/null +++ b/obs-studio/.clang-format @@ -0,0 +1,213 @@ +# please use clang-format version 16 or later + +AccessModifierOffset: -8 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +AllowShortLambdasOnASingleLine: Inline +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakStringLiterals: false # apparently unpredictable +ColumnLimit: 120 +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +FixNamespaceComments: true +ForEachMacros: + - 'json_object_foreach' + - 'json_object_foreach_safe' + - 'json_array_foreach' + - 'HASH_ITER' +IncludeBlocks: Preserve +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 8 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 8 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true + +PenaltyBreakAssignment: 10 +PenaltyBreakBeforeFirstCallParameter: 30 +PenaltyBreakComment: 10 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakString: 10 +PenaltyExcessCharacter: 100 +PenaltyReturnTypeOnItsOwnLine: 60 + +PointerAlignment: Right +ReflowComments: false +SkipMacroDefinitionBody: true +SortIncludes: false +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +StatementMacros: + - 'Q_OBJECT' +TabWidth: 8 +TypenameMacros: + - 'DARRAY' +UseTab: ForContinuationAndIndentation +--- +Language: Cpp +Standard: c++17 +InsertBraces: true +--- +Language: ObjC +AccessModifierOffset: 2 +AlignArrayOfStructures: Right +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: false + AcrossComments: true +AllowShortBlocksOnASingleLine: Never +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: None +AttributeMacros: ['__unused', '__autoreleasing', '_Nonnull', '__bridge'] +BitFieldColonSpacing: Both +#BreakBeforeBraces: Webkit +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: Never + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: true +BreakAfterAttributes: Never +BreakArrays: false +BreakBeforeConceptDeclarations: Allowed +BreakBeforeInlineASMColon: OnlyMultiline +BreakConstructorInitializers: AfterColon +BreakInheritanceList: AfterComma +ColumnLimit: 120 +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: true +IndentExternBlock: Indent +IndentGotoLabels: false +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: true +InsertBraces: false +InsertNewlineAtEOF: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +NamespaceIndentation: All +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: false +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PPIndentWidth: -1 +PackConstructorInitializers: NextLine +QualifierAlignment: Leave +ReferenceAlignment: Right +RemoveSemicolon: false +RequiresClausePosition: WithPreceding +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: false +#SortUsingDeclarations: LexicographicNumeric +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInConditionalStatement: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +Standard: c++17 +TabWidth: 4 +UseTab: Never +... diff --git a/obs-studio/.editorconfig b/obs-studio/.editorconfig new file mode 100644 index 0000000..5c9704f --- /dev/null +++ b/obs-studio/.editorconfig @@ -0,0 +1,63 @@ +# EditorConfig is awesome: http://EditorConfig.org +# Since OBS follows the Linux kernel coding style I have started this file to +# help with automatically setting various text editors to those requirements. + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file. +[*] +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 +indent_style = tab +indent_size = 8 + +# As per notr1ch, for 3rd party code that's a part of obs-outputs. +[plugins/obs-outputs/librtmp/*.{cpp,c,h}] +indent_style = space +indent_size = 4 + +[CMakeLists.txt] +indent_style = space +indent_size = 2 + +[**/CMakeLists.txt] +indent_style = space +indent_size = 2 + +[cmake/**/*.cmake] +indent_style = space +indent_size = 2 + +[plugins/{rtmp-services,win-capture}/data/**/*.json] +indent_style = space +indent_size = 4 + +[*.qss] +indent_style = space +indent_size = 4 + +[build-aux/**/*.json] +indent_style = space +indent_size = 4 + +[*.py] +indent_style = space +indent_size = 4 + +[*.yaml] +indent_style = space +indent_size = 2 + +[{*.zsh,.*.zsh,build-aux/.functions/*,.github/scripts/utils.zsh/*}] +indent_style = space +indent_size = 2 + +[*.ui] +indent_style = space +indent_size = 1 + +[{*.obt,*.oha,*.ovt}] +indent_style = space +indent_size = 4 diff --git a/obs-studio/.gersemirc b/obs-studio/.gersemirc new file mode 100644 index 0000000..59c4a78 --- /dev/null +++ b/obs-studio/.gersemirc @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/BlankSpruce/gersemi/master/gersemi/configuration.schema.json + +definitions: [] +line_length: 120 +indent: 2 +list_expansion: favour-inlining +unsafe: false +warn_about_unknown_commands: false diff --git a/obs-studio/.github/FUNDING.yml b/obs-studio/.github/FUNDING.yml new file mode 100644 index 0000000..4b0e759 --- /dev/null +++ b/obs-studio/.github/FUNDING.yml @@ -0,0 +1,2 @@ +open_collective: obsproject +patreon: obsproject diff --git a/obs-studio/.github/actions/build-obs/action.yaml b/obs-studio/.github/actions/build-obs/action.yaml new file mode 100644 index 0000000..ddafb12 --- /dev/null +++ b/obs-studio/.github/actions/build-obs/action.yaml @@ -0,0 +1,121 @@ +name: Set Up and Build obs-studio +description: Builds obs-studio for specified architecture and build config +inputs: + target: + description: Build target for obs-studio + required: true + config: + description: Build configuration + required: false + default: RelWithDebInfo + codesign: + description: Enable codesigning (macOS only) + required: false + default: 'false' + codesignIdent: + description: Developer ID for application codesigning (macOS only) + required: false + default: '-' + codesignTeam: + description: Team ID for application codesigning (macOS only) + required: false + default: '' + provisioningProfileUUID: + description: UUID of provisioning profile (macOS only) + required: false + default: '' + 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 --no-rcs --errexit --pipefail {0} + working-directory: ${{ inputs.workingDirectory }} + env: + CODESIGN_IDENT: ${{ inputs.codesignIdent }} + CODESIGN_TEAM: ${{ inputs.codesignTeam }} + PROVISIONING_PROFILE: ${{ inputs.provisioningProfileUUID }} + run: | + : Run macOS Build + + local -a build_args=( + --config ${{ inputs.config }} + --target macos-${{ inputs.target }} + ) + if (( ${+RUNNER_DEBUG} )) build_args+=(--debug) + + if [[ '${{ inputs.codesign }}' == true ]] build_args+=(--codesign) + + git fetch origin --no-tags --no-recurse-submodules -q + .github/scripts/build-macos ${build_args} + + - name: Install Dependencies 🛍️ + if: runner.os == 'Linux' + shell: bash + run: | + : Install Dependencies 🛍️ + echo ::group::Install Dependencies + eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH + brew update + brew install --quiet zsh + echo ::endgroup:: + + - name: Run Ubuntu Build + if: runner.os == 'Linux' + shell: zsh --no-rcs --errexit --pipefail {0} + working-directory: ${{ inputs.workingDirectory }} + run: | + : Run Ubuntu Build + + local -a build_args=( + --config ${{ inputs.config }} + --target ubuntu-${{ inputs.target }} + ) + if (( ${+RUNNER_DEBUG} )) build_args+=(--debug) + + git fetch origin --no-tags --no-recurse-submodules -q + .github/scripts/build-ubuntu ${build_args} + + - name: Run Windows Build + if: runner.os == 'Windows' + shell: pwsh + working-directory: ${{ inputs.workingDirectory }} + run: | + # Run Windows Build + $BuildArgs = @{ + Target = '${{ inputs.target }}' + Configuration = '${{ inputs.config }}' + } + + if ( $Env:RUNNER_DEBUG -ne $null ) { + $BuildArgs += @{ Debug = $true } + } + + git fetch origin --no-tags --no-recurse-submodules -q + .github/scripts/Build-Windows.ps1 @BuildArgs + + - name: Create Summary 📊 + if: runner.os == 'Linux' + shell: zsh --no-rcs --errexit --pipefail {0} + run: | + : Create Summary 📊 + + local -a ccache_data + if (( ${+RUNNER_DEBUG} )) { + setopt XTRACE + ccache_data=("${(fA)$(ccache -s -vv)}") + } else { + ccache_data=("${(fA)$(ccache -s)}") + } + + print '### ${{ runner.os }} Ccache Stats (${{ inputs.target }})' >> $GITHUB_STEP_SUMMARY + print '```' >> $GITHUB_STEP_SUMMARY + for line (${ccache_data}) { + print ${line} >> $GITHUB_STEP_SUMMARY + } + print '```' >> $GITHUB_STEP_SUMMARY diff --git a/obs-studio/.github/actions/check-changes/action.yaml b/obs-studio/.github/actions/check-changes/action.yaml new file mode 100644 index 0000000..40e4a3a --- /dev/null +++ b/obs-studio/.github/actions/check-changes/action.yaml @@ -0,0 +1,82 @@ +name: Check For Changed Files +description: Checks for changed files compared to specific git reference and glob expression +inputs: + baseRef: + description: Git reference to check against + required: false + ref: + description: Git reference to check with + required: false + default: HEAD + checkGlob: + description: Glob expression to limit check to specific files + required: false + useFallback: + description: Use fallback compare against prior commit + required: false + default: 'true' + diffFilter: + description: git diff-filter string to use + required: false + default: '' +outputs: + hasChangedFiles: + value: ${{ steps.checks.outputs.hasChangedFiles }} + description: True if specified files were changed in comparison to specified git reference + changedFiles: + value: ${{ steps.checks.outputs.changedFiles }} + description: List of changed files +runs: + using: composite + steps: + - name: Check For Changed Files ✅ + shell: bash + id: checks + env: + GIT_BASE_REF: ${{ inputs.baseRef }} + GIT_REF: ${{ inputs.ref }} + GITHUB_EVENT_FORCED: ${{ github.event.forced }} + GITHUB_REF_BEFORE: ${{ github.event.before }} + USE_FALLBACK: ${{ inputs.useFallback }} + DIFF_FILTER: ${{ inputs.diffFilter }} + run: | + : Check for Changed Files ✅ + if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi + shopt -s extglob + shopt -s dotglob + + # 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is a "hidden" sha1 hash of + # the "empty tree", retrieved via 'git hash-object -t tree /dev/null', + # and used here as a last-resort fallback to always provide a valid + # git ref. + + if [[ "${GIT_BASE_REF}" ]]; then + if ! git cat-file -e "${GIT_BASE_REF}" &> /dev/null; then + echo "::warning::Provided base reference ${GIT_BASE_REF} is invalid" + if [[ "${USE_FALLBACK}" == 'true' ]]; then + GIT_BASE_REF='HEAD~1' + fi + fi + else + if ! git cat-file -e ${GITHUB_REF_BEFORE} &> /dev/null; then + GITHUB_REF_BEFORE='4b825dc642cb6eb9a060e54bf8d69288fbee4904' + fi + + GIT_BASE_REF='HEAD~1' + case "${GITHUB_EVENT_NAME}" in + pull_request) GIT_BASE_REF="origin/${GITHUB_BASE_REF}" ;; + push) if [[ "${GITHUB_EVENT_FORCED}" != 'true' ]]; then GIT_BASE_REF="${GITHUB_REF_BEFORE}"; fi ;; + *) ;; + esac + fi + + changes=($(git diff --name-only --diff-filter="${DIFF_FILTER}" ${GIT_BASE_REF} ${GIT_REF} -- ${{ inputs.checkGlob }})) + + if (( ${#changes[@]} )); then + file_string="${changes[*]}" + echo "hasChangedFiles=true" >> $GITHUB_OUTPUT + echo "changedFiles=[\"${file_string// /\",\"}\"]" >> $GITHUB_OUTPUT + else + echo "hasChangedFiles=false" >> $GITHUB_OUTPUT + echo "changedFiles=[]" >> GITHUB_OUTPUT + fi diff --git a/obs-studio/.github/actions/compatibility-validator/action.yaml b/obs-studio/.github/actions/compatibility-validator/action.yaml new file mode 100644 index 0000000..c6c4607 --- /dev/null +++ b/obs-studio/.github/actions/compatibility-validator/action.yaml @@ -0,0 +1,64 @@ +name: Compatibility Data Validator +description: Checks Windows compatibility data files +inputs: + repositorySecret: + description: GitHub token for API access + required: true + workingDirectory: + description: Working directory for checks + required: false + default: ${{ github.workspace }} +runs: + using: composite + steps: + - name: Check Runner Operating System 🏃‍♂️ + if: runner.os == 'Windows' + shell: bash + run: | + : Check Runner Operating System 🏃‍♂️ + echo "services-validation action requires a macOS-based or Linux-based runner." + exit 2 + + - name: Install and Configure Python 🐍 + shell: bash + run: | + : Install and Configure Python 🐍 + if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi + + echo ::group::Python Set Up + if [[ "${RUNNER_OS}" == Linux ]]; then + eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH + fi + brew update + brew install --quiet python3 + + python3 -m venv .venv + + source .venv/bin/activate + python3 -m pip install jsonschema json_source_map + echo ::endgroup:: + + - name: Validate Compatibility Files JSON Schema 🕵️ + shell: bash + working-directory: ${{ inputs.workingDirectory }} + run: | + : Validate services file JSON schema 🕵️ + if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi + shopt -s extglob + + echo ::group::Schema Validation + source .venv/bin/activate + python3 -u \ + .github/scripts/utils.py/check-jsonschema.py \ + --loglevel INFO \ + plugins/win-capture/data/@(compatibility|package).json + echo ::endgroup:: + + - name: Annotate Schema Validation Errors 🏷️ + uses: yuzutech/annotations-action@00b2d488bcba3bd01014dc073d276ef4a45d5c6c # v0.6.0 + if: failure() + with: + repo-token: ${{ inputs.repositorySecret }} + title: Compatibility JSON Errors + input: ${{ inputs.workingDirectory }}/validation_errors.json diff --git a/obs-studio/.github/actions/flatpak-builder-lint/action.yaml b/obs-studio/.github/actions/flatpak-builder-lint/action.yaml new file mode 100644 index 0000000..481ff6c --- /dev/null +++ b/obs-studio/.github/actions/flatpak-builder-lint/action.yaml @@ -0,0 +1,75 @@ +name: Run flatpak-builder-lint +description: Runs flatpak-builder-lint with exceptions +inputs: + artifact: + description: Type of artifact to lint (builddir, repo, manifest, appstream) + required: true + path: + description: Path to flatpak-builder manifest or Flatpak build directory + required: true + workingDirectory: + description: Working directory to clone flatpak-builder-lint + required: false + default: ${{ github.workspace }} +runs: + using: composite + steps: + - name: Check artifact type + shell: bash + working-directory: ${{ inputs.workingDirectory }} + run: | + : Check artifact input + if ! [[ "${{ inputs.artifact }}" =~ builddir|repo|manifest|appstream ]]; then + echo "::error::Given artifact type is incorrect" + exit 2 + fi + + - name: Run flatpak-builder-lint + id: result + shell: bash + working-directory: ${{ inputs.workingDirectory }} + run: | + : Run flatpak-builder-lint + + return=0 + result="$(flatpak-builder-lint --exceptions --user-exceptions ${GITHUB_ACTION_PATH}/exceptions.json ${{ inputs.artifact }} ${{ inputs.path }})" || return=$? + + if [[ ${return} != 0 && -z "${result}" ]]; then + echo "::error::Error while running flatpak-builder-lint" + exit 2 + fi + + if [[ "${{ inputs.artifact }}" == "appstream" ]]; then + echo "${result}" + + if [[ ${return} != 0 ]]; then echo "::error::Flatpak appstream info is not valid"; fi + + exit ${return} + fi + + # This jq command selects any available array under the 'warnings' key in the JSON document + # or provides an empty array as a fallback if the key is not present. This array is then + # piped to the 'map' function to apply a transformation to every element in the array, + # converting it to a string prefixed with the output level, the actual element value, and + # finally the suffix string defined in 'template'. + # + # The result of this expression is concatenated with a similar expression doing the same + # but for the 'errors' key and its associated array. + # + # The second jq invocation then selects each element of the array and outputs it directly, + # which will be strings of the formats: + # + # * '::warning::