Projects
Multimedia
obs-studio
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 140
View file
obs-studio.changes
Changed
@@ -1,4 +1,200 @@ ------------------------------------------------------------------- +Fri Oct 23 23:52:10 UTC 2026 - darix <packman@nordisch.org> + +- Update to version 33.0.0: + * CI: Update deps to 2026-10-23 release + * rtmp-services: Update Twitch/IVS Ingests + +------------------------------------------------------------------- +Wed Oct 21 07:32:29 UTC 2026 - darix <packman@nordisch.org> + +- Update to version 33.0.0~rc3: + * obs-browser: Update version to 2.27.4 + +------------------------------------------------------------------- +Fri Oct 16 23:33:08 UTC 2026 - darix <packman@nordisch.org> + +- Update to version 33.0.0~rc2: + * obs-browser: Update version to 2.27.3 + * cmake: Fix regression when disabling core modules + * rtmp-services: Remove defunct servers/services + * build-aux: Update steam vcam script + * frontend: Fix add source dialog scrollbar policy + * win-dshow: Update virtualcam installer scripts + * frontend: Hide warning icon for legacy plugins + * frontend: Remove legacy replay buffer hotkey code + +------------------------------------------------------------------- +Sun Oct 11 01:42:22 UTC 2026 - darix <packman@nordisch.org> + +- use ffmpeg-9 on TW + +------------------------------------------------------------------- +Fri Oct 09 09:31:31 UTC 2026 - darix <packman@nordisch.org> + +- Update to version 33.0.0~rc1: + * obs-websocket: Update version to 5.7.6 + * frontend: Unparent missing encoders popup + * libobs: Fix obs_canvas_reset_video when other canvas is active + * frontend: Fix profile import with trailing path slash + * obs-browser: Update version to 2.27.2 + * frontend: Fix removal of missing plugins + * frontend: Fix display of plugins in safe mode + * frontend: Fix failed plugin popup in safe mode + * Update translations from Crowdin + * obs-browser: Update version to 2.27.1 + * libobs: Add PIC to obs-core-modules + +------------------------------------------------------------------- +Sat Oct 03 01:13:14 UTC 2026 - darix <packman@nordisch.org> + +- Update to version 33.0.0~beta6: + * obs-websocket: Update version to 5.7.5 + * shared: Remove Qt<6.10 code + * frontend: Remove Qt<6.10 code + * linux-v4l2: Remove support for FFmpeg<8.0 + * obs-ffmpeg: Remove support for FFmpeg<8.0 + * win-dshow Set minimum FFmpeg version to 8.0 + * frontend: Set minimum FFmpeg version to 8.0 + * media-playback: Set minimum FFmpeg version to 8.0 + * libobs: Increase minimum FFmpeg version to 8.0 + * decklink: Include previously implicit header for Linux + * frontend: Include previously implicit headers for non-Windows + * frontend: Restore OBS wrappers in callbacks + * docs: Update graphics/image-file.h docs + * frontend-tools: Update clock Lua script for new gs_image_file_ex + * win-capture: Fix data directory path + * cmake: Fix bundling of scripting files on macOS + * cmake: Make obs-core-modules header public +- bump minimum versions for ffmpeg components to match upstreams + deprecated support for older versions + +------------------------------------------------------------------- +Thu Oct 01 00:15:18 UTC 2026 - darix <packman@nordisch.org> + +- Update to version 33.0.0~beta5: + * frontend: Limit missing encoder check by output mode + * libobs: Fix data for updated monitoring + * updater: Retain legacy module path support + * frontend: Fix source icon state appearing inverted + * frontend: Fix rich text on macOS warning popups + * frontend: Unregister save replay buffer hotkey + +------------------------------------------------------------------- +Fri Sep 25 22:38:56 UTC 2026 - darix <packman@nordisch.org> + +- Update to version 33.0.0~beta4: + * CI: Update sign-windows commit + * CI: Update bouf to v0.6.6 + * CI: Update sign-windows commit + * CI: Update game capture path in windows-signing action + * libobs: Update version to 33.0.0 + * CI,build-aux: Update Flatpak to 2026-09-24 deps + * frontend-tools: Turn off scripting in Safe Mode + * frontend: Add obs_frontend_is_safe_mode_enabled() API call + * frontend: Adjust plugin error dialog text + * frontend: Avoid exec for plugin window + * frontend: Update plugin manager window + * frontend: Add InfoChip widget + * idian: Fix RowList insert position and count + * idian: Style adjustments + * frontend: Update app module loading behavior + * libobs: Add core module loading functionality + * cmake: Add OS_FLATPAK flag + * cmake: Change name of core module output directory + * cmake: Add concept of "core" modules + * cmake: Add explicit target_enable function + * rtmp-services: Update IRLToolkit ingest list + * rtmp-services: Update Streamway primary ingest + * frontend: Update default snap distance + * frontend: Improve preview source snapping + * rtmp-services: Update Whowatch + * linux-alsa: Fix use-after-free crash when USB mic not plugged in + * frontend: Refactor ScreenshotObj options + * frontend: Demangle ScreenshotObj and OBSBasic + * rtmp-services: Add multitrack_video option to PandaTV | 팬더티비 Service + * rtmp-services: Add Spoon RTMP service + * frontend: Update tab bar styling + * libobs: Make sure all code paths leave context + * libobs-d3d11: Avoid exceptions in shader cache file handling + * frontend: Log item/filter visibility changes + * frontend: Log sceneitem and filter enabled state on load + * CI, build-aux: Update CEF from 127/6533 to 150/7871 + * idian: Debounce widget repolishing + * idian: Remove Utils inheritance + * frontend: Refactor Idian widgets + * obs-browser: Update to 2.27.0 + * libobs-metal: Wrap blitSwapChains in autoreleasepool to fix mach port leak + * build-aux: Add versions to Flatpak plugin extension point + * nv-filters: Remove CUDA from audio loader + * nv-filters: Enable Video FX SDK 1.3.0 for ARM + * nv-filters: Do not display VAD for dereverb + * nv-filters: Enable audio FX SDK 3.0.0 for ARM + * libobs: Create unique groups when duplicating scene + * rtmp-services: Remove defunct servers/services + * frontend: Fix group icon styling + * cmake: Remove MbedTLS custom finder + * frontend: Minor Spinbox cleanup + * SQUASME: Address review comment + * Update codestyle document + * Update contribution guidelines for PR reviews + * win-capture: Add Roblox window class auto switch to WGC mode + * rtmp-services: Update SOOP ingests + * docs: Add precision on editable string lists + * frontend: Use styling for source items appearance + * frontend: Add icon coloring for labels + * frontend: Register the replay buffer save hotkey in the frontend + * frontend: Add replay buffer saving frontend event + * obs-ffmpeg: Add replay buffer saving output signal + * libobs: Only emit core signal handlers for public canvases + * libobs: Change canvas signal param name to `signal_canvas` + * libobs: Fix monitoring hotkey UI updates + * libobs: Free monitor hotkeys translations + * libobs: Fix deadlock on executing tasks + * obs-nvenc: Enable NVENC on Arm64 + * frontend: Fix dangling pointer in Audio Mixer logging + * CI: Update deps to 2026-08-26 release + * win-capture: Add Construct 3 window class to WGC match + * frontend: Improve spin box UX + * libobs, frontend: Add monitoring hotkeys + * docs: Mark monitoring_type as deprecated + * libobs, frontend: Deprecate source monitoring_type + * obs-ffmpeg: Fix B-frame offset calculation in AMF + * libobs, docs: Document intended use of obs_module_unload + * win-capture: Improve fullscreen window detection + * libobs/graphics: Break image file API to prevent ABI issues + * libobs/graphics: Hide GIF decoding data from exported header file + * libobs/graphics: Update libnsgif to 1.0.0 + * cmake: Require MbedTLS 3 and exclude 4 or later + * obs-outputs: Fix file splitting overshooting when b-frames are used + * obs-outputs: Do not drop last packet when flushing Hybrid file + * mac-capture: Use 64RGBAHalf pixel format for screen capture when available + * libobs-opengl: Support texture creation from IOSurface using RGBA64Half + * frontend: Scale simple output recording audio bitrate by channel count + * frontend: Ensure pending profile changes are saved + * linux-pipewire: Forbid screencast source duplication + * frontend: Abort if obs-transitions failed to load + * frontend: Add info notices to theme files + * win-capture: Reorder capture method dropdown + * win-capture: Change capture methods name + * frontend: Remove native widget property + * obs-frontend-api: Fix repeated preview en-/disables not working + * frontend: Don't read unloaded module in source toolbar + * frontend: Ensure source type exists before creating toolbar + * libobs: Ensure module exists before getting locale string + * libobs: Fix file filter for save file path widget + * docs: Add deprecation notice for source hiding + * libobs: Deprecate source hiding + * frontend: Remove superfluous hidden check + * frontend: Fix SourceButton rename handler + * frontend: Add Encoder availability check + * libobs: Update version to 32.2.2 + * frontend: Fix spacer in permissions dialog + * frontend: Update forms to fully qualified enums + * frontend: Update invokeMethod to use functions + * CI: Remove support for Ubuntu 24.04 + +------------------------------------------------------------------- Sat Aug 15 00:00:43 UTC 2026 - darix <packman@nordisch.org> - Update to version 32.2.2:
View file
obs-studio.spec
Changed
@@ -10,27 +10,24 @@ %bcond_without websockets %bcond_with split_obs_x264 -# 31.0.0~beta1 wants at least 6.1 lets just use 8 straight away -# zypper info --provides $(zypper se -t package -s ffmpeg-8 | awk -F '|' '/devel/ {print $2}') | grep pkgconfig | perl -p -e 's|^\s+pkgconfig\((^\)+)\) = (\S+)|%%global minimum_$1_version $2|g' | sort -u -#if 0%{?suse_version} >= 1699 -#global minimum_libavcodec_version 62.11.100 -#global minimum_libavdevice_version 62.1.100 -#global minimum_libavfilter_version 11.4.100 -#global minimum_libavformat_version 62.3.100 -#global minimum_libavutil_version 60.8.100 -#global minimum_libswresample_version 6.1.100 -#global minimum_libswscale_version 9.1.100 -#else -# but keep ffmpeg 7 for 16.x -%global minimum_libavcodec_version 61.19.100 -%global minimum_libavdevice_version 61.3.100 -%global minimum_libavfilter_version 10.4.100 -%global minimum_libavformat_version 61.7.100 -%global minimum_libavutil_version 59.39.100 -%global minimum_libpostproc_version 58.3.100 -%global minimum_libswresample_version 5.3.100 -%global minimum_libswscale_version 8.3.100 -#endif +# zypper info --provides $(zypper se -t package -s ffmpeg-9 | awk -F '|' '/devel/ {print $2}' | sort -u) | grep pkgconfig | perl -p -e 's|^\s+pkgconfig\((^\)+)\) = (\S+)|%global minimum_$1_version $2|g' | sort -u +%if 0%{?suse_version} >= 1699 +%global minimum_libavcodec_version 63.1.102 +%global minimum_libavdevice_version 63.1.102 +%global minimum_libavfilter_version 12.1.102 +%global minimum_libavformat_version 63.1.102 +%global minimum_libavutil_version 61.1.102 +%global minimum_libswresample_version 7.1.102 +%global minimum_libswscale_version 10.1.102 +%else +%global minimum_libavcodec_version 62.28.102 +%global minimum_libavdevice_version 62.3.102 +%global minimum_libavfilter_version 11.14.102 +%global minimum_libavformat_version 62.12.102 +%global minimum_libavutil_version 60.26.102 +%global minimum_libswresample_version 6.3.102 +%global minimum_libswscale_version 9.5.102 +%endif %if 0%{?suse_version} && 0%{?suse_version} < 1600 %global force_gcc_version 13 @@ -50,7 +47,7 @@ %endif Name: obs-studio -Version: 32.2.2 +Version: 33.0.0 Release: 0 Summary: A recording/broadcasting program Group: Productivity/Multimedia/Video/Editors and Convertors @@ -94,7 +91,7 @@ BuildRequires: libx264-devel %endif # BuildRequires: mbedtls-devel -BuildRequires: mbedtls-2-devel +BuildRequires: mbedtls-3-devel BuildRequires: pipewire-devel BuildRequires: pkgconfig BuildRequires: pkgconfig(alsa) @@ -237,8 +234,13 @@ %install %cmake_install %suse_update_desktop_file com.obsproject.Studio +install -D -d -m 0755 \ + %{buildroot}%{_libdir}/obs-modules/plugins/ \ + %{buildroot}%{_datadir}/obs/obs-modules/plugins/ + %fdupes %{buildroot}%{_datadir}/obs/ + %post /sbin/ldconfig %icon_theme_cache_postun @@ -255,9 +257,9 @@ %endif # Upstream forces libs dir regardless of arch and building plugins is encumbered # by moving them to the proper directory. -%{_libdir}/obs-plugins/ +%{_libdir}/obs-modules/ %if %{with split_obs_x264} -%exclude %{_libdir}/obs-plugins/obs-x264.so +%exclude %{_libdir}/obs-modules/core/obs-x264.so %endif %{_libdir}/libobs.so.* %{_libdir}/libobs-frontend-api.so.* @@ -272,10 +274,12 @@ %if %{with split_obs_x264} %exclude %{_datadir}/obs/obs-x264/ %endif +%dir %{_libdir}/obs-modules/plugins/ +%dir %{_datadir}/obs/obs-modules/plugins/ %if %{with split_obs_x264} %files x264 -%{_libdir}/obs-plugins/obs-x264.so +%{_libdir}/obs-modules/core/obs-x264.so %{_datadir}/obs/obs-x264/ %endif
View file
_service
Changed
@@ -1,7 +1,7 @@ <services> <service name="tar_scm" mode="manual"> <param name="versionformat">@PARENT_TAG@</param> - <param name="revision">32.2.2</param> + <param name="revision">33.0.0</param> <param name="url">https://github.com/obsproject/obs-studio.git</param> <param name="versionrewrite-pattern">(\.\d+)-(a-z.*)</param> <param name="versionrewrite-replacement">\1~\2</param>
View file
_servicedata
Changed
@@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/obsproject/obs-studio.git</param> - <param name="changesrevision">ba2f32bdf791005443988a4955e963663e16b1ed</param> + <param name="changesrevision">72e86655715d9a25d69ce446aa4dd44ba58e10d2</param> </service> </servicedata> \ No newline at end of file
View file
obs-studio-32.2.2.tar.xz/cmake/finders/FindMbedTLS.cmake
Deleted
@@ -1,249 +0,0 @@ -#=======================================================================.rst -FindMbedTLS ------------ - -FindModule for MbedTLS and associated libraries - -.. versionchanged:: 3.0 - Updated FindModule to CMake standards - -Components -^^^^^^^^^^ - -.. versionadded:: 1.0 - -This module contains provides several components: - -``mbedcrypto`` -``mbedtls`` -``mbedx509`` - -Import targets exist for each component. - -Imported Targets -^^^^^^^^^^^^^^^^ - -.. versionadded:: 2.0 - -This module defines the :prop_tgt:`IMPORTED` targets: - -``MbedTLS::mbedcrypto`` - Crypto component - -``MbedTLS::mbedtls`` - TLS component - -``MbedTLS::mbedX509`` - X509 component - -Result Variables -^^^^^^^^^^^^^^^^ - -This module sets the following variables: - -``MbedTLS_FOUND`` - True, if all required components and the core library were found. -``MbedTLS_VERSION`` - Detected version of found MbedTLS libraries. - -``MbedTLS_<COMPONENT>_VERSION`` - Detected version of found MbedTLS component library. - -Cache variables -^^^^^^^^^^^^^^^ - -The following cache variables may also be set: - -``MbedTLS_<COMPONENT>_LIBRARY`` - Path to the library component of MbedTLS. -``MbedTLS_<COMPONENT>_INCLUDE_DIR`` - Directory containing ``<COMPONENT>.h``. - -#======================================================================= - -include(FindPackageHandleStandardArgs) - -find_package(PkgConfig QUIET) -if(PKG_CONFIG_FOUND) - pkg_check_modules(PC_MbedTLS QUIET mbedtls mbedcrypto mbedx509) -endif() - -# MbedTLS_set_soname: Set SONAME on imported library targets -macro(MbedTLS_set_soname component) - if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") - execute_process( - COMMAND sh -c "otool -D '${Mbed${component}_LIBRARY}' | grep -v '${Mbed${component}_LIBRARY}'" - OUTPUT_VARIABLE _output - RESULT_VARIABLE _result - ) - - if(_result EQUAL 0 AND _output MATCHES "^@rpath/") - set_property(TARGET MbedTLS::mbed${component} PROPERTY IMPORTED_SONAME "${_output}") - endif() - elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") - execute_process( - COMMAND sh -c "objdump -p '${Mbed${component}_LIBRARY}' | grep SONAME" - OUTPUT_VARIABLE _output - RESULT_VARIABLE _result - ) - - if(_result EQUAL 0) - string(REGEX REPLACE " \t+SONAME \t+(^ \t+)" "\\1" _soname "${_output}") - set_property(TARGET MbedTLS::mbed${component} PROPERTY IMPORTED_SONAME "${_soname}") - unset(_soname) - endif() - endif() - unset(_output) - unset(_result) -endmacro() - -find_path( - MbedTLS_INCLUDE_DIR - NAMES mbedtls/ssl.h - HINTS "${PC_MbedTLS_INCLUDE_DIRS}" - PATHS /usr/include /usr/local/include - DOC "MbedTLS include directory" -) - -if(PC_MbedTLS_VERSION VERSION_GREATER 0) - set(MbedTLS_VERSION ${PC_MbedTLS_VERSION}) -elseif(EXISTS "${MbedTLS_INCLUDE_DIR}/mbedtls/build_info.h") - file( - STRINGS "${MbedTLS_INCLUDE_DIR}/mbedtls/build_info.h" - _VERSION_STRING - REGEX "#define \t+MBEDTLS_VERSION_STRING \t+.+" - ) - string( - REGEX REPLACE - ".*#define \t+MBEDTLS_VERSION_STRING \t+\"(.+)\".*" - "\\1" - MbedTLS_VERSION - "${_VERSION_STRING}" - ) -elseif(EXISTS "${MbedTLS_INCLUDE_DIR}/mbedtls/version.h") - file( - STRINGS "${MbedTLS_INCLUDE_DIR}/mbedtls/version.h" - _VERSION_STRING - REGEX "#define \t+MBEDTLS_VERSION_STRING \t+.+" - ) - string( - REGEX REPLACE - ".*#define \t+MBEDTLS_VERSION_STRING \t+\"(.+)\".*" - "\\1" - MbedTLS_VERSION - "${_VERSION_STRING}" - ) -else() - if(NOT MbedTLS_FIND_QUIETLY) - message(AUTHOR_WARNING "Failed to find MbedTLS version.") - endif() - set(MbedTLS_VERSION 0.0.0) -endif() - -if(MbedTLS_VERSION VERSION_GREATER_EQUAL 3.6.0) - message( - DEPRECATION - "Use of the custom CMake find module for MbedTLS versions >= 3.6.0 is not supported - build errors might occur!" - ) -endif() - -find_library( - Mbedtls_LIBRARY - NAMES libmbedtls mbedtls - HINTS "${PC_MbedTLS_LIBRARY_DIRS}" - PATHS /usr/lib /usr/local/lib - DOC "MbedTLS location" -) - -find_library( - Mbedcrypto_LIBRARY - NAMES libmbedcrypto mbedcrypto - HINTS "${PC_MbedTLS_LIBRARY_DIRS}" - PATHS /usr/lib /usr/local/lib - DOC "MbedCrypto location" -) - -find_library( - Mbedx509_LIBRARY - NAMES libmbedx509 mbedx509 - HINTS "${PC_MbedTLS_LIBRARY_DIRS}" - PATHS /usr/lib /usr/local/lib - DOC "MbedX509 location" -) - -if(Mbedtls_LIBRARY AND NOT Mbedcrypto_LIBRARY AND NOT Mbedx509_LIBRARY) - set(CMAKE_REQUIRED_LIBRARIES "${MbedTLS_LIBRARY}") - set(CMAKE_REQUIRED_INCLUDES "${MbedTLS_INCLUDE_DIR}") - - check_symbol_exists(mbedtls_x509_crt_init "mbedtls/x590_crt.h" MbedTLS_INCLUDES_X509) - check_symbol_exists(mbedtls_sha256_init "mbedtls/sha256.h" MbedTLS_INCLUDES_CRYPTO) - unset(CMAKE_REQUIRED_LIBRARIES) - unset(CMAKE_REQUIRED_INCLUDES) -endif() - -if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows") - set(MbedTLS_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.") -elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") - set(MbedTLS_ERROR_REASON "Ensure that MbedTLS is installed on the system.") -endif() - -if(MbedTLS_INCLUDES_X509 AND MbedTLS_INCLUDES_CRYPTO) - find_package_handle_standard_args( - MbedTLS - REQUIRED_VARS Mbedtls_LIBRARY MbedTLS_INCLUDE_DIR - VERSION_VAR MbedTLS_VERSION - REASON_FAILURE_MESSAGE "${MbedTLS_ERROR_REASON}" - ) - mark_as_advanced(Mbedtls_LIBRARY MbedTLS_INCLUDE_DIR) - list(APPEND _COMPONENTS tls) -else() - find_package_handle_standard_args( - MbedTLS - REQUIRED_VARS Mbedtls_LIBRARY Mbedcrypto_LIBRARY Mbedx509_LIBRARY MbedTLS_INCLUDE_DIR - VERSION_VAR MbedTLS_VERSION - REASON_FAILURE_MESSAGE "${MbedTLS_ERROR_REASON}" - ) - mark_as_advanced(Mbedtls_LIBRARY Mbedcrypto_LIBRARY Mbedx509_LIBRARY MbedTLS_INCLUDE_DIR) - list(APPEND _COMPONENTS tls crypto x509) -endif() -unset(MbedTLS_ERROR_REASON) - -if(MbedTLS_FOUND) - foreach(component IN LISTS _COMPONENTS) - if(NOT TARGET MbedTLS::mbed${component}) - if(IS_ABSOLUTE "${Mbed${component}_LIBRARY}") - add_library(MbedTLS::mbed${component} UNKNOWN IMPORTED) - set_property(TARGET MbedTLS::mbed${component} PROPERTY IMPORTED_LOCATION "${Mbed${component}_LIBRARY}") - else() - add_library(MbedTLS::mbed${component} INTERFACE IMPORTED) - set_property(TARGET MbedTLS::mbed${component} PROPERTY IMPORTED_LIBNAME "${Mbed${component}_LIBRARY}") - endif() - - mbedtls_set_soname(${component}) - set_target_properties( - MbedTLS::mbedtls - PROPERTIES - INTERFACE_COMPILE_OPTIONS "${PC_MbedTLS_CFLAGS_OTHER}" - INTERFACE_INCLUDE_DIRECTORIES "${MbedTLS_INCLUDE_DIR}" - INTERFACE_LINK_OPTIONS "$<$<AND:$<PLATFORM_ID:Windows>,$<CONFIG:DEBUG>>:/NODEFAULTLIB:MSVCRT>" - VERSION ${MbedTLS_VERSION} - ) - endif() - endforeach() - - if(MbedTLS_INCLUDES_X509 AND MbedTLS_INCLUDES_CRYPTO) - set(MbedTLS_LIBRARIES ${MbedTLS_LIBRARY}) - else() - set(MbedTLS_LIBRARIES ${MbedTLS_LIBRARY} ${MbedCrypto_LIBRARY} ${MbedX509_LIBRARY}) - set_property(TARGET MbedTLS::mbedtls PROPERTY INTERFACE_LINK_LIBRARIES MbedTLS::mbedcrypto MbedTLS::mbedx509) - endif() -endif() - -include(FeatureSummary) -set_package_properties( - MbedTLS - PROPERTIES - URL "https://www.trustedfirmware.org/projects/mbed-tls" - DESCRIPTION - "A C library implementing cryptographic primitives, X.509 certificate manipulation, and the SSL/TLS and DTLS protocols." -)
View file
obs-studio-32.2.2.tar.xz/libobs/graphics/libnsgif/libnsgif.c
Deleted
@@ -1,1291 +0,0 @@ -/* - * Copyright 2003 James Bursa <bursa@users.sourceforge.net> - * Copyright 2004 John Tytgat <John.Tytgat@aaug.net> - * Copyright 2004 Richard Wilson <richard.wilson@netsurf-browser.org> - * Copyright 2008 Sean Fox <dyntryx@gmail.com> - * - * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ - * Licenced under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - */ - -//#include <stdbool.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> -#include <stdio.h> -#include "libnsgif.h" - - -#ifdef NDEBUG -# define LOG(x) ((void) 0) -#else -# define LOG(x) do { fprintf(stderr, x), fputc('\n', stderr); } while (0) -#endif /* NDEBUG */ - - - -/* READING GIF FILES - ================= - - The functions provided by this file allow for efficient progressive GIF - decoding. Whilst the initialisation does not ensure that there is - sufficient image data to complete the entire frame, it does ensure that - the information provided is valid. Any subsequent attempts to decode an - initialised GIF are guaranteed to succeed, and any bytes of the image - not present are assumed to be totally transparent. - - To begin decoding a GIF, the 'gif' structure must be initialised with - the 'gif_data' and 'buffer_size' set to their initial values. The - 'buffer_position' should initially be 0, and will be internally updated - as the decoding commences. The caller should then repeatedly call - gif_initialise() with the structure until the function returns 1, or - no more data is available. - - Once the initialisation has begun, the decoder completes the variables - 'frame_count' and 'frame_count_partial'. The former being the total - number of frames that have been successfully initialised, and the - latter being the number of frames that a partial amount of data is - available for. This assists the caller in managing the animation whilst - decoding is continuing. - - To decode a frame, the caller must use gif_decode_frame() which updates - the current 'frame_image' to reflect the desired frame. The required - 'disposal_method' is also updated to reflect how the frame should be - plotted. The caller must not assume that the current 'frame_image' will - be valid between calls if initialisation is still occurring, and should - either always request that the frame is decoded (no processing will - occur if the 'decoded_frame' has not been invalidated by initialisation) - or perform the check itself. - - It should be noted that gif_finalise() should always be called, even if - no frames were initialised. Additionally, it is the responsibility of - the caller to free 'gif_data'. - - rjw - Fri 2nd April 2004 -*/ - -/* TO-DO LIST - ================= - - + Plain text and comment extensions could be implemented if there is any - interest in doing so. -*/ - - - - -/* Maximum colour table size -*/ -#define GIF_MAX_COLOURS 256 - -/* Internal flag that the colour table needs to be processed -*/ -#define GIF_PROCESS_COLOURS 0xaa000000 - -/* Internal flag that a frame is invalid/unprocessed -*/ -#define GIF_INVALID_FRAME -1 - -/* Transparent colour -*/ -#define GIF_TRANSPARENT_COLOUR 0x00 - -/* GIF Flags -*/ -#define GIF_FRAME_COMBINE 1 -#define GIF_FRAME_CLEAR 2 -#define GIF_FRAME_RESTORE 3 -#define GIF_FRAME_QUIRKS_RESTORE 4 -#define GIF_IMAGE_SEPARATOR 0x2c -#define GIF_INTERLACE_MASK 0x40 -#define GIF_COLOUR_TABLE_MASK 0x80 -#define GIF_COLOUR_TABLE_SIZE_MASK 0x07 -#define GIF_EXTENSION_INTRODUCER 0x21 -#define GIF_EXTENSION_GRAPHIC_CONTROL 0xf9 -#define GIF_DISPOSAL_MASK 0x1c -#define GIF_TRANSPARENCY_MASK 0x01 -#define GIF_EXTENSION_COMMENT 0xfe -#define GIF_EXTENSION_PLAIN_TEXT 0x01 -#define GIF_EXTENSION_APPLICATION 0xff -#define GIF_BLOCK_TERMINATOR 0x00 -#define GIF_TRAILER 0x3b - -/* Internal GIF routines -*/ -static gif_result gif_initialise_sprite(gif_animation *gif, unsigned int width, unsigned int height); -static gif_result gif_initialise_frame(gif_animation *gif); -static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int frame); -static gif_result gif_skip_frame_extensions(gif_animation *gif); -static unsigned int gif_interlaced_line(int height, int y); - - - -/* Internal LZW routines -*/ -static void gif_init_LZW(gif_animation *gif); -static bool gif_next_LZW(gif_animation *gif); -static int gif_next_code(gif_animation *gif, int code_size); - -static const int maskTbl16 = {0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, - 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff}; - -/** Initialises necessary gif_animation members. -*/ -void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks) { - memset(gif, 0, sizeof(gif_animation)); - gif->bitmap_callbacks = *bitmap_callbacks; - gif->decoded_frame = GIF_INVALID_FRAME; -} - - -/** Initialises any workspace held by the animation and attempts to decode - any information that hasn't already been decoded. - If an error occurs, all previously decoded frames are retained. - - @return GIF_FRAME_DATA_ERROR for GIF frame data error - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to process - any more frames - GIF_INSUFFICIENT_MEMORY for memory error - GIF_DATA_ERROR for GIF error - GIF_INSUFFICIENT_DATA for insufficient data to do anything - GIF_OK for successful decoding - GIF_WORKING for successful decoding if more frames are expected -*/ -gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data) { - unsigned char *gif_data; - unsigned int index; - gif_result return_value; - - /* The GIF format is thoroughly documented; a full description - * can be found at http://www.w3.org/Graphics/GIF/spec-gif89a.txt - */ - - /* Initialize values - */ - gif->buffer_size = (unsigned int)size; - gif->gif_data = data; - - /* Check for sufficient data to be a GIF (6-byte header + 7-byte logical screen descriptor) - */ - if (gif->buffer_size < 13) return GIF_INSUFFICIENT_DATA; - - /* Get our current processing position - */ - gif_data = gif->gif_data + gif->buffer_position; - - /* See if we should initialise the GIF - */ - if (gif->buffer_position == 0) { - - /* We want everything to be NULL before we start so we've no chance - of freeing bad pointers (paranoia) - */ - gif->frame_image = NULL; - gif->frames = NULL; - gif->local_colour_table = NULL; - gif->global_colour_table = NULL; - - /* The caller may have been lazy and not reset any values - */ - gif->frame_count = 0; - gif->frame_count_partial = 0; - gif->decoded_frame = GIF_INVALID_FRAME; - - /* 6-byte GIF file header is: - * - * +0 3CHARS Signature ('GIF') - * +3 3CHARS Version ('87a' or '89a') - */ - if (strncmp((const char *) gif_data, "GIF", 3) != 0) - return GIF_DATA_ERROR; - gif_data += 3; - - /* Ensure GIF reports version 87a or 89a - */ -/* if ((strncmp(gif_data, "87a", 3) != 0) && - (strncmp(gif_data, "89a", 3) != 0)) - LOG(("Unknown GIF format - proceeding anyway")); -*/ gif_data += 3; - - /* 7-byte Logical Screen Descriptor is: - * - * +0 SHORT Logical Screen Width - * +2 SHORT Logical Screen Height - * +4 CHAR __Packed Fields__ - * 1BIT Global Colour Table Flag - * 3BITS Colour Resolution - * 1BIT Sort Flag - * 3BITS Size of Global Colour Table - * +5 CHAR Background Colour Index - * +6 CHAR Pixel Aspect Ratio - */ - gif->width = gif_data0 | (gif_data1 << 8); - gif->height = gif_data2 | (gif_data3 << 8); - gif->global_colours = (gif_data4 & GIF_COLOUR_TABLE_MASK); - gif->colour_table_size = (2 << (gif_data4 & GIF_COLOUR_TABLE_SIZE_MASK)); - gif->background_index = gif_data5; - gif->aspect_ratio = gif_data6; - gif->loop_count = 1; - gif_data += 7; - - /* Some broken GIFs report the size as the screen size they were created in. As - such, we detect for the common cases and set the sizes as 0 if they are found - which results in the GIF being the maximum size of the frames. - */ - if (((gif->width == 640) && (gif->height == 480)) || - ((gif->width == 640) && (gif->height == 512)) || - ((gif->width == 800) && (gif->height == 600)) || - ((gif->width == 1024) && (gif->height == 768)) || - ((gif->width == 1280) && (gif->height == 1024)) || - ((gif->width == 1600) && (gif->height == 1200)) || - ((gif->width == 0) || (gif->height == 0)) || - ((gif->width > 2048) || (gif->height > 2048))) { - gif->width = 1; - gif->height = 1; - } - - /* Allocate some data irrespective of whether we've got any colour tables. We - always get the maximum size in case a GIF is lying to us. It's far better - to give the wrong colours than to trample over some memory somewhere. - */ - gif->global_colour_table = (unsigned int *)calloc(GIF_MAX_COLOURS, sizeof(int)); - gif->local_colour_table = (unsigned int *)calloc(GIF_MAX_COLOURS, sizeof(int)); - if ((gif->global_colour_table == NULL) || (gif->local_colour_table == NULL)) { - gif_finalise(gif); - return GIF_INSUFFICIENT_MEMORY; - } - - /* Set the first colour to a value that will never occur in reality so we - know if we've processed it - */ - gif->global_colour_table0 = GIF_PROCESS_COLOURS; - - /* Check if the GIF has no frame data (13-byte header + 1-byte termination block) - * Although generally useless, the GIF specification does not expressly prohibit this - */ - if (gif->buffer_size == 14) { - if (gif_data0 == GIF_TRAILER) - return GIF_OK; - else - return GIF_INSUFFICIENT_DATA; - } - - /* Initialise enough workspace for 4 frames initially - */ - if ((gif->frames = (gif_frame *)malloc(sizeof(gif_frame))) == NULL) { - gif_finalise(gif); - return GIF_INSUFFICIENT_MEMORY; - } - gif->frame_holders = 1; - - /* Initialise the sprite header - */ - assert(gif->bitmap_callbacks.bitmap_create); - if ((gif->frame_image = gif->bitmap_callbacks.bitmap_create(gif->width, gif->height)) == NULL) { - gif_finalise(gif); - return GIF_INSUFFICIENT_MEMORY; - } - - /* Remember we've done this now - */ - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data); - } - - /* Do the colour map if we haven't already. As the top byte is always 0xff or 0x00 - depending on the transparency we know if it's been filled in. - */ - if (gif->global_colour_table0 == GIF_PROCESS_COLOURS) { - /* Check for a global colour map signified by bit 7 - */ - if (gif->global_colours) { - if (gif->buffer_size < (gif->colour_table_size * 3 + 12)) { - return GIF_INSUFFICIENT_DATA; - } - for (index = 0; index < gif->colour_table_size; index++) { - /* Gif colour map contents are r,g,b. - * - * We want to pack them bytewise into the - * colour table, such that the red component - * is in byte 0 and the alpha component is in - * byte 3. - */ - unsigned char *entry = (unsigned char *) &gif-> - global_colour_tableindex; - - entry0 = gif_data0; /* r */ - entry1 = gif_data1; /* g */ - entry2 = gif_data2; /* b */ - entry3 = 0xff; /* a */ - - gif_data += 3; - } - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data); - } else { - /* Create a default colour table with the first two colours as black and white - */ - unsigned int *entry = gif->global_colour_table; - - entry0 = 0x00000000; - /* Force Alpha channel to opaque */ - ((unsigned char *) entry)3 = 0xff; - - entry1 = 0xffffffff; - } - } - - /* Repeatedly try to initialise frames - */ - while ((return_value = gif_initialise_frame(gif)) == GIF_WORKING); - - /* If there was a memory error tell the caller - */ - if ((return_value == GIF_INSUFFICIENT_MEMORY) || - (return_value == GIF_DATA_ERROR)) - return return_value; - - /* If we didn't have some frames then a GIF_INSUFFICIENT_DATA becomes a - GIF_INSUFFICIENT_FRAME_DATA - */ - if ((return_value == GIF_INSUFFICIENT_DATA) && (gif->frame_count_partial > 0)) - return GIF_INSUFFICIENT_FRAME_DATA; - - /* Return how many we got - */ - return return_value; -} - - -/** Updates the sprite memory size - - @return GIF_INSUFFICIENT_MEMORY for a memory error - GIF_OK for success -*/ -static gif_result gif_initialise_sprite(gif_animation *gif, unsigned int width, unsigned int height) { - unsigned int max_width; - unsigned int max_height; - struct bitmap *buffer; - - /* Check if we've changed - */ - if ((width <= gif->width) && (height <= gif->height)) - return GIF_OK; - - /* Get our maximum values - */ - max_width = (width > gif->width) ? width : gif->width; - max_height = (height > gif->height) ? height : gif->height; - - /* Allocate some more memory - */ - assert(gif->bitmap_callbacks.bitmap_create); - if ((buffer = gif->bitmap_callbacks.bitmap_create(max_width, max_height)) == NULL) - return GIF_INSUFFICIENT_MEMORY; - assert(gif->bitmap_callbacks.bitmap_destroy); - gif->bitmap_callbacks.bitmap_destroy(gif->frame_image); - gif->frame_image = buffer; - gif->width = max_width; - gif->height = max_height; - - /* Invalidate our currently decoded image - */ - gif->decoded_frame = GIF_INVALID_FRAME; - return GIF_OK; -} - - -/** Attempts to initialise the next frame - - @return GIF_INSUFFICIENT_DATA for insufficient data to do anything - GIF_FRAME_DATA_ERROR for GIF frame data error - GIF_INSUFFICIENT_MEMORY for insufficient memory to process - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame - GIF_DATA_ERROR for GIF error (invalid frame header) - GIF_OK for successful decoding - GIF_WORKING for successful decoding if more frames are expected -*/ -static gif_result gif_initialise_frame(gif_animation *gif) { - int frame; - gif_frame *temp_buf; - - unsigned char *gif_data, *gif_end; - int gif_bytes; - unsigned int flags = 0; - unsigned int width, height, offset_x, offset_y; - unsigned int block_size, colour_table_size; - bool first_image = true; - gif_result return_value; - - /* Get the frame to decode and our data position - */ - frame = gif->frame_count; - - /* Get our buffer position etc. - */ - gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position); - gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size); - gif_bytes = (unsigned int)(gif_end - gif_data); - - /* Check if we've finished - */ - if ((gif_bytes > 0) && (gif_data0 == GIF_TRAILER)) return GIF_OK; - - /* Check if we have enough data - * The shortest block of data is a 4-byte comment extension + 1-byte block terminator + 1-byte gif trailer - */ - if (gif_bytes < 6) return GIF_INSUFFICIENT_DATA; - - /* We could theoretically get some junk data that gives us millions of frames, so - we ensure that we don't have a silly number - */ - if (frame > 4096) return GIF_FRAME_DATA_ERROR; - - /* Get some memory to store our pointers in etc. - */ - if ((int)gif->frame_holders <= frame) { - /* Allocate more memory - */ - if ((temp_buf = (gif_frame *)realloc(gif->frames, - (frame + 1) * sizeof(gif_frame))) == NULL) - return GIF_INSUFFICIENT_MEMORY; - gif->frames = temp_buf; - gif->frame_holders = frame + 1; - } - - /* Store our frame pointer. We would do it when allocating except we - start off with one frame allocated so we can always use realloc. - */ - gif->framesframe.frame_pointer = gif->buffer_position; - gif->framesframe.display = false; - gif->framesframe.virgin = true; - gif->framesframe.disposal_method = 0; - gif->framesframe.transparency = false; - gif->framesframe.frame_delay = 100; - gif->framesframe.redraw_required = false; - - /* Invalidate any previous decoding we have of this frame - */ - if (gif->decoded_frame == frame) - gif->decoded_frame = GIF_INVALID_FRAME; - - /* We pretend to initialise the frames, but really we just skip over all - the data contained within. This is all basically a cut down version of - gif_decode_frame that doesn't have any of the LZW bits in it. - */ - - /* Initialise any extensions - */ - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data); - if ((return_value = gif_initialise_frame_extensions(gif, frame)) != GIF_OK) - return return_value; - gif_data = (gif->gif_data + gif->buffer_position); - gif_bytes = (unsigned int)(gif_end - gif_data); - - /* Check if we've finished - */ - if ((gif_bytes = (unsigned int)(gif_end - gif_data)) < 1) - return GIF_INSUFFICIENT_FRAME_DATA; - else if (gif_data0 == GIF_TRAILER) { - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data); - gif->frame_count = frame + 1; - return GIF_OK; - } - - /* If we're not done, there should be an image descriptor - */ - if (gif_data0 != GIF_IMAGE_SEPARATOR) return GIF_FRAME_DATA_ERROR; - - /* Do some simple boundary checking - */ - offset_x = gif_data1 | (gif_data2 << 8); - offset_y = gif_data3 | (gif_data4 << 8); - width = gif_data5 | (gif_data6 << 8); - height = gif_data7 | (gif_data8 << 8); - - /* Set up the redraw characteristics. We have to check for extending the area - due to multi-image frames. - */ - if (!first_image) { - if (gif->framesframe.redraw_x > offset_x) { - gif->framesframe.redraw_width += (gif->framesframe.redraw_x - offset_x); - gif->framesframe.redraw_x = offset_x; - } - if (gif->framesframe.redraw_y > offset_y) { - gif->framesframe.redraw_height += (gif->framesframe.redraw_y - offset_y); - gif->framesframe.redraw_y = offset_y; - } - if ((offset_x + width) > (gif->framesframe.redraw_x + gif->framesframe.redraw_width)) - gif->framesframe.redraw_width = (offset_x + width) - gif->framesframe.redraw_x; - if ((offset_y + height) > (gif->framesframe.redraw_y + gif->framesframe.redraw_height)) - gif->framesframe.redraw_height = (offset_y + height) - gif->framesframe.redraw_y; - } else { - first_image = false; - gif->framesframe.redraw_x = offset_x; - gif->framesframe.redraw_y = offset_y; - gif->framesframe.redraw_width = width; - gif->framesframe.redraw_height = height; - } - - /* if we are clearing the background then we need to redraw enough to cover the previous - frame too - */ - gif->framesframe.redraw_required = ((gif->framesframe.disposal_method == GIF_FRAME_CLEAR) || - (gif->framesframe.disposal_method == GIF_FRAME_RESTORE)); - - /* Boundary checking - shouldn't ever happen except with junk data - */ - if (gif_initialise_sprite(gif, (offset_x + width), (offset_y + height))) - return GIF_INSUFFICIENT_MEMORY; - - /* Decode the flags - */ - flags = gif_data9; - colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK); - - /* Move our data onwards and remember we've got a bit of this frame - */ - gif_data += 10; - gif_bytes = (unsigned int)(gif_end - gif_data); - gif->frame_count_partial = frame + 1; - - /* Skip the local colour table - */ - if (flags & GIF_COLOUR_TABLE_MASK) { - gif_data += 3 * colour_table_size; - if ((gif_bytes = (unsigned int)(gif_end - gif_data)) < 0) - return GIF_INSUFFICIENT_FRAME_DATA; - } - - /* Ensure we have a correct code size - */ - if (gif_data0 > GIF_MAX_LZW) - return GIF_DATA_ERROR; - - /* Move our pointer to the actual image data - */ - gif_data++; - if (--gif_bytes < 0) - return GIF_INSUFFICIENT_FRAME_DATA; - - /* Repeatedly skip blocks until we get a zero block or run out of data - * These blocks of image data are processed later by gif_decode_frame() - */ - block_size = 0; - while (block_size != 1) { - block_size = gif_data0 + 1; - /* Check if the frame data runs off the end of the file - */ - if ((int)(gif_bytes - block_size) < 0) { - /* Try to recover by signaling the end of the gif. - * Once we get garbage data, there is no logical - * way to determine where the next frame is. - * It's probably better to partially load the gif - * than not at all. - */ - if (gif_bytes >= 2) { - gif_data0 = 0; - gif_data1 = GIF_TRAILER; - gif_bytes = 1; - ++gif_data; - break; - } else - return GIF_INSUFFICIENT_FRAME_DATA; - } else { - gif_bytes -= block_size; - gif_data += block_size; - } - } - - /* Add the frame and set the display flag - */ - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data); - gif->frame_count = frame + 1; - gif->framesframe.display = true; - - /* Check if we've finished - */ - if (gif_bytes < 1) - return GIF_INSUFFICIENT_FRAME_DATA; - else - if (gif_data0 == GIF_TRAILER) return GIF_OK; - return GIF_WORKING; -} - -/** Attempts to initialise the frame's extensions - - @return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame - GIF_OK for successful initialisation -*/ -static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int frame) { - unsigned char *gif_data, *gif_end; - int gif_bytes; - unsigned int block_size; - - /* Get our buffer position etc. - */ - gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position); - gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size); - - /* Initialise the extensions - */ - while (gif_data0 == GIF_EXTENSION_INTRODUCER) { - ++gif_data; - gif_bytes = (unsigned int)(gif_end - gif_data); - - /* Switch on extension label - */ - switch(gif_data0) { - /* 6-byte Graphic Control Extension is: - * - * +0 CHAR Graphic Control Label - * +1 CHAR Block Size - * +2 CHAR __Packed Fields__ - * 3BITS Reserved - * 3BITS Disposal Method - * 1BIT User Input Flag - * 1BIT Transparent Color Flag - * +3 SHORT Delay Time - * +5 CHAR Transparent Color Index - */ - case GIF_EXTENSION_GRAPHIC_CONTROL: - if (gif_bytes < 6) return GIF_INSUFFICIENT_FRAME_DATA; - gif->framesframe.frame_delay = gif_data3 | (gif_data4 << 8); - if (gif_data2 & GIF_TRANSPARENCY_MASK) { - gif->framesframe.transparency = true; - gif->framesframe.transparency_index = gif_data5; - } - gif->framesframe.disposal_method = ((gif_data2 & GIF_DISPOSAL_MASK) >> 2); - /* I have encountered documentation and GIFs in the wild that use - * 0x04 to restore the previous frame, rather than the officially - * documented 0x03. I believe some (older?) software may even actually - * export this way. We handle this as a type of "quirks" mode. - */ - if (gif->framesframe.disposal_method == GIF_FRAME_QUIRKS_RESTORE) - gif->framesframe.disposal_method = GIF_FRAME_RESTORE; - gif_data += (2 + gif_data1); - break; - - /* 14-byte+ Application Extension is: - * - * +0 CHAR Application Extension Label - * +1 CHAR Block Size - * +2 8CHARS Application Identifier - * +10 3CHARS Appl. Authentication Code - * +13 1-256 Application Data (Data sub-blocks) - */ - case GIF_EXTENSION_APPLICATION: - if (gif_bytes < 17) return GIF_INSUFFICIENT_FRAME_DATA; - if ((gif_data1 == 0x0b) && - (strncmp((const char *) gif_data + 2, - "NETSCAPE2.0", 11) == 0) && - (gif_data13 == 0x03) && - (gif_data14 == 0x01)) { - gif->loop_count = gif_data15 | (gif_data16 << 8); - } - gif_data += (2 + gif_data1); - break; - - /* Move the pointer to the first data sub-block - * Skip 1 byte for the extension label - */ - case GIF_EXTENSION_COMMENT: - ++gif_data; - break; - - /* Move the pointer to the first data sub-block - * Skip 2 bytes for the extension label and size fields - * Skip the extension size itself - */ - default: - gif_data += (2 + gif_data1); - } - - /* Repeatedly skip blocks until we get a zero block or run out of data - * This data is ignored by this gif decoder - */ - gif_bytes = (unsigned int)(gif_end - gif_data); - block_size = 0; - while (gif_data0 != GIF_BLOCK_TERMINATOR) { - block_size = gif_data0 + 1; - if ((gif_bytes -= block_size) < 0) - return GIF_INSUFFICIENT_FRAME_DATA; - gif_data += block_size; - } - ++gif_data; - } - - /* Set buffer position and return - */ - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data); - return GIF_OK; -} - - -/** Decodes a GIF frame. - - @return GIF_FRAME_DATA_ERROR for GIF frame data error - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame - GIF_DATA_ERROR for GIF error (invalid frame header) - GIF_INSUFFICIENT_DATA for insufficient data to do anything - GIF_INSUFFICIENT_MEMORY for insufficient memory to process - GIF_OK for successful decoding - If a frame does not contain any image data, GIF_OK is returned and - gif->current_error is set to GIF_FRAME_NO_DISPLAY -*/ -gif_result gif_decode_frame(gif_animation *gif, unsigned int frame) { - unsigned int index = 0; - unsigned char *gif_data, *gif_end; - int gif_bytes; - unsigned int width, height, offset_x, offset_y; - unsigned int flags, colour_table_size, interlace; - unsigned int *colour_table; - unsigned int *frame_data = 0; // Set to 0 for no warnings - unsigned int *frame_scanline; - unsigned int save_buffer_position; - gif_result return_value = GIF_OK; - unsigned int x, y, decode_y, burst_bytes; - int last_undisposed_frame = (frame - 1); - register unsigned char colour; - - /* Ensure we have a frame to decode - */ - if (frame >= gif->frame_count_partial) - return GIF_INSUFFICIENT_DATA; - - /* Ensure this frame is supposed to be decoded - */ - if (gif->framesframe.display == false) { - gif->current_error = GIF_FRAME_NO_DISPLAY; - return GIF_OK; - } - - if ((!gif->clear_image) && ((int)frame == gif->decoded_frame)) - return GIF_OK; - - /* Get the start of our frame data and the end of the GIF data - */ - gif_data = gif->gif_data + gif->framesframe.frame_pointer; - gif_end = gif->gif_data + gif->buffer_size; - gif_bytes = (unsigned int)(gif_end - gif_data); - - /* Check if we have enough data - * The shortest block of data is a 10-byte image descriptor + 1-byte gif trailer - */ - if (gif_bytes < 12) return GIF_INSUFFICIENT_FRAME_DATA; - - /* Save the buffer position - */ - save_buffer_position = gif->buffer_position; - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data); - - /* Skip any extensions because we all ready processed them - */ - if ((return_value = gif_skip_frame_extensions(gif)) != GIF_OK) - goto gif_decode_frame_exit; - gif_data = (gif->gif_data + gif->buffer_position); - gif_bytes = (unsigned int)(gif_end - gif_data); - - /* Ensure we have enough data for the 10-byte image descriptor + 1-byte gif trailer - */ - if (gif_bytes < 12) { - return_value = GIF_INSUFFICIENT_FRAME_DATA; - goto gif_decode_frame_exit; - } - - /* 10-byte Image Descriptor is: - * - * +0 CHAR Image Separator (0x2c) - * +1 SHORT Image Left Position - * +3 SHORT Image Top Position - * +5 SHORT Width - * +7 SHORT Height - * +9 CHAR __Packed Fields__ - * 1BIT Local Colour Table Flag - * 1BIT Interlace Flag - * 1BIT Sort Flag - * 2BITS Reserved - * 3BITS Size of Local Colour Table - */ - if (gif_data0 != GIF_IMAGE_SEPARATOR) { - return_value = GIF_DATA_ERROR; - goto gif_decode_frame_exit; - } - offset_x = gif_data1 | (gif_data2 << 8); - offset_y = gif_data3 | (gif_data4 << 8); - width = gif_data5 | (gif_data6 << 8); - height = gif_data7 | (gif_data8 << 8); - - /* Boundary checking - shouldn't ever happen except unless the data has been - modified since initialisation. - */ - if ((offset_x + width > gif->width) || (offset_y + height > gif->height)) { - return_value = GIF_DATA_ERROR; - goto gif_decode_frame_exit; - } - - /* Decode the flags - */ - flags = gif_data9; - colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK); - interlace = flags & GIF_INTERLACE_MASK; - - /* Move our pointer to the colour table or image data (if no colour table is given) - */ - gif_data += 10; - gif_bytes = (unsigned int)(gif_end - gif_data); - - /* Set up the colour table - */ - if (flags & GIF_COLOUR_TABLE_MASK) { - if (gif_bytes < (int)(3 * colour_table_size)) { - return_value = GIF_INSUFFICIENT_FRAME_DATA; - goto gif_decode_frame_exit; - } - colour_table = gif->local_colour_table; - if (!gif->clear_image) { - for (index = 0; index < colour_table_size; index++) { - /* Gif colour map contents are r,g,b. - * - * We want to pack them bytewise into the - * colour table, such that the red component - * is in byte 0 and the alpha component is in - * byte 3. - */ - unsigned char *entry = - (unsigned char *) &colour_tableindex; - - entry0 = gif_data0; /* r */ - entry1 = gif_data1; /* g */ - entry2 = gif_data2; /* b */ - entry3 = 0xff; /* a */ - - gif_data += 3; - } - } else { - gif_data += 3 * colour_table_size; - } - gif_bytes = (unsigned int)(gif_end - gif_data); - } else { - colour_table = gif->global_colour_table; - } - - /* Check if we've finished - */ - if (gif_bytes < 1) { - return_value = GIF_INSUFFICIENT_FRAME_DATA; - goto gif_decode_frame_exit; - } else if (gif_data0 == GIF_TRAILER) { - return_value = GIF_OK; - goto gif_decode_frame_exit; - } - - /* Get the frame data - */ - assert(gif->bitmap_callbacks.bitmap_get_buffer); - frame_data = (void *)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image); - if (!frame_data) - return GIF_INSUFFICIENT_MEMORY; - - /* If we are clearing the image we just clear, if not decode - */ - if (!gif->clear_image) { - /* Ensure we have enough data for a 1-byte LZW code size + 1-byte gif trailer - */ - if (gif_bytes < 2) { - return_value = GIF_INSUFFICIENT_FRAME_DATA; - goto gif_decode_frame_exit; - /* If we only have a 1-byte LZW code size + 1-byte gif trailer, we're finished - */ - } else if ((gif_bytes == 2) && (gif_data1 == GIF_TRAILER)) { - return_value = GIF_OK; - goto gif_decode_frame_exit; - } - - /* If the previous frame's disposal method requires we restore the background - * colour or this is the first frame, clear the frame data - */ - if ((frame == 0) || (gif->decoded_frame == GIF_INVALID_FRAME)) { - memset((char*)frame_data, GIF_TRANSPARENT_COLOUR, gif->width * gif->height * sizeof(int)); - gif->decoded_frame = frame; - /* The line below would fill the image with its background color, but because GIFs support - * transparency we likely wouldn't want to do that. */ - /* memset((char*)frame_data, colour_tablegif->background_index, gif->width * gif->height * sizeof(int)); */ - } else if ((frame != 0) && (gif->framesframe - 1.disposal_method == GIF_FRAME_CLEAR)) { - gif->clear_image = true; - if ((return_value = gif_decode_frame(gif, (frame - 1))) != GIF_OK) - goto gif_decode_frame_exit; - gif->clear_image = false; - /* If the previous frame's disposal method requires we restore the previous - * image, find the last image set to "do not dispose" and get that frame data - */ - } else if ((frame != 0) && (gif->framesframe - 1.disposal_method == GIF_FRAME_RESTORE)) { - while ((last_undisposed_frame != -1) && (gif->frameslast_undisposed_frame--.disposal_method == GIF_FRAME_RESTORE)) { - } - /* If we don't find one, clear the frame data - */ - if (last_undisposed_frame == -1) { - /* see notes above on transparency vs. background color */ - memset((char*)frame_data, GIF_TRANSPARENT_COLOUR, gif->width * gif->height * sizeof(int)); - } else { - if ((return_value = gif_decode_frame(gif, last_undisposed_frame)) != GIF_OK) - goto gif_decode_frame_exit; - /* Get this frame's data - */ - assert(gif->bitmap_callbacks.bitmap_get_buffer); - frame_data = (void *)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image); - if (!frame_data) - return GIF_INSUFFICIENT_MEMORY; - } - } - gif->decoded_frame = frame; - - /* Initialise the LZW decoding - */ - gif->set_code_size = gif_data0; - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data + 1); - - /* Set our code variables - */ - gif->code_size = gif->set_code_size + 1; - gif->clear_code = (1 << gif->set_code_size); - gif->end_code = gif->clear_code + 1; - gif->max_code_size = gif->clear_code << 1; - gif->max_code = gif->clear_code + 2; - gif->curbit = gif->lastbit = 0; - gif->last_byte = 2; - gif->get_done = false; - gif->direct = gif->buf; - gif_init_LZW(gif); - - /* Decompress the data - */ - for (y = 0; y < height; y++) { - if (interlace) - decode_y = gif_interlaced_line(height, y) + offset_y; - else - decode_y = y + offset_y; - frame_scanline = frame_data + offset_x + (decode_y * gif->width); - - /* Rather than decoding pixel by pixel, we try to burst out streams - of data to remove the need for end-of data checks every pixel. - */ - x = width; - while (x > 0) { - burst_bytes = (unsigned int)(gif->stack_pointer - gif->stack); - if (burst_bytes > 0) { - if (burst_bytes > x) - burst_bytes = x; - x -= burst_bytes; - while (burst_bytes-- > 0) { - colour = *--gif->stack_pointer; - if (((gif->framesframe.transparency) && - (colour != gif->framesframe.transparency_index)) || - (!gif->framesframe.transparency)) - *frame_scanline = colour_tablecolour; - frame_scanline++; - } - } else { - if (!gif_next_LZW(gif)) { - /* Unexpected end of frame, try to recover - */ - if (gif->current_error == GIF_END_OF_FRAME) - return_value = GIF_OK; - else - return_value = gif->current_error; - goto gif_decode_frame_exit; - } - } - } - } - } else { - /* Clear our frame - */ - if (gif->framesframe.disposal_method == GIF_FRAME_CLEAR) { - for (y = 0; y < height; y++) { - frame_scanline = frame_data + offset_x + ((offset_y + y) * gif->width); - if (gif->framesframe.transparency) - memset(frame_scanline, GIF_TRANSPARENT_COLOUR, width * 4); - else - memset(frame_scanline, colour_tablegif->background_index, width * 4); - } - } - } -gif_decode_frame_exit: - - /* Check if we should test for optimisation - */ - if (gif->framesframe.virgin) { - if (gif->bitmap_callbacks.bitmap_test_opaque) - gif->framesframe.opaque = gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image); - else - gif->framesframe.opaque = false; - gif->framesframe.virgin = false; - } - if (gif->bitmap_callbacks.bitmap_set_opaque) - gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, gif->framesframe.opaque); - if (gif->bitmap_callbacks.bitmap_modified) - gif->bitmap_callbacks.bitmap_modified(gif->frame_image); - - /* Restore the buffer position - */ - gif->buffer_position = save_buffer_position; - - /* Success! - */ - return return_value; - -} - -/** Skips the frame's extensions (which have been previously initialised) - - @return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame - GIF_OK for successful decoding -*/ -static gif_result gif_skip_frame_extensions(gif_animation *gif) { - unsigned char *gif_data, *gif_end; - int gif_bytes; - unsigned int block_size; - - /* Get our buffer position etc. - */ - gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position); - gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size); - gif_bytes = (unsigned int)(gif_end - gif_data); - - /* Skip the extensions - */ - while (gif_data0 == GIF_EXTENSION_INTRODUCER) { - ++gif_data; - - /* Switch on extension label - */ - switch(gif_data0) { - /* Move the pointer to the first data sub-block - * 1 byte for the extension label - */ - case GIF_EXTENSION_COMMENT: - ++gif_data; - break; - - /* Move the pointer to the first data sub-block - * 2 bytes for the extension label and size fields - * Skip the extension size itself - */ - default: - gif_data += (2 + gif_data1); - } - - /* Repeatedly skip blocks until we get a zero block or run out of data - * This data is ignored by this gif decoder - */ - gif_bytes = (unsigned int)(gif_end - gif_data); - block_size = 0; - while (gif_data0 != GIF_BLOCK_TERMINATOR) { - block_size = gif_data0 + 1; - if ((gif_bytes -= block_size) < 0) - return GIF_INSUFFICIENT_FRAME_DATA; - gif_data += block_size; - } - ++gif_data; - } - - /* Set buffer position and return - */ - gif->buffer_position = (unsigned int)(gif_data - gif->gif_data); - return GIF_OK; -} - -static unsigned int gif_interlaced_line(int height, int y) { - if ((y << 3) < height) return (y << 3); - y -= ((height + 7) >> 3); - if ((y << 3) < (height - 4)) return (y << 3) + 4; - y -= ((height + 3) >> 3); - if ((y << 2) < (height - 2)) return (y << 2) + 2; - y -= ((height + 1) >> 2); - return (y << 1) + 1; -} - -/* Releases any workspace held by the animation -*/ -void gif_finalise(gif_animation *gif) { - /* Release all our memory blocks - */ - if (gif->frame_image) { - assert(gif->bitmap_callbacks.bitmap_destroy); - gif->bitmap_callbacks.bitmap_destroy(gif->frame_image); - } - gif->frame_image = NULL; - free(gif->frames); - gif->frames = NULL; - free(gif->local_colour_table); - gif->local_colour_table = NULL; - free(gif->global_colour_table); - gif->global_colour_table = NULL; -} - -/** - * Initialise LZW decoding - */ -void gif_init_LZW(gif_animation *gif) { - int i; - - gif->current_error = 0; - if (gif->clear_code >= (1 << GIF_MAX_LZW)) { - gif->stack_pointer = gif->stack; - gif->current_error = GIF_FRAME_DATA_ERROR; - return; - } - - /* initialise our table */ - memset(gif->table, 0x00, (1 << GIF_MAX_LZW) * 8); - for (i = 0; i < gif->clear_code; ++i) - gif->table1i = i; - - /* update our LZW parameters */ - gif->code_size = gif->set_code_size + 1; - gif->max_code_size = gif->clear_code << 1; - gif->max_code = gif->clear_code + 2; - gif->stack_pointer = gif->stack; - do { - gif->firstcode = gif->oldcode = gif_next_code(gif, gif->code_size); - } while (gif->firstcode == gif->clear_code); - *gif->stack_pointer++ =gif->firstcode; -} - - -static bool gif_next_LZW(gif_animation *gif) { - int code, incode; - int block_size; - int new_code; - - code = gif_next_code(gif, gif->code_size); - if (code < 0) { - gif->current_error = code; - return false; - } else if (code == gif->clear_code) { - gif_init_LZW(gif); - return true; - } else if (code == gif->end_code) { - /* skip to the end of our data so multi-image GIFs work */ - if (gif->zero_data_block) { - gif->current_error = GIF_FRAME_DATA_ERROR; - return false; - } - block_size = 0; - while (block_size != 1) { - block_size = gif->gif_datagif->buffer_position + 1; - gif->buffer_position += block_size; - } - gif->current_error = GIF_FRAME_DATA_ERROR; - return false; - } - - incode = code; - if (code >= gif->max_code) { - if (gif->stack_pointer >= gif->stack + ((1 << GIF_MAX_LZW) * 2)) { - gif->current_error = GIF_FRAME_DATA_ERROR; - return false; - } - *gif->stack_pointer++ = gif->firstcode; - code = gif->oldcode; - } - - /* The following loop is the most important in the GIF decoding cycle as every - * single pixel passes through it. - * - * Note: our gif->stack is always big enough to hold a complete decompressed chunk. */ - while (code >= gif->clear_code) { - if (gif->stack_pointer >= gif->stack + ((1 << GIF_MAX_LZW) * 2)) { - gif->current_error = GIF_FRAME_DATA_ERROR; - return false; - } - *gif->stack_pointer++ = gif->table1code; - new_code = gif->table0code; - if (new_code < gif->clear_code) { - code = new_code; - break; - } - - if (gif->stack_pointer >= gif->stack + ((1 << GIF_MAX_LZW) * 2)) { - gif->current_error = GIF_FRAME_DATA_ERROR; - return false; - } - *gif->stack_pointer++ = gif->table1new_code; - code = gif->table0new_code; - if (code == new_code) { - gif->current_error = GIF_FRAME_DATA_ERROR; - return false; - } - } - - if (gif->stack_pointer >= gif->stack + ((1 << GIF_MAX_LZW) * 2)) { - gif->current_error = GIF_FRAME_DATA_ERROR; - return false; - } - *gif->stack_pointer++ = gif->firstcode = gif->table1code; - - if ((code = gif->max_code) < (1 << GIF_MAX_LZW)) { - gif->table0code = gif->oldcode; - gif->table1code = gif->firstcode; - ++gif->max_code; - if ((gif->max_code >= gif->max_code_size) && (gif->max_code_size < (1 << GIF_MAX_LZW))) { - gif->max_code_size = gif->max_code_size << 1; - ++gif->code_size; - } - } - gif->oldcode = incode; - return true; -} - -static int gif_next_code(gif_animation *gif, int code_size) { - int i, j, end, count, ret; - unsigned char *b; - - (void)code_size; - - end = gif->curbit + gif->code_size; - if (end >= gif->lastbit) { - if (gif->get_done) - return GIF_END_OF_FRAME; - gif->buf0 = gif->directgif->last_byte - 2; - gif->buf1 = gif->directgif->last_byte - 1; - - /* get the next block */ - gif->direct = gif->gif_data + gif->buffer_position; - gif->zero_data_block = ((count = gif->direct0) == 0); - if ((gif->buffer_position + count) >= gif->buffer_size) - return GIF_INSUFFICIENT_FRAME_DATA; - if (count == 0) - gif->get_done = true; - else { - gif->direct -= 1; - gif->buf2 = gif->direct2; - gif->buf3 = gif->direct3; - } - gif->buffer_position += count + 1; - - /* update our variables */ - gif->last_byte = 2 + count; - gif->curbit = (gif->curbit - gif->lastbit) + 16; - gif->lastbit = (2 + count) << 3; - end = gif->curbit + gif->code_size; - } - - i = gif->curbit >> 3; - if (i < 2) - b = gif->buf; - else - b = gif->direct; - - ret = bi; - j = (end >> 3) - 1; - if (i <= j) { - ret |= (bi + 1 << 8); - if (i < j) - ret |= (bi + 2 << 16); - } - ret = (ret >> (gif->curbit % 8)) & maskTblgif->code_size; - gif->curbit += gif->code_size; - return ret; -}
View file
obs-studio-32.2.2.tar.xz/libobs/graphics/libnsgif/libnsgif.h
Deleted
@@ -1,142 +0,0 @@ -/* - * Copyright 2004 Richard Wilson <richard.wilson@netsurf-browser.org> - * Copyright 2008 Sean Fox <dyntryx@gmail.com> - * - * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ - * Licenced under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - */ - -/** \file - * Progressive animated GIF file decoding (interface). - */ - -#ifndef _LIBNSGIF_H_ -#define _LIBNSGIF_H_ - -#include <stdbool.h> -#include <inttypes.h> - -#if defined(__cplusplus) -extern "C" -{ -#endif -/* Error return values -*/ -typedef enum { - GIF_WORKING = 1, - GIF_OK = 0, - GIF_INSUFFICIENT_FRAME_DATA = -1, - GIF_FRAME_DATA_ERROR = -2, - GIF_INSUFFICIENT_DATA = -3, - GIF_DATA_ERROR = -4, - GIF_INSUFFICIENT_MEMORY = -5, - GIF_FRAME_NO_DISPLAY = -6, - GIF_END_OF_FRAME = -7 -} gif_result; - -/* Maximum LZW bits available -*/ -#define GIF_MAX_LZW 12 - -/* The GIF frame data -*/ -typedef struct gif_frame { - bool display; /**< whether the frame should be displayed/animated */ - unsigned int frame_delay; /**< delay (in 100th second intervals) before animating the frame */ - /** Internal members are listed below - */ - unsigned int frame_pointer; /**< offset (in bytes) to the GIF frame data */ - bool virgin; /**< whether the frame has previously been used */ - bool opaque; /**< whether the frame is totally opaque */ - bool redraw_required; /**< whether a forcable screen redraw is required */ - unsigned char disposal_method; /**< how the previous frame should be disposed; affects plotting */ - bool transparency; /**< whether we acknowledge transparency */ - unsigned char transparency_index; /**< the index designating a transparent pixel */ - unsigned int redraw_x; /**< x co-ordinate of redraw rectangle */ - unsigned int redraw_y; /**< y co-ordinate of redraw rectangle */ - unsigned int redraw_width; /**< width of redraw rectangle */ - unsigned int redraw_height; /**< height of redraw rectangle */ -} gif_frame; - -/* API for Bitmap callbacks -*/ -typedef void* (*gif_bitmap_cb_create)(int width, int height); -typedef void (*gif_bitmap_cb_destroy)(void *bitmap); -typedef unsigned char* (*gif_bitmap_cb_get_buffer)(void *bitmap); -typedef void (*gif_bitmap_cb_set_opaque)(void *bitmap, bool opaque); -typedef bool (*gif_bitmap_cb_test_opaque)(void *bitmap); -typedef void (*gif_bitmap_cb_modified)(void *bitmap); - -/* The Bitmap callbacks function table -*/ -typedef struct gif_bitmap_callback_vt { - gif_bitmap_cb_create bitmap_create; /**< Create a bitmap. */ - gif_bitmap_cb_destroy bitmap_destroy; /**< Free a bitmap. */ - gif_bitmap_cb_get_buffer bitmap_get_buffer; /**< Return a pointer to the pixel data in a bitmap. */ - /** Members below are optional - */ - gif_bitmap_cb_set_opaque bitmap_set_opaque; /**< Sets whether a bitmap should be plotted opaque. */ - gif_bitmap_cb_test_opaque bitmap_test_opaque; /**< Tests whether a bitmap has an opaque alpha channel. */ - gif_bitmap_cb_modified bitmap_modified; /**< The bitmap image has changed, so flush any persistent cache. */ -} gif_bitmap_callback_vt; - -/* The GIF animation data -*/ -typedef struct gif_animation { - gif_bitmap_callback_vt bitmap_callbacks; /**< callbacks for bitmap functions */ - unsigned char *gif_data; /**< pointer to GIF data */ - unsigned int width; /**< width of GIF (may increase during decoding) */ - unsigned int height; /**< height of GIF (may increase during decoding) */ - unsigned int frame_count; /**< number of frames decoded */ - unsigned int frame_count_partial; /**< number of frames partially decoded */ - gif_frame *frames; /**< decoded frames */ - int decoded_frame; /**< current frame decoded to bitmap */ - void *frame_image; /**< currently decoded image; stored as bitmap from bitmap_create callback */ - int loop_count; /**< number of times to loop animation */ - gif_result current_error; /**< current error type, or 0 for none*/ - /** Internal members are listed below - */ - unsigned int buffer_position; /**< current index into GIF data */ - unsigned int buffer_size; /**< total number of bytes of GIF data available */ - unsigned int frame_holders; /**< current number of frame holders */ - unsigned int background_index; /**< index in the colour table for the background colour */ - unsigned int aspect_ratio; /**< image aspect ratio (ignored) */ - unsigned int colour_table_size; /**< size of colour table (in entries) */ - bool global_colours; /**< whether the GIF has a global colour table */ - unsigned int *global_colour_table; /**< global colour table */ - unsigned int *local_colour_table; /**< local colour table */ - - - /* General LZW values. They are NO LONGER shared for all GIFs being decoded BECAUSE - THAT IS A TERRIBLE IDEA TO SAVE 10Kb or so per GIF. - */ - unsigned char buf4; - unsigned char *direct; - - int table2(1 << GIF_MAX_LZW); - unsigned char stack(1 << GIF_MAX_LZW) * 2; - unsigned char *stack_pointer; - int code_size, set_code_size; - int max_code, max_code_size; - int clear_code, end_code; - int curbit, lastbit, last_byte; - int firstcode, oldcode; - bool zero_data_block; - bool get_done; - - /* Whether to clear the decoded image rather than plot - */ - bool clear_image; -} gif_animation; - -void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks); -gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data); -gif_result gif_decode_frame(gif_animation *gif, unsigned int frame); -void gif_finalise(gif_animation *gif); - -#if defined(__cplusplus) -}; -#endif - -#endif
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/cmake/macos/Info-helper.plist.in
Deleted
@@ -1,37 +0,0 @@ -<?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>CFBundleDisplayName</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>com.obsproject.obs-studio.helper${BUNDLE_ID_SUFFIX}</string> - <key>CFBundleVersion</key> - <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> - <key>CFBundleShortVersionString</key> - <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>LSEnvironment</key> - <dict> - <key>MallocNanoZone</key> - <string>0</string> - </dict> - <key>LSFileQuarantineEnabled</key> - <true/> - <key>LSMinimumSystemVersion</key> - <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string> - <key>LSUIElement</key> - <string>1</string> - <key>NSSupportsAutomaticGraphicsSwitching</key> - <true/> - <key>NSHumanReadableCopyright</key> - <string>(c) 2012-${CURRENT_YEAR} Lain Bailey</string> -</dict> -</plist>
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/cmake/macos/Info.plist.in
Deleted
@@ -1,28 +0,0 @@ -<?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>obs-browser</string> - <key>CFBundleIdentifier</key> - <string>com.obsproject.obs-browser</string> - <key>CFBundleVersion</key> - <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> - <key>CFBundleShortVersionString</key> - <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleExecutable</key> - <string>obs-browser</string> - <key>CFBundlePackageType</key> - <string>BNDL</string> - <key>CFBundleSupportedPlatforms</key> - <array> - <string>MacOSX</string> - </array> - <key>LSMinimumSystemVersion</key> - <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string> - <key>NSHumanReadableCopyright</key> - <string>(c) 2012-${CURRENT_YEAR} Lain Bailey</string> -</dict> -</plist>
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/helper-info.plist
Deleted
@@ -1,33 +0,0 @@ -<?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>CFBundleDisplayName</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>com.obsproject.obs-studio.helper${BUNDLE_ID_SUFFIX}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>LSEnvironment</key> - <dict> - <key>MallocNanoZone</key> - <string>0</string> - </dict> - <key>LSFileQuarantineEnabled</key> - <true/> - <key>LSMinimumSystemVersion</key> - <string>${MINIMUM_VERSION}</string> - <key>LSUIElement</key> - <string>1</string> - <key>NSSupportsAutomaticGraphicsSwitching</key> - <true/> - <key>NSHumanReadableCopyright</key> - <string>(c) 2012-${CURRENT_YEAR} Lain Bailey</string> -</dict> -</plist>
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/components/DoubleSpinBox.cpp
Deleted
@@ -1,49 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -******************************************************************************/ - -#include <Idian/DoubleSpinBox.hpp> - -#include <Idian/moc_DoubleSpinBox.cpp> - -using idian::DoubleSpinBox; - -DoubleSpinBox::DoubleSpinBox(QWidget *parent) : QFrame(parent) -{ - layout = new QHBoxLayout(); - setLayout(layout); - - layout->setContentsMargins(0, 0, 0, 0); - - decr = new QPushButton("-"); - decr->setObjectName("obsSpinBoxButton"); - layout->addWidget(decr); - - setFocusProxy(decr); - - sbox = new QDoubleSpinBox(); - sbox->setObjectName("obsSpinBox"); - sbox->setButtonSymbols(QAbstractSpinBox::NoButtons); - sbox->setAlignment(Qt::AlignCenter); - layout->addWidget(sbox); - - incr = new QPushButton("+"); - incr->setObjectName("obsSpinBoxButton"); - layout->addWidget(incr); - - connect(decr, &QPushButton::pressed, sbox, &QDoubleSpinBox::stepDown); - connect(incr, &QPushButton::pressed, sbox, &QDoubleSpinBox::stepUp); -}
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/components/SpinBox.cpp
Deleted
@@ -1,46 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -******************************************************************************/ - -#include <Idian/SpinBox.hpp> - -#include <Idian/moc_SpinBox.cpp> - -using idian::SpinBox; - -SpinBox::SpinBox(QWidget *parent) : QFrame(parent) -{ - layout = new QHBoxLayout(); - setLayout(layout); - - layout->setContentsMargins(0, 0, 0, 0); - - decr = new QPushButton("-"); - decr->setObjectName("obsSpinBoxButton"); - layout->addWidget(decr); - - sbox = new QSpinBox(); - sbox->setObjectName("obsSpinBox"); - sbox->setButtonSymbols(QAbstractSpinBox::NoButtons); - layout->addWidget(sbox); - - incr = new QPushButton("+"); - incr->setObjectName("obsSpinBoxButton"); - layout->addWidget(incr); - - connect(decr, &QPushButton::pressed, sbox, &QSpinBox::stepDown); - connect(incr, &QPushButton::pressed, sbox, &QSpinBox::stepUp); -}
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/DoubleSpinBox.hpp
Deleted
@@ -1,42 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -******************************************************************************/ - -#pragma once - -#include <QFrame> -#include <QLayout> -#include <QPushButton> -#include <QSpinBox> - -namespace idian { - -class DoubleSpinBox : public QFrame { - Q_OBJECT; - -public: - DoubleSpinBox(QWidget *parent = nullptr); - - QDoubleSpinBox *spinBox() const { return sbox; } - -private: - QHBoxLayout *layout; - QPushButton *decr; - QPushButton *incr; - QDoubleSpinBox *sbox; -}; - -} // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/Group.hpp
Deleted
@@ -1,71 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -******************************************************************************/ - -#pragma once - -#include <Idian/PropertiesList.hpp> -#include <Idian/Row.hpp> -#include <Idian/ToggleSwitch.hpp> - -#include <QLabel> -#include <QLayout> -#include <QMouseEvent> -#include <QWidget> - -namespace idian { - -class Group : public QFrame, public Utils { - Q_OBJECT - -public: - Group(QWidget *parent = nullptr); - - PropertiesList *properties() const { return propertyList; } - - void addRow(GenericRow *row) const; - - void setTitle(QString name); - void setDescription(QString desc); - - void showTitle(bool visible); - void showDescription(bool visible); - - void setCheckable(bool check); - bool isCheckable() { return checkable; } - -private: - QVBoxLayout *layout = nullptr; - - QWidget *headerContainer = nullptr; - QHBoxLayout *headerLayout = nullptr; - QWidget *labelContainer = nullptr; - QVBoxLayout *labelLayout = nullptr; - QWidget *controlContainer = nullptr; - QVBoxLayout *controlLayout = nullptr; - - QWidget *contentsContainer = nullptr; - QVBoxLayout *contentsLayout = nullptr; - - QLabel *nameLabel = nullptr; - QLabel *descriptionLabel = nullptr; - - PropertiesList *propertyList = nullptr; - - ToggleSwitch *toggleSwitch = nullptr; - bool checkable = false; -}; -} // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/PropertiesList.hpp
Deleted
@@ -1,57 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -******************************************************************************/ - -#pragma once - -#include <Idian/Utils.hpp> - -#include <QFrame> -#include <QLayout> -#include <QWidget> - -namespace idian { -class GenericRow; - -class PropertiesList : public QFrame { - Q_OBJECT - -public: - PropertiesList(QWidget *parent = nullptr); - - void addRow(GenericRow *row); - void clear(); - - QList<GenericRow *> rows() const { return rowsList; } - -private: - GenericRow *first = nullptr; - GenericRow *last = nullptr; - - QVBoxLayout *layout; - QList<GenericRow *> rowsList; -}; - -// Spacer with only cosmetic functionality -class PropertiesListSpacer : public QFrame { - Q_OBJECT -public: - PropertiesListSpacer(QWidget *parent = nullptr) : QFrame(parent) - { - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - } -}; -} // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/SpinBox.hpp
Deleted
@@ -1,42 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -******************************************************************************/ - -#pragma once - -#include <QFrame> -#include <QLayout> -#include <QPushButton> -#include <QSpinBox> - -namespace idian { - -class SpinBox : public QFrame { - Q_OBJECT; - -public: - SpinBox(QWidget *parent = nullptr); - - QSpinBox *spinBox() const { return sbox; } - -private: - QHBoxLayout *layout; - QPushButton *decr; - QPushButton *incr; - QSpinBox *sbox; -}; - -} // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/widgets/Group.cpp
Deleted
@@ -1,126 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -******************************************************************************/ - -#include <Idian/Group.hpp> - -#include <Idian/Utils.hpp> - -#include <Idian/moc_Group.cpp> - -using idian::Group; - -Group::Group(QWidget *parent) : QFrame(parent), Utils(this) -{ - layout = new QVBoxLayout(this); - layout->setSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - - headerContainer = new QWidget(); - headerLayout = new QHBoxLayout(); - headerLayout->setSpacing(0); - headerLayout->setContentsMargins(0, 0, 0, 0); - headerContainer->setLayout(headerLayout); - Utils::addClass(headerContainer, "header"); - - labelContainer = new QWidget(); - labelLayout = new QVBoxLayout(); - labelLayout->setSpacing(0); - labelLayout->setContentsMargins(0, 0, 0, 0); - labelContainer->setLayout(labelLayout); - labelContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); - - controlContainer = new QWidget(); - controlLayout = new QVBoxLayout(); - controlLayout->setSpacing(0); - controlLayout->setContentsMargins(0, 0, 0, 0); - controlContainer->setLayout(controlLayout); - - headerLayout->addWidget(labelContainer); - headerLayout->addWidget(controlContainer); - - contentsContainer = new QWidget(); - contentsLayout = new QVBoxLayout(); - contentsLayout->setSpacing(0); - contentsLayout->setContentsMargins(0, 0, 0, 0); - contentsContainer->setLayout(contentsLayout); - Utils::addClass(contentsContainer, "contents"); - - layout->addWidget(headerContainer); - layout->addWidget(contentsContainer); - - propertyList = new PropertiesList(this); - - setLayout(layout); - - contentsLayout->addWidget(propertyList); - - nameLabel = new QLabel(); - Utils::addClass(nameLabel, "title"); - nameLabel->setVisible(false); - labelLayout->addWidget(nameLabel); - - descriptionLabel = new QLabel(); - Utils::addClass(descriptionLabel, "description"); - descriptionLabel->setVisible(false); - labelLayout->addWidget(descriptionLabel); -} - -void Group::addRow(GenericRow *row) const -{ - propertyList->addRow(row); -} - -void Group::setTitle(QString name) -{ - nameLabel->setText(name); - setAccessibleName(name); - showTitle(true); -} - -void Group::setDescription(QString desc) -{ - descriptionLabel->setText(desc); - setAccessibleDescription(desc); - showDescription(true); -} - -void Group::showTitle(bool visible) -{ - nameLabel->setVisible(visible); -} - -void Group::showDescription(bool visible) -{ - descriptionLabel->setVisible(visible); -} - -void Group::setCheckable(bool check) -{ - checkable = check; - - if (checkable && !toggleSwitch) { - toggleSwitch = new ToggleSwitch(true); - controlLayout->addWidget(toggleSwitch); - connect(toggleSwitch, &ToggleSwitch::toggled, this, - this(bool checked) { propertyList->setEnabled(checked); }); - } - - if (!checkable && toggleSwitch) { - controlLayout->removeWidget(toggleSwitch); - toggleSwitch->deleteLater(); - } -}
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/widgets/PropertiesList.cpp
Deleted
@@ -1,88 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -******************************************************************************/ - -#include <Idian/PropertiesList.hpp> - -#include <Idian/Row.hpp> - -#include <QStyle> - -#include <Idian/moc_PropertiesList.cpp> - -using idian::PropertiesList; - -PropertiesList::PropertiesList(QWidget *parent) : QFrame(parent) -{ - layout = new QVBoxLayout(); - layout->setSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); - - rowsList = QList<GenericRow *>(); - - setLayout(layout); -} - -// Note: This function takes ownership of the added widget -// and it may be deleted when the properties list is destroyed -// or the clear() method is called! -void PropertiesList::addRow(GenericRow *row) -{ - // Add custom spacer once more than one element exists - if (layout->count() > 0) { - layout->addWidget(new PropertiesListSpacer(this)); - } - - // Custom properties to work around :first and :last not existing. - if (!first) { - Utils::addClass(row, "first"); - first = row; - } - - // Remove last property from existing last item - if (last) { - Utils::removeClass(last, "last"); - } - - // Most recently added item is also always last - Utils::addClass(row, "last"); - last = row; - - row->setParent(this); - rowsList.append(row); - layout->addWidget(row); - adjustSize(); -} - -void PropertiesList::clear() -{ - rowsList.clear(); - first = nullptr; - last = nullptr; - QLayoutItem *item = layout->takeAt(0); - - while (item) { - if (item->widget()) { - item->widget()->deleteLater(); - } - delete item; - - item = layout->takeAt(0); - } - - adjustSize(); -}
View file
obs-studio-32.2.2.tar.xz/.github/actions/windows-signing/action.yaml -> obs-studio-33.0.0.tar.xz/.github/actions/windows-signing/action.yaml
Changed
@@ -31,9 +31,9 @@ - name: Setup bouf shell: pwsh env: - BOUF_TAG: 'v0.6.5' - BOUF_HASH: '2e16d5116415579b5dd8cd68b3fe6edaa7513938427567121942f592292605d5' - BOUF_NSIS_HASH: 'e323043627cfeebd237d306afc001c8c36a3c37f6ecef2b349a19a3209ae3450' + BOUF_TAG: 'v0.6.6' + BOUF_HASH: 'a4ad7c06fe00c4fdd2c22cab26b72d75b14655f9c756245f4be5dd2dadb7d5c8' + BOUF_NSIS_HASH: '02b533c3f9388391ec5a5079fac41486886fde67a26e5ed0e2652fa4e895deb4' GH_TOKEN: ${{ github.token }} run: | # Download bouf release @@ -43,14 +43,14 @@ $windows_zip = "bouf-windows-${env:BOUF_TAG}.zip" $nsis_zip = "bouf-nsis-${env:BOUF_TAG}.zip" Invoke-External gh release download "${env:BOUF_TAG}" -R "obsproject/bouf" -p $windows_zip -p $nsis_zip - + if ((Get-FileHash $windows_zip -Algorithm SHA256).Hash -ne "${env:BOUF_HASH}") { throw "bouf hash does not match." } if ((Get-FileHash $nsis_zip -Algorithm SHA256).Hash -ne "${env:BOUF_NSIS_HASH}") { throw "NSIS package hash does not match." } - + Expand-Archive -Path $windows_zip -DestinationPath bin Expand-Archive -Path $nsis_zip -DestinationPath nsis @@ -70,7 +70,7 @@ . ${env:GITHUB_ACTION_PATH}\Ensure-Location.ps1 . ${env:GITHUB_ACTION_PATH}\Invoke-External.ps1 Ensure-Location gcng - + Invoke-External gh release download "${env:CNG_TAG}" -R "GoogleCloudPlatform/kms-integrations" -p "*amd64.zip" Expand-Archive -Path *.zip $sigPath = Get-ChildItem *.sig -Recurse @@ -84,7 +84,7 @@ shell: pwsh run: | choco install rclone --version=1.69.3 -y --no-progress - + - name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093' # v3.0.0 with: @@ -112,7 +112,7 @@ "/f", "repo/.github/actions/windows-signing/prod-gc.crt" "/csp", "Google Cloud KMS Provider" "/kc", "projects/ci-signing/locations/global/keyRings/production/cryptoKeys/game-capture-release-sign-hsm/cryptoKeyVersions/1" - "${{ github.workspace }}/build/data/obs-plugins/win-capture/*.dll" + "${{ github.workspace }}/build/core/win-capture/data/*.dll" ) Invoke-External $SignToolExe @signArgs
View file
obs-studio-32.2.2.tar.xz/.github/workflows/build-project.yaml -> obs-studio-33.0.0.tar.xz/.github/workflows/build-project.yaml
Changed
@@ -4,7 +4,7 @@ jobs: check-event: name: Event Data 🔎 - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 defaults: run: shell: bash @@ -182,7 +182,7 @@ strategy: fail-fast: false matrix: - os: ubuntu-24.04, ubuntu-26.04 + os: ubuntu-26.04 runs-on: ${{ matrix.os }} needs: check-event defaults: @@ -254,7 +254,7 @@ flatpak-build: name: Flatpak 📦 - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 needs: check-event defaults: run: @@ -262,7 +262,7 @@ env: FLATPAK_BUILD_SHARE_PATH: flatpak_app/files/share container: - image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08 + image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-26.08 options: --privileged volumes: - /usr/local/lib/android:/to_clean/android
View file
obs-studio-32.2.2.tar.xz/.github/workflows/check-format.yaml -> obs-studio-33.0.0.tar.xz/.github/workflows/check-format.yaml
Changed
@@ -3,7 +3,7 @@ workflow_call: jobs: clang-format: - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -27,7 +27,7 @@ failCondition: error gersemi: - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -39,7 +39,7 @@ failCondition: error flatpak-validator: - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -51,7 +51,7 @@ failCondition: error qt-xml-validator: - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with:
View file
obs-studio-32.2.2.tar.xz/.github/workflows/dispatch.yaml -> obs-studio-33.0.0.tar.xz/.github/workflows/dispatch.yaml
Changed
@@ -59,7 +59,7 @@ download-language-files: name: Download Language Files 🌐 if: github.repository_owner == 'obsproject' && inputs.job == 'translations' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 env: CROWDIN_PAT: ${{ secrets.CROWDIN_SYNC_CROWDIN_PAT }} steps: @@ -91,7 +91,7 @@ update-documentation: name: Update Documentation 📖 if: github.repository_owner == 'obsproject' && inputs.job == 'documentation' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/generate-docs @@ -99,7 +99,7 @@ update-documentation-cloudflare: name: Update Documentation for Cloudflare ☁️ if: github.repository_owner == 'obsproject' && inputs.job == 'documentation' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/generate-docs @@ -109,7 +109,7 @@ deploy-documentation: name: Deploy Documentation to Cloudflare ☁️ if: github.repository_owner == 'obsproject' && inputs.job == 'documentation' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 needs: update-documentation-cloudflare defaults: run:
View file
obs-studio-32.2.2.tar.xz/.github/workflows/pr-pull.yaml -> obs-studio-33.0.0.tar.xz/.github/workflows/pr-pull.yaml
Changed
@@ -29,7 +29,7 @@ compatibility-validation: name: Validate Compatibility 🕵️ if: github.base_ref == 'master' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 permissions: checks: write steps: @@ -51,7 +51,7 @@ services-validation: name: Validate Services 🕵️ if: github.base_ref == 'master' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 permissions: checks: write steps: @@ -77,7 +77,7 @@ update-documentation: name: Update Documentation 📖 if: github.repository_owner == 'obsproject' && github.base_ref == 'master' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with:
View file
obs-studio-32.2.2.tar.xz/.github/workflows/publish.yaml -> obs-studio-33.0.0.tar.xz/.github/workflows/publish.yaml
Changed
@@ -16,7 +16,7 @@ check-tag: name: Check Release Tag if: github.repository_owner == 'obsproject' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 outputs: validTag: ${{ steps.check.outputs.validTag }} flatpakMatrix: ${{ steps.check.outputs.flatpakMatrix }} @@ -72,7 +72,7 @@ name: Flathub 📦 needs: check-tag if: github.repository_owner == 'obsproject' && fromJSON(needs.check-tag.outputs.validTag) - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 defaults: run: shell: bash @@ -87,7 +87,7 @@ YOUTUBE_SECRET: ${{ secrets.YOUTUBE_SECRET }} YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }} container: - image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08 + image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-26.08 options: --privileged volumes: - /usr/local/lib/android:/to_clean/android @@ -323,7 +323,7 @@ path: ${{ github.workspace }}/output merge-appcasts: - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 needs: create-appcast steps: - name: Merge Appcasts
View file
obs-studio-32.2.2.tar.xz/.github/workflows/push.yaml -> obs-studio-33.0.0.tar.xz/.github/workflows/push.yaml
Changed
@@ -29,7 +29,7 @@ compatibility-validation: name: Validate Compatibility 🕵️ if: github.ref_name == 'master' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 permissions: checks: write steps: @@ -53,7 +53,7 @@ services-validation: name: Validate Services 🕵️ if: github.ref_name == 'master' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 permissions: checks: write steps: @@ -79,7 +79,7 @@ update-documentation: name: Update Documentation 📖 if: github.repository_owner == 'obsproject' && (github.ref_name == 'master' || github.ref_type == 'tag') - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -101,7 +101,7 @@ deploy-documentation: name: Deploy Documentation to Cloudflare ☁️ if: github.repository_owner == 'obsproject' && github.ref_type == 'tag' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 needs: update-documentation defaults: run: @@ -138,7 +138,7 @@ sign-windows-build: name: Windows Signing ✍️ - uses: obsproject/obs-studio/.github/workflows/sign-windows.yaml@ac19ea663375cd02997be92b7d8ff6dd89a511ad + uses: obsproject/obs-studio/.github/workflows/sign-windows.yaml@04a973a1d9c585bed7292eb11234c397e606dd02 if: github.repository_owner == 'obsproject' && github.ref_type == 'tag' needs: build-project permissions: @@ -150,7 +150,7 @@ create-release: name: Create Release 🛫 if: github.ref_type == 'tag' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 needs: build-project, sign-windows-build defaults: run: @@ -194,8 +194,6 @@ macos_arm64_dsym_artifact_name="obs-studio-macos-arm64-${commit_hash}-dSYMs" macos_intel_artifact_name="obs-studio-macos-x86_64-${commit_hash}" macos_intel_dsym_artifact_name="obs-studio-macos-x86_64-${commit_hash}-dSYMs" - ubuntu_2404_x86_64_artifact_name="obs-studio-ubuntu-24.04-x86_64-${commit_hash}" - ubuntu_2404_x86_64_debug_name="obs-studio-ubuntu-24.04-x86_64-${commit_hash}-dbgsym" ubuntu_2604_x86_64_artifact_name="obs-studio-ubuntu-26.04-x86_64-${commit_hash}" ubuntu_2604_x86_64_debug_name="obs-studio-ubuntu-26.04-x86_64-${commit_hash}-dbgsym" ubuntu_2604_sources_name="obs-studio-ubuntu-26.04-sources-${commit_hash}" @@ -214,10 +212,6 @@ "${root_dir}"/OBS-Studio-${{ steps.check.outputs.version }}-macOS-Intel.dmg mv -v "${macos_intel_dsym_artifact_name}/"obs-studio-*-macos-intel-dSYMs.tar.xz \ "${root_dir}"/OBS-Studio-${{ steps.check.outputs.version }}-macOS-Intel-dSYMs.tar.xz - mv -v "${ubuntu_2404_x86_64_artifact_name}/"obs-studio-*-x86_64-ubuntu-gnu.deb \ - "${root_dir}"/OBS-Studio-${{ steps.check.outputs.version }}-Ubuntu-24.04-x86_64.deb - mv -v "${ubuntu_2404_x86_64_debug_name}/"obs-studio-*-x86_64-ubuntu-gnu-dbgsym.ddeb \ - "${root_dir}"/OBS-Studio-${{ steps.check.outputs.version }}-Ubuntu-24.04-x86_64-dbsym.ddeb mv -v "${ubuntu_2604_x86_64_artifact_name}/"obs-studio-*-x86_64-ubuntu-gnu.deb \ "${root_dir}"/OBS-Studio-${{ steps.check.outputs.version }}-Ubuntu-26.04-x86_64.deb mv -v "${ubuntu_2604_x86_64_debug_name}/"obs-studio-*-x86_64-ubuntu-gnu-dbgsym.ddeb \
View file
obs-studio-32.2.2.tar.xz/.github/workflows/scheduled.yaml -> obs-studio-33.0.0.tar.xz/.github/workflows/scheduled.yaml
Changed
@@ -34,7 +34,7 @@ cache-cleanup: name: Cache Cleanup 🧹 - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 permissions: actions: write steps: @@ -107,7 +107,7 @@ upload-language-files: name: Upload Language Files 🌐 if: github.repository_owner == 'obsproject' && github.ref_name == 'master' - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with:
View file
obs-studio-32.2.2.tar.xz/AUTHORS -> obs-studio-33.0.0.tar.xz/AUTHORS
Changed
@@ -14,17 +14,17 @@ Palana tytan652 WizardCM + Warchamp7 Norihiro Kamae fryshorts - Warchamp7 pkv Georges Basile Stavracas Neto DDRBoxman Kurt Kartaltepe - Rodney Gol-D-Ace - BtbN + Rodney tt2468 + BtbN Exeldro Shaolin kc5nra @@ -34,14 +34,14 @@ Zachary Lund Dennis Sädtler shiina424 + Penwywern SuslikV Paul Hindt Ed Maste Vainock + jcm Alex Luccisano CodeYan01 - jcm - Penwywern Reboot Martell Malone Ford Smith @@ -63,6 +63,7 @@ juvester mvji wangshaohui + FiniteSingularity Jimi Huotari Sean DuBois craftwar @@ -104,6 +105,7 @@ Michel Quinn Damerell Tristan Matthews + prgmitchell Anthony Torres Anton Bershanskiy Bennik2000 @@ -120,6 +122,7 @@ Palakis Theodore Dubois test + tfo Alexandre Vicenzi Barnabás Pőcze Carl Fürstenberg @@ -129,7 +132,6 @@ Timo Gurr Tjienta Vara Wahaj Dar - prgmitchell thirumalai-qcom Aaron Boxer Aleks Todorov @@ -146,12 +148,12 @@ MaZderMind OldBaldGeek Stephen Seo + WarmUpTill Zhao Zhili bl makise-homura nleseul nquah - tfo univrsal Alexander Popov Artem Polishchuk @@ -165,7 +167,6 @@ Daniel Lopez David Cooper Doğukan Korkmaztürk - FiniteSingularity Friedhelm Birth Gale, Thy-Lan Hernán @@ -192,7 +193,6 @@ Tatsuyuki Ishi Torge Matthies Valentin - WarmUpTill Yoshimasa Niwa jeiea karenkim-AfreecaTV @@ -209,6 +209,7 @@ Albert Alex Miller Alexander Schittler + Alfred Wingate Amin.MasterkinG Andreas Reischuck Andrei Nistor @@ -264,6 +265,7 @@ PancakeTAS Paul Gregoire Piotr Esden-Tempski + Ramjivan Jangid Sergio Garcia Murillo Sergo Skid-Inc @@ -279,6 +281,7 @@ Vadim Zhukov Warren Turkal Willy Liu(HQ ENG) + Wu Haoyu WuLongyue Yuri Victorovich adray @@ -302,6 +305,7 @@ moocowsheep notmark obiwac + rch850 skwerlman stephematician stopforumspam @@ -444,6 +448,7 @@ Haden F Han-Tai Chen Hayden McAfee + Hernán R Hicham LEMGHARI Hong Hak-Gyu Iblis Lin @@ -487,6 +492,7 @@ Kevin Tardif Kevin Wang Keylase + Kira-NT Kraz3D Lasse Dalegaard Laurin Müller @@ -530,9 +536,11 @@ Morten Bøgeskov MrMahgu Murnux + Myeong Gyu Lee Nathan-Huckleberry Nerixyz Nick Stockton + Nick von Kaenel Nicolas F Nicolas Fella Night @@ -540,6 +548,7 @@ Oliver Lietz Olivier Humbert OvchinnikovDmitrii + Pablo Patrick Ancillotti Paul Mc Galey Per Heed @@ -549,8 +558,8 @@ Philip Loche Philipp Bauer Piotr Kubaj + R0te Rafael Franco - Ramjivan Jangid RedBlackAka Regan Black René Rebe @@ -618,7 +627,6 @@ William Casarin Wooster Wouter - Wu Haoyu Yann Salmon Ying Yin Younes SERRAJ @@ -629,6 +637,7 @@ Zulleyy3 Zulleyy3 a1346054 adocilesloth + alvin1995 andrewsoncha ansh1406 antho @@ -674,6 +683,7 @@ jeremiah joelgerard jsnkan + kangunnie_soop ka’imi kiwialec kokole @@ -705,7 +715,6 @@ qhy040404 qiongzai.sun raincomplex - rch850 redcrazyheart repeat rkfg @@ -721,6 +730,7 @@ striphat-dev sunjingzhao thekrzos + tom trwnh tujinshu ty2570 @@ -818,7 +828,6 @@ AL-3boud_25 (alaboud257) Salah Naser (salah.k.2775) Hani Sweileh (hno.sweileh) - zefr0x BWU Wheelman (Wheelman) Nasser Bin Laboun (nasserbinlaboun) M24 AL-Zurqan (mohammedamer2443) @@ -843,6 +852,7 @@ chaironeko aalhaif 07OM + OhWalP (ohwalp) Hadi Gamer (hadigamer3131) Aragonese: juanpabl @@ -896,7 +906,7 @@ guyguy120 (gilenlecuona) unknowndomain Idoia Suárez (idoiasuarez86) - Fiwi1265 + Aitzia (aitzia) Aritz Herrero (aritzherrero4) OBS-Staff Belarusian: @@ -943,8 +953,8 @@ Dremski kalmarin Seyhan Halil (easythe) - BeCaReFuL24 Krasimir Dankov (krasidankov) + BeCaReFuL24 capitalrhino Night (mcnight212) Kosti (Kostirip) @@ -990,8 +1000,8 @@ OBS-Staff Chinese Simplified: Bob Liu (Akagi201) - fangzheng Andepthy + fangzheng AlexGuo1998 wwj402_github FrzMtrsprt (FrzHrzn) @@ -1087,9 +1097,9 @@ notlin4 abc0922001 Michael Yeh (hinet60613) + SeasonChannel3322 (SeasonChannel32) Julian_Lai OBS-Staff - SeasonChannel3322 (SeasonChannel32) myjourney in Steemit (myjourney) Yu-Juei Tseng (e222et) Kanbi Dungaitj (open3) @@ -1099,12 +1109,14 @@ Gol D. Ace (goldace) 兔頭 (yeahdamn) craftwar + Donder2026 Thomas (thomassth) Jcys 菘菘 (SiongSng) Rice Hung (ricehung29) xixiaofan (XXXF) 吳軒竹 (ggjason.tw) + Aelura (kldhsh123) 翟谦益 (ZhaiQianYi) Supaplextw HUGOALH (hugoalh) @@ -1120,7 +1132,6 @@ ak-47root Append Huang (append) X-RAY team film (961111ray) - 遥汐Aelura (kldhsh123) fangzheng zhtw yeft @@ -1214,6 +1225,7 @@ Johan Keller Jensen (JKeller) Christian Henriksen (cnhenriksen) unknowndomain + Alfred (Alfred_GE) Alex Smotra (smotraalex75) Daniel Aundal (aundal) OBS-Staff @@ -1273,7 +1285,7 @@ Issa1553 unknowndomain matwey - 遥汐Aelura (kldhsh123) + Aelura (kldhsh123) Seb King (spud) HENRY MARTIN (n3rdl0rd) Cristhofer Sanchez Solano (JafetSS) @@ -1332,6 +1344,7 @@ Dex (deloxs) C3kos (C3kos1) Bentologi + peacecop kalmer: (peacecop) Gol D. Ace (goldace) unknowndomain Musaks Kõik (musakskoik) @@ -1408,10 +1421,10 @@ Takoz Sipokad Yberion + corrigo Léo (leeo97one) RisedSky Pikana - corrigo BoboopTeam DoK_- leluk @@ -1429,10 +1442,10 @@ Gol D. Ace (goldace) Figurant16 Youtubeur FR│Giaco35 (Giaco35) + Christophe Gesché (Moosh-be) Wiwok Kévin (FleuryK) steve_fr - Christophe Gesché (Moosh-be) Valentin (valentin45) LEMIBANDDEXARI kyllian (tardigradeus) @@ -1479,6 +1492,7 @@ SkytAsul (skytasul) xav blacyre (xav35000) Alex Smotra (smotraalex75) + aetheri0us HugOmega Raphaël M (Zemelix) Antoine Gros (gros_) @@ -1740,6 +1754,7 @@ unknowndomain therealnandy bali028 + Dani (Stravorn) abydosan (abydoshun) not.skelly Minta Máté (Cubebanyasz) @@ -1782,7 +1797,7 @@ LordShadow95 Marocco2 uman - tiwi90 + Tiwi90 (tiwi90) imcesca smart2128 Vincenzo Reale (vinx.reale) @@ -1852,6 +1867,7 @@ nishi-ruse meitel1014 (meitel1234) kotobato + ? (a2y4) ラズベリージャム (rpiuser1923) Kanji1113 (kanji1113) nkamae @@ -1862,9 +1878,9 @@ ato lash (hal_shu_sato) unknowndomain 依神紫苑 (MonogoiNoobs) + 吉田成人 (9demaio1964) 神成フィルム (kami00nari) Koronteto - ? (a2y4) GO Channel (georgestv.0129) Bob Liu (Akagi201) Tolr @@ -1881,7 +1897,7 @@ Agurzil ButterflyOfFire ⁂ (BoFFire) ZiriSut - Azwaw Aqbayli (Azwaw) + Afrux n Tmes (Aksel10) Karakalpak: KarLin - Karakalpak Translators Team (karakalpaklingvo) flower (flower_flower) @@ -1948,7 +1964,7 @@ bkrhnr Ardurekic Lao: - bone NI (bounkirdni) + Bone NI (bounkirdni) nirankoon.singpraseuth (nirankoon) Baker123 Latvian: @@ -2064,6 +2080,7 @@ Farshid Meidani (farshid_mi) mahdi ram (mhadi-ram) rahimz + R (Mvtbh) ROkelbow Gol D. Ace (goldace) PRNUse @@ -2153,6 +2170,7 @@ Pedro Ricardo (Pedro270707) kayal15948 andre_satorres + Chloe Medeiros (twinfantas) João Faro (FaroJoaoFaro) Diogo Ramos (dr03ramos) ROkelbow @@ -2160,14 +2178,15 @@ Paulo Soares (psoares.gm) Gost_Evil Tiago Mesquita (tiagomesquita) + CookieCaptainD Hélder Ferreira (Mtx32) Rafa.Godoy moonlightz (moonlightzzz) Portuguese, Brazilian: Diogo Ramos (dr03ramos) Shaolin (admshao) - Marcelo dos Santos Mafra (msmafra) igorruckert + Marcelo dos Santos Mafra (msmafra) Lincoln H. (LincolnH) Skellingtor Ramon Mendes (rbrgameplays) @@ -2299,7 +2318,7 @@ Pavel (Shevalie) VNGXR Сергей (nasferatus) - Рушан Мухутдинов (deflecta) + Rushan Mukhutdinov (deflecta) Bugo MishaRey (mishaareyy) Alexey Frolov (frolovlife) @@ -2373,6 +2392,7 @@ unknowndomain zy9c 1337 (zy9c228) Илья Кузнецов (ilyavj) + Башҡорт агенты (vint6908) allan walpy (AndreyLysenkov) Ninja Hacker3000 (ninjahacker3875) evilserge @@ -2390,7 +2410,6 @@ Anatoly (Atsupak) MeDustyy Nezila Nez (Nezila) - Башҡорт агенты (vint6908) Timofey Sosnovsky (timofey.sosnovsky) Kcurett TM (thekcurett) Leika098 @@ -2477,6 +2496,7 @@ admrs Aleksander Kovač (Acookook) MG lolenstine (mglolenstine) + Peter Klofutar (PKlofutar) mspacapan ROkelbow Grimpy @@ -2507,11 +2527,14 @@ Alejandro Moctezuma (AlejandroMoc) Cristhofer Sanchez Solano (JafetSS) Lluís R (LluisR98) + Pedro Villa (SoyPredator) francisco Emanuel montero cordoba (monterofranciscoemanuel) Maximiliano Schtroumpftech Pena-Roig (som2tokmynam) fordink257 + Luis Góngora Alonso (LuisGongora) Carlos Plata (Braixenfan989) JaviermbPlays (JavierMB) + Frank (frank4real) Gonzalo Lorenzo (Gxnzalo) Kael (KaelSky) eemiroj @@ -2588,6 +2611,7 @@ Gol D. Ace (goldace) dotar (TorstenAugustsson) Dennisbdhdkdsgslaowhsosvsj Hskdldkd Trousershsjsodhdldheodhdisjsvs (saxwelcoki) + Hempa Henrik Mattsson-Mårn (rchk) unknowndomain Axel Aminoff (axel.aminoff) @@ -2595,7 +2619,7 @@ Lennart Bonnevier (lennartbon) Jonas Svensson (jonassanojj99) Hannes Blåman (hannesblaman) - pitedaniel + Daniel Lundström (pitedaniel) TacticalKebab kronblom2 OBS-Staff @@ -2626,7 +2650,8 @@ Tatar: Әлмәт Ак Арыслан (19082004amir) Timur Seber (seber) - Рушан Мухутдинов (deflecta) + Rushan Mukhutdinov (deflecta) + Aivaz Latypov (pngdrift) Ilgiz Zigangirov (inov8) Telugu: chakradhar mylapilli (SonuAnshu) @@ -2655,6 +2680,7 @@ Sakia Normal Human (arcanaarcana5) XZP (XZP) (xe4a177) นักลูบคม อันดับ 1 (mrmanyt629) + Pannathat Thongklat (MePannathat) 2RD Channel (2RD) Worawut Weerawan (nero.exe) PlyKung (plykung) @@ -2690,18 +2716,19 @@ Ufuk Furkan Öztürk (UfukFurkanOzturk) Emir (dirt3009) Nejdet ACAR (nejdetacar) + Samo (SamoE) Cemal Dursun (cmldrs) Serhat Öktem (delidolu1adam) Kayhan (SwitchAlpha) Savas Tokmak (Laserist) Burkicannjr - Samo (SamoE) Umut kılıç (kilic190787) Burak Eker (mburakeker) Ege (smoolz) Bora Atıcı (Brtc) BreezeQS keke_ea + Rumuz AGO (rumuzago) furkanbicici fikarme İsmail Efe Top (Ektaynot) @@ -2734,6 +2761,7 @@ Berk Kırıkçı (BunCat09) Zafer Yılmaz (yilmazzafer722) Mehmet Coşkun (mmehmet.ccoskun) + Levo K (lexinch) myasincavdar Arat Ünal (AratreyizprogamerX) ownieyo @@ -2745,6 +2773,7 @@ Toraichi (toraichi) bkzspam Ferhat Geçdoğan (ferhatgec) + Berk Udum (berkflame) Onur Yılmaz (Makaron3422) TahaCelik Baran Mordoğan (okunamayanad) @@ -2794,9 +2823,10 @@ lxlalexlxl Anatolii Bielibov (anatoly136ua) veydzh3r - Marm (Marm_Marm) Дмитро Маркевич (hotr1pak) + Marm (Marm_Marm) Kefir (Kefir2105) + Богдан Лук'яненко (BLuk) Lino Bico (bicolino34) Dekanenko (dekanenko) slvvko @@ -2807,6 +2837,7 @@ Oleh Hnat (aetrnm) FOR___REST (konstantinkostenko96) Свиридюк Іван (fl1per) + Volky Grendel (oshovsky) Микола Мірчук (mr.cobreen) MishaRey (mishaareyy) Gol D. Ace (goldace) @@ -2846,8 +2877,9 @@ Uyghur: Abduqadir Abliz (Sahran) Uzbek: - Bilolbek Normuminov (mainculprit) Abye (ABYEGAMER) + Asadbek Jalolov (asadkasal923) + Bilolbek Normuminov (mainculprit) Valencian: Decis Vietnamese: @@ -2865,6 +2897,7 @@ zungsle Bui Huy Quang (bhuyquang1) Bach Le (BachWumpus) + Brad 'Bảo' Hirsch (bradfreedom) nguyenthanhphong Loc Huynh (loccun) BIGO - 지혜 (parkjihye98) @@ -2882,6 +2915,7 @@ Michio Nakano (michioxd) Shinoge Geenzo Gamer (geenzogamer164) + logitech lift (logitechlift) unknowndomain Vũ Hải Tây (tayngungo1999) SITUVNgcd
View file
obs-studio-32.2.2.tar.xz/CMakePresets.json -> obs-studio-33.0.0.tar.xz/CMakePresets.json
Changed
@@ -27,49 +27,43 @@ "obsproject.com/obs-studio": { "dependencies": { "prebuilt": { - "version": "2026-07-15", + "version": "2026-10-23", "baseUrl": "https://github.com/obsproject/obs-deps/releases/download", "label": "Pre-Built obs-deps", "hashes": { - "macos-universal": "4ecb4c598dfa853168df6c2a0c4e0ffec8495a81fbd1ba051ef88ecd5e0f7e53", - "windows-x64": "6f90e9598fa10cff5ad23cdcfae49b87868c07bf896b02cd464582b4ce2f2ba9", - "windows-x86": "f33697d7e248b53f38893f02440454b91b0aab05c981c646830521335242fd08", - "windows-arm64": "4e7d6835ae36dbc569bf6f88646cb6c4f1f0319b5c13d9d37ba3d19b25b1e240" + "macos-universal": "6ded92c5d97f1d1b5effa07be13cc9f539826aa9c65013a15872328e39acffbf", + "windows-x64": "7508972a867a0ef68c26cd8bdba61fd999edd0a92fa9eb9585774de9bf51bfbe", + "windows-x86": "bca7f4d6603028a7ac9cfa6a88aa3ff0e9402627593633e26cc0b3a5e5312a9b", + "windows-arm64": "05e24a7f18a63ac53bcdc5d7017943481be13c1399a1cbb6311a076fe202eb8c" } }, "qt6": { - "version": "2026-07-15", + "version": "2026-10-23", "baseUrl": "https://github.com/obsproject/obs-deps/releases/download", "label": "Pre-Built Qt6", "hashes": { - "macos-universal": "d4b8058612a7067e44b2205fe7925ee24e9ec6b15ac8c29d3e6230c70030b102", - "windows-x64": "7c7f985711d80467bdc1795b6592275a27d5b0e5a2c7a61db1f2c1d08d6a5579", - "windows-arm64": "6d5047a04cad3ecc2615bf8b3df6eb22ec953a458b6cd89253bf131ee4981b90" + "macos-universal": "b216560cea8497207f9fc350c713716fb84aec6b973bb0ff8ac6add7734abad5", + "windows-x64": "78cd7a138464bb6edcdd3b85fcd63a5a7c69e369629963f3bc395bab74fb3f47", + "windows-arm64": "ec6a715c57b260c62c7db917d804ddc600252def89817044fbd341a63eefe2d8" }, "debugSymbols": { - "windows-x64": "471d0b2191c424a520a51d064f3741084f117e1ff6ee5af1d16aabcdbacc6659", - "windows-arm64": "ffe5b46f6abc81355a4161efdef6cbb2e8862eb053bd2211808c4d4833fcee78" + "windows-x64": "5c97809dcb663a51e5b5f47983359d03a213a8c711c4b158a1b62429b8dff6be", + "windows-arm64": "47fe11add033d56291826e8e9fffd11b6f0663626a9e690487bb27070a1bd457" } }, "cef": { - "version": "6533", + "version": "7871", "baseUrl": "https://cdn-fastly.obsproject.com/downloads", "label": "Chromium Embedded Framework", "hashes": { - "macos-x86_64": "37bf7571a48c5dfa8519817e4a90a3503a0eb30f9eadd68f4c3e783e363f272a", - "macos-arm64": "429b50e74f6c174dcfe2f14d8204b54add497eaafe117f7b69ce6bb2354d2626", - "ubuntu-x86_64": "7963335519a19ccdc5233f7334c5ab023026e2f3e9a0cc417007c09d86608146", - "ubuntu-aarch64": "642514469eaa29a5c887891084d2e73f7dc2d7405f7dfa7726b2dbc24b309999", - "windows-x64": "922efbda1f2f8be9e5b2754d878a14d90afc81f04e94fc9101a7513e2b5cecc1", - "windows-arm64": "df9df4bd85826b4c071c6db404fd59cf93efd9c58ec3ab64e204466ae19bb02a" + "macos-x86_64": "980783bba509e7e79a671c29040bbe29d832a934c1368b500a17a22e076eb0f4", + "macos-arm64": "0343233fc462384c2f1f58a4222028bc6171f05948a822241f89df2faa7cee8d", + "ubuntu-x86_64": "8ffc64d06ea74da613eeda7f2aa5d4e98661af6fa3ed8c68724c9a6e4e89ea8e", + "ubuntu-aarch64": "b05cf13b0f482e3b0149ac21268268c536d091b5e6608c742019ebd6c8e8a1e3", + "windows-x64": "54cd191a3f56bb1f05be22b95e1fa8041061b38bd5fe94e0776fb34dd599f341", + "windows-arm64": "3f5b604eab71baab20c08f054d68c6212d06237e172fb8d38271c2384c2eb3a6" }, - "revision": { - "macos-x86_64": 5, - "macos-arm64": 5, - "ubuntu-x86_64": 6, - "ubuntu-aarch64": 6, - "windows-x64": 2 - } + "revision": {} } }, "tools": {
View file
obs-studio-32.2.2.tar.xz/CODESTYLE.md -> obs-studio-33.0.0.tar.xz/CODESTYLE.md
Changed
@@ -214,7 +214,7 @@ > !IMPORTANT > The “`static`” keyword is one of the more confusing aspects of modern C++, particularly compared to C. The meaning of the keyword changes depending on whether it is used for a function, a global variable, a function-scope variable, a class method, or a class member. > -> In general limit its use in C++ code to describe “storage duration” of variables or for class methods (e.g. factory methods). Use thread-safe functions to initialize a function-local static variable or class member (to prevent possible race conditions when the variable is initialized). Also be mindful of the “Static Initialization Order Fiasco”. Otherwise all the common established pitfalls and issues of global variables apply. +> In general limit its use in C++ code to describe “storage duration” of variables or for class methods (e.g. factory methods). Be mindful that even though since C++11 function-local static variables are initialized non-concurrently, this does not make consecutive _access_ of the object thread-safe as well. Also be mindful of the “Static Initialization Order Fiasco”. Otherwise all the common established pitfalls and issues of global variables apply. > > `constexpr` definitions do not need to use the static keyword. `constexpr` implies const and const implies static storage duration by default. >
View file
obs-studio-32.2.2.tar.xz/CONTRIBUTING.md -> obs-studio-33.0.0.tar.xz/CONTRIBUTING.md
Changed
@@ -26,6 +26,21 @@ Authors of contributions to the OBS Project are expected to abide by the “OBS Project Code of Conduct” available at https://github.com/obsproject/obs-studio/blob/master/COC.rst. +## Pull Request Review Guidelines + +In general reviews of pull requests are not limited to project members and can be undertaken by contributors and other GitHub users. Project members commonly coordinate reviews of pull requests at their own discretion in line with project needs and available bandwidth. + +To reduce possible friction of the review process, a simple set of rules should be followed: + +* **Do not** request reviews from specific community or project members yourself. + * It is permitted to ping other GitHub users to notify them of a PR and kindly ask them if they are willing (and able) to review it, all within reason. +* Reviewers might leave comments or ask for changes on specific lines of changed code. Once the comment has been addressed **do not unilaterally resolve** the comment. + * It is entirely the reviewer's decision whether they would consider the changes to be sufficient to address their concerns. Just having addressed a comment, does not resolve it. + * As a reviewer, make sure to regularly review the comments received on your reviews, check the code changes, and resolve your comments once they have been addressed. **Don't leave pull request authors hanging.** + * Project members will usually ping reviewers about unresolved review comments and resolve such comments themselves to unblock PRs from being merged. +* When addressing review comments through code changes, try to avoid force-pushes and use temporary commits which can be squashed later (see below). + * Unless necessary, avoid rebasing a pull request branch unless it is absolutely necessary. Rebasing will pull in changes from the base branch into the "changes since last push" of the pull request, making it harder for reviewers to check what changes have been pushed. + ## Commit Authoring Guidelines The project uses the “50/72” standard for commit messages, which requires that a commit title uses no more than 50 characters, while any consecutive line used for the commit description is allowed to use a maximum of 72 characters (with long lines manually broken up). @@ -108,7 +123,7 @@ Co-authored-by: Name <git@address.TLD> ``` -# AI/Machine Learning Policy +## AI/Machine Learning Policy AI/machine learning systems such as Copilot, ChatGPT, and Claude, are prone to generating plausible-sounding, but wrong code that makes incorrect assumptions about OBS internals or APIs it interfaces with.
View file
obs-studio-32.2.2.tar.xz/build-aux/com.obsproject.Studio.json -> obs-studio-33.0.0.tar.xz/build-aux/com.obsproject.Studio.json
Changed
@@ -1,7 +1,7 @@ { "id": "com.obsproject.Studio", "runtime": "org.freedesktop.Platform", - "runtime-version": "25.08", + "runtime-version": "26.08", "sdk": "org.freedesktop.Sdk", "command": "obs", "finish-args": @@ -22,15 +22,16 @@ "add-extensions": { "com.obsproject.Studio.Plugin": { "directory": "plugins", + "versions": "stable;test", "subdirectories": true, "add-ld-path": "lib", - "merge-dirs": "lib/obs-plugins;share/obs/obs-plugins", + "merge-dirs": "lib/obs-modules/plugins;share/obs/obs-modules/plugins;lib/obs-plugins;share/obs/obs-plugins", "no-autodownload": true, "autodelete": true }, "org.freedesktop.LinuxAudio.Plugins": { "directory": "extensions/Plugins", - "version": "25.08", + "version": "26.08", "add-ld-path": "lib", "merge-dirs": "vst", "subdirectories": true, @@ -48,8 +49,8 @@ { "type": "file", "dest-filename": "base.tar.xz", - "url": "https://github.com/obsproject/obs-deps-buildstream/releases/download/2026-07-15/flatpak-base-x86_64-2026-07-15.tar.xz", - "sha256": "396522a370529c31bbec6de810aff8bd5ba4eef103b2218954ffa5d8847dc943" + "url": "https://github.com/obsproject/obs-deps-buildstream/releases/download/2026-09-24/flatpak-base-x86_64-2026-09-24.tar.xz", + "sha256": "480a98e55b51566603b6ea0ee28dbeddaefc1e172d18fb72f16ab9d941794c79" } }, @@ -63,8 +64,8 @@ { "type": "file", "dest-filename": "devel.tar.xz", - "url": "https://github.com/obsproject/obs-deps-buildstream/releases/download/2026-07-15/flatpak-devel-x86_64-2026-07-15.tar.xz", - "sha256": "2499b622f450f3ae6ea7e9d893d8063cdacd8aa2089ecd4b8462d16e970fbc43" + "url": "https://github.com/obsproject/obs-deps-buildstream/releases/download/2026-09-24/flatpak-devel-x86_64-2026-09-24.tar.xz", + "sha256": "c15e10e46054150d927bd81880dfbcc71641658395b84cdaad3f572920481f4a" } }, @@ -81,8 +82,8 @@ { "type": "file", "dest-filename": "devtools.tar.xz", - "url": "https://github.com/obsproject/obs-deps-buildstream/releases/download/2026-07-15/flatpak-devtools-x86_64-2026-07-15.tar.xz", - "sha256": "557e5cf96a7118f1377b7eabe402621908f7ba6a9bc93fbb134ebc175d31a5d9" + "url": "https://github.com/obsproject/obs-deps-buildstream/releases/download/2026-09-24/flatpak-devtools-x86_64-2026-09-24.tar.xz", + "sha256": "f5ba4578cade6bfd3670340e7eeb0f31876b39e29bc978b5ed47da7de03ffc70" } }, @@ -96,8 +97,8 @@ { "type": "file", "dest-filename": "qt.tar.xz", - "url": "https://github.com/obsproject/obs-deps-buildstream/releases/download/2026-07-15/flatpak-qt-x86_64-2026-07-15.tar.xz", - "sha256": "231c5671173f7b6d33df457eb6991c5b6a76bccc59545b7e32d56f0e87b97872" + "url": "https://github.com/obsproject/obs-deps-buildstream/releases/download/2026-09-24/flatpak-qt-x86_64-2026-09-24.tar.xz", + "sha256": "7a4060cab48798e13be0eb9aa967dd3cb6f94209c6594eacccf3223c5c91e3de" } }, @@ -120,8 +121,8 @@ "sources": { "type": "archive", - "url": "https://cdn-fastly.obsproject.com/downloads/cef_binary_6533_linux_x86_64_v6.tar.xz", - "sha256": "7963335519a19ccdc5233f7334c5ab023026e2f3e9a0cc417007c09d86608146" + "url": "https://cdn-fastly.obsproject.com/downloads/cef_binary_7871_linux_x86_64.tar.xz", + "sha256": "8ffc64d06ea74da613eeda7f2aa5d4e98661af6fa3ed8c68724c9a6e4e89ea8e" } }, @@ -131,6 +132,8 @@ "builddir": true, "config-opts": "-DCMAKE_BUILD_TYPE=RelWithDebInfo", + "-DCMAKE_INCLUDE_PATH=/app/include;/usr/include", + "-DENABLE_FLATPAK=ON", "-DENABLE_WAYLAND=ON", "-DENABLE_BROWSER=ON", "-DCEF_ROOT_DIR=/app/cef",
View file
obs-studio-32.2.2.tar.xz/build-aux/steam/scripts_windows/install.bat -> obs-studio-33.0.0.tar.xz/build-aux/steam/scripts_windows/install.bat
Changed
@@ -22,32 +22,9 @@ mkdir "%PROGRAMDATA%\obs-studio-hook" icacls "%PROGRAMDATA%\obs-studio-hook" /grant "ALL APPLICATION PACKAGES":(OI)(CI)(GR,GE) -:checkDLL - echo Checking for 32-bit Virtual Cam registration... - reg query "HKLM\SOFTWARE\Classes\CLSID\{A3FCE0F5-3493-419F-958A-ABA1250EC20B}" >nul 2>&1 /reg:32 - if %errorLevel% == 0 ( - echo 32-bit Virtual Cam found, skipping install... - echo. - ) else ( - echo 32-bit Virtual Cam not found, installing... - goto install32DLL - ) - -:CheckDLLContinue - echo Checking for 64-bit Virtual Cam registration... - reg query "HKLM\SOFTWARE\Classes\CLSID\{A3FCE0F5-3493-419F-958A-ABA1250EC20B}" >nul 2>&1 /reg:64 - if %errorLevel% == 0 ( - echo 64-bit Virtual Cam found, skipping install... - echo. - ) else ( - echo 64-bit Virtual Cam not found, installing... - goto install64DLL - ) - goto endSuccess - :install32DLL echo Installing 32-bit Virtual Cam... - regsvr32.exe /i /s %1\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll + regsvr32.exe /i /s %1\core\win-dshow\data\obs-virtualcam-module32.dll reg query "HKLM\SOFTWARE\Classes\CLSID\{A3FCE0F5-3493-419F-958A-ABA1250EC20B}" >nul 2>&1 /reg:32 if %errorLevel% == 0 ( echo 32-bit Virtual Cam successfully installed @@ -57,11 +34,10 @@ echo. goto endFail ) - goto checkDLLContinue :install64DLL echo Installing 64-bit Virtual Cam... - regsvr32.exe /i /s %1\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll + regsvr32.exe /i /s %1\core\win-dshow\data\obs-virtualcam-module64.dll reg query "HKLM\SOFTWARE\Classes\CLSID\{A3FCE0F5-3493-419F-958A-ABA1250EC20B}" >nul 2>&1 /reg:64 if %errorLevel% == 0 ( echo 64-bit Virtual Cam successfully installed
View file
obs-studio-32.2.2.tar.xz/build-aux/steam/scripts_windows/uninstall.bat -> obs-studio-33.0.0.tar.xz/build-aux/steam/scripts_windows/uninstall.bat
Changed
@@ -23,8 +23,8 @@ RMDIR /S /Q "%PROGRAMDATA%\obs-studio\shader-cache" :uninstallDLLs - regsvr32.exe /u /s %1\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll - regsvr32.exe /u /s %1\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll + regsvr32.exe /u /s %1\core\win-dshow\data\obs-virtualcam-module32.dll + regsvr32.exe /u /s %1\core\win-dshow\data\obs-virtualcam-module64.dll :endSuccess echo Virtual Cam uninstalled!
View file
obs-studio-32.2.2.tar.xz/cmake/common/helpers_common.cmake -> obs-studio-33.0.0.tar.xz/cmake/common/helpers_common.cmake
Changed
@@ -40,7 +40,7 @@ endforeach() endif() - if(ENABLE_PLUGINS) + if(ENABLE_CORE_MODULES) get_property(OBS_MODULES_ENABLED GLOBAL PROPERTY OBS_MODULES_ENABLED) list(SORT OBS_MODULES_ENABLED COMPARE NATURAL CASE SENSITIVE ORDER ASCENDING) @@ -82,6 +82,11 @@ endif() endfunction() +# target_enable: Adds target to list of enabled modules +function(target_enable target) + set_property(GLOBAL APPEND PROPERTY OBS_MODULES_ENABLED ${target}) +endfunction() + # target_disable: Adds target to list of disabled modules function(target_disable target) set_property(GLOBAL APPEND PROPERTY OBS_MODULES_DISABLED ${target}) @@ -451,13 +456,17 @@ return(PROPAGATE ${return_value}) endfunction() -# add_obs_plugin: Add plugin subdirectory if host platform is in specified list of supported platforms and architectures -function(add_obs_plugin target) +# add_core_module: Add module subdirectory if host platform is in specified list of supported platforms and architectures +function(add_core_module target) set(options WITH_MESSAGE) set(oneValueArgs "") set(multiValueArgs PLATFORMS ARCHITECTURES) cmake_parse_arguments(PARSE_ARGV 0 _AOP "${options}" "${oneValueArgs}" "${multiValueArgs}") + if(NOT TARGET libobs) + message(FATAL_ERROR "Cannot add libobs core module without existing 'libobs' target") + endif() + set(found_platform FALSE) list(LENGTH _AOP_PLATFORMS _AOP_NUM_PLATFORMS) @@ -499,8 +508,41 @@ if(found_platform AND found_architecture) add_subdirectory(${target}) - elseif(_AOP_WITH_MESSAGE) - add_custom_target(${target} COMMENT "Dummy target for unavailable module ${target}") + endif() + + if(TARGET ${target}) + target_enable(${target}) + else() + if(_AOP_WITH_MESSAGE) + add_custom_target(${target} COMMENT "Dummy target for unavailable module ${target}") + endif() target_disable(${target}) endif() endfunction() + +function(set_obs_core_modules) + if(NOT TARGET libobs OR NOT TARGET libobs-core-modules) + message(FATAL_ERROR "Unable to set up OBS Core Modules without 'libobs' target") + endif() + + get_property(OBS_MODULES_ENABLED GLOBAL PROPERTY OBS_MODULES_ENABLED) + get_target_property(libobs_source_directory libobs SOURCE_DIR) + get_target_property(libobs_binary_directory libobs BINARY_DIR) + + list(LENGTH OBS_MODULES_ENABLED core_modules_count) + string(REPLACE ";" "\",\n\t\"" core_modules_array_content "${OBS_MODULES_ENABLED}") + + set(OBS_CORE_MODULE_COUNT "${core_modules_count}") + + if(core_modules_count GREATER 0) + set(OBS_CORE_MODULE_LIST "\t\"${core_modules_array_content}\"") + else() + set(OBS_CORE_MODULE_LIST "\tNULL") + endif() + + configure_file( + "${libobs_source_directory}/obs-core-modules.c.in" + "${libobs_binary_directory}/obs-core-modules.c" + @ONLY + ) +endfunction()
View file
obs-studio-32.2.2.tar.xz/cmake/common/osconfig.cmake -> obs-studio-33.0.0.tar.xz/cmake/common/osconfig.cmake
Changed
@@ -17,4 +17,13 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux") string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) set(OS_${_SYSTEM_NAME_U} TRUE) + + option(ENABLE_FLATPAK "Enable Flatpak-specific implementations." OFF) + mark_as_advanced(ENABLE_FLATPAK) + + if(OS_LINUX AND ENABLE_FLATPAK) + set(OS_FLATPAK TRUE) + else() + set(OS_FLATPAK FALSE) + endif() endif()
View file
obs-studio-32.2.2.tar.xz/cmake/linux/defaults.cmake -> obs-studio-33.0.0.tar.xz/cmake/linux/defaults.cmake
Changed
@@ -25,13 +25,13 @@ set(OBS_EXECUTABLE_DESTINATION "${CMAKE_INSTALL_BINDIR}") set(OBS_INCLUDE_DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/obs") set(OBS_LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}") -set(OBS_PLUGIN_DESTINATION "${CMAKE_INSTALL_LIBDIR}/obs-plugins") +set(OBS_PLUGIN_DESTINATION "${CMAKE_INSTALL_LIBDIR}/obs-modules") set(OBS_SCRIPT_PLUGIN_DESTINATION "${CMAKE_INSTALL_LIBDIR}/obs-scripting") set(OBS_DATA_DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/obs") set(OBS_CMAKE_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") # Set additional paths used by OBS for self-discovery -set(OBS_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/obs-plugins") +set(OBS_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/obs-modules/core") set(OBS_SCRIPT_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/obs-scripting") set(OBS_DATA_PATH "${OBS_DATA_DESTINATION}") set(OBS_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
View file
obs-studio-32.2.2.tar.xz/cmake/linux/helpers.cmake -> obs-studio-33.0.0.tar.xz/cmake/linux/helpers.cmake
Changed
@@ -22,6 +22,10 @@ set(OBS_SOVERSION 30) if(target_type STREQUAL EXECUTABLE) + if(target STREQUAL browser-helper) + set(OBS_EXECUTABLE_DESTINATION "${OBS_PLUGIN_DESTINATION}/core") + endif() + install(TARGETS ${target} RUNTIME DESTINATION "${OBS_EXECUTABLE_DESTINATION}" COMPONENT Runtime) add_custom_command( @@ -124,7 +128,7 @@ set(plugin_destination "${OBS_SCRIPT_PLUGIN_DESTINATION}") set_property(TARGET ${target} PROPERTY INSTALL_RPATH "$ORIGIN/;$ORIGIN/..") else() - set(plugin_destination "${OBS_PLUGIN_DESTINATION}") + set(plugin_destination "${OBS_PLUGIN_DESTINATION}/core") endif() install( @@ -170,19 +174,20 @@ add_custom_command( TARGET ${target} POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/core" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${imported_location}" "${cef_location}/chrome-sandbox" "${cef_location}/libEGL.so" "${cef_location}/libGLESv2.so" "${cef_location}/libvk_swiftshader.so" "${cef_location}/libvulkan.so.1" "${cef_location}/v8_context_snapshot.bin" - "${cef_location}/vk_swiftshader_icd.json" "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/" + "${cef_location}/vk_swiftshader_icd.json" "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/core" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${cef_root_location}/Resources/chrome_100_percent.pak" "${cef_root_location}/Resources/chrome_200_percent.pak" "${cef_root_location}/Resources/icudtl.dat" - "${cef_root_location}/Resources/resources.pak" "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/" + "${cef_root_location}/Resources/resources.pak" + "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/core" COMMAND "${CMAKE_COMMAND}" -E copy_directory "${cef_root_location}/Resources/locales" - "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/locales" + "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/core/locales" COMMENT "Add Chromium Embedded Framework to library directory" ) @@ -200,21 +205,19 @@ "${cef_root_location}/Resources/chrome_200_percent.pak" "${cef_root_location}/Resources/icudtl.dat" "${cef_root_location}/Resources/resources.pak" - DESTINATION "${OBS_PLUGIN_DESTINATION}" + DESTINATION "${OBS_PLUGIN_DESTINATION}/core" COMPONENT Runtime ) install( DIRECTORY "${cef_root_location}/Resources/locales" - DESTINATION "${OBS_PLUGIN_DESTINATION}" + DESTINATION "${OBS_PLUGIN_DESTINATION}/core" USE_SOURCE_PERMISSIONS COMPONENT Runtime ) endif() endif() endif() - - set_property(GLOBAL APPEND PROPERTY OBS_MODULES_ENABLED ${target}) endif() target_install_resources(${target}) @@ -236,9 +239,9 @@ source_group("Resources/${relative_path}" FILES "${data_file}") endforeach() - get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) - if(target IN_LIST obs_module_list) - set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/${target}") + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL MODULE_LIBRARY) + set(target_destination "${OBS_DATA_DESTINATION}/obs-modules/core/${target}") elseif(target STREQUAL obs) set(target_destination "${OBS_DATA_DESTINATION}/obs-studio") else() @@ -267,11 +270,11 @@ # Helper function to add a specific resource to a bundle function(target_add_resource target resource) - get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) + get_target_property(target_type ${target} TYPE) if(ARGN) set(target_destination "${ARGN}") - elseif(${target} IN_LIST obs_module_list) - set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/${target}") + elseif(target_type STREQUAL MODULE_LIBRARY) + set(target_destination "${OBS_DATA_DESTINATION}/obs-modules/core/${target}") elseif(target STREQUAL obs) set(target_destination "${OBS_DATA_DESTINATION}/obs-studio") else()
View file
obs-studio-32.2.2.tar.xz/cmake/macos/helpers.cmake -> obs-studio-33.0.0.tar.xz/cmake/macos/helpers.cmake
Changed
@@ -169,6 +169,11 @@ "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/Resources" COMMENT "Add OBS::python import module" ) + set_property(TARGET ${target} APPEND PROPERTY XCODE_EMBED_PLUGINS obspython) + endif() + + if(TARGET obslua) + set_property(TARGET ${target} APPEND PROPERTY XCODE_EMBED_PLUGINS obslua) endif() if( @@ -303,7 +308,6 @@ endif() endif() - set_property(GLOBAL APPEND PROPERTY OBS_MODULES_ENABLED ${target}) set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target}) endif()
View file
obs-studio-32.2.2.tar.xz/cmake/windows/defaults.cmake -> obs-studio-33.0.0.tar.xz/cmake/windows/defaults.cmake
Changed
@@ -5,7 +5,7 @@ set(OBS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(OBS_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/rundir") -set(OBS_PLUGIN_DESTINATION obs-plugins/64bit) +set(OBS_PLUGIN_DESTINATION core) set(OBS_DATA_DESTINATION data) set(OBS_CMAKE_DESTINATION cmake) set(OBS_SCRIPT_PLUGIN_DESTINATION "${OBS_DATA_DESTINATION}/obs-scripting/64bit") @@ -14,7 +14,7 @@ set(OBS_LIBRARY_DESTINATION lib) set(OBS_INCLUDE_DESTINATION include) # Set relative paths used by OBS for self-discovery -set(OBS_PLUGIN_PATH "../../${CMAKE_INSTALL_LIBDIR}/obs-plugins/64bit") +set(OBS_PLUGIN_PATH "../../${CMAKE_INSTALL_LIBDIR}/core") set(OBS_SCRIPT_PLUGIN_PATH "../../${OBS_DATA_DESTINATION}/obs-scripting/64bit") set(OBS_DATA_PATH "../../${OBS_DATA_DESTINATION}")
View file
obs-studio-32.2.2.tar.xz/cmake/windows/helpers.cmake -> obs-studio-33.0.0.tar.xz/cmake/windows/helpers.cmake
Changed
@@ -22,9 +22,9 @@ if(target_type STREQUAL EXECUTABLE) if(target STREQUAL obs-browser-helper) - set(OBS_EXECUTABLE_DESTINATION "${OBS_PLUGIN_DESTINATION}") + set(OBS_EXECUTABLE_DESTINATION "${OBS_PLUGIN_DESTINATION}/obs-browser") elseif(target STREQUAL inject-helper OR target STREQUAL get-graphics-offsets) - set(OBS_EXECUTABLE_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture") + set(OBS_EXECUTABLE_DESTINATION "${OBS_PLUGIN_DESTINATION}/win-capture/data") _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION} x86) @@ -66,7 +66,7 @@ elseif(target STREQUAL "obspython" OR target STREQUAL "obslua") set(target_destination "${OBS_SCRIPT_PLUGIN_DESTINATION}") elseif(target STREQUAL graphics-hook) - set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/win-capture") + set(target_destination "${OBS_PLUGIN_DESTINATION}/win-capture/data") target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan64.json" "${target_destination}") target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan32.json" "${target_destination}") @@ -76,7 +76,7 @@ _target_install_obs(${target} DESTINATION ${target_destination} x64) endif() elseif(target STREQUAL obs-virtualcam-module) - set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow") + set(target_destination "${OBS_PLUGIN_DESTINATION}/win-dshow/data") _target_install_obs(${target} DESTINATION ${target_destination} x86) @@ -84,7 +84,7 @@ _target_install_obs(${target} DESTINATION ${target_destination} x64) endif() else() - set(target_destination "${OBS_PLUGIN_DESTINATION}") + set(target_destination "${OBS_PLUGIN_DESTINATION}/${target}") endif() _target_install_obs(${target} DESTINATION ${target_destination}) @@ -157,8 +157,6 @@ endif() endif() endif() - - set_property(GLOBAL APPEND PROPERTY OBS_MODULES_ENABLED ${target}) endif() target_link_options(${target} PRIVATE "/PDBALTPATH:$<TARGET_PDB_FILE_NAME:${target}>") @@ -314,9 +312,9 @@ source_group("Resources/${relative_path}" FILES "${data_file}") endforeach() - get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) - if(target IN_LIST obs_module_list) - set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/${target}") + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL MODULE_LIBRARY) + set(target_destination "${OBS_PLUGIN_DESTINATION}/${target}/data") elseif(target STREQUAL obs-studio) set(target_destination "${OBS_DATA_DESTINATION}/obs-studio") else() @@ -346,11 +344,11 @@ # Helper function to add a specific resource to a bundle function(target_add_resource target resource) - get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) + get_target_property(target_type ${target} TYPE) if(ARGN) set(target_destination "${ARGN}") - elseif(${target} IN_LIST obs_module_list) - set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/${target}") + elseif(target_type STREQUAL MODULE_LIBRARY) + set(target_destination "${OBS_PLUGIN_DESTINATION}/${target}/data") elseif(target STREQUAL obs-studio) set(target_destination "${OBS_DATA_DESTINATION}/obs-studio") else() @@ -397,7 +395,7 @@ set(plugins_list) foreach(library IN LISTS found_dependencies) - # CEF needs to be placed in obs-plugins directory on Windows, which is handled already + # CEF needs to be placed in core directory on Windows, which is handled already if(${library} STREQUAL CEF::Library) continue() endif()
View file
obs-studio-32.2.2.tar.xz/docs/sphinx/reference-canvases.rst -> obs-studio-33.0.0.tar.xz/docs/sphinx/reference-canvases.rst
Changed
@@ -300,3 +300,9 @@ Render the canvas's view. Must be called on the graphics thread. --------------------- + +.. function:: bool obs_canvas_video_active(obs_canvas_t *canvas) + + Returns true if video of the canvas is active, false otherwise. + +---------------------
View file
obs-studio-32.2.2.tar.xz/docs/sphinx/reference-frontend-api.rst -> obs-studio-33.0.0.tar.xz/docs/sphinx/reference-frontend-api.rst
Changed
@@ -150,6 +150,10 @@ Triggered when the replay buffer has fully stopped. + - **OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVING** + + Triggered when the replay buffer is saving. + - **OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVED** Triggered when the replay buffer has been saved. @@ -985,3 +989,11 @@ :param duplicate: *true* for paste duplicate, *false* for paste reference .. versionadded:: 32.2 + +--------------------------------------- + +.. function:: bool obs_frontend_is_safe_mode_enabled(void) + + :return: *true* if OBS was launched in Safe Mode, *false* otherwise + + .. versionadded:: 33.0
View file
obs-studio-32.2.2.tar.xz/docs/sphinx/reference-libobs-graphics-image-file.rst -> obs-studio-33.0.0.tar.xz/docs/sphinx/reference-libobs-graphics-image-file.rst
Changed
@@ -10,24 +10,24 @@ #include <graphics/image-file.h> -.. struct:: gs_image_file +.. struct:: gs_image_file_ex Image file structure -.. type:: gs_texture_t *gs_image_file.texture +.. type:: gs_texture_t *gs_image_file_ex.texture Texture -.. type:: struct gs_image_file gs_image_file_t +.. type:: struct gs_image_file_ex gs_image_file_ex_t Image file type --------------------- -.. function:: void gs_image_file_init(gs_image_file_t *image, const char *file) +.. function:: void gs_image_file_ex_init(gs_image_file_ex_t *image, const char *file, enum gs_image_alpha_mode alpha_mode) Loads an initializes an image file helper. Does not initialize the - texture; call :c:func:`gs_image_file_init_texture()` to initialize + texture; call :c:func:`gs_image_file_ex_init_texture()` to initialize the texture. :param image: Image file helper to initialize @@ -35,7 +35,7 @@ --------------------- -.. function:: void gs_image_file_free(gs_image_file_t *image) +.. function:: void gs_image_file_ex_free(gs_image_file_ex_t *image) Frees an image file helper @@ -43,28 +43,28 @@ --------------------- -.. function:: void gs_image_file_init_texture(gs_image_file_t *image) +.. function:: void gs_image_file_ex_init_texture(gs_image_file_ex_t *image) Initializes the texture of an image file helper. This is separate - from :c:func:`gs_image_file_init()` because it allows deferring the + from :c:func:`gs_image_file_ex_init()` because it allows deferring the graphics initialization if needed. :param image: Image file helper --------------------- -.. function:: bool gs_image_file_tick(gs_image_file_t *image, uint64_t elapsed_time_ns) +.. function:: bool gs_image_file_ex_tick(gs_image_file_ex_t *image, uint64_t elapsed_time_ns) Performs a tick operation on the image file helper (used primarily for animated file). Does not update the texture until - :c:func:`gs_image_file_update_texture()` is called. + :c:func:`gs_image_file_ex_update_texture()` is called. :param image: Image file helper :param elapsed_time_ns: Elapsed time in nanoseconds --------------------- -.. function:: void gs_image_file_update_texture(gs_image_file_t *image) +.. function:: void gs_image_file_ex_update_texture(gs_image_file_ex_t *image) Updates the texture (used primarily for animated files)
View file
obs-studio-32.2.2.tar.xz/docs/sphinx/reference-modules.rst -> obs-studio-33.0.0.tar.xz/docs/sphinx/reference-modules.rst
Changed
@@ -55,7 +55,19 @@ .. function:: void obs_module_unload(void) - Optional: Called when the module is unloaded. + Optional: Called when libobs is shutting down and the module is about + to be unloaded. All libobs objects are still active and valid at this + point. Use this function to save user settings and release any strong + references that the module itself is holding to libobs objects (sources, + canvases, outputs, encoders, and services). + + Do not attempt to release or destroy any still-active objects provided + by the module - ensure that they can continue functioning even after + returning from this function, as libobs may still need to call into the + module's callbacks (e.g., destroy) to clean up any remaining instances. + + After this function returns, do not make any further libobs API calls + outside of libobs callbacks. ---------------------
View file
obs-studio-32.2.2.tar.xz/docs/sphinx/reference-properties.rst -> obs-studio-33.0.0.tar.xz/docs/sphinx/reference-properties.rst
Changed
@@ -173,8 +173,8 @@ Adds a 'path' property. Can be a directory or a file. - If target is a file path, the filters should be this format, separated by - double semicolons, and extensions separated by space:: + If target is a file path or file save, the filters should be this format, + separated by double semicolons, and extensions separated by space:: "Example types 1 and 2 (*.ex1 *.ex2);;Example type 3 (*.ex3)" @@ -187,9 +187,10 @@ - **OBS_PATH_DIRECTORY** - Directory :param filter: If type is a file path, then describes the file filter - that the user can browse. Items are separated via - double semicolons. If multiple file types in a - filter, separate with space. + that the user can browse. If type is a save path, + then describes the file types the file can be + saved as. Items are separated via double semicolons. + If multiple file types in a filter, separate with space. :param default_path: The default path to start in, or *NULL* :return: The property @@ -740,6 +741,9 @@ :param val: The actual string value stored and will be returned by :c:func:`obs_data_get_string` :returns: The index of the list item. + Note: If ``p`` is of type OBS_COMBO_TYPE_EDITABLE, :c:func:`obs_data_get_string` will return ``name`` instead of + ``val``. + --------------------- .. function:: size_t obs_property_list_add_int(obs_property_t *p, const char *name, long long val) @@ -770,6 +774,9 @@ :param name: Localized name shown to user :param val: The actual string value stored and will be returned by :c:func:`obs_data_get_string` + Note: If ``p`` is of type OBS_COMBO_TYPE_EDITABLE, :c:func:`obs_data_get_string` will return ``name`` instead of + ``val``. + --------------------- .. function:: void obs_property_list_insert_int(obs_property_t *p, size_t idx, const char *name, long long val)
View file
obs-studio-32.2.2.tar.xz/docs/sphinx/reference-settings.rst -> obs-studio-33.0.0.tar.xz/docs/sphinx/reference-settings.rst
Changed
@@ -188,6 +188,9 @@ .. function:: const char *obs_data_get_string(obs_data_t *data, const char *name) + Note: If the data object was generated from a OBS_COMBO_TYPE_EDITABLE property, the property's ``name`` will be + returned instead of its ``val``. + --------------------- .. function:: long long obs_data_get_int(obs_data_t *data, const char *name)
View file
obs-studio-32.2.2.tar.xz/docs/sphinx/reference-sources.rst -> obs-studio-33.0.0.tar.xz/docs/sphinx/reference-sources.rst
Changed
@@ -976,6 +976,8 @@ Gets/sets the hidden property that determines whether it should be hidden from the user. Used when the source is still alive but should not be referenced. + .. deprecated:: 33.0 + --------------------- .. function:: uint32_t obs_source_get_output_flags(const obs_source_t *source) @@ -1210,6 +1212,9 @@ .. function:: void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type) enum obs_monitoring_type obs_source_get_monitoring_type(obs_source_t *source) + .. deprecated:: 33.0 + Use :c:func:`obs_source_set_monitoring_enabled` and :c:func:`obs_source_get_monitoring_enabled` instead. + Sets/gets the desktop audio monitoring type. :param order: | OBS_MONITORING_TYPE_NONE - Do not monitor @@ -1218,6 +1223,16 @@ --------------------- +.. function:: void obs_source_set_monitoring_enabled(obs_source_t *source, bool enable) + bool obs_source_get_monitoring_enabled(const obs_source_t *source) + + + Sets/gets the audio monitoring enabled state for the source. + + .. versionadded:: 33.0 + +--------------------- + .. function:: void obs_source_set_audio_active(obs_source_t *source, bool active) bool obs_source_audio_active(const obs_source_t *source)
View file
obs-studio-32.2.2.tar.xz/frontend/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/frontend/CMakeLists.txt
Changed
@@ -9,7 +9,7 @@ target_enable_feature(obs "User Interface") endif() -find_package(FFmpeg REQUIRED COMPONENTS avcodec avutil avformat) +find_package(FFmpeg 8.0 REQUIRED COMPONENTS avcodec avutil avformat) find_package(CURL REQUIRED) if(NOT TARGET OBS::json11) @@ -24,6 +24,10 @@ add_subdirectory("${CMAKE_SOURCE_DIR}/shared/bpm" bpm) endif() +if(NOT TARGET OBS::qt-obs-spinbox) + add_subdirectory("${CMAKE_SOURCE_DIR}/shared/qt/obs-spinbox" obs-spinbox) +endif() + add_executable(obs-studio) add_executable(OBS::studio ALIAS obs-studio) @@ -38,6 +42,7 @@ OBS::frontend-api OBS::json11 OBS::bpm + OBS::qt-obs-spinbox ) include(cmake/ui-components.cmake) @@ -94,10 +99,6 @@ endif() endforeach() -get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) -list(JOIN obs_module_list "|" SAFE_MODULES) -target_compile_definitions(obs-studio PRIVATE "SAFE_MODULES=\"${SAFE_MODULES}\"") - get_target_property(target_sources obs-studio SOURCES) set(target_cpp_sources ${target_sources}) set(target_hpp_sources ${target_sources})
View file
obs-studio-32.2.2.tar.xz/frontend/OBSApp.cpp -> obs-studio-33.0.0.tar.xz/frontend/OBSApp.cpp
Changed
@@ -30,9 +30,6 @@ #if !defined(_WIN32) && !defined(__APPLE__) #include <obs-nix-platform.h> -#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) -#include <qpa/qplatformnativeinterface.h> -#endif #endif #include <qt-wrappers.hpp> @@ -48,9 +45,9 @@ #endif #include <chrono> +#include <sstream> #ifdef _WIN32 -#include <sstream> #define WIN32_LEAN_AND_MEAN #include <windows.h> #else @@ -81,6 +78,8 @@ extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; #endif +constexpr double kDefaultSnapDistance = 5.0; + namespace { typedef struct UncleanLaunchAction { @@ -88,6 +87,35 @@ bool sendCrashReport = false; } UncleanLaunchAction; +enum class PluginFailureAction { Continue, OpenPluginManager }; + +PluginFailureAction handlePluginFailure() +{ + QMessageBox pluginWarning; + + pluginWarning.setIcon(QMessageBox::Warning); + + pluginWarning.setWindowTitle(QTStr("PluginFailure.Dialog.Title")); + pluginWarning.setText(QTStr("PluginFailure.Labels.Text")); + + QPushButton *continueButton = + pluginWarning.addButton(QTStr("PluginFailure.Dialog.Continue"), QMessageBox::RejectRole); + QPushButton *handleButton = + pluginWarning.addButton(QTStr("PluginFailure.Dialog.Open"), QMessageBox::AcceptRole); + + pluginWarning.setDefaultButton(continueButton); + + pluginWarning.exec(); + + bool openPluginManager = pluginWarning.clickedButton() == handleButton; + + if (openPluginManager) { + return PluginFailureAction::OpenPluginManager; + } else { + return PluginFailureAction::Continue; + } +} + UncleanLaunchAction handleUncleanShutdown(bool enableCrashUpload) { UncleanLaunchAction launchAction; @@ -97,9 +125,7 @@ QMessageBox crashWarning; crashWarning.setIcon(QMessageBox::Warning); -#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) crashWarning.setOption(QMessageBox::Option::DontUseNativeDialog); -#endif crashWarning.setWindowTitle(QTStr("CrashHandling.Dialog.Title")); crashWarning.setText(QTStr("CrashHandling.Labels.Text")); @@ -361,7 +387,7 @@ config_set_default_bool(userConfig, "BasicWindow", "ScreenSnapping", true); config_set_default_bool(userConfig, "BasicWindow", "SourceSnapping", true); config_set_default_bool(userConfig, "BasicWindow", "CenterSnapping", false); - config_set_default_double(userConfig, "BasicWindow", "SnapDistance", 10.0); + config_set_default_double(userConfig, "BasicWindow", "SnapDistance", kDefaultSnapDistance); config_set_default_bool(userConfig, "BasicWindow", "SpacingHelpersEnabled", true); config_set_default_bool(userConfig, "BasicWindow", "RecordWhenStreaming", false); config_set_default_bool(userConfig, "BasicWindow", "KeepRecordingWhenStreamStops", false); @@ -628,7 +654,8 @@ void OBSApp::MigrateLegacySettings(const uint32_t lastVersion) { - bool hasChanges = false; + bool hasUserConfigChanges = false; + bool hasGlobalConfigChanges = false; const uint32_t v19 = MAKE_SEMANTIC_VERSION(19, 0, 0); const uint32_t v21 = MAKE_SEMANTIC_VERSION(21, 0, 0); @@ -644,7 +671,7 @@ bool useOldDefaults = lastVersion && lastVersion < version; config_set_bool(userConfig, "General", configKey.c_str(), useOldDefaults); - hasChanges = true; + hasUserConfigChanges = true; } } @@ -653,7 +680,7 @@ bool layoutUpdated = UpdatePre22MultiviewLayout(layout); - hasChanges = hasChanges | layoutUpdated; + hasUserConfigChanges = hasUserConfigChanges | layoutUpdated; } if (lastVersion && lastVersion < v24) { @@ -663,12 +690,34 @@ config_set_string(userConfig, "General", "HotkeyFocusType", "DisableHotkeysInFocus"); } - hasChanges = true; + hasUserConfigChanges = true; + } + + if (lastVersion && lastVersion < MAKE_SEMANTIC_VERSION(33, 0, 0)) { + bool migratedUserSettings = config_has_user_value(appConfig, "General", "Pre33.0Migrated"); + + if (!migratedUserSettings) { + double currentSnapDistance = config_get_double(userConfig, "BasicWindow", "SnapDistance"); + + if (currentSnapDistance == 10.0) { + double newDefaultSnapDistance = kDefaultSnapDistance; + config_set_double(userConfig, "BasicWindow", "SnapDistance", newDefaultSnapDistance); + } + + config_set_bool(appConfig, "General", "Pre33.0Migrated", true); + + hasUserConfigChanges = true; + hasGlobalConfigChanges = true; + } } - if (hasChanges) { + if (hasUserConfigChanges) { userConfig.SaveSafe("tmp"); } + + if (hasGlobalConfigChanges) { + appConfig.SaveSafe("tmp"); + } } static constexpr string_view OBSGlobalIniPath = "/obs-studio/global.ini"; @@ -1219,7 +1268,7 @@ /* to get clang-format to behave */ task(param); }; - QMetaObject::invokeMethod(App(), "Exec", wait ? WaitConnection() : Qt::AutoConnection, Q_ARG(VoidFunc, doTask)); + QMetaObject::invokeMethod(App(), &OBSApp::Exec, wait ? WaitConnection() : Qt::AutoConnection, doTask); } bool OBSApp::OBSInit() @@ -1230,11 +1279,9 @@ #if !defined(_WIN32) && !defined(__APPLE__) if (QApplication::platformName() == "xcb") { -#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) auto native = qGuiApp->nativeInterface<QNativeInterface::QX11Application>(); obs_set_nix_platform_display(native->display()); -#endif obs_set_nix_platform(OBS_NIX_PLATFORM_X11_EGL); @@ -1243,11 +1290,9 @@ #ifdef ENABLE_WAYLAND if (QApplication::platformName().contains("wayland")) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) auto native = qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>(); obs_set_nix_platform_display(native->display()); -#endif obs_set_nix_platform(OBS_NIX_PLATFORM_WAYLAND); setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); @@ -1256,10 +1301,6 @@ } #endif -#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) - QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface(); - obs_set_nix_platform_display(native->nativeResourceForIntegration("display")); -#endif #endif #ifdef __APPLE__ @@ -2037,16 +2078,27 @@ emit logLineAdded(logLevel, message); } -void OBSApp::loadAppModules(struct obs_module_failure_info &mfi) +void OBSApp::loadAppModules() +{ + using PluginMode = OBS::PluginManager::Mode; + PluginMode mode = (disable_3p_plugins || safe_mode) ? PluginMode::CoreOnly : PluginMode::Full; + pluginManager_->setPluginMode(mode); + + pluginManager_->loadAllPlugins(portable_mode); +} + +void OBSApp::handlePluginLoadState() { - pluginManager_->preLoad(); - blog(LOG_INFO, "---------------------------------"); - obs_load_all_modules2(&mfi); - blog(LOG_INFO, "---------------------------------"); - obs_log_loaded_modules(); - blog(LOG_INFO, "---------------------------------"); - obs_post_load_modules(); - pluginManager_->postLoad(); + using PluginState = OBS::PluginManager::State; + PluginState loadState = pluginManager_->loadState(); + + if (loadState != PluginState::Success) { + PluginFailureAction action = handlePluginFailure(); + + if (action == PluginFailureAction::OpenPluginManager) { + pluginManagerOpenDialog(); + } + } } void OBSApp::pluginManagerOpenDialog()
View file
obs-studio-32.2.2.tar.xz/frontend/OBSApp.hpp -> obs-studio-33.0.0.tar.xz/frontend/OBSApp.hpp
Changed
@@ -137,7 +137,6 @@ private slots: void commitData(QSessionManager &manager); - void addLogLine(int logLevel, const QString &message); void themeFileChanged(const QString &); void applicationShutdown() noexcept; @@ -236,14 +235,16 @@ static void sigQuitSignalHandler(int); #endif - void loadAppModules(struct obs_module_failure_info &mfi); + void loadAppModules(); ThumbnailManager *thumbnails() const { return thumbnailManager; } // Plugin Manager Accessors void pluginManagerOpenDialog(); + void handlePluginLoadState(); public slots: + void addLogLine(int logLevel, const QString &message); void Exec(VoidFunc func); void processSigInt(); void processSigTerm();
View file
obs-studio-32.2.2.tar.xz/frontend/OBSStudioAPI.cpp -> obs-studio-33.0.0.tar.xz/frontend/OBSStudioAPI.cpp
Changed
@@ -11,6 +11,7 @@ extern volatile bool recording_paused; extern volatile bool replaybuf_active; extern volatile bool virtualcam_active; +extern bool safe_mode; template<typename T> inline size_t GetCallbackIdx(std::vector<OBSStudioCallback<T>> &callbacks, T callback, void *private_data) @@ -66,11 +67,11 @@ void OBSStudioAPI::obs_frontend_set_current_scene(obs_source_t *scene) { if (main->IsPreviewProgramMode()) { - QMetaObject::invokeMethod(main, "TransitionToScene", WaitConnection(), - Q_ARG(OBSSource, OBSSource(scene))); + QMetaObject::invokeMethod( + main, this, scene = OBSSource(scene)() { main->TransitionToScene(scene); }, WaitConnection()); } else { - QMetaObject::invokeMethod(main, "SetCurrentScene", WaitConnection(), Q_ARG(OBSSource, OBSSource(scene)), - Q_ARG(bool, false)); + QMetaObject::invokeMethod(main, qOverload<OBSSource, bool>(&OBSBasic::SetCurrentScene), + WaitConnection(), OBSSource(scene), false); } } @@ -93,7 +94,7 @@ void OBSStudioAPI::obs_frontend_set_current_transition(obs_source_t *transition) { - QMetaObject::invokeMethod(main, "SetTransition", Q_ARG(OBSSource, OBSSource(transition))); + QMetaObject::invokeMethod(main, &OBSBasic::SetTransition, OBSSource(transition)); } int OBSStudioAPI::obs_frontend_get_transition_duration() @@ -103,17 +104,17 @@ void OBSStudioAPI::obs_frontend_set_transition_duration(int duration) { - QMetaObject::invokeMethod(main, "SetTransitionDuration", Q_ARG(int, duration)); + QMetaObject::invokeMethod(main, &OBSBasic::SetTransitionDuration, duration); } void OBSStudioAPI::obs_frontend_release_tbar() { - QMetaObject::invokeMethod(main, "TBarReleased"); + QMetaObject::invokeMethod(main, &OBSBasic::TBarReleased); } void OBSStudioAPI::obs_frontend_set_tbar_position(int position) { - QMetaObject::invokeMethod(main, "TBarChanged", Q_ARG(int, position)); + QMetaObject::invokeMethod(main, &OBSBasic::TBarChanged, position); } int OBSStudioAPI::obs_frontend_get_tbar_position() @@ -161,8 +162,9 @@ bool OBSStudioAPI::obs_frontend_add_scene_collection(const char *name) { bool success = false; - QMetaObject::invokeMethod(main, "CreateNewSceneCollection", WaitConnection(), Q_RETURN_ARG(bool, success), - Q_ARG(QString, QT_UTF8(name))); + QMetaObject::invokeMethod( + main, this, &success, name = QT_UTF8(name)() { success = main->CreateNewSceneCollection(name); }, + WaitConnection()); return success; } @@ -208,27 +210,27 @@ void OBSStudioAPI::obs_frontend_create_profile(const char *name) { - QMetaObject::invokeMethod(main, "CreateNewProfile", Q_ARG(QString, name)); + QMetaObject::invokeMethod(main, &OBSBasic::CreateNewProfile, QString::fromUtf8(name)); } void OBSStudioAPI::obs_frontend_duplicate_profile(const char *name) { - QMetaObject::invokeMethod(main, "CreateDuplicateProfile", Q_ARG(QString, name)); + QMetaObject::invokeMethod(main, &OBSBasic::CreateDuplicateProfile, QString::fromUtf8(name)); } void OBSStudioAPI::obs_frontend_delete_profile(const char *profile) { - QMetaObject::invokeMethod(main, "DeleteProfile", Q_ARG(QString, profile)); + QMetaObject::invokeMethod(main, &OBSBasic::DeleteProfile, QString::fromUtf8(profile)); } void OBSStudioAPI::obs_frontend_streaming_start() { - QMetaObject::invokeMethod(main, "StartStreaming"); + QMetaObject::invokeMethod(main, &OBSBasic::StartStreaming); } void OBSStudioAPI::obs_frontend_streaming_stop() { - QMetaObject::invokeMethod(main, "StopStreaming"); + QMetaObject::invokeMethod(main, &OBSBasic::StopStreaming); } bool OBSStudioAPI::obs_frontend_streaming_active() @@ -238,12 +240,12 @@ void OBSStudioAPI::obs_frontend_recording_start() { - QMetaObject::invokeMethod(main, "StartRecording"); + QMetaObject::invokeMethod(main, &OBSBasic::StartRecording); } void OBSStudioAPI::obs_frontend_recording_stop() { - QMetaObject::invokeMethod(main, "StopRecording"); + QMetaObject::invokeMethod(main, &OBSBasic::StopRecording); } bool OBSStudioAPI::obs_frontend_recording_active() @@ -294,17 +296,17 @@ void OBSStudioAPI::obs_frontend_replay_buffer_start() { - QMetaObject::invokeMethod(main, "StartReplayBuffer"); + QMetaObject::invokeMethod(main, &OBSBasic::StartReplayBuffer); } void OBSStudioAPI::obs_frontend_replay_buffer_save() { - QMetaObject::invokeMethod(main, "ReplayBufferSave"); + QMetaObject::invokeMethod(main, &OBSBasic::ReplayBufferSave); } void OBSStudioAPI::obs_frontend_replay_buffer_stop() { - QMetaObject::invokeMethod(main, "StopReplayBuffer"); + QMetaObject::invokeMethod(main, &OBSBasic::StopReplayBuffer); } bool OBSStudioAPI::obs_frontend_replay_buffer_active() @@ -455,7 +457,7 @@ proj.type = ProjectorType::Multiview; } } - QMetaObject::invokeMethod(main, "OpenSavedProjector", WaitConnection(), Q_ARG(SavedProjectorInfo *, &proj)); + QMetaObject::invokeMethod(main, this, &proj() { main->OpenSavedProjector(&proj); }, WaitConnection()); } void OBSStudioAPI::obs_frontend_save() @@ -465,12 +467,12 @@ void OBSStudioAPI::obs_frontend_defer_save_begin() { - QMetaObject::invokeMethod(main, "DeferSaveBegin"); + QMetaObject::invokeMethod(main, &OBSBasic::DeferSaveBegin); } void OBSStudioAPI::obs_frontend_defer_save_end() { - QMetaObject::invokeMethod(main, "DeferSaveEnd"); + QMetaObject::invokeMethod(main, &OBSBasic::DeferSaveEnd); } void OBSStudioAPI::obs_frontend_add_save_callback(obs_frontend_save_cb callback, void *private_data) @@ -546,7 +548,7 @@ void OBSStudioAPI::obs_frontend_preview_program_trigger_transition() { - QMetaObject::invokeMethod(main, "TransitionClicked"); + QMetaObject::invokeMethod(main, &OBSBasic::TransitionClicked); } bool OBSStudioAPI::obs_frontend_preview_enabled() @@ -556,8 +558,10 @@ void OBSStudioAPI::obs_frontend_set_preview_enabled(bool enable) { - if (main->previewEnabled != enable) { - main->EnablePreviewDisplay(enable); + if (enable) { + main->EnablePreview(); + } else { + main->DisablePreview(); } } @@ -574,19 +578,19 @@ void OBSStudioAPI::obs_frontend_set_current_preview_scene(obs_source_t *scene) { if (main->IsPreviewProgramMode()) { - QMetaObject::invokeMethod(main, "SetCurrentScene", Q_ARG(OBSSource, OBSSource(scene)), - Q_ARG(bool, false)); + QMetaObject::invokeMethod(main, qOverload<OBSSource, bool>(&OBSBasic::SetCurrentScene), + OBSSource(scene), false); } } void OBSStudioAPI::obs_frontend_take_screenshot() { - QMetaObject::invokeMethod(main, "Screenshot"); + QMetaObject::invokeMethod(main, &OBSBasic::Screenshot, nullptr); } void OBSStudioAPI::obs_frontend_take_source_screenshot(obs_source_t *source) { - QMetaObject::invokeMethod(main, "Screenshot", Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(main, &OBSBasic::Screenshot, OBSSource(source)); } obs_output_t *OBSStudioAPI::obs_frontend_get_virtualcam_output() @@ -597,12 +601,12 @@ void OBSStudioAPI::obs_frontend_start_virtualcam() { - QMetaObject::invokeMethod(main, "StartVirtualCam"); + QMetaObject::invokeMethod(main, &OBSBasic::StartVirtualCam); } void OBSStudioAPI::obs_frontend_stop_virtualcam() { - QMetaObject::invokeMethod(main, "StopVirtualCam"); + QMetaObject::invokeMethod(main, &OBSBasic::StopVirtualCam); } bool OBSStudioAPI::obs_frontend_virtualcam_active() @@ -617,22 +621,22 @@ void OBSStudioAPI::obs_frontend_open_source_properties(obs_source_t *source) { - QMetaObject::invokeMethod(main, "OpenProperties", Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(main, &OBSBasic::OpenProperties, OBSSource(source)); } void OBSStudioAPI::obs_frontend_open_source_filters(obs_source_t *source) { - QMetaObject::invokeMethod(main, "OpenFilters", Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(main, &OBSBasic::OpenFilters, OBSSource(source)); } void OBSStudioAPI::obs_frontend_open_source_interaction(obs_source_t *source) { - QMetaObject::invokeMethod(main, "OpenInteraction", Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(main, &OBSBasic::OpenInteraction, OBSSource(source)); } void OBSStudioAPI::obs_frontend_open_sceneitem_edit_transform(obs_sceneitem_t *item) { - QMetaObject::invokeMethod(main, "OpenEditTransform", Q_ARG(OBSSceneItem, OBSSceneItem(item))); + QMetaObject::invokeMethod(main, &OBSBasic::OpenEditTransform, OBSSceneItem(item)); } char *OBSStudioAPI::obs_frontend_get_current_record_output_path() @@ -718,6 +722,11 @@ main->pasteSceneItem(scene, duplicate); } +bool OBSStudioAPI::obs_frontend_is_safe_mode_enabled() +{ + return safe_mode; +} + void OBSStudioAPI::on_load(obs_data_t *settings) { for (size_t i = saveCallbacks.size(); i > 0; i--) {
View file
obs-studio-32.2.2.tar.xz/frontend/OBSStudioAPI.hpp -> obs-studio-33.0.0.tar.xz/frontend/OBSStudioAPI.hpp
Changed
@@ -230,6 +230,8 @@ void obs_frontend_paste_sceneitem(obs_scene_t *scene, bool duplicate) override; + bool obs_frontend_is_safe_mode_enabled(void) override; + void on_load(obs_data_t *settings) override; void on_preload(obs_data_t *settings) override;
View file
obs-studio-32.2.2.tar.xz/frontend/api/obs-frontend-api.cpp -> obs-studio-33.0.0.tar.xz/frontend/api/obs-frontend-api.cpp
Changed
@@ -686,3 +686,8 @@ return c->obs_frontend_paste_sceneitem(scene, duplicate); } } + +bool obs_frontend_is_safe_mode_enabled(void) +{ + return !!callbacks_valid() ? c->obs_frontend_is_safe_mode_enabled() : false; +}
View file
obs-studio-32.2.2.tar.xz/frontend/api/obs-frontend-api.h -> obs-studio-33.0.0.tar.xz/frontend/api/obs-frontend-api.h
Changed
@@ -65,6 +65,8 @@ OBS_FRONTEND_EVENT_CANVAS_ADDED, OBS_FRONTEND_EVENT_CANVAS_REMOVED, + + OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVING, }; /* ------------------------------------------------------------------------- */ @@ -260,6 +262,8 @@ EXPORT bool obs_frontend_can_paste_sceneitem(bool duplicate); EXPORT void obs_frontend_paste_sceneitem(obs_scene_t *scene, bool duplicate); +EXPORT bool obs_frontend_is_safe_mode_enabled(void); + /* ------------------------------------------------------------------------- */ #ifdef __cplusplus
View file
obs-studio-32.2.2.tar.xz/frontend/api/obs-frontend-internal.hpp -> obs-studio-33.0.0.tar.xz/frontend/api/obs-frontend-internal.hpp
Changed
@@ -142,6 +142,7 @@ virtual void obs_frontend_copy_sceneitem(obs_sceneitem_t *item) = 0; virtual bool obs_frontend_can_paste_sceneitem(bool duplicate) = 0; virtual void obs_frontend_paste_sceneitem(obs_scene_t *scene, bool duplicate) = 0; + virtual bool obs_frontend_is_safe_mode_enabled(void) = 0; }; EXPORT void obs_frontend_set_callbacks_internal(obs_frontend_callbacks *callbacks);
View file
obs-studio-32.2.2.tar.xz/frontend/cmake/feature-plugin-manager.cmake -> obs-studio-33.0.0.tar.xz/frontend/cmake/feature-plugin-manager.cmake
Changed
@@ -1,12 +1,38 @@ find_package(nlohmann_json 3.11 REQUIRED) +set(OBS_PLATFORM_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/") +set(OBS_PLATFORM_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}/") +set(OBS_PLATFORM_DATA_PATH "${CMAKE_INSTALL_DATAROOTDIR}/") +set(OBS_PLATFORM_CORE_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/obs-modules/core") +set(OBS_PLATFORM_CORE_DATA_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/obs/obs-modules/core") +set(OBS_PLATFORM_PLUGIN_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/obs-modules/plugins") +set(OBS_PLATFORM_PLUGIN_DATA_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/obs/obs-modules/plugins") + target_sources( obs-studio PRIVATE + plugin-manager/InstalledPluginRow.cpp + plugin-manager/InstalledPluginRow.hpp plugin-manager/PluginManager.cpp plugin-manager/PluginManager.hpp plugin-manager/PluginManagerWindow.cpp plugin-manager/PluginManagerWindow.hpp + plugin-manager/PluginModuleLoader.hpp ) +if(OS_WINDOWS) + target_sources(obs-studio PRIVATE plugin-manager/PluginModuleLoader_Windows.cpp) +elseif(OS_MACOS) + target_sources(obs-studio PRIVATE plugin-manager/PluginModuleLoader_MacOS.mm) +elseif(OS_FLATPAK) + configure_file(plugin-manager/LoaderPaths_Flatpak.hpp.in LoaderPaths_Flatpak.hpp @ONLY) + target_sources(obs-studio PRIVATE plugin-manager/PluginModuleLoader_Flatpak.cpp LoaderPaths_Flatpak.hpp) +elseif(OS_LINUX) + configure_file(plugin-manager/LoaderPaths_Linux.hpp.in LoaderPaths_Linux.hpp @ONLY) + target_sources(obs-studio PRIVATE plugin-manager/PluginModuleLoader_Linux.cpp LoaderPaths_Linux.hpp) +elseif(OS_FREEBSD OR OS_OPENBSD) + configure_file(plugin-manager/LoaderPaths_BSD.hpp.in LoaderPaths_BSD.hpp @ONLY) + target_sources(obs-studio PRIVATE plugin-manager/PluginModuleLoader_BSD.cpp LoaderPaths_BSD.hpp) +endif() + target_link_libraries(obs-studio PRIVATE nlohmann_json::nlohmann_json)
View file
obs-studio-32.2.2.tar.xz/frontend/cmake/feature-whatsnew.cmake -> obs-studio-33.0.0.tar.xz/frontend/cmake/feature-whatsnew.cmake
Changed
@@ -6,9 +6,7 @@ if(OS_MACOS) include(cmake/feature-macos-update.cmake) elseif(OS_LINUX) - set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) - find_package(MbedTLS REQUIRED) - set(CMAKE_FIND_PACKAGE_PREFER_CONFIG FALSE) + find_package(MbedTLS 3...<4 REQUIRED) find_package(nlohmann_json 3.11 REQUIRED) if(NOT TARGET OBS::blake2)
View file
obs-studio-32.2.2.tar.xz/frontend/cmake/linux/com.obsproject.Studio.desktop -> obs-studio-33.0.0.tar.xz/frontend/cmake/linux/com.obsproject.Studio.desktop
Changed
@@ -119,6 +119,8 @@ Commenttl_PH=Walang Bayad at Bukas na Pinagmulang Palatuntunan ng Pagsasahimpapawid/Pagtatala GenericNametr_TR=Yayın/Kayıt Yazılımı Commenttr_TR=Ücretsiz ve Açık Kaynaklı Yayın/Kayıt Yazılımı +GenericNamett_RU=Стриминг/видео яздыру программасы +Commenttt_RU=Ирекле һәм ачык чыганаклы cтриминг/видео яздыру программасы GenericNameug_CN=ئېقىم تارقىتىش/خاتىرىلەش يۇمشاق دېتالى Commentug_CN=ئەركىن ۋە ئوچۇق كودلۇق ئېقىم تارقىتىش/سىنغا ئېلىش يۇمشاق دېتالى GenericNameuk_UA=Програма для трансляцій/запису
View file
obs-studio-32.2.2.tar.xz/frontend/cmake/os-freebsd.cmake -> obs-studio-33.0.0.tar.xz/frontend/cmake/os-freebsd.cmake
Changed
@@ -9,10 +9,6 @@ target_compile_definitions(obs-studio PRIVATE OBS_INSTALL_PREFIX="${OBS_INSTALL_PREFIX}") target_link_libraries(obs-studio PRIVATE Qt::DBus procstat) -if(Qt6_VERSION AND Qt6_VERSION VERSION_LESS "6.9.0") - target_link_libraries(obs-studio PRIVATE Qt::GuiPrivate) -endif() - find_package(Libpci REQUIRED) target_link_libraries(obs-studio PRIVATE Libpci::pci)
View file
obs-studio-32.2.2.tar.xz/frontend/cmake/os-linux.cmake -> obs-studio-33.0.0.tar.xz/frontend/cmake/os-linux.cmake
Changed
@@ -12,10 +12,6 @@ ) target_link_libraries(obs-studio PRIVATE Qt::DBus) -if(Qt6_VERSION AND Qt6_VERSION VERSION_LESS "6.9.0") - target_link_libraries(obs-studio PRIVATE Qt::GuiPrivate) -endif() - find_package(Libpci REQUIRED) target_link_libraries(obs-studio PRIVATE Libpci::pci)
View file
obs-studio-32.2.2.tar.xz/frontend/cmake/os-windows.cmake -> obs-studio-33.0.0.tar.xz/frontend/cmake/os-windows.cmake
Changed
@@ -6,9 +6,7 @@ add_subdirectory("${CMAKE_SOURCE_DIR}/deps/w32-pthreads" "${CMAKE_BINARY_DIR}/deps/w32-pthreads") endif() -set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) -find_package(MbedTLS REQUIRED) -set(CMAKE_FIND_PACKAGE_PREFER_CONFIG FALSE) +find_package(MbedTLS 3...<4 REQUIRED) find_package(Detours REQUIRED) find_package(nlohmann_json 3.11 REQUIRED)
View file
obs-studio-32.2.2.tar.xz/frontend/cmake/ui-components.cmake -> obs-studio-33.0.0.tar.xz/frontend/cmake/ui-components.cmake
Changed
@@ -44,6 +44,8 @@ components/FocusList.hpp components/GameCaptureToolbar.cpp components/GameCaptureToolbar.hpp + components/InfoChip.cpp + components/InfoChip.hpp components/ImageSourceToolbar.cpp components/ImageSourceToolbar.hpp components/MediaControls.cpp
View file
obs-studio-32.2.2.tar.xz/frontend/components/ApplicationAudioCaptureToolbar.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/ApplicationAudioCaptureToolbar.cpp
Changed
@@ -13,6 +13,10 @@ ui->activateButton = nullptr; obs_module_t *mod = obs_get_module("win-wasapi"); + if (!mod) { + return; + } + const char *device_str = obs_module_get_locale_text(mod, "Window"); ui->deviceLabel->setText(device_str);
View file
obs-studio-33.0.0.tar.xz/frontend/components/InfoChip.cpp
Added
@@ -0,0 +1,28 @@ +/****************************************************************************** + Copyright (C) 2026 by Warchamp7 <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "InfoChip.hpp" + +InfoChip::InfoChip(QWidget *parent) : QLabel(parent) +{ + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); +} + +InfoChip::InfoChip(const QString &text, QWidget *parent) : InfoChip(parent) +{ + setText(text); +}
View file
obs-studio-33.0.0.tar.xz/frontend/components/InfoChip.hpp
Added
@@ -0,0 +1,28 @@ +/****************************************************************************** + Copyright (C) 2026 by Warchamp7 <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <QLabel> + +class InfoChip : public QLabel { + Q_OBJECT + +public: + explicit InfoChip(QWidget *parent); + explicit InfoChip(const QString &text, QWidget *parent); +};
View file
obs-studio-32.2.2.tar.xz/frontend/components/MediaControls.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/MediaControls.cpp
Changed
@@ -10,37 +10,37 @@ void MediaControls::OBSMediaStopped(void *data, calldata_t *) { MediaControls *media = static_cast<MediaControls *>(data); - QMetaObject::invokeMethod(media, "SetRestartState"); + QMetaObject::invokeMethod(media, &MediaControls::SetRestartState); } void MediaControls::OBSMediaPlay(void *data, calldata_t *) { MediaControls *media = static_cast<MediaControls *>(data); - QMetaObject::invokeMethod(media, "SetPlayingState"); + QMetaObject::invokeMethod(media, &MediaControls::SetPlayingState); } void MediaControls::OBSMediaPause(void *data, calldata_t *) { MediaControls *media = static_cast<MediaControls *>(data); - QMetaObject::invokeMethod(media, "SetPausedState"); + QMetaObject::invokeMethod(media, &MediaControls::SetPausedState); } void MediaControls::OBSMediaStarted(void *data, calldata_t *) { MediaControls *media = static_cast<MediaControls *>(data); - QMetaObject::invokeMethod(media, "SetPlayingState"); + QMetaObject::invokeMethod(media, &MediaControls::SetPlayingState); } void MediaControls::OBSMediaNext(void *data, calldata_t *) { MediaControls *media = static_cast<MediaControls *>(data); - QMetaObject::invokeMethod(media, "UpdateSlideCounter"); + QMetaObject::invokeMethod(media, &MediaControls::UpdateSlideCounter); } void MediaControls::OBSMediaPrevious(void *data, calldata_t *) { MediaControls *media = static_cast<MediaControls *>(data); - QMetaObject::invokeMethod(media, "UpdateSlideCounter"); + QMetaObject::invokeMethod(media, &MediaControls::UpdateSlideCounter); } MediaControls::MediaControls(QWidget *parent) : QWidget(parent), ui(new Ui::MediaControls)
View file
obs-studio-32.2.2.tar.xz/frontend/components/OBSAdvAudioCtrl.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/OBSAdvAudioCtrl.cpp
Changed
@@ -40,9 +40,8 @@ percent = new QSpinBox(); forceMono = new QCheckBox(); balance = new BalanceSlider(); - if (obs_audio_monitoring_available()) { - monitoringType = new QComboBox(); - } + monitoringCheckBox = new QCheckBox(); + syncOffset = new QSpinBox(); mixer1 = new QCheckBox(); mixer2 = new QCheckBox(); @@ -58,9 +57,7 @@ sigs.emplace_back(handler, "volume", OBSSourceVolumeChanged, this); sigs.emplace_back(handler, "audio_sync", OBSSourceSyncChanged, this); sigs.emplace_back(handler, "update_flags", OBSSourceFlagsChanged, this); - if (obs_audio_monitoring_available()) { - sigs.emplace_back(handler, "audio_monitoring", OBSSourceMonitoringTypeChanged, this); - } + sigs.emplace_back(handler, "monitor", OBSSourceMonitoringChanged, this); sigs.emplace_back(handler, "audio_mixers", OBSSourceMixersChanged, this); sigs.emplace_back(handler, "audio_balance", OBSSourceBalanceChanged, this); sigs.emplace_back(handler, "rename", OBSSourceRenamed, this); @@ -152,18 +149,11 @@ syncOffset->setFixedWidth(100); syncOffset->setAccessibleName(QTStr("Basic.AdvAudio.SyncOffsetSource").arg(sourceName)); - int idx; - if (obs_audio_monitoring_available()) { - monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.None"), (int)OBS_MONITORING_TYPE_NONE); - monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.Both"), - (int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); - monitoringType->setPlaceholderText(QTStr("Basic.AdvAudio.Monitoring.MonitorOnly")); - int mt = (int)obs_source_get_monitoring_type(source); - idx = monitoringType->findData(mt); - monitoringType->setCurrentIndex(idx); - monitoringType->setAccessibleName(QTStr("Basic.AdvAudio.MonitoringSource").arg(sourceName)); - monitoringType->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - } + monitoringCheckBox->setEnabled(obs_audio_monitoring_available()); + monitoringCheckBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + monitoringCheckBox->setText(QTStr("Enable")); + monitoringCheckBox->setChecked(obs_source_get_monitoring_enabled(source)); + monitoringCheckBox->setAccessibleName(QTStr("Basic.AdvAudio.MonitoringSource").arg(sourceName)); mixer1->setText("1"); mixer1->setChecked(mixers & (1 << 0)); @@ -208,9 +198,7 @@ connect(balance, &BalanceSlider::valueChanged, this, &OBSAdvAudioCtrl::balanceChanged); connect(balance, &BalanceSlider::doubleClicked, this, &OBSAdvAudioCtrl::ResetBalance); connect(syncOffset, &QSpinBox::valueChanged, this, &OBSAdvAudioCtrl::syncOffsetChanged); - if (obs_audio_monitoring_available()) { - connect(monitoringType, &QComboBox::currentIndexChanged, this, &OBSAdvAudioCtrl::monitoringTypeChanged); - } + connect(monitoringCheckBox, &QCheckBox::toggled, this, &OBSAdvAudioCtrl::monitoringChanged); auto connectMixer = this(QCheckBox *mixer, int num) { connect(mixer, &QCheckBox::clicked, this, @@ -235,9 +223,7 @@ forceMono->deleteLater(); balanceContainer->deleteLater(); syncOffset->deleteLater(); - if (obs_audio_monitoring_available()) { - monitoringType->deleteLater(); - } + monitoringCheckBox->deleteLater(); mixerContainer->deleteLater(); } @@ -253,9 +239,7 @@ layout->addWidget(forceMono, lastRow, idx++); layout->addWidget(balanceContainer, lastRow, idx++); layout->addWidget(syncOffset, lastRow, idx++); - if (obs_audio_monitoring_available()) { - layout->addWidget(monitoringType, lastRow, idx++); - } + layout->addWidget(monitoringCheckBox, lastRow, idx++); layout->addWidget(mixerContainer, lastRow, idx++); layout->layout()->setAlignment(mixerContainer, Qt::AlignVCenter); layout->setHorizontalSpacing(15); @@ -266,57 +250,57 @@ void OBSAdvAudioCtrl::OBSSourceActivated(void *param, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceActiveChanged", Q_ARG(bool, true)); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SourceActiveChanged, true); } void OBSAdvAudioCtrl::OBSSourceDeactivated(void *param, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceActiveChanged", Q_ARG(bool, false)); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SourceActiveChanged, false); } void OBSAdvAudioCtrl::OBSSourceFlagsChanged(void *param, calldata_t *calldata) { uint32_t flags = (uint32_t)calldata_int(calldata, "flags"); - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceFlagsChanged", Q_ARG(uint32_t, flags)); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SourceFlagsChanged, flags); } void OBSAdvAudioCtrl::OBSSourceVolumeChanged(void *param, calldata_t *calldata) { float volume = (float)calldata_float(calldata, "volume"); - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceVolumeChanged", Q_ARG(float, volume)); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SourceVolumeChanged, volume); } void OBSAdvAudioCtrl::OBSSourceSyncChanged(void *param, calldata_t *calldata) { int64_t offset = calldata_int(calldata, "offset"); - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceSyncChanged", Q_ARG(int64_t, offset)); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SourceSyncChanged, offset); } -void OBSAdvAudioCtrl::OBSSourceMonitoringTypeChanged(void *param, calldata_t *calldata) +void OBSAdvAudioCtrl::OBSSourceMonitoringChanged(void *param, calldata_t *calldata) { - int type = calldata_int(calldata, "type"); - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceMonitoringTypeChanged", - Q_ARG(int, type)); + bool enabled = calldata_bool(calldata, "monitor"); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SourceMonitoringChanged, + enabled); } void OBSAdvAudioCtrl::OBSSourceMixersChanged(void *param, calldata_t *calldata) { uint32_t mixers = (uint32_t)calldata_int(calldata, "mixers"); - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceMixersChanged", - Q_ARG(uint32_t, mixers)); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SourceMixersChanged, mixers); } void OBSAdvAudioCtrl::OBSSourceBalanceChanged(void *param, calldata_t *calldata) { int balance = (float)calldata_float(calldata, "balance") * 100.0f; - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceBalanceChanged", Q_ARG(int, balance)); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SourceBalanceChanged, + balance); } void OBSAdvAudioCtrl::OBSSourceRenamed(void *param, calldata_t *calldata) { QString newName = QT_UTF8(calldata_string(calldata, "new_name")); - QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SetSourceName", Q_ARG(QString, newName)); + QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), &OBSAdvAudioCtrl::SetSourceName, newName); } /* ------------------------------------------------------------------------- */ @@ -370,12 +354,11 @@ syncOffset->blockSignals(false); } -void OBSAdvAudioCtrl::SourceMonitoringTypeChanged(int type) +void OBSAdvAudioCtrl::SourceMonitoringChanged(bool enabled) { - int idx = monitoringType->findData(type); - monitoringType->blockSignals(true); - monitoringType->setCurrentIndex(idx); - monitoringType->blockSignals(false); + monitoringCheckBox->blockSignals(true); + monitoringCheckBox->setChecked(enabled); + monitoringCheckBox->blockSignals(false); } void OBSAdvAudioCtrl::SourceMixersChanged(uint32_t mixers) @@ -530,39 +513,25 @@ std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid, true); } -void OBSAdvAudioCtrl::monitoringTypeChanged(int index) +void OBSAdvAudioCtrl::monitoringChanged(bool enabled) { - obs_monitoring_type prev = obs_source_get_monitoring_type(source); + bool prev = obs_source_get_monitoring_enabled(source); - obs_monitoring_type mt = (obs_monitoring_type)monitoringType->itemData(index).toInt(); - obs_source_set_monitoring_type(source, mt); - - const char *type = nullptr; - - switch (mt) { - case OBS_MONITORING_TYPE_NONE: - type = "none"; - break; - case OBS_MONITORING_TYPE_MONITOR_ONLY: - type = "monitor only"; - break; - case OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT: - type = "monitor and output"; - break; - } + obs_source_set_monitoring_enabled(source, enabled); const char *name = obs_source_get_name(source); - blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s", name ? name : "(null)", type); + blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s", name ? name : "(null)", + enabled ? "true" : "false"); - auto undo_redo = (const std::string &uuid, obs_monitoring_type val) { + auto undo_redo = (const std::string &uuid, bool val) { OBSSourceAutoRelease source = obs_get_source_by_uuid(uuid.c_str()); - obs_source_set_monitoring_type(source, val); + obs_source_set_monitoring_enabled(source, val); }; const char *uuid = obs_source_get_uuid(source); OBSBasic::Get()->undo_s.add_action(QTStr("Undo.MonitoringType.Change").arg(name), std::bind(undo_redo, std::placeholders::_1, prev), - std::bind(undo_redo, std::placeholders::_1, mt), uuid, uuid); + std::bind(undo_redo, std::placeholders::_1, enabled), uuid, uuid); } static inline void setMixer(obs_source_t *source, const int mixerIdx, const bool checked)
View file
obs-studio-32.2.2.tar.xz/frontend/components/OBSAdvAudioCtrl.hpp -> obs-studio-33.0.0.tar.xz/frontend/components/OBSAdvAudioCtrl.hpp
Changed
@@ -40,7 +40,7 @@ QPointer<QLabel> labelL; QPointer<QLabel> labelR; QPointer<QSpinBox> syncOffset; - QPointer<QComboBox> monitoringType; + QPointer<QCheckBox> monitoringCheckBox; QPointer<QCheckBox> mixer1; QPointer<QCheckBox> mixer2; QPointer<QCheckBox> mixer3; @@ -55,7 +55,7 @@ static void OBSSourceFlagsChanged(void *param, calldata_t *calldata); static void OBSSourceVolumeChanged(void *param, calldata_t *calldata); static void OBSSourceSyncChanged(void *param, calldata_t *calldata); - static void OBSSourceMonitoringTypeChanged(void *param, calldata_t *calldata); + static void OBSSourceMonitoringChanged(void *param, calldata_t *calldata); static void OBSSourceMixersChanged(void *param, calldata_t *calldata); static void OBSSourceBalanceChanged(void *param, calldata_t *calldata); static void OBSSourceRenamed(void *param, calldata_t *calldata); @@ -75,7 +75,7 @@ void SourceFlagsChanged(uint32_t flags); void SourceVolumeChanged(float volume); void SourceSyncChanged(int64_t offset); - void SourceMonitoringTypeChanged(int type); + void SourceMonitoringChanged(bool enabled); void SourceMixersChanged(uint32_t mixers); void SourceBalanceChanged(int balance); void SetSourceName(QString newName); @@ -85,6 +85,6 @@ void downmixMonoChanged(bool checked); void balanceChanged(int val); void syncOffsetChanged(int milliseconds); - void monitoringTypeChanged(int index); + void monitoringChanged(bool enabled); void ResetBalance(); };
View file
obs-studio-32.2.2.tar.xz/frontend/components/SceneTree.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/SceneTree.cpp
Changed
@@ -235,13 +235,3 @@ QListWidget::rowsInserted(parent, start, end); } - -#if QT_VERSION < QT_VERSION_CHECK(6, 4, 3) -// Workaround for QTBUG-105870. Remove once that is solved upstream. -void SceneTree::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) -{ - if (selected.count() == 0 && deselected.count() > 0 && !property("clearing").toBool()) { - setCurrentRow(deselected.indexes().front().row()); - } -} -#endif
View file
obs-studio-32.2.2.tar.xz/frontend/components/SceneTree.hpp -> obs-studio-33.0.0.tar.xz/frontend/components/SceneTree.hpp
Changed
@@ -36,9 +36,6 @@ virtual void dragMoveEvent(QDragMoveEvent *event) override; virtual void dragLeaveEvent(QDragLeaveEvent *event) override; virtual void rowsInserted(const QModelIndex &parent, int start, int end) override; -#if QT_VERSION < QT_VERSION_CHECK(6, 4, 3) - virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override; -#endif signals: void scenesReordered();
View file
obs-studio-32.2.2.tar.xz/frontend/components/SourceSelectButton.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/SourceSelectButton.cpp
Changed
@@ -151,7 +151,7 @@ void SourceSelectButton::obsSourceRenamed(void *data, calldata_t *params) { - const char *newNamePtr = static_cast<const char *>(calldata_ptr(params, "new_name")); + const char *newNamePtr = static_cast<const char *>(calldata_string(params, "new_name")); if (!newNamePtr) { return; }
View file
obs-studio-32.2.2.tar.xz/frontend/components/SourceTreeItem.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/SourceTreeItem.cpp
Changed
@@ -4,6 +4,7 @@ #include <widgets/OBSBasic.hpp> #include <qt-wrappers.hpp> +#include <Idian/Utils.hpp> #include <QCheckBox> #include <QLineEdit> @@ -68,20 +69,24 @@ iconLabel = new QLabel(); iconLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); iconLabel->setPixmap(pixmap); - iconLabel->setEnabled(sourceVisible); iconLabel->setStyleSheet("background: none"); - iconLabel->setProperty("class", "source-icon"); + idian::Utils::addClass(iconLabel, "source-icon"); + idian::Utils::toggleClass(iconLabel, "text-muted", !sourceVisible); + style()->polish(iconLabel); + idian::Utils::applyColorToIcon(iconLabel); } vis = new QCheckBox(); - vis->setProperty("class", "checkbox-icon indicator-visibility"); + idian::Utils::addClass(vis, "checkbox-icon"); + idian::Utils::addClass(vis, "indicator-visibility"); vis->setChecked(sourceVisible); vis->setAccessibleName(QTStr("Basic.Main.Sources.Visibility")); vis->setAccessibleDescription(QTStr("Basic.Main.Sources.VisibilityDescription").arg(name)); vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); lock = new QCheckBox(); - lock->setProperty("class", "checkbox-icon indicator-lock"); + idian::Utils::addClass(lock, "checkbox-icon"); + idian::Utils::addClass(lock, "indicator-lock"); lock->setChecked(obs_sceneitem_locked(sceneitem)); lock->setAccessibleName(QTStr("Basic.Main.Sources.Lock")); lock->setAccessibleDescription(QTStr("Basic.Main.Sources.LockDescription").arg(name)); @@ -90,13 +95,13 @@ label = new OBSSourceLabel(source); label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); label->setAttribute(Qt::WA_TranslucentBackground); - label->setEnabled(sourceVisible); + idian::Utils::toggleClass(label, "text-muted", !sourceVisible); const char *sourceId = obs_source_get_unversioned_id(source); switch (obs_source_load_state(sourceId)) { case OBS_MODULE_DISABLED: case OBS_MODULE_MISSING: - label->setStyleSheet("QLabel {color: #CC0000;}"); + idian::Utils::addClass(label, "text-danger"); break; default: break; @@ -134,11 +139,15 @@ obs_source_t *source = obs_sceneitem_get_source(sceneitem); auto undo_redo = (const std::string &uuid, int64_t id, bool val) { - OBSSourceAutoRelease s = obs_get_source_by_uuid(uuid.c_str()); - obs_scene_t *sc = obs_group_or_scene_from_source(s); - obs_sceneitem_t *si = obs_scene_find_sceneitem_by_id(sc, id); - if (si) { - obs_sceneitem_set_visible(si, val); + OBSSourceAutoRelease sceneSource = obs_get_source_by_uuid(uuid.c_str()); + obs_scene_t *scene = obs_group_or_scene_from_source(sceneSource); + obs_sceneitem_t *sceneItem = obs_scene_find_sceneitem_by_id(scene, id); + if (sceneItem) { + obs_sceneitem_set_visible(sceneItem, val); + const char *itemName = obs_source_get_name(obs_sceneitem_get_source(sceneItem)); + const char *name = obs_source_get_name(sceneSource); + blog(LOG_INFO, "User set sceneitem '%s' (%li) on scene '%s' to %s (undo_redo)", + itemName, (long)id, name, val ? "enabled" : "disabled"); } }; @@ -151,6 +160,10 @@ QSignalBlocker sourcesSignalBlocker(this); obs_sceneitem_set_visible(sceneitem, val); + + const char *itemName = obs_source_get_name(obs_sceneitem_get_source(sceneitem)); + blog(LOG_INFO, "User set sceneitem '%s' (%li) on scene '%s' to %s", itemName, (long)id, name, + val ? "enabled" : "disabled"); }; auto setItemLocked = this(bool checked) { @@ -195,16 +208,15 @@ auto removeItem = (void *data, calldata_t *cd) { SourceTreeItem *this_ = static_cast<SourceTreeItem *>(data); - obs_sceneitem_t *curItem = (obs_sceneitem_t *)calldata_ptr(cd, "item"); - obs_scene_t *curScene = (obs_scene_t *)calldata_ptr(cd, "scene"); + OBSSceneItem curItem = (obs_sceneitem_t *)calldata_ptr(cd, "item"); + OBSScene curScene = (obs_scene_t *)calldata_ptr(cd, "scene"); if (curItem == this_->sceneitem) { - QMetaObject::invokeMethod(this_->tree, "Remove", Q_ARG(OBSSceneItem, curItem), - Q_ARG(OBSScene, curScene)); + QMetaObject::invokeMethod(this_->tree, &SourceTree::Remove, curItem, curScene); curItem = nullptr; } if (!curItem) { - QMetaObject::invokeMethod(this_, "Clear"); + QMetaObject::invokeMethod(this_, &SourceTreeItem::Clear); } }; @@ -214,7 +226,7 @@ bool visible = calldata_bool(cd, "visible"); if (curItem == this_->sceneitem) { - QMetaObject::invokeMethod(this_, "VisibilityChanged", Q_ARG(bool, visible)); + QMetaObject::invokeMethod(this_, &SourceTreeItem::VisibilityChanged, visible); } }; @@ -224,7 +236,7 @@ bool locked = calldata_bool(cd, "locked"); if (curItem == this_->sceneitem) { - QMetaObject::invokeMethod(this_, "LockedChanged", Q_ARG(bool, locked)); + QMetaObject::invokeMethod(this_, &SourceTreeItem::LockedChanged, locked); } }; @@ -233,7 +245,7 @@ obs_sceneitem_t *curItem = (obs_sceneitem_t *)calldata_ptr(cd, "item"); if (curItem == this_->sceneitem) { - QMetaObject::invokeMethod(this_, "Select"); + QMetaObject::invokeMethod(this_, &SourceTreeItem::Select); } }; @@ -242,13 +254,13 @@ obs_sceneitem_t *curItem = (obs_sceneitem_t *)calldata_ptr(cd, "item"); if (curItem == this_->sceneitem) { - QMetaObject::invokeMethod(this_, "Deselect"); + QMetaObject::invokeMethod(this_, &SourceTreeItem::Deselect); } }; auto reorderGroup = (void *data, calldata_t *) { SourceTreeItem *this_ = static_cast<SourceTreeItem *>(data); - QMetaObject::invokeMethod(this_->tree, "ReorderItems"); + QMetaObject::invokeMethod(this_->tree, &SourceTree::ReorderItems); }; obs_scene_t *scene = obs_sceneitem_get_scene(sceneitem); @@ -275,7 +287,7 @@ SourceTreeItem *this_ = static_cast<SourceTreeItem *>(data); this_->DisconnectSignals(); this_->sceneitem = nullptr; - QMetaObject::invokeMethod(this_->tree, "RefreshItems"); + QMetaObject::invokeMethod(this_->tree, &SourceTree::RefreshItems); }; obs_source_t *source = obs_sceneitem_get_source(sceneitem); @@ -457,11 +469,11 @@ } if (LineEditCanceled(event)) { - QMetaObject::invokeMethod(this, "ExitEditMode", Qt::QueuedConnection, Q_ARG(bool, false)); + QMetaObject::invokeMethod(this, &SourceTreeItem::ExitEditMode, Qt::QueuedConnection, false); return true; } if (LineEditChanged(event)) { - QMetaObject::invokeMethod(this, "ExitEditMode", Qt::QueuedConnection, Q_ARG(bool, true)); + QMetaObject::invokeMethod(this, &SourceTreeItem::ExitEditMode, Qt::QueuedConnection, true); return true; } @@ -471,9 +483,11 @@ void SourceTreeItem::VisibilityChanged(bool visible) { if (iconLabel) { - iconLabel->setEnabled(visible); + idian::Utils::toggleClass(iconLabel, "text-muted", !visible); + style()->polish(iconLabel); + idian::Utils::applyColorToIcon(iconLabel); } - label->setEnabled(visible); + idian::Utils::toggleClass(label, "text-muted", !visible); vis->setChecked(visible); } @@ -539,7 +553,8 @@ } else if (type == Type::Group) { expand = new QCheckBox(); - expand->setProperty("class", "checkbox-icon indicator-expand"); + idian::Utils::addClass(expand, "checkbox-icon"); + idian::Utils::addClass(expand, "indicator-expand"); expand->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); #ifdef __APPLE__ expand->setAttribute(Qt::WA_LayoutUsesWidgetRect);
View file
obs-studio-32.2.2.tar.xz/frontend/components/SourceTreeModel.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/SourceTreeModel.cpp
Changed
@@ -308,7 +308,7 @@ st->UpdateWidget(createIndex(0, 0, nullptr), group); UpdateGroupState(true); - QMetaObject::invokeMethod(st, "Edit", Qt::QueuedConnection, Q_ARG(int, 0)); + QMetaObject::invokeMethod(st, &SourceTree::Edit, Qt::QueuedConnection, 0); } void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices) @@ -353,7 +353,7 @@ /* that's created automatically. */ int newIdx = indices0.row(); - QMetaObject::invokeMethod(st, "NewGroupEdit", Qt::QueuedConnection, Q_ARG(int, newIdx)); + QMetaObject::invokeMethod(st, &SourceTree::NewGroupEdit, Qt::QueuedConnection, newIdx); } void SourceTreeModel::UngroupSelectedGroups(QModelIndexList &indices)
View file
obs-studio-32.2.2.tar.xz/frontend/components/VisibilityItemWidget.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/VisibilityItemWidget.cpp
Changed
@@ -28,7 +28,14 @@ setLayout(itemLayout); - connect(vis, &QCheckBox::clicked, this, this(bool visible) { obs_source_set_enabled(source, visible); }); + connect(vis, &QCheckBox::clicked, this, this(bool visible) { + obs_source_set_enabled(source, visible); + const char *filterName = obs_source_get_name(source); + obs_source_t *parent = obs_filter_get_parent(source); + const char *sourceName = obs_source_get_name(parent); + blog(LOG_INFO, "User set filter '%s' on source '%s' to %s", filterName, sourceName, + visible ? "enabled" : "disabled"); + }); } void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data) @@ -36,7 +43,7 @@ VisibilityItemWidget *window = static_cast<VisibilityItemWidget *>(param); bool enabled = calldata_bool(data, "enabled"); - QMetaObject::invokeMethod(window, "SourceEnabled", Q_ARG(bool, enabled)); + QMetaObject::invokeMethod(window, &VisibilityItemWidget::SourceEnabled, enabled); } void VisibilityItemWidget::SourceEnabled(bool enabled)
View file
obs-studio-32.2.2.tar.xz/frontend/components/VolumeControl.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/VolumeControl.cpp
Changed
@@ -16,9 +16,8 @@ bool isSourceUnassigned(obs_source_t *source) { uint32_t mixes = (obs_source_get_audio_mixers(source) & ((1 << MAX_AUDIO_MIXES) - 1)); - obs_monitoring_type mt = obs_source_get_monitoring_type(source); - return mixes == 0 && mt != OBS_MONITORING_TYPE_MONITOR_ONLY; + return mixes == 0; } void showUnassignedWarning(const char *name) @@ -41,7 +40,7 @@ } }; - QMetaObject::invokeMethod(App(), "Exec", Qt::QueuedConnection, Q_ARG(VoidFunc, msgBox)); + QMetaObject::invokeMethod(App(), &OBSApp::Exec, Qt::QueuedConnection, msgBox); } } // namespace @@ -52,8 +51,6 @@ contextMenu(nullptr), QFrame(parent) { - utils = std::make_unique<idian::Utils>(this); - uuid = obs_source_get_uuid(source); mainLayout = new QBoxLayout(QBoxLayout::LeftToRight, this); @@ -63,21 +60,21 @@ categoryLabel = new QLabel("Active"); categoryLabel->setAlignment(Qt::AlignCenter); - utils->addClass(categoryLabel, "mixer-category"); - utils->addClass(categoryLabel, "text-tiny"); + idian::Utils::addClass(categoryLabel, "mixer-category"); + idian::Utils::addClass(categoryLabel, "text-tiny"); nameButton = new VolumeName(source, this); nameButton->setMaximumWidth(280); - utils->addClass(nameButton, "text-small"); - utils->addClass(nameButton, "mixer-name"); + idian::Utils::addClass(nameButton, "text-small"); + idian::Utils::addClass(nameButton, "mixer-name"); muteButton = new QPushButton(this); muteButton->setCheckable(true); - utils->addClass(muteButton, "btn-mute"); + idian::Utils::addClass(muteButton, "btn-mute"); monitorButton = new QPushButton(this); monitorButton->setCheckable(true); - utils->addClass(monitorButton, "btn-monitor"); + idian::Utils::addClass(monitorButton, "btn-monitor"); volumeLabel = new QLabel(this); volumeLabel->setIndent(0); @@ -90,14 +87,14 @@ sourceName = obs_source_get_name(source); setObjectName(sourceName); - utils->applyStateStylingEventFilter(muteButton); - utils->applyStateStylingEventFilter(monitorButton); + idian::Utils::applyStateStylingEventFilter(muteButton); + idian::Utils::applyStateStylingEventFilter(monitorButton); volumeMeter = new VolumeMeter(this, source); obsMuted = obs_source_muted(source); bool unassigned = isSourceUnassigned(source); - obsMonitoringType = obs_source_get_monitoring_type(source); + obsMonitoring = obs_source_get_monitoring_enabled(source); volumeMeter->setMuted(obsMuted || unassigned); @@ -109,7 +106,7 @@ obsSignals.reserve(9); obsSignals.emplace_back(obs_source_get_signal_handler(source), "mute", obsVolumeMuted, this); obsSignals.emplace_back(obs_source_get_signal_handler(source), "audio_mixers", obsMixersChanged, this); - obsSignals.emplace_back(obs_source_get_signal_handler(source), "audio_monitoring", obsMonitoringChanged, this); + obsSignals.emplace_back(obs_source_get_signal_handler(source), "monitor", obsMonitoringChanged, this); obsSignals.emplace_back(obs_source_get_signal_handler(source), "activate", VolumeControl::obsSourceActivated, this); obsSignals.emplace_back(obs_source_get_signal_handler(source), "deactivate", @@ -198,7 +195,7 @@ { VolumeControl *volControl = static_cast<VolumeControl *>(data); - QMetaObject::invokeMethod(volControl, "changeVolume", Qt::QueuedConnection); + QMetaObject::invokeMethod(volControl, &VolumeControl::changeVolume, Qt::QueuedConnection); } void VolumeControl::obsVolumeMuted(void *data, calldata_t *params) @@ -206,38 +203,39 @@ VolumeControl *volControl = static_cast<VolumeControl *>(data); bool muted = calldata_bool(params, "muted"); - QMetaObject::invokeMethod(volControl, "onMuteChanged", Qt::QueuedConnection, Q_ARG(bool, muted)); + QMetaObject::invokeMethod(volControl, &VolumeControl::onMuteChanged, Qt::QueuedConnection, muted); } void VolumeControl::obsMixersChanged(void *data, calldata_t *) { VolumeControl *volControl = static_cast<VolumeControl *>(data); - QMetaObject::invokeMethod(volControl, "processMixerState", Qt::QueuedConnection); + QMetaObject::invokeMethod(volControl, &VolumeControl::processMixerState, Qt::QueuedConnection); } void VolumeControl::obsMonitoringChanged(void *data, calldata_t *params) { VolumeControl *volControl = static_cast<VolumeControl *>(data); - auto type = static_cast<int>(calldata_int(params, "type")); + bool enable = calldata_bool(params, "monitor"); - QMetaObject::invokeMethod(volControl, "onMonitoringChanged", Qt::QueuedConnection, Q_ARG(int, type)); + QMetaObject::invokeMethod(volControl, &VolumeControl::onMonitoringChanged, Qt::QueuedConnection, enable); } void VolumeControl::obsSourceActivated(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<VolumeControl *>(data), "onSourceActiveChanged", Qt::QueuedConnection, - Q_ARG(bool, true)); + QMetaObject::invokeMethod(static_cast<VolumeControl *>(data), &VolumeControl::onSourceActiveChanged, + Qt::QueuedConnection, true); } void VolumeControl::obsSourceDeactivated(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<VolumeControl *>(data), "onSourceActiveChanged", Qt::QueuedConnection, - Q_ARG(bool, false)); + QMetaObject::invokeMethod(static_cast<VolumeControl *>(data), &VolumeControl::onSourceActiveChanged, + Qt::QueuedConnection, false); } void VolumeControl::obsSourceDestroy(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<VolumeControl *>(data), "onSourceDestroyed", Qt::QueuedConnection); + QMetaObject::invokeMethod(static_cast<VolumeControl *>(data), &VolumeControl::onSourceDestroyed, + Qt::QueuedConnection); } void VolumeControl::setLayoutVertical(bool vertical) @@ -608,9 +606,9 @@ processMixerState(); } -void VolumeControl::onMonitoringChanged(int type) +void VolumeControl::onMonitoringChanged(bool enabled) { - obsMonitoringType = static_cast<obs_monitoring_type>(type); + obsMonitoring = enabled; processMixerState(); } @@ -641,11 +639,11 @@ bool styleUnassigned = mixerStatus().has(VolumeControl::MixerStatus::Unassigned); bool stylePreviewed = mixerStatus().has(VolumeControl::MixerStatus::Preview); - utils->toggleClass("volume-pinned", stylePinned); - utils->toggleClass("volume-inactive", styleInactive); - utils->toggleClass("volume-preview", styleInactive && stylePreviewed); - utils->toggleClass("volume-hidden", styleHidden && !stylePinned); - utils->toggleClass("volume-unassigned", styleUnassigned); + idian::Utils::toggleClass(this, "volume-pinned", stylePinned); + idian::Utils::toggleClass(this, "volume-inactive", styleInactive); + idian::Utils::toggleClass(this, "volume-preview", styleInactive && stylePreviewed); + idian::Utils::toggleClass(this, "volume-hidden", styleHidden && !stylePinned); + idian::Utils::toggleClass(this, "volume-unassigned", styleUnassigned); categoryLabel->setText(labelText); categoryLabel->setAlignment(Qt::AlignCenter); @@ -719,27 +717,26 @@ std::bind(undo_redo, std::placeholders::_1, mute), uuid, uuid); } -void VolumeControl::setMonitoring(obs_monitoring_type type) +void VolumeControl::setMonitoring(bool enabled) { OBSSource source = OBSGetStrongRef(weakSource()); if (!source) { return; } - obs_monitoring_type prevMonitoringType = obs_source_get_monitoring_type(source); - obs_source_set_monitoring_type(source, type); + bool prevMonitoring = obs_source_get_monitoring_enabled(source); + obs_source_set_monitoring_enabled(source, enabled); - auto undo_redo = (const std::string &uuid, obs_monitoring_type val) { + auto undo_redo = (const std::string &uuid, bool val) { OBSSourceAutoRelease source = obs_get_source_by_uuid(uuid.c_str()); - obs_source_set_monitoring_type(source, val); + obs_source_set_monitoring_enabled(source, val); }; QString text = QTStr("Undo.MonitoringType.Change"); const char *name = obs_source_get_name(source); - OBSBasic::Get()->undo_s.add_action(text.arg(name), - std::bind(undo_redo, std::placeholders::_1, prevMonitoringType), - std::bind(undo_redo, std::placeholders::_1, type), uuid, uuid); + OBSBasic::Get()->undo_s.add_action(text.arg(name), std::bind(undo_redo, std::placeholders::_1, prevMonitoring), + std::bind(undo_redo, std::placeholders::_1, enabled), uuid, uuid); } void VolumeControl::onSourceActiveChanged(bool active) @@ -770,10 +767,10 @@ QSignalBlocker blockMute(muteButton); QSignalBlocker blockMonitor(monitorButton); - bool showAsMuted = obsMuted || obsMonitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY; - bool showAsMonitored = obsMonitoringType != OBS_MONITORING_TYPE_NONE; + bool showAsMuted = obsMuted; + bool showAsMonitored = obsMonitoring; bool showAsUnassigned = !obsMuted && unassigned; - bool showWarningIcon = showAsUnassigned || obsMonitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY; + bool showWarningIcon = showAsUnassigned; volumeMeter->setMuted((showAsMuted || showAsUnassigned) && !showAsMonitored); setUseDisabledColors(showAsMuted || !isActive); @@ -804,10 +801,10 @@ // Qt doesn't support overriding the QPushButton icon using pseudo state selectors like :checked // in QSS so we set a checked class selector on the button to be used instead. - utils->toggleClass(muteButton, "checked", showAsMuted); - utils->toggleClass(monitorButton, "checked", showAsMonitored); + idian::Utils::toggleClass(muteButton, "checked", showAsMuted); + idian::Utils::toggleClass(monitorButton, "checked", showAsMonitored); - utils->toggleClass(muteButton, "mute-warning", showWarningIcon); + idian::Utils::toggleClass(muteButton, "mute-warning", showWarningIcon); style()->polish(muteButton); style()->polish(monitorButton); @@ -818,18 +815,11 @@ void VolumeControl::handleMuteButton(bool mute) { setMuted(mute); - - if (!mute && obsMonitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY) { - setMonitoring(OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); - } } void VolumeControl::handleMonitorButton(bool enableMonitoring) { - obs_monitoring_type newType = (enableMonitoring) ? OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT - : OBS_MONITORING_TYPE_NONE; - - setMonitoring(newType); + setMonitoring(enableMonitoring); } void VolumeControl::sliderChanged(int vol)
View file
obs-studio-32.2.2.tar.xz/frontend/components/VolumeControl.hpp -> obs-studio-33.0.0.tar.xz/frontend/components/VolumeControl.hpp
Changed
@@ -66,12 +66,10 @@ }; private: - std::unique_ptr<idian::Utils> utils; - OBSWeakSource weakSource_; const char *uuid; std::vector<OBSSignal> obsSignals; - obs_monitoring_type obsMonitoringType; + bool obsMonitoring; bool obsMuted; QBoxLayout *mainLayout; @@ -112,7 +110,7 @@ void updatePeakMeterType(); void setMuted(bool mute); - void setMonitoring(obs_monitoring_type type); + void setMonitoring(bool enabled); public slots: void setUseDisabledColors(bool greyscale); @@ -131,7 +129,7 @@ void onSourceActiveChanged(bool active); void onMuteChanged(bool muted); - void onMonitoringChanged(int type); + void onMonitoringChanged(bool enabled); void onSourceDestroyed() { deleteLater(); } signals:
View file
obs-studio-32.2.2.tar.xz/frontend/components/VolumeMeter.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/VolumeMeter.cpp
Changed
@@ -364,7 +364,7 @@ void VolumeMeter::obsSourceDestroyed(void *data, calldata_t *) { VolumeMeter *self = static_cast<VolumeMeter *>(data); - QMetaObject::invokeMethod(self, "onSourceDestroyed", Qt::QueuedConnection); + QMetaObject::invokeMethod(self, &VolumeMeter::onSourceDestroyed, Qt::QueuedConnection); } void VolumeMeter::setLevels(const float magnitudeMAX_AUDIO_CHANNELS, const float peakMAX_AUDIO_CHANNELS,
View file
obs-studio-32.2.2.tar.xz/frontend/components/VolumeName.cpp -> obs-studio-33.0.0.tar.xz/frontend/components/VolumeName.cpp
Changed
@@ -123,21 +123,21 @@ VolumeName *widget = static_cast<VolumeName *>(data); const char *name = calldata_string(params, "new_name"); - QMetaObject::invokeMethod(widget, "onRenamed", Qt::QueuedConnection, Q_ARG(QString, name)); + QMetaObject::invokeMethod(widget, &VolumeName::onRenamed, Qt::QueuedConnection, QString::fromUtf8(name)); } void VolumeName::obsSourceRemoved(void *data, calldata_t *) { VolumeName *widget = static_cast<VolumeName *>(data); - QMetaObject::invokeMethod(widget, "onRemoved", Qt::QueuedConnection); + QMetaObject::invokeMethod(widget, &VolumeName::onRemoved, Qt::QueuedConnection); } void VolumeName::obsSourceDestroyed(void *data, calldata_t *) { VolumeName *widget = static_cast<VolumeName *>(data); - QMetaObject::invokeMethod(widget, "onDestroyed", Qt::QueuedConnection); + QMetaObject::invokeMethod(widget, &VolumeName::onDestroyed, Qt::QueuedConnection); } void VolumeName::resizeEvent(QResizeEvent *event)
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ar-SA.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ar-SA.ini
Changed
@@ -503,14 +503,9 @@ Basic.Main.PreviewDisabled="المعاينة تم تعطيلها" Basic.SourceSelect="إضافة مصدر" Basic.SourceSelect.SelectType="نوع المصدر" -Basic.SourceSelect.Recent="المضاف حديثاً" -Basic.SourceSelect.NewSource="إنشاء مصدر جديد" -Basic.SourceSelect.Existing="إضافة مصدر موجود" Basic.SourceSelect.CreateButton="إنشاء جديد" Basic.SourceSelect.AddVisible="جعل المصدر ظاهراً" -Basic.SourceSelect.NoExisting="لا يوجد مصادر %1" Basic.SourceSelect.Accessible.SourceName="إسم المصدر" -Basic.SourceSelect.Accessible.Existing="إضافة مصدر موجود" Basic.SourceSelect.Deprecated.Create="نوع المصدر هذا مصنف كنوع مصدر مُهمل وقد تتم إزالته في المستقبل." Basic.Main.Sources.Visibility="الرؤية" Basic.Main.Sources.VisibilityDescription="يتحكم في وضوح '%1' في اللوحة" @@ -1373,5 +1368,6 @@ PluginManager.Section.Discover="تصفُح" PluginManager.Section.Manage="مُثبت" PluginManager.Section.Updates="التحديثات" -PluginManager.Section.Manage.Title="إدارة المكونات الإضافية المُفعلة" +PluginManager.Section.Manage.Title="مُثبت" Accessible.Widget.Name.AlignmentSelector="مُحدد المحاذاة" +EncoderMissing.Unknown="غير معرّف"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/az-AZ.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/az-AZ.ini
Changed
@@ -498,14 +498,9 @@ Basic.Main.PreviewDisabled="Ön baxış hazırda deaktivdir" Basic.SourceSelect="Mənbə Əlavə et" Basic.SourceSelect.SelectType="Mənbə Tipi" -Basic.SourceSelect.Recent="Son Əlavə Edilənlər" -Basic.SourceSelect.NewSource="Yeni Mənbə Yarat" -Basic.SourceSelect.Existing="Mövcud Mənbəni Əlavə et" Basic.SourceSelect.CreateButton="Yenisini Yarat" Basic.SourceSelect.AddVisible="Mənbəni görünən et" -Basic.SourceSelect.NoExisting="Heç bir mövcud %1 mənbəyi yoxdur" Basic.SourceSelect.Accessible.SourceName="Mənbə Adı" -Basic.SourceSelect.Accessible.Existing="Mövcud Mənbəni Əlavə et" Basic.SourceSelect.Deprecated.Create="Bu mənbə növü köhnəlmiş kimi işarələnib və gələcəkdə silinə bilər." Basic.Main.Sources.Visibility="Görünmə" Basic.Main.Sources.VisibilityDescription="Canvas-da '%1'-in görünməsini idarə edir" @@ -1330,5 +1325,4 @@ PluginManager.Section.Discover="Gözdən keçir" PluginManager.Section.Manage="Quraşdırıldı" PluginManager.Section.Updates="Güncəlləmələr" -PluginManager.Section.Manage.Title="Aktiv Plaginləri İdarə et" Accessible.Widget.Name.AlignmentSelector="Düzlənmə Seçicisi"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/be-BY.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/be-BY.ini
Changed
@@ -126,6 +126,10 @@ CrashHandling.Buttons.LaunchNormal="Запуск у звычайным рэжыме" CrashHandling.Errors.UploadJSONError="Падчас зацягвання апошняй справаздачы аб збоі ўзнікла памылка. Паўтарыце спробу пазней." CrashHandling.Errors.Title="Памылка зацягвання справаздачы" +PluginFailure.Dialog.Title="Памылкі плагінаў" +PluginFailure.Labels.Text="Не ўдалося загрузіць усе староннія плагіны.\n\nБольш можна даведацца ў менеджары плагінаў." +PluginFailure.Dialog.Continue="Адхіліць" +PluginFailure.Dialog.Open="Адкрыць менеджар плагінаў" SafeMode.Restart="Ці жадаеце Вы перазапусціць OBS у бяспечным рэжыме (адключаныя іншыя плагіны, скрыпты і WebSockets)?" SafeMode.RestartNormal="Ці хочаце Вы перазапусціць OBS у нармальным рэжыме?" ChromeOS.Title="Платформа не падтрымліваецца" @@ -508,12 +512,14 @@ Basic.Main.PreviewDisabled="Перадпрагляд адключаны" Basic.SourceSelect="Дадаць крыніцу" Basic.SourceSelect.SelectType="Тып крыніцы" -Basic.SourceSelect.Recent="Нядаўна дададзеныя" -Basic.SourceSelect.NewSource="Стварыць крыніцу" -Basic.SourceSelect.Existing="Дадаць існуючую крыніцу" +Basic.SourceSelect.Recent="Нядаўна створаныя" +Basic.SourceSelect.Description="Выберыце адну або некалькі крыніц, якія вы хочаце дадаць да бягучай сцэны." +Basic.SourceSelect.NewSource="Стварыць крыніцу «%1»" +Basic.SourceSelect.AddExisting="Дадаць існуючую крыніцу «%1»" +Basic.SourceSelect.NoSelection="Дадаць існуючую" Basic.SourceSelect.CreateButton="Стварыць" Basic.SourceSelect.AddVisible="Зрабіць крыніцу бачнай" -Basic.SourceSelect.NoExisting="Крыніц тыпу «%1» няма" +Basic.SourceSelect.NoExisting="У вас пакуль няма крыніц тыпу «%1»." Basic.SourceSelect.Accessible.SourceName="Назва крыніцы" Basic.SourceSelect.Accessible.Existing="Дадаць існуючую крыніцу" Basic.SourceSelect.Deprecated.Create="Гэты тып крыніцы пазначаны як састарэлы і, магчыма, пазней будзе выдалены." @@ -1195,6 +1201,8 @@ Unmute="Уключыць гук" Push-to-mute="Выключыць гук пры націсканні" Push-to-talk="Уключыць гук пры націсканні" +MonitorOn="Уключыць маніторынг" +MonitorOff="Адключыць маніторынг" SceneItemShow="Паказаць: %1" SceneItemHide="Схаваць: %1" OutputWarnings.NoTracksSelected="Выберыце прынамсі адну дарожку" @@ -1360,5 +1368,40 @@ PluginManager.Section.Discover="Агляд" PluginManager.Section.Manage="Усталяваны" PluginManager.Section.Updates="Абнаўленні" -PluginManager.Section.Manage.Title="Кіраванне ўключанымі плагінамі" +PluginManager.Section.Manage.Title="Усталяваныя" +PluginManager.Section.Manage.Description="Кіруйце плагінамі, якія ў вас усталяваны." +PluginManager.Section.Manage.NoPlugins="Плагіны не знойдзены." +PluginManager.Section.Errors.Title="Памылковыя" +PluginManager.Section.Errors.Description="Гэтыя плагіны не ўдалося загрузіць. Пераканайцеся ў іх актуальнасці і сумяшчальнасці з бягучай версіяй OBS Studio." +PluginManager.Section.Missing.Title="Адсутныя" +PluginManager.Section.Missing.Description="Гэтыя плагіны былі ўсталяваны раней, але цяпер іх немагчыма знайсці." +PluginManager.Button.Enable="Уключыць плагін «%1»" +PluginManager.Status.Legacy="Састарэлы" +PluginManager.Status.Disabled="Адключаны" +PluginManager.Status.Error="Памылковы" +PluginManager.Status.Missing="Адсутнічае" +PluginManager.Status.Legacy.Description="Гэты плагін усталяваны ў каталозе, які не будзе падтрымлівацца ў будучыні. <a href=\"%1\">Даведацца больш</a>" Accessible.Widget.Name.AlignmentSelector="Сектар выраўноўвання" +EncoderMissing.Title="Адсутныя кадавальнікі" +EncoderMissing.Text="Наступныя кадавальнікі былі наладжаны, але адсутнічаюць:\n<ul>\n%1</ul><br>\nКаб даведацца больш, глядзіце <a href=\"%2\">артыкул у базе ведаў (англ.)</a>." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (код: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Невядомы" +EncoderMissing.MissingModule="Модуль «%1» не загружаны" +EncoderMissing.NVENC.TestProgramFailedStartup="Збой запуску праграмы праверкі NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Збой працэсу праверкі NVENC, код выхаду: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Збой чытання выходных даных працэсу праверкі NVENC, код выхаду: %1" +EncoderMissing.NVENC.TestProgramError="Праверка NVENC не ўдалася, прычына: %1" +EncoderMissing.NVENC.NoDevices="Не знойдзены ГП NVIDIA" +EncoderMissing.NVENC.Unsupported.Kepler="Архітэктура (Kepler) вашага ГП (%1) больш не падтрымліваецца. Выкарыстоўвайце OBS версіі 30.2 або ніжэй." +EncoderMissing.NVENC.Reason.NvmlLoad="Не ўдалося загрузіць бібліятэку NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Не ўдалося запусціць NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Не ўдалося загрузіць бібліятэку NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Не ўдалося запусціць NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Адсутнічае версія NVENC" +EncoderMissing.NVENC.Reason.CudaLoad="Не ўдалося загрузіць бібліятэку CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Не ўдалося запусціць CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Версія CUDA памылковая або адсутнічае" +EncoderMissing.NVENC.Reason.DriverOutdated="Састарэлы драйвер" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Не знойдзены прылады NVIDIA з падтрымкай NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Перавышаны ліміт сеансу кадавальніка" +EncoderMissing.NVENC.Reason.AV1Unsupported="Ніводны з ГП NVIDIA не падтрымлівае кадаванне AV1"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/bg-BG.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/bg-BG.ini
Changed
@@ -380,6 +380,8 @@ LogUploadDialog.Title="Изпращане на отчетен файл на OSB Studio" LogUploadDialog.Labels.PrivacyNotice="Преди да започнете да качвате файлове, запознайте се с <a href='https://obsproject.com/privacy-policy'>Политика за конфиденциалностy</a> и в това число разделът, касаещ споделянето на файлове." LogUploadDialog.Labels.Progress="Изпращане на отчетен файл. Моля, изчакайте..." +LogUploadDialog.Buttons.ConfirmUpload="Качване" +LogUploadDialog.Buttons.RetryButton="Опитай отново" Remux.SourceFile="OBS запис" Remux.TargetFile="Целеви файл" Remux.Remux="Ремултиплексиране" @@ -489,7 +491,11 @@ Basic.Main.MixerRename.Title="Преименуване на Звуков Източник" Basic.Main.MixerRename.Text="Моля, въведете името на източника на звук" Basic.Main.PreviewDisabled="Прегледа в момента е забранен" +Basic.SourceSelect="Добави източник" +Basic.SourceSelect.SelectType="Вид източник" +Basic.SourceSelect.CreateButton="Създай нов" Basic.SourceSelect.AddVisible="Направете видим източника" +Basic.SourceSelect.Accessible.SourceName="Име на източник" Basic.Main.Sources.Visibility="Видимост" Basic.Main.Sources.VisibilityDescription="Управлява видимостта на '%1' в рамката" Basic.Main.Sources.Lock="Заключване" @@ -539,6 +545,7 @@ Basic.TransformWindow.Size="Големина" Basic.TransformWindow.Width="Ширина" Basic.TransformWindow.Height="Височина" +Basic.TransformWindow.Alignment="Подравняване" Basic.TransformWindow.BoundsWidth="Ширина на ограничителя" Basic.TransformWindow.BoundsHeight="Височина на ограничителя" Basic.TransformWindow.Crop="Изрязване" @@ -546,6 +553,8 @@ Basic.TransformWindow.CropRight="Изрязване вдясно" Basic.TransformWindow.CropTop="Изрязване отгоре" Basic.TransformWindow.CropBottom="Изрязване отдолу" +Basic.TransformWindow.Accessible.PositionX="Позиция Х" +Basic.TransformWindow.Accessible.PositionY="Позиция Y" Basic.TransformWindow.Alignment.TopLeft="Горе вляво" Basic.TransformWindow.Alignment.TopCenter="Горе в центъра" Basic.TransformWindow.Alignment.TopRight="Горе вдясно" @@ -555,6 +564,7 @@ Basic.TransformWindow.Alignment.BottomLeft="Долу вляво" Basic.TransformWindow.Alignment.BottomCenter="Долу в центъра" Basic.TransformWindow.Alignment.BottomRight="Долу вдясно" +Basic.TransformWindow.BoundsType.None="Автоматично" Basic.TransformWindow.BoundsType.MaxOnly="Само максимален размер" Basic.TransformWindow.BoundsType.ScaleInner="Оразмеряване" Basic.TransformWindow.BoundsType.ScaleToWidth="Запълни ширината" @@ -580,6 +590,7 @@ Basic.Main.PauseRecording="Пауза на записа" Basic.Main.UnpauseRecording="Отпускане на паузата на записа" Basic.Main.SplitFile="Раздели записващия файл" +Basic.Main.AddChapterMarker="Добави маркер за глава (Хибритен MP4/MOV)" Basic.Main.StoppingRecording="Спиране на записа..." Basic.Main.StopReplayBuffer="Изкючване на Буферa за Повторение" Basic.Main.StoppingReplayBuffer="Спиране на Буферa за Повторение..." @@ -593,6 +604,7 @@ Basic.Main.HideContextBar="Скрий панела с инструменти на източника" Basic.Main.StopVirtualCam="Спри виртуалната камера" Basic.Main.Group="Група %1" +Basic.Main.NewGroup="Нова група" Basic.Main.GroupItems="Групиране на избраните елементи" Basic.Main.Ungroup="Разгрупирай" Basic.Main.GridMode="Режим решетка" @@ -758,6 +770,10 @@ Basic.Settings.Appearance.General.Variant="Стил" Basic.Settings.Appearance.General.NoVariant="Няма налични стилове" Basic.Settings.Appearance.FontScale="Размер на шрифта" +Basic.Settings.Appearance.Classic="Класически" +Basic.Settings.Appearance.Compact="Компактен" +Basic.Settings.Appearance.Normal="Нормален" +Basic.Settings.Appearance.Comfortable="Удобен" Basic.Settings.Stream="Стрийм" Basic.Settings.Stream.Custom.UseAuthentication="Използване на удостоверяване" Basic.Settings.Stream.Custom.Username="Потребителско име" @@ -778,6 +794,7 @@ Basic.Settings.Stream.Recommended.MaxAudioBitrate="Максимален битрейт на аудиото: %1 kbps" Basic.Settings.Stream.Recommended.MaxResolution="Максимална разд. способност: %1" Basic.Settings.Stream.Recommended.MaxFPS="Максимални кадри в сек.: %1" +Basic.Settings.Stream.SpecifyCustomServer="Задай друг сървър" Basic.Settings.Stream.ServiceCustomServer="Персонализиран сървър" Basic.Settings.Stream.EnableMultitrackVideo="Включи %1" Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrate="Максимална честотна лента за стрийминг" @@ -1063,6 +1080,10 @@ Basic.AudioMixer.Category.Preview="Преглед" Basic.AudioMixer.Category.Hidden="Скрито" Basic.AudioMixer.Category.Unassigned="Незададено" +Basic.AudioMixer.Layout.Horizontal="Хоризонтално разположение" +Basic.AudioMixer.Layout.Vertical="Вертикално разположение" +Basic.AudioMixer.Monitoring.Enable="Включване на мониторнинг" +Basic.AudioMixer.Monitoring.Disable="Изключване на мониторнинг" Basic.AdvAudio="Допълнителни Звукови Характеристики" Basic.AdvAudio.ActiveOnly="Само активни източници" Basic.AdvAudio.Name="Име" @@ -1077,6 +1098,7 @@ Basic.AdvAudio.Monitoring="Прослушване на звука" Basic.AdvAudio.Monitoring.None="Наблюдението е изключено" Basic.AdvAudio.Monitoring.MonitorOnly="Само наблюдение (заглушаване на изхода)" +Basic.AdvAudio.Monitoring.Both="Мониторинг е включен" Basic.AdvAudio.MonitoringSource="Завуково прослушване за '%1'" Basic.AdvAudio.AudioTracks="Писти" Basic.Settings.Hotkeys="Горещи клавиши" @@ -1256,4 +1278,3 @@ PluginManager.Section.Discover="Избери" PluginManager.Section.Manage="Инсталирани" PluginManager.Section.Updates="Обновления" -PluginManager.Section.Manage.Title="Управление на включените приставки"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ca-ES.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ca-ES.ini
Changed
@@ -124,6 +124,10 @@ CrashHandling.Buttons.LaunchNormal="Inicia en mode normal\n" CrashHandling.Errors.UploadJSONError="S'ha produït un error en intentar carregar el registre d'errors més recent. Torneu-ho a provar més tard." CrashHandling.Errors.Title="Error en carregar el registre de fallades\n" +PluginFailure.Dialog.Title="Errors del connector" +PluginFailure.Labels.Text="L'OBS Studio no ha pogut carregar tots els connectors de tercers.\n\nHi ha més detalls disponibles al gestor de connectors." +PluginFailure.Dialog.Continue="Descarta" +PluginFailure.Dialog.Open="Obre el Gestor de connectors" SafeMode.Restart="Voleu reiniciar l'OBS en mode segur (es desactivaran els complements de tercers, scripts i WebSockets)?" SafeMode.RestartNormal="Voleu reiniciar l'OBS en mode normal?" ChromeOS.Title="Plataforma no compatible" @@ -500,12 +504,14 @@ Basic.Main.PreviewDisabled="La previsualització està inhabilitada" Basic.SourceSelect="Afegeix una font" Basic.SourceSelect.SelectType="Tipus de font" -Basic.SourceSelect.Recent="Afegida recentment" -Basic.SourceSelect.NewSource="Crea una font nova" -Basic.SourceSelect.Existing="Afegeix una font existent" +Basic.SourceSelect.Recent="Creat recentment" +Basic.SourceSelect.Description="Seleccioneu les fonts que voleu afegir a l'escena actual." +Basic.SourceSelect.NewSource="Afegeix una nova %1" +Basic.SourceSelect.AddExisting="Afegeix %1 d'existent" +Basic.SourceSelect.NoSelection="Afegeix una existent" Basic.SourceSelect.CreateButton="Crea una nova" Basic.SourceSelect.AddVisible="Fes visible l'origen" -Basic.SourceSelect.NoExisting="No existeixen fonts %1" +Basic.SourceSelect.NoExisting="Encara no teniu cap font %1 existent." Basic.SourceSelect.Accessible.SourceName="Nom de la font" Basic.SourceSelect.Accessible.Existing="Afegeix una font existent" Basic.SourceSelect.Deprecated.Create="Aquest tipus de font està marcada com a obsoleta i és possible que se suprimeixi en el futur." @@ -1190,6 +1196,8 @@ Unmute="Treu el silenci" Push-to-mute="Prémer per silenciar" Push-to-talk="Prémer per parlar" +MonitorOn="Activa el seguiment" +MonitorOff="Desactiva el seguiment" SceneItemShow="Mostra «%1»" SceneItemHide="Amaga «%1»" OutputWarnings.NoTracksSelected="Heu de seleccionar almenys una cançó" @@ -1354,5 +1362,38 @@ PluginManager.Section.Discover="Navega" PluginManager.Section.Manage="Instal·lat" PluginManager.Section.Updates="Actualitzacions" -PluginManager.Section.Manage.Title="Gestiona els complements habilitats" +PluginManager.Section.Manage.Title="Instal·lat" +PluginManager.Section.Manage.Description="Gestioneu els connectors instal·lats actualment." +PluginManager.Section.Manage.NoPlugins="No s'ha trobat cap connector." +PluginManager.Section.Errors.Description="Aquests connectors no s'han pogut carregar. Assegureu-vos que estiguin actualitzats i siguin compatibles amb aquesta versió d'OBS Studio." +PluginManager.Section.Missing.Title="No disponible" +PluginManager.Section.Missing.Description="Aquests connectors es van instal·lar anteriorment però ja no estan disponibles." +PluginManager.Button.Enable="Habilita el connector %1" +PluginManager.Status.Legacy="Antic" +PluginManager.Status.Disabled="Inhabilitat" +PluginManager.Status.Missing="No disponible" +PluginManager.Status.Legacy.Description="Aquest connector s'instal·la en una ubicació que deixarà de funcionar en el futur. <a href=\"%1\">Més informació</a>" Accessible.Widget.Name.AlignmentSelector="Selector d'alineació" +EncoderMissing.Title="No s'han trobat codificadors" +EncoderMissing.Text="No s'han trobat aquests codificadors:\n<ul>\n%1</ul><br>\nPer a més informació, consulteu la <a href=\"%2\">Base de coneixements</a>." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (codi: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Desconegut" +EncoderMissing.MissingModule="No s'ha carregat el mòdul «%1\"»" +EncoderMissing.NVENC.TestProgramFailedStartup="Error en iniciar el programa de comprovació NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Error amb el procés de comprovació NVENC, codi de sortida: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Error de lectura amb el procés de sortida NVENC, codi: %1" +EncoderMissing.NVENC.TestProgramError="Ha fallat la comprovació NVENC; motiu: %1" +EncoderMissing.NVENC.NoDevices="No s'ha trobat cap GPU NVIDIA" +EncoderMissing.NVENC.Unsupported.Kepler="L'arquitectura (Kepler) de la vostra GPU (%1) ja no és compatible. Utilitzeu l'OBS 30.2 o anterior." +EncoderMissing.NVENC.Reason.NvmlLoad="Ha fallat en carregar la llibreria NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Ha fallat en inicialitzar NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Ha fallat en carregar la llibreria NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Ha fallat en inicialitzar NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Versió NVENC buida" +EncoderMissing.NVENC.Reason.CudaLoad="Ha fallat en carregar la llibreria CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Ha fallat en inicialitzar CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Versió CUDA no vàlida/no trobada" +EncoderMissing.NVENC.Reason.DriverOutdated="Controlador obsolet" +EncoderMissing.NVENC.Reason.NoSupportedDevices="No s'ha trobat cap dispositiu que suporti NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="S'ha superat el límit de sessions del codificador" +EncoderMissing.NVENC.Reason.AV1Unsupported="La codificació AV1 no és compatible amb cap GPU NVIDIA del sistema"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/cs-CZ.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/cs-CZ.ini
Changed
@@ -498,12 +498,14 @@ Basic.Main.PreviewDisabled="Náhled je zakázán" Basic.SourceSelect="Přidat zdroj" Basic.SourceSelect.SelectType="Typ zdroje" -Basic.SourceSelect.Recent="Nedávno přidáno" -Basic.SourceSelect.NewSource="Vytvořit nový zdroj" -Basic.SourceSelect.Existing="Přidat existující zdroj" +Basic.SourceSelect.Recent="Nedávno vytvořené" +Basic.SourceSelect.Description="Vyberte zdroje, které máte přidat do aktuální scény." +Basic.SourceSelect.NewSource="Přidat nový %1" +Basic.SourceSelect.AddExisting="Přidat %1 existující(ch)" +Basic.SourceSelect.NoSelection="Přidat existující" Basic.SourceSelect.CreateButton="Vytvořit nový" Basic.SourceSelect.AddVisible="Zviditelnit zdroj" -Basic.SourceSelect.NoExisting="Žádné existující zdroje typu %1" +Basic.SourceSelect.NoExisting="Zatím nemáte žádné %1 zdroje." Basic.SourceSelect.Accessible.SourceName="Název zdroje" Basic.SourceSelect.Accessible.Existing="Přidat existující zdroj" Basic.SourceSelect.Deprecated.Create="Tento typ zdroje byl označen jako zastaralý a může být v budoucnu odstraněn." @@ -1180,6 +1182,8 @@ Unmute="Odtlumit" Push-to-mute="Ztlumit podržením" Push-to-talk="Naslouchat podržením" +MonitorOn="Zapnout monitorování" +MonitorOff="Vypnout monitorování" SceneItemShow="Zobrazit '%1'" SceneItemHide="Skrýt '%1'" OutputWarnings.NoTracksSelected="Musíte vybrat alespoň jednu stopu" @@ -1344,5 +1348,27 @@ PluginManager.Section.Discover="Procházet" PluginManager.Section.Manage="Nainstalované" PluginManager.Section.Updates="Aktualizace" -PluginManager.Section.Manage.Title="Spravovat povolené pluginy" Accessible.Widget.Name.AlignmentSelector="Výběr zarovnání" +EncoderMissing.Title="Chybějící enkodéry" +EncoderMissing.Text="Chybí následující nakonfigurované enkodéry: \n<ul>\n%1</ul><br>\nDalší informace najdete v <a href=\"%2\">článku znalostní báze</a>." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (kód: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Neznámý" +EncoderMissing.MissingModule="Modul \"%1\" nebyl načten" +EncoderMissing.NVENC.TestProgramFailedStartup="Chyba při spuštění kontrolního programu NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Selhání kontrolního procesu NVENC, chybový kód: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Chyba při čtení výstupu procesu kontroly NVENC, chybový kód: %1" +EncoderMissing.NVENC.TestProgramError="Kontrola NVENC selhala z důvodu: %1" +EncoderMissing.NVENC.NoDevices="Nebyly nalezeny žádné grafické karty NVIDIA" +EncoderMissing.NVENC.Unsupported.Kepler="Architektura (Kepler) vaší GPU (%1) již není podporována. Použijte prosím OBS verze 30.2 nebo starší." +EncoderMissing.NVENC.Reason.NvmlLoad="Chyba při načítání knihovny NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Chyba při inicializaci NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Chyba při načítání knihovny NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Chyba při inicializaci NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Verze NVENC prázdná" +EncoderMissing.NVENC.Reason.CudaLoad="Chyba při načítání knihovny CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Chyba při inicializaci CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Neplatná/chybějící verze CUDA" +EncoderMissing.NVENC.Reason.DriverOutdated="Zastaralý ovladač" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Nebyla nalezena žádná NVIDIA zařízení s podporou NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Byl překročen limit relací enkodéru" +EncoderMissing.NVENC.Reason.AV1Unsupported="Kódování AV1 není podporováno žádnou z GPU NVIDIA v tomto systému"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/da-DK.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/da-DK.ini
Changed
@@ -115,6 +115,7 @@ CrashHandling.Labels.Text="OBS Studio lukkede ikke rigtigt ned.\n\nStart i Fejlsikret tilstand (tredjeparts udvidelser, scripts og WebSockets vil være slået fra)?" CrashHandling.Checkbox.SendReport="Jeg har læst privatlivspolitikken og samtykker til at uploade." CrashHandling.Buttons.LaunchSafe="Start i Fejlsikret tilstand" +CrashHandling.Buttons.LaunchNormal="Kør i normal tilstand" SafeMode.Restart="Vil du genstarte OBS i Fejlsikret tilstand (tredjeparts udvidelser, scripts og WebSockets vil være slået fra)?" SafeMode.RestartNormal="Vil du genstarte OBS i normal tilstand?" ChromeOS.Title="Uunderstøttet platform"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/de-DE.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/de-DE.ini
Changed
@@ -122,6 +122,10 @@ CrashHandling.Buttons.LaunchNormal="Im normalen Modus starten" CrashHandling.Errors.UploadJSONError="Beim Hochladen des Absturzprotokolls ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal." CrashHandling.Errors.Title="Fehler beim Hochladen des Absturzprotokolls" +PluginFailure.Dialog.Title="Plugin-Fehler" +PluginFailure.Labels.Text="OBS Studio konnte nicht alle Drittanbieter-Plugins laden.\n\nWeitere Details sind im Plugin-Manager verfügbar." +PluginFailure.Dialog.Continue="Ignorieren" +PluginFailure.Dialog.Open="Plugin-Manager öffnen" SafeMode.Restart="Möchten Sie OBS im abgesicherten Modus (mit deaktivierten Drittanbieter-Plugins, Skripten und WebSockets) neu starten?" SafeMode.RestartNormal="Möchten Sie OBS im normalen Modus neu starten?" ChromeOS.Title="Nicht unterstützte Plattform" @@ -489,12 +493,14 @@ Basic.Main.PreviewDisabled="Vorschau ist deaktiviert" Basic.SourceSelect="Quelle hinzufügen" Basic.SourceSelect.SelectType="Quellentyp" -Basic.SourceSelect.Recent="Zuletzt hinzugefügt" -Basic.SourceSelect.NewSource="Neue Quelle hinzufügen" -Basic.SourceSelect.Existing="Vorhandene Quelle hinzufügen" +Basic.SourceSelect.Recent="Kürzlich erstellt" +Basic.SourceSelect.Description="Wählen Sie die Quelle(n) aus, die Sie zur aktuellen Szene hinzufügen wollen." +Basic.SourceSelect.NewSource="%1-Quelle hinzufügen" +Basic.SourceSelect.AddExisting="Vorhandene %1-Quelle hinzufügen" +Basic.SourceSelect.NoSelection="Vorhandene hinzufügen" Basic.SourceSelect.CreateButton="Neu erstellen" Basic.SourceSelect.AddVisible="Quelle sichtbar" -Basic.SourceSelect.NoExisting="Keine vorhandenen %1-Quellen" +Basic.SourceSelect.NoExisting="Noch keine %1-Quelle vorhanden" Basic.SourceSelect.Accessible.SourceName="Name der Quelle" Basic.SourceSelect.Accessible.Existing="Vorhandene Quelle hinzufügen" Basic.SourceSelect.Deprecated.Create="Dieser Quelltyp ist als veraltet markiert und wird möglicherweise in Zukunft entfernt." @@ -1152,6 +1158,8 @@ Unmute="Stummschaltung aufheben" Push-to-mute="Push-To-Mute" Push-to-talk="Push-To-Talk" +MonitorOn="Monitoring aktivieren" +MonitorOff="Monitoring deaktivieren" SceneItemShow="„%1“ anzeigen" SceneItemHide="„%1“ verbergen" OutputWarnings.NoTracksSelected="Sie müssen mindestens eine Spur auswählen." @@ -1313,5 +1321,40 @@ PluginManager.SafeMode="Alle Plugins wurden durch den abgesicherten Modus temporär deaktiviert" PluginManager.Section.Discover="Durchsuchen" PluginManager.Section.Manage="Installiert" -PluginManager.Section.Manage.Title="Aktive Plugins verwalten" +PluginManager.Section.Manage.Title="Installiert" +PluginManager.Section.Manage.Description="Verwalten Sie ihre installierten Plugins" +PluginManager.Section.Manage.NoPlugins="Keine Plugins gefunden." +PluginManager.Section.Errors.Title="Fehler" +PluginManager.Section.Errors.Description="Diese Plugins konnten nicht geladen werden. Stellen Sie sicher, dass die Plugins aktuell und mit der jetzigen OBS-Version kompatibel sind." +PluginManager.Section.Missing.Title="Fehlend" +PluginManager.Section.Missing.Description="Diese Plugins wurden zuvor installiert, können aber nicht mehr gefunden werden." +PluginManager.Button.Enable="Plugin \"%1\" aktivieren" +PluginManager.Status.Legacy="Veraltet" +PluginManager.Status.Disabled="Deaktiviert" +PluginManager.Status.Error="Fehler" +PluginManager.Status.Missing="Fehlend" +PluginManager.Status.Legacy.Description="Dieses Plugin wurde in einem Dateipfad installiert, welcher in der Zukunft nicht mehr unterstützt wird. <a href=\"%1\">Mehr erfahren</a>" Accessible.Widget.Name.AlignmentSelector="Ausrichtungsauswahl" +EncoderMissing.Title="Fehlender Kodierer" +EncoderMissing.Text="Die folgenden konfigurierten Kodierer fehlen:\n<ul>\n%1</ul><br>\nIn unserer <a href=\"%2\">Knowledge Base</a> finden Sie weitere Informationen." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (Code: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Unbekannt" +EncoderMissing.MissingModule="Modul \"%1\" wurde nicht geladen" +EncoderMissing.NVENC.TestProgramFailedStartup="Start der NVENC-Testanwendung fehlgeschlagen" +EncoderMissing.NVENC.TestProgramExitWithError="Start der NVENC-Testanwendung fehlgeschlagen, Rückgabewert: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Ausgabe der NVENC-Testanwendung konnte nicht gelesen werden, Rückgabewert: %1" +EncoderMissing.NVENC.TestProgramError="NVENC-Testanwendung fehlgeschlagen mit Grund: %1" +EncoderMissing.NVENC.NoDevices="Keine NVIDIA-Grafikkarte(n) gefunden" +EncoderMissing.NVENC.Unsupported.Kepler="Die Architektur (Kepler) der Grafikkarte (%1) wird nicht länger unterstützt. Nutzen Sie bitte stattdessen OBS 30.2 oder älter." +EncoderMissing.NVENC.Reason.NvmlLoad="Laden der NVML-Bibliothek fehlgeschlagen" +EncoderMissing.NVENC.Reason.NvmlInit="Initialisierung von NVML fehlgeschlagen" +EncoderMissing.NVENC.Reason.NvencLoad="Laden der NVENC-Bibliothek fehlgeschlagen" +EncoderMissing.NVENC.Reason.NvencInit="Initialisierung von NVENC fehlgeschlagen" +EncoderMissing.NVENC.Reason.NvencVersion="Keine NVENC-Version erkannt" +EncoderMissing.NVENC.Reason.CudaLoad="Laden der CUDA-Bibliothek fehlgeschlagen" +EncoderMissing.NVENC.Reason.CudaInit="Initialisierung von CUDA fehlgeschlagen" +EncoderMissing.NVENC.Reason.CudaVersion="Ungültige oder fehlende CUDA-Version " +EncoderMissing.NVENC.Reason.DriverOutdated="Veraltete Grafiktreiber" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Keine NVIDIA-Geräte mit NVENC-Unterstützung gefunden" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Kodierer-Sitzungslimit überschritten" +EncoderMissing.NVENC.Reason.AV1Unsupported="Die AV1-Kodierung wird von keiner installierten NVIDIA-Grafikkarte unterstützt"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/el-GR.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/el-GR.ini
Changed
@@ -1238,5 +1238,4 @@ PluginManager.Section.Discover="Περιήγηση" PluginManager.Section.Manage="Εγκατεστημένο" PluginManager.Section.Updates="Ενημερώσεις" -PluginManager.Section.Manage.Title="Διαχείριση ενεργών πρόσθετων" Accessible.Widget.Name.AlignmentSelector="Επιλογέας στοίχισης"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/en-GB.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/en-GB.ini
Changed
@@ -104,3 +104,9 @@ MultitrackVideo.Info="%1 automatically optimises your stream settings, which may include encoding multiple video qualities and/or canvas orientations. Selecting this option will send %2 information about your computer and software setup." Basic.OpenPluginManager="Plug-in Manager" PluginManager="Plug-in Manager" +PluginManager.Status.Legacy.Description="This plugin is installed to a location that will stop working in the future. <a href=\"%1\">Learn More</a>" +EncoderMissing.Text="The following configured encoders are missing:\n<ul>\n%1</ul><br>\nSee the <a href=\"%2\">Knowledge Base Article</a> for further information." +EncoderMissing.MissingModule="Module \"%1\" not loaded" +EncoderMissing.NVENC.Reason.NvmlInit="Failed initialising NVML" +EncoderMissing.NVENC.Reason.NvencInit="Failed initialising NVENC" +EncoderMissing.NVENC.Reason.CudaInit="Failed initialising CUDA"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/en-US.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/en-US.ini
Changed
@@ -141,6 +141,12 @@ CrashHandling.Errors.UploadJSONError="An error occurred while trying to upload the most recent crash log. Please try again later." CrashHandling.Errors.Title="Crash Log Upload Error" +# Plugin Manager Load Failure +PluginFailure.Dialog.Title="Plugin Errors" +PluginFailure.Labels.Text="OBS Studio was not able to load all third-party plugins.\n\nMore details are available in the plugin manager." +PluginFailure.Dialog.Continue="Dismiss" +PluginFailure.Dialog.Open="Open Plugin Manager" + # Safe Mode Restart Option SafeMode.Restart="Do you want to restart OBS in Safe Mode (third-party plugins, scripting, and WebSockets disabled)?" SafeMode.RestartNormal="Do you want to restart OBS in Normal Mode?" @@ -1454,6 +1460,8 @@ Unmute="Unmute" Push-to-mute="Push-to-mute" Push-to-talk="Push-to-talk" +MonitorOn="Enable Monitoring" +MonitorOff="Disable Monitoring" # scene item hotkeys SceneItemShow="Show '%1'" @@ -1676,7 +1684,46 @@ PluginManager.Section.Discover="Browse" PluginManager.Section.Manage="Installed" PluginManager.Section.Updates="Updates" -PluginManager.Section.Manage.Title="Manage Enabled Plugins" +PluginManager.Section.Manage.Title="Installed" +PluginManager.Section.Manage.Description="Manage your currently installed plugins." +PluginManager.Section.Manage.NoPlugins="No plugins found." +PluginManager.Section.Errors.Title="Errors" +PluginManager.Section.Errors.Description="These plugins failed to load. Make sure they are up to date and compatible with this version of OBS Studio." +PluginManager.Section.Missing.Title="Missing" +PluginManager.Section.Missing.Description="These plugins were previously installed but can no longer be found." +PluginManager.Button.Enable="Enable %1 plugin" +PluginManager.Status.Legacy="Legacy" +PluginManager.Status.Disabled="Disabled" +PluginManager.Status.Error="Error" +PluginManager.Status.Missing="Missing" +PluginManager.Status.Legacy.Description="This plugin is installed to a location that will stop working in the future. <a href=\"%1\">Learn More</a>" # Custom Widget Localization Accessible.Widget.Name.AlignmentSelector="Alignment Selector" + +# Missing Encoder Warning +EncoderMissing.Title="Missing Encoders" +EncoderMissing.Text="The following configured encoders are missing:\n<ul>\n%1</ul><br>\nSee the <a href=\"%2\">Knowledge Base Article</a> for further information." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (code: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Unknown" +EncoderMissing.MissingModule="Module \"%1\" not loaded" + +## Nvenc specific errors +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC check program start failure" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC check process failure, exit code: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC check process output read failure, exit code: %1" +EncoderMissing.NVENC.TestProgramError="NVENC check failed with reason: %1" +EncoderMissing.NVENC.NoDevices="No NVIDIA GPUs found" +EncoderMissing.NVENC.Unsupported.Kepler="The architecture (Kepler) of your GPU (%1) is no longer supported. Please use OBS 30.2 or earlier instead." +EncoderMissing.NVENC.Reason.NvmlLoad="Failed loading NVML library" +EncoderMissing.NVENC.Reason.NvmlInit="Failed initializing NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Failed loading NVENC library" +EncoderMissing.NVENC.Reason.NvencInit="Failed initializing NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC version empty" +EncoderMissing.NVENC.Reason.CudaLoad="Failed loading CUDA library" +EncoderMissing.NVENC.Reason.CudaInit="Failed initializing CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Invalid/Missing CUDA version" +EncoderMissing.NVENC.Reason.DriverOutdated="Outdated driver" +EncoderMissing.NVENC.Reason.NoSupportedDevices="No NVIDIA devices with NVENC support found" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Encoder session limit exceeded" +EncoderMissing.NVENC.Reason.AV1Unsupported="AV1 encoding is not supported by any of the system's NVIDIA GPUs"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/es-ES.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/es-ES.ini
Changed
@@ -40,16 +40,16 @@ Show="Mostrar" Hide="Ocultar" UnhideAll="Mostrar todos" -Untitled="Sin Título" +Untitled="Sin título" New="Nuevo" Duplicate="Duplicar" Enable="Habilitar" DisableOSXVSync="Deshabilitar V-Sync en macOS" -ResetOSXVSyncOnExit="Resetear V-Sync de macOS al salir" +ResetOSXVSyncOnExit="Restablecer V-Sync de macOS al salir" HighResourceUsage="¡Sobrecarga al codificar! Considera bajar los ajustes de vídeo o usa una configuración del codificador más rápida." Transition="Transición" QuickTransitions="Transiciones rápidas" -FadeToBlack="Desvanecer a negro" +FadeToBlack="Fundido a negro" Left="Izquierda" Right="Derecha" Top="Arriba" @@ -78,7 +78,7 @@ ShowTransition="Transición al mostrar" HideTransition="Transición al ocultar" None="Ninguno" -StudioMode.Preview="Vista Previa" +StudioMode.Preview="Vista previa" StudioMode.Program="Programa" StudioMode.PreviewSceneName="Vista previa: %1" StudioMode.ProgramSceneName="Programa: %1" @@ -125,6 +125,10 @@ CrashHandling.Buttons.LaunchNormal="Ejecutar en modo normal" CrashHandling.Errors.UploadJSONError="Se ha producido un error al intentar subir el registro de error más reciente. Por favor, inténtalo más tarde." CrashHandling.Errors.Title="Error al subir el registro de errores" +PluginFailure.Dialog.Title="Errores de extensión" +PluginFailure.Labels.Text="OBS Studio no fue capaz de cargar todas las extensiones de terceros.\n\nMás detalles disponibles en el administrador de extensiones" +PluginFailure.Dialog.Continue="Descartar" +PluginFailure.Dialog.Open="Abrir administrador de extensiones" SafeMode.Restart="¿Quieres reiniciar OBS en modo seguro (plugins de terceros, scripts y websockets deshabilitados)?" SafeMode.RestartNormal="¿Quieres reiniciar OBS en modo normal?" ChromeOS.Title="Plataforma no soportada" @@ -498,14 +502,16 @@ Basic.Main.PreviewDisabled="Vista previa desactivada" Basic.SourceSelect="Añadir fuente" Basic.SourceSelect.SelectType="Tipo de fuente" -Basic.SourceSelect.Recent="Añadido recientemente" -Basic.SourceSelect.NewSource="Crear nueva fuente" -Basic.SourceSelect.Existing="Añadir fuente existente" +Basic.SourceSelect.Recent="Creado recientemente" +Basic.SourceSelect.Description="Selecciona qué fuente(s) añadir a tu escena actual" +Basic.SourceSelect.NewSource="Añadir un(a) nuevo(a) %1" +Basic.SourceSelect.AddExisting="Añadir %1 existente" +Basic.SourceSelect.NoSelection="Añadir existente" Basic.SourceSelect.CreateButton="Crear nueva" Basic.SourceSelect.AddVisible="Hacer visible la fuente" -Basic.SourceSelect.NoExisting="No existen fuentes %1" +Basic.SourceSelect.NoExisting="No tienes una fuente de %1 existente todavía." Basic.SourceSelect.Accessible.SourceName="Nombre de la fuente" -Basic.SourceSelect.Accessible.Existing="Añadir fuente existente" +Basic.SourceSelect.Accessible.Existing="Añadir una fuente existente" Basic.SourceSelect.Deprecated.Create="Este tipo de fuente está marcada como obsoleta y puede ser eliminada en el futuro." Basic.Main.Sources.Visibility="Visibilidad" Basic.Main.Sources.VisibilityDescription="Controla la visibilidad de '%1' en el lienzo" @@ -1124,6 +1130,7 @@ Basic.AdvAudio.Monitoring="Monitorización de audio" Basic.AdvAudio.Monitoring.None="Monitorización desactivada" Basic.AdvAudio.Monitoring.MonitorOnly="Solo monitorización (salida silenciada)" +Basic.AdvAudio.Monitoring.Both="Monitorización activada" Basic.AdvAudio.MonitoringSource="Monitorización de audio para '%1'" Basic.AdvAudio.AudioTracks="Pistas" Basic.Settings.Hotkeys="Atajos" @@ -1173,6 +1180,8 @@ Unmute="Quitar silencio" Push-to-mute="Pulsar para Silenciar" Push-to-talk="Pulsar para Hablar" +MonitorOn="Habilitar monitorización" +MonitorOff="Deshabilitar monitorización" SceneItemShow="Mostrar '%1'" SceneItemHide="Ocultar '%1'" OutputWarnings.NoTracksSelected="Debe seleccionar al menos una pista" @@ -1337,5 +1346,39 @@ PluginManager.Section.Discover="Examinar" PluginManager.Section.Manage="Instalado" PluginManager.Section.Updates="Actualizaciones" -PluginManager.Section.Manage.Title="Administrar plugins habilitados" +PluginManager.Section.Manage.Title="Instalado" +PluginManager.Section.Manage.Description="Administra tus extensiones instaladas" +PluginManager.Section.Manage.NoPlugins="Extensiones no encontradas." +PluginManager.Section.Errors.Title="Errores" +PluginManager.Section.Errors.Description="Estas extensiones no se cargaron correctamente. Asegúrate de que están actualizadas y son compatibles con esta versión de OBS Studio." +PluginManager.Section.Missing.Title="No encontrados" +PluginManager.Section.Missing.Description="Estas extensiones estaban instaladas pero ya no se encuentran." +PluginManager.Button.Enable="Habilitar %1 de la extensión" +PluginManager.Status.Legacy="Legado" +PluginManager.Status.Disabled="Desactivado" +PluginManager.Status.Missing="No encontrado" +PluginManager.Status.Legacy.Description="Esta extensión está instalada en una localización que puede que deje de funcionar en el futuro. <a href=\"%1\">Aprender más</a>" Accessible.Widget.Name.AlignmentSelector="Selector de alineamiento" +EncoderMissing.Title="Faltan Codificadores" +EncoderMissing.Text="Faltan los siguientes codificadores configurados:\n<ul>\n%1</ul><br>\nSonsulta el <a href=\"%2\">artículo de la base de conocimientos</a> para obtener más información." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (código: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Desconocido" +EncoderMissing.MissingModule="Módulo \"%1\" not loaded" +EncoderMissing.NVENC.TestProgramFailedStartup="Fallo al iniciar el programa de comprobación de NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Fallo en el proceso de comprobación de NVENC, código de salida: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Fallo al leer la salida del proceso de comprobación de NVENC, código de salida: %1" +EncoderMissing.NVENC.TestProgramError="La comprobación de NVENC falló con el motivo: %1" +EncoderMissing.NVENC.NoDevices="No se han encontrado GPUs de NVIDIA" +EncoderMissing.NVENC.Unsupported.Kepler="La arquitectura (Kepler) de tu GPU (%1) ya no es compatible. Por favor utiliza en su lugar OBS 30.2 o versiones anteriores." +EncoderMissing.NVENC.Reason.NvmlLoad="Error al cargar la biblioteca NVML" +EncoderMissing.NVENC.Reason.NvmlInit="" +EncoderMissing.NVENC.Reason.NvencLoad="Error al iniciar la biblioteca NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Error al iniciar NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Versión del NVENC vacía" +EncoderMissing.NVENC.Reason.CudaLoad="Error al cargar la biblioteca CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Error al iniciar CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Versión del CUDA inválida/vacía" +EncoderMissing.NVENC.Reason.DriverOutdated="Driver obsoleto" +EncoderMissing.NVENC.Reason.NoSupportedDevices="No se han encontrado dispositivos NVIDIA compatibles con NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Límite de sesión de codificación alcanzado" +EncoderMissing.NVENC.Reason.AV1Unsupported="Codificación AV1 no es compatible con ninguna de las GPUs de NVIDIA del sistema"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/et-EE.ini
Changed
@@ -124,6 +124,10 @@ CrashHandling.Buttons.LaunchNormal="Käivita tavarežiimis" CrashHandling.Errors.UploadJSONError="Uusima krahhilogi üleslaadimisel ilmnes viga. Palun proovige hiljem uuesti." CrashHandling.Errors.Title="Krahhi logi üleslaadimise viga" +PluginFailure.Dialog.Title="Plugina vead" +PluginFailure.Labels.Text="OBS Studio ei suutnud kõiki kolmanda osapoole pluginaid laadida.\n\nRohkem teavet leidub plugina halduris." +PluginFailure.Dialog.Continue="Eira" +PluginFailure.Dialog.Open="Ava pluginate haldur" SafeMode.Restart="Kas soovid OBS-i taaskäivitada turvalises režiimis (kolmandate osapoolte pluginad, skriptid ja WebSockets on keelatud)?" SafeMode.RestartNormal="Kas soovid OBS-i taaskäivitada tavarežiimis?" ChromeOS.Title="Toetuseta platvorm" @@ -288,8 +292,8 @@ Undo.Transform.Paste="Kleebi teisendus faili '%1'" Undo.Transform.Rotate="Pööramine '%1'-s" Undo.Transform.Reset="Teisendus Lähtesta failis '%1'" -Undo.Transform.HFlip="Horisontaalne pööramine '%1'-s" -Undo.Transform.VFlip="Vertikaalne pööramine '%1'-s" +Undo.Transform.HFlip="Horisontaalne peegeldamine '%1'-s" +Undo.Transform.VFlip="Vertikaalne peegeldamine '%1'-s" Undo.Transform.FitToScreen="Sobita ekraanile %1" Undo.Transform.StretchToScreen="Venita ekraanile '%1'" Undo.Transform.Center="Ekraani keskele paigutamine '%1'-s" @@ -318,6 +322,11 @@ Undo.PasteSource="Kleebi allikas(ed) kausta '%1'" Undo.PasteSourceRef="Kleebi allikaviide(d) kausta '%1'" Undo.GroupItems="Rühmita üksused „%1“ alusel" +Undo.ScaleFiltering="Skaala filtreerimine‚ %1 puhul‚ %2-s" +Undo.BlendingMode="Seginemise režiim, %1 puhul‚ %2-s" +Undo.BlendingMethod="Segunemise meetod, %1 puhul‚ %2-s" +Undo.DeinterlacingMode="Ülerealaotuse eemaldamise režiim, %1 puhul" +Undo.DeinterlacingOrder="Ülerealaotuse eemaldamise väljade järjestamine, %1 puhul" TransitionNameDlg.Text="Sisesta ülemineku nimi" TransitionNameDlg.Title="Ülemineku nimi" TitleBar.SafeMode="TURVAREŽIIM" @@ -467,7 +476,7 @@ BlendingMode.Multiply="Korrutamine" BlendingMode.Lighten="Helendamine" BlendingMode.Darken="Tumendamine" -Deinterlacing="Põimingu eemaldamine" +Deinterlacing="Ülerealaotuse eemaldamine" Deinterlacing.Discard="Loobu" Deinterlacing.TopFieldFirst="Ülemine väli esimesena" Deinterlacing.BottomFieldFirst="Alumine väli esimesena" @@ -498,14 +507,17 @@ Basic.Main.PreviewDisabled="Eelvaade on hetkel välja lülitatud" Basic.SourceSelect="Lisa allikas" Basic.SourceSelect.SelectType="Allika tüüp" -Basic.SourceSelect.Recent="Hiljuti lisatud" -Basic.SourceSelect.NewSource="Loo uus allikas" -Basic.SourceSelect.Existing="Lisa olemasolev allikas" +Basic.SourceSelect.Recent="Hiljuti loodud" +Basic.SourceSelect.Description="Vali, millise(id) allika(id) soovid oma praegusesse stseeni lisada." +Basic.SourceSelect.NewSource="Lisa uus %1" +Basic.SourceSelect.AddExisting="Lisa %1 olemasolev" +Basic.SourceSelect.NoSelection="Lisa olemasolev" Basic.SourceSelect.CreateButton="Loo uus" Basic.SourceSelect.AddVisible="Tee allikas nähtavaks" -Basic.SourceSelect.NoExisting="Pole olemasolevaid %1 allikaid" +Basic.SourceSelect.NoExisting="Sul pole veel ühtegi %1 allikat." Basic.SourceSelect.Accessible.SourceName="Allika nimi" Basic.SourceSelect.Accessible.Existing="Lisa olemasolev allikas" +Basic.SourceSelect.Deprecated.Create="See allikatüüp on märgitud vananenuks ja võib saada tulevikus eemaldatud." Basic.Main.Sources.Visibility="Nähtavus" Basic.Main.Sources.VisibilityDescription="Juhib '%1' nähtavust lõuendil" Basic.Main.Sources.Lock="Lukusta" @@ -660,8 +672,8 @@ Basic.MainMenu.Edit.Transform.Rotate90CW="Pööra 90 kraadi paremale" Basic.MainMenu.Edit.Transform.Rotate90CCW="Pööra 90 kraadi vasakule" Basic.MainMenu.Edit.Transform.Rotate180="Pööra 180 kraadi" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Pööra &horisontaalseks" -Basic.MainMenu.Edit.Transform.FlipVertical="Pööra &vertikaalseks" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Peegelda &horisontaalselt" +Basic.MainMenu.Edit.Transform.FlipVertical="Peegelda &vertikaalselt" Basic.MainMenu.Edit.Transform.FitToScreen="Sobita ekraanile (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="Venita ekraanile (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="Joonda ekraani &keskele" @@ -1177,6 +1189,8 @@ Unmute="Lõpeta summutamine" Push-to-mute="Vajuta ja vaigista" Push-to-talk="Vajuta ja räägi" +MonitorOn="Lülita jälgimine sisse" +MonitorOff="Lülita jälgimine välja" SceneItemShow="Näita „%1“" SceneItemHide="Peida '%1'" OutputWarnings.NoTracksSelected="Pead valima vähemalt ühe raja" @@ -1319,6 +1333,7 @@ FailedToStartStream.FailedToGetOBSVideoInfo="OBS-video info hankimine kodeerija '%1' loomisel ebaõnnestus (tüüp: '%2')" FailedToStartStream.FailedToCreateAudioEncoder="Helikooderi loomine ebaõnnestus" FailedToStartStream.FallbackToDefault="Voo käivitamine %1 abil nurjus; kas soovite uuesti proovida ühe kodeerimise sätetega?" +FailedToStartStream.ConfigRequestFailed="Konfiguratsiooni ei õnnestunud %1-st alla laadida\n\nHTTP-viga: %2" FailedToStartStream.WarningUnknownStatus="Saadi tundmatu olekuväärtus '%1'" FailedToStartStream.WarningRetryNonMultitrackVideo="\n\nKas soovite voogedastust jätkata ilma %1-ta?" FailedToStartStream.WarningRetry="\n\nKas soovite voogedastust jätakata?" @@ -1326,6 +1341,7 @@ FailedToStartStream.InvalidEncoderConfig="Avaldamise konfiguratsioon sisaldas sobimatut kodeerija konfiguratsiooni" FailedToStartStream.StatusMissingHTML="Avaldamise taotlus tagastas määratlemata vea" FailedToStartStream.NoConfigSupplied="Puuduv konfiguratsioon" +MultitrackVideo.Info="%1 optimeerib automaatselt sinu voogedastuse seadeid, mis võivad hõlmata mitme erineva videokvaliteedi ja/või lõuendi suuna kodeerimist. Selle valiku valimisel saadetakse %2-le teavet sinu arvuti ja tarkvara seadistuste kohta." MultitrackVideo.IncompatibleSettings.Title="Ühildamatud seaded" MultitrackVideo.IncompatibleSettings.AudioChannels="%1 ei ole hetkel ühilduv Heli → Üldine → Kanalid seadistusega '%2', %3" MultitrackVideo.IncompatibleSettings.AudioChannelsSingle="Heli → Üldine → Kanalid peab olema seatud väärtusele '%1'" @@ -1338,5 +1354,40 @@ PluginManager.Section.Discover="Sirvi" PluginManager.Section.Manage="Paigaldatud" PluginManager.Section.Updates="Värskendused" -PluginManager.Section.Manage.Title="Halda lubatud pluginaid" +PluginManager.Section.Manage.Title="Paigaldatud" +PluginManager.Section.Manage.Description="Halda oma paigaldatud pluginaid" +PluginManager.Section.Manage.NoPlugins="Pluginaid ei leitud" +PluginManager.Section.Errors.Title="Vead" +PluginManager.Section.Errors.Description="Neid pluginaid ei õnnestunud laadida. Veendu, et need oleksid ajakohased ja ühilduvad selle OBS Studio versiooniga." +PluginManager.Section.Missing.Title="Puudub" +PluginManager.Section.Missing.Description="Need pluginad olid varem paigaldatud, kuid neid ei ole enam võimalik leida." +PluginManager.Button.Enable="Luba %1 plugin" +PluginManager.Status.Legacy="Pärand" +PluginManager.Status.Disabled="Keelatud" +PluginManager.Status.Error="Viga" +PluginManager.Status.Missing="Puudub" +PluginManager.Status.Legacy.Description="See plugin on paigaldatud asukohta, mis tulevikus enam ei tööta. <a href=\"%1\">Lisateave</a>" Accessible.Widget.Name.AlignmentSelector="Joonduse valik" +EncoderMissing.Title="Kodeerijad puuduvad" +EncoderMissing.Text="Puuduvad järgmised konfigureeritud kodeerijad: \n<ul>\n%1</ul><br>\nLisateavet saab <a href=\"%2\">Teadmistebaasi artiklist</a>." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (kod: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Tundmatu" +EncoderMissing.MissingModule="Moodul „%1“ ei ole laaditud" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC kontrollprogrammi käivitamise ebaõnnestumine" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC kontrolliprotsessi viga, lõpetamiskood: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC-kontrolliprotsessi väljundi lugemise viga, lõpetamiskood: %1" +EncoderMissing.NVENC.TestProgramError="NVENC kontroll ebaõnnestus järgmisel põhjusel: %1" +EncoderMissing.NVENC.NoDevices="NVIDIA graafikakaarte ei leitud" +EncoderMissing.NVENC.Unsupported.Kepler="Sinu GPU (%1) arhitektuuri (Kepler) ei toetata enam. Palun kasuta selle asemel OBS 30.2 või varasemat versiooni." +EncoderMissing.NVENC.Reason.NvmlLoad="NVML teegi laadimine ebaõnnestus" +EncoderMissing.NVENC.Reason.NvmlInit="NVML-i algseadistamine ebaõnnestus" +EncoderMissing.NVENC.Reason.NvencLoad="NVENC teegi laadimine ebaõnnestus" +EncoderMissing.NVENC.Reason.NvencInit="NVENC-i algseadistamine ebaõnnestus" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC versioon puudub" +EncoderMissing.NVENC.Reason.CudaLoad="CUDA teegi laadimine ebaõnnestus" +EncoderMissing.NVENC.Reason.CudaInit="CUDA algseadistamine ebaõnnestus" +EncoderMissing.NVENC.Reason.CudaVersion="CUDA versioon on kehtetu/puudub" +EncoderMissing.NVENC.Reason.DriverOutdated="Aegunud draiver" +EncoderMissing.NVENC.Reason.NoSupportedDevices="NVENC-t toetavaid NVIDIA seadmeid ei leitud" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Kodeerija seansi piirang ületatud" +EncoderMissing.NVENC.Reason.AV1Unsupported="Süsteemi ükski NVIDIA graafikakaartidest ei toeta AV1-kodeeringut"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/eu-ES.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/eu-ES.ini
Changed
@@ -127,6 +127,10 @@ CrashHandling.Buttons.LaunchNormal="Exekutatu modu arruntean" CrashHandling.Errors.UploadJSONError="Errore bat gertatu da saiatzean azken hutsegite-txostena igotzen. Saiatu beranduago." CrashHandling.Errors.Title="Hutsegite erregistroa igotzeko errorea" +PluginFailure.Dialog.Title="Pluginen erroreak" +PluginFailure.Labels.Text="OBS Studio-k ezin izan ditu hirugarrenen plugin guztiak kargatu.\n\nXehetasun gehiago eskuragarri daude plugin-kudeatzailean." +PluginFailure.Dialog.Continue="Baztertu" +PluginFailure.Dialog.Open="Ireki Pluginen kudeatzailea" SafeMode.Restart="OBS modu seguruan berrabiarazi nahi duzu (hirugarrenen pluginak, script-ak eta WebSockets desgaituta)?" SafeMode.RestartNormal="Nahi duzu OBS modu normalean berrabiarazi ?" ChromeOS.Title="Euskarririk gabeko plataforma" @@ -506,14 +510,16 @@ Basic.Main.PreviewDisabled="Aurrebista ezgaituta dago" Basic.SourceSelect="Gehitu iturburua" Basic.SourceSelect.SelectType="Iturburu mota" -Basic.SourceSelect.Recent="Duela gutxikoa" -Basic.SourceSelect.NewSource="Sortu iturburu berria" -Basic.SourceSelect.Existing="Gehitu dagoen iturburu bat" +Basic.SourceSelect.Recent="Duela gutxi sortuak" +Basic.SourceSelect.Description="Hautatu zein iturri gehitu zure uneko eszenari." +Basic.SourceSelect.NewSource="Gehitu %1 berri bat" +Basic.SourceSelect.AddExisting="Gehitu lehendik dagoen %1" +Basic.SourceSelect.NoSelection="Gehitu lehendik dagoena" Basic.SourceSelect.CreateButton="Sortu berria" Basic.SourceSelect.AddVisible="Egin iturburua ikusgarri" -Basic.SourceSelect.NoExisting="Ez dago %1 iturbururik" +Basic.SourceSelect.NoExisting="Oraindik ez duzu %1 iturririk." Basic.SourceSelect.Accessible.SourceName="Iturburuaren izena" -Basic.SourceSelect.Accessible.Existing="Gehitu dagoen iturburu bat" +Basic.SourceSelect.Accessible.Existing="Gehitu lehendik dagoen iturri bat" Basic.SourceSelect.Deprecated.Create="Iturburu mota hau zaharkitu gisa markatu da eta baliteke etorkizunean kentzea." Basic.Main.Sources.Visibility="Ikusgaitasuna" Basic.Main.Sources.VisibilityDescription="Kontrolatzen du '%1' (e)k oihalean duen ikusgaitasuna" @@ -1203,6 +1209,8 @@ Unmute="Ez mututu" Push-to-mute="Sakatu-mututzeko" Push-to-talk="Sakatu-hitz-egiteko" +MonitorOn="Gaitu monitorizazioa" +MonitorOff="Desgaitu monitorizazioa" SceneItemShow="Erakutsi '%1'" SceneItemHide="Ezkutatu '%1'" OutputWarnings.NoTracksSelected="Gutxienez pista bat hautatu behar duzu" @@ -1368,5 +1376,39 @@ PluginManager.Section.Discover="Nabigatu" PluginManager.Section.Manage="Instalatua" PluginManager.Section.Updates="Eguneraketak" -PluginManager.Section.Manage.Title="Kudeatu gaitutako pluginak" +PluginManager.Section.Manage.Title="Instalatuta" +PluginManager.Section.Manage.Description="Kudeatu instalatutako pluginak." +PluginManager.Section.Manage.NoPlugins="Ez da pluginik aurkitu." +PluginManager.Section.Errors.Title="Erroreak" +PluginManager.Section.Errors.Description="Plugin hauek ezin izan dira kargatu. Ziurtatu eguneratuta daudela eta bateragarriak direla OBS Studio-ren bertsio honekin." +PluginManager.Section.Missing.Title="Falta da" +PluginManager.Section.Missing.Description="Plugin hauek lehenago instalatu ziren baina jada ezin dira aurkitu." +PluginManager.Button.Enable="Gaitu %1 plugina" +PluginManager.Status.Legacy="Zaharkitua" +PluginManager.Status.Disabled="Ezgaituta" +PluginManager.Status.Error="Errorea" +PluginManager.Status.Missing="Falta da" +PluginManager.Status.Legacy.Description="Plugin hau etorkizunean funtzionatzeari utziko dion kokapen batean instalatuta dago. <a href=\"%1\">Lortu informazio gehiago</a>" Accessible.Widget.Name.AlignmentSelector="Lerrokatze-hautatzailea" +EncoderMissing.Title="Kodetzaileak falta dira" +EncoderMissing.Text="Konfiguratutako kodetzaile hauek falta dira:\n<ul>\n%1</ul><br>\nIkusi <a href=\"%2\">Knowledge Base artikulua</a> informazio gehiago lortzeko." +EncoderMissing.Unknown="Ezezaguna" +EncoderMissing.MissingModule="\"%1\" modulua ez da kargatu" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC egiaztatzeko programaren hasierak huts egin du" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC egiaztatzeko prozesuaren hutsegitea, irteera kodea: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC egiaztatzeko prozesuaren irteera irakurtzeko hutsegitea, irteera kodea: %1" +EncoderMissing.NVENC.TestProgramError="NVENC egiaztapenak huts egin du arrazoi honekin: %1" +EncoderMissing.NVENC.NoDevices="Ez da NVIDIA GPUrik aurkitu" +EncoderMissing.NVENC.Unsupported.Kepler="Zure GPUaren (%1) arkitektura (Kepler) ez da jada onartzen. Mesedez, erabili OBS 30.2 edo lehenagokoa." +EncoderMissing.NVENC.Reason.NvmlLoad="Ezin izan da NVML liburutegia kargatu" +EncoderMissing.NVENC.Reason.NvmlInit="Ezin izan da NVML hasieratu" +EncoderMissing.NVENC.Reason.NvencLoad="Ezin izan da NVENC liburutegia kargatu" +EncoderMissing.NVENC.Reason.NvencInit="Ezin izan da NVENC hasieratu" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC bertsioa hutsik" +EncoderMissing.NVENC.Reason.CudaLoad="Ezin izan da CUDA liburutegia kargatu" +EncoderMissing.NVENC.Reason.CudaInit="Ezin izan da CUDA hasieratu" +EncoderMissing.NVENC.Reason.CudaVersion="CUDA bertsio baliogabea edo falta da" +EncoderMissing.NVENC.Reason.DriverOutdated="Kontrolatzaile zaharkitua" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Ez da NVENC euskarria duen NVIDIA gailurik aurkitu" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Kodetzailearen saioen muga gainditu da" +EncoderMissing.NVENC.Reason.AV1Unsupported="AV1 kodeketa ez du sistemaren NVIDIA GPU-k onartzen"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/fa-IR.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/fa-IR.ini
Changed
@@ -127,6 +127,10 @@ CrashHandling.Buttons.LaunchNormal="اجرا در حالت عادی" CrashHandling.Errors.UploadJSONError="در هنگام تلاش برای آپلود آخرین گزارش خرابی خطایی رخ داده است. لطفاً در زمان دیگری مجدداً تلاش کنید." CrashHandling.Errors.Title="خطا در آپلود گزارش خرابی" +PluginFailure.Dialog.Title="خطاهای افزونه" +PluginFailure.Labels.Text="OBS Studio نتوانست تمام افزونههای شخص ثالث را بارگذاری کند.\n\nجزئیات بیشتر در مدیریت افزونهها موجود است." +PluginFailure.Dialog.Continue="رد کردن" +PluginFailure.Dialog.Open="باز کردن مدیریت افزونهها" SafeMode.Restart="آیا مایل هستید OBS را در حالت ایمن (غیر فعال بودن پلاگین های شخص ثالث، اسکریپتها و وبسوکتها) ریاستارت کنید؟" SafeMode.RestartNormal="آیا مایل هستید OBS را در حالت عادی ریاستارت کنید؟" ChromeOS.Title="پلتفرم پشتیبانی نشده" @@ -508,12 +512,14 @@ Basic.Main.PreviewDisabled="پیش نمایش در حال حاضر غیرفعال است" Basic.SourceSelect="افزودن منبع" Basic.SourceSelect.SelectType="نوع منبع" -Basic.SourceSelect.Recent="اخیرا افزوده شده" -Basic.SourceSelect.NewSource="ایجاد منبع جدید" -Basic.SourceSelect.Existing="افزودن منبع موجود" +Basic.SourceSelect.Recent="به تازگی ایجاد شده" +Basic.SourceSelect.Description="منابعی را که می خواهید به صحنه فعلی خود اضافه کنید را انتخاب کنید" +Basic.SourceSelect.NewSource="اضافه کردن %1 جدید" +Basic.SourceSelect.AddExisting="اضافه کردن %1 موجود" +Basic.SourceSelect.NoSelection="اضافه کردن موجود" Basic.SourceSelect.CreateButton="ایجاد مورد جدید" Basic.SourceSelect.AddVisible="سورس را قابل رویت کن" -Basic.SourceSelect.NoExisting="هیچ منبع %1 موجود نیست" +Basic.SourceSelect.NoExisting="شما هنوز هیچ منبع %1 موجودی ندارید" Basic.SourceSelect.Accessible.SourceName="نام منبع" Basic.SourceSelect.Accessible.Existing="افزودن منبع موجود" Basic.SourceSelect.Deprecated.Create="این نوع منبع به عنوان منسوخ علامتگذاری شده و ممکن است در آینده حذف شود." @@ -1211,6 +1217,8 @@ Unmute="صدادار" Push-to-mute="فشار دادن برای بیصدا" Push-to-talk="فشار دادن برای گفتگو" +MonitorOn="فعالکردن مانیتورینگ" +MonitorOff="غیرفعال کردن مانیتورینگ" SceneItemShow="نمایش \"%1\"" SceneItemHide="مخفی کردن \"%1\"" OutputWarnings.NoTracksSelected="شما حداقل باید یک لایه صوتی را انتخاب کنید" @@ -1377,5 +1385,40 @@ PluginManager.Section.Discover="مرور" PluginManager.Section.Manage="نصب شده" PluginManager.Section.Updates="بهروزرسانیها" -PluginManager.Section.Manage.Title="مدیریت پلاگینهای فعال شده" +PluginManager.Section.Manage.Title="نصبشده" +PluginManager.Section.Manage.Description="افزونههای نصبشدهٔ فعلی خود را مدیریت کنید." +PluginManager.Section.Manage.NoPlugins="هیچ افزونهای یافت نشد." +PluginManager.Section.Errors.Title="خطاها" +PluginManager.Section.Errors.Description="بارگذاری این افزونهها با شکست مواجه شد. اطمینان حاصل کنید که آنها بهروز هستند و با این نسخه از OBS Studio سازگاری دارند." +PluginManager.Section.Missing.Title="گمشده" +PluginManager.Section.Missing.Description="این افزونهها قبلاً نصب شده بودند، اما دیگر پیدا نمیشوند." +PluginManager.Button.Enable="فعالسازی افزونه %1" +PluginManager.Status.Legacy="قدیمی" +PluginManager.Status.Disabled="غیرفعال" +PluginManager.Status.Error="خطا" +PluginManager.Status.Missing="گمشده" +PluginManager.Status.Legacy.Description="این افزونه در مکانی نصب شده است که در آینده از کار خواهد افتاد. <a href=\"%1\">بیشتر بدانید</a>" Accessible.Widget.Name.AlignmentSelector="انتخابگر ترازبندی" +EncoderMissing.Title="رمزگذارهای گمشده" +EncoderMissing.Text="رمزگذارهای پیکربندیشدهی زیر وجود ندارند:\n<ul>\n%1</ul><br>\nبرای اطلاعات بیشتر به <a href=\"%2\">مقالهی پایگاه دانش</a> مراجعه کنید." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (کد: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="ناشناخته" +EncoderMissing.MissingModule="ماژول \"%1\" بارگیری نشد" +EncoderMissing.NVENC.TestProgramFailedStartup="خرابی شروع برنامه بررسی NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="شکست فرآیند بررسی NVENC، کد خروج: %1" +EncoderMissing.NVENC.TestProgramReadFailure="خطای خواندن خروجی فرآیند بررسی NVENC، کد خروج: %1" +EncoderMissing.NVENC.TestProgramError="بررسی NVENC به دلیل زیر ناموفق بود: %1" +EncoderMissing.NVENC.NoDevices="هیچ پردازنده گرافیکی انودیا یافت نشد" +EncoderMissing.NVENC.Unsupported.Kepler="معماری (کپلر) پردازنده گرافیکی شما (%1) دیگر پشتیبانی نمیشود. لطفاً به جای آن از OBS 30.2 یا نسخههای قدیمیتر استفاده کنید." +EncoderMissing.NVENC.Reason.NvmlLoad="بارگیری کتابخانه NVML ناموفق بود" +EncoderMissing.NVENC.Reason.NvmlInit="مقداردهی اولیه NVML ناموفق بود" +EncoderMissing.NVENC.Reason.NvencLoad="بارگیری کتابخانه NVENC ناموفق بود" +EncoderMissing.NVENC.Reason.NvencInit="مقداردهی اولیه NVENC ناموفق بود" +EncoderMissing.NVENC.Reason.NvencVersion="نسخه NVENC خالی است" +EncoderMissing.NVENC.Reason.CudaLoad="بارگیری کتابخانه CUDA ناموفق بود" +EncoderMissing.NVENC.Reason.CudaInit="مقداردهی اولیه CUDA ناموفق بود" +EncoderMissing.NVENC.Reason.CudaVersion="نسخه CUDA نامعتبر/گم شده است" +EncoderMissing.NVENC.Reason.DriverOutdated="درایور قدیمی" +EncoderMissing.NVENC.Reason.NoSupportedDevices="هیچ دستگاه انودیا با پشتیبانی NVENC یافت نشد" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="محدودیت جلسه رمزگذار بیش از حد شد" +EncoderMissing.NVENC.Reason.AV1Unsupported="رمزگذاری AV1 توسط هیچ یک از پردازندههای گرافیکی انودیا سیستم پشتیبانی نمیشود."
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/fi-FI.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/fi-FI.ini
Changed
@@ -492,9 +492,9 @@ Basic.Main.PreviewDisabled="Esikatselu on poistettu käytöstä" Basic.SourceSelect="Lisää lähde" Basic.SourceSelect.SelectType="Lähteen tyyppi" -Basic.SourceSelect.Recent="Äskettäin lisätty" -Basic.SourceSelect.NewSource="Luo uusi lähde" -Basic.SourceSelect.Existing="Lisää olemassa oleva lähde" +Basic.SourceSelect.Recent="Äskettäin luotu" +Basic.SourceSelect.NewSource="Lisää uusi %1" +Basic.SourceSelect.NoSelection="Lisää olemassaoleva" Basic.SourceSelect.CreateButton="Luo uusi" Basic.SourceSelect.AddVisible="Tee lähteestä näkyvä" Basic.SourceSelect.Accessible.SourceName="Lähteen nimi" @@ -1318,4 +1318,13 @@ PluginManager.Section.Discover="Selaa" PluginManager.Section.Manage="Asennettu" PluginManager.Section.Updates="Päivitykset" -PluginManager.Section.Manage.Title="Hallitse käytössä olevia liitännäisiä" +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (koodi: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Tuntematon" +EncoderMissing.MissingModule="Moduulia \"%1\" ei ole ladattu" +EncoderMissing.NVENC.NoDevices="NVIDIA:n näytönohjaimia ei löytynyt" +EncoderMissing.NVENC.Reason.NvencLoad="NVENC-kirjaston lataaminen epäonnistui" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC:n versio on tyhjä" +EncoderMissing.NVENC.Reason.CudaLoad="CUDA-kirjaston lataaminen epäonnistui" +EncoderMissing.NVENC.Reason.CudaVersion="Virheellinen/puuttuva CUDA-versio" +EncoderMissing.NVENC.Reason.DriverOutdated="Vanhentunut ajuri" +EncoderMissing.NVENC.Reason.NoSupportedDevices="NVENC-tuella varustettuja NVIDIA-laitteita ei löytynyt"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/fr-FR.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/fr-FR.ini
Changed
@@ -499,14 +499,16 @@ Basic.Main.PreviewDisabled="L'aperçu est actuellement désactivé" Basic.SourceSelect="Ajouter une Source" Basic.SourceSelect.SelectType="Type de Source" -Basic.SourceSelect.Recent="Ajouté récemment" -Basic.SourceSelect.NewSource="Créer une Nouvelle Source" -Basic.SourceSelect.Existing="Ajouter une Source Existante" +Basic.SourceSelect.Recent="Créé récemment" +Basic.SourceSelect.Description="Sélectionner les sources à ajouter à la scène actuelle." +Basic.SourceSelect.NewSource="Ajouter un nouveau %1" +Basic.SourceSelect.AddExisting="Ajouter %1 existant" +Basic.SourceSelect.NoSelection="Ajouter un élément existant" Basic.SourceSelect.CreateButton="Créer une nouvelle" Basic.SourceSelect.AddVisible="Rendre la source visible" -Basic.SourceSelect.NoExisting="Il n'existe pas %1 sources" +Basic.SourceSelect.NoExisting="Vous n'avez pas encore de sources %1 existantes." Basic.SourceSelect.Accessible.SourceName="Nom de la Source" -Basic.SourceSelect.Accessible.Existing="Ajouter une Source Existante" +Basic.SourceSelect.Accessible.Existing="Ajouter une source existante" Basic.SourceSelect.Deprecated.Create="Ce type de source est indiquée comme obsolète et ne permet pas de créer de nouvelles sources." Basic.Main.Sources.Visibility="Visibilité" Basic.Main.Sources.VisibilityDescription="Contrôle la visibilité de \"%1\" sur le canevas" @@ -1176,6 +1178,8 @@ Mute="Couper l'Audio" Unmute="Restaurer l'Audio" Push-to-talk="Appuyer-pour-parler" +MonitorOn="Activer la surveillance" +MonitorOff="Désactiver la surveillance" SceneItemShow="Afficher '%1'" SceneItemHide="Cacher '%1'" OutputWarnings.NoTracksSelected="Vous devez sélectionner au moins une piste" @@ -1341,5 +1345,27 @@ PluginManager.Section.Discover="Parcourir" PluginManager.Section.Manage="Installé" PluginManager.Section.Updates="Mises à jour" -PluginManager.Section.Manage.Title="Gérer les plugins activés" Accessible.Widget.Name.AlignmentSelector="Sélecteur d’Alignement" +EncoderMissing.Title="Encodeurs manquants" +EncoderMissing.Text="Les encodeurs configurés suivants sont manquants :\n<ul>\n%1</ul><br>\nConsultez l'<a href=\"%2\">article de la base de connaissances</a> pour plus d'informations." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (code : <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Inconnu" +EncoderMissing.MissingModule="Module « %1 » non chargé" +EncoderMissing.NVENC.TestProgramFailedStartup="Échec du démarrage du programme de vérification NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Échec du processus de vérification NVENC, code de sortie : %1" +EncoderMissing.NVENC.TestProgramReadFailure="Échec de lecture de la sortie du processus de vérification NVENC, code de sortie : %1" +EncoderMissing.NVENC.TestProgramError="La vérification NVENC a échoué pour la raison suivante : %1" +EncoderMissing.NVENC.NoDevices="Aucun GPU NVIDIA trouvé" +EncoderMissing.NVENC.Unsupported.Kepler="L'architecture (Kepler) de votre GPU (%1) n'est plus prise en charge. Veuillez utiliser OBS 30.2 ou une version antérieure." +EncoderMissing.NVENC.Reason.NvmlLoad="Échec du chargement de la bibliothèque NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Échec de l'initialisation de NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Échec du chargement de la bibliothèque NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Échec de l'initialisation de NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Version NVENC vide" +EncoderMissing.NVENC.Reason.CudaLoad="Échec du chargement de la bibliothèque CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Échec de l'initialisation de CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Version CUDA invalide ou manquante" +EncoderMissing.NVENC.Reason.DriverOutdated="Pilote obsolète" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Aucun périphérique NVIDIA avec prise en charge de NVENC trouvé" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Limite de session d'encodage dépassée" +EncoderMissing.NVENC.Reason.AV1Unsupported="L'encodage AV1 n'est pris en charge par aucun des GPU NVIDIA du système"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/gl-ES.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/gl-ES.ini
Changed
@@ -500,12 +500,14 @@ Basic.Main.PreviewDisabled="A vista previa está desactivada actualmente" Basic.SourceSelect="Engadir fonte" Basic.SourceSelect.SelectType="Tipo de fonte" -Basic.SourceSelect.Recent="Engadido recentemente" -Basic.SourceSelect.NewSource="Crear unha nova fonte" -Basic.SourceSelect.Existing="Engadir unha fonte existente" +Basic.SourceSelect.Recent="Creado recentemente" +Basic.SourceSelect.Description="Selecciona a(s) fonte(s) que queres engadir á escena actual." +Basic.SourceSelect.NewSource="Engadir un %1 novo" +Basic.SourceSelect.AddExisting="Engadir %1 existente" +Basic.SourceSelect.NoSelection="Engadir existente" Basic.SourceSelect.CreateButton="Crear novo" Basic.SourceSelect.AddVisible="Facer visíbel a fonte" -Basic.SourceSelect.NoExisting="Non existen fontes de %1" +Basic.SourceSelect.NoExisting="Aínda non tes fontes %1 existentes." Basic.SourceSelect.Accessible.SourceName="Nome da fonte" Basic.SourceSelect.Accessible.Existing="Engadir unha fonte existente" Basic.SourceSelect.Deprecated.Create="Este tipo de fonte está marcado como obsoleto e pode que sexa eliminado no futuro." @@ -1132,6 +1134,7 @@ Basic.AdvAudio.Monitoring="Monitorización do son" Basic.AdvAudio.Monitoring.None="Monitor apagado" Basic.AdvAudio.Monitoring.MonitorOnly="Só o monitor (silenciar a saída)" +Basic.AdvAudio.Monitoring.Both="Monitorización activada" Basic.AdvAudio.MonitoringSource="Monitorización de son para «%1»" Basic.AdvAudio.AudioTracks="Pistas" Basic.Settings.Hotkeys="Teclas rápidas" @@ -1181,6 +1184,8 @@ Unmute="Activar son" Push-to-mute="Premer para silenciar" Push-to-talk="Premer para falar" +MonitorOn="Activar a monitorización" +MonitorOff="Desactivar a monitorización" SceneItemShow="Amosar «%1»" SceneItemHide="Agochar «%1»" OutputWarnings.NoTracksSelected="Debe seleccionar, cando menos, unha pista" @@ -1344,5 +1349,26 @@ PluginManager.Section.Discover="Navegar" PluginManager.Section.Manage="Instalado" PluginManager.Section.Updates="Actualizacións" -PluginManager.Section.Manage.Title="Xestionar complementos Activados" Accessible.Widget.Name.AlignmentSelector="Selector de aliñamento" +EncoderMissing.Title="Codificadores ausentes" +EncoderMissing.Text="Faltan os seguintes codificadores configurados:\n<ul>\n%1</ul><br>\nConsulta o <a href=\"%2\">artigo da Base de coñecemento</a> para obter máis información." +EncoderMissing.Unknown="Descoñecido" +EncoderMissing.MissingModule="Módulo «%1» non cargado" +EncoderMissing.NVENC.TestProgramFailedStartup="Non se puido iniciar o programa de comprobación de NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Produciuse un erro no proceso de comprobación de NVENC, código de saída: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Non se puido ler a saída do proceso de comprobación de NVENC, código de saída: %1" +EncoderMissing.NVENC.TestProgramError="A comprobación de NVENC fallou polo seguinte motivo: %1" +EncoderMissing.NVENC.NoDevices="Non se atoparon GPU de NVIDIA" +EncoderMissing.NVENC.Unsupported.Kepler="A arquitectura (Kepler) da túa GPU (%1) xa non é compatible. Usa OBS 30.2 ou unha versión anterior." +EncoderMissing.NVENC.Reason.NvmlLoad="Non se puido cargar a biblioteca NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Non se puido inicializar NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Non se puido cargar a biblioteca NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Non se puido inicializar NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Versión de NVENC baleira" +EncoderMissing.NVENC.Reason.CudaLoad="Non se puido cargar a biblioteca CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Non se puido inicializar CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Versión de CUDA non válida ou ausente" +EncoderMissing.NVENC.Reason.DriverOutdated="Controlador desactualizado" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Non se atoparon dispositivos NVIDIA con compatibilidade con NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Superouse o límite de sesións do codificador" +EncoderMissing.NVENC.Reason.AV1Unsupported="Ningunha das GPU NVIDIA do sistema admite a codificación AV1"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/he-IL.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/he-IL.ini
Changed
@@ -509,12 +509,14 @@ Basic.Main.PreviewDisabled="תצוגה מקדימה אינה זמינה כעת" Basic.SourceSelect="הוספת מקור" Basic.SourceSelect.SelectType="סוג מקור" -Basic.SourceSelect.Recent="נוסף לאחרונה" -Basic.SourceSelect.NewSource="יצירת מקור חדש" -Basic.SourceSelect.Existing="הוספת מקור קיים" +Basic.SourceSelect.Recent="נוצר לאחרונה" +Basic.SourceSelect.Description="נא לבחור אילו מקורות להוסיף לסצנה הנוכחית." +Basic.SourceSelect.NewSource="הוספת %1 חדש" +Basic.SourceSelect.AddExisting="הוספת %1 קיים" +Basic.SourceSelect.NoSelection="הוספת קיים" Basic.SourceSelect.CreateButton="יצירת חדש" Basic.SourceSelect.AddVisible="הפוך מקור לגלוי" -Basic.SourceSelect.NoExisting="אין מקורות %1 קיימים" +Basic.SourceSelect.NoExisting="אין לך מקורות %1 קיימים עדיין." Basic.SourceSelect.Accessible.SourceName="שם מקור" Basic.SourceSelect.Accessible.Existing="הוספת מקור קיים" Basic.SourceSelect.Deprecated.Create="סוג המקור הזה מסומן כמיושן ועלול להיגרע בעתיד." @@ -1162,6 +1164,7 @@ Basic.AdvAudio.Monitoring="ניטור שמע" Basic.AdvAudio.Monitoring.None="ללא ניטור" Basic.AdvAudio.Monitoring.MonitorOnly="ניטור בלבד (השתקת הפלט)" +Basic.AdvAudio.Monitoring.Both="הופעל ניטור" Basic.AdvAudio.MonitoringSource="ניטור שמע עבור \"%1\"" Basic.AdvAudio.AudioTracks="רצועות" Basic.Settings.Hotkeys="מקשי קיצור" @@ -1210,6 +1213,8 @@ Unmute="בטל השתקה" Push-to-mute="לחץ-להשתקה" Push-to-talk="לחץ-כדי-לדבר" +MonitorOn="הפעלת ניטור" +MonitorOff="השבתת ניטור" SceneItemShow="הצגת \"%1\"" SceneItemHide="הסתר '%1'" OutputWarnings.NoTracksSelected="חובה לבחור רצועה אחת לפחות" @@ -1355,7 +1360,10 @@ FailedToStartStream.FailedToCreateAudioEncoder="יצירת מקודד השמע נכשלה" FailedToStartStream.NoRTMPURLInConfig="ההגדרות לא מכילות כתובת יעד תזרים RTMP(S)" FailedToStartStream.FallbackToDefault="התחלת ההזרמה באמצעות %1 נכשלה, לנסות שוב בעזרת הגדרות קידוד יחידניות?" +FailedToStartStream.ConfigRequestFailed="לא ניתן למשוך את ההגדרות מתוך %1\n\nשגיאת HTTP: %2" FailedToStartStream.WarningUnknownStatus="התקבל ערך מצב ‚%1’ לא מוכר" +FailedToStartStream.WarningRetryNonMultitrackVideo="\n\nלהמשיך להזרים בלי %1?" +FailedToStartStream.WarningRetry="\n\nלהמשיך להזרים?" FailedToStartStream.MissingEncoderConfigs="הגדרות העלייה לאוויר לא כללו הגדרות מקודדים" FailedToStartStream.InvalidEncoderConfig="הגדרות עלייה לאוויר כוללות הגדרות מקודד שגויות" FailedToStartStream.StatusMissingHTML="בקשת עלייה לאוויר החזירה שגיאה לא ידועה" @@ -1373,5 +1381,27 @@ PluginManager.Section.Discover="עיון" PluginManager.Section.Manage="מותקן" PluginManager.Section.Updates="עדכונים" -PluginManager.Section.Manage.Title="ניהול תוספים פעילים" Accessible.Widget.Name.AlignmentSelector="בורר יישור" +EncoderMissing.Title="מקודדים חסרים" +EncoderMissing.Text="המקודדים המוגדרים הבאים חסרים:\n<ul>\n%1</ul><br>\nיש <a href=\"%2\">ערך במאגר הידע</a> שמסביר על הנושא." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (קוד: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="לא ידוע" +EncoderMissing.MissingModule="המודול „%1” לא נטען" +EncoderMissing.NVENC.TestProgramFailedStartup="הפעלת תוכנית בדיקת NVENC נכשלה" +EncoderMissing.NVENC.TestProgramExitWithError="תהליך בדיקת NVENC נכשל, קוד היציאה: %1" +EncoderMissing.NVENC.TestProgramReadFailure="קריאת פלא תהליך בדיקת NVENC נכשלה, קוד היציאה: %1" +EncoderMissing.NVENC.TestProgramError="בדיקת NVENC נכשלה מהסיבה: %1" +EncoderMissing.NVENC.NoDevices="לא נמצאו מעבדים גרפיים מבית NVIDIA" +EncoderMissing.NVENC.Unsupported.Kepler="ארכיטקטורת (Kepler) המעבד הגרפי (%1) שלך לא נתמכת עוד. נא להשתמש ב־OBS 30.2 או בגרסאות שלפניה במקום." +EncoderMissing.NVENC.Reason.NvmlLoad="טעינת ספריית NVML נכשלה" +EncoderMissing.NVENC.Reason.NvmlInit="אתחול NVML נכשל" +EncoderMissing.NVENC.Reason.NvencLoad="טעינת ספריית NVENC נכשלה" +EncoderMissing.NVENC.Reason.NvencInit="אתחול NVENC נכשל" +EncoderMissing.NVENC.Reason.NvencVersion="גרסת NVENC ריקה" +EncoderMissing.NVENC.Reason.CudaLoad="טעינת ספריית CUDA נכשלה" +EncoderMissing.NVENC.Reason.CudaInit="אתחול CUDA נכשל" +EncoderMissing.NVENC.Reason.CudaVersion="גרסת CUDA שגויה/חסרה" +EncoderMissing.NVENC.Reason.DriverOutdated="מנהל התקן מיושן" +EncoderMissing.NVENC.Reason.NoSupportedDevices="לא נמצאו התקני NVIDIA עם תמיכה ב־NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="חריגה ממגבלת הפעלת מקודד" +EncoderMissing.NVENC.Reason.AV1Unsupported="אין תמיכה בקידוד AV1 באף אחד מהמעבדים הגרפיים מבית NVIDIA של המערכת"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/hi-IN.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/hi-IN.ini
Changed
@@ -505,11 +505,13 @@ Basic.SourceSelect="स्रोत जोड़ें" Basic.SourceSelect.SelectType="स्रोत प्रकार" Basic.SourceSelect.Recent="हाल ही में जोड़ा गया" -Basic.SourceSelect.NewSource="एक नया स्रोत बनाएं" -Basic.SourceSelect.Existing="एक उपलब्ध स्रोत जोड़ें" +Basic.SourceSelect.Description="अपने वर्तमान दृश्य में जोड़ने के लिए स्रोत चुनें." +Basic.SourceSelect.NewSource="एक नए %1 को जोड़ें" +Basic.SourceSelect.AddExisting=" उपलब्ध %1 को जोड़ें" +Basic.SourceSelect.NoSelection=" उपलब्ध को जोड़ें" Basic.SourceSelect.CreateButton="नया बनाएँ" Basic.SourceSelect.AddVisible="स्रोत दृश्यमान बनाएं" -Basic.SourceSelect.NoExisting="कोई उपलब्ध %1 स्रोत नहीं" +Basic.SourceSelect.NoExisting="आपके पास अभी तक कोई %1 स्रोत नहीं हैं." Basic.SourceSelect.Accessible.SourceName="स्रोत का नाम" Basic.SourceSelect.Accessible.Existing="एक उपलब्ध स्रोत जोड़ें" Basic.SourceSelect.Deprecated.Create="इस स्रोत प्रकार को अप्रचलित के रूप में चिह्नित किया गया है और इसे भविष्य में हटाया जा सकता है." @@ -1154,6 +1156,7 @@ Basic.AdvAudio.Monitoring="ऑडियो निगरानी" Basic.AdvAudio.Monitoring.None="मॉनिटर बंद" Basic.AdvAudio.Monitoring.MonitorOnly="केवल मॉनिटर (आउटपुट चुप करें)" +Basic.AdvAudio.Monitoring.Both="निगरानी सक्षम" Basic.AdvAudio.MonitoringSource="'%1' के लिए ऑडियो मॉनिटरिंग" Basic.AdvAudio.AudioTracks="ट्रैक" Basic.Settings.Hotkeys="सक्रिय कुंजी" @@ -1346,7 +1349,10 @@ FailedToStartStream.FailedToCreateAudioEncoder="ऑडियो एन्कोडर बनाने में विफल" FailedToStartStream.NoRTMPURLInConfig="कॉन्फ़िगरेशन में स्ट्रीम लक्ष्य RTMP(S) URL शामिल नहीं है" FailedToStartStream.FallbackToDefault="%1 का उपयोग करके स्ट्रीम प्रारंभ करना विफल रहा; क्या आप एकल एन्कोड सेटिंग्स का उपयोग करके पुनः प्रयास करना चाहते हैं?" +FailedToStartStream.ConfigRequestFailed="%1 से कॉन्फ़िगरेशन नहीं लाया जा सका\n\nHTTP त्रुटि: %2" FailedToStartStream.WarningUnknownStatus="अज्ञात स्थिति मान '%1' प्राप्त हुआ" +FailedToStartStream.WarningRetryNonMultitrackVideo="\n\nक्या आप %1 के बिना स्ट्रीमिंग जारी रखना चाहते हैं?" +FailedToStartStream.WarningRetry="\n\nक्या आप स्ट्रीमिंग जारी रखना चाहते हैं?" FailedToStartStream.MissingEncoderConfigs="गो लाइव कॉन्फिग में एनकोडर कॉन्फिगरेशन शामिल नहीं था" FailedToStartStream.InvalidEncoderConfig="गो लाइव कॉन्फ़िग में एक अमान्य एन्कोडर कॉन्फ़िगरेशन शामिल था" FailedToStartStream.StatusMissingHTML="गो लाइव अनुरोध ने एक अनिर्दिष्ट त्रुटि लौटा दी" @@ -1364,5 +1370,4 @@ PluginManager.Section.Discover="ब्राउज़" PluginManager.Section.Manage="इंस्टॉल हुआ" PluginManager.Section.Updates="अपडेट" -PluginManager.Section.Manage.Title="सक्षम प्लगइन्स प्रबंधित करें" Accessible.Widget.Name.AlignmentSelector="संरेखण चयनकर्ता"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/hr-HR.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/hr-HR.ini
Changed
@@ -502,14 +502,9 @@ Basic.Main.PreviewDisabled="Pregled je trenutačno onemogućen" Basic.SourceSelect="Dodaj izvor" Basic.SourceSelect.SelectType="Vrsta izvora" -Basic.SourceSelect.Recent="Nedavno dodano" -Basic.SourceSelect.NewSource="Stvori novi izvor" -Basic.SourceSelect.Existing="Dodaj postojeći izvor" Basic.SourceSelect.CreateButton="Stvori novi" Basic.SourceSelect.AddVisible="Prikaži izvor" -Basic.SourceSelect.NoExisting="Nema postojećih %1 izvora" Basic.SourceSelect.Accessible.SourceName="Ime izvora" -Basic.SourceSelect.Accessible.Existing="Dodaj jedan postojeći izvor" Basic.SourceSelect.Deprecated.Create="Ova je vrsta izvora označena kao zastarjela i može biti da će se u budućnosti ukloniti." Basic.Main.Sources.Visibility="Vidljivost" Basic.Main.Sources.VisibilityDescription="Kontrolira vidljivost '%1' na platnu" @@ -1354,5 +1349,4 @@ PluginManager.Section.Discover="Pregledaj" PluginManager.Section.Manage="Instalirano" PluginManager.Section.Updates="Ažuriranja" -PluginManager.Section.Manage.Title="Upravljanje omogućenim dodacima" Accessible.Widget.Name.AlignmentSelector="Biranje poravnanja"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/hu-HU.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/hu-HU.ini
Changed
@@ -123,6 +123,10 @@ CrashHandling.Buttons.LaunchNormal="Futtatás normál módban" CrashHandling.Errors.UploadJSONError="Hiba történt a legutóbbi összeomlás-jelentés feltöltési kísérlete során. Próbálja újra később." CrashHandling.Errors.Title="Összeomlásjelentés-feltöltési hiba" +PluginFailure.Dialog.Title="Bővítményhibák" +PluginFailure.Labels.Text="Az OBS Studio nem tudta betölteni az összes harmadik féltől származó bővítményt.\n\nTöbb részlet érhető el a bővítménykezelőben." +PluginFailure.Dialog.Continue="Elvetés" +PluginFailure.Dialog.Open="Bővítménykezelő megnyitása" SafeMode.Restart="Újraindítja csökkentett módban az OBS-t (letiltja a harmadik féltől származó bővítményeket, parancsfájlokat és WebSocketeket)?" SafeMode.RestartNormal="Újraindítja normál módban az OBS-t?" ChromeOS.Title="Nem támogatott platform" @@ -501,12 +505,14 @@ Basic.Main.PreviewDisabled="Előnézet pillanatnyilag kikapcsolva" Basic.SourceSelect="Forrás hozzáadása" Basic.SourceSelect.SelectType="Forrás típusa" -Basic.SourceSelect.Recent="Nemrég hozzáadva" -Basic.SourceSelect.NewSource="Új forrás létrehozása" -Basic.SourceSelect.Existing="Meglévő forrás hozzáadása" +Basic.SourceSelect.Recent="Nemrég létrehozva" +Basic.SourceSelect.Description="Válassza ki a jelenlegi jelenethez adandó forrásokat." +Basic.SourceSelect.NewSource="Új %1 hozzáadása" +Basic.SourceSelect.AddExisting="%1 meglévő hozzáadása" +Basic.SourceSelect.NoSelection="Meglévő hozzáadása" Basic.SourceSelect.CreateButton="Új létrehozása" Basic.SourceSelect.AddVisible="Forrás láthatóvá tétele" -Basic.SourceSelect.NoExisting="Nem érhető el %1 forrás" +Basic.SourceSelect.NoExisting="Még nincs meglévő %1 forrása." Basic.SourceSelect.Accessible.SourceName="Forrás neve" Basic.SourceSelect.Accessible.Existing="Meglévő forrás hozzáadása" Basic.SourceSelect.Deprecated.Create="Ez a forrástípus elavultnak van jelölve, és eltávolításra kerülhet a jövőben." @@ -1188,6 +1194,8 @@ Unmute="Némítás megszüntetése" Push-to-mute="Gombnyomással történő némítás" Push-to-talk="Gombnyomással történő beszéd" +MonitorOn="Megfigyelés bekapcsolása" +MonitorOff="Megfigyelés kikapcsolása" SceneItemShow="„%1” megjelenítése" SceneItemHide="„%1” elrejtése" OutputWarnings.NoTracksSelected="Legalább egy sávot ki kell választania" @@ -1354,5 +1362,40 @@ PluginManager.Section.Discover="Tallózás" PluginManager.Section.Manage="Telepítve" PluginManager.Section.Updates="Frissítések" -PluginManager.Section.Manage.Title="Engedélyezett bővítmények kezelése" +PluginManager.Section.Manage.Title="Telepítve" +PluginManager.Section.Manage.Description="Jelenleg telepített bővítmények kezelése." +PluginManager.Section.Manage.NoPlugins="Nem található bővítmény." +PluginManager.Section.Errors.Title="Hibák" +PluginManager.Section.Errors.Description="Nem sikerült a bővítmények betöltése. Győződjön meg róla, hogy frissek és kompatibilisek az OBS Studio jelenlegi verziójával." +PluginManager.Section.Missing.Title="Hiányzó" +PluginManager.Section.Missing.Description="Ezek a bővítmények korábban telepítve voltak, de már nem találhatók." +PluginManager.Button.Enable="%1 bővítmény engedélyezése" +PluginManager.Status.Legacy="Örökölt" +PluginManager.Status.Disabled="Letiltva" +PluginManager.Status.Error="Hiba" +PluginManager.Status.Missing="Hiányzó" +PluginManager.Status.Legacy.Description="Ez a bővítmény olyan helyre van telepítve, ahonnan nem fog működni a jövőben. <a href=\"%1\">További tudnivalók</a>" Accessible.Widget.Name.AlignmentSelector="Igazításválasztó" +EncoderMissing.Title="Hiányzó kódolók" +EncoderMissing.Text="A következő beállított kódolók hiányoznak:\n<ul>\n%1</ul><br>\nTovábbi információkért lásd a <a href=\"%2\">tudásbázis-leírást</a>." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (kód: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Ismeretlen" +EncoderMissing.MissingModule="A(z) „%1” modul nincs betöltve" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC ellenőrzési program indítási hibája" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC ellenőrzési folyamat hibája, kilépési kód: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC ellenőrzési folyamat kimenetolvasási hibája, kilépési kód: %1" +EncoderMissing.NVENC.TestProgramError="NVENC ellenőrzés sikertelen, ok: %1" +EncoderMissing.NVENC.NoDevices="Nem található NVIDIA GPU" +EncoderMissing.NVENC.Unsupported.Kepler="A GPU (%1) architektúrája (Kepler) már nem támogatott. Használja az OBS 30.2-es vagy korábbi verzióját." +EncoderMissing.NVENC.Reason.NvmlLoad="Nem sikerült az NVML programkönyvtár betöltése" +EncoderMissing.NVENC.Reason.NvmlInit="Nem sikerült az NVML előkészítése" +EncoderMissing.NVENC.Reason.NvencLoad="Nem sikerült az NVENC programkönyvtár betöltése" +EncoderMissing.NVENC.Reason.NvencInit="Nem sikerült az NVENC előkészítése" +EncoderMissing.NVENC.Reason.NvencVersion="Az NVENC verziója üres" +EncoderMissing.NVENC.Reason.CudaLoad="Nem sikerült a CUDA programkönyvtár betöltése" +EncoderMissing.NVENC.Reason.CudaInit="Nem sikerült a CUDA előkészítése" +EncoderMissing.NVENC.Reason.CudaVersion="Érvénytelen/hiányzó CUDA verzió" +EncoderMissing.NVENC.Reason.DriverOutdated="Elavult illesztőprogram" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Nem található NVENC támogatású NVIDIA eszköz" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="A kódoló munkamenetkorlátja túllépve" +EncoderMissing.NVENC.Reason.AV1Unsupported="Az AV1 kódolást a rendszer egyetlen NVIDIA GPU-ja sem támogatja"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/id-ID.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/id-ID.ini
Changed
@@ -123,6 +123,10 @@ CrashHandling.Buttons.LaunchNormal="Jalankan dalam Mode Biasa" CrashHandling.Errors.UploadJSONError="Sebuah galat terjadi saat mencoba mengunggah laporan galat terkini. Mohon coba lagi nanti." CrashHandling.Errors.Title="Galat Unggah Laporan Galat" +PluginFailure.Dialog.Title="Galat Plugin" +PluginFailure.Labels.Text="OBS Studio tadi tidak dapat memuat semua plugin pihak-ketiga.\n\nDetail lebih lanjut ada di dalam pengelola plugin." +PluginFailure.Dialog.Continue="Bubarkan" +PluginFailure.Dialog.Open="Buka Pengelola Plugin" SafeMode.Restart="Apakah Anda ingin mengaktifkan ulang OBS dalam Mode Aman (plugin pihak ketiga, skrip, dan WebSockets dinonaktifkan)?" SafeMode.RestartNormal="Apakah Anda ingin mengaktifkan ulang OBS dalam Mode Biasa?" ChromeOS.Title="Platform Tidak Didukung" @@ -489,14 +493,16 @@ Basic.Main.PreviewDisabled="Pratinjau saat ini dinonaktifkan" Basic.SourceSelect="Tambahkan Sumber" Basic.SourceSelect.SelectType="Jenis Sumber" -Basic.SourceSelect.Recent="Terakhir Ditambahkan" -Basic.SourceSelect.NewSource="Buat sebuah Sumber Baru" -Basic.SourceSelect.Existing="Tambahkan sebuah Sumber yang Tersedia" +Basic.SourceSelect.Recent="Akhir-Akhir Ini Dibuat" +Basic.SourceSelect.Description="Pilih sebuah / beberapa sumber untuk ditambahkan ke adegan Anda saat ini." +Basic.SourceSelect.NewSource="Tambahkan sebuah %1 baru" +Basic.SourceSelect.AddExisting="Tambahkan %1 dengan yang ada" +Basic.SourceSelect.NoSelection="Tambahkan dengan yang ada" Basic.SourceSelect.CreateButton="Buat Baru" Basic.SourceSelect.AddVisible="Buat sumber terlihat" -Basic.SourceSelect.NoExisting="Tidak ada sumber %1 yang tersedia" +Basic.SourceSelect.NoExisting="Anda saat ini tidak mempunyai sumber %1 yang ada." Basic.SourceSelect.Accessible.SourceName="Nama Sumber" -Basic.SourceSelect.Accessible.Existing="Tambahkan sebuah Sumber yang Tersedia" +Basic.SourceSelect.Accessible.Existing="Tambahkan sebuah sumber yang ada" Basic.SourceSelect.Deprecated.Create="Jenis sumber ini telah ditandai sebagai usang dan mungkin kedepannya akan dihapus." Basic.Main.Sources.Visibility="Visibilitas" Basic.Main.Sources.VisibilityDescription="Kontrol visibilitas '%1' di kanvas" @@ -1153,6 +1159,8 @@ Hotkeys.MouseButton="Tetikus %1" Mute="Senyapkan suara" Unmute="Hidupkan suara" +MonitorOn="Pemantauan Aktif" +MonitorOff="Pemantauan Nonaktif" SceneItemShow="Tampilkan '%1'" SceneItemHide="Sembunyikan '%1'" OutputWarnings.NoTracksSelected="Anda harus memilih setidaknya satu trek" @@ -1316,5 +1324,40 @@ PluginManager.Section.Discover="Telusuri" PluginManager.Section.Manage="Terpasang" PluginManager.Section.Updates="Pembaruan" -PluginManager.Section.Manage.Title="Kelola Plugin yang Aktif" +PluginManager.Section.Manage.Title="Terpasang" +PluginManager.Section.Manage.Description="Kelola plugin Anda yang terpasang saat ini." +PluginManager.Section.Manage.NoPlugins="Tidak ada plugin yang ditemukan." +PluginManager.Section.Errors.Title="Galat" +PluginManager.Section.Errors.Description="Plugin berikut ini gagal untuk memuat. Pastikan plugin tersebut adalah yang terbaru dan kompatibel dengan versi OBS Studio ini." +PluginManager.Section.Missing.Title="Hilang" +PluginManager.Section.Missing.Description="Plugin berikut ini sebelumnya telah terpasang namun tidak dapat lagi ditemukan." +PluginManager.Button.Enable="Aktifkan plugin %1" +PluginManager.Status.Legacy="Lawas" +PluginManager.Status.Disabled="Nonaktif" +PluginManager.Status.Error="Galat" +PluginManager.Status.Missing="Hilang" +PluginManager.Status.Legacy.Description="Plugin ini terpasang ke lokasi yang kedepannya akan berhenti bekerja. <a href=\"%1\">Pelajarai Lebih Lanjut</a>" Accessible.Widget.Name.AlignmentSelector="Pemilih Penjajaran" +EncoderMissing.Title="Pengkodean Hilang" +EncoderMissing.Text="Pengkodean terkonfigurasi berikut ini tidak ditemukan:\n<ul>\n%1</ul><br>\nLihat <a href=\"%2\">Artikel Basis Pengetahuan</a> untuk informasi lebih lanjut." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (kode: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Tidak diketahui" +EncoderMissing.MissingModule="Modul \"%1\" tidak dimuat" +EncoderMissing.NVENC.TestProgramFailedStartup="Pengecekan memulai program NVENC gagal" +EncoderMissing.NVENC.TestProgramExitWithError="Pengecekan proses NVENC gagal, kode keluar: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Pengecekan proses membaca output NVENC gagal, kode keluar: %1" +EncoderMissing.NVENC.TestProgramError="Pengecekan NVENC gagal dengan alasan: %1" +EncoderMissing.NVENC.NoDevices="Tidak ada GPU NVIDIA ditemukan" +EncoderMissing.NVENC.Unsupported.Kepler="Arsitektur (Kepler) pada GPU Anda (%1) tidak lagi didukung. Sebagai gantinya, mohon gunakan OBS 30.2 atau versi sebelumnya." +EncoderMissing.NVENC.Reason.NvmlLoad="Gagal memuat pustaka NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Gagal menginisialisasi NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Gagal memuat pustaka NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Gagal menginisialisasi NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Versi NVENC kosong" +EncoderMissing.NVENC.Reason.CudaLoad="Gagal memuat pustaka CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Gagal menginisialisasi CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Versi CUDA Tidak sah/Hilang" +EncoderMissing.NVENC.Reason.DriverOutdated="Driver usang" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Tidak ada perangkat NVIDIA dengan dukungan NVENC ditemukan" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Batas sesi pengkodean terlampaui" +EncoderMissing.NVENC.Reason.AV1Unsupported="Pengkodean AV1 tidak didukung oleh sistem GPU NVIDIA apapun"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/it-IT.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/it-IT.ini
Changed
@@ -501,12 +501,14 @@ Basic.Main.PreviewDisabled="L'anteprima è attualmente disattivata" Basic.SourceSelect="Aggiungi sorgente" Basic.SourceSelect.SelectType="Tipo di sorgente" -Basic.SourceSelect.Recent="Aggiunti di recente" -Basic.SourceSelect.NewSource="Crea una nuova sorgente" -Basic.SourceSelect.Existing="Aggiungi una sorgente esistente" +Basic.SourceSelect.Recent="Creato recentemente" +Basic.SourceSelect.Description="Seleziona quali sorgenti aggiungere alla scena attuale" +Basic.SourceSelect.NewSource="Aggiungi un nuovo %1" +Basic.SourceSelect.AddExisting="Aggiungi %1 esistente" +Basic.SourceSelect.NoSelection="Aggiungi esistente" Basic.SourceSelect.CreateButton="Crea nuova" Basic.SourceSelect.AddVisible="Rendi visibile la fonte" -Basic.SourceSelect.NoExisting="Nessuna sorgente %1 esistente" +Basic.SourceSelect.NoExisting="Non hai ancora sorgenti %1 esistenti." Basic.SourceSelect.Accessible.SourceName="Nome sorgente" Basic.SourceSelect.Accessible.Existing="Aggiungi una sorgente esistente" Basic.SourceSelect.Deprecated.Create="Questo tipo di sorgente è contrassegnata come deprecata e consente la creazione di nuove sorgenti." @@ -1178,6 +1180,8 @@ Mute="Silenzia" Unmute="Riattiva" Push-to-talk="Premi-per-parlare" +MonitorOn="Abilita monitoraggio" +MonitorOff="Disabilita monitoraggio" SceneItemShow="Mostra «%1»" SceneItemHide="Nascondi «%1»" OutputWarnings.NoTracksSelected="Devi selezionare almeno una traccia" @@ -1330,6 +1334,7 @@ FailedToStartStream.InvalidEncoderConfig="GO Live Config ha incluso una configurazione dell'encoder non valida" FailedToStartStream.StatusMissingHTML="La richiesta di \"Vai in diretta\" ha restituito un errore non specificato" FailedToStartStream.NoConfigSupplied="Configurazione mancante" +MultitrackVideo.Info="%1 Ottimizza automaticamente le tue impostazioni per le dirette, che potrebbe includere la codifica di qualità video e/o orientamenti della tela multipli. Selezionando questa opzione invierà %2 informazioni sul tuo computer e impostazioni del software." MultitrackVideo.IncompatibleSettings.Title="Impostazioni incompatibili" MultitrackVideo.IncompatibleSettings.AudioChannels="%1 non è attualmente compatibile con Audio → Generale → Canali impostato su '%2', %3" MultitrackVideo.IncompatibleSettings.AudioChannelsSingle="Audio → Generale → Canali deve essere impostato su '%1'" @@ -1342,5 +1347,27 @@ PluginManager.Section.Discover="Sfoglia" PluginManager.Section.Manage="Installato" PluginManager.Section.Updates="Aggiornamenti" -PluginManager.Section.Manage.Title="Gestisci plugin abilitati" Accessible.Widget.Name.AlignmentSelector="Selettore allineamento" +EncoderMissing.Title="Encoder mancanti" +EncoderMissing.Text="Mancano i seguenti encoder configurati:\n<ul>\n%1</ul><br>\nPer ulteriori informazioni consulta l'<a href=\"%2\">articolo della Knowledge Base</a>." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (codice: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Sconosciuto" +EncoderMissing.MissingModule="Modulo \"%1\" non caricato" +EncoderMissing.NVENC.TestProgramFailedStartup="Errore in avvio del programma di controllo NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Errore del processo di controllo NVENC, codice di uscita: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Errore di lettura dell'output del processo di controllo NVENC, codice di uscita: %1" +EncoderMissing.NVENC.TestProgramError="Controllo NVENC non riuscito - motivo: %1" +EncoderMissing.NVENC.NoDevices="Nessuna GPU NVIDIA trovata" +EncoderMissing.NVENC.Unsupported.Kepler="L'architettura (Kepler) della GPU (%1) non è più supportata. Usa invece OBS 30.2 o versioni precedenti." +EncoderMissing.NVENC.Reason.NvmlLoad="Impossibile caricare la libreria NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Impossibile inizializzare NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Impossibile caricare la libreria NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Impossibile inizializzare NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Versione NVENC vuota" +EncoderMissing.NVENC.Reason.CudaLoad="Impossibile caricare la libreria CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Impossibile inizializzare CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Versione CUDA non valida/mancante" +EncoderMissing.NVENC.Reason.DriverOutdated="Driver obsoleto" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Nessun dispositivo NVIDIA con supporto NVENC trovato" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Limite della sessione encoder superato" +EncoderMissing.NVENC.Reason.AV1Unsupported="La codifica AV1 non è supportata da nessuna delle GPU NVIDIA del sistema"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ja-JP.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ja-JP.ini
Changed
@@ -126,6 +126,10 @@ CrashHandling.Buttons.LaunchNormal="通常モードで実行" CrashHandling.Errors.UploadJSONError="最新のクラッシュログのアップロード中にエラーが発生しました。 後でもう一度お試しください。" CrashHandling.Errors.Title="クラッシュログアップロードエラー" +PluginFailure.Dialog.Title="プラグインエラー" +PluginFailure.Labels.Text="OBS Studioはすべてのサードパーティ製プラグインを読み込めませんでした。\n\n詳細はプラグインマネージャーで確認できます。" +PluginFailure.Dialog.Continue="閉じる" +PluginFailure.Dialog.Open="プラグインマネージャーを開く" SafeMode.Restart="OBSをセーフモード (サードパーティプラグイン、スクリプト、WebSocketは無効) で再起動しますか?" SafeMode.RestartNormal="OBSを通常モードで再起動しますか?" ChromeOS.Title="サポートされていないプラットフォーム" @@ -507,12 +511,14 @@ Basic.Main.PreviewDisabled="プレビューは現在無効です" Basic.SourceSelect="ソースを追加" Basic.SourceSelect.SelectType="ソースの種類" -Basic.SourceSelect.Recent="最近追加したもの" -Basic.SourceSelect.NewSource="新しいソースを作成" -Basic.SourceSelect.Existing="既存のソースを追加" +Basic.SourceSelect.Recent="最近作成したもの" +Basic.SourceSelect.Description="現在のシーンに追加するソースを選択してください。" +Basic.SourceSelect.NewSource="新しい %1 を追加" +Basic.SourceSelect.AddExisting="既存を %1 個追加" +Basic.SourceSelect.NoSelection="既存を追加" Basic.SourceSelect.CreateButton="新規作成" Basic.SourceSelect.AddVisible="ソースを表示した状態で作成" -Basic.SourceSelect.NoExisting="既存の %1 ソースはありません" +Basic.SourceSelect.NoExisting="既存の %1 ソースはありません。" Basic.SourceSelect.Accessible.SourceName="ソース名" Basic.SourceSelect.Accessible.Existing="既存のソースを追加" Basic.SourceSelect.Deprecated.Create="このソースの種類は非推奨としてマークされており将来的に削除される可能性があります。" @@ -1197,6 +1203,8 @@ Unmute="ミュート解除" Push-to-mute="プッシュツーミュート" Push-to-talk="プッシュツートーク" +MonitorOn="モニタリングを有効化" +MonitorOff="モニタリングを無効化" SceneItemShow="'%1' を表示" SceneItemHide="'%1' を非表示" OutputWarnings.NoTracksSelected="少なくとも1つのトラックを選択する必要があります" @@ -1362,5 +1370,40 @@ PluginManager.Section.Discover="参照" PluginManager.Section.Manage="インストール済み" PluginManager.Section.Updates="更新" -PluginManager.Section.Manage.Title="有効プラグインの管理" +PluginManager.Section.Manage.Title="インストール済み" +PluginManager.Section.Manage.Description="現在インストールされているプラグインを管理します。" +PluginManager.Section.Manage.NoPlugins="プラグインが見つかりません。" +PluginManager.Section.Errors.Title="エラー" +PluginManager.Section.Errors.Description="これらのプラグインの読み込みに失敗しました。 プラグインが最新の状態でこのバージョンのOBS Studioと互換性があることを確認してください。" +PluginManager.Section.Missing.Title="見つからない" +PluginManager.Section.Missing.Description="これらのプラグインは以前インストールされていましたが、現在は見つかりません。" +PluginManager.Button.Enable="%1 プラグインを有効にする" +PluginManager.Status.Legacy="旧方式" +PluginManager.Status.Disabled="無効" +PluginManager.Status.Error="エラー" +PluginManager.Status.Missing="見つからない" +PluginManager.Status.Legacy.Description="このプラグインは将来的に動作しなくなる場所にインストールされています。 <a href=\"%1\">詳細はこちら</a>" Accessible.Widget.Name.AlignmentSelector="配置セレクター" +EncoderMissing.Title="エンコーダが見つかりません" +EncoderMissing.Text="以下の設定済みエンコーダが見つかりません:\n<ul>\n%1</ul><br>\n詳しくは<a href=\"%2\">ナレッジベースの記事</a>をご覧ください。" +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (コード: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="不明" +EncoderMissing.MissingModule="モジュール \"%1\" が読み込まれていません" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC チェックプログラムの起動に失敗しました" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC チェック処理が失敗、終了コード: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC チェックプロセスの出力読み取りに失敗、終了コード: %1" +EncoderMissing.NVENC.TestProgramError="NVENC チェックに失敗 理由: %1" +EncoderMissing.NVENC.NoDevices="NVIDIA GPU が見つかりません" +EncoderMissing.NVENC.Unsupported.Kepler="お使いの GPU (%1) のアーキテクチャ (Kepler) はサポートされなくなりました。 代わりに OBS 30.2 以前のバージョンを使用してください。" +EncoderMissing.NVENC.Reason.NvmlLoad="NVML ライブラリの読み込みに失敗しました" +EncoderMissing.NVENC.Reason.NvmlInit="NVML の初期化に失敗しました" +EncoderMissing.NVENC.Reason.NvencLoad="NVENC ライブラリの読み込みに失敗しました" +EncoderMissing.NVENC.Reason.NvencInit="NVENC の初期化に失敗しました" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC バージョンが空です" +EncoderMissing.NVENC.Reason.CudaLoad="CUDA ライブラリの読み込みに失敗しました" +EncoderMissing.NVENC.Reason.CudaInit="CUDA の初期化に失敗しました" +EncoderMissing.NVENC.Reason.CudaVersion="CUDA のバージョンが無効または見つかりません" +EncoderMissing.NVENC.Reason.DriverOutdated="古いドライバー" +EncoderMissing.NVENC.Reason.NoSupportedDevices="NVENC をサポートする NVIDIA デバイスが見つかりません" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="エンコーダセッションの制限を超えました" +EncoderMissing.NVENC.Reason.AV1Unsupported="このシステムの NVIDIA GPU はいずれも AV1 エンコードをサポートしていません。"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ka-GE.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ka-GE.ini
Changed
@@ -444,10 +444,10 @@ MacPermissions.Item.Camera.Details="ამ ნებართვას საჭიროებს ვებკამერიდან ან ჩამწერი დაფიდან ვიდეოს გადასაღებად." MacPermissions.Item.Microphone="მიკროფონი" MacPermissions.Item.Microphone.Details="OBS საჭიროებს ამ ნებართვას მიკროფონიდან ან სხვა გარე მოწყობილობიდან ხმის ჩასაწერად." -MacPermissions.Item.InputMonitoring="შეტანის მეთვალყურეობა" +MacPermissions.Item.InputMonitoring="შეტანის მოსმენა" MacPermissions.Item.InputMonitoring.Details="ეს ნებართვა საჭიროა, რომ ღილაკებმა იმუშაოს, როცა OBS ფონურადაა გაშვებული." MacPermissions.Item.Accessibility="ხელმისაწვდომობა" -MacPermissions.Item.Accessibility.Details="ძველად დაყენებისას, OBS შეიძლება აღნუსხული იყოს „ხელმისაწვდომობის“ არეში „შეტანის მეთვალყურეობის“ ნაცვლად." +MacPermissions.Item.Accessibility.Details="ძველად დაყენებულებში, OBS შეიძლება აღნუსხული იყოს „ხელმისაწვდომობის“ არეში „შეტანის მოსმენის“ ნაცვლად." MacPermissions.Continue="განაგრძეთ" SourceLeak.Title="წყაროს გასუფთავების შეცდომა" SourceLeak.Text="ხარვეზი წარმოიშვა სცენის კრებულის ცვლილებისას და ზოგიერთი წყაროს მოცილება ვერ მოხერხდა. ჩვეულებრივ, ამის მიზეზია ხოლმე დანამატები, რომლებიც ვერ ახერხებს მასალების სათანადოდ გამოთავისუფლებას. გთხოვთ დარწმუნდეთ, რომ ყველა დანამატი განახლებულია.\n\nOBS Studio ახლა დაიხურება მონაცემთა დაზიანების ასარიდებლად." @@ -504,12 +504,14 @@ Basic.Main.PreviewDisabled="შეთვალიერება მიუწვდომელია" Basic.SourceSelect="წყაროს დამატება" Basic.SourceSelect.SelectType="წყაროს სახეობა" -Basic.SourceSelect.Recent="ბოლოს დამატებული" -Basic.SourceSelect.NewSource="ახალი წყაროს შექმნა" -Basic.SourceSelect.Existing="არსებული წყაროს დამატება" +Basic.SourceSelect.Recent="ბოლოს შექმნილი" +Basic.SourceSelect.Description="აირჩიეთ, რომელი წყარო(ები) დაემატოს მიმდინარე სცენას." +Basic.SourceSelect.NewSource="დაემატოს ახალი %1" +Basic.SourceSelect.AddExisting="დაემატოს %1 არსებული" +Basic.SourceSelect.NoSelection="დაემატოს არსებული" Basic.SourceSelect.CreateButton="ახლის შექმნა" Basic.SourceSelect.AddVisible="წყაროს გამოჩენა" -Basic.SourceSelect.NoExisting="არსებული %1 წყარო არ მოიძებნა" +Basic.SourceSelect.NoExisting="არსებული %1 წყარო არ მოიძებნა." Basic.SourceSelect.Accessible.SourceName="წყაროს სახელი" Basic.SourceSelect.Accessible.Existing="არსებული წყაროს დამატება" Basic.SourceSelect.Deprecated.Create="ამ წყაროს სახეობა მიჩნეულია მოძველებულად და ახლო მომავალში მოცილდება." @@ -1140,8 +1142,8 @@ Basic.AudioMixer.Category.Unassigned="მიუნიჭებელი" Basic.AudioMixer.Layout.Horizontal="თარაზული განლაგება" Basic.AudioMixer.Layout.Vertical="შვეული განლაგება" -Basic.AudioMixer.Monitoring.Enable="მეთვალყურეობის ჩართვა" -Basic.AudioMixer.Monitoring.Disable="მეთვალყურეობის გათიშვა" +Basic.AudioMixer.Monitoring.Enable="მოსმენის ჩართვა" +Basic.AudioMixer.Monitoring.Disable="მოსმენის გამორთვა" Basic.AdvAudio="ხმის გაფართოებული პარამეტრები" Basic.AdvAudio.ActiveOnly="მხოლოდ მოქმედი წყაროები" Basic.AdvAudio.Name="სახელი" @@ -1156,7 +1158,8 @@ Basic.AdvAudio.Monitoring="ხმის მოსმენა" Basic.AdvAudio.Monitoring.None="მოსმენის გარეშე" Basic.AdvAudio.Monitoring.MonitorOnly="მხოლოდ მოსმენა (უხმო გამოტანა)" -Basic.AdvAudio.MonitoringSource="ხმის მოსასმენი „%1“" +Basic.AdvAudio.Monitoring.Both="მოსმენა ჩართულია" +Basic.AdvAudio.MonitoringSource="ხმის მოსმენა, „%1“" Basic.AdvAudio.AudioTracks="ჩანაწერები" Basic.Settings.Hotkeys="ღილაკები" Basic.Settings.Hotkeys.Pair="გადამრთველის სახით იმუშავებს ღილაკთან „%1“" @@ -1191,6 +1194,8 @@ Unmute="ხმის ჩართვა" Push-to-mute="დაჭერისას დადუმება" Push-to-talk="დაჭერისას საუბარი" +MonitorOn="მოსმენის ჩართვა" +MonitorOff="მოსმენის გამორთვა" SceneItemShow="გამოჩნდეს „%1“" SceneItemHide="დაიმალოს „%1“" OutputWarnings.NoTracksSelected="უნდა მიუთითოთ ერთი ხმოვანი ჩანაწერი მაინც" @@ -1357,5 +1362,27 @@ PluginManager.Section.Discover="მოძიება" PluginManager.Section.Manage="ჩადგმული" PluginManager.Section.Updates="განახლებები" -PluginManager.Section.Manage.Title="მოქმედი დანამატების მართვა" Accessible.Widget.Name.AlignmentSelector="განლაგების მიმთითებელი" +EncoderMissing.Title="მშიფრავები აკლია" +EncoderMissing.Text="მოცემული მომართული მშიფრავები ამოკლებულია:\n<ul>\n%1</ul><br>\nიხილეთ <a href=\"%2\">ცოდნის წყაროდან სტატია</a> დაწვრილებითი ინფორმაციისთვის." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (კოდი: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="უცნობი" +EncoderMissing.MissingModule="მოდული „%1“ არ ჩაიტვირთა" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC-ს შემმოწმებელი ვერ გაეშვა" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC-ს შემოწმების პროცესი ვერ გაეშვა, შეწყვეტის მიზეზი: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC-ს შემოწმების დასკვნის წაკითხვა ვერ მოხერხდა, შეწყვეტის მიზეზი: %1" +EncoderMissing.NVENC.TestProgramError="NVENC-ს შემოწმება ვერ მოხერხდა, მიზეზი: %1" +EncoderMissing.NVENC.NoDevices="არცერთი NVIDIA GPU არ მოიძებნა" +EncoderMissing.NVENC.Unsupported.Kepler="მოცემული აგებულებით (Kepler) თქვენი GPU (%1) აღარაა მხარდაჭერილი. გთხოვთ გამოიყენოთ OBS 30.2 ან უფრო ადრინდელი." +EncoderMissing.NVENC.Reason.NvmlLoad="ვერ ჩაიტვირთა NVML-ბიბლიოთეკა" +EncoderMissing.NVENC.Reason.NvmlInit="ვერ გაეშვა NVML" +EncoderMissing.NVENC.Reason.NvencLoad="ვერ ჩაიტვირთა NVENC-ბიბლიოთეკა" +EncoderMissing.NVENC.Reason.NvencInit="ვერ გაეშვა NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC-ვერსია ცარიელია" +EncoderMissing.NVENC.Reason.CudaLoad="ვერ ჩაიტვირთა CUDA-ბიბლიოთეკა" +EncoderMissing.NVENC.Reason.CudaInit="ვერ გაეშვა CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="უმართებულო/ამოკლებული CUDA-ვერსია" +EncoderMissing.NVENC.Reason.DriverOutdated="ვადაგასული დრაივერი" +EncoderMissing.NVENC.Reason.NoSupportedDevices="ვერცერთი NVIDIA-მოწყობილობა ვერ მოიძებნა NVENC-მხარდაჭერით" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="მშიფრავით სარგებლობის ზღვარი მიღწეულია" +EncoderMissing.NVENC.Reason.AV1Unsupported="AV1-მშიფრავის მხარდაჭერით არაა სისტემის არცერთი NVIDIA GPU"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/kaa.ini
Changed
@@ -3,91 +3,97 @@ Cancel="Бийкарлаў" Close="Жабыў" Save="Сақлаў" -Discard="Biykaw etiw" +Discard="Өшириў" Disable="Өшириў" Yes="Аўа" No="Яқ" Add="Қосыў" Remove="Өшириў" -Rename="Qayta ataw" -Interact="Óz-ara háreket etiw" -Filters="Фильтр" -Properties="Qásiyetler" -MoveUp="Joqarıǵa kóshiriw" -MoveDown="Tómenge kóshiriw" +Rename="Қайта атаў" +Filters="Фильтрлер" +Properties="Қәсиетлер" +MoveUp="Жоқарыға" +MoveDown="Төменге" Settings="Сазлаўлар" Display="Экран" Name="Атамасы" Exit="Шығыў" -Mixer="Audio aralastırģısh" -Browse="Tańlaw" +Mixer="Сес миксери" +Browse="Таңлаў" Mono="Моно" Stereo="Стерео" -DroppedFrames="Túsirip qaldırılģan kadrlar %1 (%2%)" -Projector.Display="Displey: %1" +DroppedFrames="Түсип қалған кадрлар %1 (%2%)" +Projector.Open.Program="Программа проектирин ашыў" +Projector.Open.Preview="Көринис проектирин ашыў" +Projector.Open.Scene="Сахна проектирин ашыў" +Projector.Open.Source="Дерек проектирин ашыў" +Projector.Open.Multiview="Мульти көринисти ашыў" +Projector.Display="Экран: %1" +Projector.Window="Жаңа айна" +Projector.Title="Проектор" +Projector.Title.Scene="Сахна: %1" +Projector.Title.Source="Дерек: %1" +Projector.Title.Multiview="Мульти көринис" Clear="Тазалаў" -Revert="Qaytarıw" +Revert="Қайтарыў" Show="Көрсетиў" Hide="Жасырыў" -UnhideAll="Barlıǵın kórsetiw" +UnhideAll="Бәрин көрсетиў" Untitled="Атамасыз" New="Жаратыў" Duplicate="Нусқалаў" -Enable="Qosıw" -DisableOSXVSync="MacOS vertical sáykeslestiriwin óshiriw" -ResetOSXVSyncOnExit="Shıǵıwda macOS V-Sync tazalaw" -HighResourceUsage="Kodlaw hádden tısqarı júklengen! Video sazlamaların páseytiń yáki tez kodlawshı sazlamadan paydalanıń." -Transition="Ótiw" -QuickTransitions="Tez ótiwler" -FadeToBlack="Qara reńge sóniw" -Left="Shepten" -Right="Ońnan" -Top="Joqarıdan" -Bottom="Tómennen" -Reset="Qayta ornatıw" -Hours="Saat" -Minutes="Minut" -Seconds="Sekund" -Deprecated="Eskirgen" -ReplayBuffer="Qayta qoyıw bufferi" +Enable="Қосыў" +DisableOSXVSync="macOS V-Sync өшириў" +ResetOSXVSyncOnExit="Шыққанда macOS V-Sync қайта орнатыў" +Transition="Өтиў" +QuickTransitions="Тез өтиўлер" +Left="Шептен" +Right="Оңнан" +Top="Жоқарыдан" +Bottom="Төменнен" +Width="Ени" +Height="Узынлығы" +Hours="Саат" +Minutes="Минут" +Seconds="Секунд" +Deprecated="Ескирген" +ReplayBuffer="Қайталаў буфери" Import="Импорт" Export="Экспорт" Copy="Көширип алыў" -Paste="Jaylastırıw" -PasteReference="Jaylastırıw (Silteme)" -PasteDuplicate="Jaylastırıw (Kóbeytiw)" -RemuxRecordings="Jazıwlardı Remux qılıw" +Paste="Қойыў" +PasteReference="Қойыў (силтеме)" +PasteDuplicate="Қойыў (нусқа)" Next="Кейинги" Back="Артқа" Defaults="Әдепки" RestoreDefaults="Әдепки" -HideMixer="Aralastırģıshta jasırıw" -TransitionOverride="Ótiwdi ózgertiw" -ShowTransition="Ótiwdi kórsetiw" -HideTransition="Ótiw effektin kórsetpew" +HideMixer="Миксерде көрсетпеў" +TransitionOverride="Басқа өтиўди көрсетиў" None="Жоқ" -StudioMode.Preview="Aldınnan kóriw" +StudioMode.Preview="Көринис" StudioMode.Program="Бағдарлама" -StudioMode.PreviewSceneName="Aldınnan kóriw:%1" -StudioMode.ProgramSceneName="Baǵdarlama: %1" -ShowInMultiview="Multi-kóriniste kórsetiw" -VerticalLayout="Tik ornalastırıw (vertikal)" +StudioMode.PreviewSceneName="Көринис: %1" +StudioMode.ProgramSceneName="Бағдарлама: %1" +ShowInMultiview="Мульти көринисте көрсетиў" +VerticalLayout="Вертикал жайласыў" Group="Топар" DoNotShowAgain="Басқа көрсетпеў" Default="(Әдепки)" -Calculating="Esaplamaqta..." -Fullscreen="Толық экран режимы" -Windowed="Айна режимы" +Calculating="Есапланбақта..." +Fullscreen="Толық экран режими" +Windowed="Айна режими" RefreshBrowser="Жаңалаў" -AspectRatio="Tárepler sáykesligi <b>%1:%2</b>" -LockVolume="Dawıstı quliplaw" -LogViewer="Jurnaldı qaraw quralı" -ShowOnStartup="Iske túsirgende kórsetiw" +AspectRatio="Тәреплер пропорциясы <b>%1:%2</b>" +LockVolume="Сес бәлентлигин блоклаў" +LogViewer="Журналды көриў" +ShowOnStartup="Иске түсиргенде көрсетиў" OpenFile="Файлды ашыў" +AddScene="Сахна қосыў" AddSource="Дерек қосыў" -RemoveScene="Tańlanǵan saxnanı óshiriw" -RemoveSource="Tańlanǵan dereklerdi óshiriw" -MoveSceneUp="Saxnanı joqarıǵa kóshiriw" +RemoveScene="Таңланған сахнаны өшириў" +RemoveSource="Таңланған дереклерди өшириў" +MoveSceneUp="Сахнаны жоқарыға көтериў" MoveSceneDown="Saxnanı tómenge kóshiriw" MoveSourceUp="Derek(ler)di joqarıǵa kóshiriw" MoveSourceDown="Derek(ler)di tómenge kóshiriw" @@ -96,10 +102,21 @@ MixerToolbarMenu="Audio mikser bólimi" SceneFilters="Saxna filtrlerin ashıw" List="Дизим" +Grid="Кесте" +Automatic="Автоматикалық" +ComingSoon="Жақын арада" PluginsFailedToLoad.Title="Плагинди жүклеўдеги қәтелик" PluginsFailedToLoad.Text="Usı plaginlerdi júklep bolmadı:\n\n%1\n Iltmas, plaginlerdi jańalań yáki óshiriń." AlreadyRunning.Title="OBS әллеқашан иске түсирилген" AlreadyRunning.LaunchAnyway="Hárqanday jaǵdayda da iske qosıw" +CrashHandling.Dialog.Title="OBS Studio қәтелиги анықланды" +CrashHandling.Labels.Text="OBS Studio дурыс жабылмады.\n\nҚәўипсиз режимде иске түсирилсин бе? (үшинши тәреп плагинлери, скриптлер ҳәм веб-сокетлер өширилген ҳалда)" +CrashHandling.Checkbox.SendReport="Мен қупыялық шәртлерин оқыдым ҳәм жибериўге разыман." +CrashHandling.Buttons.LaunchSafe="Қәўипсиз режимде иске түсириў" +CrashHandling.Buttons.LaunchNormal="Нормал режимде иске түсириў" +CrashHandling.Errors.UploadJSONError="Соңғы қәтелик журналын жибериўде қәтелик жүз берди. Өтиниш, кейинирек қайтадан урынып көриң." +CrashHandling.Errors.Title="Журналды жибериўде қәтелик" +SafeMode.Restart="OBS-ты қәўипсиз режимде қайта иске түсириўди қәлейсиз бе (үшинши тәреп плагинлери, скриптлер ҳәм веб-сокетлер өширилген ҳалда)?" SafeMode.RestartNormal="OBStı ádettegi rejimde iske túsiriwdi qáleysiz be?" ChromeOS.Title="Qollap-quwatlanbaytuǵın platforma" ChromeOS.Text="OBS baǵdarlaması ChromeOS ishinde iske qosılǵan. Bul platforma qollap-quwatlanbaydı." @@ -118,11 +135,12 @@ Auth.LoadingChannel.Title="Kanal haqqında maǵlıwmat júklenbekte..." Auth.LoadingChannel.Text="%1 ushın kanal haqqında maǵlıwmat júklenbekte, ótinish, kútiń..." Auth.LoadingChannel.Error="Kanal haqqında maǵlıwmattı júklew ámelge aspadı." -Auth.ChannelFailure.Title="Kanaldı júklew ámelge aspadı" +Auth.ChannelFailure.Title="Каналды жүклеў қәтелиги" Auth.ChannelFailure.Text="%1\n\n%2: %3 ushın kanal haqqında maǵlıwmattı júklew ámelge aspadı" Auth.Chat="Чат" Auth.StreamInfo="Трансляция мағлыўматы" TwitchAuth.Stats="Twitch статистикасы" +TwitchAuth.Feed="Twitch белсендилик лентасы" TwitchAuth.TwoFactorFail.Title="Esittiriw giltin soraw ámelge aspadı" TwitchAuth.TwoFactorFail.Text="Twitch akkauntıńızǵa qosılıw múmkin emes. <a href='https://www.twitch.tv/settings/security'>Twitch qáwipsizlik sazlawları</a>nda Eki faktorlı autentifikaciya qosılǵanına isenim kámil etiń; tikkeley efir júrgiziw ushın bul talap etiledi." RestreamAuth.Channels="Restream каналлары" @@ -160,15 +178,16 @@ Basic.AutoConfig.StreamPage.UseStreamKey="Esittiriw giltin qollanıw" Basic.AutoConfig.StreamPage.UseStreamKeyAdvanced="Esittiriw giltin qollanıw (sheber qollanıwshılar ushın)" Basic.AutoConfig.StreamPage.Service="Хызмет" -Basic.AutoConfig.StreamPage.Service.ShowAll="Barlıǵın kórsetiw..." +Basic.AutoConfig.StreamPage.Service.ShowAll="Бәрин көрсетиў..." Basic.AutoConfig.StreamPage.Service.Custom="Арнаўлы..." Basic.AutoConfig.StreamPage.Server="Сервер" -Basic.AutoConfig.StreamPage.StreamKey="Esittiriw gilti" -Basic.AutoConfig.StreamPage.EncoderKey="Kodlawshı gilti" -Basic.AutoConfig.StreamPage.BearerToken="Paydalanıwshı tokeni" +Basic.AutoConfig.StreamPage.StreamKey="Трансляция гилти" +Basic.AutoConfig.StreamPage.EncoderKey="Кодлаўшы гилти" +Basic.AutoConfig.StreamPage.BearerToken="Ийелик токени" Basic.AutoConfig.StreamPage.ConnectedAccount="Жалғанған аккаунт" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Apparatlıq kodlawshını abzal kóriw" Basic.AutoConfig.StreamPage.StreamWarning.Title="Трансляция ескертиўи" +Basic.AutoConfig.StreamPage.UseMultitrackVideo="Тест %1" Basic.AutoConfig.TestPage="Соңғы нәтийжелер" Basic.AutoConfig.TestPage.SubTitle.Testing="Baǵdarlama házirgi waqıtta bir qatar ideal sazlawlardı tekserip atır" Basic.AutoConfig.TestPage.SubTitle.Complete="Тестлеў жуўмақланды" @@ -198,18 +217,18 @@ Basic.Stats.Status.Recording="Jazılmaqta" Basic.Stats.Status.Live="ЭФИР" Basic.Stats.Status.Reconnecting="Қайта жалғанбақта" -Basic.Stats.Status.Inactive="Aktiv emes" +Basic.Stats.Status.Inactive="Актив емес" Basic.Stats.Status.Active="Актив" -Basic.Stats.DroppedFrames="Ótkerip jiberilgen kadrlar (tarmaq)" -Basic.Stats.MegabytesSent="Jámi jiberildi" -Basic.Stats.Bitrate="Bit tezligi" +Basic.Stats.MegabytesSent="Жәми жиберилди" +Basic.Stats.Bitrate="Битрейт" Basic.Stats.DiskFullIn="Disk tolǵanǵa deyin waqıt (shama menen)" +Basic.Stats.DiskFullIn.Text="%1 саат, %2 мин." Basic.Stats.ResetStats="Statistikanı qayta ornatıw" ResetUIWarning.Title="Paydalanıwshı interfeysın qayta ornatıwǵa isenimińiz kámil me?" Updater.Title="Jańa jańalanıw bar" Updater.Text="Jańa jańalanıw bar:" -Updater.UpdateNow="Házir jańalaw" -Updater.RemindMeLater="Keyinirek esletiw" +Updater.UpdateNow="Ҳәзир жаңалаў" +Updater.RemindMeLater="Кейинирек еслетиў" Updater.Skip="Versiyanı ótkizip jiberiw" Updater.NoUpdatesAvailable.Title="Jańalanıw joq" Updater.NoUpdatesAvailable.Text="Jańalanıwlar tabılmadı" @@ -251,10 +270,10 @@ TitleBar.SafeMode="QÁWIPSIZ REJIM" TitleBar.PortableMode="Qolaylı rejim" TitleBar.Profile="Профиль" -TitleBar.Scenes="Saxnalar" -NameExists.Title="Atama álleqashan bar" -NameExists.Text="Bul atama álleqashan paydalanılmaqta." -NoNameEntered.Title="Ótinish, jaramlı atama kirgiziń" +TitleBar.Scenes="Сахналар" +NameExists.Title="Атама әллеқашан бар" +NameExists.Text="Бул атама әллеқашан қолланылмақта" +NoNameEntered.Title="Өтиниш, жарамлы атама киргизиң" NoNameEntered.Text="Siz bos atamalardı qollana alamaysız." ConfirmStart.Title="Esittiriw baslansın ba?" ConfirmStart.Text="Esittiriwdi baslawǵa isenimińiz kámil me?" @@ -296,18 +315,24 @@ Output.NoBroadcast.Text="Tuwrıdan-tuwrı efirdi baslaw ushın, siz aldın ala esettiriwdi sazlawıńız kerek." Output.BroadcastStartFailed="Esittiriwdi baslaw ámelge aspadı" Output.BroadcastStopFailed="Esittiriwdi toqtatıw ámelge aspadı" +LogUploadDialog.Title="OBS Studio журнал файлын жибериў" +LogUploadDialog.Buttons.ConfirmUpload="Жибериў" +LogUploadDialog.Buttons.CopyURL="Журнал силтемесин көширип алыў" +LogUploadDialog.Buttons.RetryButton="Қайталаў" +LogUploadDialog.Errors.Template="Файлды жибериўдеги қәтелик:\n%1" +LogUploadDialog.Errors.NoLogFile="Жибериў ушын файллар табылмады ямаса файл бос болған." Remux.SourceFile="OBS jazba faylı" Remux.ClearFinished="Juwmaqlanǵanlardı dizimnen óshiriw" Remux.ClearAll="Dizimdi tazalaw" Remux.OBSRecording="OBS jazba faylı" Remux.SelectRecording="OBS jazba faylın tańlań..." Remux.SelectTarget="Fayldı tańlań..." -MissingFiles="Joq fayllar" -MissingFiles.MissingFile="Joq fayl" -MissingFiles.NewFile="Jańa fayl" -MissingFiles.HelpText="OBStı sońǵı ret qollanǵanıńızdan baslap birqansha fayllar joq." -MissingFiles.Clear="<tazalanǵan>" -MissingFiles.NumFound="%1 den tabıldı %2" +Remux.FileExistsTitle="Файллар бар" +Remux.FileExists="Усы файллар әллеқашан бар. Оларды қайта жазасыз ба?" +MissingFiles="Жоқ файллар" +MissingFiles.MissingFile="Жоқ файл" +MissingFiles.NewFile="Жаңа файл" +MissingFiles.NumFound="%2 / %1 табылды" MissingFiles.Search="Katalogtı izlew..." MissingFiles.SelectFile="Fayldı tańlań..." MissingFiles.SelectDir="Izlew ushın papkanı tańlań" @@ -323,15 +348,15 @@ MacPermissions.MenuAction="Qosımshanıń ruqsatların kóriw..." MacPermissions.Title="Qosımshanıń ruqsatların kóriw" MacPermissions.Description.OpenDialog="Bul menyudı OBS menyuinen qayta ashıw múmkin." -MacPermissions.AccessGranted="Ruqsat berildi" -MacPermissions.RequestAccess="Ruqsat soraw" +MacPermissions.AccessGranted="Руқсат берилди" +MacPermissions.RequestAccess="Руқсат сораў" MacPermissions.OpenPreferences="%1 sazlawların ashıw" MacPermissions.Item.ScreenRecording="Ekrannan jazıp alıw" MacPermissions.Item.ScreenRecording.Details="Siziń ekranıńızdı qamtıp alıw ushın OBS bul ruqsattı talap etedi." -MacPermissions.Item.Camera="Kamera" -MacPermissions.Item.Microphone="Mikrofon" -MacPermissions.Item.Accessibility="Arnawlı imkaniyatlar" -MacPermissions.Continue="Dawam etiw" +MacPermissions.Item.Camera="Камера" +MacPermissions.Item.Microphone="Микрофон" +MacPermissions.Item.Accessibility="Арнаўлы имканиятлар" +MacPermissions.Continue="Даўам етиў" SourceLeak.Title="Derekti tazalaw qátesi" SourceLeak.Text="Saxnalar toplamın ózgertiwde qátelik kelip shıqtı hám birqansha dereklerdi júklew ámelge aspadı. Bul mashqala ádette xordı durıs bosatpaytuǵın plaginlerden kelip shıǵadı. Ótinish, barlıq qollanıp atırǵan plaginler jańalanǵanın tekseriń.\n\nMaǵlıwmatlardıń buzılıwın aldın alıw ushın OBS jumısın toqtatadı." Basic.DesktopDevice1="Jumıs stolı dawısı" @@ -354,7 +379,7 @@ BlendingMode.Normal="Ádettegidey" BlendingMode.Additive="Qosıw" BlendingMode.Subtract="Alıp tastaw" -BlendingMode.Screen="Ekran" +BlendingMode.Screen="Экран" BlendingMode.Multiply="Kóbeytiw" BlendingMode.Lighten="Jaqtılandırıw" BlendingMode.Darken="Qarańǵılatıw" @@ -368,16 +393,26 @@ Basic.Main.AddSceneCollection.Title="Saxnalar toplamın qosıw" Basic.Main.AddSceneCollection.Text="Ótinish, saxnalar toplamınıń atamasın kirgizıń" Basic.Main.RenameSceneCollection.Title="Saxna toplamın qayta ataw" -AddProfile.Title="Profil qosıw" +AddProfile.Title="Профиль қосыў" AddProfile.Text="Ótinish, profil atamasın kirgizıń" AddProfile.WizardCheckbox="Avtomat tárizde sazlaw ustasın kórsetiw" RenameProfile.Title="Profildi qayta ataw" Basic.Main.MixerRename.Title="Audio derekti qayta ataw" Basic.Main.MixerRename.Text="Ótinish, audio derektiń atamasın kirgizıń" Basic.Main.PreviewDisabled="Aldınnan kóriw házirgi waqıtta óshirilgen" -Basic.SourceSelect.AddVisible="Derekti kórinetuǵın etiw" -Basic.Main.Sources.Visibility="Kórinis" +Basic.SourceSelect="Дерек қосыў" +Basic.SourceSelect.SelectType="Дерек түри" +Basic.SourceSelect.Recent="Соңғы жаратылған" +Basic.SourceSelect.NewSource="Жаңа %1 қосыў" +Basic.SourceSelect.CreateButton="Жаңасын жаратыў" +Basic.SourceSelect.AddVisible="Деректи көринетуғын қылыў" +Basic.SourceSelect.NoExisting="Сизде ҳәзирше бар дерек жоқ %1." +Basic.SourceSelect.Accessible.SourceName="Дерек атамасы" +Basic.SourceSelect.Accessible.Existing="Бар деректи қосыў" +Basic.SourceSelect.Deprecated.Create="Бул дерек түри ескирген деп билгиленген ҳәм келешекте өширилиўи мүмкин." +Basic.Main.Sources.Visibility="Көринис" Basic.Main.Sources.Lock="Bloklaw" +Basic.PropertiesWindow.AutoSelectFormat="%1 (авто-таңлаў: %2)" Basic.PropertiesWindow.SelectColor="Reńdi tańlaw" Basic.PropertiesWindow.SelectFont="Shrifttı tańlaw" Basic.PropertiesWindow.SelectFont.WindowTitle="Shriftti tańlaw" @@ -385,29 +420,22 @@ Basic.PropertiesWindow.Confirm="Saqlanbaǵan ózgerisler bar. Olardı saqlawdı qáleysiz be?" Basic.PropertiesWindow.AddFiles="Fayllardı qosıw" Basic.PropertiesWindow.AddDir="Papka qosıw" -Basic.PropertiesWindow.AddURL="Jol/URL qosıw" -Basic.PropertiesView.UrlButton.Text.Url="URL mánzil: %1" -Basic.PropertiesView.UrlButton.OpenUrl="URL mánzildi ashıw" -Basic.StatusBar.Reconnecting="Baylanıs úzildi, qayta jalǵanıw %2 sekunttan (urınıw sanı: %1)" -Basic.StatusBar.AttemptingReconnect="Qayta jalǵanıw urınısı... (urınıw sanı: %1)" -Basic.StatusBar.ReconnectSuccessful="Qayta jalǵanıw tabıslı" -Basic.StatusBar.Delay="Irkilis (%1 s)" -Basic.StatusBar.DelayStartingIn="Irkilis (baslanıwı %1 sekunttan keyin)" -Basic.StatusBar.DelayStoppingIn="Irkilis (toqtatılıwı %1 sekunttan keyin)" -Basic.StatusBar.DelayStartingStoppingIn="Irkilis (toqtatılıwı %1 sekunttan keyin, baslanıwı %2 sekunttan keyin)" -Basic.StatusBar.RecordingSavedTo="Jazba '%1' jolına saqlandı" -Basic.Filters="Filtrler" -Basic.Filters.AsyncFilters="Audio/Video filtrleri" -Basic.Filters.AudioFilters="Audio filtrler" -Basic.Filters.EffectFilters="Effekt filtrleri" -Basic.Filters.Title="'%1' ushın filtrler" -Basic.Filters.AddFilter.Title="Filtr ataması" -Basic.Filters.AddFilter.Text="Ótinish, filtr atamasın kirgizıń" -Basic.TransformWindow.Position="Orın" -Basic.TransformWindow.Rotation="Aylanıw" -Basic.TransformWindow.Size="Kólemi" -Basic.TransformWindow.Width="Eni" -Basic.TransformWindow.Height="Uzınlıǵı" +Basic.PropertiesWindow.AddURL="Жол/силтеме қосыў" +Basic.PropertiesView.UrlButton.Text.Url="Силтеме: %1" +Basic.PropertiesView.UrlButton.OpenUrl="Силтемени ашыў" +Basic.StatusBar.AttemptingReconnect="Қайта жалғаныў урынысы... (%1-урыныс)" +Basic.StatusBar.Delay="Иркилис (%1 s)" +Basic.Filters="Фильтрлер" +Basic.Filters.AsyncFilters="Аудио/видео фильтрлери" +Basic.Filters.AudioFilters="Аудио фильтрлери" +Basic.Filters.EffectFilters="Эффект фильтрлери" +Basic.Filters.Title="'%1' ушын фильтрлер" +Basic.Filters.AddFilter.Title="Фильтр атамасы" +Basic.Filters.AddFilter.Text="Өтиниш, фильтр атамасын көрсетиң" +Basic.TransformWindow.Size="Көлеми" +Basic.TransformWindow.Width="Ени" +Basic.TransformWindow.Height="Узынлығы" +Basic.TransformWindow.Alignment="Тегислеў" Basic.TransformWindow.BoundsWidth="Sheklew qutısı biyikligi" Basic.TransformWindow.BoundsHeight="Sheklewshiniń biyikligi" Basic.TransformWindow.Crop="Kesiw" @@ -415,6 +443,8 @@ Basic.TransformWindow.CropRight="Oń tárepti qıyıw" Basic.TransformWindow.CropTop="Joqarı tárepti qıyıw" Basic.TransformWindow.CropBottom="Tómengi tárepti qıyıw" +Basic.TransformWindow.Accessible.PositionX="Z позициясы" +Basic.TransformWindow.Accessible.PositionY="Y позициясы" Basic.TransformWindow.Alignment.TopLeft="Joqarı shep tárep" Basic.TransformWindow.Alignment.TopCenter="Joqarı oray" Basic.TransformWindow.Alignment.TopRight="Joqarı oń tárep" @@ -424,73 +454,54 @@ Basic.TransformWindow.Alignment.BottomLeft="Tómengi shep tárep" Basic.TransformWindow.Alignment.BottomCenter="Tómengi oray" Basic.TransformWindow.Alignment.BottomRight="Tómengi oń tárep" +Basic.TransformWindow.BoundsType.None="Автоматикалық" Basic.TransformWindow.BoundsType.MaxOnly="Maksimal kólem" -Basic.TransformWindow.NoSelectedSource="Derek tańlanbaǵan" -Basic.Main.AddSourceHelp.Title="Derek qosıw múmkin emes" -Basic.Main.AddSourceHelp.Text="Derek qosıw ushın keminde bir saxna jaratıwıńız kerek." -Basic.Main.Scenes="Saxnalar" -Basic.Main.Sources="Derekler" -Basic.Main.Source="Derek" -Basic.Main.Controls="Basqarıw" -Basic.Main.Connecting="Jalǵanbaqta..." -Basic.Main.StartRecording="Jazıp alıwdı baslaw" -Basic.Main.SaveReplay="Qayta qoyıwdı saqlaw" -Basic.Main.StartStreaming="Esittiriwdi baslaw" -Basic.Main.StartBroadcast="Efirge shıǵıw" -Basic.Main.StartVirtualCam="Virtual kameranı iske túsiriw" -Basic.Main.StopRecording="Jazıp alıwdı toqtatıw" -Basic.Main.PauseRecording="Jazıp alıwdı toqtatıp turıw" -Basic.Main.UnpauseRecording="Jazıp alıwdı dawam etiw" -Basic.Main.SplitFile="Jazba faylın bóliw" -Basic.Main.StoppingRecording="Jazıw toqtatılmaqta..." -Basic.Main.SetupBroadcast="Esittiriwdi basqarıw" -Basic.Main.StopStreaming="Esittiriwdi toqtatıw" -Basic.Main.StopBroadcast="Esittiriwdi tamamlaw" -Basic.Main.AutoStopEnabled="(Avtomat tárizde toqtatıw)" -Basic.Main.StoppingStreaming="Esittiriw toqtatımaqta..." -Basic.Main.ShowContextBar="Derektiń ásbaplar panelin kórsetiw" -Basic.Main.HideContextBar="Derektiń ásbaplar panelin jasırıw" -Basic.Main.StopVirtualCam="Virtual kameranı toqtatıw" -Basic.Main.Group="Topar %1" -Basic.Main.GridMode="Keste rejimi" -Basic.Main.ListMode="Dizim rejimi" -Basic.Main.VirtualCamConfig="Virtual kameranı sazlaw" -Basic.VCam.VirtualCamera="Virtual kamera" -Basic.VCam.OutputType="Shıǵıw túri" -Basic.VCam.OutputType.Program="Baǵdarlama (ádepki)" -Basic.VCam.OutputSelection.NoSelection="Bul shıǵıw túri ushın tańlaw joq" -Basic.VCam.RestartWarning="Bul ózgerislerdi qollanıw ushın virtual kamera qayta iske túsiriledi" -Basic.MainMenu.File="Fayl (&F)" -Basic.MainMenu.File.Export="Eksportlaw (&E)" -Basic.MainMenu.File.Import="Importlaw (&I)" -Basic.MainMenu.File.ShowRecordings="Jazbalardı kórsetiw (&R)" -Basic.MainMenu.File.Settings="Sazlawlar (&S)" -Basic.MainMenu.File.ShowSettingsFolder="Sazlawlar papkasın ashıw" -Basic.MainMenu.File.ShowProfileFolder="Profil papkasın ashıw" +Basic.TransformWindow.BoundsType.Stretch="Созыў" +Basic.TransformWindow.NoSelectedSource="Дерек таңланбаған" +Basic.Main.AddSourceHelp.Title="Дерек қосыў мүмкин емес" +Basic.Main.Scenes="Сахналар" +Basic.Main.Sources="Дереклер" +Basic.Main.Source="Дерек" +Basic.Main.Controls="Басқарыў" +Basic.Main.PreparingStream="Таярланбақта..." +Basic.Main.Connecting="Жалғанбақта..." +Basic.Main.StartRecording="Жазыўды баслаў" +Basic.Main.StartBroadcast="Эфирге шығыў" +Basic.Main.StartVirtualCam="Виртуал камераны иске түсириў" +Basic.Main.StopRecording="Жазыўды тоқатыў" +Basic.Main.UnpauseRecording="Жазыўды даўам етиў" +Basic.Main.AutoStopEnabled="(Авто-тоқтатыў)" +Basic.Main.StoppingStreaming="Трансляция тоқтатылмақта..." +Basic.Main.ShowContextBar="Дереклер панелин көрсетиў" +Basic.Main.HideContextBar="Дереклер панелин жасырыў" +Basic.Main.StopVirtualCam="Виртуал камераны тоқтатыў" +Basic.Main.Group="Топар %1" +Basic.Main.NewGroup="Жаңа топар" +Basic.Main.GridMode="Кесте режими" +Basic.Main.ListMode="Дизим режими" +Basic.Main.VirtualCamConfig="Виртуал камераны сазлаў" +Basic.VCam.VirtualCamera="Виртуал камера" +Basic.VCam.OutputType.Program="Бағдарлама (әдепки)" +Basic.MainMenu.File="Файл (&F)" +Basic.MainMenu.File.Export="Экспорт (&E)" +Basic.MainMenu.File.Import="Импорт (&I)" +Basic.MainMenu.File.Settings="Сазлаўлар (&S)" Basic.MainMenu.File.ShowMissingFiles="Joǵalǵan fayllardı tekseriw" -Basic.MainMenu.File.Exit="Shıǵıw (&X)" -Basic.MainMenu.Edit="Ózgeris kirgiziw (&E)" +Basic.MainMenu.File.Exit="Шығыў (&X)" +Basic.MainMenu.Edit="Өзгертиў (&E)" Basic.MainMenu.Edit.Undo="Biykarlaw (&U)" Basic.MainMenu.Edit.Redo="Qaytalaw (&R)" -Basic.MainMenu.Edit.LockPreview="Aldınnan kóriwdi bloklaw (&L)" -Basic.MainMenu.Edit.Scale="Aldınnan kóriw kólemi (&S)" -Basic.MainMenu.Edit.Scale.Window="Ayna kólemi" -Basic.MainMenu.Edit.Scale.Output="Shıǵıw (%1x%2)" -Basic.MainMenu.Edit.Transform.Rotate180="180 gradusqa aylandırıw" -Basic.MainMenu.Edit.Order="Tártip (&O)" -Basic.MainMenu.Edit.Order.MoveUp="Joqarıǵa kóshiriw (&U)" -Basic.MainMenu.Edit.Order.MoveDown="Tómenge kóshiriw (&D)" -Basic.MainMenu.Edit.Order.MoveToTop="Eń joqarıǵa kóshiriw (&T)" -Basic.MainMenu.Edit.Order.MoveToBottom="Eń tomenge kóshiriw (&B)" -Basic.MainMenu.Edit.AdvAudio="Dawıstıń keńeytilgen qásiyetleri (&A)" -Basic.MainMenu.View="Kórinis (&V)" -Basic.MainMenu.View.Toolbars="Ásbaplar paneli (&T)" -Basic.MainMenu.View.ContextBar="Derektiń ásbaplar paneli" -Basic.MainMenu.View.StatusBar="Jaǵday qatarı (&S)" -Basic.MainMenu.View.Fullscreen.Interface="Tolıq ekran" -Basic.MainMenu.View.AlwaysOnTop="&Hámiyshe basqa aynalar ústinde" +Basic.MainMenu.Edit.Scale="Aldınnan kóriw kólemi" +Basic.MainMenu.Edit.Scale.Canvas="Холст (%1x%2)" +Basic.MainMenu.Edit.Order="Тәртип (&O)" +Basic.MainMenu.View="Көринис (&V)" +Basic.MainMenu.View.ContextBar="Дереклер панели" +Basic.MainMenu.View.SourceIcons="Дерек белгилери (&I)" +Basic.MainMenu.View.Fullscreen.Interface="Толық экран режими" Basic.MainMenu.View.SceneListMode="Saxnalar dizimi rejimi" Basic.MainMenu.Docks="&Paneller" +Basic.MainMenu.Import="Импорт…" +Basic.MainMenu.Export="Экспорт…" Basic.MainMenu.SceneCollection="&Saxnalar toplamı" Basic.MainMenu.Profile="Profil (&P)" Basic.MainMenu.Profile.Import="Profildi importlaw" @@ -499,7 +510,7 @@ Basic.MainMenu.SceneCollection.Export="Saxna toplamın eksport qılıw" Basic.MainMenu.Profile.Exists="Profil álleqashan bar" Basic.MainMenu.Tools="Ásbaplar (&T)" -Basic.MainMenu.Help="Járdem (&H)" +Basic.MainMenu.Help="Жәрдем (&H)" Basic.MainMenu.Help.HelpPortal="Maǵlıwmatlar portalı (&P)" Basic.MainMenu.Help.Website="Veb-saytqa kiriw (&W)" Basic.MainMenu.Help.WhatsNew="Ne jańalıq" @@ -513,16 +524,16 @@ Basic.MainMenu.Help.CrashLogs="Qátelikler tuwralı esaplar (&R)" Basic.MainMenu.Help.CrashLogs.ShowLogs="Qátelikler tuwralı esaplardı kórsetiw" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Qátelik tuwralı aldıńǵı esaptı jiberiw (&P)" -Basic.MainMenu.Help.About="Baǵdarlama haqqında (&A)" +Basic.MainMenu.Help.About="Бағдарлама туўралы (&A)" Basic.Settings.ProgramRestart="Bul sazlawlar kúshke kiriwi ushın baǵdarlamanı qayta iske túsiriw talap etiledi." Basic.Settings.ConfirmTitle="Ózgerislerdi tastıyıqlaw" Basic.Settings.Confirm="Sizde saqlanbaǵan ózgerisler bar. Ózgerisler saqlansın ba?" -Basic.Settings.General="Ulıwmalıq" -Basic.Settings.General.Language="Til" -Basic.Settings.General.Updater="Jańalanıwlar" -Basic.Settings.General.UpdateChannel="Jańalaw kanalı" -Basic.Settings.General.UpdateChannelDisabled="(Óshirilgen)" -Basic.Settings.General.UpdateChannelDefault="(Aldınnan ornatılǵan)" +Basic.Settings.General="Улыўмалық" +Basic.Settings.General.Language="Тил" +Basic.Settings.General.Updater="Жаңаланыўлар" +Basic.Settings.General.UpdateChannel="Жаңалаў каналы" +Basic.Settings.General.UpdateChannelDisabled="(Өширилген)" +Basic.Settings.General.UpdateChannelDefault="(Әдепки)" Basic.Settings.General.EnableAutoUpdates="Iske túsirgende jańalanıwlardı tekseriw" Basic.Settings.General.OpenStatsOnStartup="Iske túsirgende statistika aynasın ashıw" Basic.Settings.General.HideOBSWindowsFromCapture="Qamtıp alıwdan OBS aynaların jasırıw" @@ -530,24 +541,37 @@ Basic.Settings.General.WarnBeforeStoppingStream="Esittiriwdi toqtatqanda, tastıyıqlaw aynasın kórsetiw" Basic.Settings.General.WarnBeforeStoppingRecord="Jazıp alıwdı toqtatqanda, tastıyıqlaw aynasın kórsetiw" Basic.Settings.General.Projectors="Proektorlar" +Basic.Settings.General.HideProjectorCursor="Проекторлар үстинде курсорды жасырыў" Basic.Settings.General.ProjectorAlwaysOnTop="Proektorlardı hámiyshe barlıq aynalar ústinde kórsetiw" Basic.Settings.General.RecordWhenStreaming="Esittiriw waqtında avtomat tárizde jazıp alıw" Basic.Settings.General.KeepRecordingWhenStreamStops="Esittiriwdi juwmaqlaǵanda jazıp alıwdı dawam etiw" Basic.Settings.General.SysTray="Xabarlamalar maydanı" Basic.Settings.General.SaveProjectors="Shıqqanda proektorlardı saqlaw" Basic.Settings.General.Preview="Aldınnan kóriw" +Basic.Settings.General.Importers="Импортёрлар" Basic.Settings.General.TogglePreviewProgramLabels="Aldınnan kóriw/Baǵdarlama belgilerin kórsetiw" +Basic.Settings.General.Multiview="Мульти көринис" Basic.Settings.General.Multiview.DrawSourceNames="Saxna atamaların kórsetiw" Basic.Settings.General.Multiview.DrawSafeAreas="Qáwipsiz zonalardı sızıw (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Мульти көринис жайласыўы" Basic.Settings.General.MultiviewLayout.4Scene="Tek saxnalar (4 saxna)" Basic.Settings.General.MultiviewLayout.9Scene="Tek saxnalar (9 saxna)" Basic.Settings.General.MultiviewLayout.16Scene="Tek saxnalar (16 saxna)" Basic.Settings.General.MultiviewLayout.25Scene="Tek saxnalar (25 saxna)" Basic.Settings.General.ChannelName.stable="Turaqlı" Basic.Settings.General.ChannelDescription.stable="Sońǵı turaqlı versiya" -Basic.Settings.Stream="Esittiriw" -Basic.Settings.Stream.Custom.Username="Paydalanıwshı atı" -Basic.Settings.Stream.Custom.Password="Parol" +Basic.Settings.Appearance="Сыртқы көринис" +Basic.Settings.Appearance.General="Улыўмалық" +Basic.Settings.Appearance.General.Theme="Тема" +Basic.Settings.Appearance.General.Variant="Стиль" +Basic.Settings.Appearance.FontScale="Шрифт өлшеми" +Basic.Settings.Appearance.Classic="Классик" +Basic.Settings.Appearance.Compact="Компакт" +Basic.Settings.Appearance.Normal="Нормал" +Basic.Settings.Appearance.Comfortable="Қолайлы" +Basic.Settings.Stream="Трансляция" +Basic.Settings.Stream.Custom.Username="Пайдаланыўшы аты" +Basic.Settings.Stream.Custom.Password="Пароль" Basic.Settings.Stream.Custom.Username.ToolTip="RIST: kirgiziń srp_username.\nRTMP: paydalanıwshı atın kirgiziń.\nSRT: qollanılmaydı." Basic.Settings.Stream.Custom.Password.ToolTip="RIST: kirgiziń srp_password.\nRTMP: paroldı kirgiziń.\nSRT: shifrlaw parolin kirgiziń." Basic.Settings.Stream.TTVAddon="Twitch chatınıń qosımshaları" @@ -559,6 +583,8 @@ Basic.Settings.Stream.IgnoreRecommended.Warn.Title="Usınılǵan sazlawlardı qayta belgilew" Basic.Settings.Stream.IgnoreRecommended.Warn.Text="Eskertiw: Esittiriw xızmetlerinıń sheklewlerin esapqa almaw onı júrgiziwge yamasa onıń sapasına jaman tásir etiwi múmkin.\n\nDawam ettiriwdi qáleysiz be?" Basic.Settings.Stream.ServiceCustomServer="Arnawlı Server" +Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrateAuto="Авто" +Basic.Settings.Stream.MultitrackVideoMaximumVideoTracksAuto="Авто" Basic.Settings.Output="Shıǵıw" Basic.Settings.Output.Format="Jazıp alıw formatı" Basic.Settings.Output.Format.fMP4="Bóleklengen MP4 (.mp4)" @@ -576,7 +602,6 @@ Basic.Settings.Output.Simple.RecordingQuality="Jazıw sapası" Basic.Settings.Output.Simple.RecordingQuality.Stream="Esittiriwdegidey" Basic.Settings.Output.Simple.RecordingQuality.Small="Joqarı sapa, ortasha fayl kólemi" -Basic.Settings.Output.Simple.Encoder.Software="Programmalıq (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV.H264="Apparatlıq (QSV, H.264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV.AV1="Apparatlıq (QSV, AV1)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD.H264="Apparatlıq (AMD, H.264)" @@ -601,14 +626,15 @@ Basic.Settings.Output.EncoderPreset.fast="%1 (OPdan paydalanıw joqarı, joqarı sapa)" Basic.Settings.Output.CustomEncoderSettings="Kodlawshınıń arnawlı sazlawları" Basic.Settings.Output.NoSpaceFileName="Fayl atamasın bos orınsız jaratıw" +Basic.Settings.Output.Adv.Rescale.Disabled="Жоқ" Basic.Settings.Output.Adv.Streaming="Esittiriw" Basic.Settings.Output.Adv.Streaming.Settings="Esittiriw sazlawları" -Basic.Settings.Output.Adv.Audio.Track1="Qosıq 1" -Basic.Settings.Output.Adv.Audio.Track2="Qosıq 2" -Basic.Settings.Output.Adv.Audio.Track3="Qosıq 3" -Basic.Settings.Output.Adv.Audio.Track4="Qosıq 4" -Basic.Settings.Output.Adv.Audio.Track5="Qosıq 5" -Basic.Settings.Output.Adv.Audio.Track6="Qosıq 6" +Basic.Settings.Output.Adv.Audio.Track1="Трек 1" +Basic.Settings.Output.Adv.Audio.Track2="Трек 2" +Basic.Settings.Output.Adv.Audio.Track3="Трек 3" +Basic.Settings.Output.Adv.Audio.Track4="Трек 4" +Basic.Settings.Output.Adv.Audio.Track5="Трек 5" +Basic.Settings.Output.Adv.Audio.Track6="Трек 6" Basic.Settings.Output.Adv.Encoder="Kodlawshı sazlawları" Basic.Settings.Output.Adv.Recording="Jazıp alıw" Basic.Settings.Output.Adv.Recording.Settings="Jazıp alıw sazlawları" @@ -624,6 +650,8 @@ Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Barlıq fayllar" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Fayl jolı yamasa URL mánzil" Basic.Settings.Output.Adv.FFmpeg.Format="Konteyner format" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Аудио" +Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Видео" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Standart format" Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Konteyner format táriypi" Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio hám video kodekler URL mánzil yamasa fayl jolı arqalı tabıladı" @@ -652,118 +680,111 @@ FilenameFormatting.TT.B="Aydıń tolıq ataması" FilenameFormatting.TT.H="Saat 24 saat formatında (00-23)" FilenameFormatting.TT.I="Saat 12 saat formatında (01-12)" -FilenameFormatting.TT.M="Minut (00-59)" -FilenameFormatting.TT.S="Sekund (00-59)" -FilenameFormatting.TT.y="Jıl, sońǵı eki san (00-99)" -FilenameFormatting.TT.Y="Jıl" +FilenameFormatting.TT.M="Минут (00-59)" +FilenameFormatting.TT.S="Секунд (00-59)" +FilenameFormatting.TT.Y="Жыл" FilenameFormatting.TT.FPS="Kadrlar tezligi" -Basic.Settings.Video.Adapter="Video adapter" +Basic.Settings.Video="Видео" +Basic.Settings.Video.Adapter="Видеоадаптер" Basic.Settings.Video.FPS="Kadrlar tezligi (FPS)" -Basic.Settings.Audio.Channels="Kanallar" -Basic.Settings.Audio.Meters="Ólshewishler" -Basic.Settings.Audio.MeterDecayRate.Fast="Tez" -Basic.Settings.Audio.Devices="Ulıwmalıq dawıs qurılmaları" +Basic.Settings.Video.Renderer.Experimental="%1 (Экспериментал)" +Basic.Settings.Audio="Аудио" +Basic.Settings.Audio.Channels="Каналлар" +Basic.Settings.Audio.MeterDecayRate.Fast="Тез" Basic.Settings.Audio.DesktopDevice="Jumıs stolı dawısı" Basic.Settings.Audio.DesktopDevice2="Jumıs stolı dawısı 2" Basic.Settings.Audio.AuxDevice="Mikrofon/qosımsha dawıs" Basic.Settings.Audio.AuxDevice2="Mikrofon/qosımsha dawıs 2" Basic.Settings.Audio.AuxDevice3="Mikrofon/qosımsha dawıs 3" -Basic.Settings.Audio.AuxDevice4="Mikrofon/qosımsha dawıs 4" -Basic.Settings.Audio.Disabled="Óshirilgen" +Basic.Settings.Audio.Disabled="Өширилген" Basic.Settings.Accessibility="Arnawlı imkaniyatlar" Basic.Settings.Accessibility.ColorOverrides="Basqa reńlerdi qollanıw" -Basic.Settings.Accessibility.ColorOverrides.Preset.Default="Aldınnan ornatılǵan" -Basic.Settings.Accessibility.ColorOverrides.Preset.Custom="Arnawlı" -Basic.Settings.Advanced="Qosımsha" -Basic.Settings.Advanced.General.ProcessPriority.High="Joqarı" -Basic.Settings.Advanced.General.ProcessPriority.Normal="Ortasha" -Basic.Settings.Advanced.General.ProcessPriority.Idle="Tómen" -Basic.Settings.Advanced.Video.ColorFormat="Reń formatı" -Basic.Settings.Advanced.Video.ColorFormat.NV12="NV12 (8 bit, 4:2:0, 2 dáreje)" -Basic.Settings.Advanced.Video.ColorFormat.I420="I420 (8 bit, 4:2:0, 3 dáreje)" -Basic.Settings.Advanced.Video.ColorFormat.I444="I444 (8 bit, 4:4:4, 3 dáreje)" -Basic.Settings.Advanced.Video.ColorFormat.P010="P010 (10 bit, 4:2:0, 2 dáreje)" -Basic.Settings.Advanced.Video.ColorFormat.I010="I010 (10 bit, 4:2:0, 3 dáreje)" -Basic.Settings.Advanced.Video.ColorFormat.P216="P216 (16 bit, 4:2:2, 2 dáreje)" +Basic.Settings.Accessibility.ColorOverrides.Preset.Default="Әдепки" +Basic.Settings.Accessibility.ColorOverrides.Preset.Custom="Арнаўлы" +Basic.Settings.Advanced.General.ProcessPriority.High="Жоқары" +Basic.Settings.Advanced.General.ProcessPriority.Normal="Нормал" +Basic.Settings.Advanced.General.ProcessPriority.Idle="Төмен" +Basic.Settings.Advanced.Video.ColorFormat="Рең форматы" +Basic.Settings.Advanced.Video.ColorFormat.NV12="NV12 (8 бит, 4:2:0, 2 дәреже)" +Basic.Settings.Advanced.Video.ColorFormat.I420="I420 (8 бит, 4:2:0, 3 дәреже)" +Basic.Settings.Advanced.Video.ColorFormat.I444="I444 (8 бит, 4:4:4, 3 дәреже)" +Basic.Settings.Advanced.Video.ColorFormat.P010="P010 (10 бит, 4:2:0, 2 дәреже)" +Basic.Settings.Advanced.Video.ColorFormat.I010="I010 (10 бит, 4:2:0, 3 дәреже)" +Basic.Settings.Advanced.Video.ColorFormat.P216="P216 (16 бит, 4:2:2, 2 дәреже)" Basic.Settings.Advanced.Video.ColorFormat.P416="P416 (16 bit, 4:4:4, 2 dáreje)" Basic.Settings.Advanced.Video.ColorFormat.BGRA="BGRA (8 bit)" -Basic.Settings.Advanced.Video.ColorSpace="Reń maydanı" -Basic.Settings.Advanced.Video.ColorRange="Reń aralıǵı" -Basic.Settings.Advanced.Video.ColorRange.Partial="Sheklengen" -Basic.Settings.Advanced.Video.ColorRange.Full="Tolıq" +Basic.Settings.Advanced.Video.ColorRange="Рең аралығы" +Basic.Settings.Advanced.Video.ColorRange.Partial="Шекленген" +Basic.Settings.Advanced.Video.ColorRange.Full="Толық" Basic.Settings.Advanced.Video.SdrWhiteLevel="SDR aqlıq dárejesi" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Aldınnan ornatılǵan" Basic.Settings.Advanced.Network="Tarmaq" Basic.Settings.Advanced.Network.Disabled="Ámeldegi tańlanǵan esittiriw protokolı tarmaq sazlawların ózgertiwdi jebemeydi." Basic.Settings.Advanced.AutoRemux.MP4="(mkv retinde jazıp alıw)" +Basic.AudioMixer.Pin="Қадаў" +Basic.AudioMixer.Unpin="Шешиў" +Basic.AudioMixer.Hide="Жасырыў" +Basic.AudioMixer.Unhide="Көрсетиў" +Basic.AudioMixer.Category.Global="Глобал" +Basic.AudioMixer.Category.Pinned="Қадалған" +Basic.AudioMixer.Category.Active="Актив" +Basic.AudioMixer.Category.Inactive="Актив емес" +Basic.AudioMixer.Category.Preview="Көринис" +Basic.AudioMixer.Category.Hidden="Жасырын" Basic.AdvAudio="Dawıstıń keńeytilgen qásiyetleri" Basic.AdvAudio.ActiveOnly="Tek aktiv derekler" -Basic.AdvAudio.Name="Ataması" -Basic.AdvAudio.Volume="Dawıs bálentligi" +Basic.AdvAudio.Name="Атамасы" Basic.AdvAudio.VolumeSource="'%1' ushın dawıs bálentligi" -Basic.AdvAudio.AudioTracks="Qosıqlar" +Basic.AdvAudio.Mono="Моно" +Basic.AdvAudio.Balance="Баланс" +Basic.AdvAudio.AudioTracks="Треклер" Basic.Settings.Hotkeys.Filter="Filtr" Basic.Hotkeys.SelectScene="Saxnaǵa ótiw" -Basic.SystemTray.Show="Kórsetıw" -Basic.SystemTray.Hide="Jasırıw" +Basic.SystemTray.Show="Көрсетиў" +Basic.SystemTray.Hide="Жасырыў" Basic.SystemTray.Message.Reconnecting="Baylanıs úzildi. Qayta jalǵanbaqta..." -Hotkeys.Insert="Ornalastırıw" +Hotkeys.Insert="Қойыў" Hotkeys.Delete="Óshiriw" -Hotkeys.Home="Bas bet" +Hotkeys.Home="Бас бет" Hotkeys.End="Juwmaqlaw" Hotkeys.PageUp="1 bet joqarıǵa" Hotkeys.PageDown="1 bet tómenge" -Hotkeys.Pause="Pauza" +Hotkeys.Tab="↹" +Hotkeys.Print="Print Screen" +Hotkeys.Pause="Pause Break" Hotkeys.Left="Shep" Hotkeys.Right="Oń" Hotkeys.Up="Joqarıǵa" Hotkeys.Down="Tómenge" -Hotkeys.Menu="Menyu" -Hotkeys.Space="Bos orın" -Hotkeys.MouseButton="Tıshqansha %1" -Mute="Dawıstı óshiriw" -Unmute="Dawıstı qosıw" -SceneItemShow="Kórsetiw '%1'" -SceneItemHide="Jasırıw '%1'" -OutputWarnings.NoTracksSelected="Siz keminde bir qosıqtı tańlawıńız kerek" -OutputWarnings.NoTracksSelectedOnExit.Title="Shıǵıw sazlawları qáteligi" +Hotkeys.Windows="⊞ Win" +Hotkeys.Menu="Меню" +Hotkeys.Space="Бос орын" +Mute="Даўыссыз қылыў" +Unmute="Даўыслы қылыў" CodecCompat.Incompatible="(%1 penen sáykes emes)" -CodecCompat.CodecPlaceholder="Kodlawshını tańlaw..." -CodecCompat.ContainerPlaceholder="Formattı tańlaw..." -CodecCompat.CodecMissingOnExit.Title="Kodlawshı tańlanbaǵan" -CodecCompat.ContainerMissingOnExit.Title="Format tańlanbaǵan" +CodecCompat.ContainerPlaceholder="Форматты таңлаў..." CodecCompat.ContainerMissingOnExit.Text="Jazıp alıw formatı tańlanbaǵan. Ótinish, tańlanǵan esittiriw kodlawshısı menen sáykes jazıp alıw formatın tańlań." -FinalScene.Title="Saxnanı óshiriw" +FinalScene.Title="Сахнаны өшириў" FinalScene.Text="Sońǵı saxnanı óshiriwge bolmaydı." -NoSources.Title="Derekler joq" +NoSources.Title="Дереклер жоқ" NoSources.Label="Sizde derekler joq\nQosıw ushın tómendegi + túymesine yamasa usı jerge tıshqanshanıń oń túymesin basıń." ChangeBG="Reń ornatıw" -CustomColor="Arnawlı reń" +CustomColor="Арнаўлы рең" BrowserSource.EnableHardwareAcceleration="«Brauzer» deregi ushın apparatlıq tezlestiriwdi qosıw" -About="Baǵdarlama haqqında" -About.Donate="Úles qosıw" -About.GetInvolved="Qatnasıw" -About.Authors="Avtorlar" -About.License="Licenziya" -About.Error="Qátelik! Fayldı oqıw múmkin emes.\n\nGit: %1" -About.Contribute="OBS jobasın qollap-quwatlaw" -AddUrl.Title="URL mánzil arqalı derek qosıw" -AddUrl.Text.Url="URL mánzil: %1" -ResizeOutputSizeOfSource.Continue="Dawam etiwdi qáleysiz be?" +About="Бағдарлама туўралы" +About.Donate="Үлес қосыў" +About.GetInvolved="Қатнасыў" +About.Authors="Авторлар" +About.License="Лицензия" +AddUrl.Text.Url="Силтеме: %1" +ResizeOutputSizeOfSource.Continue="Даўам етесиз бе?" PreviewTransition="Ótiwdi aldınnan kóriw" Importer.SelectCollection="Saxnalar toplamın tańlań" Importer.Collection="Saxnalar toplamı" -Importer.Path="Toplam jolı" -Importer.Program="Tabılǵan qosımsha" -Importer.AutomaticCollectionPrompt="Saxnalar toplamların avtomat tárizde izlew" -Restart="Qayta iske túsiriw" +Importer.Path="Топлам жолы" +Restart="Қайта иске түсириў" NeedsRestart="OBS qayta iske túsiriliwi zárúr. Házir qayta iske túsiriwdi qáleysiz be?" -ContextBar.NoSelectedSource="Derek tańlanbaǵan" -ContextBar.MediaControls.PlayMedia="Media qoyıw" -ContextBar.MediaControls.PauseMedia="Medianı toqtatıp turıw" -ContextBar.MediaControls.StopMedia="Medianı toqtatıw" -ContextBar.MediaControls.RestartMedia="Medianı qayta qoyıw" -ContextBar.MediaControls.PlaylistPrevious="Pleylistte aldınǵısı" +ContextBar.NoSelectedSource="Дерек таңланбаған" YouTube.Auth.WaitingAuth.Text="Ótinish, kiriwdi sırtqı brauzerge juwmaqlań.<br>Eger sırtqı brauzer ashılmasa, usı siltemege ótiń hám kiriwdi juwmaqlań:<br>%1" YouTube.AuthError.Text="Kanal haqqında maǵlıwmattı alıw ámelge aspadı: %1." YouTube.Actions.CreateNewEvent="Jańa esittiriw jaratıw" @@ -775,32 +796,47 @@ YouTube.Actions.Privacy.Private="Jekelik" YouTube.Actions.Privacy.Public="Hámmege kórinetuǵın" YouTube.Actions.Privacy.Unlisted="Silteme arqalı kiriw" -YouTube.Actions.Category="Kategoriya" -YouTube.Actions.Thumbnail.SelectFile="Fayldı tańlaw..." -YouTube.Actions.Thumbnail.NoFileSelected="Fayl tańlanbaǵan" -YouTube.Actions.Thumbnail.ClearFile="Tazalaw" -YouTube.Actions.MadeForKids="Bul video balalar ushın tayarlanǵan ba?*" -YouTube.Actions.MadeForKids.Yes="Awa, bul balalar ushın tayarlanǵan" -YouTube.Actions.MadeForKids.No="Yaq, bul balalar ushın tayarlanbaǵan" -YouTube.Actions.AdditionalSettings="Qosımsha sazlawlar" -YouTube.Actions.Latency="Iskilis" -YouTube.Actions.Latency.Normal="Ortasha" -YouTube.Actions.Latency.Low="Tómen" -YouTube.Actions.Latency.UltraLow="Júda tómen" -YouTube.Actions.EnableAutoStart="Avtomat tárizde iske túsiriwdi qosıw" -YouTube.Actions.EnableAutoStop="Avtomat tárizde toqtatıwdı qosıw" -YouTube.Actions.EnableDVR="DVRdı qosıw" +YouTube.Actions.Category="Категория" +YouTube.Actions.Thumbnail="Миниатюра" +YouTube.Actions.Thumbnail.SelectFile="Файлды таңлаў..." +YouTube.Actions.Thumbnail.NoFileSelected="Файл таңланбаған" +YouTube.Actions.Thumbnail.ClearFile="Тазалаў" +YouTube.Actions.MadeForKids="Бул видео баллар ушын ба?*" +YouTube.Actions.MadeForKids.Yes="Аўа, бул видео балалар ушын" +YouTube.Actions.MadeForKids.No="Яқ, балалар ушын емес" +YouTube.Actions.AdditionalSettings="Қосымша сазлаўлар" +YouTube.Actions.Latency="Иркилис" +YouTube.Actions.Latency.Normal="Нормал" +YouTube.Actions.Latency.Low="Төмен" +YouTube.Actions.Latency.UltraLow="Жүдә төмен" +YouTube.Actions.EnableDVR="DVR қосыў" +YouTube.Actions.360Video="360 видео" YouTube.Actions.ScheduleForLater="Keyinirekke rejelestiriw" YouTube.Actions.RememberSettings="Bul sazlawlardı este saqlaw" YouTube.Actions.Create_Ready="Esittiriw jaratıw" YouTube.Actions.Choose_Ready="Esittiriwdi tańlaw" YouTube.Actions.Dashboard="YouTube Studionı Ashıw" -YouTube.Actions.Error.Title="Esittiriwdi jaratıw qátesi" -YouTube.Actions.Error.BroadcastNotFound="Tańlanǵan esittiriw tabılmadı." -YouTube.Actions.Error.FileMissing="Tańlanǵan fayl joq." -YouTube.Actions.Error.FileOpeningFailed="Tańlanǵan fayldı ashıw ámelge aspadı." -YouTube.Actions.Error.FileTooLarge="Tańlanǵan fayl júdá úlken (sheklew: 2 Mb)" -YouTube.Actions.Stream="Esittiriw" -YouTube.Actions.Stream.YTStudio="YouTube Studio tárepinen avtomat tárizde jaratıldı" -YouTube.Actions.AutoStartStreamingWarning.Title="Qolda iske túsiriw talap etiledi" +YouTube.Actions.Error.FileMissing="Таңланған файл жоқ." +YouTube.Actions.Error.FileTooLarge="Таңланған файл жүдә үлкен (шеклеў: 2 МБ)" +YouTube.Actions.Stream.ScheduledFor="Режелестирилген: %1" +YouTube.Actions.Stream.YTStudio="YouTube Studio тәрепинен автоматикалық жаратылды" YouTube.Errors.errorStreamInactive="Esittiriwińiz ushın YouTube maǵlıwmatlardı almay atır. Ótinish, sazlawlardı teskeriń hám qayta urınıp kóriń." +ConfigDownload.WarningMessageTitle="Дыққат" +PluginManager.MissingPlugin="Жоқ плагинлер" +PluginManager.Section.Manage="Орнатылған" +PluginManager.Section.Updates="Жаңаланыўлар" +PluginManager.Section.Manage.Title="Орнатылған" +PluginManager.Section.Manage.NoPlugins="Плагинлер табылмады." +PluginManager.Section.Errors.Title="Қәтеликлер" +PluginManager.Section.Missing.Title="Жоқ" +PluginManager.Status.Legacy="Ескирген" +PluginManager.Status.Disabled="Өширилген" +PluginManager.Status.Error="Қәтелик" +PluginManager.Status.Missing="Жоқ" +EncoderMissing.Title="Жоқ кодлаўшылар" +EncoderMissing.Unknown="Белгисиз" +EncoderMissing.NVENC.TestProgramError="NVENC тексериўинде қәтелик: %1" +EncoderMissing.NVENC.NoDevices="NVIDIA графикалық процессоры табылмады" +EncoderMissing.NVENC.Reason.NvmlInit="NVML инициализациялаў қәтелиги" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC версиясы көрсетилмеген" +EncoderMissing.NVENC.Reason.DriverOutdated="Ескирген драйвер"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/kab-KAB.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/kab-KAB.ini
Changed
@@ -441,13 +441,9 @@ Basic.Main.PreviewDisabled="Tadlayt tensa akka tura" Basic.SourceSelect="Rnu aɣbalu" Basic.SourceSelect.SelectType="Anaw n uɣbaly" -Basic.SourceSelect.Recent="Yettwarna melmi kan" -Basic.SourceSelect.NewSource="Rnu aɣbalu amaynut" -Basic.SourceSelect.Existing="Rnu aɣbalu i yellan" Basic.SourceSelect.CreateButton="Snulfu-d amaynut" Basic.SourceSelect.AddVisible="Err aɣbalu ad yettban" Basic.SourceSelect.Accessible.SourceName="Isem n uɣbalu" -Basic.SourceSelect.Accessible.Existing="Rnu aɣbalu i yellan" Basic.Main.Sources.Visibility="Tawalit" Basic.Main.Sources.VisibilityDescription="Ad isenqed tawalit n '%1' di teɣzut n usuneɣ" Basic.Main.Sources.Lock="Sekkeṛ"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/kmr-TR.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/kmr-TR.ini
Changed
@@ -1199,4 +1199,3 @@ PluginManager.Section.Discover="Bigere" PluginManager.Section.Manage="Sazkirî" PluginManager.Section.Updates="Rojanekirin" -PluginManager.Section.Manage.Title="Pêvekên çalakkirî bi rê ve bibe"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ko-KR.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ko-KR.ini
Changed
@@ -127,7 +127,11 @@ CrashHandling.Buttons.LaunchNormal="일반 모드로 실행" CrashHandling.Errors.UploadJSONError="가장 최근의 비정상 종료 로그를 업로드하는 중 오류가 발생했습니다. 나중에 다시 시도해 주세요." CrashHandling.Errors.Title="비정상 종료 업로드 오류" -SafeMode.Restart="안전모드에서 OBS를 다시 시작하시겠습니까? (3자 제공 플러그인, 스크립트, 웹소켓 꺼짐)" +PluginFailure.Dialog.Title="플러그인 오류" +PluginFailure.Labels.Text="OBS Studio에서 서드파티 플러그인을 모두 불러오지 못했습니다.\n\n자세한 플러그인 관리자에서 확인할 수 있습니다." +PluginFailure.Dialog.Continue="무시" +PluginFailure.Dialog.Open="플러그인 관리 열기" +SafeMode.Restart="안전모드에서 OBS를 다시 시작하시겠습니까? (서드파티 플러그인, 스크립트, 웹소켓 꺼짐)" SafeMode.RestartNormal="OBS를 일반 모드로 다시 실행하시겠습니까?" ChromeOS.Title="지원하지 않는 플랫폼" ChromeOS.Text="OBS가 ChromeOS 컨테이너 안에서 작동 중입니다. 이 플랫폼은 지원되지 않습니다." @@ -507,12 +511,14 @@ Basic.Main.PreviewDisabled="미리보기가 꺼져 있습니다" Basic.SourceSelect="소스 추가" Basic.SourceSelect.SelectType="소스 유형" -Basic.SourceSelect.Recent="최근 추가함" -Basic.SourceSelect.NewSource="새 소스 생성" -Basic.SourceSelect.Existing="기존 소스 추가" +Basic.SourceSelect.Recent="최근 생성함" +Basic.SourceSelect.Description="현재 장면에 추가할 소스를 선택하세요." +Basic.SourceSelect.NewSource="새로운 %1 추가하기" +Basic.SourceSelect.AddExisting="기존 %1 추가하기" +Basic.SourceSelect.NoSelection="기존 항목 추가" Basic.SourceSelect.CreateButton="새로 만들기" Basic.SourceSelect.AddVisible="소스를 표시" -Basic.SourceSelect.NoExisting="기존 %1 소스 없음" +Basic.SourceSelect.NoExisting="기존 %1 소스가 없습니다." Basic.SourceSelect.Accessible.SourceName="소스 이름" Basic.SourceSelect.Accessible.Existing="기존 소스 추가" Basic.SourceSelect.Deprecated.Create="이 소스 유형은 지원 종료 예정이며 미래에 제거될 수 있습니다." @@ -1196,6 +1202,8 @@ Unmute="음소거 해제" Push-to-mute="눌러서 음소거" Push-to-talk="눌러서 말하기" +MonitorOn="모니터링 켜기" +MonitorOff="모니터링 끄기" SceneItemShow="'%1' 표시" SceneItemHide="'%1' 숨기기" OutputWarnings.NoTracksSelected="하나 이상의 트랙을 선택해야 합니다" @@ -1361,5 +1369,40 @@ PluginManager.Section.Discover="탐색" PluginManager.Section.Manage="설치함" PluginManager.Section.Updates="업데이트" -PluginManager.Section.Manage.Title="켜진 플러그인 관리" +PluginManager.Section.Manage.Title="설치함" +PluginManager.Section.Manage.Description="현재 설치한 플러그인을 관리합니다." +PluginManager.Section.Manage.NoPlugins="플러그인을 찾을 수 없음." +PluginManager.Section.Errors.Title="오류" +PluginManager.Section.Errors.Description="플러그인을 불러오는 데 실패했습니다. 플러그인이 최신 버전이고 이 버전의 OBS Studio와 호환되는지 확인하십시오." +PluginManager.Section.Missing.Title="누락" +PluginManager.Section.Missing.Description="플러그인을 이전에 설치했지만 더 이상 찾을 수 없습니다." +PluginManager.Button.Enable="%1 플러그인 활성화" +PluginManager.Status.Legacy="구식" +PluginManager.Status.Disabled="사용 안 함" +PluginManager.Status.Error="오류" +PluginManager.Status.Missing="누락" +PluginManager.Status.Legacy.Description="플러그인이 향후 작동하지 않게 될 위치에 설치되어 있습니다. <a href=\"%1\">자세히 알아보기</a>" Accessible.Widget.Name.AlignmentSelector="정렬 선택기" +EncoderMissing.Title="인코더 누락" +EncoderMissing.Text="다음의 구성된 인코더가 누락되었습니다:\n<ul>\n%1</ul><br>\n더 많은 정보는 <a href=\"%2\">지식 창고 문서</a>를 참조하십시오." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (코드: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="알 수 없음" +EncoderMissing.MissingModule="\"%1\" 모듈을 불러오지 않음" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC 검사 프로그램 시작 실패" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC 검사 프로세스 실패, 종료 코드: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC 검사 프로세스 출력 읽기 실패, 종료 코드: %1" +EncoderMissing.NVENC.TestProgramError="NVENC 검사 실패, 사유: %1" +EncoderMissing.NVENC.NoDevices="NVIDIA GPU를 찾을 수 없음" +EncoderMissing.NVENC.Unsupported.Kepler="사용 중인 GPU(%1)의 아키텍처(Kepler)는 더 이상 지원하지 않습니다. OBS 30.2 이전 버전을 사용해 주십시오." +EncoderMissing.NVENC.Reason.NvmlLoad="NVML 라이브러리 불러오기 실패" +EncoderMissing.NVENC.Reason.NvmlInit="NVML 초기화 실패" +EncoderMissing.NVENC.Reason.NvencLoad="NVENC 라이브러리 불러오기 실패" +EncoderMissing.NVENC.Reason.NvencInit="NVENC 초기화 실패" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC 버전 비었음" +EncoderMissing.NVENC.Reason.CudaLoad="CUDA 라이브러리 불러오기 실패" +EncoderMissing.NVENC.Reason.CudaInit="CUDA 초기화 실패" +EncoderMissing.NVENC.Reason.CudaVersion="CUDA 버전 잘못됨/누락" +EncoderMissing.NVENC.Reason.DriverOutdated="구형 드라이버" +EncoderMissing.NVENC.Reason.NoSupportedDevices="NVENC를 지원하는 NVIDIA 기기를 찾을 수 없음" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="인코더 세션 제한을 초과함" +EncoderMissing.NVENC.Reason.AV1Unsupported="시스템의 모든 NVIDIA GPU가 AV1 인코딩을 지원하지 않음"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/lo-LA.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/lo-LA.ini
Changed
@@ -1136,4 +1136,3 @@ PluginManager.Section.Discover="ເລືອກເບິ່ງ" PluginManager.Section.Manage="ຕິດຕັ້ງແລ້ວ" PluginManager.Section.Updates="ການອັບເດດ" -PluginManager.Section.Manage.Title="ຈັດການປັກອິນທີ່ເປີດໃຊ້ງານ"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/lv-LV.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/lv-LV.ini
Changed
@@ -481,13 +481,9 @@ Basic.Main.PreviewDisabled="Priekšskats pašlaik ir atspējots" Basic.SourceSelect="Pievienot Avotu" Basic.SourceSelect.SelectType="Avota Tips" -Basic.SourceSelect.Recent="Nesen Pievienots" -Basic.SourceSelect.NewSource="Izveidot Jaunu Avotu" -Basic.SourceSelect.Existing="Pievienot Esošu Avotu" Basic.SourceSelect.CreateButton="Izveidot Jaunu" Basic.SourceSelect.AddVisible="Padarīt avotu redzamu" Basic.SourceSelect.Accessible.SourceName="Avota Nosaukums" -Basic.SourceSelect.Accessible.Existing="Pievienot Esošu Avotu" Basic.SourceSelect.Deprecated.Create="Šis avota tips ir atzīmēts kā novecojis un nākotnē var tikt noņemts." Basic.Main.Sources.Visibility="Redzamība" Basic.Main.Sources.VisibilityDescription="Kontrolē '%1' redzamību kanvās"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ms-MY.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ms-MY.ini
Changed
@@ -492,14 +492,16 @@ Basic.Main.PreviewDisabled="Pratonton buat masa ini dilumpuhkan" Basic.SourceSelect="Tambah Sumber" Basic.SourceSelect.SelectType="Jenis Sumber" -Basic.SourceSelect.Recent="Yang Baru Ditambah" -Basic.SourceSelect.NewSource="Cipta Sumber Baharu" -Basic.SourceSelect.Existing="Tambah Sumber Sedia Ada" +Basic.SourceSelect.Recent="Dicipta baru-baru ini" +Basic.SourceSelect.Description="Pilih sumber yang hendak ditambah pada babak semasa anda." +Basic.SourceSelect.NewSource="Tambah %1 baharu" +Basic.SourceSelect.AddExisting="Tambah %1 yang sedia ada" +Basic.SourceSelect.NoSelection="Tambah yang sedia ada" Basic.SourceSelect.CreateButton="Cipta Baru" Basic.SourceSelect.AddVisible="Biar sumber tampak" -Basic.SourceSelect.NoExisting="Tidak wujud %1 sumber" +Basic.SourceSelect.NoExisting="Anda belum mempunyai sumber %1 sedia ada." Basic.SourceSelect.Accessible.SourceName="Nama Sumber" -Basic.SourceSelect.Accessible.Existing="Tambah Sumber Sedia Ada" +Basic.SourceSelect.Accessible.Existing="Tambah sumber sedia ada" Basic.SourceSelect.Deprecated.Create="Jenis sumber ini ditanda sebagai tidak digunakan lagi dan mungkin akan dialih keluar pada masa hadapan." Basic.Main.Sources.Visibility="Ketampakan" Basic.Main.Sources.VisibilityDescription="Kawal ketampakan '%1' dalam kanvas" @@ -1159,6 +1161,8 @@ Unmute="Nyahbisukan" Push-to-mute="Tekan-untuk-senyap" Push-to-talk="Tekan-untuk-cakap" +MonitorOn="Hidupkan Pemantauan" +MonitorOff="Matikankan Pemantauan" SceneItemShow="Tunjuk '%1'" SceneItemHide="Sembunyi '%1'" OutputWarnings.NoTracksSelected="Anda mesti memilih sekurang-kurangnya satu trek" @@ -1324,5 +1328,26 @@ PluginManager.Section.Discover="Layari" PluginManager.Section.Manage="Dipasang" PluginManager.Section.Updates="Kemaskini" -PluginManager.Section.Manage.Title="Urus Pemalam Yang Dihidupkan" Accessible.Widget.Name.AlignmentSelector="Pemilih Penjajaran" +EncoderMissing.Title="Pengekod Hilang" +EncoderMissing.Text="Pengekod yang dikonfigurasikan berikut tiada:\n<ul>\n%1</ul><br>\nLihat <a href=\"%2\">Artikel Pangkalan Pengetahuan</a> untuk maklumat lanjut." +EncoderMissing.Unknown="Tidak Diketahui" +EncoderMissing.MissingModule="Modul \"%1\" tidak dimuatkan" +EncoderMissing.NVENC.TestProgramFailedStartup="Kegagalan permulaan program semakan NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Kegagalan proses semakan NVENC, kod keluar: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Output proses semakan NVENC gagal baca, kod keluar: %1" +EncoderMissing.NVENC.TestProgramError="Semakan NVENC gagal dengan sebab: %1" +EncoderMissing.NVENC.NoDevices="Tiada NVIDIA GPU ditemui" +EncoderMissing.NVENC.Unsupported.Kepler="Seni bina (Kepler) GPU anda (%1) tidak lagi disokong. Sila gunakan OBS 30.2 atau versi sebelumnya." +EncoderMissing.NVENC.Reason.NvmlLoad="Gagal memuatkan pustaka NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Gagal memulakan NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Gagal memuatkan pustaka NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Gagal memulakan NVML" +EncoderMissing.NVENC.Reason.NvencVersion="Versi NVENC kosong" +EncoderMissing.NVENC.Reason.CudaLoad="Gagal memuatkan pustaka CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Gagal memulakan CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Versi CUDA tidak sah/tiada" +EncoderMissing.NVENC.Reason.DriverOutdated="Pemacu ketinggalan zaman" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Tiada peranti NVIDIA dengan sokongan NVENC ditemui" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Had sesi pengekod telah dilampaui" +EncoderMissing.NVENC.Reason.AV1Unsupported="Pengekodan AV1 tidak disokong oleh mana-mana GPU NVIDIA sistem"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/nl-NL.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/nl-NL.ini
Changed
@@ -119,6 +119,9 @@ CrashHandling.Buttons.LaunchNormal="Starten in normale modus" CrashHandling.Errors.UploadJSONError="Er is een fout opgetreden bij het uploaden van het meest recente crashlog. Probeer het later opnieuw." CrashHandling.Errors.Title="Crash log upload fout" +PluginFailure.Dialog.Title="Plugin fouten" +PluginFailure.Labels.Text="OBS Studio kon niet alle plugins van derden laden.\n\nMeer informatie is beschikbaar in de plugin manager.\n" +PluginFailure.Dialog.Continue="Negeer" SafeMode.Restart="Wil je OBS herstarten in veilige modus (plugins van derden, scripting en WebSockets uitgeschakeld)?" SafeMode.RestartNormal="Wil je OBS herstarten in normale modus?" ChromeOS.Title="Niet-ondersteund platform" @@ -482,12 +485,14 @@ Basic.Main.PreviewDisabled="Preview is momenteel uitgeschakeld" Basic.SourceSelect="Bron toevoegen" Basic.SourceSelect.SelectType="Bronsoort" -Basic.SourceSelect.Recent="Recent toegevoegd" -Basic.SourceSelect.NewSource="Maak een nieuwe bron" -Basic.SourceSelect.Existing="Voeg een bestaande bron toe" +Basic.SourceSelect.Recent="Recent gemaakt" +Basic.SourceSelect.Description="Selecteer welke bron(en) je wil toevoegen aan je huidige scene." +Basic.SourceSelect.NewSource="Een nieuwe %1 toevoegen" +Basic.SourceSelect.AddExisting="Bestaande %1 toevoegen" +Basic.SourceSelect.NoSelection="Bestaande toevoegen" Basic.SourceSelect.CreateButton="Nieuwe aanmaken" Basic.SourceSelect.AddVisible="Maak bron zichtbaar" -Basic.SourceSelect.NoExisting="Geen bestaande %1 bronnen" +Basic.SourceSelect.NoExisting="Je hebt nog geen bestaande %1 bronnen." Basic.SourceSelect.Accessible.SourceName="Bronnaam" Basic.SourceSelect.Accessible.Existing="Voeg een bestaande bron toe" Basic.SourceSelect.Deprecated.Create="Dit brontype is gemarkeerd als verouderd en kan in de toekomst worden verwijderd." @@ -1077,6 +1082,7 @@ Basic.AdvAudio.Monitoring="Audio monitoring" Basic.AdvAudio.Monitoring.None="Niet monitoren" Basic.AdvAudio.Monitoring.MonitorOnly="Alleen monitoren (uitvoer gedempt)" +Basic.AdvAudio.Monitoring.Both="Monitoring ingeschakeld" Basic.AdvAudio.MonitoringSource="Audio monitoring voor '%1'" Basic.AdvAudio.AudioTracks="Sporen" Basic.Settings.Hotkeys="Sneltoetsen" @@ -1099,6 +1105,8 @@ Hotkeys.NumpadSubtract="Numpad Min" Hotkeys.NumpadDecimal="Numpad Punt" Hotkeys.MouseButton="Muis %1" +MonitorOn="Monitoring inschakelen" +MonitorOff="Monitoring uitschakelen" SceneItemShow="Toon '%1'" SceneItemHide="Verberg '%1'" OutputWarnings.NoTracksSelected="Selecteer a.u.b. ten minste een track" @@ -1256,5 +1264,37 @@ PluginManager.SafeMode="Alle plugins zijn tijdelijk uitgeschakeld door veilige modus" PluginManager.Section.Discover="Bladeren" PluginManager.Section.Manage="Geïnstalleerd" -PluginManager.Section.Manage.Title="Beheer ingeschakelde plugins" +PluginManager.Section.Manage.Title="Geïnstalleerd" +PluginManager.Section.Manage.Description="Beheer uw momenteel geïnstalleerde plugins." +PluginManager.Section.Manage.NoPlugins="Geen plugins gevonden." +PluginManager.Section.Errors.Title="Fouten"\nPluginManager.Section.Errors.Description="\nDeze plugins konden niet worden geladen. Zorg ervoor dat ze up-to-date zijn en compatibel met deze versie van OBS Studio." +PluginManager.Section.Missing.Title="Ontbrekende" +PluginManager.Section.Missing.Description="Deze plugins waren eerder geïnstalleerd, maar zijn niet meer te vinden."\nPluginManager.Button.Enable="\nSchakel de %1-plugin in" +PluginManager.Status.Legacy="Verouderd" +PluginManager.Status.Disabled="Uitgeschakeld" +PluginManager.Status.Error="Fout" +PluginManager.Status.Missing="Ontbrekende" +PluginManager.Status.Legacy.Description="Deze plugin is geïnstalleerd op een locatie die in de toekomst niet meer zal werken. <a href=\"%1\">Meer informatie</a>" Accessible.Widget.Name.AlignmentSelector="uitlijningsselector" +EncoderMissing.Title="Missende encoders" +EncoderMissing.Text="De volgende geconfigureerde encoders ontbreken:\n<ul>\n%1</ul><br>\nRaadpleeg het <a href=\"%2\">artikel in de kennisbank</a> voor meer informatie." +EncoderMissing.Unknown="Onbekend" +EncoderMissing.MissingModule="Module \"%1\" niet geladen" +EncoderMissing.NVENC.TestProgramFailedStartup="Fout bij het starten van het NVENC-controleprogramma" +EncoderMissing.NVENC.TestProgramExitWithError="Fout bij NVENC-controleproces, afsluitcode: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Fout bij het lezen van de uitvoer van het NVENC-controleproces, afsluitcode: %1" +EncoderMissing.NVENC.TestProgramError="NVENC-controle mislukt, reden: %1" +EncoderMissing.NVENC.NoDevices="Geen NVIDIA GPU's gevonden" +EncoderMissing.NVENC.Unsupported.Kepler="De architectuur (Kepler) van uw GPU (%1) wordt niet langer ondersteund. Gebruik in plaats daarvan OBS 30.2 of een eerdere versie." +EncoderMissing.NVENC.Reason.NvmlLoad="Laden van NVML-bibliotheek mislukt" +EncoderMissing.NVENC.Reason.NvmlInit="Initialisatie van NVML mislukt" +EncoderMissing.NVENC.Reason.NvencLoad="Laden van NVENC-bibliotheek mislukt" +EncoderMissing.NVENC.Reason.NvencInit="Initialisatie van NVENC mislukt" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC-versie leeg" +EncoderMissing.NVENC.Reason.CudaLoad="Laden van CUDA-bibliotheek mislukt" +EncoderMissing.NVENC.Reason.CudaInit="Initialisatie van CUDA mislukt" +EncoderMissing.NVENC.Reason.CudaVersion="Ongeldige/ontbrekende CUDA-versie" +EncoderMissing.NVENC.Reason.DriverOutdated="Verouderd stuurprogramma" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Geen NVIDIA-apparaten met NVENC-ondersteuning gevonden" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Limiet voor encoder-sessies overschreden" +EncoderMissing.NVENC.Reason.AV1Unsupported="AV1-codering wordt door geen van de NVIDIA-GPU's van het systeem ondersteund."
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/pl-PL.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/pl-PL.ini
Changed
@@ -123,6 +123,10 @@ CrashHandling.Buttons.LaunchNormal="Uruchom w trybie normalnym" CrashHandling.Errors.UploadJSONError="Wystąpił błąd podczas próby przesłania najnowszego dziennika awarii. Spróbuj ponownie później." CrashHandling.Errors.Title="Błąd przesyłania dziennika awarii" +PluginFailure.Dialog.Title="Błędy wtyczek" +PluginFailure.Labels.Text="OBS Studio nie mogło załadować wszystkich wtyczek innych firm.\n\nWięcej szczegółów znajdziesz w menedżerze wtyczek." +PluginFailure.Dialog.Continue="Odrzuć" +PluginFailure.Dialog.Open="Otwórz menedżer wtyczek" SafeMode.Restart="Czy chcesz uruchomić ponownie OBS w trybie awaryjnym (wyłączone wtyczki, skrypty i websockety)?" SafeMode.RestartNormal="Czy chcesz uruchomić OBS ponownie w normalnym trybie?" ChromeOS.Title="Platforma nieobsługiwana" @@ -499,12 +503,14 @@ Basic.Main.PreviewDisabled="Podgląd jest nieaktywny" Basic.SourceSelect="Dodaj źródło" Basic.SourceSelect.SelectType="Typ źródła" -Basic.SourceSelect.Recent="Ostatnio dodane" -Basic.SourceSelect.NewSource="Stwórz nowe źródło" -Basic.SourceSelect.Existing="Dodaj istniejące źródło" +Basic.SourceSelect.Recent="Ostatnio utworzone" +Basic.SourceSelect.Description="Wybierz źródła do dodania do obecnej sceny" +Basic.SourceSelect.NewSource="Dodaj nowe %1" +Basic.SourceSelect.AddExisting="Dodaj istniejące %1" +Basic.SourceSelect.NoSelection="Dodaj istniejące " Basic.SourceSelect.CreateButton="Stwórz nowe" Basic.SourceSelect.AddVisible="Źródło widoczne" -Basic.SourceSelect.NoExisting="Brak istniejących %1 źródeł " +Basic.SourceSelect.NoExisting="Nie posiadasz jeszcze istniejących źródeł %1" Basic.SourceSelect.Accessible.SourceName="Nazwa źródła" Basic.SourceSelect.Accessible.Existing="Dodaj istniejące źródło" Basic.SourceSelect.Deprecated.Create="Ten typ źródła jest oznaczony jako przestarzały i może być usunięty w przyszłości." @@ -1174,6 +1180,8 @@ Unmute="Wyłącz wyciszenie" Push-to-mute="Naciśnij-aby-wyciszyć" Push-to-talk="Naciśnij-aby-mówić" +MonitorOn="Włącz monitorowanie" +MonitorOff="Wyłącz monitorowanie" SceneItemShow="Pokaż '%1'" SceneItemHide="Ukryj '%1'" OutputWarnings.NoTracksSelected="Musisz wybrać przynajmniej jedną ścieżkę" @@ -1338,5 +1346,40 @@ PluginManager.Section.Discover="Przeglądaj" PluginManager.Section.Manage="Zainstalowana" PluginManager.Section.Updates="Aktualizacje" -PluginManager.Section.Manage.Title="Zarządzaj włączonymi wtyczkami" +PluginManager.Section.Manage.Title="Zainstalowane" +PluginManager.Section.Manage.Description="Zarządzaj zainstalowanymi wtyczkami" +PluginManager.Section.Manage.NoPlugins="Nie znaleziono wtyczek" +PluginManager.Section.Errors.Title="Błędy" +PluginManager.Section.Errors.Description="Nie udało się załadować tych wtyczek. Upewnij się, że są aktualne i zgodne z tą wersją OBS Studio." +PluginManager.Section.Missing.Title="Brakujące" +PluginManager.Section.Missing.Description="Te wtyczki były zainstalowane, ale nie można ich znaleźć." +PluginManager.Button.Enable="Włącz wtyczkę: %1" +PluginManager.Status.Legacy="Stary typ" +PluginManager.Status.Disabled="Wyłączone" +PluginManager.Status.Error="Błąd" +PluginManager.Status.Missing="Brak" +PluginManager.Status.Legacy.Description="Wtyczka zainstalowana jest w miejscu, gdzie przestanie działać w przyszłości. <a href=\"%1\">Dowiedz się więcej</a>" Accessible.Widget.Name.AlignmentSelector="Selektor wyrównania" +EncoderMissing.Title="Brak enkoderów" +EncoderMissing.Text="Brakuje poniższych, skonfigurowanych enkoderów:\n<ul>\n%1</ul><br>\nWięcej informacji znajdziesz w naszym <a href=\"%2\">wpisie w Bazie Wiedzy</a>." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (kod: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Nieznany" +EncoderMissing.MissingModule="Moduł \"%1\" niezaładowany." +EncoderMissing.NVENC.TestProgramFailedStartup="Błąd startu programu sprawdzającego NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Proces sprawdzający NVENC zakończony błędem. Kod błędu: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Błąd odczytu wyjścia procesu sprawdzającego NVENC. Kod błędu: %1" +EncoderMissing.NVENC.TestProgramError="Sprawdzenie NVENC nieudane: %1" +EncoderMissing.NVENC.NoDevices="Brak karty graficznej NVIDIA" +EncoderMissing.NVENC.Unsupported.Kepler="Architektura (Kepler) Twojej karty graficznej (%1) nie jest wspierana. Użyj OBS w wersji 30.2 lub wcześniejszej." +EncoderMissing.NVENC.Reason.NvmlLoad="Niezaładowano biblioteki NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Nieudana inicjalizacja NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Niezaładowano biblioteki NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Nieudana inicjalizacja NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Brak wersji NVENC" +EncoderMissing.NVENC.Reason.CudaLoad="Nie załadowano biblioteki CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Nieudana inicjalizacja CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Błędna lub brakująca wersja CUDA" +EncoderMissing.NVENC.Reason.DriverOutdated="Przestarzały sterownik graficzny" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Brak urządzeń NVIDIA wspierających NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Przekroczony limit sesji enkodera" +EncoderMissing.NVENC.Reason.AV1Unsupported="Żadna z kart graficznych NVIDIA w systemie nie wspiera enkodowania AV1"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/pt-BR.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/pt-BR.ini
Changed
@@ -125,6 +125,10 @@ CrashHandling.Buttons.LaunchNormal="Executar no modo normal" CrashHandling.Errors.UploadJSONError="Houve um erro ao tentar enviar o registro de falha mais recente. Por favor, tente de novo mais tarde." CrashHandling.Errors.Title="Erro no envio do registro de falha" +PluginFailure.Dialog.Title="Erros do plugin" +PluginFailure.Labels.Text="O OBS Studio não conseguiu carregar todos os plugins de terceiros.\n\nMais detalhes no gerenciador de plugins." +PluginFailure.Dialog.Continue="Dispensar" +PluginFailure.Dialog.Open="Abrir Gerenciador de Plugins" SafeMode.Restart="Deseja reiniciar o OBS no modo de segurança (plugins de terceiros, scripts e WebSockets desativados)?" SafeMode.RestartNormal="Deseja reiniciar o OBS no modo normal?" ChromeOS.Title="Plataforma não suportada" @@ -498,12 +502,14 @@ Basic.Main.PreviewDisabled="A pré-visualização esta desativada" Basic.SourceSelect="Adicionar fonte" Basic.SourceSelect.SelectType="Tipo de fonte" -Basic.SourceSelect.Recent="Adicionado recentemente" -Basic.SourceSelect.NewSource="Criar uma nova fonte" -Basic.SourceSelect.Existing="Adicionar uma fonte existente" +Basic.SourceSelect.Recent="Criado recentemente" +Basic.SourceSelect.Description="Selecione quais fontes serão adicionadas à sua cena atual." +Basic.SourceSelect.NewSource="Adicionar novo %1" +Basic.SourceSelect.AddExisting="Adicionar %1 existente" +Basic.SourceSelect.NoSelection="Adicionar existente" Basic.SourceSelect.CreateButton="Criar novo" Basic.SourceSelect.AddVisible="Tornar a fonte visível" -Basic.SourceSelect.NoExisting="%1 fontes não existentes" +Basic.SourceSelect.NoExisting="Você ainda não possui fontes %1 existentes." Basic.SourceSelect.Accessible.SourceName="Nome da fonte" Basic.SourceSelect.Accessible.Existing="Adicionar uma fonte existente" Basic.SourceSelect.Deprecated.Create="Este tipo de fonte está marcado como obsoleto e pode ser removido no futuro." @@ -1167,6 +1173,8 @@ Unmute="Desativar mudo" Push-to-mute="Pressionar-para-ativar-mudo" Push-to-talk="Pressione-para-falar" +MonitorOn="Ativar monitoramento" +MonitorOff="Desativar monitoramento" SceneItemShow="Mostrar '%1'" SceneItemHide="Ocultar '%1'" OutputWarnings.NoTracksSelected="Você deve selecionar pelo menos uma faixa" @@ -1331,5 +1339,40 @@ PluginManager.Section.Discover="Explorar" PluginManager.Section.Manage="Instalados" PluginManager.Section.Updates="Atualizações" -PluginManager.Section.Manage.Title="Gerenciar plugins ativos" +PluginManager.Section.Manage.Title="Instalados" +PluginManager.Section.Manage.Description="Gerencie os seus plugins instalados no momento." +PluginManager.Section.Manage.NoPlugins="Nenhum plugin encontrado." +PluginManager.Section.Errors.Title="Erros" +PluginManager.Section.Errors.Description="Falha ao carregar estes plugins. Certifique-se de que eles estão atualizados e são compatíveis com esta versão do OBS Studio." +PluginManager.Section.Missing.Title="Ausente" +PluginManager.Section.Missing.Description="Estes plugins já estavam instalados, mas não foram encontrados." +PluginManager.Button.Enable="Ativar %1 plugin" +PluginManager.Status.Legacy="Legado" +PluginManager.Status.Disabled="Desativado" +PluginManager.Status.Error="Erro" +PluginManager.Status.Missing="Ausente" +PluginManager.Status.Legacy.Description="Este plugin está instalado em um local que irá parar de funcionar no futuro. <a href=\"%1\">Saiba mais</a>" Accessible.Widget.Name.AlignmentSelector="Seletor de alinhamento" +EncoderMissing.Title="Codificadores faltando" +EncoderMissing.Text="Os seguintes codificadores configurados estão faltando:\n<ul>\n%1</ul><br>\nVeja o <a href=\"%2\">Artigo da Base de Conhecimento</a> para mais informações." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (código: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Desconhecido" +EncoderMissing.MissingModule="Módulo \"%1\" não carregado" +EncoderMissing.NVENC.TestProgramFailedStartup="Falha ao iniciar programa de verificação do NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Falha no processo de verificação do NVENC, código de saída: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Falha na leitura da saída do processo de verificação do NVENC, código de saída: %1" +EncoderMissing.NVENC.TestProgramError="Falha na verificação do NVENC pelo motivo: %1" +EncoderMissing.NVENC.NoDevices="Nenhuma GPU da NVIDIA encontrada" +EncoderMissing.NVENC.Unsupported.Kepler="A arquitetura (Kepler) da sua GPU (%1) não é mais suportada. Por favor, utilize o OBS 30.2 ou uma versão anterior." +EncoderMissing.NVENC.Reason.NvmlLoad="Falha ao carregar a biblioteca NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Falha ao inicializar NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Falha ao carregar a biblioteca NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Falha ao inicializar NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Versão do NVENC vazia" +EncoderMissing.NVENC.Reason.CudaLoad="Falha ao carregar a biblioteca CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Falha ao inicializar CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Versão CUDA inválida/ausente" +EncoderMissing.NVENC.Reason.DriverOutdated="Driver desatualizado" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Nenhum dispositivo NVIDIA com suporte NVENC encontrado" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Limite de sessão do codificador excedido" +EncoderMissing.NVENC.Reason.AV1Unsupported="A codificação AV1 não é suportada por nenhuma GPU NVIDIA do sistema"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/pt-PT.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/pt-PT.ini
Changed
@@ -126,6 +126,10 @@ CrashHandling.Buttons.LaunchNormal="Excecutar em Modo normal" CrashHandling.Errors.UploadJSONError="Ocorreu um erro ao tentar carregar o ficheiro de registo de falhas mais recente. Por favor, tente novamente mais tarde" CrashHandling.Errors.Title="Erro as carregar o ficheiro de registo de falhas" +PluginFailure.Dialog.Title="Erros de plugins" +PluginFailure.Labels.Text="O OBS Studio não conseguiu carregar todos os plugins de terceiros. \n\nMais detalhes estão disponíveis no gestor de plugins." +PluginFailure.Dialog.Continue="Ignorar" +PluginFailure.Dialog.Open="Abrir gestor de plugins" SafeMode.Restart="Deseja reiniciar o OBS em modo de segurança (plugins de terceiros, scripts e WebSockets desativados)?" SafeMode.RestartNormal="Deseja reiniciar o OBS em modo normal?" ChromeOS.Title="Plataforma não suportada" @@ -504,12 +508,14 @@ Basic.Main.PreviewDisabled="A antevisão está desativada" Basic.SourceSelect="Adicionar fonte" Basic.SourceSelect.SelectType="Tipo de fonte" -Basic.SourceSelect.Recent="Adicionada recentemente" -Basic.SourceSelect.NewSource="Criar nova fonte" -Basic.SourceSelect.Existing="Adicionar fonte existente" +Basic.SourceSelect.Recent="Criados recentemente" +Basic.SourceSelect.Description="Selecione a(s) fonte(s) a adicionar à sua cena atual." +Basic.SourceSelect.NewSource="Adicionar um novo %1" +Basic.SourceSelect.AddExisting="Adicionar %1 existente" +Basic.SourceSelect.NoSelection="Adicionar existente" Basic.SourceSelect.CreateButton="Criar nova" Basic.SourceSelect.AddVisible="Tornar a fonte visível" -Basic.SourceSelect.NoExisting="Sem fontes %1" +Basic.SourceSelect.NoExisting="Ainda não possui nenhuma fonte de %1 existente." Basic.SourceSelect.Accessible.SourceName="Nome da fonte" Basic.SourceSelect.Accessible.Existing="Adicionar fonte existente" Basic.SourceSelect.Deprecated.Create="Este tipo de fonte está marcado como obsoleto e poderá ser removido no futuro." @@ -1137,6 +1143,7 @@ Basic.AdvAudio.Monitoring="Monitorização de áudio" Basic.AdvAudio.Monitoring.None="Monitor desligado" Basic.AdvAudio.Monitoring.MonitorOnly="Só monitor (silenciar saída)" +Basic.AdvAudio.Monitoring.Both="Monitorização ativada" Basic.AdvAudio.MonitoringSource="Monitorização de áudio para '%1'" Basic.AdvAudio.AudioTracks="Pistas" Basic.Settings.Hotkeys="Atalhos" @@ -1173,6 +1180,8 @@ Unmute="Ativar som" Push-to-mute="Premir-para-silenciar" Push-to-talk="Premir-para-falar" +MonitorOn="Ativar monitorização" +MonitorOff="Desativar monitorização" SceneItemShow="Mostrar '%1'" SceneItemHide="Ocultar '%1'" OutputWarnings.NoTracksSelected="Tem de selecionar pelo menos uma pista" @@ -1301,7 +1310,7 @@ YouTube.Errors.errorExecutingTransition="A transição falhou devido a um erro da área administrativa. Por favor, tente novamente daqui a alguns segundos." YouTube.Errors.errorStreamInactive="O YouTube não está a receber dados da sua transmissão. Por favor, verifique a sua configuração e tente novamente." YouTube.Errors.invalidTransition="A transição tentada foi inválida. Isto pode ocorrer devido ao fluxo não ter terminado uma transição anterior. Por favor, aguarde alguns segundos e tente novamente." -YouTube.DocksRemoval.Title="Limpar docas de navegador legadas do YouTube" +YouTube.DocksRemoval.Title="Limpar docas de navegador obsoletas do YouTube" YouTube.DocksRemoval.Text="Estas docas de navegador serão removidas por serem obsoletas:\n\n%1\nEm vez disto, use \"Docas/Sala de controle ao vivo do YouTube\"." ConfigDownload.WarningMessageTitle="Aviso" FailedToStartStream.MissingConfigURL="Nenhum URL de configuração disponível para o serviço atual" @@ -1337,5 +1346,25 @@ PluginManager.Section.Discover="Navegar" PluginManager.Section.Manage="Instalado" PluginManager.Section.Updates="Atualizações" -PluginManager.Section.Manage.Title="Gerir plugins ativados" +PluginManager.Section.Manage.Title="Instalado" +PluginManager.Section.Manage.Description="Gerir os seus plugins atualmente instalados." +PluginManager.Section.Manage.NoPlugins="Nenhum plugin encontrado." +PluginManager.Section.Errors.Title="Erros" +PluginManager.Section.Errors.Description="Não foi possível carregar estes plugins. Certifique-se de que estão atualizados e são compatíveis com esta versão do OBS Studio." +PluginManager.Section.Missing.Title="Em falta" +PluginManager.Section.Missing.Description="Estes plugins foram instalados anteriormente, mas já não podem ser encontrados." +PluginManager.Button.Enable="Ativar plugin %1" +PluginManager.Status.Legacy="Obsoleto" +PluginManager.Status.Disabled="Desativado" +PluginManager.Status.Error="Erro" +PluginManager.Status.Missing="Em falta" +PluginManager.Status.Legacy.Description="Este plugin está instalado num local que deixará de funcionar no futuro. <a href=\"%1\">Saber mais</a>" Accessible.Widget.Name.AlignmentSelector="Seletor de alinhamento" +EncoderMissing.Title="Codificadores em falta" +EncoderMissing.Text="Estão em falta os seguintes codificadores configurados:\n<ul>\n%1</ul><br>\nConsulte o <a href=\"%2\">artigo da Base de Conhecimentos</a> para obter mais informações." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (código: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Desconhecido" +EncoderMissing.MissingModule="Módulo \"%1\" não carregado" +EncoderMissing.NVENC.Reason.DriverOutdated="Driver desatualizado" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Limite de sessão do codificador excedido" +EncoderMissing.NVENC.Reason.AV1Unsupported="A codificação AV1 não é suportada por nenhuma das GPUs NVIDIA do sistema."
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ro-RO.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ro-RO.ini
Changed
@@ -1202,4 +1202,3 @@ PluginManager.Section.Discover="Răsfoiește" PluginManager.Section.Manage="Instalate" PluginManager.Section.Updates="Actualizări" -PluginManager.Section.Manage.Title="Gestionează pluginurile activate"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ru-RU.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ru-RU.ini
Changed
@@ -126,6 +126,10 @@ CrashHandling.Buttons.LaunchNormal="Запустить в обычном режиме" CrashHandling.Errors.UploadJSONError="Произошла ошибка при попытке отправки последнего журнала. Пожалуйста, повторите попытку через несколько секунд." CrashHandling.Errors.Title="Ошибка отправки журнала ошибки" +PluginFailure.Dialog.Title="Ошибки плагина" +PluginFailure.Labels.Text="OBS Studio не смог загрузить все сторонние плагины.\n\nПодробности доступны в менеджере плагинов." +PluginFailure.Dialog.Continue="Отклонить" +PluginFailure.Dialog.Open="Открыть менеджер плагинов" SafeMode.Restart="Хотите перезапустить OBS в безопасном режиме (с отключением сторонних плагинов, скриптов и веб-сокетов)?" SafeMode.RestartNormal="Хотите перезапустить OBS в обычном режиме?" ChromeOS.Title="Неподдерживаемая платформа" @@ -508,12 +512,14 @@ Basic.Main.PreviewDisabled="Предпросмотр в данный момент отключён" Basic.SourceSelect="Добавить источник" Basic.SourceSelect.SelectType="Тип источника" -Basic.SourceSelect.Recent="Недавно добавлено" -Basic.SourceSelect.NewSource="Создать новый источник" -Basic.SourceSelect.Existing="Добавить существующий источник" +Basic.SourceSelect.Recent="Недавно созданные" +Basic.SourceSelect.Description="Выберите источники для добавления в текущую сцену." +Basic.SourceSelect.NewSource="Добавить новый %1" +Basic.SourceSelect.AddExisting="Добавить существующих: %1" +Basic.SourceSelect.NoSelection="Добавить существующих: " Basic.SourceSelect.CreateButton="Создать новый" Basic.SourceSelect.AddVisible="Сделать источник видимым" -Basic.SourceSelect.NoExisting="Нет существующих источников %1" +Basic.SourceSelect.NoExisting="У вас пока нет существующих источников %1." Basic.SourceSelect.Accessible.SourceName="Имя источника" Basic.SourceSelect.Accessible.Existing="Добавить существующий источник" Basic.SourceSelect.Deprecated.Create="Этот тип источника помечен как устаревший и может быть удален в будущем." @@ -1202,6 +1208,8 @@ Unmute="Включить звук" Push-to-mute="Отключать звук по нажатии" Push-to-talk="Включать звук по нажатии" +MonitorOn="Включить мониторинг" +MonitorOff="Отключить мониторинг" SceneItemShow="Показать «%1»" SceneItemHide="Скрыть «%1»" OutputWarnings.NoTracksSelected="Вы должны выбрать хотя бы одну звуковую дорожку" @@ -1368,5 +1376,40 @@ PluginManager.Section.Discover="Поиск" PluginManager.Section.Manage="Установленные" PluginManager.Section.Updates="Обновления" -PluginManager.Section.Manage.Title="Управление включенными плагинами" +PluginManager.Section.Manage.Title="Установлено" +PluginManager.Section.Manage.Description="Управляйте своими установленными плагинами." +PluginManager.Section.Manage.NoPlugins="Плагины не найдены." +PluginManager.Section.Errors.Title="Ошибки" +PluginManager.Section.Errors.Description="Эти плагины не удалось загрузить. Убедитесь, что они актуальны и совместимы с этой версией OBS Studio." +PluginManager.Section.Missing.Title="Отсутствует" +PluginManager.Section.Missing.Description="Эти плагины были ранее установлены, но больше их нельзя найти." +PluginManager.Button.Enable="Включить плагин %1" +PluginManager.Status.Legacy="Устаревший" +PluginManager.Status.Disabled="Отключено" +PluginManager.Status.Error="Ошибка" +PluginManager.Status.Missing="Отсутствует" +PluginManager.Status.Legacy.Description="Этот плагин установлен в расположение, которое перестанет работать в будущем. <a href=\"%1\">Подробнее</a>" Accessible.Widget.Name.AlignmentSelector="Выбор выравнивания" +EncoderMissing.Title="Отсутствующие кодировщики" +EncoderMissing.Text="Следующие настроенные кодировщики отсутствуют:\n<ul>\n%1</ul><br>\nПодробнее см. в <a href=\"%2\">статье базы знаний</a>." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (код: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Неизвестно" +EncoderMissing.MissingModule="Модуль «%1» не загружен" +EncoderMissing.NVENC.TestProgramFailedStartup="Сбой запуска проверочной программы NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Сбой процесса проверки NVENC, код выхода: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Сбой чтения вывода процесса проверки NVENC, код выхода: %1" +EncoderMissing.NVENC.TestProgramError="Проверка NVENC завершилась ошибкой по причине: %1" +EncoderMissing.NVENC.NoDevices="Графический процессор NVIDIA не найден" +EncoderMissing.NVENC.Unsupported.Kepler="Архитектура (Kepler) вашего ГП (%1) больше не поддерживается. Пожалуйста, используйте OBS 30.2 или более раннюю версию." +EncoderMissing.NVENC.Reason.NvmlLoad="Не удалось загрузить библиотеку NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Не удалось инициализировать NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Не удалось загрузить библиотеку NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Не удалось инициализировать NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Версия NVENC не указана" +EncoderMissing.NVENC.Reason.CudaLoad="Не удалось загрузить библиотеку CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Не удалось инициализировать CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Неверная или отсутствующая версия CUDA" +EncoderMissing.NVENC.Reason.DriverOutdated="Устаревший драйвер" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Не найдены устройства NVIDIA с поддержкой NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Превышен предел сеансов кодировщика" +EncoderMissing.NVENC.Reason.AV1Unsupported="Кодирование AV1 не поддерживается ни одним из графических процессоров NVIDIA в системе"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/sk-SK.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/sk-SK.ini
Changed
@@ -121,6 +121,10 @@ CrashHandling.Buttons.LaunchNormal="Spustiť v normálnom režime" CrashHandling.Errors.UploadJSONError="Pri nahrávaní najnovšieho logu o havárií nastala chyba. Prosím skúste znova neskôr." CrashHandling.Errors.Title="Chyba pri nahrávaní logu havárie" +PluginFailure.Dialog.Title="Chyby pluginu" +PluginFailure.Labels.Text="OBS Štúdio nebolo schopné načítať všetky pluginy tretích strán.\n\nViac detailov je dostupných v správcovi pluginov." +PluginFailure.Dialog.Continue="Zamietnuť" +PluginFailure.Dialog.Open="Otvoriť správcu pluginov" SafeMode.Restart="Chcete reštartovať OBS v núdzovom režime (pluginy tretích strán, skriptovanie, a websockety vypnuté)?" SafeMode.RestartNormal="Chcete reštartovať OBS v normálnom režime?" ChromeOS.Title="Nepodporovaná platforma" @@ -498,12 +502,14 @@ Basic.Main.PreviewDisabled="Náhľad je momentálne vypnutý" Basic.SourceSelect="Pridať zdroj" Basic.SourceSelect.SelectType="Typ zdroja" -Basic.SourceSelect.Recent="Nedávno pridané" -Basic.SourceSelect.NewSource="Vytvoriť nový zdroj" -Basic.SourceSelect.Existing="Pridať existujúci zdroj" +Basic.SourceSelect.Recent="Nedávno vytvorené" +Basic.SourceSelect.Description="Vyberte, ktoré zdroje chcete pridať do aktuálnej scény." +Basic.SourceSelect.NewSource="Pridať nový %1" +Basic.SourceSelect.AddExisting="Pridať %1 existujúcich" +Basic.SourceSelect.NoSelection="Pridať existujúci" Basic.SourceSelect.CreateButton="Vytvoriť nový" Basic.SourceSelect.AddVisible="Zviditeľniť zdroj" -Basic.SourceSelect.NoExisting="Žiadne existujúce %1 zdroje" +Basic.SourceSelect.NoExisting="Zatiaľ nemáte žiadne existujúce %1 zdroje." Basic.SourceSelect.Accessible.SourceName="Názov zdroja" Basic.SourceSelect.Accessible.Existing="Pridať existujúci zdroj" Basic.SourceSelect.Deprecated.Create="Tento typ zdroja je označený ako zastaralý a môže byť odstránený v budúcnosti." @@ -1141,6 +1147,7 @@ Basic.AdvAudio.Monitoring="Monitorovanie zvuku" Basic.AdvAudio.Monitoring.None="Vypnuté monitorovanie" Basic.AdvAudio.Monitoring.MonitorOnly="Iba monitorovanie (žiaden výstup)" +Basic.AdvAudio.Monitoring.Both="Monitorovanie zapnuté" Basic.AdvAudio.MonitoringSource="Monitorovanie zvuku pre '%1'" Basic.AdvAudio.AudioTracks="Stopy" Basic.Settings.Hotkeys="Klávesové skratky" @@ -1175,6 +1182,8 @@ Unmute="Zrušiť stlmenie" Push-to-mute="Stlač-pre-stíšenie" Push-to-talk="Stlač-pre-rozprávanie" +MonitorOn="Zapnúť monitorovanie" +MonitorOff="Vypnúť monitorovanie" SceneItemShow="Zobraz '%1'" SceneItemHide="Skry '%1'" OutputWarnings.NoTracksSelected="Musíte vybrať aspoň jednu zvukovú stopu" @@ -1338,5 +1347,40 @@ PluginManager.Section.Discover="Prehliadať" PluginManager.Section.Manage="Nainštalovaný" PluginManager.Section.Updates="Aktualizácie" -PluginManager.Section.Manage.Title="Spravovať zapnuté pluginy" +PluginManager.Section.Manage.Title="Nainštalované" +PluginManager.Section.Manage.Description="Spravujte svoje aktuálne nainštalované pluginy." +PluginManager.Section.Manage.NoPlugins="Nenájdené žiadne pluginy." +PluginManager.Section.Errors.Title="Chyby" +PluginManager.Section.Errors.Description="Tieto pluginy sa nepodarilo načítať. Uistite sa že sú aktuálne a kompatibilné s touto verziou OBS Štúdia." +PluginManager.Section.Missing.Title="Chýbajúce" +PluginManager.Section.Missing.Description="Tieto pluginy boli predtým nainštalované, ale teraz ich nie je možné nájsť." +PluginManager.Button.Enable="Zapnúť plugin %1" +PluginManager.Status.Legacy="Zastarané" +PluginManager.Status.Disabled="Vypnutý" +PluginManager.Status.Error="Chyba" +PluginManager.Status.Missing="Chýbajúce" +PluginManager.Status.Legacy.Description="Tento plugin je nainštalovaný na mieste, ktoré prestane fungovať v budúcnosti. <a href=\"%1\">Zistiť viac</a>" Accessible.Widget.Name.AlignmentSelector="Výber zarovnania" +EncoderMissing.Title="Chýbajúce enkodéry" +EncoderMissing.Text="Následujúce konfigurované enkodéry chýbajú:\n<ul>\n%1</ul><br>\nPozrite si <a href=\"%2\">článok databázy znalostí</a> pre viac informácií." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (kód: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Neznámy" +EncoderMissing.MissingModule="Modul \"%1\" nie je načítaný" +EncoderMissing.NVENC.TestProgramFailedStartup="Zlyhanie štartu programu NVENC kontroly" +EncoderMissing.NVENC.TestProgramExitWithError="Zlyhanie procesu NVENC kontroly, výstupný kód: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Zlyhanie čítania výstupu procesu NVENC kontroly, výstupný kód: %1" +EncoderMissing.NVENC.TestProgramError="NVENC kontrola zlyhala s dôvodom: %1" +EncoderMissing.NVENC.NoDevices="Nenájdená žiadna NVIDIA GPU" +EncoderMissing.NVENC.Unsupported.Kepler="Architektúra (Kepler) vašej GPU (%1) už nie je podporovaná. Prosím používajte OBS 30.2 alebo skorší namiesto tejto verzie." +EncoderMissing.NVENC.Reason.NvmlLoad="Zlyhalo načítanie NVML knižnice" +EncoderMissing.NVENC.Reason.NvmlInit="Zlyhala inicializácia NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Zlyhalo načítanie NVENC knižnice" +EncoderMissing.NVENC.Reason.NvencInit="Zlyhala inicializácia NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC verzia je prázdna" +EncoderMissing.NVENC.Reason.CudaLoad="Zlyhalo načítanie CUDA knižnice" +EncoderMissing.NVENC.Reason.CudaInit="Zlyhala inicializácia CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Neplatná/chýbajúca CUDA verzia" +EncoderMissing.NVENC.Reason.DriverOutdated="Zastaraný ovládač" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Nenájdené žiadne NVIDIA zariadenia s NVENC podporou" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Prekročený limit relácie enkodéra" +EncoderMissing.NVENC.Reason.AV1Unsupported="AV1 enkódovanie nie je podporované žiadnou systémovou NVIDIA GPU"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/sl-SI.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/sl-SI.ini
Changed
@@ -54,6 +54,8 @@ Right="Desno" Top="Zgoraj" Bottom="Spodaj" +Width="Širina" +Height="Višina" Reset="Ponastavi" Hours="urah" Minutes="minutah" @@ -121,6 +123,10 @@ CrashHandling.Buttons.LaunchNormal="Zagon v normalnem načinu" CrashHandling.Errors.UploadJSONError="Pri nalaganju zadnjega dnevnika o sesutju se je zgodila napaka. Znova poskusite kasneje." CrashHandling.Errors.Title="Napaka pri nalaganju dnevnika o sesutju" +PluginFailure.Dialog.Title="Napake vtičnikov" +PluginFailure.Labels.Text="OBS Studio ni mogel naložiti vseh vtičnikov tretjih oseb.\n\nVeč podrobnosti je na voljo v upravljalniku vtičnikov." +PluginFailure.Dialog.Continue="Opusti" +PluginFailure.Dialog.Open="Odpri upravljalnika vtičnikov" SafeMode.Restart="Ali želite ponovno zagnati OBS v varnem načinu (z onemogočenimi vstavki, skriptami in spletnimi vtičnicami tretjih strani)?" SafeMode.RestartNormal="Ali želite ponovno zagnati OBS v navadnem načinu?" ChromeOS.Title="Nepodprta platforma" @@ -334,6 +340,7 @@ ConfirmBWTest.Title="Zaženi preizkus pasovne širine?" ConfirmBWTest.Text="OBS imate nastavljen v načinu preizkusa pasovne širine. Ta način omogoča preizkušanje omrežja brez oddajanja v živo. Ko končate s preizkusom, ga boste morali onemogočiti, da si bodo gledalci lahko ogledali vaš pretok.\n\nŽelite nadaljevati?" ConfirmExit.Title="" +ConfirmExit.Text="OBS je trenutno še dejaven. Vsi pretoki/snemanja bodo ustavljena." ConfirmRemove.Title="Potrdite odstranitev" ConfirmRemove.Text="Ali res želite odstraniti '%1'?" ConfirmRemove.TextMultiple="Ali res želite odstraniti %1 predmetov?" @@ -473,6 +480,7 @@ VolControl.Mute="Utišaj '%1'" VolControl.Properties="Lastnosti za '%1'" VolControl.UnassignedWarning.Title="Nedodeljen zvočni vir" +VolControl.UnassignedWarning.Text="»%1« ni dodeljen nobeni zvočni sledi in ne bo slišen v pretokih ali posnetkih.\n\nČe želite dodeliti zvočni vir sledi, v menijski vrstici odprite Napredne lastnosti zvoka preko menija Uredi ali gumba zobnika v orodni vrstici sidrišča mešalnika." Basic.Main.AddSceneDlg.Title="Dodaj prizor" Basic.Main.AddSceneDlg.Text="Vnesite ime prizora" Basic.Main.DefaultSceneName.Text="%1. prizor" @@ -484,6 +492,7 @@ Basic.Main.RemigrateSceneCollection.CannotMigrate.Active="Ko so izhodi aktivni, ni mogoče posodobiti ločljivosti zbirke scen." Basic.Main.RemigrateSceneCollection.CannotMigrate.UnknownBaseResolution="Ločljivosti zbirke scen ni bilo mogoče posodobiti. Izvirna ločljivost ni poznana." Basic.Main.RemigrateSceneCollection.CannotMigrate.FailedVideoReset="Ponastavitev ni možna. Sprememba ločljivosti OBS ni uspela." +Basic.Main.RemigrateSceneCollection.CannotMigrate.BaseResolutionMatches="Ponastavitev ni mogoča: trenutna ločljivost je že osnovna ločljivost zbirke prizorov." AddProfile.Title="Dodaj profil" AddProfile.Text="Vnesite ime profila" AddProfile.WizardCheckbox="Prikaži čarovnika za samodejno konfiguracijo" @@ -491,7 +500,16 @@ Basic.Main.MixerRename.Title="Preimenuj zvočni vir" Basic.Main.MixerRename.Text="Vnesite ime zvočnega vira" Basic.Main.PreviewDisabled="Predogled je trenutno onemogočen" +Basic.SourceSelect="Dodaj vir" +Basic.SourceSelect.SelectType="Vrsta vira" +Basic.SourceSelect.Recent="Nedavno ustvarjen" +Basic.SourceSelect.NewSource="Dodaj nov %1" +Basic.SourceSelect.NoSelection="Dodaj obstoječega" +Basic.SourceSelect.CreateButton="Ustvari novega" Basic.SourceSelect.AddVisible="Prikaži vir" +Basic.SourceSelect.Accessible.SourceName="Ime vira" +Basic.SourceSelect.Accessible.Existing="Dodaj obstoječi vir" +Basic.SourceSelect.Deprecated.Create="Ta vir je označen kot zastarel in bo v prihodnosti morda odstranjen." Basic.Main.Sources.Visibility="Vidnost" Basic.Main.Sources.VisibilityDescription="Nadzira vidnost '%1' v platnu" Basic.Main.Sources.Lock="Zakleni" @@ -541,13 +559,20 @@ Basic.TransformWindow.Size="Velikost" Basic.TransformWindow.Width="Širina" Basic.TransformWindow.Height="Višina" +Basic.TransformWindow.Alignment="Poravnava" +Basic.TransformWindow.BoundsType="Vrsta okvirja" +Basic.TransformWindow.BoundsAlignment="Poravnava okvirja" +Basic.TransformWindow.Bounds="Okvir" Basic.TransformWindow.BoundsWidth="Širina okvirja" Basic.TransformWindow.BoundsHeight="Višina okvirja" +Basic.TransformWindow.CropToBounds="Obreži okvir" Basic.TransformWindow.Crop="Obreži" Basic.TransformWindow.CropLeft="Obreži levo" Basic.TransformWindow.CropRight="Obreži desno" Basic.TransformWindow.CropTop="Obreži zgoraj" Basic.TransformWindow.CropBottom="Obreži spodaj" +Basic.TransformWindow.Accessible.PositionX="Položaj X" +Basic.TransformWindow.Accessible.PositionY="Položaj Y" Basic.TransformWindow.Alignment.TopLeft="Zgoraj levo" Basic.TransformWindow.Alignment.TopCenter="Sredina zgoraj" Basic.TransformWindow.Alignment.TopRight="Zgoraj desno" @@ -557,7 +582,11 @@ Basic.TransformWindow.Alignment.BottomLeft="Spodaj levo" Basic.TransformWindow.Alignment.BottomCenter="Sredina spodaj" Basic.TransformWindow.Alignment.BottomRight="Spodaj desno" +Basic.TransformWindow.BoundsType.None="Samodejno" Basic.TransformWindow.BoundsType.MaxOnly="Samo največja velikost" +Basic.TransformWindow.BoundsType.ScaleToWidth="Zapolni širino" +Basic.TransformWindow.BoundsType.ScaleToHeight="Zapolni višino" +Basic.TransformWindow.BoundsType.Stretch="Raztegni" Basic.TransformWindow.Title="Uredi transformacijo za '%1'" Basic.TransformWindow.NoSelectedSource="Noben vir ni izbran" Basic.Main.AddSourceHelp.Title="Ni mogoče dodati vira" @@ -578,6 +607,7 @@ Basic.Main.PauseRecording="Premor snemanja" Basic.Main.UnpauseRecording="Nadaljuj snemanje" Basic.Main.SplitFile="Razdeli datoteko posnetka" +Basic.Main.AddChapterMarker="Dodaj oznako poglavja (samo hibridni mp4/mov)" Basic.Main.StoppingRecording="Zaustavljanje snemanja …" Basic.Main.StopReplayBuffer="Zaustavi medpomnilnik za ponovitve" Basic.Main.StoppingReplayBuffer="Zaustavljanje medp. ponovitve..." @@ -591,6 +621,7 @@ Basic.Main.HideContextBar="Skrij orodno vrstico vira" Basic.Main.StopVirtualCam="Zaustavi virtualne kamere" Basic.Main.Group="%1. skupina" +Basic.Main.NewGroup="Nova skupina" Basic.Main.GroupItems="Združi izbrane predmete" Basic.Main.Ungroup="Razdruži" Basic.Main.GridMode="Mrežni način" @@ -620,6 +651,9 @@ Basic.MainMenu.Edit.Scale.Window="Prilagodi oknu" Basic.MainMenu.Edit.Scale.Canvas="Platno (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Izhod (%1x%2)" +Basic.MainMenu.Edit.Scale.ZoomIn="Povečaj" +Basic.MainMenu.Edit.Scale.ZoomOut="Pomanjšaj" +Basic.MainMenu.Edit.Scale.ResetZoom="Ponastavi povečavo" Basic.MainMenu.Edit.Transform="Preoblikuj (&T)" Basic.MainMenu.Edit.Transform.EditTransform="Ur&edi preobliko …" Basic.MainMenu.Edit.Transform.CopyTransform="Kopiraj preobliko" @@ -656,12 +690,16 @@ Basic.MainMenu.Docks.LockDocks="&Zakleni sidrišča" Basic.MainMenu.Docks.SideDocks="&Sidrišča polne višine" Basic.MainMenu.Docks.CustomBrowserDocks="Sidrišča &brskalnika po meri ..." +Basic.MainMenu.Import="Uvozi …" +Basic.MainMenu.Export="Izvozi …" Basic.MainMenu.SceneCollection="Zbirka prizorov (&S)" Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Profile.Import="Uvozi profil" Basic.MainMenu.Profile.Export="Izvozi profil" Basic.MainMenu.SceneCollection.Import="Uvozi zbirko prizorov" Basic.MainMenu.SceneCollection.Export="Izvozi zbirko prizorov" +Basic.MainMenu.SceneCollection.Remigrate="Ponastavi osnovno ločljivost" +Basic.MainMenu.SceneCollection.Migrate="Nastavi osnovno ločljivost" Basic.MainMenu.Profile.Exists="Profil že obstaja" Basic.MainMenu.Tools="Orodja (&T)" Basic.MainMenu.Help="Pomoč (&H)" @@ -686,6 +724,7 @@ Basic.Settings.ProgramRestart="Program je treba ponovno zagnati, da se te nastavitve uveljavijo." Basic.Settings.ConfirmTitle="Potrdi spremembe" Basic.Settings.Confirm="Imate neshranjene spremembe. Shrani spremembe?" +Basic.Settings.MultitrackVideoDisabledSettings="%1 %2 nadzira nekatere nastavitve pretoka." Basic.Settings.General="Splošno" Basic.Settings.General.Language="Jezik" Basic.Settings.General.Updater="Posodobitve" @@ -751,6 +790,13 @@ Basic.Settings.Appearance.General.Theme="Tema" Basic.Settings.Appearance.General.Variant="Slog" Basic.Settings.Appearance.General.NoVariant="Slogi niso na voljo" +Basic.Settings.Appearance.FontScale="Velikost pisave" +Basic.Settings.Appearance.Density="Gostota" +Basic.Settings.Appearance.Classic="Klasična" +Basic.Settings.Appearance.Compact="Strnjena" +Basic.Settings.Appearance.Normal="Običajna" +Basic.Settings.Appearance.Comfortable="Udobna" +Basic.Settings.Appearance.OptionsWarning="Nekatere možnosti videza za ta slog niso na voljo." Basic.Settings.Stream="Pretok" Basic.Settings.Stream.Destination="Cilj" Basic.Settings.Stream.Custom.UseAuthentication="Uporabi overitev" @@ -1243,3 +1289,10 @@ YouTube.DocksRemoval.Text="Ti zloženi zavihki brskalnika bodo odstranjeni kot opuščeni:\n\n%1\nNamesto tega uporabite »Zavihki/režija YouTube«." ConfigDownload.WarningMessageTitle="Opozorilo" MultitrackVideo.IncompatibleSettings.Title="Nezdružljive nastavitve" +PluginManager.Section.Discover="Brskaj" +PluginManager.Section.Manage="Nameščeno" +PluginManager.Section.Updates="Posodobitve" +PluginManager.Section.Manage.Title="Nameščeno" +PluginManager.Section.Manage.Description="Upravljaj trenutno nameščene vtičnike." +PluginManager.Section.Manage.NoPlugins="Vtičnikov ni bilo mogoče najti." +PluginManager.Section.Errors.Title="Napake"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/sv-SE.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/sv-SE.ini
Changed
@@ -122,6 +122,10 @@ CrashHandling.Buttons.LaunchNormal="Starta i normalt läge" CrashHandling.Errors.UploadJSONError="Ett fel uppstod när den senaste kraschloggen skulle laddas upp. Försök igen senare." CrashHandling.Errors.Title="Fel under uppladdning av kraschlogg" +PluginFailure.Dialog.Title="Fel i insticksprogram" +PluginFailure.Labels.Text="OBS Studio kunde inte läsa in alla insticksprogram från tredje part.\n\nMer information finns i insticksprogramshanteraren." +PluginFailure.Dialog.Continue="Stäng" +PluginFailure.Dialog.Open="Öppna insticksprogramshanteraren" SafeMode.Restart="Vill du starta om OBS i säkert läge (insticksprogram från tredje part, skript och WebSockets inaktiveras)?" SafeMode.RestartNormal="Vill du starta om OBS i normalt läge?" ChromeOS.Title="Plattformen stöds inte" @@ -495,12 +499,14 @@ Basic.Main.PreviewDisabled="Förhandsvisning har för tillfället inaktiverats" Basic.SourceSelect="Lägg till källa" Basic.SourceSelect.SelectType="Källtyp" -Basic.SourceSelect.Recent="Nyligen tillagda" -Basic.SourceSelect.NewSource="Skapa en ny källa" -Basic.SourceSelect.Existing="Lägg till en befintlig källa" +Basic.SourceSelect.Recent="Nyligen skapade" +Basic.SourceSelect.Description="Välj vilka källor som ska läggas till i din aktuella scen." +Basic.SourceSelect.NewSource="Lägg till en ny %1" +Basic.SourceSelect.AddExisting="Lägg till %1 befintliga" +Basic.SourceSelect.NoSelection="Lägg till befintlig" Basic.SourceSelect.CreateButton="Skapa ny" Basic.SourceSelect.AddVisible="Gör källan synlig" -Basic.SourceSelect.NoExisting="Inga befintliga källor av typen %1" +Basic.SourceSelect.NoExisting="Du har ännu inga befintliga källor av typen %1." Basic.SourceSelect.Accessible.SourceName="Källnamn" Basic.SourceSelect.Accessible.Existing="Lägg till en befintlig källa" Basic.SourceSelect.Deprecated.Create="Denna källtyp har markerats som föråldrad och kan tas bort i framtiden." @@ -1170,6 +1176,8 @@ Unmute="Slå på ljud" Push-to-mute="Tryck för att tysta" Push-to-talk="Tryck för att tala" +MonitorOn="Aktivera övervakning" +MonitorOff="Inaktivera övervakning" SceneItemShow="Visa \"%1\"" SceneItemHide="Dölj \"%1\"" OutputWarnings.NoTracksSelected="Du måste välja minst ett spår" @@ -1335,5 +1343,40 @@ PluginManager.Section.Discover="Bläddra" PluginManager.Section.Manage="Installerade" PluginManager.Section.Updates="Uppdateringar" -PluginManager.Section.Manage.Title="Hanterade aktiverade insticksprogram" +PluginManager.Section.Manage.Title="Installerade" +PluginManager.Section.Manage.Description="Hantera dina installerade insticksprogram." +PluginManager.Section.Manage.NoPlugins="Inga insticksprogram hittades." +PluginManager.Section.Errors.Title="Fel" +PluginManager.Section.Errors.Description="Dessa insticksprogram kunde inte läsas in. Se till att de är uppdaterade och kompatibla med denna version av OBS Studio." +PluginManager.Section.Missing.Title="Saknas" +PluginManager.Section.Missing.Description="Dessa insticksprogram var tidigare installerade men går inte längre att hitta." +PluginManager.Button.Enable="Aktivera insticksprogrammet %1" +PluginManager.Status.Legacy="Äldre" +PluginManager.Status.Disabled="Inaktiverad" +PluginManager.Status.Error="Fel" +PluginManager.Status.Missing="Saknas" +PluginManager.Status.Legacy.Description="Detta insticksprogram är installerat på en plats som kommer att sluta fungera i framtiden. <a href=\"%1\">Läs mer</a>" Accessible.Widget.Name.AlignmentSelector="Justeringsväljare" +EncoderMissing.Title="Kodare saknas" +EncoderMissing.Text="Följande konfigurerade kodare saknas:\n<ul>\n%1</ul><br>\nSe <a href=\"%2\">artikeln i kunskapsbasen</a> för mer information." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (kod: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Okänd" +EncoderMissing.MissingModule="Modulen \"%1\" lästes inte in" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC-kontrollprogrammet misslyckades att startas" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC-kontrollprocessen misslyckades, slutkod: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC-kontrollprocessens utmatning misslyckades att läsas, slutkod: %1" +EncoderMissing.NVENC.TestProgramError="NVENC-kontrollen misslyckades med orsaken: %1" +EncoderMissing.NVENC.NoDevices="Inga NVIDIA-grafikprocessorer hittades" +EncoderMissing.NVENC.Unsupported.Kepler="Arkitekturen (Kepler) för din grafikprocessor (%1) stöds inte längre. Använd OBS 30.2 eller tidigare istället." +EncoderMissing.NVENC.Reason.NvmlLoad="Misslyckades att läsa in NVML-biblioteket" +EncoderMissing.NVENC.Reason.NvmlInit="Misslyckades att initialisera NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Misslyckades att läsa in NVENC-biblioteket" +EncoderMissing.NVENC.Reason.NvencInit="Misslyckades att initialisera NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC-versionen är tom" +EncoderMissing.NVENC.Reason.CudaLoad="Misslyckades att läsa in CUDA-biblioteket" +EncoderMissing.NVENC.Reason.CudaInit="Misslyckades att initialisera CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Ogiltig/saknad CUDA-version" +EncoderMissing.NVENC.Reason.DriverOutdated="Föråldrad drivrutin" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Inga NVIDIA-enheter med NVENC-stöd hittades" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Gränsen för kodarsession överskreds" +EncoderMissing.NVENC.Reason.AV1Unsupported="AV1-kodning stöds inte av någon av systemets NVIDIA-grafikprocessorer"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/te-IN.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/te-IN.ini
Changed
@@ -7,8 +7,8 @@ Discard="తొలఁగించు" Disable="రద్దు చేయబడింది" Yes="అవును" -No="కాదు" -Add="యాడ్ చేయి " +No="లేదు " +Add="చేర్చు" Remove="తొలఁగించు" Rename="పేరు మార్చు" Interact="ఇంటరాక్ట్ చేయి " @@ -36,25 +36,25 @@ Projector.Title.Scene="సీన్: %1" Projector.Title.Source=" సోర్స్: %1" Projector.Title.Multiview="మల్టీవ్యూ" -Projector.ResizeWindowToContent="కంటెంట్కు విండోని సరిపోల్చండి" -Clear="క్లియర్ చేయండి" +Projector.ResizeWindowToContent="విండోని కంటెంట్కు కుదుర్చు" +Clear="క్లియర్" Revert="మార్పులను తిరస్కరించు" Show="చూపించు" Hide="దాచు" -UnhideAll="దాచవద్దు అన్ని" +UnhideAll="అన్నింటినీ అన్హైడ్ చేయండి" Untitled="పేరులేని" New="కొత్త" -Duplicate="నకిలీ" +Duplicate="డూప్లికేట్" Enable="ఎనేబుల్" DisableOSXVSync="macOS V-Sync డిసేబుల్" ResetOSXVSyncOnExit="నిష్క్రమణపై macOS V-sync ని రీసెట్ చేయండి" HighResourceUsage="ఎన్కోడింగ్ ఓవర్లోడ్! వీడియో సెట్టింగులను తిరస్కరించడం లేదా వేగవంతమైన ఎన్కోడింగ్ ప్రీసెట్ను ఉపయోగించడం పరిగణించండి." -Transition="పరివర్తన" +Transition="ట్రాన్సిషన్" QuickTransitions="శీఘ్ర పరివర్తనాలు" -FadeToBlack="నలుపు రంగులోకి మారండి" +FadeToBlack="నలుపు రంగులోకి ఫేడ్ " Left="ఎడమ" Right="కుడి" -Top="టాప్" +Top="పైన" Bottom="దిగువ" Width="వెడల్పు" Height="ఎత్తు" @@ -67,12 +67,12 @@ Import="దిగుమతి" Export="ఎగుమతి" Copy="కాపీ" -Paste="అతికించండి" -PasteReference="అతికించండి (సూచన)" -PasteDuplicate="అతికించండి (నకిలీ)" +Paste="అతికించు " +PasteReference="అతికించు (రిఫరెన్స్ గా)" +PasteDuplicate="అతికించు (డూప్లికేట్ గా)" RemuxRecordings="రీమిక్స్ రికార్డింగ్లు" Next="తరువాత" -Back="వెనుకకు" +Back="వెనక్కి" Defaults="డిఫాల్ట్లు" RestoreDefaults="డిఫాల్ట్లు" HideMixer="మిక్సర్ లో దాచు " @@ -99,7 +99,7 @@ ShowOnStartup="తెరిచినప్పుడు చూపు " OpenFile="ఫైల్ తెరు " AddScene="సీన్ జోడించు " -AddSource="జోడించండి" +AddSource="సోర్స్ జోడించు " RemoveScene="ఎంచుకున్న సీన్ తీసివేయి " RemoveSource="ఎంచుకున్న సోర్స్(లను) తీసివేయి " MoveSceneUp="సీన్ని పైకి జరుపు" @@ -134,3 +134,28 @@ Wine.Title="Wine గుర్తించబడింది " Wine.Text="Wineలో OBSను రన్ చేయడానికి సపోర్ట్ లేదు , మరియు క్యాప్చర్ లేదా డివైస్ సోర్సెస్ వంటి అనేక ఫీచర్లు పనిచేయవు లేదా పరిమిత సామర్థ్యంతో మాత్రమే పనిచేస్తాయి. <br><br>దానికి బదులుగా, OBS యొక్క నేటివ్ వెర్షన్ను రన్ చేయమని సిఫార్సు చేయబడింది, ఉదాహరణకు <a href='https://flathub.org/apps/details/com.obsproject.Studio'>మా Flatpak version </a> లేదా మీ ఆపరేటింగ్ సిస్టమ్ ప్యాకేజీలు." DockCloseWarning.Title="డాక్ అయ్యే విండో ను మూసివేస్తుంది" +ExtraBrowsers="స్వయ బ్రౌజింగ్ డాక్" +ExtraBrowsers.DockName="డాక్ పేరు" +Auth.Authing.Title="ధ్రువీకరిస్తుంది" +Auth.Authing.Text=" %1 తో ధ్రువీకరిస్తుంది, వేచి ఉండండి" +Auth.AuthFailure.Title="ధ్రువీకరణ విఫలం" +Auth.AuthFailure.Text=" %1:\n\n%2: %3 తో ధ్రువీకరణ విఫలం అయింది" +Auth.InvalidScope.Title="ధ్రువీకరణ అవసరం" +Auth.InvalidScope.Text="%1 తో ధ్రువీకరణ చేయడానికి రిక్వైర్మెంట్స్ మారాయి , కొన్ని ఫీచర్లు అందుబాటులో ఉండకపోవచ్చు" +Auth.LoadingChannel.Title="చానల్ సమాచారం లోడ్ అవుతోంది" +Auth.LoadingChannel.Text="%1 కోసం చానల్ సమాచారం లో చేస్తుంది , వేచి ఉండండి" +Auth.LoadingChannel.Error="చానల్స్ సమాచారం పొందలేకపోతోంది" +Auth.ChannelFailure.Title="ఛానల్ లోడ్ చేయడంలో విఫలం" +Auth.ChannelFailure.Text="%1\n\n%2: %3 కోసం ఛానల్ సమాచారం లోడ్ చేయడంలో విఫలం" +Auth.Chat="చాట్ " +Auth.StreamInfo="స్ట్రీమ్ సమాచారం" +TwitchAuth.Stats="Twitch స్టాట్స్ " +TwitchAuth.Feed="Twitch యాక్టివిటీ ఫీడ్" +BandwidthTest.Region="ప్రాంతం" +BandwidthTest.Region.US="యునైటెడ్ స్టేట్స్" +BandwidthTest.Region.EU="ఐరోపా" +BandwidthTest.Region.Asia="ఆసియా" +BandwidthTest.Region.Other="ఇతర" +Basic.AutoConfig="స్వయంచాలక కాన్ఫిగరేషన్ మార్గదర్శి" +Basic.AutoConfig.ApplySettings="సెట్టింగ్లను అప్లై చెయ్" +Basic.AutoConfig.StartPage="యూసేజ్ సమాచారం "
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/th-TH.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/th-TH.ini
Changed
@@ -498,7 +498,16 @@ Basic.Main.MixerRename.Title="เปลี่ยนชื่อแหล่งเสียง" Basic.Main.MixerRename.Text="โปรดใส่ชื่อให้กับแหล่งเสียง" Basic.Main.PreviewDisabled="ภาพตัวอย่างถูกปิดใช้งานในขณะนี้" +Basic.SourceSelect="เพิ่มเนื้อหา" +Basic.SourceSelect.SelectType="ประเภทเนื้อหา" +Basic.SourceSelect.Recent="สร้างขึ้นล่าสุด" +Basic.SourceSelect.Description="เลือกแหล่งที่คุณต้องการเพิ่มลงในฉากปัจจุบัน" +Basic.SourceSelect.NewSource="เพิ่ม %1 ใหม่" +Basic.SourceSelect.AddExisting="เพิ่มที่มีอยู่ %1" +Basic.SourceSelect.NoSelection="เพิ่มที่มีอยู่" +Basic.SourceSelect.CreateButton="สร้างใหม่" Basic.SourceSelect.AddVisible="แสดงแหล่ง" +Basic.SourceSelect.Accessible.SourceName="ชื่อเนื้อหา" Basic.Main.Sources.Visibility="ความชัดเจน" Basic.Main.Sources.VisibilityDescription="ควบคุมการมองเห็น '%1' ในแคนวาส" Basic.Main.Sources.Lock="ล๊อค" @@ -1324,5 +1333,11 @@ PluginManager.Section.Discover="เรียกดู" PluginManager.Section.Manage="ติดตั้งแล้ว" PluginManager.Section.Updates="อัปเดต" -PluginManager.Section.Manage.Title="จัดการปลั๊กอินที่ติดตั้งไว้" Accessible.Widget.Name.AlignmentSelector="ที่เลือกการจัดแนว" +EncoderMissing.Title="ไม่พบตัวเข้ารหัส" +EncoderMissing.Unknown="ไม่ทราบ" +EncoderMissing.NVENC.NoDevices="ไม่พบหน่วยประมวลผลกราฟิก NVIDIA" +EncoderMissing.NVENC.Unsupported.Kepler="สถาปัตยกรรม (Kepler) ของหน่วยประมวลผลกราฟิกของคุณ (%1) ไม่ถูกรองรับอีกต่อไป โปรดใช้ OBS 30.2 หรือเวอร์ชันก่อนหน้าแทน" +EncoderMissing.NVENC.Reason.DriverOutdated="ไดรเวอร์ล้าสมัย" +EncoderMissing.NVENC.Reason.NoSupportedDevices="ไม่พบอุปกรณ์ NVIDIA ที่รองรับ NVENC" +EncoderMissing.NVENC.Reason.AV1Unsupported="การเข้ารหัสแบบ AV1 ไม่ถูกรองรับโดยหน่วยประมวลผลกราฟิก NVIDIA ใด ๆ ในระบบ"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/tr-TR.ini
Changed
@@ -124,6 +124,10 @@ CrashHandling.Buttons.LaunchNormal="Normal Mod'da başlat" CrashHandling.Errors.UploadJSONError="En son çökme günlüğünü yüklemeye çalışırken bir hata oluştu." CrashHandling.Errors.Title="Çökme Günlüğü Yükleme Hatası" +PluginFailure.Dialog.Title="Eklenti Hataları" +PluginFailure.Labels.Text="OBS Studio üçüncü taraf eklentilerin tamamını yükleyemedi.\n\nEklenti yöneticisinde daha fazla ayrıntı bulabilirsiniz." +PluginFailure.Dialog.Continue="Yoksay" +PluginFailure.Dialog.Open="Eklenti Yöneticisi'ni Aç" SafeMode.Restart="OBS'i Güvenli Mod'da yeniden başlatmak ister misin? (3. parti eklentiler, betikler ve WebSocketler kapalı şekilde)" SafeMode.RestartNormal="OBS'i Normal Mod'da yeniden başlatmak ister misin?" ChromeOS.Title="Desteklenmeyen Platform" @@ -495,14 +499,16 @@ Basic.Main.PreviewDisabled="Önizleme şu anda devre dışı" Basic.SourceSelect="Kaynak ekle" Basic.SourceSelect.SelectType="Kaynak Türü" -Basic.SourceSelect.Recent="Son Eklenenler" -Basic.SourceSelect.NewSource="Yeni Kaynak Oluştur" -Basic.SourceSelect.Existing="Mevcut Bir Kaynağı Ekle" +Basic.SourceSelect.Recent="Yakın Zamanda Oluşturuldu" +Basic.SourceSelect.Description="Sahnenize hangi kaynakları eklemek istediğinizi seçin." +Basic.SourceSelect.NewSource="Yeni bir %1 ekle" +Basic.SourceSelect.AddExisting="Var olana %1 ekle" +Basic.SourceSelect.NoSelection="Var olanı ekle" Basic.SourceSelect.CreateButton="Oluştur" Basic.SourceSelect.AddVisible="Kaynağı görünür yap" -Basic.SourceSelect.NoExisting="Mevcut %1 kaynağı yok" +Basic.SourceSelect.NoExisting="Henüz var olan bir %1 kaynağınız yok." Basic.SourceSelect.Accessible.SourceName="Kaynak Adı" -Basic.SourceSelect.Accessible.Existing="Mevcut Bir Kaynağı Ekle" +Basic.SourceSelect.Accessible.Existing="Var olan bir kaynak ekleyin" Basic.SourceSelect.Deprecated.Create="Bu kaynak türü kullanımdan kaldırılmış olarak işaretlenmiştir ve yeni kaynak oluşturulmasına izin verilmemektedir." Basic.Main.Sources.Visibility="Görünürlük" Basic.Main.Sources.VisibilityDescription="'%1' 'in tuvaldeki görünebilirliğini ayarlar" @@ -1181,6 +1187,8 @@ Unmute="Sesi Aç" Push-to-mute="Bas-Sessize Al" Push-to-talk="Bas konuş" +MonitorOn="İzlemeyi etkinleştir" +MonitorOff="İzlemeyi devre dışı bırak" SceneItemShow="'%1' Göster" SceneItemHide="'%1' Gizle" OutputWarnings.NoTracksSelected="En az bir ses parçası seçmelisiniz" @@ -1345,5 +1353,40 @@ PluginManager.Section.Discover="Gözat" PluginManager.Section.Manage="Yüklendi" PluginManager.Section.Updates="Güncellemeler" -PluginManager.Section.Manage.Title="Etkin Eklentileri Yönet" +PluginManager.Section.Manage.Title="Yüklü" +PluginManager.Section.Manage.Description="Şu anda yüklü eklentilerinizi yönetin." +PluginManager.Section.Manage.NoPlugins="Eklenti bulunamadı." +PluginManager.Section.Errors.Title="Hatalar" +PluginManager.Section.Errors.Description="Bu eklentiler yüklenemedi. Güncel olduklarından ve OBS Studio'nun bu sürümüyle uyumlu olduklarından emin olun." +PluginManager.Section.Missing.Title="Kayıp" +PluginManager.Section.Missing.Description="Bu eklentiler daha önce kurulmuştu ancak artık bulunamıyor." +PluginManager.Button.Enable="%1 eklentisini etkinleştir" +PluginManager.Status.Legacy="Eski" +PluginManager.Status.Disabled="Devre Dışı" +PluginManager.Status.Error="Hata" +PluginManager.Status.Missing="Kayıp" +PluginManager.Status.Legacy.Description="Bu eklenti gelecekte çalışmayı durduracak bir konuma kurulur. <a href=\"%1\">Daha Fazla Bilgi Edinin</a>" Accessible.Widget.Name.AlignmentSelector="Hizalam Seçici" +EncoderMissing.Title="Eksik Kodlayıcılar" +EncoderMissing.Text="Aşağıdaki yapılandırılmış kodlayıcılar eksik:\n<ul>\n%1</ul><br>\nDaha fazla bilgi için <a href=\"%2\">Bilgi Tabanı Makalesine</a> bakın." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (kod: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Bilinmeyen" +EncoderMissing.MissingModule="Modül \"%1\" yüklenmedi" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC kontrol programı başlatma hatası" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC kontrol süreci hatası, çıkış kodu: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC kontrol süreci çıkışı okuma hatası, çıkış kodu: %1" +EncoderMissing.NVENC.TestProgramError="NVENC denetimi şu nedenle başarısız oldu: %1" +EncoderMissing.NVENC.NoDevices="NVIDIA GPU bulunamadı" +EncoderMissing.NVENC.Unsupported.Kepler="GPU'nuzun (%1) mimarisi (Kepler) artık desteklenmiyor. Lütfen bunun yerine OBS 30.2 veya önceki sürümünü kullanın." +EncoderMissing.NVENC.Reason.NvmlLoad="NVML kütüphanesi yüklenemedi" +EncoderMissing.NVENC.Reason.NvmlInit="NVML başlatılamadı" +EncoderMissing.NVENC.Reason.NvencLoad="NVENC kütüphanesi yüklenemedi" +EncoderMissing.NVENC.Reason.NvencInit="NVENC başlatılamadı" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC sürümü boş" +EncoderMissing.NVENC.Reason.CudaLoad="CUDA kütüphanesi yüklenemedi" +EncoderMissing.NVENC.Reason.CudaInit="CUDA başlatılamadı" +EncoderMissing.NVENC.Reason.CudaVersion="CUDA sürümü geçersiz ya da eksik" +EncoderMissing.NVENC.Reason.DriverOutdated="Eski sürücü" +EncoderMissing.NVENC.Reason.NoSupportedDevices="NVENC desteği bulunan NVIDIA cihazı bulunamadı" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Kodlayıcı oturum limiti aşıldı" +EncoderMissing.NVENC.Reason.AV1Unsupported="Sistemin NVIDIA GPU'larının hiçbiri AV1 kodlamasını desteklemiyor"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/tt-RU.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/tt-RU.ini
Changed
@@ -39,6 +39,8 @@ Right="Уң" Top="Өстә" Bottom="Аста" +Width="Киңлек" +Height="Биеклек" Reset="Ташлату" Hours="сәгатьтән" Minutes="минуттан" @@ -265,6 +267,7 @@ Basic.MainMenu.Edit="Үзгәртү (&E)" Basic.MainMenu.Edit.Scale.Canvas="Киндер (%1×%2)" Basic.MainMenu.Edit.Order="Тәртип (&O)" +Basic.MainMenu.View="Карау (&V)" Basic.MainMenu.Import="Импортлау..." Basic.MainMenu.Export="Экспортлау..." Basic.MainMenu.Profile="Профиль (&P)"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/ug-CN.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/ug-CN.ini
Changed
@@ -127,6 +127,10 @@ CrashHandling.Buttons.LaunchNormal="ئۆلچەملىك ھالەتتە ئىجرا قىل" CrashHandling.Errors.UploadJSONError="ئەڭ يېڭى يىمىرىلىش كۈندىلىك خاتىرە ھۆججىتىنى يۈكلەشنى سىناۋاتقاندا خاتالىق كۆرۈلدى. سەل تۇرۇپ قايتا سىناڭ." CrashHandling.Errors.Title="يىمىرىلىش خاتىرىسىنى يۈكلەش خاتالىقى" +PluginFailure.Dialog.Title="قىستۇرما خاتالىقى" +PluginFailure.Labels.Text="OBS Studio بارلىق ئۈچىنچى تەرەپ قىستۇرمىسىنى يۈكلىيەلمىگەن.\n\nتېخىمۇ كۆپ تەپسىلاتىنى قىستۇرما باشقۇرغۇچتىن كۆرگىلى بولىدۇ." +PluginFailure.Dialog.Continue="پەرۋا قىلما" +PluginFailure.Dialog.Open="قىستۇرما باشقۇرغۇچنى ئاچ" SafeMode.Restart="OBS نى بىخەتەر ھالەتتە قايتا قوزغىتامسىز (ئۈچىنچى تەرەپ قىستۇرما، قوليازما ۋە WebSockets چەكلىنىدۇ)؟ " SafeMode.RestartNormal="OBS نى نورمال ھالەتتە قوزغىتامسىز؟" ChromeOS.Title="قوللىمايدىغان سۇپا" @@ -508,12 +512,14 @@ Basic.Main.PreviewDisabled="نۆۋەتتە ئالدىن كۆزىتىش چەكلەندى" Basic.SourceSelect="مەنبە قوش" Basic.SourceSelect.SelectType="مەنبە تۈرى" -Basic.SourceSelect.Recent="يېقىندا قوشقان" -Basic.SourceSelect.NewSource="يېڭى مەنبە قۇر" -Basic.SourceSelect.Existing="مەۋجۇت مەنبە قوش" +Basic.SourceSelect.Recent="يېقىندا قۇرغان" +Basic.SourceSelect.Description="نۆۋەتتىكى كۆرۈنۈشكە قوشىدىغان مەنبە تاللىنىدۇ." +Basic.SourceSelect.NewSource="يېڭى %1 قوش" +Basic.SourceSelect.AddExisting="مەۋجۇت %1 نى قوش" +Basic.SourceSelect.NoSelection="مەۋجۇتنى قوش" Basic.SourceSelect.CreateButton="يېڭىدىن قۇر" Basic.SourceSelect.AddVisible="مەنبە كۆرۈنۈشچان" -Basic.SourceSelect.NoExisting="مەۋجۇت بولمىغان %1 مەنبە" +Basic.SourceSelect.NoExisting="تېخى مەۋجۇت %1 مەنبە يوق." Basic.SourceSelect.Accessible.SourceName="مەنبە ئىسمى" Basic.SourceSelect.Accessible.Existing="مەۋجۇت مەنبە قوش" Basic.SourceSelect.Deprecated.Create="بۇ خىل مەنبە تۈرىگە ئىشلىتىلمەيدۇ دەپ بەلگە سېلىنغان، كەلگۈسىدە چىقىرىۋېتىلىشى مۇمكىن." @@ -1157,6 +1163,7 @@ Basic.AdvAudio.Monitoring="ئۈن نازارەتچىلىك" Basic.AdvAudio.Monitoring.None="نازارەتچىلىك تاقاق" Basic.AdvAudio.Monitoring.MonitorOnly="نازارەتچىلىكلا (چىقىرىش ئۈنسىز)" +Basic.AdvAudio.Monitoring.Both="نازارەتچىلىك قوزغىتىلغان" Basic.AdvAudio.MonitoringSource="«%1» نىڭ ئۈن نازارەتچىلىكى" Basic.AdvAudio.AudioTracks="نەغمىلەر" Basic.Settings.Hotkeys="تېزلەتمە كۇنۇپكىلار" @@ -1202,6 +1209,8 @@ Unmute="ئۈنلۈك" Push-to-mute="بېسىلسا ئۈنسىز" Push-to-talk="بېسىپ سۆزلىنىدۇ" +MonitorOn="نازارەتچىلىكنى قوزغىتىدۇ" +MonitorOff="نازارەتچىلىكنى چەكلەيدۇ" SceneItemShow="«%1» نى كۆرسىتىدۇ" SceneItemHide="«%1» نى يوشۇرىدۇ" OutputWarnings.NoTracksSelected="كەم دېگەندە بىر يولنى تاللىشىڭىز كېرەك" @@ -1368,5 +1377,40 @@ PluginManager.Section.Discover="كۆز يۈگۈرت" PluginManager.Section.Manage="ئورنىتىلغان" PluginManager.Section.Updates="يېڭىلانما" -PluginManager.Section.Manage.Title="قوزغىتىلغان قىستۇرمىنى باشقۇرۇش" +PluginManager.Section.Manage.Title="ئورنىتىلغان" +PluginManager.Section.Manage.Description="نۆۋەتتە ئورنىتىلغان قىستۇرمىنى باشقۇرىدۇ." +PluginManager.Section.Manage.NoPlugins="ھېچقانداق قىستۇرما تېپىلمىدى." +PluginManager.Section.Errors.Title="خاتالىق" +PluginManager.Section.Errors.Description="بۇ قىستۇرمىلارنى يۈكلىيەلمىدى. ئۇلارنىڭ ئەڭ يېڭى نەشرى ئىكەنلىكى ۋە OBS Studio نىڭ نەشرى بىلەن ماسلىشىدىغانلىقىنى جەزملەڭ." +PluginManager.Section.Missing.Title="كەم" +PluginManager.Section.Missing.Description="بۇ قىستۇرمىلار ئىلگىرى ئورنىتىلغان ئەمما ئەمدى تاپالمىدى." +PluginManager.Button.Enable="%1 قىستۇرمىنى قوزغات" +PluginManager.Status.Legacy="كونا" +PluginManager.Status.Disabled="چەكلەنگەن" +PluginManager.Status.Error="خاتالىق" +PluginManager.Status.Missing="كەم" +PluginManager.Status.Legacy.Description="بۇ قىستۇرما كەلگۈسىدە ئىشلەشتىن توختايدىغان ئورۇنغا ئورنىتىلغان. <a href=\"%1\">تەپسىلاتى</a>" Accessible.Widget.Name.AlignmentSelector="توغرىلاش تاللىغۇچ" +EncoderMissing.Title="كودلىغۇچ كەم" +EncoderMissing.Text="تۆۋەندە سەپلەنگەن كودلىغۇچ كەم:\n<ul>\n%1</ul><br>\nتېخىمۇ كۆپ ئۇچۇرنى <a href=\"%2\">بىلىم ئامبىرى ماقالىسى</a>دىن كۆرۈڭ." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (كود: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="يوچۇن" +EncoderMissing.MissingModule="«%1» بۆلەك يۈكلەنمىدى" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC تەكشۈرۈش پىروگرامىىسى قوزغىلالمىدى" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC تەكشۈرۈش جەريانى مەغلۇپ بولدى، چېكىنىش كودى: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC تەكشۈرۈش جەريانى چىقىرىش ئوقۇش مەغلۇپ بولدى، چېكىنىش كودى: %1" +EncoderMissing.NVENC.TestProgramError="NVENC تەكشۈرۈش مەغلۇپ بولدى، سەۋەبى: %1" +EncoderMissing.NVENC.NoDevices="NVIDIA GPU تېپىلمىدى" +EncoderMissing.NVENC.Unsupported.Kepler="سىزنىڭ GPU (%1) نىڭ قۇرۇلمىسى (Kepler) ئەمدى قوللىمايدۇ. OBS 30.2 ياكى تېخىمۇ ئىلگىرىكى نەشرىنى ئىشلىتىڭ." +EncoderMissing.NVENC.Reason.NvmlLoad="NVML ئامبىرىنى يۈكلىيەلمىدى" +EncoderMissing.NVENC.Reason.NvmlInit="NVML نى دەسلەپلەشتۈرەلمىدى" +EncoderMissing.NVENC.Reason.NvencLoad="NVENC ئامبىرىنى يۈكلىيەلمىدى" +EncoderMissing.NVENC.Reason.NvencInit="NVENC نى دەسلەپلەشتۈرەلمىدى" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC نەشرى بوش" +EncoderMissing.NVENC.Reason.CudaLoad="CUDA ئامبىرىنى يۈكلىيەلمىدى" +EncoderMissing.NVENC.Reason.CudaInit="CUDA نى دەسلەپلەشتۈرەلمىدى" +EncoderMissing.NVENC.Reason.CudaVersion="CUDA نەشرى ئىناۋەتسىز/كەم" +EncoderMissing.NVENC.Reason.DriverOutdated="ۋاقتى ئۆتكەن قوزغاتقۇ" +EncoderMissing.NVENC.Reason.NoSupportedDevices="NVENC نى قوللايدىغان ھېچقانداق NVIDIA ئۈسكۈنىسى يوق" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="كودلىغۇچنىڭ جەريانچاق چېكىدىن ئېشىپ كەتتى" +EncoderMissing.NVENC.Reason.AV1Unsupported="سىستېمىدىكى بارلىق NVIDIA GPU نىڭ ھەممىسى AV1 كودلاشنى قوللىمايدۇ."
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/uk-UA.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/uk-UA.ini
Changed
@@ -127,6 +127,10 @@ CrashHandling.Buttons.LaunchNormal="Запустити у звичайному режимі" CrashHandling.Errors.UploadJSONError="Під час спроби вивантажити найновіший журнал збоїв сталася помилка. Спробуйте ще раз пізніше." CrashHandling.Errors.Title="Помилка вивантаження звіту про збій" +PluginFailure.Dialog.Title="Помилки плагінів" +PluginFailure.Labels.Text="OBS Studio не вдалося завантажити всі сторонні плагіни.\n\nБільш детальну інформацію можна знайти в диспетчері плагінів." +PluginFailure.Dialog.Continue="Відхилити" +PluginFailure.Dialog.Open="Відкрити менеджер плагінів" SafeMode.Restart="Ви хочете перезапустити OBS у безпечному режимі (вимкнувши сторонні плагіни, скрипти та вебсокети)?" SafeMode.RestartNormal="Ви хочете перезапустити OBS у звичайному режимі?" ChromeOS.Title="Непідтримувана платформа" @@ -506,17 +510,19 @@ Basic.Main.MixerRename.Title="Перейменувати джерело аудіо" Basic.Main.MixerRename.Text="Будь ласка, введіть назву джерела аудіо" Basic.Main.PreviewDisabled="Попередній перегляд зараз вимкнено" -Basic.SourceSelect="Додати Джерело" -Basic.SourceSelect.SelectType="Тип Джерела" -Basic.SourceSelect.Recent="Нещодавно Додане" -Basic.SourceSelect.NewSource="Створити Нове Джерело" -Basic.SourceSelect.Existing="Додати Наявне Джерело" -Basic.SourceSelect.CreateButton="Створити Нове" +Basic.SourceSelect="Додати джерело" +Basic.SourceSelect.SelectType="Тип джерела" +Basic.SourceSelect.Recent="Нещодавно створені" +Basic.SourceSelect.Description="Виберіть, які джерела додати до поточної сцени." +Basic.SourceSelect.NewSource="Додати нове %1" +Basic.SourceSelect.AddExisting="Додати %1 наявне" +Basic.SourceSelect.NoSelection="Додати наявне" +Basic.SourceSelect.CreateButton="Створити нове" Basic.SourceSelect.AddVisible="Зробити джерело видимим" -Basic.SourceSelect.NoExisting="Немає наявних джерел %1" -Basic.SourceSelect.Accessible.SourceName="Ім'я Джерела" -Basic.SourceSelect.Accessible.Existing="Додати Наявне Джерело" -Basic.SourceSelect.Deprecated.Create="Цей тип джерела позначений як застарілий і може бути вилучений у майбутньому." +Basic.SourceSelect.NoExisting="Ще немає наявних %1 джерел." +Basic.SourceSelect.Accessible.SourceName="Назва джерела" +Basic.SourceSelect.Accessible.Existing="Додати наявне джерело" +Basic.SourceSelect.Deprecated.Create="Цей тип джерела позначений застарілим і може бути вилучений у майбутньому." Basic.Main.Sources.Visibility="Видимість" Basic.Main.Sources.VisibilityDescription="Контролює видимість '%1' на полотні" Basic.Main.Sources.Lock="Блокувати" @@ -630,7 +636,7 @@ Basic.Main.HideContextBar="Приховати панель джерела" Basic.Main.StopVirtualCam="Зупинити віртуальну камеру" Basic.Main.Group="Група %1" -Basic.Main.NewGroup="Нова Група" +Basic.Main.NewGroup="Нова група" Basic.Main.GroupItems="Згрупувати вибрані елементи" Basic.Main.Ungroup="Розгрупувати" Basic.Main.GridMode="Режим сітки" @@ -1159,6 +1165,7 @@ Basic.AdvAudio.Monitoring="Прослуховування звуку" Basic.AdvAudio.Monitoring.None="Прослуховування вимкнено" Basic.AdvAudio.Monitoring.MonitorOnly="Тільки прослуховування (заглушити вивід)" +Basic.AdvAudio.Monitoring.Both="Моніторинг увімкнено" Basic.AdvAudio.MonitoringSource="Моніторинг звуку для «%1»" Basic.AdvAudio.AudioTracks="Доріжки" Basic.Settings.Hotkeys="Гарячі клавіші" @@ -1182,6 +1189,8 @@ Unmute="Увімкнути звук" Push-to-mute="Вимкнути утримуванням клавіші" Push-to-talk="Увімкнути утримуванням клавіші" +MonitorOn="Увімкнути моніторинг" +MonitorOff="Вимкнути моніторинг" SceneItemShow="Показати '%1'" SceneItemHide="Приховати '%1'" OutputWarnings.NoTracksSelected="Ви повинні вибрати хоча б одну доріжку" @@ -1326,7 +1335,10 @@ FailedToStartStream.FailedToCreateAudioEncoder="Не вдалося створити кодувальник звуку" FailedToStartStream.NoRTMPURLInConfig="Конфігурація не містить URL-адреси цільового потоку RTMP(S)" FailedToStartStream.FallbackToDefault="Не вдалося запустити трансляцію за допомогою %1; ви хочете спробувати ще раз, використовуючи налаштування одного кодування?" +FailedToStartStream.ConfigRequestFailed="Не вдалося отримати конфігурацію з %1\n\nПомилка HTTP: %2" FailedToStartStream.WarningUnknownStatus="Отримано невідоме значення стану '%1'" +FailedToStartStream.WarningRetryNonMultitrackVideo="\n\nЧи хочете ви продовжити трансляцію без %1?" +FailedToStartStream.WarningRetry="\n\n Чи хочете ви продовжити трансляцію?" FailedToStartStream.MissingEncoderConfigs="Конфігурація для запуску не містить конфігурацій кодувальників" FailedToStartStream.InvalidEncoderConfig="Конфігурація для запуску містить недійсну конфігурацію кодувальника" FailedToStartStream.StatusMissingHTML="Запит на запуск повернув невизначену помилку" @@ -1344,5 +1356,40 @@ PluginManager.Section.Discover="Огляд" PluginManager.Section.Manage="Установлено" PluginManager.Section.Updates="Оновлення" -PluginManager.Section.Manage.Title="Керування увімкненими плагінами" +PluginManager.Section.Manage.Title="Встановлено" +PluginManager.Section.Manage.Description="Керуйте встановленими на цей час плагінами." +PluginManager.Section.Manage.NoPlugins="Плагінів не знайдено." +PluginManager.Section.Errors.Title="Помилки" +PluginManager.Section.Errors.Description="Ці плагіни не вдалося завантажити. Переконайтеся, що вони оновлені та сумісні з цією версією OBS Studio." +PluginManager.Section.Missing.Title="Відсутні" +PluginManager.Section.Missing.Description="Ці плагіни раніше були встановлені, але зараз їх неможливо знайти." +PluginManager.Button.Enable="Увімкнути %1 плагін" +PluginManager.Status.Legacy="Застаріле" +PluginManager.Status.Disabled="Вимкнено" +PluginManager.Status.Error="Помилка" +PluginManager.Status.Missing="Відсутні" +PluginManager.Status.Legacy.Description="Цей плагін встановлено в теку, яка в майбутньому перестане працювати. <a href=\"%1\">Дізнатися більше</a>" Accessible.Widget.Name.AlignmentSelector="Селектор вирівнювання" +EncoderMissing.Title="Відсутні кодувальники" +EncoderMissing.Text="Відсутні такі налаштовані кодувальники:\n<ul>\n%1</ul><br>\nДивіться <a href=\"%2\">Статтю з бази знань</a> для отримання додаткової інформації." +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2 (код: <code>%3</code>)\n</li>" +EncoderMissing.Unknown="Невідомо" +EncoderMissing.MissingModule="Модуль \"%1\" не завантажено" +EncoderMissing.NVENC.TestProgramFailedStartup="Помилка запуску програми перевірки NVENC" +EncoderMissing.NVENC.TestProgramExitWithError="Помилка процесу перевірки NVENC, код завершення: %1" +EncoderMissing.NVENC.TestProgramReadFailure="Помилка зчитування вихідних даних процесу перевірки NVENC, код завершення: %1" +EncoderMissing.NVENC.TestProgramError="Перевірка NVENC завершилася невдало з наступною причиною: %1" +EncoderMissing.NVENC.NoDevices="Графічних процесорів NVIDIA не знайдено" +EncoderMissing.NVENC.Unsupported.Kepler="Архітектура (Kepler) вашого графічного процесора (%1) більше не підтримується. Замість цього, будь ласка, використовуйте OBS 30.2 або попередні версії." +EncoderMissing.NVENC.Reason.NvmlLoad="Не вдалося завантажити бібліотеку NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Помилка ініціалізації NVML" +EncoderMissing.NVENC.Reason.NvencLoad="Не вдалося завантажити бібліотеку NVENC" +EncoderMissing.NVENC.Reason.NvencInit="Помилка ініціалізації NVENC" +EncoderMissing.NVENC.Reason.NvencVersion="Версія NVENC відсутня" +EncoderMissing.NVENC.Reason.CudaLoad="Не вдалося завантажити бібліотеку CUDA" +EncoderMissing.NVENC.Reason.CudaInit="Помилка ініціалізації CUDA" +EncoderMissing.NVENC.Reason.CudaVersion="Неправильна/відсутня версія CUDA" +EncoderMissing.NVENC.Reason.DriverOutdated="Застарілий драйвер" +EncoderMissing.NVENC.Reason.NoSupportedDevices="Не знайдено пристроїв NVIDIA з підтримкою NVENC" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="Перевищено ліміт сеансів кодувальника" +EncoderMissing.NVENC.Reason.AV1Unsupported="Кодування AV1 не підтримується жодним із графічних процесорів NVIDIA у цій системі"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/uz-UZ.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/uz-UZ.ini
Changed
@@ -3,7 +3,7 @@ Cancel="Bekor qilish" Close="Yopish" Save="Saqlash" -Discard="Voz kechish" +Discard="Rad etish" Disable="Oʻchirish" Yes="Ha" No="Yoʻq" @@ -21,6 +21,7 @@ Exit="Chiqish" Mixer="Ovoz aralashtirgichi" Browse="Izlash" +Mono="mono" DroppedFrames="Yo‘qotilgan kadrlar %1 (%2%)" Projector.Open.Program="Dastur proyektorini ochish" Projector.Open.Preview="Dastur proyektorini peshko‘rish" @@ -32,7 +33,7 @@ Projector.Title="Proyektor" Projector.Title.Scene="Sahna: %1" Projector.Title.Source="Manba: %1" -Projector.Title.Multiview="Ko‘pko‘rinish" +Projector.Title.Multiview="Koʻpkoʻrinish" Projector.ResizeWindowToContent="Oynani tarkibga moslash" Clear="Tozalash" Revert="Qaytarish" @@ -49,8 +50,8 @@ Transition="Almashish" QuickTransitions="Tez almashish" FadeToBlack="Qorayib yo‘qolish" -Left="Chap" -Right="Oʻng" +Left="Chapga strelka" +Right="Oʻngga strelka" Top="Usti" Bottom="Osti" Width="Kenglik" @@ -61,6 +62,7 @@ Seconds="Sekund" Deprecated="Eskirgan" ReplayBuffer="Qayta ko‘rish buferi" +Import="Olib kirish" Export="Eksport" Copy="Nusxalash" Paste="Qoʻyish" @@ -75,8 +77,8 @@ TransitionOverride="O‘tishni bekor qilish" ShowTransition="O‘tishni ko‘rsatish" HideTransition="O‘tishni yashirish" -None="Yoʻq" -StudioMode.Preview="Peshko‘rish" +None="Yo‘q (Bo‘sh)" +StudioMode.Preview="Oldindan koʻrish" StudioMode.Program="Dastur" StudioMode.PreviewSceneName="Peshko‘rish: %1" StudioMode.ProgramSceneName="Dastur: %1" @@ -84,7 +86,7 @@ VerticalLayout="Vertikal maket" Group="Guruh" DoNotShowAgain="Qayta ko‘rsatilmasin" -Default="Birlamchi" +Default="(Birlamchi)" Calculating="Hisoblanmoqda..." Fullscreen="To‘liq ekran" Windowed="Oynalangan" @@ -94,8 +96,8 @@ LogViewer="Jurnal koʻrish" ShowOnStartup="Ishga tushganda ko‘rsatish" OpenFile="Faylni ochish" -AddScene="Sahna qo‘shish" -AddSource="Manba qo‘shish" +AddScene="Sahna Qoʻshish" +AddSource="Manba Qoʻshish" RemoveScene="Tanlangan sahnani olib tashlash" RemoveSource="Tanlangan manba(lar)ni olib tashlash" MoveSceneUp="Sahnani yuqoriga ko‘chirish" @@ -117,14 +119,22 @@ AlreadyRunning.LaunchAnyway="Baribir ishga tushurish" CrashHandling.Dialog.Title="OBS Studioda nosozlik yuz berdi" CrashHandling.Labels.Text="OBS Studio dasturi notoʻgʻri yopilgan.\n\nXavfsiz rejimda ochasizmi (tashqi plaginlar, skriptlar va WebSocketʼlar oʻchirilgan holda)?" +CrashHandling.Labels.PrivacyNotice="Eng so‘nggi nosozlik hisobotini OBSProject’ga avtomatik yuborishni ham tanlashingiz mumkin.<br /><br />Fayllarni yuborishdan oldin <a href='https://obsproject.com/privacy-policy'>Maxfiylik siyosati</a>ni o‘qib chiqing va ayniqsa fayllarni yuborishga oid qismlarga e’tibor bering." CrashHandling.Checkbox.SendReport="Maxfiylik siyosatini oʻqidim va yuklab qoʻyishga rozilik beraman." CrashHandling.Buttons.LaunchSafe="Xavfsiz rejimda ishga tushirish" CrashHandling.Buttons.LaunchNormal="Normal rejimda ishga tushirish" +CrashHandling.Errors.UploadJSONError="Eng so‘nggi nosozlik jurnalini yuborishda xatolik yuz berdi. Keyinroq qayta urinib ko‘ring." +CrashHandling.Errors.Title="Nosozlik jurnalini yuborish xatosi" +SafeMode.Restart="OBS’ni xavfsiz ish tartibida qayta ishga tushirmoqchimisiz (uchinchi tomon qo‘shimchalari, buyruqlar fayllari va WebSocket’lar o‘chiriladi)?" SafeMode.RestartNormal="OBSʼni normal rejimda qaytadan ishga tushirmoqchisizmi?" ChromeOS.Title="Qoʻllab‑quvvatlanmaydigan platforma" ChromeOS.Text="OBS ChromOS konteyneri ichida ishga tushirilganiga oʻxshaydi. Ushbu platforma qoʻllab‑quvvatlanmaydi." Wine.Title="Wine aniqlandi" +Wine.Text="OBS’ni Wine orqali ishlatish qo‘llab-quvvatlanmaydi. Signal olish yoki qurilma manbalari kabi ko‘plab imkoniyatlar ishlamasligi yoki cheklangan holda ishlashi mumkin.<br><br>Buning o‘rniga OBS’ning tizimingiz uchun yaratilgan asl talqinidan foydalanish tavsiya etiladi, masalan <a href='https://flathub.org/apps/details/com.obsproject.Studio'>Flatpak talqinimiz</a> yoki operatsion tizimingiz paketlaridan." +DockCloseWarning.Title="Biriktiriladigan oynani yopish" +DockCloseWarning.Text="Siz hozirgina biriktiriladigan oynani yopdingiz. Uni yana ko‘rsatish uchun menyu satridagi “Biriktirilgan oynalar” menyusidan foydalaning." ExtraBrowsers="Maxsus brauzer doklari" +ExtraBrowsers.Info="Biriktiriladigan oynalarga nom va veb-manzil berib qo‘shing, so‘ng ularni ochish uchun “Qo‘llash” yoki “Yopish” tugmasini bosing. Ularni istalgan vaqtda qo‘shishingiz yoki olib tashlashingiz mumkin." ExtraBrowsers.DockName="Dok nomi" Auth.Authing.Title="Autentifikatsiya qilinmoqda..." Auth.Authing.Text="%1 bilan autentifikatsiya qilinmoqda, kutib turing..." @@ -137,14 +147,22 @@ Auth.LoadingChannel.Error="Kanal maʼlumotlarini olib boʻlmadi" Auth.ChannelFailure.Title="Kanalni yuklab boʻlmadi" Auth.ChannelFailure.Text="%1 uchun kanal maʼlumotlarini yuklab boʻlmadi\n\n%2: %3" +Auth.Chat="suhbat" Auth.StreamInfo="Strim haqida maʼlumot" TwitchAuth.Stats="Twitch statistikasi" +TwitchAuth.Feed="Twitch faoliyat tasmasi" +TwitchAuth.TwoFactorFail.Title="Jonli uzatish kalitini olib bo‘lmadi" +TwitchAuth.TwoFactorFail.Text="OBS Twitch hisobingizga ulana olmadi. Jonli uzatish uchun talab qilinadigan ikki bosqichli tasdiqlash <a href='https://www.twitch.tv/settings/security'>Twitch xavfsizlik sozlamalari</a>da yoqilganiga ishonch hosil qiling." +RestreamAuth.Channels="Qayta uzatish kanallari" Copy.Filters="Filtrlarni nusxalash" Paste.Filters="Filtrlarni qoʻyish" +BrowserPanelInit.Title="Brauzer ishga tayyorlanmoqda..." +BrowserPanelInit.Text="Brauzer ishga tayyorlanmoqda, kuting..." BandwidthTest.Region.US="AQSh" BandwidthTest.Region.EU="Yevropa" BandwidthTest.Region.Asia="Osiyo" BandwidthTest.Region.Other="Boshqa" +Basic.AutoConfig="Avtomatik sozlash yordamchisi" Basic.AutoConfig.ApplySettings="Sozlamalarni qoʻllash" Basic.AutoConfig.StartPage="Foydalanish haqida maʼlumot" Basic.AutoConfig.StartPage.SubTitle="Dasturni nima uchun ishlatmoqchiligingizni ayting" @@ -157,6 +175,7 @@ Basic.AutoConfig.VideoPage.FPS.UseCurrent="Hozirgini ishlatish (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 yoki 30, lekin iloji boʻlsa 60 afzal koʻrilsin" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 yoki 30, lekin yuqoriroq rezolyutsiya afzal koʻrilsin" +Basic.AutoConfig.VideoPage.CanvasExplanation="Eslatma: Ish maydonining (asosiy) o‘lchami jonli uzatish yoki yozib olish o‘lchami bilan bir xil bo‘lishi shart emas. Tizim resurslari sarfini yoki bit tezligi talabini kamaytirish uchun haqiqiy jonli uzatish/yozib olish o‘lchami ish maydoni o‘lchamidan kichraytirilishi mumkin." Basic.AutoConfig.StreamPage="Strim haqida maʼlumot" Basic.AutoConfig.StreamPage.SubTitle="Strim haqida maʼlumotni kiriting" Basic.AutoConfig.StreamPage.ConnectAccount="Akkauntni bogʻlash" @@ -170,20 +189,60 @@ Basic.AutoConfig.StreamPage.Service="Servis" Basic.AutoConfig.StreamPage.Service.ShowAll="Barchasini koʻrsatish..." Basic.AutoConfig.StreamPage.Service.Custom="Maxsus..." +Basic.AutoConfig.StreamPage.Server="server" Basic.AutoConfig.StreamPage.StreamKey="Strim kaliti" +Basic.AutoConfig.StreamPage.StreamKey.ToolTip="RIST: shifrlash maxfiy iborasini kiriting.\nRTMP: xizmat tomonidan berilgan kalitni kiriting.\nSRT: agar xizmat undan foydalansa, streamid ni kiriting." +Basic.AutoConfig.StreamPage.EncoderKey="Kodlovchi kaliti" +Basic.AutoConfig.StreamPage.BearerToken="Bearer tokeni" Basic.AutoConfig.StreamPage.ConnectedAccount="Bogʻlangan akkaunt" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Tarmoq o‘tkazuvchanligini tekshirib, bit tezligini aniqlash (bir necha daqiqa davom etishi mumkin)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Apparatli kodlashni afzal ko‘rish" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Apparatli kodlash protsessor yuklamasining katta qismini kamaytiradi, ammo bir xil sifatga erishish uchun yuqoriroq bit tezligi talab qilinishi mumkin." Basic.AutoConfig.StreamPage.StreamWarning.Title="Strim haqida ogohlantirish" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Tarmoq o‘tkazuvchanligi sinovi kanalingizga ovozsiz tasodifiy video ma’lumotlarini uzatadi. Imkon bo‘lsa, sinov tugaguniga qadar jonli uzatish videolarini saqlashni vaqtincha o‘chirib, uzatishni yashirin holatga o‘tkazish tavsiya etiladi. Davom etilsinmi?" Basic.AutoConfig.StreamPage.UseMultitrackVideo="%1ʼni test qilish" Basic.AutoConfig.TestPage="Oxirgi natijalar" Basic.AutoConfig.TestPage.SubTitle.Testing="Optimal sozlamalarni aniqlash uchun dastur bir qator testlarni bajarmoqda" Basic.AutoConfig.TestPage.SubTitle.Complete="Test tugadi" Basic.AutoConfig.TestPage.TestingBandwidth="Tarmoq oʻtkazuvchanligi tekshirilmoqda, bu bir necha daqiqa vaqt olishi mumkin..." +Basic.AutoConfig.TestPage.TestingBandwidth.NoOutput="Ushbu xizmat bayonnomasi uchun chiqish topilmadi" +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="%1 ga ulanmoqda..." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Hech bir serverga ulanib bo‘lmadi. Internet aloqangizni tekshirib, qayta urinib ko‘ring." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="%1 uchun tarmoq o‘tkazuvchanligi tekshirilmoqda" +Basic.AutoConfig.TestPage.TestingStreamEncoder="Jonli uzatish kodlovchisi tekshirilmoqda, bu bir daqiqacha davom etishi mumkin..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Yozib olish kodlovchisi tekshirilmoqda, bu bir daqiqacha davom etishi mumkin..." +Basic.AutoConfig.TestPage.TestingRes.Fail="Kodlovchini ishga tushirib bo‘lmadi" Basic.AutoConfig.TestPage.TestingRes.Resolution="%1x%2 %3 FPS test qilinmoqda..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Jonli uzatish kodlovchisi" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Yozib olish kodlovchisi" +Basic.AutoConfig.TestPage.Result.Header="Dastur quyidagi taxminiy sozlamalarni siz uchun eng maqbul deb aniqladi:" +Basic.AutoConfig.TestPage.Result.Footer="Ushbu sozlamalardan foydalanish uchun “Sozlamalarni qo‘llash” tugmasini bosing. Yordamchini qayta sozlab, yana urinib ko‘rish uchun “Orqaga” tugmasini bosing. Sozlamalarni qo‘lda o‘zgartirish uchun “Bekor qilish” tugmasini bosib, “Sozlamalar”ni oching." +Basic.AutoConfig.Info="Avtomatik sozlash yordamchisi kompyuteringiz xususiyatlari va internet tezligiga qarab eng maqbul sozlamalarni aniqlaydi." +Basic.AutoConfig.RunAnytime="Buni istalgan vaqtda “Vositalar” menyusi orqali ishga tushirish mumkin." +Basic.AutoConfig.TestPage.Result.StreamingResolution="Jonli uzatish o‘lchami (masshtablangan)" Basic.Stats="Statistika" +Basic.Stats.CPUUsage="Protsessor yuklamasi" +Basic.Stats.HDDSpaceAvailable="Diskdagi bo‘sh joy" +Basic.Stats.MemoryUsage="Xotira sarfi" +Basic.Stats.AverageTimeToRender="Kadrni tasvirlashning o‘rtacha vaqti" +Basic.Stats.SkippedFrames="Kodlash kechikishi sabab o‘tkazib yuborilgan kadrlar" +Basic.Stats.MissedFrames="Tasvirlash kechikishi sabab yo‘qotilgan kadrlar" Basic.Stats.Output.Stream="Strim" +Basic.Stats.Output.Recording="Yozib olinmoqda" +Basic.Stats.Status="Holat" +Basic.Stats.Status.Recording="Yozib olinmoqda" +Basic.Stats.Status.Live="JONLI EFIR" +Basic.Stats.Status.Reconnecting="Qayta ulanmoqda" +Basic.Stats.Status.Inactive="Faol emas" +Basic.Stats.Status.Active="Faol" +Basic.Stats.DroppedFrames="Yo‘qotilgan kadrlar (tarmoq)" +Basic.Stats.MegabytesSent="Jami uzatilgan ma’lumot" +Basic.Stats.Bitrate="Bit tezligi" +Basic.Stats.DiskFullIn="Disk to‘lishigacha (taxminan)" Basic.Stats.DiskFullIn.Text="%1 soat, %2 minut" Basic.Stats.ResetStats="Statistikani tiklash" ResetUIWarning.Title="Rostan ham interfeysni tiklamoqchimisiz?" +ResetUIWarning.Text="Foydalanuvchi interfeysini asl holatiga qaytarish qo‘shimcha biriktirilgan oynalarni yashiradi. Ularni yana ko‘rsatish uchun “Biriktirilgan oynalar” menyusidan qayta ko‘rsatishingiz kerak bo‘ladi.\n\nFoydalanuvchi interfeysini asl holatiga qaytarmoqchimisiz?" Updater.Title="Yangi yangilanish mavjud" Updater.Text="Yangi yangilanish mavjud:" Updater.UpdateNow="Hozir yangilash" @@ -191,12 +250,83 @@ Updater.Skip="Versiyani oʻtkazib yuborish" Updater.NoUpdatesAvailable.Title="Hech qanday yangilanish yoʻq" Updater.NoUpdatesAvailable.Text="Hozirda hech qanday yangilanish yoʻq" +Updater.BranchNotFound.Title="Yangilash kanali olib tashlangan" +Updater.BranchNotFound.Text="Siz tanlagan yangilash kanali endi mavjud emas. OBS standart yangilash kanaliga qaytarildi." +Updater.RepairButUpdatesAvailable.Title="Yaxlitlikni tekshirish mavjud emas" +Updater.RepairButUpdatesAvailable.Text="Fayllar yaxlitligini faqat mavjud eng so‘nggi talqinda tekshirish mumkin. OBS o‘rnatilishini tekshirish va yangilash uchun Yordam → Yangilanishlarni tekshirish bo‘limidan foydalaning." +Updater.RepairConfirm.Title="Yaxlitlik tekshiruvini tasdiqlash" +Updater.RepairConfirm.Text="Yaxlitlik tekshiruvini boshlash OBS o‘rnatilishini buzilgan fayllarga tekshiradi va buzilgan yoki o‘zgartirilgan fayllarni qayta yuklab oladi. Bu biroz vaqt olishi mumkin.\n\nDavom etmoqchimisiz?" +Updater.FailedToLaunch="Yangilagichni ishga tushirib bo‘lmadi" +QuickTransitions.SwapScenes="O‘tishdan so‘ng oldindan ko‘rish va dastur sahnalarini almashtirish" +QuickTransitions.SwapScenesTT="O‘tishdan so‘ng oldindan ko‘rish va dastur sahnalarini o‘zaro almashtiradi (agar dasturning asl sahnasi hali ham mavjud bo‘lsa).\nBu dasturning asl sahnasiga kiritilgan o‘zgarishlarni bekor qilmaydi." +QuickTransitions.DuplicateScene="Sahna nusxasini yaratish" +QuickTransitions.DuplicateSceneTT="Bir xil sahnani tahrirlashda dastur chiqishini o‘zgartirmasdan manbalarning joylashuvi, o‘lchami va ko‘rinishini tahrirlash imkonini beradi.\nManbalar xususiyatlarini dastur chiqishini o‘zgartirmasdan tahrirlash uchun “Manbalarni nusxalash”ni yoqing.\nBu qiymatni o‘zgartirish joriy dastur sahnasini asl holatiga qaytaradi (agar u hali mavjud bo‘lsa)." +QuickTransitions.EditProperties="Manbalarni nusxalash" +QuickTransitions.EditPropertiesTT="Bir xil sahnani tahrirlashda dastur chiqishini o‘zgartirmasdan manbalar xususiyatlarini tahrirlash imkonini beradi.\nBundan faqat “Sahna nusxasini yaratish” yoqilgan bo‘lsa foydalanish mumkin.\nAyrim manbalar (masalan, signal olish yoki media manbalari) buni qo‘llab-quvvatlamaydi va ularni alohida tahrirlab bo‘lmaydi.\nBu qiymatni o‘zgartirish joriy dastur sahnasini asl holatiga qaytaradi (agar u hali mavjud bo‘lsa).\n\nOgohlantirish: Manbalar nusxalanishi sababli qo‘shimcha tizim yoki video resurslari talab qilinishi mumkin." +QuickTransitions.HotkeyName="Tezkor o‘tish: %1" +Basic.AddTransition="Sozlanadigan o‘tishni qo‘shish" +Basic.RemoveTransition="Sozlanadigan o‘tishni olib tashlash" +Basic.TransitionProperties="O‘tish xususiyatlari" +Basic.SceneTransitions="Sahna o‘tishlari" +Basic.TransitionDuration="Davomiyligi" Basic.TogglePreviewProgramMode="Studiya rejimi" Basic.EnablePreviewProgramMode="Studiya rejimini yoqish" Basic.DisablePreviewProgramMode="Studiya rejimini oʻchirish" +Undo.Undo="Bekor qilish" +Undo.Redo="Qayta bajarish" +Undo.Add="“%1”ni qo‘shish" +Undo.Delete="“%1”ni o‘chirish" +Undo.Rename="“%1” nomini o‘zgartirish" +Undo.SceneCollection.Switch="“%1”ga o‘tish" +Undo.Item.Undo="%1 amalini bekor qilish" +Undo.Item.Redo="%1 amalini qayta bajarish" +Undo.Sources.Multi="%1 ta manbani o‘chirish" +Undo.Filters="“%1”dagi filtr o‘zgarishlari" Undo.Filters.Paste.Single="'%1' filtrini '%2' filtriga qoʻyish" Undo.Filters.Paste.Multiple="'%1' filtridan '%2' filtriga nusxalash" +Undo.Transform="“%1”dagi manba(lar)ni o‘zgartirish" +Undo.Transform.Paste="“%1”ga o‘zgartirish parametrlarini joylash" +Undo.Transform.Rotate="“%1”dagi burilish" +Undo.Transform.Reset="“%1”dagi o‘zgartirishlarni asl holatiga qaytarish" +Undo.Transform.HFlip="“%1”da gorizontal akslantirish" +Undo.Transform.VFlip="“%1”da vertikal akslantirish" +Undo.Transform.FitToScreen="“%1”ni ekranga moslashtirish" +Undo.Transform.StretchToScreen="“%1”ni ekranga cho‘zish" +Undo.Transform.Center="“%1”ni ekranga cho‘zish" +Undo.Transform.VCenter="“%1”ni ekran bo‘ylab vertikal markazlash" +Undo.Transform.HCenter="“%1”ni ekran bo‘ylab gorizontal markazlash" +Undo.Volume.Change="“%1” ovoz balandligini o‘zgartirish" +Undo.Volume.Mute="'%1' ovozsizlash" +Undo.Volume.Unmute="“%1” ovozini yoqish" +Undo.Balance.Change="“%1” ovoz muvozanatini o‘zgartirish" +Undo.SyncOffset.Change="'%1'da Audio Sinxronlash Surilmasini Oʻzgartirish" +Undo.MonitoringType.Change="'%1'da Audio Monitoringini Oʻzgartirish" +Undo.Mixers.Change="'%1'da Audio Qorishtirgichlarini Oʻzgartirish" +Undo.ForceMono.On="'%1'da Majburiy Mononi Yoqish" +Undo.ForceMono.Off="'%1'da Majburiy Mononi Oʻchirish" +Undo.Properties="'%1'da Xususiyatni Oʻzgartirish" +Undo.Scene.Duplicate="'%1' Sahnasini Egizaklash" +Undo.ShowTransition="'%1'da Oʻtishni Koʻrsatish" +Undo.HideTransition="'%1'da Oʻtishni Yashirish" +Undo.ShowSceneItem="'%2' Ichida '%1'ni Koʻrsatish" +Undo.HideSceneItem="'%2' Ichida '%1'ni Yashirish" +Undo.ReorderSources="'%1'dagi Manbalarni Qayta Tartiblash" +Undo.MoveUp="'%2' Ichida '%1'ni Yuqoriga Koʻchirish" +Undo.MoveDown="'%2' Ichida '%1'ni Quyiga Surish" +Undo.MoveToTop="'%2' Ichida '%1'ni Eng Yuqoriga Surish" +Undo.MoveToBottom="'%2' Ichida '%1'ni Eng Quyiga Surish" +Undo.PasteSource="'%1' Ichiga Manba(lar)ni Joylashtirish" +Undo.PasteSourceRef="'%1' Ichiga Manba Tayanch(lar)ini Joylashtirish" +Undo.GroupItems="Buyumlarni '%1' ichiga Guruhlsh" +Undo.ScaleFiltering="'%2' ichidagi '%1'da Koʻlamlash Filtri" +Undo.BlendingMode="'%2' ichidagi '%1'da Birlashtirish Tartibi" +Undo.BlendingMethod="'%2' ichidagi '%1'da Birlashtirish Usuli" +Undo.DeinterlacingMode="'%1'da Qatlamasizlash Tartibi" +Undo.DeinterlacingOrder="'%1'da Qatlamasizlash Maydoni Tartibi" +TransitionNameDlg.Text="Iltimos, Oʻtish nomini kiriting" +TransitionNameDlg.Title="Oʻtish Nomi" TitleBar.SafeMode="XAVFSIZ REJIM" +TitleBar.PortableMode="Koʻchma Tartib" TitleBar.Profile="Profil" TitleBar.Scenes="Sahnalar" NameExists.Title="Nom allaqachon mavjud" @@ -207,64 +337,363 @@ ConfirmStart.Text="Rostan ham strimni boshlamoqchimisiz?" ConfirmStop.Title="Strimni toʻxtatasizmi?" ConfirmStop.Text="Rostan ham strimni toʻxtatmoqchimisiz?" +ConfirmStopRecord.Title="Yozib olish Toʻxtatilsinmi?" +ConfirmStopRecord.Text="Haqiqatan ham Yozib olishni toʻxtatmoqchimisiz?" +ConfirmBWTest.Title="Sigʻim tekshiruvi Boshlansinmi?" +ConfirmBWTest.Text="Sizda OBS sigʻimi tekshiruv tartibida tuzimlangan. Bu tartib kanalingiz efirga chiqmagan holda tarmoqni sinovdan oʻtkazish imkonini beradi. Sinovni yakunlaganingizdan soʻng, tomoshabinlar strimingizni koʻra olishlari uchun uni oʻchirib qoʻyishingiz kerak boʻladi.\n\n Davom etishni istaysizmi?" +ConfirmExit.Title="Faol Chiqishlar" +ConfirmExit.Text="OBS hozir faol. Barcha strimlar/yozuvlar oʻchiriladi." +ConfirmRemove.Title="Olib tashlashni Tasdiqlash" +ConfirmRemove.Text="Haqiqatan ham '%1'ni olib tashlashni istaysizmi?" +ConfirmRemove.TextMultiple="Haqiqatan ham %1 ta buyumni olib tashlash istagidamisiz?" +ConfirmReset.Title="Xususiyatlarni Qaytarish" +ConfirmReset.Text="Haqiqatan ham joriy xususiyatlarni ularning birlamchilariga qaytarishni istaysizmi?" Output.StartStreamFailed="Strimni boshlab boʻlmadi" +Output.StartRecordingFailed="Yozib olishni boshlashda xatolik" +Output.StartReplayFailed="Takrorlash buferini boshlashda xatolik" +Output.StartVirtualCamFailed="Virtual kamerani boshlashda xatolik" +Output.StartFailedGeneric="Chiqishni boshlashda xatolik. Tafsilotlar uchun qaydlarni tekshiring.\n\n Eslatma: Agar siz NVENC yoki AMD kodlovchilaridan foydalanayotgan boʻlsangiz, video drayverlaringiz eng soʻnggi talqinda ekanligiga ishonch hosil qiling." +Output.ReplayBuffer.PauseWarning.Title="Tanaffus paytida takrorlashlarni saqlab boʻlmaydi" +Output.ReplayBuffer.PauseWarning.Text="Ogohlantirish: Tanaffusda takrorlashlarni saqlab boʻlmaydi." Output.ConnectFail.Title="Ulanib boʻlmadi" +Output.ConnectFail.BadPath="Yaroqsiz Manzil yoki Ulanish URL'i. Toʻgʻri ekanligiga amin boʻlish uchun sozlamalarni tekshiring." Output.ConnectFail.ConnectFailed="Serverga ulanib boʻlmadi" +Output.ConnectFail.InvalidStream="Aniqlangan kanal yoki strim kalitiga kirish imkonsiz, strim kalitingizni qayta tekshiring. Agar u toʻgʻri boʻlsa, serverga ulanishda muammo boʻlishi mumkin." +Output.ConnectFail.HdrDisabled="Mazkur chiqish uchun HDR chiqishi hozirda oʻchirilgan." +Output.ConnectFail.Error="Serverga ulanishga urinishda kutilmagan xatolik yuz berdi. Batafsil maʼlumot qaydlar faylida." Output.ConnectFail.Disconnected="Serverdan uzildi." +Output.StreamEncodeError.Title="Kodlash xatoligi" +Output.RecordFail.Title="Yozib olishni boshlashda xatolik" +Output.RecordFail.Unsupported="Chiqish formati qoʻllab-quvvatlanmaydi yoki bir nechta audio yoʻlakchasini qoʻllamaydi. Sozlamalaringizni tekshirib, qayta urinib koʻring." Output.RecordNoSpace.Title="Diskda joy yetarli emas" +Output.RecordNoSpace.Msg="Yozib olishni davom ettirish uchun diskda yetarlicha boʻsh joy yoʻq." +Output.RecordError.Title="Yozib olish xatoligi" +Output.RecordError.Msg="Yozib olish paytida noma’lum xatolik yuz berdi." +Output.RecordError.EncodeErrorMsg="Yozib olishda kodlovchi xatoligi yuz berdi." +Output.BadPath.Title="Yaroqsiz Fayl Manzili" +Output.BadPath.Text="Tuzimlangan Yozib olish Manzili ochilmadi. Sozlamalar → Chiqish → Yozib olish boʻlimidagi Yozib olish Manzilini tekshiring." +Output.NoBroadcast.Title="Translyatsiya Tuzimlanmagan" +Output.NoBroadcast.Text="Jonli efirni boshlashdan oldin translyatsiyani moslashingiz kerak." Output.BroadcastStartFailed="Translyatsiyani boshlab boʻlmadi" Output.BroadcastStopFailed="Translyatsiyani toʻxtatib boʻlmadi" +LogUploadDialog.Title="OBS Studio Qaydlar Faylini Yuklash" +LogUploadDialog.Labels.Progress="Qaydlar yuklanmoqda. Iltimos kuting..." +LogUploadDialog.Labels.Description.AppLog="Qaydlar faylingiz yuklandi. Endi tuzatish yoki qoʻllab-quvvatlash uchun ushbu URL'ni ulashishingiz mumkin." +LogUploadDialog.Labels.Description.CrashLog="Qulash hisobotingiz yuklandi. Endi tuzatish maqsadida ushbu URL'ni ulashishingiz mumkin." LogUploadDialog.Buttons.ConfirmUpload="Yuklab qoʻyish" +LogUploadDialog.Buttons.CopyURL="Qaydlar URL'ini Nusxalash" +LogUploadDialog.Buttons.AnalyzeURL="Qaydlar Faylini Tahlil Qilish" +LogUploadDialog.Buttons.RetryButton="Qayta urinish" +LogUploadDialog.Errors.Template="Faylni yuklashda xatolik yuz berdi:\n\n%1" +LogUploadDialog.Errors.NoLogFile="Yuklash uchun fayl topilmadi yoki fayl boʻsh." +Remux.SourceFile="OBS Yozuvi" +Remux.TargetFile="Yakuniy Fayl" +Remux.Remux="Qadoq" +Remux.Stop="Qadoqlashni Toʻxtatish" +Remux.ClearFinished="Yakunlangan Buyumlarni Tozalash" +Remux.ClearAll="Barcha Buyumlarni Tozalash" +Remux.OBSRecording="OBS Yozuvi" +Remux.FinishedTitle="Qadoqlash yakunlandi" +Remux.Finished="Yozuv qadoqlandi" +Remux.FinishedError="Yozuv qadoqlandi, ammo fayl butun boʻlmasligi mumkin" +Remux.SelectRecording="OBS Yozuvini Tanlash..." +Remux.SelectTarget="Yakuniy faylni tanlash..." +Remux.FileExistsTitle="Yakuniy fayllar mavjud" +Remux.FileExists="Quyidagi yakuniy fayllar allaqachon mavjud. Ularni qayta yozishni istaysizmi?" +Remux.ExitUnfinishedTitle="Qadoqlanmoqda" +Remux.HelpText="Qadoqlash uchun fayllarni ushbu oynaga tashlang yoki faylni qidirish uchun boʻsh \"OBS Yozuvi\" katakchasini tanlang." +Remux.NoFilesAddedTitle="Qadoqlash fayli qoʻshilmagan" +Remux.NoFilesAdded="Qadoqlash uchun fayl qoʻshilmadi. Bir yoki bir nechta video fayllarni oʻz ichiga olgan jildni tashlang." +MissingFiles="Yetishmayotgan Fayllar" +MissingFiles.MissingFile="Yetishmayotgan Fayl" +MissingFiles.NewFile="Yangi Fayl" +MissingFiles.HelpText="OBS soʻnggi foydalanuvidan soʻng ayrim fayllar topilmadi." +MissingFiles.Clear="<tozalandi>" +MissingFiles.NumFound="%2 tadan %1 tasi topildi" +MissingFiles.Search="Jildni Qidirish..." +MissingFiles.SelectFile="Faylni tanlash..." +MissingFiles.SelectDir="Qidirish Uchun Jildni Tanlash" MissingFiles.State="Holat" +MissingFiles.Missing="Topilmadi" +MissingFiles.Replaced="Almashtirildi" +MissingFiles.Cleared="Tozalandi" +MissingFiles.Found="Topildi" +MissingFiles.AutoSearch="Qoʻshimcha mos keluvchi fayllar topildi" +MissingFiles.AutoSearchText="OBS bu jildda boshqa mos fayllarni topdi. Ularni qoʻshasizmi?" +MissingFiles.NoMissing.Title="Yetishmayotgan Fayllarni Tekshirish" +MissingFiles.NoMissing.Text="Yetishmayotgan fayllar mavjud emas." +MacPermissions.MenuAction="Ilova Ruxsatlarini Koʻrib Chiqish..." +MacPermissions.Title="Ilova Ruxsatlarini Koʻrib Chiqish" +MacPermissions.Description="OBS Studio ayrim xususiyatlari uchun ruxsatingiz talab qilinadi. Ushbu ruxsatlarni yoqish tavsiya etiladi, biroq ilovadan foydalanish uchun ular shart emas. Ularni istalgan vaqt keyinroq yoqishingiz mumkin." +MacPermissions.Description.OpenDialog="Ushbu dialog oynasini OBS Studio menyusi orqali qayta ochishingiz mumkin." +MacPermissions.AccessGranted="Kirishga Ruxsat berildi" +MacPermissions.RequestAccess="Kirishni Soʻrash" +MacPermissions.OpenPreferences="%1 Sozlamalarini Ochish" +MacPermissions.Item.ScreenRecording="Ekran Yozuvi" +MacPermissions.Item.ScreenRecording.Details="Ekranni yozib olish uchun ‘OBS’ga ushbu ruxsat kerak." MacPermissions.Item.Camera="Kamera" +MacPermissions.Item.Camera.Details="Veb-kamera yoki yozib olish kartasidan kontent olish uchun ushbu ruxsat zarur." +MacPermissions.Item.Microphone="Mikrofon" +MacPermissions.Item.Microphone.Details="Mikrofon yoki tashqi audio qurilmasini yozib olish uchun ‘OBS’ga ushbu ruxsat kerak." +MacPermissions.Item.InputMonitoring="Kiritish Nazorati" +MacPermissions.Item.InputMonitoring.Details="OBS orqa fonda boʻlgan paytda tezkor tugmalar ishlashi uchun ushbu ruxsat talab qilinadi." +MacPermissions.Item.Accessibility="Maxsus Imkoniyatlar" +MacPermissions.Item.Accessibility.Details="Eski oʻrnatmalarda OBS \"Kiritish Nazorati\" oʻrniga \"Maxsus Imkoniyatlar\" boʻlimida koʻrsatilgan boʻlishi mumkin." MacPermissions.Continue="Davom etish" +SourceLeak.Title="Manbani Tozalash Xatoligi" +SourceLeak.Text="Sahna toʻplamlarini almashtirishda muammo yuz berdi va ayrim manbalar yopilmadi. Bu odatda resurslarni toʻgʻri taqsimlamagan kengaytmalar tufayli yuz beradi. Ishlatilayotgan barcha kengaytmalarni yangi ekanligiga ishonch hosil qiling.\n\nMaʼlumotlar buzilishini oldini olish maqsadida OBS Studio yopiladi." +Basic.DesktopDevice1="Ish Stoli Audiosi" +Basic.DesktopDevice2="Ish Stoli Audiosi 2" +Basic.AuxDevice1="Mik/Aux" +Basic.AuxDevice2="Mik/Aux 2" +Basic.AuxDevice3="Mik/Aux 3" +Basic.AuxDevice4="Mik/Aux 4" Basic.Scene="Sahna" +Basic.DisplayCapture="Ekranni Yozib olish" +Basic.Main.PreviewConextMenu.Enable="Koʻrib chiqishni Yoqish" +Basic.Main.Preview.Disable="Koʻrib chiqishni Oʻchirish" +ScaleFiltering="Ko’lamni Filtrlash" +ScaleFiltering.Point="Nuqtali" +ScaleFiltering.Bilinear="Bilineal" +ScaleFiltering.Bicubic="Bikubik" +ScaleFiltering.Lanczos="Lantsosh" +ScaleFiltering.Area="Soha" +BlendingMethod="Birlashtirish Usuli" +BlendingMethod.Default="Birlamchi" +BlendingMethod.SrgbOff="sRGB Oʻchiq" +BlendingMode="Birlashtirish Tartibi" +BlendingMode.Normal="Odatiy" +BlendingMode.Additive="Qoʻshish" +BlendingMode.Subtract="Ayirish" +BlendingMode.Screen="Ekran" +BlendingMode.Multiply="Koʻpaytirish" +BlendingMode.Lighten="Yorugʻlashtirish" +BlendingMode.Darken="Qorongʻilashtirish" +Deinterlacing="Qatlamasizlash" +Deinterlacing.Discard="Rad etish" +Deinterlacing.TopFieldFirst="Avval Yuqori Maydon" +Deinterlacing.BottomFieldFirst="Avval Quyi Maydon" +VolControl.SliderUnmuted="'%1' uchun tovush balandligi slayderi:" +VolControl.SliderMuted="'%1' uchun tovush balandligi slayderi: (hozirda ovozsiz)" +VolControl.Mute="'%1' ovozsizlash" +VolControl.Properties="'%1' xususiyatlari" +VolControl.UnassignedWarning.Title="Biriktirilmagan Audio Manbasi" +VolControl.UnassignedWarning.Text="%1\" audio yoʻlakchalarga biriktirilmagan va strim yoki yozuvlarda eshitilmaydi.\n\nUni yoʻlakchaga biriktirish uchun menyu varaqasidagi Tahrirlash menyusi yoki qorishtirgich dokidagi tishli gʻildirakcha tugma orqali Murakkab Audio Xususiyatlarini oching." +Basic.Main.AddSceneDlg.Title="Sahna Qoʻshish" +Basic.Main.AddSceneDlg.Text="Iltimos, sahna nomini kiriting" +Basic.Main.DefaultSceneName.Text="Sahna %1" +Basic.Main.AddSceneCollection.Title="Sahnalar Toʻplamini Qoʻshish" +Basic.Main.AddSceneCollection.Text="Iltimos, sahnalar toʻplami nomini kiriting" +Basic.Main.RenameSceneCollection.Title="Sahnalar Toʻplamini Qaytanomlash" +Basic.Main.RemigrateSceneCollection.Title="Sahnalar Toʻplami Oʻlchamini Yangilash" +Basic.Main.RemigrateSceneCollection.Text="\"%1\" sahnalar toʻplami oʻlchamini joriy profilning %2x%3 ish maydoni oʻlchamiga moslab yangilashni xohlaysizmi?" +Basic.Main.RemigrateSceneCollection.CannotMigrate.Active="Chiqishlar faol boʻlganda sahnalar toʻplami oʻlchamini yangilab boʻlmaydi." +Basic.Main.RemigrateSceneCollection.CannotMigrate.UnknownBaseResolution="Sahnalar toʻplami oʻlchamini yangilash amalga oshirilmadi. Asl oʻlcham nomaʼlum." +Basic.Main.RemigrateSceneCollection.CannotMigrate.FailedVideoReset="Qaytarish imkonsiz: OBS oʻlchamini oʻzgartirish amalga oshirilmadi." +Basic.Main.RemigrateSceneCollection.CannotMigrate.BaseResolutionMatches="Qaytarish imkonsiz: Joriy oʻlcham allaqachon sahnalar toʻplamining asosiy oʻlchami." +AddProfile.Title="Profil Qoʻshish" +AddProfile.Text="Iltimos, profil nomini kiriting" +AddProfile.WizardCheckbox="Avto-tuzimlash ustasini koʻrsatish" +RenameProfile.Title="Profilni Qaytanomlash" +Basic.Main.MixerRename.Title="Audio Manbasini Qaytanomlash" +Basic.Main.MixerRename.Text="Iltimos, audio manbasi nomini kiriting" +Basic.Main.PreviewDisabled="Oldindan koʻrish hozir oʻchirilgan" +Basic.SourceSelect="Manba qo‘shish" +Basic.SourceSelect.SelectType="Manba Turi" +Basic.SourceSelect.Recent="Yaqinda Yaratilgan" +Basic.SourceSelect.Description="Joriy sahnaga qoʻshish uchun manba(lar)ni tanlang." +Basic.SourceSelect.NewSource="Yangi %1 qoʻshish" +Basic.SourceSelect.AddExisting="Mavjud %1 qoʻshish" +Basic.SourceSelect.NoSelection="Mavjudini qoʻshish" +Basic.SourceSelect.CreateButton="Yangisini Yaratish" +Basic.SourceSelect.AddVisible="Manbani koʻrinadigan qilish" +Basic.SourceSelect.NoExisting="Sizda hali mavjud %1 manbalari yoʻq." +Basic.SourceSelect.Accessible.SourceName="Manba Nomi" +Basic.SourceSelect.Accessible.Existing="Mavjud manbani qoʻshish" +Basic.SourceSelect.Deprecated.Create="Bu manba turi eskirgan va kelgusida olib tashlanishi mumkin." +Basic.Main.Sources.Visibility="Koʻrinuvchanlik" +Basic.Main.Sources.VisibilityDescription="Ish maydonida '%1' koʻrinuvchanligini boshqaradi" +Basic.Main.Sources.Lock="Qulflash" +Basic.Main.Sources.LockDescription="Ish maydonida '%1' joylashuvi va koʻlamini qulflaydi" +Basic.PropertiesWindow="'%1' xususiyatlari" +Basic.PropertiesWindow.AutoSelectFormat="%1 (avtotanlov: %2)" +Basic.PropertiesWindow.SelectColor="Rangni tanlash" +Basic.PropertiesWindow.SelectFont="Shriftni tanlash" +Basic.PropertiesWindow.SelectFont.WindowTitle="Shriftni Tanlash" +Basic.PropertiesWindow.ConfirmTitle="Sozlamalar Oʻzgartirildi" +Basic.PropertiesWindow.Confirm="Saqlanmagan oʻzgarishlar bor. Ularni saqlashni xohlaysizmi?" +Basic.PropertiesWindow.NoProperties="Xususiyatlar mavjud emas" +Basic.PropertiesWindow.AddFiles="Fayllarni Qoʻshish" +Basic.PropertiesWindow.AddDir="Jild Qoʻshish" +Basic.PropertiesWindow.AddURL="Manzil/URL Qoʻshish" +Basic.PropertiesWindow.AddEditableListDir="'%1' ichiga jild qoʻshish" +Basic.PropertiesWindow.AddEditableListFiles="'%1' ichiga fayllar qoʻshish" +Basic.PropertiesWindow.AddEditableListEntry="'%1' ichiga kiritma qoʻshish" +Basic.PropertiesWindow.EditEditableListEntry="'%1' ichidagi kiritmani tahrirlash" Basic.PropertiesView.FPS.Simple="Oddiy FPS qiymatlari" Basic.PropertiesView.FPS.Rational="Ratsional FPS qiymatlari" Basic.PropertiesView.FPS.ValidFPSRanges="Yaroqli FPS diapazoni:" -Basic.PropertiesView.UrlButton.Text="Ushbu havolani birlamchi veb‑brauzerda ochasizmi?" -Basic.PropertiesView.UrlButton.OpenUrl="URLʼni ochish" +Basic.PropertiesView.UrlButton.Text="Bu havolani standart veb-brauzeringizda ochmoqchimisiz?" +Basic.PropertiesView.UrlButton.Text.Url="Veb-manzil (URL): %1" +Basic.PropertiesView.UrlButton.OpenUrl="Veb-manzilni (URL) ochish" +Basic.InteractionWindow="'%1' bilan aloqa qilinmoqda" +Basic.StatusBar.Reconnecting="Aloqa uzildi, %2 soniyada qayta ulanmoqda (%1-urinish)" +Basic.StatusBar.AttemptingReconnect="Qayta ulanmoqda... (%1-urinish)" +Basic.StatusBar.ReconnectSuccessful="Qayta ulandi" +Basic.StatusBar.Delay="Kechiktirish (%1 soniya)" +Basic.StatusBar.DelayStartingIn="Kechiktirish (%1 soniyadan soʻng boshlanmoqda)" +Basic.StatusBar.DelayStoppingIn="Kechiktirish (%1 soniyada toʻxtatilmoqda)" +Basic.StatusBar.DelayStartingStoppingIn="Kechiktirish (%1 soniyada toʻxtatilmoqda, %2 soniyada boshlanmoqda)" +Basic.StatusBar.RecordingSavedTo="Yozib olish '%1' manziliga saqlandi" +Basic.StatusBar.ReplayBufferSavedTo="Takrorlash buferi '%1' manziliga saqlandi" +Basic.StatusBar.ScreenshotSavedTo="Skrinshot '%1' manziliga saqlandi" +Basic.StatusBar.AutoRemuxedTo="Yozib olish '%1' manziliga avtomatik qadoqlandi" Basic.Filters="Filtrlar" -Basic.Filters.AsyncFilters="Audio/Video filtrlar" +Basic.Filters.AsyncFilters="Audio/Video filtrlari" Basic.Filters.AudioFilters="Audio filtrlar" Basic.Filters.EffectFilters="Effekt filtrlari" Basic.Filters.Title="'%1' uchun filtr" Basic.Filters.AddFilter.Title="Filtr nomi" Basic.Filters.AddFilter.Text="Filtr nomini kiriting" +Basic.TransformWindow="Sahna Buyumini Shakllantirish" Basic.TransformWindow.Position="Pozitsiya" Basic.TransformWindow.Rotation="Aylanish" Basic.TransformWindow.Size="Oʻlcham" Basic.TransformWindow.Width="Kenglik" Basic.TransformWindow.Height="Balandlik" +Basic.TransformWindow.Alignment="Tekislash" Basic.TransformWindow.BoundsType="Chegaralar turi" +Basic.TransformWindow.BoundsAlignment="Hoshiyani Tekislash" Basic.TransformWindow.Bounds="Chegaralar" +Basic.TransformWindow.BoundsWidth="Cheklovchi Quti Kengligi" +Basic.TransformWindow.BoundsHeight="Cheklovchi Quti Balandligi" +Basic.TransformWindow.CropToBounds="Hoshiyalarni Qirqish" +Basic.TransformWindow.Crop="Qirqish" +Basic.TransformWindow.CropLeft="Chapdan Qirqish" +Basic.TransformWindow.CropRight="Oʻngdan Qirqish" +Basic.TransformWindow.CropTop="Yuqoridan Qirqish" +Basic.TransformWindow.CropBottom="Quyidan Qirqish" +Basic.TransformWindow.Accessible.PositionX="X Joylashuvi" +Basic.TransformWindow.Accessible.PositionY="Y Joylashuvi" +Basic.TransformWindow.Alignment.TopLeft="Yuqori Chap" +Basic.TransformWindow.Alignment.TopCenter="Yuqori Markaz" +Basic.TransformWindow.Alignment.TopRight="Yuqori Oʻng" +Basic.TransformWindow.Alignment.CenterLeft="Markaz Chap" +Basic.TransformWindow.Alignment.Center="Markaz" +Basic.TransformWindow.Alignment.CenterRight="Markaz Oʻng" +Basic.TransformWindow.Alignment.BottomLeft="Quyi Chap" +Basic.TransformWindow.Alignment.BottomCenter="Quyi Markaz" +Basic.TransformWindow.Alignment.BottomRight="Quyi Oʻng" +Basic.TransformWindow.BoundsType.None="Avtomatik" +Basic.TransformWindow.BoundsType.MaxOnly="Faqat eng yuqori hajm" +Basic.TransformWindow.BoundsType.ScaleInner="Moslashtirish" +Basic.TransformWindow.BoundsType.ScaleOuter="Qoplash" +Basic.TransformWindow.BoundsType.ScaleToWidth="Kenglikni Toʻldirish" +Basic.TransformWindow.BoundsType.ScaleToHeight="Balandlikni Toʻldirish" +Basic.TransformWindow.BoundsType.Stretch="Choʻzish" +Basic.TransformWindow.Title="'%1' uchun Shaklni oʻzgartirishni Tahrirlash" +Basic.TransformWindow.NoSelectedSource="Manba tanlanmagan" +Basic.Main.AddSourceHelp.Title="Manba Qoʻshish Imkonsiz" +Basic.Main.AddSourceHelp.Text="Manba qoʻshish uchun sizda kamida 1 ta sahna boʻlishi kerak." Basic.Main.Scenes="Sahnalar" Basic.Main.Sources="Manbalar" Basic.Main.Source="Manba" +Basic.Main.Controls="Nazoratlar" Basic.Main.PreparingStream="Tayyorlanmoqda..." Basic.Main.Connecting="Ulanmoqda..." +Basic.Main.StartRecording="Yozib olishni Boshlash" +Basic.Main.StartReplayBuffer="Takrorlash Buferini Boshlash" +Basic.Main.SaveReplay="Takrorlashni Saqlash" Basic.Main.StartStreaming="Strimni boshlash" Basic.Main.StartBroadcast="Efirga chiqish" +Basic.Main.StartVirtualCam="Virtual Kamerani Boshlash" +Basic.Main.StopRecording="Yozib olishni Toʻxtatish" +Basic.Main.PauseRecording="Yozib olishni Tanaffuslash" +Basic.Main.UnpauseRecording="Yozib olishni Davom ettirish" +Basic.Main.SplitFile="Yozib olish Faylini Ajratish" +Basic.Main.AddChapterMarker="Bob Belgisini Qoʻshish (Faqat Aralash MP4/MOV)" +Basic.Main.StoppingRecording="Yozib olish Toʻxtatilmoqda..." +Basic.Main.StopReplayBuffer="Takrorlash Buferini Toʻxtatish" +Basic.Main.StoppingReplayBuffer="Takrorlash Buferi Toʻxtatilmoqda..." +Basic.Main.SetupBroadcast="Translyatsiyani Boshqarish" Basic.Main.StopStreaming="Strimni toʻxtatish" Basic.Main.StopBroadcast="Translyatsiyani yakunlash" +Basic.Main.AutoStopEnabled="(Avtomatik Toʻxtatish)" Basic.Main.StoppingStreaming="Strim toʻxtatilmoqda..." +Basic.Main.ForceStopStreaming="Jonli efirni Toʻxtatish (kechiktirishni rad etish)" +Basic.Main.ShowContextBar="Manba Uskunalar varaqasini Koʻrsatish" +Basic.Main.HideContextBar="Manba Uskunalar varaqasini Yashirish" Basic.Main.StopVirtualCam="Virtual kamerani toʻxtatish" Basic.Main.Group="%1‑guruh" Basic.Main.NewGroup="Yangi guruh" +Basic.Main.GroupItems="Tanlangan Buyumlarni Guruhlash" +Basic.Main.Ungroup="Guruhdan ajratish" +Basic.Main.GridMode="Toʻr Tartibi" Basic.Main.ListMode="Roʻyxat rejimi" Basic.Main.VirtualCamConfig="Virtual kamerani sozlash" Basic.VCam.VirtualCamera="Virtual kamera" +Basic.VCam.OutputType="Chiqish Turi" +Basic.VCam.OutputSelection="Chiqishni Tanlash" Basic.VCam.OutputType.Program="Dastur (birlamchi)" +Basic.VCam.OutputSelection.NoSelection="Ushbu chiqish turi uchun tanlanma yoʻq" +Basic.VCam.RestartWarning="Ushbu oʻzgartirishni qoʻllash uchun virtual kamera qayta ishga tushiriladi" Basic.MainMenu.File="&Fayl" Basic.MainMenu.File.Export="&Eksport" +Basic.MainMenu.File.Import="&Olib kirish" +Basic.MainMenu.File.ShowRecordings="&Yozuvlarni Koʻrsatish" +Basic.MainMenu.File.Remux="Yozuvlarni &Qadoqlash" Basic.MainMenu.File.Settings="&Sozlamalar" Basic.MainMenu.File.ShowSettingsFolder="Sozlamalar jildini ochish" +Basic.MainMenu.File.ShowProfileFolder="Profil Jildini Koʻrsatish" +Basic.MainMenu.File.ShowMissingFiles="Yetishmayotgan Fayllarni Tekshirish" +Basic.MainMenu.File.Exit="Dasturdan ch&iqish" +Basic.MainMenu.Edit="&Tahrirlash" +Basic.MainMenu.Edit.LockPreview="Oldindan koʻrishni Q&ulflash" +Basic.MainMenu.Edit.Scale="Oldindan koʻrishni &Koʻlamlash" +Basic.MainMenu.Edit.Scale.Window="Oynaga Koʻlamlash" +Basic.MainMenu.Edit.Scale.Canvas="Ish maydoni (%1x%2)" +Basic.MainMenu.Edit.Scale.Output="Chiqish (%1x%2)" +Basic.MainMenu.Edit.Scale.Manual="Koʻlamlangan (%1x%2)" +Basic.MainMenu.Edit.Scale.ZoomIn="Yaqinlashtirish" +Basic.MainMenu.Edit.Scale.ZoomOut="Uzoqlashtirish" +Basic.MainMenu.Edit.Scale.ResetZoom="Masshtabni qaytarish" +Basic.MainMenu.Edit.Transform="&Shaklni oʻzgartirish" +Basic.MainMenu.Edit.Transform.EditTransform="Shakl oʻzgarishini &tahrirlash" +Basic.MainMenu.Edit.Transform.CopyTransform="Shakl oʻzgarishini nusxalash" +Basic.MainMenu.Edit.Transform.PasteTransform="Shakl oʻzgarishini joylashtirish" +Basic.MainMenu.Edit.Transform.ResetTransform="Shakl oʻzgarishini &qaytarish" +Basic.MainMenu.Edit.Transform.Rotate90CW="Oʻngga 90 daraja burish" +Basic.MainMenu.Edit.Transform.Rotate90CCW="Chapga 90 daraja burish" +Basic.MainMenu.Edit.Transform.Rotate180="180 daraja burish" +Basic.MainMenu.Edit.Transform.FlipHorizontal="&Eniga akslantirish" +Basic.MainMenu.Edit.Transform.FlipVertical="&Tik akslantirish" +Basic.MainMenu.Edit.Transform.FitToScreen="Ekranga &moslashtirish" +Basic.MainMenu.Edit.Transform.StretchToScreen="Ekranga &choʻzish" +Basic.MainMenu.Edit.Transform.CenterToScreen="Ekran &markaziga joylash" +Basic.MainMenu.Edit.Transform.VerticalCenter="Tikiga markazlash" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Eniga markazlash" +Basic.MainMenu.Edit.Order="&Tartib" +Basic.MainMenu.Edit.Order.MoveUp="Yuqoriga &koʻchirish" +Basic.MainMenu.Edit.Order.MoveDown="Quyiga &koʻchirish" +Basic.MainMenu.Edit.Order.MoveToTop="Eng yuqoriga &koʻchirish" +Basic.MainMenu.Edit.Order.MoveToBottom="Eng quyiga &koʻchirish" +Basic.MainMenu.Edit.AdvAudio="&Murakkab audio xususiyatlari" Basic.MainMenu.View="&Koʻrinish" Basic.MainMenu.View.Toolbars="&Asboblar paneli" +Basic.MainMenu.View.ListboxToolbars="Uskunalar varaqalarini doklash" Basic.MainMenu.View.ContextBar="Manbalar paneli" +Basic.MainMenu.View.SourceIcons="Manba &nishonchalari" +Basic.MainMenu.View.StatusBar="&Holat varaqasi" +Basic.MainMenu.View.Fullscreen.Interface="Toʻliq ekran interfeysi" Basic.MainMenu.View.ResetUI="Interfeysni tiklash" +Basic.MainMenu.View.AlwaysOnTop="&Har doim yuqorida" Basic.MainMenu.View.SceneListMode="Sahnalar ro'yxati rejimi" Basic.MainMenu.Docks="&Doklar" +Basic.MainMenu.Docks.ResetDocks="Doklarni &qaytarish" +Basic.MainMenu.Docks.LockDocks="Doklarni &qulflash" +Basic.MainMenu.Docks.SideDocks="&Toʻliq balandlikdagi doklar" +Basic.MainMenu.Docks.CustomBrowserDocks="&Moslashtirilgan brauzer doklari" +Basic.MainMenu.Import="Olib kirish..." Basic.MainMenu.Export="Eksport..." Basic.MainMenu.SceneCollection="&Sahnalar kolleksiyasi" Basic.MainMenu.Profile="&Profil" @@ -272,6 +701,8 @@ Basic.MainMenu.Profile.Export="Profilni eksport qilish" Basic.MainMenu.SceneCollection.Import="Sahnalar kolleksiyasini import qilish" Basic.MainMenu.SceneCollection.Export="Sahnalar kolleksiyasini eksport qilish" +Basic.MainMenu.SceneCollection.Remigrate="Asosiy oʻlchamni qaytarish" +Basic.MainMenu.SceneCollection.Migrate="Asosiy oʻlchamni oʻrnatish" Basic.MainMenu.Profile.Exists="Profil allaqachon mavjud" Basic.MainMenu.Tools="&Asboblar" Basic.MainMenu.Help="&Yordam" @@ -281,23 +712,67 @@ Basic.MainMenu.Help.WhatsNew="Yangiliklar" Basic.MainMenu.Help.Logs="&Jurnal fayllari" Basic.MainMenu.Help.Logs.ShowLogs="&Jurnal fayllarini koʻrsatish" +Basic.MainMenu.Help.Logs.UploadCurrentLog="&Joriy qaydlar faylini yuklash" +Basic.MainMenu.Help.Logs.UploadLastLog="&Oldingi qaydlar faylini yuklash" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Joriy qaydlarni &koʻrish" +Basic.MainMenu.Help.ReleaseNotes="Nashr qaydlari" +Basic.MainMenu.Help.CheckForUpdates="Yangilanishlarni tekshirish" +Basic.MainMenu.Help.Repair="Fayl yaxlitligini tekshirish" Basic.MainMenu.Help.RestartSafeMode="Xavfsiz rejimda qayta ishga tushirish" Basic.MainMenu.Help.RestartNormal="Normal rejimda qayta ishga tushirish" +Basic.MainMenu.Help.CrashLogs="Qulash &hisobotlari" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Qulash hisobotlarini &koʻrsatish" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Oldingi qulash hisobotini yuklash" Basic.MainMenu.Help.About="Dastur &haqida" Basic.Settings.ProgramRestart="Ushbu sozlamalar kuchga kirishi uchun dastur qaytadan ishga tushirilishi kerak." Basic.Settings.ConfirmTitle="Oʻzgarishlarni tasdiqlash" Basic.Settings.Confirm="Saqlanmagan oʻzgarishlaringiz bor. Ular saqlansinmi?" +Basic.Settings.MultitrackVideoDisabledSettings="%1 %2 baʼzi strim sozlamalaringizni boshqarmoqda" Basic.Settings.General="Umumiy" Basic.Settings.General.Language="Til" Basic.Settings.General.Updater="Yangilanishlar" Basic.Settings.General.UpdateChannel="Yangilash kanali" +Basic.Settings.General.UpdateChannelDisabled="(Oʻchirilgan)" Basic.Settings.General.UpdateChannelDefault="(Birlamchi)" +Basic.Settings.General.EnableAutoUpdates="Yoqilishda yangilanishlarni avtomatik tarzda tekshirish" +Basic.Settings.General.OpenStatsOnStartup="Yoqilishda statistika dialog oynasini ochish" +Basic.Settings.General.HideOBSWindowsFromCapture="Ekran tasvirini olishdan OBS oynalarini yashirish" +Basic.Settings.General.HideOBSWindowsFromCapture.Tooltip="Bu tanlov yoqilganda barcha proyektor boʻlmagan OBS Studio oynalari OBS tomonidan tasvirga olinmaydi va konferensiya, ekran ulashish, masofaviy qoʻllab-quvvatlash, skrinshotlar va boshqa tasvirga olish dasturiy taʼminoti kabi boshqa ilovalarga taʼsir qiladi." Basic.Settings.General.WarnBeforeStartingStream="Strim boshlanganida ogohlantirish koʻrsatilsin" Basic.Settings.General.WarnBeforeStoppingStream="Strim toʻxtatilganida ogohlantirish koʻrsatilsin" +Basic.Settings.General.WarnBeforeStoppingRecord="Yozib olishni toʻxtatishda tasdiqlashni soʻrash" Basic.Settings.General.Projectors="Proyektorlar" +Basic.Settings.General.HideProjectorCursor="Proyektorlar ustida kursorni yashirish" +Basic.Settings.General.ProjectorAlwaysOnTop="Proyektorlarni har doim yuqorida qilish" +Basic.Settings.General.Snapping="Manba tekislanishini ilashtirish" +Basic.Settings.General.ScreenSnapping="Manbalarni ekran chetiga ilashtirish" +Basic.Settings.General.CenterSnapping="Manbalarni eniga va tik markazga ilashtirish" +Basic.Settings.General.SourceSnapping="Manbalarni boshqa manbalarga ilashtirish" +Basic.Settings.General.SnapDistance="Ilashtirish sezuvchanligi" +Basic.Settings.General.SpacingHelpers="Piksel tekislash chiziqlarini koʻrsatish" Basic.Settings.General.RecordWhenStreaming="Strim qilganda avtomatik yozib olinsin" Basic.Settings.General.KeepRecordingWhenStreamStops="Strim toʻxtaganda yozib olish davom etsin" +Basic.Settings.General.ReplayBufferWhileStreaming="Striming paytida takrorlash buferini avtomatik tarzda boshlash" +Basic.Settings.General.KeepReplayBufferStreamStops="Strim toʻxtaganda takrorlash buferini faol saqlab qolish" +Basic.Settings.General.SysTray="Tizim maydoni" +Basic.Settings.General.SysTrayWhenStarted="Ishga tushirilganda tizim maydoniga kichraytirish" +Basic.Settings.General.SystemTrayHideMinimize="Har doim ‘vazifalar varaqasi’ oʻrniga ‘tizim maydoni’ga kichraytirish" +Basic.Settings.General.SaveProjectors="Dasturdan chiqishda proyektorlarni saqlash" +Basic.Settings.General.CloseExistingProjectors="Har bir ekran uchun bitta toʻliq ekran proyektorini cheklash" +Basic.Settings.General.Preview="Peshko‘rish" +Basic.Settings.General.OverflowHidden="Ortiqcha qismniyashirish" +Basic.Settings.General.OverflowAlwaysVisible="Ortiqcha qism har doim koʻrinadi" +Basic.Settings.General.OverflowSelectionHidden="Manba koʻrinmas boʻlsa ham ortiqcha qismni koʻrsatish" +Basic.Settings.General.Importers="Olib kiruvchilar" +Basic.Settings.General.AutomaticCollectionSearch="Olib kirishda sahna toʻplamlari uchun maʼlum manzillarni qidirish" +Basic.Settings.General.SwitchOnDoubleClick="Ikki marta bosilganda sahnaga oʻtish" +Basic.Settings.General.StudioPortraitLayout="Portret/tik maketni yoqish" +Basic.Settings.General.TogglePreviewProgramLabels="Oldindan koʻrish/dastur yorliqlarini koʻrsatish" +Basic.Settings.General.Multiview="Ko‘pko‘rinish" +Basic.Settings.General.Multiview.MouseSwitch="Sahnalar oʻrtasida almashtirish uchun bosing" Basic.Settings.General.Multiview.DrawSourceNames="Sahna nomlarini koʻrsatish" +Basic.Settings.General.Multiview.DrawSafeAreas="Xavfsiz sohalarni chizish (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Koʻpkoʻrinish maketi" Basic.Settings.General.MultiviewLayout.Horizontal.Top="Gorizontal, ust (8 ta sahna)" Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Gorizontal, past (8 ta sahna)" Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertikal, chap (8 ta sahna)" @@ -311,6 +786,7 @@ Basic.Settings.General.ChannelName.stable="Stabil" Basic.Settings.General.ChannelDescription.stable="Soʻnggi stabil reliz" Basic.Settings.General.ChannelName.beta="Betalar / reliz kandidatlari" +Basic.Settings.General.ChannelDescription.beta="Potensial beqaror nashrdan oldingi talqinlar" Basic.Settings.Appearance="Koʻrinish" Basic.Settings.Appearance.General="Umumiy" Basic.Settings.Appearance.General.Theme="Tema" @@ -319,28 +795,91 @@ Basic.Settings.Appearance.FontScale="Shrift oʻlchami" Basic.Settings.Appearance.Density="Zichlik" Basic.Settings.Appearance.Classic="Klassik" +Basic.Settings.Appearance.Compact="Zich" +Basic.Settings.Appearance.Normal="Oddiy" +Basic.Settings.Appearance.Comfortable="Qulay" +Basic.Settings.Appearance.OptionsWarning="Ushbu uslub uchun baʼzi tashqi koʻrinish tanlovlari qoʻllanilarli emas." Basic.Settings.Stream="Strim" +Basic.Settings.Stream.Destination="Manzil" Basic.Settings.Stream.Custom.UseAuthentication="Autentifikatsiya ishlatish" Basic.Settings.Stream.Custom.Username="Foydalanuvchi nomi" -Basic.Settings.Stream.Custom.Password="Parol" +Basic.Settings.Stream.Custom.Password="O'ron" +Basic.Settings.Stream.Custom.Username.ToolTip="RIST: srp_username kiriting.\nRTMP: foydalanuvchi ismini kiriting.\nSRT: ishlatilmaydi." +Basic.Settings.Stream.Custom.Password.ToolTip="RIST: srp_password kiriting.\nRTMP: oʻronni kiriting.\nSRT: shifrlash maxfiy soʻzini kiriting." +Basic.Settings.Stream.BandwidthTestMode="Sigʻim Tekshiruv tartibini Yoqish" Basic.Settings.Stream.TTVAddon="Twitch chat kengaytmalari" -Basic.Settings.Stream.TTVAddon.None="Yoʻq" +Basic.Settings.Stream.TTVAddon.None="Yo‘q (Bo‘sh)" Basic.Settings.Stream.TTVAddon.Both="BetterTTV va FrankerFaceZ" +Basic.Settings.Stream.MissingSettingAlert="Yetishmayotgan Strim Moslamasi" Basic.Settings.Stream.StreamSettingsWarning="Sozlamalarni ochish" +Basic.Settings.Stream.MissingUrlAndApiKey="URL va strim kaliti topilmadi.\n\nURL va strim kalitini 'strim' boʻlimiga kiritish uchun sozlamalarni oching." +Basic.Settings.Stream.MissingUrl="Strim URL topilmadi.\n\nURLni 'Strim' boʻlimiga kiritish uchun sozlamalarni oching." +Basic.Settings.Stream.MissingStreamKey="Strim kaliti topilmadi.\n\nStrim kalitini 'Strim' boʻlimiga kiritish uchun sozlamalarni oching." +Basic.Settings.Stream.IgnoreRecommended="Striming xizmati sozlama tavsiyalariga eʼtibor bermaslik" +Basic.Settings.Stream.IgnoreRecommended.Warn.Title="Tavsiya etilgan sozlamalarni qayta belgilash" +Basic.Settings.Stream.IgnoreRecommended.Warn.Text="Ogohlantirish: Xizmat cheklovlariga eʼtibor bermaslik strim sifatini pasayishiga olib kelishi yoki strim qilishingizga toʻsqinlik qilishi mumkin.\n\nDavom etilsinmi?" +Basic.Settings.Stream.Recommended.MaxVideoBitrate="Eng yuqori video bitreyti: %1 kbit/s" +Basic.Settings.Stream.Recommended.MaxAudioBitrate="Eng yuqori audio bitreyti: %1 kbit/s" Basic.Settings.Stream.Recommended.MaxResolution="Maksimum rezolyutsiya: %1" Basic.Settings.Stream.Recommended.MaxFPS="Maksimum FPS: %1" Basic.Settings.Stream.SpecifyCustomServer="Maxsus serverni belgilang..." Basic.Settings.Stream.ServiceCustomServer="Maxsus server" Basic.Settings.Stream.EnableMultitrackVideo="%1ʼni yoqish" -Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrateAuto="Avto" -Basic.Settings.Stream.MultitrackVideoMaximumVideoTracksAuto="Avto" +Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrate="Eng yuqori striming sigʻimi" +Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrateAuto="Avtomatik" +Basic.Settings.Stream.MultitrackVideoMaximumVideoTracks="Eng yuqori video yoʻlakchalari" +Basic.Settings.Stream.MultitrackVideoMaximumVideoTracksAuto="Avtomatik" +Basic.Settings.Stream.MultitrackVideoStreamDumpEnable="FLV ga strim tashlashni yoqish (oddiy yozib olish fayli sozlamalaridan foydalanadi)" +Basic.Settings.Stream.MultitrackVideoConfigOverride="Tuzimni Qayta belgilash (JSON)" +Basic.Settings.Stream.MultitrackVideoConfigOverrideEnable="Tuzimni Qayta belgilashni Yoqish" +Basic.Settings.Stream.MultitrackVideoLabel="Koʻp yoʻlakchali Video" +Basic.Settings.Stream.MultitrackVideoExtraCanvas="Qoʻshimcha Ish maydoni" +Basic.Settings.Stream.WHIPSimulcastLabel="Hamtarqatish" +Basic.Settings.Stream.WHIPSimulcastInfo="Hamtarqatish sizga bir nechta video sifatlarini kodlash va yuborish imkonini beradi. Batafsil maʼlumot" +Basic.Settings.Stream.WHIPSimulcastTotalLayers="Jami qatlamlar" Basic.Settings.Stream.AdvancedOptions="Kengaytirilgan sozlamalar" +Basic.Settings.Output="Chiqish" +Basic.Settings.Output.Format="Yozib olish formati" +Basic.Settings.Output.Format.MKV="Matroska videosi (.mkv)" Basic.Settings.Output.Format.hMP4="Gibrid MP4 (.mp4)" Basic.Settings.Output.Format.hMOV="Gibrid MOV (.mp4)" +Basic.Settings.Output.Format.fMP4="Boʻlaklangan MP4 (.mp4)" +Basic.Settings.Output.Format.fMOV="Boʻlaklangan MOV (.mov)" +Basic.Settings.Output.Format.TT.fragmented_mov="Boʻlaklangan MOV yozuvni qismlarga boʻlib yozadi va anʼanaviy MOV fayllaridek yakunlashni talab qilmaydi.\nBu, masalan, BSOD yoki elektr uzilishi natijasida diskka yozish toʻxtab qolsa ham, faylning ijro etilishini kafolatlaydi.\n\nBu barcha pleyerlar va tahrirlovchilarga mos kelmasligi mumkin. Zarur boʻlsa, faylni mosroq formatga oʻtkazish uchun Fayl → Yozuvlarni qadoqlash dan foydalaning." +Basic.Settings.Output.Format.TT.fragmented_mp4="Boʻlaklangan MP4 yozuvni qismlarga boʻlib yozadi va anʼanaviy MP4 fayllaridek yakunlashni talab qilmaydi.\nBu, masalan, BSOD yoki elektr uzilishi natijasida diskka yozish toʻxtab qolsa ham, faylning ijro etilishini kafolatlaydi.\n\nBu barcha pleyerlar va tahrirlovchilarga mos kelmasligi mumkin. Zarur boʻlsa, faylni mosroq formatga oʻtkazish uchun Fayl → Yozuvlarni qadoqlash dan foydalaning." +Basic.Settings.Output.Encoder.Video="Video Kodlovchi" +Basic.Settings.Output.Encoder.Audio="Audio Kodlovchi" +Basic.Settings.Output.SelectDirectory="Yozib olish Jildini Tanlash" +Basic.Settings.Output.DynamicBitrate="Tiqilinchni boshqarish uchun bitreytni dinamik tarzda oʻzgartirish" +Basic.Settings.Output.DynamicBitrate.Beta="Tiqilinchni boshqarish uchun bitreytni dinamik tarzda oʻzgartirish (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="Tiqilinchni kamaytirish uchun kadrlarni tashlab yuborish oʻrniga bitreytni dinamik tarzda oʻzgartiradi.\n\nE'tibor bering, agar to'satdan katta tiqilinch yuz bersa, bu tomoshabinlar uchun kechikishni oshirishi mumkin.\nBitreyt tushib ketganda uni qayta tiklash uchun bir necha daqiqa vaqt ketishi mumkin.\n\nHozirda faqat RTMP uchun qoʻllab-quvvatlanadi." +Basic.Settings.Output.Mode="Chiqish Tartibi" Basic.Settings.Output.Mode.Simple="Oddiy" Basic.Settings.Output.Mode.Adv="Kengaytirilgan" Basic.Settings.Output.Mode.FFmpeg="FFmpeg chiqishi" +Basic.Settings.Output.UseReplayBuffer="Takrorlash Buferini Yoqish" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Eng Yuqori Takrorlash Vaqti" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Eng Yuqori Xotira" +Basic.Settings.Output.ReplayBuffer.Estimate="Chamalangan xotira bandligi: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateTooLarge="Ogohlantirish: %1 MiB chamalangan xotira bandligi tavsiya etilgan %2 MiB eng yuqori miqdoridan katta" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Xotira bandligini chamalab boʻlmaydi. Iltimos, eng yuqori xotira limitini oʻrnating." +Basic.Settings.Output.ReplayBuffer.Prefix="Takrorlash Buferi Fayl Nomi Prefiksi" Basic.Settings.Output.ReplayBuffer.Suffix="Suffiks" +Basic.Settings.Output.ReplayBuffer.UnavailableCustomFFmpeg="Yozib olish turi Moslashtirilgan Chiqish (FFmpeg) qilib oʻrnatilganda takrorlash buferidan foydalanib boʻlmaydi." +Basic.Settings.Output.Simple.SavePath="Yozib olish Manzili" +Basic.Settings.Output.Simple.RecordingQuality="Yozib olish Sifati" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Strim bilan bir xil" +Basic.Settings.Output.Simple.RecordingQuality.Small="Yuqori Sifat, Oʻrtacha Fayl Hajmi" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Farqlanmaydigan Sifat, Katta Fayl Hajmi" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Yoʻqotishsiz Sifat, Juda Katta Fayl Hajmi" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Ogohlantirish: Striming video bitreyti joriy striming xizmati uchun yuqori chegara boʻlgan %1 ga oʻrnatiladi." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Ogohlantirish: Striming audio bitreyti joriy striming xizmati uchun yuqori chegara boʻlgan %1 ga oʻrnatiladi." +Basic.Settings.Output.Simple.Warn.CannotPause="Ogohlantirish: Agar yozib olish sifati \"Strim bilan bir xil\" qilib oʻrnatilgan boʻlsa, yozib olishni toʻxtatib turib boʻlmaydi." +Basic.Settings.Output.Simple.Warn.IncompatibleContainer="Ogohlantirish: Hozirda tanlangan yozib olish formati tanlangan strim kodlovchi(lar)iga mos kelmaydi." +Basic.Settings.Output.Simple.Warn.Encoder="Ogohlantirish: Agar bir vaqtning oʻzida ham strim qilsangiz, ham yozib olsangiz, dasturiy kodlovchi yordamida strimdan farqli sifatda yozib olish qoʻshimcha CPU resurslarini talab qiladi." +Basic.Settings.Output.Simple.Warn.Lossless="Ogohlantirish: Yoʻqotishsiz sifat juda katta hajmdagi fayllarni yaratadi! Yoʻqotishsiz sifat yuqori oʻlcham va kadrlar tezligida har bir daqiqa uchun 7 gigabaytdan ortiq disk xotirasidan foydalanishi mumkin. Agar diskda juda katta miqdorda boʻsh joyingiz boʻlmasa, yoʻqotishsiz sifat uzoq yozuvlar uchun tavsiya etilmaydi. Yoʻqotishsiz sifatdan foydalanganda takrorlash buferidan foydalanib boʻlmaydi." +Basic.Settings.Output.Simple.Warn.Lossless.Msg="Yoʻqotishsiz sifatdan foydalanishni aniq istaysizmi?" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Yoʻqotishsiz sifat ogohlantirishi!" Basic.Settings.Output.Simple.Codec.AAC.Default="AAC (birlamchi)" Basic.Settings.Output.Simple.RecAudioTrack="Audio trek" Basic.Settings.Output.Adv.Rescale.Disabled="Oʻchirilgan" @@ -353,9 +892,12 @@ Basic.Settings.Output.Adv.Audio.Track4="4‑trek" Basic.Settings.Output.Adv.Audio.Track5="5‑trek" Basic.Settings.Output.Adv.Audio.Track6="6‑trek" +Basic.Settings.Output.Adv.Recording="Yozib olinmoqda" Basic.Settings.Output.Adv.Recording.Type="Turi" Basic.Settings.Output.Adv.Recording.Type.Standard="Standart" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Barcha fayllar" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="audio / ovoz" +Basic.Settings.Output.Adv.FFmpeg.FormatVideo="video" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Birlamchi format" Basic.Settings.Output.Adv.FFmpeg.Settings="FFmpeg sozlamalari" Screenshot.StudioProgram="Dastur skrinshotini saqlash" @@ -367,18 +909,25 @@ FilenameFormatting.TT.S="Sekund (00–59)" FilenameFormatting.TT.y="Yil, oxirgi ikkita raqam (00–99)" FilenameFormatting.TT.Y="Yil" +Basic.Settings.Video="video" Basic.Settings.Video.FPSInteger="Butun FPS qiymati" Basic.Settings.Video.FPSFraction="Kasrli FPS qiymati" Basic.Settings.Video.Numerator="Surat" Basic.Settings.Video.Denominator="Maxraj" Basic.Settings.Video.Renderer.Experimental="%1 (Eksperimental)" +Basic.Settings.Audio="audio / ovoz" Basic.Settings.Audio.Channels="Kanallar" Basic.Settings.Audio.MeterDecayRate.Fast="Tez" +Basic.Settings.Audio.DesktopDevice="Ish Stoli Audiosi" +Basic.Settings.Audio.DesktopDevice2="Ish Stoli Audiosi 2" +Basic.Settings.Audio.Disabled="Oʻchirilgan" +Basic.Settings.Accessibility="Maxsus Imkoniyatlar" Basic.Settings.Accessibility.ColorOverrides.Preset.Default="Birlamchi" Basic.Settings.Advanced="Kengaytirilgan" Basic.Settings.Advanced.General.ProcessPriority="Protsess prioriteti" Basic.Settings.Advanced.General.ProcessPriority.High="Yuqori" Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Normaldan yuqori" +Basic.Settings.Advanced.General.ProcessPriority.Normal="Oddiy" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Normaldan past" Basic.Settings.Advanced.Video.ColorFormat="Rang formati" Basic.Settings.Advanced.Video.ColorFormat.BGRA="BGRA (8 bit)" @@ -387,26 +936,48 @@ Basic.Settings.Advanced.Video.ColorRange.Full="Toʻla" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Birlamchi" Basic.Settings.Advanced.StreamDelay="Strim kechikishi" +Basic.Settings.Advanced.StreamDelay.Duration="Davomiyligi" Basic.Settings.Advanced.Network="Tarmoq" +Basic.AudioMixer.Hide="Berkitish" Basic.AudioMixer.Category.Pinned="Qadalgan" -Basic.AudioMixer.Category.Active="Aktiv" -Basic.AudioMixer.Category.Inactive="Passiv" +Basic.AudioMixer.Category.Active="Faol" +Basic.AudioMixer.Category.Inactive="Faol emas" +Basic.AudioMixer.Category.Preview="Peshko‘rish" +Basic.AudioMixer.Layout.Vertical="Vertikal maket" Basic.AdvAudio.Name="Nom" Basic.AdvAudio.Volume="Ovoz balandligi" Basic.AdvAudio.VolumeSource="'%1' uchun ovoz balandligi" +Basic.AdvAudio.Mono="mono" Basic.AdvAudio.Balance="Balans" Basic.AdvAudio.BalanceSource="'%1' uchun balans" Basic.AdvAudio.AudioTracks="Treklar" Basic.Settings.Hotkeys.Filter="Filtr" +Basic.SystemTray.Show="Koʻrsatish" +Basic.SystemTray.Hide="Berkitish" +Hotkeys.Delete="Yoʻq qilish" +Hotkeys.End="tugatish / oxiri" +Hotkeys.PageUp="sahifa Up" +Hotkeys.PageDown="sahifa Down" +Hotkeys.NumLock="Num qulflash" +Hotkeys.ScrollLock="Scroll qulflash" +Hotkeys.CapsLock="Caps qulflash" +Hotkeys.Pause="Tanaffus" Hotkeys.Left="Chapga strelka" Hotkeys.Right="Oʻngga strelka" Hotkeys.Up="Tepaga strelka" Hotkeys.Down="Pastga strelka" +Hotkeys.Windows="oynalar / Windows" +Hotkeys.Menu="menyu" Hotkeys.Space="Boʻshliq" Hotkeys.NumpadMultiply="Numpad *" Hotkeys.NumpadDivide="Numpad /" Hotkeys.NumpadAdd="Numpad +" Hotkeys.NumpadSubtract="Numpad -" +Hotkeys.AppleKeypadNum="%1 (klaviatura)" +Hotkeys.AppleKeypadMultiply="* (klaviatura)" +Hotkeys.AppleKeypadDivide="/ (klaviatura)" +Hotkeys.AppleKeypadAdd="+ (klaviatura)" +Hotkeys.AppleKeypadSubtract="- (klaviatura)" Hotkeys.MouseButton="Sichqoncha %1" SceneItemShow="'%1'ni koʻrsatish" SceneItemHide="'%1'ni yashirish" @@ -418,7 +989,9 @@ About.Donate="Hissa qoʻshish" About.Authors="Avtorlar" About.License="Litsenziya" +AddUrl.Text.Url="Veb-manzil (URL): %1" ResizeOutputSizeOfSource.Continue="Rostan ham davom ettirmoqchimisiz?" +Importer="Sahnalar kolleksiyasini import qilish" Importer.Program="Aniqlangan dastur" ContextBar.NoSelectedSource="Manba tanlanmagan" ContextBar.MediaControls.PlayMedia="Mediani ijro etish" @@ -428,6 +1001,9 @@ YouTube.Actions.ChooseEvent="Mavjud translyatsiyani tanlash" YouTube.Actions.MyBroadcast="Mening translyatsiyam" YouTube.Actions.Description="Tavsif" +YouTube.Actions.Thumbnail.SelectFile="Faylni tanlash..." +YouTube.Actions.Thumbnail.ClearFile="Tozalash" +YouTube.Actions.Latency.Normal="Oddiy" YouTube.Actions.Create_Ready="Translyatsiya yaratish" YouTube.Actions.Create_GoLive="Translyatsiya yaratish va strimni boshlash" YouTube.Actions.Choose_Ready="Translyatsiyani tanlash" @@ -435,3 +1011,5 @@ YouTube.Actions.Dashboard="YouTube Studioʼni ochish" YouTube.Actions.Error.NoStreamCreated="Strim yaratilmadi. Akkauntingizni qaytadan ulang." YouTube.Actions.Stream="Strim" +PluginManager.Section.Discover="Izlash" +PluginManager.Section.Updates="Yangilanishlar"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/vi-VN.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/vi-VN.ini
Changed
@@ -474,9 +474,6 @@ Basic.Main.PreviewDisabled="Xem trước hiện đang vô hiệu hoá" Basic.SourceSelect="Thêm nguồn" Basic.SourceSelect.SelectType="Loại nguồn" -Basic.SourceSelect.Recent="Mới thêm gần đây" -Basic.SourceSelect.NewSource="Tạo nguồn mới" -Basic.SourceSelect.Existing="Thêm nguồn có sẵn" Basic.SourceSelect.CreateButton="Tạo mới" Basic.SourceSelect.AddVisible="Làm cho nguồn có thể nhìn thấy" Basic.Main.Sources.Visibility="Hiển thị" @@ -1124,6 +1121,8 @@ Unmute="Bật tiếng" Push-to-mute="Bấm để tắt tiếng" Push-to-talk="Bấm để nói" +MonitorOn="Bật giám sát" +MonitorOff="Tắt giám sát" SceneItemShow="Hiển thị '%1'" SceneItemHide="Ẩn '%1'" OutputWarnings.NoTracksSelected="Bạn phải chọn ít nhất một rãnh âm" @@ -1284,4 +1283,11 @@ PluginManager.Section.Discover="Duyệt" PluginManager.Section.Manage="Đã cài" PluginManager.Section.Updates="Cập nhật" -PluginManager.Section.Manage.Title="Quản lí các trình cắm đã bật" +EncoderMissing.Title="Thiếu bộ biên mã" +EncoderMissing.Text="Đang thiếu các bộ biên mã sau:\n<ul>\n%1</ul><br>\nXem <a href=\"%2\">bài viết trên cơ sở kiến thức</a> để biết thêm thông tin chi tiết." +EncoderMissing.Unknown="Không rõ" +EncoderMissing.MissingModule="Mô đun \"%1\" không được nạp" +EncoderMissing.NVENC.NoDevices="Không thấy GPU NVIDIA" +EncoderMissing.NVENC.Reason.NvmlLoad="Không nạp được thư viện NVML" +EncoderMissing.NVENC.Reason.NvmlInit="Không khởi tạo NVML được" +EncoderMissing.NVENC.Reason.DriverOutdated="Trình điều khiển lỗi thời"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/zh-CN.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/zh-CN.ini
Changed
@@ -127,6 +127,10 @@ CrashHandling.Buttons.LaunchNormal="以正常模式运行" CrashHandling.Errors.UploadJSONError="尝试上传最新的崩溃日志时出错。请稍后重试。" CrashHandling.Errors.Title="崩溃日志上传错误" +PluginFailure.Dialog.Title="插件错误" +PluginFailure.Labels.Text="OBS Studio 无法加载所有第三方插件。\n\n更多详情可在插件管理器中查看。" +PluginFailure.Dialog.Continue="忽略" +PluginFailure.Dialog.Open="打开插件管理器" SafeMode.Restart="您要以安全模式重启 OBS(禁用第三方插件、脚本和 WebSocket)吗?" SafeMode.RestartNormal="您要以正常模式重启 OBS 吗?" ChromeOS.Title="不支持的平台" @@ -509,12 +513,14 @@ Basic.Main.PreviewDisabled="预览当前已禁用" Basic.SourceSelect="添加源" Basic.SourceSelect.SelectType="源类型" -Basic.SourceSelect.Recent="最近添加" -Basic.SourceSelect.NewSource="创建新源" -Basic.SourceSelect.Existing="添加现有源" +Basic.SourceSelect.Recent="最近创建" +Basic.SourceSelect.Description="选择要添加到当前场景的源。" +Basic.SourceSelect.NewSource="添加新的 %1" +Basic.SourceSelect.AddExisting="添加 %1 个现有" +Basic.SourceSelect.NoSelection="添加现有" Basic.SourceSelect.CreateButton="新建" Basic.SourceSelect.AddVisible="使源可见" -Basic.SourceSelect.NoExisting="无现有 %1 源" +Basic.SourceSelect.NoExisting="暂无现有 %1 源。" Basic.SourceSelect.Accessible.SourceName="源名称" Basic.SourceSelect.Accessible.Existing="添加现有源" Basic.SourceSelect.Deprecated.Create="此源类型已被标记为已弃用,将来可能会被移除。" @@ -1198,6 +1204,8 @@ Unmute="取消静音" Push-to-mute="按住静音" Push-to-talk="按住讲话" +MonitorOn="启用监控" +MonitorOff="禁用监控" SceneItemShow="显示“%1”" SceneItemHide="隐藏“%1”" OutputWarnings.NoTracksSelected="您必须选择至少一个轨道" @@ -1363,5 +1371,40 @@ PluginManager.Section.Discover="浏览" PluginManager.Section.Manage="已安装" PluginManager.Section.Updates="更新" -PluginManager.Section.Manage.Title="管理已启用的插件" +PluginManager.Section.Manage.Title="已安装" +PluginManager.Section.Manage.Description="管理您当前安装的插件。" +PluginManager.Section.Manage.NoPlugins="未找到插件。" +PluginManager.Section.Errors.Title="错误" +PluginManager.Section.Errors.Description="这些插件未能加载。请确保它们是最新版本并与此版本的 OBS Studio 兼容。" +PluginManager.Section.Missing.Title="缺少" +PluginManager.Section.Missing.Description="这些插件之前已安装,但现在找不到了。" +PluginManager.Button.Enable="启用 %1 插件" +PluginManager.Status.Legacy="旧版" +PluginManager.Status.Disabled="已禁用" +PluginManager.Status.Error="错误" +PluginManager.Status.Missing="缺失" +PluginManager.Status.Legacy.Description="该插件安装的位置到了将来会失效。<a href=\"%1\">了解详情</a>" Accessible.Widget.Name.AlignmentSelector="对齐选择器" +EncoderMissing.Title="缺少编码器" +EncoderMissing.Text="以下已配置的编码器缺失:\n<ul>\n%1</ul><br>\n请参阅<a href=\"%2\">知识库文章</a>了解更多信息。" +EncoderMissing.ItemText="<li>\n<h3>%1</h3>\n%2(代码:<code>%3</code>)\n</li>" +EncoderMissing.Unknown="未知" +EncoderMissing.MissingModule="模块“%1”未加载" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC 检查程序启动失败" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC 检查过程失败,退出代码:%1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC 检查过程输出读取失败,退出代码:%1" +EncoderMissing.NVENC.TestProgramError="NVENC 检查失败,原因:%1" +EncoderMissing.NVENC.NoDevices="未找到 NVIDIA GPU" +EncoderMissing.NVENC.Unsupported.Kepler="您的 GPU (%1) 的架构 (Kepler) 已不再受支持。请改用 OBS 30.2 或更早版本。" +EncoderMissing.NVENC.Reason.NvmlLoad="加载 NVML 库失败" +EncoderMissing.NVENC.Reason.NvmlInit="NVML 初始化失败" +EncoderMissing.NVENC.Reason.NvencLoad="加载 NVENC 库失败" +EncoderMissing.NVENC.Reason.NvencInit="NVENC 初始化失败" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC 版本为空" +EncoderMissing.NVENC.Reason.CudaLoad="加载 CUDA 库失败" +EncoderMissing.NVENC.Reason.CudaInit="CUDA 初始化失败" +EncoderMissing.NVENC.Reason.CudaVersion="CUDA 版本无效/缺失" +EncoderMissing.NVENC.Reason.DriverOutdated="驱动程序过时" +EncoderMissing.NVENC.Reason.NoSupportedDevices="未找到支持 NVENC 的 NVIDIA 设备" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="已超出编码器会话限制" +EncoderMissing.NVENC.Reason.AV1Unsupported="该系统的所有 NVIDIA GPU 均不支持 AV1 编码。"
View file
obs-studio-32.2.2.tar.xz/frontend/data/locale/zh-TW.ini -> obs-studio-33.0.0.tar.xz/frontend/data/locale/zh-TW.ini
Changed
@@ -127,6 +127,10 @@ CrashHandling.Buttons.LaunchNormal="以一般模式執行" CrashHandling.Errors.UploadJSONError="嘗試上傳最新的當機記錄時發生錯誤。請稍後再試。" CrashHandling.Errors.Title="當機記錄上傳錯誤" +PluginFailure.Dialog.Title="外掛錯誤" +PluginFailure.Labels.Text="OBS Studio 無法載入所有第三方外掛。 \n\n更多詳情請查看外掛管理器。" +PluginFailure.Dialog.Continue="略過" +PluginFailure.Dialog.Open="開啟外掛管理器" SafeMode.Restart="您是否想將 OBS 重新啟動至安全模式(也就是停用第三方外掛程式、指令稿和 WebSocket)?" SafeMode.RestartNormal="你要以一般模式重新啟動 OBS 嗎?" ChromeOS.Title="不支援的平台" @@ -508,14 +512,16 @@ Basic.Main.PreviewDisabled="目前預覽已停用" Basic.SourceSelect="加入來源" Basic.SourceSelect.SelectType="來源類型" -Basic.SourceSelect.Recent="近期加入" -Basic.SourceSelect.NewSource="建立新來源" -Basic.SourceSelect.Existing="加入現存來源" +Basic.SourceSelect.Recent="最近建立" +Basic.SourceSelect.Description="選擇要新增至目前場景的來源。" +Basic.SourceSelect.NewSource="新增一個新的 %1" +Basic.SourceSelect.AddExisting="新增現有的 %1" +Basic.SourceSelect.NoSelection="加入已建立來源" Basic.SourceSelect.CreateButton="新增" Basic.SourceSelect.AddVisible="顯示來源" -Basic.SourceSelect.NoExisting="沒有現有的 %1 來源" +Basic.SourceSelect.NoExisting="您目前尚無任何現有的 %1 來源。" Basic.SourceSelect.Accessible.SourceName="來源名稱" -Basic.SourceSelect.Accessible.Existing="加入現存來源" +Basic.SourceSelect.Accessible.Existing="新增現有來源" Basic.SourceSelect.Deprecated.Create="此來源類型已被標記為棄用,未來可能會被移除。" Basic.Main.Sources.Visibility="可見性" Basic.Main.Sources.VisibilityDescription="控制畫布中「%1」的可見性" @@ -1213,6 +1219,8 @@ Unmute="取消靜音" Push-to-mute="按壓時靜音" Push-to-talk="按壓時說話" +MonitorOn="啟用監聽" +MonitorOff="停用監聽" SceneItemShow="顯示 「%1」" SceneItemHide="隱藏 「%1」" OutputWarnings.NoTracksSelected="您必須至少選擇一個軌道" @@ -1379,5 +1387,39 @@ PluginManager.Section.Discover="瀏覽" PluginManager.Section.Manage="已安裝" PluginManager.Section.Updates="更新" -PluginManager.Section.Manage.Title="管理已啟用的外掛" +PluginManager.Section.Manage.Title="已安裝" +PluginManager.Section.Manage.Description="管理您目前已安裝的軟體" +PluginManager.Section.Manage.NoPlugins="未找到外掛程式。" +PluginManager.Section.Errors.Title="錯誤" +PluginManager.Section.Errors.Description="這些外掛載入失敗。請確保它們已更新至最新版本並與此版本的 OBS Studio 相容。" +PluginManager.Section.Missing.Title="遺失" +PluginManager.Section.Missing.Description="這些外掛之前已安裝,但現己遺失。" +PluginManager.Button.Enable="啟用 %1 外掛" +PluginManager.Status.Legacy="舊版" +PluginManager.Status.Disabled="已停用" +PluginManager.Status.Error="錯誤" +PluginManager.Status.Missing="遺失" +PluginManager.Status.Legacy.Description="此外掛安裝到的位置將來會失效。<a href=\"%1\">了解更多</a>" Accessible.Widget.Name.AlignmentSelector="對齊選擇器" +EncoderMissing.Title="缺少編碼器" +EncoderMissing.Text="以下已配置的編碼器遺失:\n<ul>\n%1</ul><br>\n請參閱 <a href=\"%2\">知識庫文章</a> 了解更多資訊。" +EncoderMissing.Unknown="未知" +EncoderMissing.MissingModule="模塊“%1”沒有被載入" +EncoderMissing.NVENC.TestProgramFailedStartup="NVENC檢查程式啓動失敗" +EncoderMissing.NVENC.TestProgramExitWithError="NVENC 檢測過程失敗,退出程式碼: %1" +EncoderMissing.NVENC.TestProgramReadFailure="NVENC 檢測進程輸出讀取失敗,退出程式碼: %1" +EncoderMissing.NVENC.TestProgramError="NVENC檢測失敗,錯誤原因:%1" +EncoderMissing.NVENC.NoDevices="未找到 NVDIA GPUs" +EncoderMissing.NVENC.Unsupported.Kepler="您所使用的GPU(%1)不再受支援,請使用OBS 30.2 或者更高的OBS版本" +EncoderMissing.NVENC.Reason.NvmlLoad="NVML庫加載失敗" +EncoderMissing.NVENC.Reason.NvmlInit="NVML 初始化失敗" +EncoderMissing.NVENC.Reason.NvencLoad="NVENC庫加載失敗" +EncoderMissing.NVENC.Reason.NvencInit="NVENC 初始化失敗" +EncoderMissing.NVENC.Reason.NvencVersion="NVENC 版本號為空" +EncoderMissing.NVENC.Reason.CudaLoad="CUDA庫加載失敗" +EncoderMissing.NVENC.Reason.CudaInit="CUDA初始化失敗" +EncoderMissing.NVENC.Reason.CudaVersion="CUDA版本號無效 / 缺失" +EncoderMissing.NVENC.Reason.DriverOutdated="過時的驅動程式" +EncoderMissing.NVENC.Reason.NoSupportedDevices="沒有找到受支援的NVENC的NVDIA裝置" +EncoderMissing.NVENC.Reason.SessionLimitExceeded="編碼器會話數量已超過限制" +EncoderMissing.NVENC.Reason.AV1Unsupported="NV1編碼器不支持任何系統的NVDIA GPUs"
View file
obs-studio-32.2.2.tar.xz/frontend/data/themes/System.obt -> obs-studio-33.0.0.tar.xz/frontend/data/themes/System.obt
Changed
@@ -1,12 +1,13 @@ -/* Intentionally left blank */ -/* Themes are created using Qt CSS, you can visit */ -/* http://doc.qt.io/qt-5/stylesheet-reference.html and */ -/* http://doc.qt.io/qt-5/stylesheet-examples.html for examples. */ - -/* OBS will use the theme filename for the settings. */ -/* You can ship images using relative paths in qss. */ -/* Dark Theme is a good place to start if you need */ -/* a template. */ +/* ------------------------------------------------------------------------- * + * * + * IMPORTANT * + * * + * ------------------------------------------------------------------------- * + * * + * This is a special theme that is not normally selectable by the user. It + * exists only for certain accessibility scenarios but is otherwise unused. + * * + * ------------------------------------------------------------------------- */ @OBSThemeMeta { name: 'System';
View file
obs-studio-32.2.2.tar.xz/frontend/data/themes/Yami.obt -> obs-studio-33.0.0.tar.xz/frontend/data/themes/Yami.obt
Changed
@@ -1,3 +1,26 @@ +/* ------------------------------------------------------------------------- * + * * + * IMPORTANT * + * * + * ------------------------------------------------------------------------- * + * * + * Yami contains many core definitions for the appearance of widgets + * throughout the app. + * + * If you are developing a custom theme it is HIGHLY RECOMMENDED that you + * use Yami as a Base and apply your changes in a Variant Theme (.ovt). + * Creating your own Base Theme means you are opting out of the default + * appearance for all widgets and will be responsible for keeping your base + * theme up to date with every new release! + * + * Do NOT copy Yami into a new base theme only to make minor changes or + * adjustments. Your theme will likely break with every OBS Studio update. + * + * You can learn more about OBS Studio's theme system on our GitHub wiki: + * https://github.com/obsproject/obs-studio/wiki/OBS-Studio-Theme-System + * * + * ------------------------------------------------------------------------- */ + @OBSThemeMeta { name: 'Yami'; id: 'com.obsproject.Yami'; @@ -88,9 +111,6 @@ --primary_dark: var(--blue4); --primary_darker: var(--blue5); - --warning: var(--yellow3); - --danger: var(--red3); - --text: var(--white1); --text_light: var(--white1); --text_muted: var(--white5); @@ -142,6 +162,7 @@ --padding_base_border: calc(var(--padding_base) + 1px); + --spinbox_min_width: calc(var(--input_height) * 2.5); --spinbox_button_height: calc(var(--input_height_half) - 1px); --volume_slider: calc(calc(4px + var(--font_base_value)) / 4); @@ -209,27 +230,23 @@ --tab_border_focus: var(--primary_lighter); --tab_border_selected: var(--primary); - --tab_padding_base: calc(5px + var(--padding_base)); - --tab_padding_large: calc(9px + var(--padding_base)); + --tab_padding_base: var(--padding_large); + --tab_padding_large: calc(0px + var(--padding_wide)); --preview_scale_width: calc(calc(var(--input_text_padding) * 3.5) * calc(var(--font_base_value) / 10)); --separator_hover: var(--white1); --action_row_base: calc(var(--input_height_base) * 0.75); - --action_row_height: calc(var(--action_row_base) + calc(var(--action_row_padding) * 2px)); - --action_row_border: 3px; --action_row_input_width: calc(var(--action_row_base) * 4); - --action_row_collapse: calc(var(--action_row_base) + var(--padding_large)); - --action_row_collapse_radius: calc(var(--action_row_collapse) / 2); - --action_row_padding: calc(var(--padding_large) * 1.5); + --action_row_padding: calc(var(--padding_large) * 1.2); --action_row_padding_x: calc(var(--action_row_padding) * 2); --action_row_padding_nested: calc(var(--action_row_padding_x) * 1.5); --toggle_border: 1; --toggle_margin: 3; - --toggle_width: calc(var(--action_row_base) * 1.8); - --toggle_height: calc(var(--action_row_base) * 0.9); + --toggle_width: calc(var(--action_row_base) * 1.6); + --toggle_height: calc(var(--action_row_base) * 0.8); --toggle_handle: calc(calc(calc(var(--toggle_height) * 0.9) - calc(var(--toggle_border) * 2)) - var(--toggle_margin)); --toggle_radius: calc(var(--toggle_height) / 2); @@ -283,6 +300,30 @@ background-color: var(--bg_base); } +.bg-primary { + background-color: var(--primary); +} + +.bg-secondary { + background-color: var(--teal3); +} + +.bg-info { + background-color: var(--grey8); +} + +.bg-warning { + background-color: var(--yellow6); +} + +.bg-danger { + background-color: var(--red6); +} + +.bg-success { + background-color: var(--green6); +} + .text-title { font-size: var(--font_large); font-weight: bold; @@ -322,17 +363,37 @@ } .text-warning { - color: var(--warning); + color: var(--yellow3); } .text-danger { - color: var(--danger); + color: var(--red3); } .text-success { color: var(--green3); } +.bg-secondary.text-secondary { + color: var(--teal1); +} + +.bg-info.text-info { + color: var(--text_light); +} + +.bg-warning.text-warning { + color: var(--yellow1); +} + +.bg-danger.text-danger { + color: var(--red1); +} + +.bg-success.text-success { + color: var(--green1); +} + .frame-notice { background: var(--grey8); border: 1px solid var(--grey6); @@ -858,8 +919,9 @@ } QDockWidget { - font-size: var(--font_base); + font-size: var(--font_small); font-weight: bold; + color: var(--text_light); titlebar-close-icon: url(theme:Dark/close.svg); titlebar-normal-icon: url(theme:Dark/popout.svg); @@ -867,8 +929,9 @@ QDockWidget::title { text-align: left; - background-color: var(--button_bg); - padding: var(--padding_large); + background-color: var(--grey5); + border: 1px solid var(--grey4); + padding: var(--padding_base) var(--padding_large); border-top-left-radius: var(--border_radius); border-top-right-radius: var(--border_radius); } @@ -1092,15 +1155,21 @@ QTabBar { outline: none; + font-size: var(--font_small); } -QTabWidget::tab-bar { - alignment: left; +QTabBar::top { + border-top-left-radius: 4px; + border-top-right-radius: 4px; } -QTabBar QToolButton { - background: var(--button_bg); - border: none; +QTabBar::bottom { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +QTabWidget::tab-bar { + alignment: left; } QTabBar::tab:top { @@ -1115,13 +1184,12 @@ QTabBar::tab { background: var(--tab_bg); - color: var(--text); - border: none; + color: var(--text_muted); + border: 1px solid var(--tab_bg); padding: var(--tab_padding_base) var(--tab_padding_large); min-width: 50px; margin: 1px 0px; margin-right: 2px; - border: 1px solid var(--tab_border); } QTabBar::tab:pressed { @@ -1139,22 +1207,21 @@ } QTabBar::tab:selected { - background: var(--tab_bg_down); + background: var(--primary); color: var(--text); + border: 1px solid var(--primary_light); } QTabBar::tab:top { - border-bottom: 0px solid transparent; margin-bottom: 0px; } QTabBar::tab:bottom { - border-top: 0px solid transparent; margin-top: 0px; } QTabBar QToolButton { - background: var(--button_bg); + background: var(--tab_bg); min-width: 16px; padding: 0px; } @@ -1284,9 +1351,12 @@ border: var(--input_border_width) solid var(--input_bg); border-radius: var(--border_radius); padding: var(--input_padding) var(--input_text_padding); + padding-right: var(--padding_base); + height: var(--input_height); min-width: var(--spinbox_width); max-height: var(--input_height); + min-width: var(--spinbox_min_width); } QSpinBox:hover, @@ -2488,26 +2558,34 @@ border-color: var(--button_border); } +InfoChip { + font-size: var(--font_small); + font-weight: bold; + padding: 0 var(--padding_large); + border-radius: var(--border_radius); +} + /* Idian Widgets */ -idian--Group { +idian--ListHeader { border-radius: var(--border_radius); font-weight: bold; margin: 0 0 var(--spacing_base); + padding: 0 var(--padding_base); min-width: 300px; - max-width: 600px; } -idian--Group .header .title { +idian--RowList .title { font-weight: bold; - padding: var(--padding_large) 0; + padding: 0; } -idian--Group .header .description { +idian--RowList .description { + font-size: var(--font_small); color: var(--text_muted); - padding: var(--spacing_small) 0; + padding: 0; } -idian--PropertiesList { +idian--RowList { border-width: 0; padding: 0; margin: var(--spacing_base) 0; @@ -2515,13 +2593,14 @@ idian--Row { background: var(--grey5); - margin: 0; padding: var(--action_row_padding) var(--action_row_padding_x); + border-radius: var(--border_radius); + border: var(--input_border_width) solid var(--border_color); } idian--Row.keyFocus { background: var(--grey4); - border: var(--highlight_width) solid var(--grey4); + border: var(--highlight_width) solid var(--highlight_color); } idian--Row.cursor-pointer.hover { @@ -2529,21 +2608,20 @@ border: var(--highlight_width) solid var(--grey1); } -idian--Row.first { +idian--RowList idian--Row { + border-radius: 0; +} + +idian--RowList idian--Row.first { border-top-left-radius: var(--border_radius); border-top-right-radius: var(--border_radius); } -idian--Row.last { +idian--RowList idian--Row.last { border-bottom-left-radius: var(--border_radius); border-bottom-right-radius: var(--border_radius); } -idian--Row > QLabel.description { - font-size: var(--font_small); - color: var(--text_muted); -} - idian--ToggleSwitch { qproperty-background: var(--grey6); qproperty-background_hover: var(--grey7); @@ -2636,7 +2714,7 @@ padding: var(--padding_base) var(--action_row_padding_x); } -idian--PropertiesListSpacer { +idian--RowListSpacer { max-height: var(--spacing_small); min-height: var(--spacing_small); background-color: var(--bg_window); @@ -2673,88 +2751,99 @@ border-color: var(--highlight_color); } -idian--CollapsibleRow { +idian--CollapsibleGroup { margin: 0; padding: 0; border: none; } -idian--CollapsibleRow.keyFocus { +idian--CollapsibleGroup.expanded > idian--Row { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +idian--CollapsibleGroup idian--Row.keyFocus { border: var(--highlight_width) solid var(--highlight_color); } -idian--CollapsibleRow idian--PropertiesList { +idian--CollapsibleGroup idian--RowList { border-radius: 0; border-left: 1px solid var(--grey5); border-right: 1px solid var(--grey5); border-bottom: 1px solid var(--grey5); + border-bottom: 1px solid var(--grey5); margin: var(--spacing_small) 0px 0px; } -idian--CollapsibleRow idian--PropertiesList idian--Row { +idian--CollapsibleGroup idian--RowList idian--Row { background-color: var(--grey6); padding-left: var(--action_row_padding_nested); } -idian--CollapsibleRow idian--Row.first, -idian--CollapsibleRow idian--Row.last { +idian--CollapsibleGroup idian--RowList idian--Row.first { border-radius: 0; } -idian--CollapsibleRow idian--PropertiesList idian--ToggleSwitch { - qproperty-background: var(--grey7); - qproperty-background_hover: var(--grey6); +idian--CollapsibleGroup idian--RowList idian--Row.last { + border-bottom-left-radius: var(--border_radius); + border-bottom-right-radius: var(--border_radius); } -idian--ExpandButton { - background: transparent; - min-width: var(--action_row_collapse); - max-width: var(--action_row_collapse); - min-height: var(--action_row_collapse); - max-height: var(--action_row_collapse); - border: none; +idian--RowList idian--CollapsibleGroup idian--Row.last { + border-radius: 0; } -idian--ExpandButton::indicator { - background: var(--grey5); - border-radius: var(--action_row_collapse_radius); - padding: var(--padding_large); - image: url(theme:Dark/down.svg); - border: var(--highlight_width) solid var(--grey5); +idian--RowList idian--CollapsibleGroup.last idian--Row.last { + border-bottom-left-radius: var(--border_radius); + border-bottom-right-radius: var(--border_radius); } -idian--ExpandButton::indicator:checked { - image: url(theme:Dark/up.svg); +idian--CollapsibleGroup idian--RowList idian--ToggleSwitch { + qproperty-background: var(--grey7); + qproperty-background_hover: var(--grey6); } -idian--ExpandButton.keyFocus, -idian--ExpandButton.keyFocus::indicator { - border-color: var(--highlight_color); +idian--InlineButton, +idian--Row idian--InlineButton { + background: transparent; + min-width: var(--input_height); + min-height: var(--input_height); + border-radius: var(--border_radius); + padding: var(--padding_base); + margin: 0 var(--spacing_base); + + border: var(--highlight_width) solid transparent; } -idian--RowFrame .btn-frame { - background: var(--grey5); - padding: var(--action_row_padding) var(--action_row_padding_x); +idian--InlineButton:hover { + background-color: var(--button_bg_hover); + border-color: var(--input_border_hover); } -idian--RowFrame.hover .btn-frame { - background: var(--grey4); +idian--InlineButton:hover, +idian--Row.hover idian--InlineButton.row-buddy { + border-color: var(--input_border_hover); } -idian--RowFrame.hover idian--Row { - background: var(--grey4); - border: var(--highlight_width) solid var(--grey1); - border-right: none; +idian--InlineButton:pressed { + background-color: var(--button_bg_down); } -idian--RowFrame.hover .row-buddy { - background: var(--grey4); - border: var(--highlight_width) solid var(--grey1); - border-left: none; +idian--InlineButton:focus, +idian--InlineButton.keyFocus, +idian--Row.keyFocus idian--InlineButton, +idian--Row.keyFocus idian--InlineButton.checked { + border-color: var(--highlight_color); } -idian--RowFrame.hover idian--ExpandButton::indicator { - border-color: var(--grey1); +idian--ExpandButton { + qproperty-icon: url(theme:Dark/down.svg); +} + +idian--ExpandButton.checked { + qproperty-icon: url(theme:Dark/up.svg); + background: transparent; + border-color: transparent; } AlignmentSelector {
View file
obs-studio-32.2.2.tar.xz/frontend/data/themes/Yami_Acri.ovt -> obs-studio-33.0.0.tar.xz/frontend/data/themes/Yami_Acri.ovt
Changed
@@ -1,3 +1,21 @@ +/* ------------------------------------------------------------------------- * + * * + * IMPORTANT * + * * + * ------------------------------------------------------------------------- * + * * + * This is a Variant Theme (Style) for Yami named Acri. Variant themes + * override variable values and append additional style rules to the end of + * the final composed stylesheet. + * + * If you are developing a custom theme it is HIGHLY RECOMMENDED that you + * use Yami as a Base and apply your changes in a Variant Theme (.ovt). + * + * You can learn more about OBS Studio's theme system on our GitHub wiki: + * https://github.com/obsproject/obs-studio/wiki/OBS-Studio-Theme-System + * * + * ------------------------------------------------------------------------- */ + @OBSThemeMeta { name: 'Acri'; id: 'com.obsproject.Yami.Acri';
View file
obs-studio-32.2.2.tar.xz/frontend/data/themes/Yami_Classic.ovt -> obs-studio-33.0.0.tar.xz/frontend/data/themes/Yami_Classic.ovt
Changed
@@ -1,3 +1,21 @@ +/* ------------------------------------------------------------------------- * + * * + * IMPORTANT * + * * + * ------------------------------------------------------------------------- * + * * + * This is a Variant Theme (Style) for Yami named Classic. Variant themes + * override variable values and append additional style rules to the end of + * the final composed stylesheet. + * + * If you are developing a custom theme it is HIGHLY RECOMMENDED that you + * use Yami as a Base and apply your changes in a Variant Theme (.ovt). + * + * You can learn more about OBS Studio's theme system on our GitHub wiki: + * https://github.com/obsproject/obs-studio/wiki/OBS-Studio-Theme-System + * * + * ------------------------------------------------------------------------- */ + @OBSThemeMeta { name: 'Classic'; id: 'com.obsproject.Yami.Classic';
View file
obs-studio-32.2.2.tar.xz/frontend/data/themes/Yami_Default.ovt -> obs-studio-33.0.0.tar.xz/frontend/data/themes/Yami_Default.ovt
Changed
@@ -1,3 +1,20 @@ +/* ------------------------------------------------------------------------- * + * * + * IMPORTANT * + * * + * ------------------------------------------------------------------------- * + * * + * This is a stub Variant Theme for Yami named Default to populate the style + * dropdown. + * + * If you are developing a custom theme it is HIGHLY RECOMMENDED that you + * use Yami as a Base and apply your changes in a Variant Theme (.ovt). + * + * You can learn more about OBS Studio's theme system on our GitHub wiki: + * https://github.com/obsproject/obs-studio/wiki/OBS-Studio-Theme-System + * * + * ------------------------------------------------------------------------- */ + @OBSThemeMeta { name: 'Default'; id: 'com.obsproject.Yami.Original';
View file
obs-studio-32.2.2.tar.xz/frontend/data/themes/Yami_Grey.ovt -> obs-studio-33.0.0.tar.xz/frontend/data/themes/Yami_Grey.ovt
Changed
@@ -1,3 +1,21 @@ +/* ------------------------------------------------------------------------- * + * * + * IMPORTANT * + * * + * ------------------------------------------------------------------------- * + * * + * This is a Variant Theme (Style) for Yami named Grey. Variant themes + * override variable values and append additional style rules to the end of + * the final composed stylesheet. + * + * If you are developing a custom theme it is HIGHLY RECOMMENDED that you + * use Yami as a Base and apply your changes in a Variant Theme (.ovt). + * + * You can learn more about OBS Studio's theme system on our GitHub wiki: + * https://github.com/obsproject/obs-studio/wiki/OBS-Studio-Theme-System + * * + * ------------------------------------------------------------------------- */ + @OBSThemeMeta { name: 'Grey'; id: 'com.obsproject.Yami.Grey';
View file
obs-studio-32.2.2.tar.xz/frontend/data/themes/Yami_Light.ovt -> obs-studio-33.0.0.tar.xz/frontend/data/themes/Yami_Light.ovt
Changed
@@ -1,3 +1,21 @@ +/* ------------------------------------------------------------------------- * + * * + * IMPORTANT * + * * + * ------------------------------------------------------------------------- * + * * + * This is a Variant Theme (Style) for Yami named Light. Variant themes + * override variable values and append additional style rules to the end of + * the final composed stylesheet. + * + * If you are developing a custom theme it is HIGHLY RECOMMENDED that you + * use Yami as a Base and apply your changes in a Variant Theme (.ovt). + * + * You can learn more about OBS Studio's theme system on our GitHub wiki: + * https://github.com/obsproject/obs-studio/wiki/OBS-Studio-Theme-System + * * + * ------------------------------------------------------------------------- */ + @OBSThemeMeta { name: 'Light'; id: 'com.obsproject.Yami.Light';
View file
obs-studio-32.2.2.tar.xz/frontend/data/themes/Yami_Rachni.ovt -> obs-studio-33.0.0.tar.xz/frontend/data/themes/Yami_Rachni.ovt
Changed
@@ -1,3 +1,21 @@ +/* ------------------------------------------------------------------------- * + * * + * IMPORTANT * + * * + * ------------------------------------------------------------------------- * + * * + * This is a Variant Theme (Style) for Yami named Rachni. Variant themes + * override variable values and append additional style rules to the end of + * the final composed stylesheet. + * + * If you are developing a custom theme it is HIGHLY RECOMMENDED that you + * use Yami as a Base and apply your changes in a Variant Theme (.ovt). + * + * You can learn more about OBS Studio's theme system on our GitHub wiki: + * https://github.com/obsproject/obs-studio/wiki/OBS-Studio-Theme-System + * * + * ------------------------------------------------------------------------- */ + @OBSThemeMeta { name: 'Rachni'; id: 'com.obsproject.Yami.Rachni';
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSBasicAdvAudio.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSBasicAdvAudio.cpp
Changed
@@ -60,14 +60,14 @@ { OBSSource source((obs_source_t *)calldata_ptr(calldata, "source")); - QMetaObject::invokeMethod(static_cast<OBSBasicAdvAudio *>(param), "SourceAdded", Q_ARG(OBSSource, source)); + QMetaObject::invokeMethod(static_cast<OBSBasicAdvAudio *>(param), &OBSBasicAdvAudio::SourceAdded, source); } void OBSBasicAdvAudio::OBSSourceRemoved(void *param, calldata_t *calldata) { OBSSource source((obs_source_t *)calldata_ptr(calldata, "source")); - QMetaObject::invokeMethod(static_cast<OBSBasicAdvAudio *>(param), "SourceRemoved", Q_ARG(OBSSource, source)); + QMetaObject::invokeMethod(static_cast<OBSBasicAdvAudio *>(param), &OBSBasicAdvAudio::SourceRemoved, source); } void OBSBasicAdvAudio::OBSSourceActivated(void *param, calldata_t *calldata) @@ -75,8 +75,8 @@ OBSSource source((obs_source_t *)calldata_ptr(calldata, "source")); if (obs_source_audio_active(source)) { - QMetaObject::invokeMethod(static_cast<OBSBasicAdvAudio *>(param), "SourceAdded", - Q_ARG(OBSSource, source)); + QMetaObject::invokeMethod(static_cast<OBSBasicAdvAudio *>(param), &OBSBasicAdvAudio::SourceAdded, + source); } }
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSBasicFilters.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSBasicFilters.cpp
Changed
@@ -276,7 +276,7 @@ void OBSBasicFilters::UpdateProperties(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(data)->view, "ReloadProperties"); + QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(data)->view, &OBSPropertiesView::ReloadProperties); } void OBSBasicFilters::AddFilter(OBSSource filter, bool focus) @@ -638,27 +638,27 @@ void OBSBasicFilters::OBSSourceFilterAdded(void *param, calldata_t *data) { OBSBasicFilters *window = static_cast<OBSBasicFilters *>(param); - obs_source_t *filter = (obs_source_t *)calldata_ptr(data, "filter"); + OBSSource filter = (obs_source_t *)calldata_ptr(data, "filter"); - QMetaObject::invokeMethod(window, "AddFilter", Q_ARG(OBSSource, OBSSource(filter))); + QMetaObject::invokeMethod(window, &OBSBasicFilters::AddFilter, filter, true); } void OBSBasicFilters::OBSSourceFilterRemoved(void *param, calldata_t *data) { OBSBasicFilters *window = static_cast<OBSBasicFilters *>(param); - obs_source_t *filter = (obs_source_t *)calldata_ptr(data, "filter"); + OBSSource filter = (obs_source_t *)calldata_ptr(data, "filter"); - QMetaObject::invokeMethod(window, "RemoveFilter", Q_ARG(OBSSource, OBSSource(filter))); + QMetaObject::invokeMethod(window, &OBSBasicFilters::RemoveFilter, filter); } void OBSBasicFilters::OBSSourceReordered(void *param, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param), "ReorderFilters"); + QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param), &OBSBasicFilters::ReorderFilters); } void OBSBasicFilters::SourceRemoved(void *param, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param), "close"); + QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param), &OBSBasicFilters::close); } void OBSBasicFilters::SourceRenamed(void *param, calldata_t *data) @@ -666,7 +666,7 @@ const char *name = calldata_string(data, "new_name"); QString title = QTStr("Basic.Filters.Title").arg(QT_UTF8(name)); - QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param), "setWindowTitle", Q_ARG(QString, title)); + QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param), &OBSBasicFilters::setWindowTitle, title); } void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy)
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSBasicInteraction.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSBasicInteraction.cpp
Changed
@@ -109,7 +109,7 @@ void OBSBasicInteraction::SourceRemoved(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSBasicInteraction *>(data), "close"); + QMetaObject::invokeMethod(static_cast<OBSBasicInteraction *>(data), &OBSBasicInteraction::close); } void OBSBasicInteraction::SourceRenamed(void *data, calldata_t *params) @@ -117,7 +117,7 @@ const char *name = calldata_string(params, "new_name"); QString title = QTStr("Basic.InteractionWindow").arg(QT_UTF8(name)); - QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data), "setWindowTitle", Q_ARG(QString, title)); + QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data), &OBSBasicInteraction::setWindowTitle, title); } void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy)
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSBasicProperties.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSBasicProperties.cpp
Changed
@@ -276,7 +276,7 @@ void OBSBasicProperties::SourceRemoved(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data), "close"); + QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data), &OBSBasicProperties::close); } void OBSBasicProperties::SourceRenamed(void *data, calldata_t *params) @@ -284,12 +284,12 @@ const char *name = calldata_string(params, "new_name"); QString title = QTStr("Basic.PropertiesWindow").arg(QT_UTF8(name)); - QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data), "setWindowTitle", Q_ARG(QString, title)); + QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data), &OBSBasicProperties::setWindowTitle, title); } void OBSBasicProperties::UpdateProperties(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data)->view, "ReloadProperties"); + QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data)->view, &OBSPropertiesView::ReloadProperties); } void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSBasicSourceSelect.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSBasicSourceSelect.cpp
Changed
@@ -482,10 +482,6 @@ bool OBSBasicSourceSelect::enumSourcesCallback(void *data, obs_source_t *source) { - if (obs_source_is_hidden(source)) { - return true; - } - OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect *>(data); OBSWeakSourceAutoRelease weakSource = obs_source_get_weak_source(source);
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSBasicTransform.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSBasicTransform.cpp
Changed
@@ -1,5 +1,6 @@ #include "OBSBasicTransform.hpp" +#include <DoubleSpinBox.hpp> #include <widgets/OBSBasic.hpp> #include "moc_OBSBasicTransform.cpp" @@ -91,11 +92,7 @@ hookWidget(ui->cropRight, ISCROLL_CHANGED, &OBSBasicTransform::onCropChanged); hookWidget(ui->cropTop, ISCROLL_CHANGED, &OBSBasicTransform::onCropChanged); hookWidget(ui->cropBottom, ISCROLL_CHANGED, &OBSBasicTransform::onCropChanged); -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) hookWidget(ui->cropToBounds, &QCheckBox::checkStateChanged, &OBSBasicTransform::onControlChanged); -#else - hookWidget(ui->cropToBounds, &QCheckBox::stateChanged, &OBSBasicTransform::onControlChanged); -#endif ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true); connect(ui->buttonBox->button(QDialogButtonBox::Reset), &QPushButton::clicked, main, @@ -155,7 +152,7 @@ void OBSBasicTransform::setItem(OBSSceneItem newItem) { - QMetaObject::invokeMethod(this, "setItemQt", Q_ARG(OBSSceneItem, OBSSceneItem(newItem))); + QMetaObject::invokeMethod(this, &OBSBasicTransform::setItemQt, OBSSceneItem(newItem)); } void OBSBasicTransform::setEnabled(bool enable) @@ -183,7 +180,7 @@ OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item"); if (item == window->item && !window->ignoreTransformSignal) { - QMetaObject::invokeMethod(window, "refreshControls"); + QMetaObject::invokeMethod(window, &OBSBasicTransform::refreshControls); } } @@ -225,7 +222,7 @@ OBSBasicTransform *window = static_cast<OBSBasicTransform *>(param); bool locked = calldata_bool(data, "locked"); - QMetaObject::invokeMethod(window, "setEnabled", Q_ARG(bool, !locked)); + QMetaObject::invokeMethod(window, &OBSBasicTransform::setEnabled, !locked); } static const uint32_t indexToAlign = {OBS_ALIGN_TOP | OBS_ALIGN_LEFT,
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSIdianPlayground.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSIdianPlayground.cpp
Changed
@@ -17,7 +17,10 @@ #include "OBSIdianPlayground.hpp" +#include <Idian/CollapsibleGroup.hpp> #include <Idian/Idian.hpp> +#include <Idian/ListHeader.hpp> +#include <Idian/RowInfo.hpp> #include <QTimer> @@ -31,7 +34,9 @@ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); - Group *test; + QLayout *contents = ui->scrollAreaWidgetContents->layout(); + + RowList *rowList; Row *tmp; ComboBox *cbox = new ComboBox; @@ -39,31 +44,29 @@ cbox->addItem("Test 2"); // Group box 1 - test = new Group(this); + rowList = new RowList(this); tmp = new Row(); - tmp->setTitle("Row with a dropdown"); - tmp->setSuffix(cbox); - test->properties()->addRow(tmp); + tmp->addWidget(new RowInfo(tmp, "Row with a dropdown")); + tmp->addBuddy(cbox); + rowList->addRow(tmp); cbox = new ComboBox; cbox->addItem("Test 3"); cbox->addItem("Test 4"); tmp = new Row(); - tmp->setTitle("Row with a dropdown"); - tmp->setDescription("And a subtitle!"); - tmp->setSuffix(cbox); - test->properties()->addRow(tmp); + tmp->addWidget(new RowInfo(tmp, "Row with a dropdown", "And a subtitle!")); + tmp->addBuddy(cbox); + rowList->addRow(tmp); tmp = new Row(); - tmp->setTitle("Toggle Switch"); - tmp->setSuffix(new ToggleSwitch()); - test->properties()->addRow(tmp); - ui->scrollAreaWidgetContents->layout()->addWidget(test); + tmp->addWidget(new RowInfo(tmp, "Toggle Switch")); + tmp->addBuddy(new ToggleSwitch()); + rowList->addRow(tmp); + contents->addWidget(rowList); tmp = new Row(); - tmp->setTitle("Delayed toggle switch"); - tmp->setDescription("The state can be set separately"); + tmp->addWidget(new RowInfo(tmp, "Delayed toggle switch", "The state can be set separately")); auto tswitch = new ToggleSwitch; tswitch->setDelayed(true); connect(tswitch, &ToggleSwitch::pendingChecked, this, =() { @@ -74,64 +77,65 @@ // Do async disable stuff, then set toggle status when complete QTimer::singleShot(1000, =() { tswitch->setStatus(false); }); }); - tmp->setSuffix(tswitch); - test->properties()->addRow(tmp); + tmp->addBuddy(tswitch); + rowList->addRow(tmp); // Group box 2 - test = new Group(); - test->setTitle("Just a few checkboxes"); + contents->addWidget(new ListHeader(rowList, "Just a few checkboxes")); + rowList = new RowList(); tmp = new Row(); - tmp->setTitle("Box 1"); - tmp->setPrefix(new CheckBox); - test->properties()->addRow(tmp); + tmp->addBuddy(new CheckBox); + tmp->addWidget(new RowInfo(tmp, "Box 1")); + rowList->addRow(tmp); tmp = new Row(); - tmp->setTitle("Box 2"); - tmp->setPrefix(new CheckBox); - test->properties()->addRow(tmp); + tmp->addBuddy(new CheckBox); + tmp->addWidget(new RowInfo(tmp, "Box 2")); + rowList->addRow(tmp); - ui->scrollAreaWidgetContents->layout()->addWidget(test); + ui->scrollAreaWidgetContents->layout()->addWidget(rowList); // Group box 2 - test = new Group(); - test->setTitle("Another Group"); - test->setDescription("With a subtitle"); + rowList = new RowList(); + contents->addWidget(new ListHeader(rowList, "Another Group", "With a subtitle")); tmp = new Row(); - tmp->setTitle("Placeholder"); - tmp->setSuffix(new ToggleSwitch); - test->properties()->addRow(tmp); + tmp->addWidget(new RowInfo(tmp, "Placeholder")); + tmp->addBuddy(new ToggleSwitch); + rowList->addRow(tmp); - CollapsibleRow *tmp2 = new CollapsibleRow(this); - tmp2->setTitle("A Collapsible row!"); + CollapsibleGroup *tmp2 = new CollapsibleGroup(this); + tmp2->row()->layout()->insertWidget(0, new RowInfo(tmp, "A Collapsible row!")); tmp2->setCheckable(true); - test->addRow(tmp2); + rowList->addRow(tmp2); tmp = new Row(); - tmp->setTitle("Spin box demo"); - tmp->setSuffix(new DoubleSpinBox()); - tmp2->addRow(tmp); + tmp->addWidget(new RowInfo(tmp, "Spin box demo")); + tmp->addBuddy(new RowDoubleSpinBox()); + tmp2->list()->addRow(tmp); tmp = new Row(); - tmp->setTitle("Just another placeholder"); - tmp->setSuffix(new ToggleSwitch(true)); - tmp2->addRow(tmp); + tmp->addWidget(new RowInfo(tmp, "Just another placeholder")); + tmp->addBuddy(new ToggleSwitch(true)); + tmp2->list()->addRow(tmp); tmp = new Row(); - tmp->setTitle("Placeholder 2"); - tmp->setSuffix(new ToggleSwitch); - test->properties()->addRow(tmp); + tmp->addWidget(new RowInfo(tmp, "Placeholder 2")); + tmp->addBuddy(new ToggleSwitch); + rowList->addRow(tmp); ui->scrollAreaWidgetContents->setContentsMargins(0, 0, 0, 0); ui->scrollAreaWidgetContents->layout()->setContentsMargins(0, 0, 0, 0); - ui->scrollAreaWidgetContents->layout()->addWidget(test); + ui->scrollAreaWidgetContents->layout()->addWidget(rowList); ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignTop | Qt::AlignHCenter); // Test Checkable Group - Group *test2 = new Group(); - test2->setTitle("Checkable Group"); - test2->setDescription("Description goes here"); - test2->setCheckable(true); + auto *test2 = new RowList(this); + + auto *header = new ListHeader(this, "Checkable Group", "Description goes here"); + header->setCheckable(true); + test2->addHeader(header); + ui->scrollAreaWidgetContents->layout()->addWidget(test2); }
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSMissingFiles.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSMissingFiles.cpp
Changed
@@ -66,8 +66,7 @@ connect(filesModel, &MissingFilesModel::dataChanged, this, &OBSMissingFiles::dataChanged); QModelIndex index = filesModel->createIndex(0, 1); - QMetaObject::invokeMethod(ui->tableView, "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(const QModelIndex &, index)); + QMetaObject::invokeMethod(ui->tableView, &QTableView::setCurrentIndex, Qt::QueuedConnection, index); } OBSMissingFiles::~OBSMissingFiles()
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSRemux.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSRemux.cpp
Changed
@@ -97,8 +97,7 @@ connect(queueModel.data(), &RemuxQueueModel::rowsRemoved, this, &OBSRemux::rowCountChanged); QModelIndex index = queueModel->createIndex(0, 1); - QMetaObject::invokeMethod(ui->tableView, "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(const QModelIndex &, index)); + QMetaObject::invokeMethod(ui->tableView, &QTableView::setCurrentIndex, Qt::QueuedConnection, index); } bool OBSRemux::stopRemux()
View file
obs-studio-32.2.2.tar.xz/frontend/dialogs/OBSYoutubeActions.cpp -> obs-studio-33.0.0.tar.xz/frontend/dialogs/OBSYoutubeActions.cpp
Changed
@@ -53,33 +53,26 @@ (const QString &link) { QDesktopServices::openUrl(QUrl(link)); }); ui->scheduledTime->setVisible(false); -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) - connect(ui->checkScheduledLater, &QCheckBox::checkStateChanged, this, - &(Qt::CheckState state) -#else - connect(ui->checkScheduledLater, &QCheckBox::stateChanged, this, - &(int state) -#endif - { - const bool checked = (state == Qt::Checked); - ui->scheduledTime->setVisible(checked); - if (checked) { - ui->checkAutoStart->setVisible(true); - ui->checkAutoStop->setVisible(true); - ui->helpAutoStartStop->setVisible(true); - - ui->checkAutoStart->setChecked(false); - ui->checkAutoStop->setChecked(false); - } else { - ui->checkAutoStart->setVisible(false); - ui->checkAutoStop->setVisible(false); - ui->helpAutoStartStop->setVisible(false); + connect(ui->checkScheduledLater, &QCheckBox::checkStateChanged, this, &(Qt::CheckState state) { + const bool checked = (state == Qt::Checked); + ui->scheduledTime->setVisible(checked); + if (checked) { + ui->checkAutoStart->setVisible(true); + ui->checkAutoStop->setVisible(true); + ui->helpAutoStartStop->setVisible(true); + + ui->checkAutoStart->setChecked(false); + ui->checkAutoStop->setChecked(false); + } else { + ui->checkAutoStart->setVisible(false); + ui->checkAutoStop->setVisible(false); + ui->helpAutoStartStop->setVisible(false); - ui->checkAutoStart->setChecked(true); - ui->checkAutoStop->setChecked(true); - } - UpdateOkButtonStatus(); - }); + ui->checkAutoStart->setChecked(true); + ui->checkAutoStop->setChecked(true); + } + UpdateOkButtonStatus(); + }); ui->checkAutoStart->setVisible(false); ui->checkAutoStop->setVisible(false); @@ -519,7 +512,7 @@ broadcast.id = this->selectedBroadcast; } }; - QMetaObject::invokeMethod(&msgBox, "accept", Qt::QueuedConnection); + QMetaObject::invokeMethod(&msgBox, &QMessageBox::accept, Qt::QueuedConnection); }; QScopedPointer<QThread> thread(CreateQThread(action)); thread->start(); @@ -585,7 +578,7 @@ broadcast.id = this->selectedBroadcast; } }; - QMetaObject::invokeMethod(&msgBox, "accept", Qt::QueuedConnection); + QMetaObject::invokeMethod(&msgBox, &QMessageBox::accept, Qt::QueuedConnection); }; QScopedPointer<QThread> thread(CreateQThread(action)); thread->start();
View file
obs-studio-32.2.2.tar.xz/frontend/docks/OBSDock.cpp -> obs-studio-33.0.0.tar.xz/frontend/docks/OBSDock.cpp
Changed
@@ -29,7 +29,7 @@ bool warned = config_get_bool(App()->GetUserConfig(), "General", "WarnedAboutClosingDocks"); if (!OBSBasic::Get()->isClosing() && !warned) { - QMetaObject::invokeMethod(App(), "Exec", Qt::QueuedConnection, Q_ARG(VoidFunc, msgBox)); + QMetaObject::invokeMethod(App(), &OBSApp::Exec, Qt::QueuedConnection, msgBox); } QDockWidget::closeEvent(event);
View file
obs-studio-32.2.2.tar.xz/frontend/docks/YouTubeChatDock.cpp -> obs-studio-33.0.0.tar.xz/frontend/docks/YouTubeChatDock.cpp
Changed
@@ -23,8 +23,8 @@ if (loginStateChanged) { OBSBasic *main = OBSBasic::Get(); if (main->GetYouTubeAppDock() != nullptr) { - QMetaObject::invokeMethod(main->GetYouTubeAppDock(), "SettingsUpdated", - Qt::QueuedConnection, Q_ARG(bool, !currentlyLoggedIn)); + QMetaObject::invokeMethod(main->GetYouTubeAppDock(), &YouTubeAppDock::SettingsUpdated, + Qt::QueuedConnection, !currentlyLoggedIn); } } };
View file
obs-studio-32.2.2.tar.xz/frontend/forms/AutoConfigFinishPage.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/AutoConfigFinishPage.ui
Changed
@@ -24,7 +24,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/AutoConfigStartPage.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/AutoConfigStartPage.ui
Changed
@@ -34,10 +34,10 @@ <item> <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -65,10 +65,10 @@ <item> <spacer name="verticalSpacer_3"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -96,10 +96,10 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/AutoConfigStreamPage.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/AutoConfigStreamPage.ui
Changed
@@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>726</width> - <height>407</height> + <height>441</height> </rect> </property> <property name="windowTitle"> @@ -39,10 +39,10 @@ </property> <layout class="QFormLayout" name="topLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="bottomMargin"> <number>12</number> @@ -50,10 +50,10 @@ <item row="0" column="0"> <spacer name="horizontalSpacer_6"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -104,7 +104,7 @@ <item row="2" column="1"> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -125,18 +125,18 @@ <widget class="QWidget" name="loginPage"> <layout class="QFormLayout" name="loginPageLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <item row="0" column="0"> <spacer name="horizontalSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -158,7 +158,7 @@ <item> <spacer name="horizontalSpacer_4"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -173,10 +173,10 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_7"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -198,7 +198,7 @@ <item> <spacer name="horizontalSpacer_8"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -215,10 +215,10 @@ <widget class="QWidget" name="streamkeyPage"> <layout class="QFormLayout" name="streamkeyPageLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <item row="0" column="0"> <widget class="QLabel" name="serverLabel"> @@ -309,7 +309,7 @@ <string notr="true"/> </property> <property name="echoMode"> - <enum>QLineEdit::Password</enum> + <enum>QLineEdit::EchoMode::Password</enum> </property> </widget> </item> @@ -379,7 +379,7 @@ <item row="4" column="0"> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -467,7 +467,7 @@ <string>MultitrackVideo.Info</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> <property name="wordWrap"> <bool>true</bool> @@ -480,7 +480,7 @@ <item row="10" column="1"> <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/AutoConfigTestPage.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/AutoConfigTestPage.ui
Changed
@@ -57,7 +57,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -93,7 +93,7 @@ <string>Basic.AutoConfig.TestPage.Result.Footer</string> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> </property> <property name="wordWrap"> <bool>true</bool> @@ -103,7 +103,7 @@ <item> <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -123,7 +123,7 @@ <string notr="true"/> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> </property> <property name="wordWrap"> <bool>true</bool>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/AutoConfigVideoPage.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/AutoConfigVideoPage.ui
Changed
@@ -17,10 +17,10 @@ <item> <layout class="QFormLayout" name="formLayout_2"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <item row="0" column="0"> <widget class="QLabel" name="label"> @@ -51,10 +51,10 @@ <item row="3" column="0"> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -82,7 +82,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/LogUploadDialog.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/LogUploadDialog.ui
Changed
@@ -15,7 +15,7 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_LogUploadDialog"> <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> + <enum>QLayout::SizeConstraint::SetFixedSize</enum> </property> <item> <widget class="QStackedWidget" name="stackedWidget"> @@ -50,7 +50,7 @@ <string>LogUploadDialog.Labels.PrivacyNotice</string> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> </property> <property name="wordWrap"> <bool>false</bool> @@ -59,7 +59,7 @@ <bool>true</bool> </property> <property name="textInteractionFlags"> - <set>Qt::TextBrowserInteraction</set> + <set>Qt::TextInteractionFlag::TextBrowserInteraction</set> </property> </widget> </item> @@ -96,7 +96,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -155,7 +155,7 @@ <string>LogUploadDialog.Labels.Description.AppLog</string> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> </property> <property name="wordWrap"> <bool>false</bool> @@ -195,7 +195,7 @@ <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Close</set> + <set>QDialogButtonBox::StandardButton::Close</set> </property> </widget> </item> @@ -227,7 +227,7 @@ <string>LogUploadDialog.Labels.UploadFailMessage</string> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> </property> </widget> </item> @@ -236,7 +236,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSAbout.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSAbout.ui
Changed
@@ -90,10 +90,10 @@ <item> <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -116,10 +116,10 @@ <item> <spacer name="verticalSpacer_3"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -156,10 +156,10 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -210,7 +210,7 @@ <string>About</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -220,7 +220,7 @@ <string>Authors</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -230,7 +230,7 @@ <string>License</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSAdvAudio.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSAdvAudio.ui
Changed
@@ -17,7 +17,7 @@ </sizepolicy> </property> <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> + <enum>Qt::ContextMenuPolicy::CustomContextMenu</enum> </property> <property name="windowTitle"> <string>Basic.AdvAudio</string> @@ -59,7 +59,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -87,7 +87,7 @@ </sizepolicy> </property> <property name="sizeAdjustPolicy"> - <enum>QAbstractScrollArea::AdjustToContents</enum> + <enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum> </property> <property name="widgetResizable"> <bool>true</bool> @@ -98,7 +98,7 @@ <x>0</x> <y>0</y> <width>1157</width> - <height>262</height> + <height>266</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_3"> @@ -230,7 +230,7 @@ </widget> </item> <item row="0" column="3"> - <widget class="QWidget" name="widget" native="true"> + <widget class="QWidget" name="widget"> <layout class="QGridLayout" name="gridLayout_2"> <property name="leftMargin"> <number>0</number> @@ -279,10 +279,10 @@ <item> <spacer name="horizontalSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Minimum</enum> + <enum>QSizePolicy::Policy::Minimum</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -309,7 +309,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSBasic.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSBasic.ui
Changed
@@ -34,7 +34,7 @@ <string notr="true"/> </property> <property name="dockOptions"> - <set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks</set> + <set>QMainWindow::DockOption::AllowNestedDocks|QMainWindow::DockOption::AllowTabbedDocks</set> </property> <widget class="QWidget" name="centralwidget"> <layout class="QVBoxLayout" name="verticalLayout"> @@ -54,7 +54,7 @@ <number>0</number> </property> <item> - <widget class="QWidget" name="canvasEditor" native="true"> + <widget class="QWidget" name="canvasEditor"> <layout class="QHBoxLayout" name="previewLayout"> <property name="spacing"> <number>2</number> @@ -98,7 +98,7 @@ <item> <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -120,7 +120,7 @@ <string>Basic.Main.PreviewDisabled</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -129,7 +129,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -149,7 +149,7 @@ <item> <spacer name="horizontalSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -164,7 +164,7 @@ <item> <spacer name="verticalSpacer_3"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -178,7 +178,7 @@ </widget> </item> <item> - <widget class="QWidget" name="previewContainer" native="true"> + <widget class="QWidget" name="previewContainer"> <layout class="QVBoxLayout" name="previewTextLayout"> <property name="spacing"> <number>0</number> @@ -207,7 +207,7 @@ <string>StudioMode.PreviewSceneName</string> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="class" stdset="0"> <string>label-preview-title</string> @@ -234,16 +234,16 @@ </size> </property> <property name="focusPolicy"> - <enum>Qt::ClickFocus</enum> + <enum>Qt::FocusPolicy::ClickFocus</enum> </property> <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> + <enum>Qt::ContextMenuPolicy::CustomContextMenu</enum> </property> <addaction name="actionRemoveSource"/> </widget> </item> <item row="2" column="1"> - <widget class="QWidget" name="previewXContainer" native="true"> + <widget class="QWidget" name="previewXContainer"> <layout class="QHBoxLayout" name="horizontalLayout_7"> <property name="spacing"> <number>0</number> @@ -313,7 +313,7 @@ <string>100%</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -381,10 +381,10 @@ <item> <spacer name="horizontalSpacer_5"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -415,7 +415,7 @@ <number>100</number> </property> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> </widget> </item> @@ -425,7 +425,7 @@ <item row="1" column="2"> <widget class="QScrollBar" name="previewYScrollBar"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> </widget> </item> @@ -456,7 +456,7 @@ <number>6</number> </property> <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> + <enum>QLayout::SizeConstraint::SetDefaultConstraint</enum> </property> <property name="leftMargin"> <number>6</number> @@ -578,7 +578,7 @@ <item> <widget class="Line" name="line_3"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> </widget> </item> @@ -663,7 +663,7 @@ <item> <widget class="Line" name="line"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> </widget> </item> @@ -972,7 +972,7 @@ <widget class="OBSBasicStatusBar" name="statusbar"/> <widget class="OBSDock" name="scenesDock"> <property name="features"> - <set>QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set> + <set>QDockWidget::DockWidgetFeature::DockWidgetClosable|QDockWidget::DockWidgetFeature::DockWidgetFloatable|QDockWidget::DockWidgetFeature::DockWidgetMovable</set> </property> <property name="windowTitle"> <string>Basic.Main.Scenes</string> @@ -1024,13 +1024,13 @@ </sizepolicy> </property> <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> + <enum>Qt::ContextMenuPolicy::CustomContextMenu</enum> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="showDropIndicator" stdset="0"> <bool>true</bool> @@ -1039,10 +1039,10 @@ <bool>true</bool> </property> <property name="dragDropMode"> - <enum>QAbstractItemView::InternalMove</enum> + <enum>QAbstractItemView::DragDropMode::InternalMove</enum> </property> <property name="defaultDropAction"> - <enum>Qt::TargetMoveAction</enum> + <enum>Qt::DropAction::TargetMoveAction</enum> </property> <!-- Spacing must be 0 due to QTBUG-106395 --> <property name="spacing"> @@ -1080,10 +1080,10 @@ <item> <spacer name="scenesFixedSizeHSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1101,7 +1101,7 @@ </widget> <widget class="OBSDock" name="sourcesDock"> <property name="features"> - <set>QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set> + <set>QDockWidget::DockWidgetFeature::DockWidgetClosable|QDockWidget::DockWidgetFeature::DockWidgetFloatable|QDockWidget::DockWidgetFeature::DockWidgetMovable</set> </property> <property name="windowTitle"> <string>Basic.Main.Sources</string> @@ -1153,10 +1153,10 @@ </sizepolicy> </property> <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> + <enum>Qt::ContextMenuPolicy::CustomContextMenu</enum> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="showDropIndicator" stdset="0"> <bool>true</bool> @@ -1165,13 +1165,13 @@ <bool>true</bool> </property> <property name="dragDropMode"> - <enum>QAbstractItemView::InternalMove</enum> + <enum>QAbstractItemView::DragDropMode::InternalMove</enum> </property> <property name="defaultDropAction"> - <enum>Qt::TargetMoveAction</enum> + <enum>Qt::DropAction::TargetMoveAction</enum> </property> <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> + <enum>QAbstractItemView::SelectionMode::ExtendedSelection</enum> </property> <!-- Spacing must be 0 due to QTBUG-106395 --> <property name="spacing"> @@ -1209,10 +1209,10 @@ <item> <spacer name="sourcesFixedSizeHSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1230,10 +1230,10 @@ </widget> <widget class="OBSDock" name="mixerDock"> <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> + <enum>Qt::ContextMenuPolicy::CustomContextMenu</enum> </property> <property name="features"> - <set>QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set> + <set>QDockWidget::DockWidgetFeature::DockWidgetClosable|QDockWidget::DockWidgetFeature::DockWidgetFloatable|QDockWidget::DockWidgetFeature::DockWidgetMovable</set> </property> <property name="windowTitle"> <string>Mixer</string> @@ -1263,7 +1263,7 @@ </widget> <widget class="OBSDock" name="transitionsDock"> <property name="features"> - <set>QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set> + <set>QDockWidget::DockWidgetFeature::DockWidgetClosable|QDockWidget::DockWidgetFeature::DockWidgetFloatable|QDockWidget::DockWidgetFeature::DockWidgetMovable</set> </property> <property name="windowTitle"> <string>Basic.SceneTransitions</string> @@ -1372,10 +1372,10 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1477,7 +1477,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1538,7 +1538,7 @@ <string>Del</string> </property> <property name="shortcutContext"> - <enum>Qt::WidgetWithChildrenShortcut</enum> + <enum>Qt::ShortcutContext::WidgetWithChildrenShortcut</enum> </property> <property name="iconVisibleInMenu"> <bool>false</bool> @@ -1562,7 +1562,7 @@ <string>Del</string> </property> <property name="shortcutContext"> - <enum>Qt::WidgetWithChildrenShortcut</enum> + <enum>Qt::ShortcutContext::WidgetWithChildrenShortcut</enum> </property> <property name="iconVisibleInMenu"> <bool>false</bool>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSBasicControls.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSBasicControls.ui
Changed
@@ -334,7 +334,7 @@ <item> <spacer name="expVSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSBasicFilters.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSBasicFilters.ui
Changed
@@ -20,7 +20,7 @@ <item> <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,10"> <property name="sizeConstraint"> - <enum>QLayout::SetMinimumSize</enum> + <enum>QLayout::SizeConstraint::SetMinimumSize</enum> </property> <item> <layout class="QVBoxLayout" name="verticalLayout_2"> @@ -67,16 +67,16 @@ </sizepolicy> </property> <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> + <enum>Qt::ContextMenuPolicy::CustomContextMenu</enum> </property> <property name="dragEnabled"> <bool>true</bool> </property> <property name="dragDropMode"> - <enum>QAbstractItemView::InternalMove</enum> + <enum>QAbstractItemView::DragDropMode::InternalMove</enum> </property> <property name="defaultDropAction"> - <enum>Qt::TargetMoveAction</enum> + <enum>Qt::DropAction::TargetMoveAction</enum> </property> <property name="spacing"> <number>1</number> @@ -220,10 +220,10 @@ <item> <spacer name="asyncToolbarSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -242,7 +242,7 @@ <item> <widget class="Line" name="separatorLine"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> </widget> </item> @@ -289,16 +289,16 @@ </sizepolicy> </property> <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> + <enum>Qt::ContextMenuPolicy::CustomContextMenu</enum> </property> <property name="dragEnabled"> <bool>true</bool> </property> <property name="dragDropMode"> - <enum>QAbstractItemView::InternalMove</enum> + <enum>QAbstractItemView::DragDropMode::InternalMove</enum> </property> <property name="defaultDropAction"> - <enum>Qt::TargetMoveAction</enum> + <enum>Qt::DropAction::TargetMoveAction</enum> </property> <property name="spacing"> <number>1</number> @@ -442,10 +442,10 @@ <item> <spacer name="effectToolbarSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -472,10 +472,10 @@ </size> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <layout class="QVBoxLayout" name="verticalLayout_6"> <property name="leftMargin"> @@ -499,7 +499,7 @@ </size> </property> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="childrenCollapsible"> <bool>false</bool> @@ -512,10 +512,10 @@ </sizepolicy> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <layout class="QVBoxLayout" name="verticalLayout_7"> <property name="spacing"> @@ -559,10 +559,10 @@ </sizepolicy> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <layout class="QVBoxLayout" name="propertiesLayout"> <property name="leftMargin"> @@ -587,12 +587,12 @@ <number>4</number> </property> <property name="sizeConstraint"> - <enum>QLayout::SetMaximumSize</enum> + <enum>QLayout::SizeConstraint::SetMaximumSize</enum> </property> <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Close|QDialogButtonBox::RestoreDefaults</set> + <set>QDialogButtonBox::StandardButton::Close|QDialogButtonBox::StandardButton::RestoreDefaults</set> </property> </widget> </item>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSBasicProperties.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSBasicProperties.ui
Changed
@@ -26,7 +26,7 @@ </size> </property> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="childrenCollapsible"> <bool>false</bool> @@ -39,10 +39,10 @@ </sizepolicy> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <layout class="QVBoxLayout" name="verticalLayout_7"> <property name="spacing"> @@ -86,10 +86,10 @@ </sizepolicy> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <layout class="QVBoxLayout" name="propertiesLayout"> <property name="leftMargin"> @@ -111,10 +111,10 @@ <item> <widget class="QFrame" name="frame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -155,7 +155,7 @@ <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set> </property> </widget> </item>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSBasicSettings.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSBasicSettings.ui
Changed
@@ -165,10 +165,10 @@ <item> <widget class="QScrollArea" name="scrollArea_2"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -181,7 +181,7 @@ <rect> <x>0</x> <y>0</y> - <width>755</width> + <width>759</width> <height>1260</height> </rect> </property> @@ -220,10 +220,10 @@ </property> <layout class="QFormLayout" name="formLayout_32"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -244,10 +244,10 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -284,10 +284,10 @@ </property> <layout class="QFormLayout" name="formLayout_20"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -322,10 +322,10 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_29"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -345,10 +345,10 @@ </property> <layout class="QFormLayout" name="formLayout_2"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -356,10 +356,10 @@ <item row="0" column="0"> <spacer name="horizontalSpacer_5"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -440,10 +440,10 @@ </property> <layout class="QFormLayout" name="formLayout_21"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -489,7 +489,7 @@ </widget> </item> <item row="1" column="1"> - <widget class="QDoubleSpinBox" name="snapDistance"> + <widget class="OBS::DoubleSpinBox" name="snapDistance"> <property name="decimals"> <number>1</number> </property> @@ -514,10 +514,10 @@ <item row="3" column="0"> <spacer name="horizontalSpacer_4"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -537,10 +537,10 @@ </property> <layout class="QFormLayout" name="formLayout_28"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -576,10 +576,10 @@ <item row="1" column="0"> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -599,10 +599,10 @@ </property> <layout class="QFormLayout" name="formLayout_29"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -637,10 +637,10 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -660,10 +660,10 @@ </property> <layout class="QFormLayout" name="formLayout_35"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -678,7 +678,7 @@ <item row="0" column="0"> <spacer name="horizontalSpacer_25"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -726,10 +726,10 @@ </property> <layout class="QFormLayout" name="formLayout_36"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -737,7 +737,7 @@ <item row="0" column="0"> <spacer name="horizontalSpacer_26"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -764,10 +764,10 @@ </property> <layout class="QFormLayout" name="formLayout_31"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -782,7 +782,7 @@ <item row="0" column="0"> <spacer name="horizontalSpacer_6"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -819,10 +819,10 @@ </property> <layout class="QFormLayout" name="formLayoutMultiview"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -830,10 +830,10 @@ <item row="0" column="0"> <spacer name="horizontalSpacerMultiview"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -892,7 +892,7 @@ <item> <spacer name="verticalSpacer_11"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -928,10 +928,10 @@ <item> <widget class="QScrollArea" name="scrollArea_420"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -944,8 +944,8 @@ <rect> <x>0</x> <y>0</y> - <width>772</width> - <height>680</height> + <width>1052</width> + <height>667</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_1337"> @@ -986,10 +986,10 @@ </property> <layout class="QFormLayout" name="formLayout_37"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -1033,10 +1033,10 @@ <item row="2" column="1"> <widget class="QFrame" name="frame_2"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -1063,13 +1063,13 @@ </sizepolicy> </property> <property name="focusPolicy"> - <enum>Qt::NoFocus</enum> + <enum>Qt::FocusPolicy::NoFocus</enum> </property> <property name="text"> <string>10</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> <property name="readOnly"> <bool>true</bool> @@ -1100,10 +1100,10 @@ <number>10</number> </property> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="tickPosition"> - <enum>QSlider::TicksBothSides</enum> + <enum>QSlider::TickPosition::TicksBothSides</enum> </property> <property name="tickInterval"> <number>1</number> @@ -1123,10 +1123,10 @@ <item row="3" column="1"> <widget class="QFrame" name="frame_5"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -1217,7 +1217,7 @@ <item row="4" column="0"> <spacer name="horizontalSpacer_17"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1233,7 +1233,7 @@ <item> <spacer name="verticalSpacer_8"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1246,10 +1246,10 @@ <item> <widget class="QFrame" name="appearanceOptionsWarning"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -1295,10 +1295,10 @@ <widget class="QFrame" name="widget_5"> <layout class="QFormLayout" name="topStreamLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -1324,7 +1324,7 @@ <string>Basic.AutoConfig.StreamPage.Service</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>service</cstring> @@ -1398,7 +1398,7 @@ </property> <layout class="QFormLayout" name="loginPageLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="topMargin"> <number>2</number> @@ -1406,10 +1406,10 @@ <item row="0" column="0"> <spacer name="horizontalSpacer_20"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1431,7 +1431,7 @@ <item> <spacer name="horizontalSpacer_21"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1446,10 +1446,10 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_22"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1471,7 +1471,7 @@ <item> <spacer name="horizontalSpacer_23"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1489,7 +1489,7 @@ <item> <spacer name="verticalSpacer_10"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1503,10 +1503,10 @@ </widget> <widget class="QScrollArea" name="streamKeyScrollArea"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -1520,7 +1520,7 @@ <x>0</x> <y>0</y> <width>987</width> - <height>791</height> + <height>910</height> </rect> </property> <layout class="QVBoxLayout" name="streamkeyPageLayout"> @@ -1543,10 +1543,10 @@ </property> <layout class="QFormLayout" name="destinationLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -1668,7 +1668,7 @@ <string notr="true"/> </property> <property name="echoMode"> - <enum>QLineEdit::Password</enum> + <enum>QLineEdit::EchoMode::Password</enum> </property> </widget> </item> @@ -1734,7 +1734,7 @@ <item> <spacer name="horizontalSpacer_19"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1749,7 +1749,7 @@ <item row="4" column="0"> <spacer name="horizontalSpacer_18"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1771,7 +1771,7 @@ <item> <spacer name="horizontalSpacer_28"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1831,7 +1831,7 @@ <item> <widget class="QLineEdit" name="authPw"> <property name="echoMode"> - <enum>QLineEdit::Password</enum> + <enum>QLineEdit::EchoMode::Password</enum> </property> </widget> </item> @@ -1871,10 +1871,10 @@ <item> <spacer name="horizontalSpacer_31"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1890,7 +1890,7 @@ <string>MultitrackVideo.Info</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> <property name="wordWrap"> <bool>true</bool> @@ -1905,15 +1905,15 @@ <item> <layout class="QFormLayout" name="formLayout_27"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <item row="0" column="0"> <spacer name="horizontalSpacer_30"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -1947,7 +1947,7 @@ </widget> </item> <item> - <widget class="QSpinBox" name="multitrackVideoMaximumAggregateBitrate"> + <widget class="OBS::SpinBox" name="multitrackVideoMaximumAggregateBitrate"> <property name="sizePolicy"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -1996,7 +1996,7 @@ </widget> </item> <item> - <widget class="QSpinBox" name="multitrackVideoMaximumVideoTracks"> + <widget class="OBS::SpinBox" name="multitrackVideoMaximumVideoTracks"> <property name="sizePolicy"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -2026,10 +2026,10 @@ <item row="4" column="0"> <spacer name="horizontalSpacer_32"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -2105,10 +2105,10 @@ <item> <spacer name="horizontalSpacer_33"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> + <enum>QSizePolicy::Policy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -2124,7 +2124,7 @@ <string>Basic.Settings.Stream.WHIPSimulcastInfo</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> <property name="wordWrap"> <bool>true</bool> @@ -2139,7 +2139,7 @@ <item> <layout class="QFormLayout" name="formLayout_39"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <item row="1" column="0"> <widget class="QLabel" name="whipSimulcastTotalLayersLabel"> @@ -2157,7 +2157,7 @@ <item row="1" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_35" stretch="0"> <item> - <widget class="QSpinBox" name="whipSimulcastTotalLayers"> + <widget class="OBS::SpinBox" name="whipSimulcastTotalLayers"> <property name="minimum"> <number>1</number> </property> @@ -2175,7 +2175,7 @@ </item> </layout> </widget> - </item> + </item> <item> <widget class="QGroupBox" name="serviceAdvancedOptionsGroupBox"> <property name="title"> @@ -2183,10 +2183,10 @@ </property> <layout class="QFormLayout" name="serviceAdvancedOptionsLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -2216,7 +2216,7 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_18_1"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -2246,7 +2246,7 @@ <string notr="true"/> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> <property name="openExternalLinks"> <bool>true</bool> @@ -2259,7 +2259,7 @@ <item> <spacer name="verticalSpacer_12"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -2329,7 +2329,7 @@ <string>Basic.Settings.MultitrackVideoDisabledSettings</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -2340,7 +2340,7 @@ <widget class="QFrame" name="widget"> <layout class="QFormLayout" name="formLayout_5"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="leftMargin"> <number>9</number> @@ -2366,7 +2366,7 @@ <string>Basic.Settings.Output.Mode</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>outputMode</cstring> @@ -2424,10 +2424,10 @@ <item> <widget class="QScrollArea" name="simpleOutScroll"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -2440,7 +2440,7 @@ <rect> <x>0</x> <y>0</y> - <width>755</width> + <width>759</width> <height>609</height> </rect> </property> @@ -2470,10 +2470,10 @@ </property> <layout class="QFormLayout" name="simpleStreamingLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -2499,7 +2499,7 @@ <string>Basic.Settings.Output.VideoBitrate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>simpleOutputVBitrate</cstring> @@ -2507,7 +2507,7 @@ </widget> </item> <item row="0" column="1"> - <widget class="QSpinBox" name="simpleOutputVBitrate"> + <widget class="OBS::SpinBox" name="simpleOutputVBitrate"> <property name="minimum"> <number>200</number> </property> @@ -2666,10 +2666,10 @@ </property> <layout class="QFormLayout" name="formLayout_6"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -2695,7 +2695,7 @@ <string>Basic.Settings.Output.Simple.SavePath</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>simpleOutputPath</cstring> @@ -3035,10 +3035,10 @@ </property> <layout class="QFormLayout" name="formLayout_24"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -3060,7 +3060,7 @@ </widget> </item> <item row="0" column="1"> - <widget class="QSpinBox" name="simpleRBSecMax"> + <widget class="OBS::SpinBox" name="simpleRBSecMax"> <property name="suffix"> <string notr="true"> sec</string> </property> @@ -3083,7 +3083,7 @@ </widget> </item> <item row="1" column="1"> - <widget class="QSpinBox" name="simpleRBMegsMax"> + <widget class="OBS::SpinBox" name="simpleRBMegsMax"> <property name="suffix"> <string notr="true"> MB</string> </property> @@ -3135,7 +3135,7 @@ <item> <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -3209,10 +3209,10 @@ <item> <widget class="QScrollArea" name="scrollArea_3"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -3249,10 +3249,10 @@ </property> <layout class="QFormLayout" name="advOutTopLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -3278,7 +3278,7 @@ <string>Basic.Settings.Output.Adv.AudioTrack</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -3437,7 +3437,7 @@ <item row="3" column="0"> <widget class="QLabel" name="advOutUseRescale"> <property name="layoutDirection"> - <enum>Qt::RightToLeft</enum> + <enum>Qt::LayoutDirection::RightToLeft</enum> </property> <property name="text"> <string>Basic.Settings.Output.Adv.Rescale</string> @@ -3488,7 +3488,7 @@ <item> <spacer name="verticalSpacer_0"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -3525,10 +3525,10 @@ <widget class="QFrame" name="advOutRecTypeContainer"> <layout class="QFormLayout" name="formLayout_9"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -3554,7 +3554,7 @@ <string>Basic.Settings.Output.Adv.Recording.Type</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>advOutRecType</cstring> @@ -3612,10 +3612,10 @@ </sizepolicy> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -3624,7 +3624,7 @@ <bool>true</bool> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> </property> <widget class="QWidget" name="scrollAreaWidgetContents_4"> <property name="geometry"> @@ -3661,13 +3661,13 @@ </property> <layout class="QFormLayout" name="formLayout_16"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="formAlignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> </property> <property name="leftMargin"> <number>9</number> @@ -3699,7 +3699,7 @@ <string>Basic.Settings.Output.Simple.SavePath</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -3739,7 +3739,7 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_27"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -4039,7 +4039,7 @@ </sizepolicy> </property> <property name="layoutDirection"> - <enum>Qt::RightToLeft</enum> + <enum>Qt::LayoutDirection::RightToLeft</enum> </property> <property name="text"> <string>Basic.Settings.Output.Adv.Rescale</string> @@ -4109,7 +4109,7 @@ </sizepolicy> </property> <property name="layoutDirection"> - <enum>Qt::RightToLeft</enum> + <enum>Qt::LayoutDirection::RightToLeft</enum> </property> <property name="text"> <string>Basic.Settings.Output.EnableSplitFile</string> @@ -4146,7 +4146,7 @@ </widget> </item> <item row="9" column="1"> - <widget class="QSpinBox" name="advOutSplitFileTime"> + <widget class="OBS::SpinBox" name="advOutSplitFileTime"> <property name="suffix"> <string> min</string> </property> @@ -4169,7 +4169,7 @@ </widget> </item> <item row="10" column="1"> - <widget class="QSpinBox" name="advOutSplitFileSize"> + <widget class="OBS::SpinBox" name="advOutSplitFileSize"> <property name="suffix"> <string> MB</string> </property> @@ -4217,7 +4217,7 @@ <item> <spacer name="verticalSpacer_3"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -4256,10 +4256,10 @@ <item> <widget class="QScrollArea" name="scrollArea_5"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -4296,10 +4296,10 @@ </property> <layout class="QFormLayout" name="formLayout_7"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -4344,7 +4344,7 @@ <string>Basic.Settings.Output.Adv.FFmpeg.Type</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -4380,7 +4380,7 @@ <string>Basic.Settings.Output.Adv.FFmpeg.SavePathURL</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -4520,7 +4520,7 @@ </widget> </item> <item row="7" column="1"> - <widget class="QSpinBox" name="advOutFFVBitrate"> + <widget class="OBS::SpinBox" name="advOutFFVBitrate"> <property name="minimum"> <number>0</number> </property> @@ -4540,7 +4540,7 @@ </widget> </item> <item row="8" column="1"> - <widget class="QSpinBox" name="advOutFFVGOPSize"> + <widget class="OBS::SpinBox" name="advOutFFVGOPSize"> <property name="maximum"> <number>1000000000</number> </property> @@ -4558,7 +4558,7 @@ </sizepolicy> </property> <property name="layoutDirection"> - <enum>Qt::RightToLeft</enum> + <enum>Qt::LayoutDirection::RightToLeft</enum> </property> <property name="text"> <string>Basic.Settings.Output.Adv.Rescale</string> @@ -4610,7 +4610,7 @@ </widget> </item> <item row="13" column="1"> - <widget class="QSpinBox" name="advOutFFABitrate"> + <widget class="OBS::SpinBox" name="advOutFFABitrate"> <property name="minimum"> <number>32</number> </property> @@ -4727,7 +4727,7 @@ <item> <spacer name="verticalSpacer_6"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -4806,10 +4806,10 @@ <item> <widget class="QScrollArea" name="scrollArea_6"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -4822,7 +4822,7 @@ <rect> <x>0</x> <y>0</y> - <width>258</width> + <width>251</width> <height>510</height> </rect> </property> @@ -4855,10 +4855,10 @@ </property> <layout class="QFormLayout" name="formLayout_10"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -4972,7 +4972,7 @@ <string>Basic.Settings.Output.AudioBitrate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>advOutTrack1Bitrate</cstring> @@ -4995,10 +4995,10 @@ </property> <layout class="QFormLayout" name="formLayout_11"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -5024,7 +5024,7 @@ <string>Basic.Settings.Output.AudioBitrate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>advOutTrack2Bitrate</cstring> @@ -5135,10 +5135,10 @@ </property> <layout class="QFormLayout" name="formLayout_12"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -5164,7 +5164,7 @@ <string>Basic.Settings.Output.AudioBitrate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>advOutTrack3Bitrate</cstring> @@ -5275,10 +5275,10 @@ </property> <layout class="QFormLayout" name="formLayout_13"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -5304,7 +5304,7 @@ <string>Basic.Settings.Output.AudioBitrate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>advOutTrack4Bitrate</cstring> @@ -5415,10 +5415,10 @@ </property> <layout class="QFormLayout" name="formLayout_25"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -5444,7 +5444,7 @@ <string>Basic.Settings.Output.AudioBitrate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>advOutTrack5Bitrate</cstring> @@ -5555,10 +5555,10 @@ </property> <layout class="QFormLayout" name="formLayout_26"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>9</number> @@ -5584,7 +5584,7 @@ <string>Basic.Settings.Output.AudioBitrate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>advOutTrack6Bitrate</cstring> @@ -5685,10 +5685,10 @@ <item> <spacer name="verticalSpacer_5"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -5769,10 +5769,10 @@ </property> <layout class="QFormLayout" name="formLayout_30"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>0</number> @@ -5794,7 +5794,7 @@ </widget> </item> <item row="0" column="1"> - <widget class="QSpinBox" name="advRBSecMax"> + <widget class="OBS::SpinBox" name="advRBSecMax"> <property name="suffix"> <string notr="true"> s</string> </property> @@ -5810,7 +5810,7 @@ </widget> </item> <item row="1" column="1"> - <widget class="QSpinBox" name="advRBMegsMax"> + <widget class="OBS::SpinBox" name="advRBMegsMax"> <property name="suffix"> <string> MB</string> </property> @@ -5848,7 +5848,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -5888,10 +5888,10 @@ <item> <widget class="QScrollArea" name="scrollArea_50"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -5943,10 +5943,10 @@ </property> <layout class="QFormLayout" name="formLayout_52"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -5963,7 +5963,7 @@ <string>Basic.Settings.Audio.SampleRate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>sampleRate</cstring> @@ -6055,10 +6055,10 @@ </property> <layout class="QFormLayout" name="formLayout_53"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -6075,7 +6075,7 @@ <string>Basic.Settings.Audio.DesktopDevice</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>desktopAudioDevice1</cstring> @@ -6095,7 +6095,7 @@ <string>Basic.Settings.Audio.DesktopDevice2</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>desktopAudioDevice2</cstring> @@ -6187,10 +6187,10 @@ </property> <layout class="QFormLayout" name="formLayout_54"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -6207,7 +6207,7 @@ <string>Basic.Settings.Audio.MeterDecayRate</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>meterDecayRate</cstring> @@ -6276,10 +6276,10 @@ </property> <layout class="QFormLayout" name="formLayout_56"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -6307,10 +6307,10 @@ <item row="2" column="0"> <spacer name="horizontalSpacer_11"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -6337,10 +6337,10 @@ </property> <layout class="QFormLayout" name="audioSourceLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -6351,7 +6351,7 @@ <item> <spacer name="verticalSpacer_4"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -6423,10 +6423,10 @@ </property> <layout class="QFormLayout" name="formLayout_15"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -6443,7 +6443,7 @@ <string>Basic.Settings.Video.BaseResolution</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>baseResolution</cstring> @@ -6583,7 +6583,7 @@ <property name="bottomMargin"> <number>0</number> </property> - <item alignment="Qt::AlignTop"> + <item alignment="Qt::AlignmentFlag::AlignTop"> <widget class="QComboBox" name="fpsCommon"> <property name="currentText"> <string notr="true">10</string> @@ -6659,8 +6659,8 @@ <property name="bottomMargin"> <number>0</number> </property> - <item alignment="Qt::AlignTop"> - <widget class="QSpinBox" name="fpsInteger"> + <item alignment="Qt::AlignmentFlag::AlignTop"> + <widget class="OBS::SpinBox" name="fpsInteger"> <property name="minimum"> <number>1</number> </property> @@ -6677,10 +6677,10 @@ <widget class="QWidget" name="page_2"> <layout class="QFormLayout" name="formLayout_4"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="leftMargin"> <number>0</number> @@ -6702,7 +6702,7 @@ </widget> </item> <item row="0" column="1"> - <widget class="QSpinBox" name="fpsNumerator"> + <widget class="OBS::SpinBox" name="fpsNumerator"> <property name="minimum"> <number>1</number> </property> @@ -6722,7 +6722,7 @@ </widget> </item> <item row="1" column="1"> - <widget class="QSpinBox" name="fpsDenominator"> + <widget class="OBS::SpinBox" name="fpsDenominator"> <property name="minimum"> <number>1</number> </property> @@ -6738,7 +6738,7 @@ <item row="4" column="0"> <spacer name="horizontalSpacer_24"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -6754,10 +6754,10 @@ <item> <spacer name="verticalSpacer_9"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -6904,7 +6904,7 @@ <widget class="QFrame" name="hotkeyScrollFrame"> <layout class="QFormLayout" name="hotkeyFormLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="leftMargin"> <number>0</number> @@ -6930,7 +6930,7 @@ <string>Basic.Settings.Hotkeys.PleaseWait</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -6960,10 +6960,10 @@ <item> <widget class="QScrollArea" name="scrollArea_7"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -7014,10 +7014,10 @@ </property> <layout class="QFormLayout" name="formLayout_8"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -7099,7 +7099,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7125,7 +7125,7 @@ <item> <spacer name="colorSpacer_1"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7185,7 +7185,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7211,7 +7211,7 @@ <item> <spacer name="colorSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7271,7 +7271,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7297,7 +7297,7 @@ <item> <spacer name="colorSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7357,7 +7357,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7383,7 +7383,7 @@ <item> <spacer name="colorSpacer_4"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7443,7 +7443,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7469,7 +7469,7 @@ <item> <spacer name="colorSpacer_5"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7529,7 +7529,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7555,7 +7555,7 @@ <item> <spacer name="colorSpacer_6"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7615,7 +7615,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7641,7 +7641,7 @@ <item> <spacer name="colorSpacer_7"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7701,7 +7701,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7727,7 +7727,7 @@ <item> <spacer name="colorSpacer_8"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7787,7 +7787,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -7813,7 +7813,7 @@ <item> <spacer name="colorSpacer_9"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7831,10 +7831,10 @@ <item> <spacer name="verticalSpacer_7"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7869,10 +7869,10 @@ <item> <widget class="QScrollArea" name="scrollArea"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -7885,7 +7885,7 @@ <rect> <x>0</x> <y>0</y> - <width>755</width> + <width>759</width> <height>952</height> </rect> </property> @@ -7924,10 +7924,10 @@ </property> <layout class="QFormLayout" name="formLayout_22"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -7948,7 +7948,7 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_13"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -7975,10 +7975,10 @@ </property> <layout class="QFormLayout" name="formLayout_14"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -8006,7 +8006,7 @@ <string>Basic.Settings.Video.Adapter</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>adapter</cstring> @@ -8035,7 +8035,7 @@ <string>Basic.Settings.Advanced.Video.ColorFormat</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="buddy"> <cstring>colorFormat</cstring> @@ -8118,7 +8118,7 @@ <number>0</number> </property> <item> - <widget class="QSpinBox" name="sdrWhiteLevel"> + <widget class="OBS::SpinBox" name="sdrWhiteLevel"> <property name="suffix"> <string notr="true"> nits</string> </property> @@ -8147,7 +8147,7 @@ </widget> </item> <item> - <widget class="QSpinBox" name="hdrNominalPeakLevel"> + <widget class="OBS::SpinBox" name="hdrNominalPeakLevel"> <property name="suffix"> <string notr="true"> nits</string> </property> @@ -8194,7 +8194,7 @@ <item row="6" column="0"> <spacer name="horizontalSpacer_12"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8214,10 +8214,10 @@ </property> <layout class="QFormLayout" name="formLayout_17"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -8287,7 +8287,7 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_10"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8307,7 +8307,7 @@ <item row="2" column="0"> <spacer name="horizontalSpacer_16"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8327,10 +8327,10 @@ </property> <layout class="QFormLayout" name="formLayout_18"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -8367,7 +8367,7 @@ <number>0</number> </property> <item> - <widget class="QSpinBox" name="streamDelaySec"> + <widget class="OBS::SpinBox" name="streamDelaySec"> <property name="enabled"> <bool>true</bool> </property> @@ -8424,7 +8424,7 @@ <item row="2" column="0"> <spacer name="horizontalSpacer_9"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8444,10 +8444,10 @@ </property> <layout class="QFormLayout" name="formLayout_19"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -8477,7 +8477,7 @@ <number>0</number> </property> <item> - <widget class="QSpinBox" name="reconnectRetryDelay"> + <widget class="OBS::SpinBox" name="reconnectRetryDelay"> <property name="suffix"> <string> s</string> </property> @@ -8506,7 +8506,7 @@ </widget> </item> <item> - <widget class="QSpinBox" name="reconnectMaxRetries"> + <widget class="OBS::SpinBox" name="reconnectMaxRetries"> <property name="minimum"> <number>1</number> </property> @@ -8530,7 +8530,7 @@ <item row="0" column="0"> <spacer name="horizontalSpacer_8"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8550,10 +8550,10 @@ </property> <layout class="QFormLayout" name="formLayout_23"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -8611,7 +8611,7 @@ <item row="4" column="0"> <spacer name="horizontalSpacer_7"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8641,10 +8641,10 @@ </property> <layout class="QFormLayout" name="formLayout_34"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -8652,7 +8652,7 @@ <item row="0" column="0"> <spacer name="horizontalSpacer_15"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8679,10 +8679,10 @@ </property> <layout class="QFormLayout" name="formLayout_33"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>2</number> @@ -8700,7 +8700,7 @@ <item row="1" column="0"> <spacer name="horizontalSpacer_14"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8716,10 +8716,10 @@ <item> <spacer name="verticalSpacer_13"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -8789,7 +8789,7 @@ <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set> </property> </widget> </item> @@ -8797,20 +8797,30 @@ </widget> <customwidgets> <customwidget> - <class>UrlPushButton</class> - <extends>QPushButton</extends> - <header>components/UrlPushButton.hpp</header> + <class>OBS::SpinBox</class> + <extends>QSpinBox</extends> + <header>SpinBox.hpp</header> </customwidget> <customwidget> - <class>OBSHotkeyEdit</class> - <extends>QLineEdit</extends> - <header>settings/OBSHotkeyEdit.hpp</header> + <class>OBS::DoubleSpinBox</class> + <extends>QDoubleSpinBox</extends> + <header>DoubleSpinBox.hpp</header> </customwidget> <customwidget> <class>AbsoluteSlider</class> <extends>QSlider</extends> <header>components/AbsoluteSlider.hpp</header> </customwidget> + <customwidget> + <class>OBSHotkeyEdit</class> + <extends>QLineEdit</extends> + <header>settings/OBSHotkeyEdit.hpp</header> + </customwidget> + <customwidget> + <class>UrlPushButton</class> + <extends>QPushButton</extends> + <header>components/UrlPushButton.hpp</header> + </customwidget> </customwidgets> <tabstops> <tabstop>listWidget</tabstop>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSBasicSourceSelect.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSBasicSourceSelect.ui
Changed
@@ -3,7 +3,7 @@ <class>OBSBasicSourceSelect</class> <widget class="QDialog" name="OBSBasicSourceSelect"> <property name="windowModality"> - <enum>Qt::NonModal</enum> + <enum>Qt::WindowModality::NonModal</enum> </property> <property name="geometry"> <rect> @@ -56,10 +56,10 @@ </sizepolicy> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -98,10 +98,10 @@ <string>Basic.SourceSelect.SelectType</string> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -143,37 +143,34 @@ <string>Basic.SourceSelect.SelectType</string> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> </property> <property name="verticalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOn</enum> + <enum>Qt::ScrollBarPolicy::ScrollBarAsNeeded</enum> </property> <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOff</enum> + <enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOff</enum> </property> <property name="sizeAdjustPolicy"> - <enum>QAbstractScrollArea::AdjustToContentsOnFirstShow</enum> + <enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum> </property> <property name="editTriggers"> - <set>QAbstractItemView::NoEditTriggers</set> + <set>QAbstractItemView::EditTrigger::NoEditTriggers</set> </property> <property name="showDropIndicator" stdset="0"> <bool>false</bool> </property> <property name="verticalScrollMode"> - <enum>QAbstractItemView::ScrollPerPixel</enum> - </property> - <property name="horizontalScrollMode"> - <enum>QAbstractItemView::ScrollPerPixel</enum> + <enum>QAbstractItemView::ScrollMode::ScrollPerPixel</enum> </property> <property name="resizeMode"> - <enum>QListView::Adjust</enum> + <enum>QListView::ResizeMode::Adjust</enum> </property> <property name="class" stdset="0"> <string/> @@ -183,10 +180,10 @@ <item> <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Minimum</enum> + <enum>QSizePolicy::Policy::Minimum</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -202,10 +199,10 @@ <item> <widget class="QFrame" name="sourcesFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -232,10 +229,10 @@ <item> <widget class="QFrame" name="selectSourceContainer"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -282,10 +279,10 @@ <item> <widget class="QFrame" name="deprecatedFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -318,10 +315,10 @@ </sizepolicy> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -330,7 +327,7 @@ <string>Basic.SourceSelect.Deprecated.Create</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -343,7 +340,7 @@ <string>Basic.SourceSelect.AddExisting</string> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -398,7 +395,7 @@ <string>Basic.SourceSelect.NoExisting</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> <property name="class" stdset="0"> <string>text-muted</string> @@ -408,25 +405,25 @@ <item> <widget class="QScrollArea" name="existingScrollArea"> <property name="focusPolicy"> - <enum>Qt::NoFocus</enum> + <enum>Qt::FocusPolicy::NoFocus</enum> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> </property> <property name="verticalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOn</enum> + <enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOn</enum> </property> <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOff</enum> + <enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOff</enum> </property> <property name="sizeAdjustPolicy"> - <enum>QAbstractScrollArea::AdjustToContents</enum> + <enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum> </property> <property name="widgetResizable"> <bool>true</bool> @@ -462,10 +459,10 @@ <item> <widget class="FlowFrame" name="existingListFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -475,7 +472,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -490,25 +487,19 @@ </widget> </item> <item> - <widget class="QWidget" name="addExistingContainer" native="true"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> + <widget class="QFrame" name="addExistingContainer"> <layout class="QHBoxLayout" name="horizontalLayout_4"> <property name="leftMargin"> - <number>0</number> + <number>1</number> </property> <property name="topMargin"> - <number>0</number> + <number>1</number> </property> <property name="rightMargin"> - <number>0</number> + <number>1</number> </property> <property name="bottomMargin"> - <number>0</number> + <number>1</number> </property> <item> <widget class="QPushButton" name="addExistingButton"> @@ -532,7 +523,7 @@ <item> <spacer name="horizontalSpacer_4"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -545,7 +536,7 @@ <item> <spacer name="horizontalSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -567,10 +558,10 @@ <item> <widget class="QFrame" name="footer"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -607,7 +598,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -626,7 +617,7 @@ </sizepolicy> </property> <property name="standardButtons"> - <set>QDialogButtonBox::Close</set> + <set>QDialogButtonBox::StandardButton::Close</set> </property> <property name="centerButtons"> <bool>false</bool>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSBasicTransform.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSBasicTransform.ui
Changed
@@ -35,10 +35,10 @@ <item> <widget class="QFrame" name="outerFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -65,10 +65,10 @@ <item> <widget class="QFrame" name="transformSettings"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -104,7 +104,7 @@ <string>Basic.TransformWindow.Width</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -117,12 +117,12 @@ <string>X</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> <item row="1" column="3"> - <widget class="QDoubleSpinBox" name="sizeX"> + <widget class="OBS::DoubleSpinBox" name="sizeX"> <property name="minimumSize"> <size> <width>120</width> @@ -169,7 +169,7 @@ </widget> </item> <item row="1" column="1"> - <widget class="QDoubleSpinBox" name="positionX"> + <widget class="OBS::DoubleSpinBox" name="positionX"> <property name="minimumSize"> <size> <width>120</width> @@ -200,7 +200,7 @@ </widget> </item> <item row="1" column="4"> - <widget class="QDoubleSpinBox" name="rotation"> + <widget class="OBS::DoubleSpinBox" name="rotation"> <property name="sizePolicy"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -245,7 +245,7 @@ <string>Basic.TransformWindow.Size</string> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="class" stdset="0"> <string>subtitle</string> @@ -261,7 +261,7 @@ <string>Basic.TransformWindow.Position</string> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="class" stdset="0"> <string>subtitle</string> @@ -271,7 +271,7 @@ <item row="1" column="6"> <spacer name="horizontalSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -290,12 +290,12 @@ <string>Y</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> <item row="2" column="1"> - <widget class="QDoubleSpinBox" name="positionY"> + <widget class="OBS::DoubleSpinBox" name="positionY"> <property name="minimumSize"> <size> <width>120</width> @@ -326,7 +326,7 @@ </widget> </item> <item row="2" column="3"> - <widget class="QDoubleSpinBox" name="sizeY"> + <widget class="OBS::DoubleSpinBox" name="sizeY"> <property name="minimumSize"> <size> <width>120</width> @@ -368,17 +368,17 @@ <string>Basic.TransformWindow.Height</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> <item row="1" column="5"> <widget class="QFrame" name="alignmentWidget"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -421,10 +421,10 @@ <item> <widget class="QFrame" name="boundsSettings"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -496,7 +496,7 @@ <item row="0" column="7" rowspan="4"> <spacer name="horizontalSpacer_4"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -522,10 +522,10 @@ <item row="1" column="3"> <widget class="QFrame" name="alignmentWidget2"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -568,7 +568,7 @@ <string>Basic.TransformWindow.Width</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -581,12 +581,12 @@ <string>Basic.TransformWindow.Height</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> <item row="2" column="1"> - <widget class="QDoubleSpinBox" name="boundsWidth"> + <widget class="OBS::DoubleSpinBox" name="boundsWidth"> <property name="enabled"> <bool>false</bool> </property> @@ -620,7 +620,7 @@ </widget> </item> <item row="3" column="1"> - <widget class="QDoubleSpinBox" name="boundsHeight"> + <widget class="OBS::DoubleSpinBox" name="boundsHeight"> <property name="enabled"> <bool>false</bool> </property> @@ -714,7 +714,7 @@ <string>Left</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -724,12 +724,12 @@ <string>Right</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> <item row="2" column="3"> - <widget class="QSpinBox" name="cropBottom"> + <widget class="OBS::SpinBox" name="cropBottom"> <property name="sizePolicy"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -762,7 +762,7 @@ <item row="1" column="4"> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -773,7 +773,7 @@ </spacer> </item> <item row="1" column="3"> - <widget class="QSpinBox" name="cropRight"> + <widget class="OBS::SpinBox" name="cropRight"> <property name="sizePolicy"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -804,7 +804,7 @@ </widget> </item> <item row="1" column="1"> - <widget class="QSpinBox" name="cropLeft"> + <widget class="OBS::SpinBox" name="cropLeft"> <property name="sizePolicy"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -840,12 +840,12 @@ <string>Top</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> <item row="2" column="1"> - <widget class="QSpinBox" name="cropTop"> + <widget class="OBS::SpinBox" name="cropTop"> <property name="sizePolicy"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -894,7 +894,7 @@ <string>Bottom</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -904,7 +904,7 @@ <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Close|QDialogButtonBox::Reset</set> + <set>QDialogButtonBox::StandardButton::Close|QDialogButtonBox::StandardButton::Reset</set> </property> </widget> </item> @@ -928,6 +928,18 @@ <tabstop>cropTop</tabstop> <tabstop>cropBottom</tabstop> </tabstops> + <customwidgets> + <customwidget> + <class>OBS::SpinBox</class> + <extends>QSpinBox</extends> + <header>SpinBox.hpp</header> + </customwidget> + <customwidget> + <class>OBS::DoubleSpinBox</class> + <extends>QDoubleSpinBox</extends> + <header>DoubleSpinBox.hpp</header> + </customwidget> + </customwidgets> <resources/> <connections> <connection>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSBasicVCamConfig.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSBasicVCamConfig.ui
Changed
@@ -50,7 +50,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -63,10 +63,10 @@ <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set> </property> </widget> </item>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSExtraBrowsers.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSExtraBrowsers.ui
Changed
@@ -30,7 +30,7 @@ <item> <widget class="QTableView" name="table"> <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> + <enum>QAbstractItemView::SelectionMode::NoSelection</enum> </property> <attribute name="horizontalHeaderMinimumSectionSize"> <number>23</number> @@ -51,7 +51,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSIdianPlayground.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSIdianPlayground.ui
Changed
@@ -17,7 +17,7 @@ <item> <widget class="QScrollArea" name="scrollArea"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="widgetResizable"> <bool>true</bool> @@ -27,8 +27,8 @@ <rect> <x>0</x> <y>0</y> - <width>786</width> - <height>919</height> + <width>682</width> + <height>682</height> </rect> </property> <layout class="QVBoxLayout" name="scrollContentsLayout">
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSImporter.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSImporter.ui
Changed
@@ -32,7 +32,7 @@ <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set> </property> </widget> </item> @@ -48,7 +48,7 @@ <item row="1" column="0"> <widget class="QTableView" name="tableView"> <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> + <enum>QAbstractItemView::SelectionMode::NoSelection</enum> </property> <attribute name="horizontalHeaderMinimumSectionSize"> <number>23</number>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSLogViewer.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSLogViewer.ui
Changed
@@ -60,7 +60,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSMissingFiles.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSMissingFiles.ui
Changed
@@ -53,7 +53,7 @@ <item row="2" column="0"> <widget class="QTableView" name="tableView"> <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> + <enum>QAbstractItemView::SelectionMode::NoSelection</enum> </property> <attribute name="horizontalHeaderMinimumSectionSize"> <number>23</number> @@ -83,7 +83,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSPermissions.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSPermissions.ui
Changed
@@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>692</width> - <height>613</height> + <height>679</height> </rect> </property> <property name="sizePolicy"> @@ -39,7 +39,7 @@ <number>0</number> </property> <property name="sizeConstraint"> - <enum>QLayout::SetNoConstraint</enum> + <enum>QLayout::SizeConstraint::SetNoConstraint</enum> </property> <property name="leftMargin"> <number>0</number> @@ -70,7 +70,7 @@ <item row="1" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -103,10 +103,10 @@ <item row="0" column="0"> <layout class="QFormLayout" name="formLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> </property> <property name="rowWrapPolicy"> - <enum>QFormLayout::WrapAllRows</enum> + <enum>QFormLayout::RowWrapPolicy::WrapAllRows</enum> </property> <property name="topMargin"> <number>22</number> @@ -125,7 +125,7 @@ <string>MacPermissions.Item.ScreenRecording</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -147,7 +147,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -198,7 +198,7 @@ <string>MacPermissions.Item.Camera</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -223,7 +223,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -274,7 +274,7 @@ <string>MacPermissions.Item.Microphone</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -296,7 +296,7 @@ <item> <spacer name="horizontalSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -347,7 +347,7 @@ <string>MacPermissions.Item.InputMonitoring</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -364,10 +364,26 @@ <item row="7" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_5"> <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> + <enum>QLayout::SizeConstraint::SetDefaultConstraint</enum> + </property> + <property name="topMargin"> + <number>8</number> + </property> + <property name="bottomMargin"> + <number>25</number> </property> <item> - <widget class="QWidget"/> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> </item> <item> <widget class="QPushButton" name="inputMonitoringPermissionButton"> @@ -412,7 +428,7 @@ <item row="9" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_6"> <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> + <enum>QLayout::SizeConstraint::SetDefaultConstraint</enum> </property> <property name="topMargin"> <number>8</number> @@ -423,7 +439,7 @@ <item> <spacer name="horizontalSpacer_4"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSRemux.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSRemux.ui
Changed
@@ -32,7 +32,7 @@ <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Close|QDialogButtonBox::Ok|QDialogButtonBox::Reset|QDialogButtonBox::RestoreDefaults</set> + <set>QDialogButtonBox::StandardButton::Close|QDialogButtonBox::StandardButton::Ok|QDialogButtonBox::StandardButton::Reset|QDialogButtonBox::StandardButton::RestoreDefaults</set> </property> </widget> </item> @@ -41,7 +41,7 @@ <item row="1" column="0"> <widget class="QTableView" name="tableView"> <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> + <enum>QAbstractItemView::SelectionMode::NoSelection</enum> </property> <attribute name="horizontalHeaderMinimumSectionSize"> <number>23</number>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSUpdate.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSUpdate.ui
Changed
@@ -44,7 +44,7 @@ <item> <widget class="Line" name="line"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> </widget> </item> @@ -53,7 +53,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -90,7 +90,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/OBSYoutubeActions.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/OBSYoutubeActions.ui
Changed
@@ -27,7 +27,7 @@ <number>6</number> </property> <property name="sizeConstraint"> - <enum>QLayout::SetMinimumSize</enum> + <enum>QLayout::SizeConstraint::SetMinimumSize</enum> </property> <item> <widget class="QTabWidget" name="tabWidget"> @@ -88,10 +88,10 @@ </property> <layout class="QFormLayout" name="formLayout_2"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <property name="topMargin"> <number>9</number> @@ -152,7 +152,7 @@ </sizepolicy> </property> <property name="sizeAdjustPolicy"> - <enum>QComboBox::AdjustToContentsOnFirstShow</enum> + <enum>QComboBox::SizeAdjustPolicy::AdjustToContentsOnFirstShow</enum> </property> </widget> </item> @@ -204,7 +204,7 @@ <string>YouTube.Actions.MadeForKids.Help</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> </widget> </item> @@ -248,13 +248,13 @@ </size> </property> <property name="frameShape"> - <enum>QFrame::Box</enum> + <enum>QFrame::Shape::Box</enum> </property> <property name="text"> <string/> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -285,7 +285,7 @@ <item row="26" column="1"> <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -338,14 +338,14 @@ <string>YouTube.Actions.360Video.Help</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> </widget> </item> <item> <spacer name="horizontalSpacer_10"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -387,14 +387,14 @@ <string notr="true"><a href=".">(?)</a></string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> </widget> </item> <item> <spacer name="horizontalSpacer_9"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -438,7 +438,7 @@ <item row="10" column="1"> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -511,7 +511,7 @@ <item> <widget class="QScrollArea" name="scrollArea"> <property name="verticalScrollBarPolicy"> - <enum>Qt::ScrollBarAsNeeded</enum> + <enum>Qt::ScrollBarPolicy::ScrollBarAsNeeded</enum> </property> <property name="widgetResizable"> <bool>true</bool> @@ -541,10 +541,10 @@ <string><big>Friday Fortnite Stream</big><br/>scheduled for 11/11/20 2:00pm</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> <property name="margin"> <number>4</number> @@ -560,10 +560,10 @@ <string><big>Friday Fortnite Stream</big><br/>scheduled for 11/11/20 2:00pm</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> <property name="margin"> <number>4</number> @@ -579,10 +579,10 @@ <string><big>Friday Fortnite Stream</big><br/>scheduled for 11/11/20 2:00pm</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> <property name="margin"> <number>4</number> @@ -598,10 +598,10 @@ <string><big>Friday Fortnite Stream</big><br/>scheduled for 11/11/20 2:00pm</string> </property> <property name="textFormat"> - <enum>Qt::RichText</enum> + <enum>Qt::TextFormat::RichText</enum> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> <property name="margin"> <number>4</number> @@ -617,7 +617,7 @@ </widget> </item> <item> - <widget class="QWidget" name="widget" native="true"> + <widget class="QWidget" name="widget"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> @@ -646,7 +646,7 @@ <number>10</number> </property> <property name="sizeConstraint"> - <enum>QLayout::SetNoConstraint</enum> + <enum>QLayout::SizeConstraint::SetNoConstraint</enum> </property> <item> <widget class="QPushButton" name="cancelButton">
View file
obs-studio-32.2.2.tar.xz/frontend/forms/PluginManagerWindow.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/PluginManagerWindow.ui
Changed
@@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>861</width> - <height>400</height> + <width>800</width> + <height>560</height> </rect> </property> <property name="windowTitle"> @@ -32,10 +32,10 @@ <item> <widget class="QFrame" name="dialogInner"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -62,15 +62,15 @@ <item> <widget class="QFrame" name="frame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> </property> - <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,4"> + <layout class="QHBoxLayout" name="horizontalLayout"> <property name="spacing"> <number>0</number> </property> @@ -88,11 +88,17 @@ </property> <item> <widget class="QFrame" name="sectionFrame"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -118,17 +124,26 @@ </property> <item> <widget class="QListWidget" name="sectionList"> + <property name="minimumSize"> + <size> + <width>180</width> + <height>0</height> + </size> + </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> </property> + <property name="sizeAdjustPolicy"> + <enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContentsOnFirstShow</enum> + </property> <property name="editTriggers"> - <set>QAbstractItemView::NoEditTriggers</set> + <set>QAbstractItemView::EditTrigger::NoEditTriggers</set> </property> <property name="showDropIndicator" stdset="0"> <bool>false</bool> @@ -139,178 +154,176 @@ </widget> </item> <item> - <widget class="QFrame" name="modulesFrame"> + <widget class="QStackedWidget" name="stackedContents"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> </property> <property name="class" stdset="0"> - <string>dialog-container dialog-frame</string> + <string>dialog-frame</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <property name="spacing"> - <number>0</number> + <widget class="QWidget" name="browsePage"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <widget class="QLabel" name="browseTitle"> + <property name="text"> + <string>NOT IMPLEMENTED</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="installedPage"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - <item> - <widget class="QLabel" name="label"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="lineWidth"> - <number>0</number> - </property> - <property name="text"> - <string>PluginManager.Section.Manage.Title</string> - </property> - <property name="indent"> - <number>0</number> - </property> - <property name="class" stdset="0"> - <string>text-title</string> - </property> - </widget> - </item> - <item> - <widget class="QScrollArea" name="modulesListContainer"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="lineWidth"> - <number>0</number> - </property> - <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="sizeAdjustPolicy"> - <enum>QAbstractScrollArea::AdjustToContents</enum> - </property> - <property name="widgetResizable"> - <bool>false</bool> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - <property name="class" stdset="0"> - <string/> - </property> - <widget class="QWidget" name="modulesListContents"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>689</width> - <height>50</height> - </rect> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QScrollArea" name="modulesListContainer"> + <property name="frameShape"> + <enum>QFrame::Shape::NoFrame</enum> </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <property name="frameShadow"> + <enum>QFrame::Shadow::Plain</enum> </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <property name="spacing"> - <number>0</number> - </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <property name="alignment"> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> + </property> + <widget class="QWidget" name="modulesListOuter"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>620</width> + <height>520</height> + </rect> </property> - <item> - <widget class="QFrame" name="modulesList"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>20</height> - </size> - </property> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="lineWidth"> - <number>0</number> - </property> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <property name="spacing"> - <number>0</number> - </property> - <property name="leftMargin"> - <number>0</number> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QFrame" name="modulesList"> + <property name="frameShape"> + <enum>QFrame::Shape::NoFrame</enum> </property> - <property name="topMargin"> - <number>0</number> + <property name="frameShadow"> + <enum>QFrame::Shadow::Plain</enum> </property> - <property name="rightMargin"> + <property name="lineWidth"> <number>0</number> </property> - <property name="bottomMargin"> - <number>0</number> + <property name="class" stdset="0"> + <string>dialog-container</string> </property> - </layout> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>10</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - </layout> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <property name="spacing"> + <number>6</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + </layout> + </widget> + </item> + </layout> + </widget> </widget> - </widget> - </item> - <item> - <widget class="QLabel" name="manageRestartLabel"> - <property name="text"> - <string>PluginManager.Restart</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - <property name="class" stdset="0"> - <string>frame-notice</string> - </property> - </widget> - </item> - </layout> + </item> + <item> + <widget class="QLabel" name="manageRestartLabel"> + <property name="text"> + <string>PluginManager.Restart</string> + </property> + <property name="alignment"> + <set>Qt::AlignmentFlag::AlignCenter</set> + </property> + <property name="class" stdset="0"> + <string>frame-notice</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="updatesPage"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <widget class="QLabel" name="browseTitle_2"> + <property name="text"> + <string>NOT IMPLEMENTED</string> + </property> + </widget> + </item> + </layout> + </widget> </widget> </item> </layout> @@ -319,10 +332,10 @@ <item> <widget class="QFrame" name="footer"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -349,7 +362,7 @@ <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::StandardButton::Discard|QDialogButtonBox::StandardButton::Save</set> </property> </widget> </item>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/StatusBarWidget.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/StatusBarWidget.ui
Changed
@@ -47,10 +47,10 @@ <string notr="true">border: none;</string> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <layout class="QHBoxLayout" name="horizontalLayout_9"> <property name="leftMargin"> @@ -84,10 +84,10 @@ <item> <widget class="QFrame" name="delayFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -124,10 +124,10 @@ <item> <widget class="QFrame" name="issuesFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -164,10 +164,10 @@ <item> <widget class="QFrame" name="networkFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -219,7 +219,7 @@ <string>0 kbps</string> </property> <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -229,10 +229,10 @@ <item> <widget class="QFrame" name="streamFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -297,10 +297,10 @@ </sizepolicy> </property> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -359,10 +359,10 @@ <item> <widget class="QFrame" name="cpuFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -392,7 +392,7 @@ <string>CPU: 0.0%</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -402,10 +402,10 @@ <item> <widget class="QFrame" name="fpsFrame"> <property name="frameShape"> - <enum>QFrame::NoFrame</enum> + <enum>QFrame::Shape::NoFrame</enum> </property> <property name="frameShadow"> - <enum>QFrame::Plain</enum> + <enum>QFrame::Shadow::Plain</enum> </property> <property name="lineWidth"> <number>0</number> @@ -435,7 +435,7 @@ <string>0.00 / 0.00 FPS</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/source-toolbar/browser-source-toolbar.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/source-toolbar/browser-source-toolbar.ui
Changed
@@ -64,14 +64,14 @@ <item> <widget class="Line" name="line"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> </widget> </item> <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/source-toolbar/color-source-toolbar.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/source-toolbar/color-source-toolbar.ui
Changed
@@ -56,7 +56,7 @@ <string notr="true">color here</string> </property> <property name="alignment"> - <set>Qt::AlignCenter</set> + <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> </item> @@ -76,7 +76,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/source-toolbar/device-select-toolbar.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/source-toolbar/device-select-toolbar.ui
Changed
@@ -27,7 +27,7 @@ </property> <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1,0,0"> <property name="sizeConstraint"> - <enum>QLayout::SetNoConstraint</enum> + <enum>QLayout::SizeConstraint::SetNoConstraint</enum> </property> <property name="leftMargin"> <number>0</number> @@ -87,7 +87,7 @@ <string notr="true"/> </property> <property name="sizeAdjustPolicy"> - <enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum> + <enum>QComboBox::SizeAdjustPolicy::AdjustToMinimumContentsLengthWithIcon</enum> </property> </widget> </item> @@ -113,10 +113,10 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/source-toolbar/game-capture-toolbar.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/source-toolbar/game-capture-toolbar.ui
Changed
@@ -131,14 +131,14 @@ <string notr="true"/> </property> <property name="sizeAdjustPolicy"> - <enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum> + <enum>QComboBox::SizeAdjustPolicy::AdjustToMinimumContentsLengthWithIcon</enum> </property> </widget> </item> <item> <spacer name="empty"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/source-toolbar/image-source-toolbar.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/source-toolbar/image-source-toolbar.ui
Changed
@@ -104,7 +104,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/frontend/forms/source-toolbar/media-controls.ui -> obs-studio-33.0.0.tar.xz/frontend/forms/source-toolbar/media-controls.ui
Changed
@@ -220,7 +220,7 @@ <bool>false</bool> </property> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> </widget> </item>
View file
obs-studio-32.2.2.tar.xz/frontend/importer/OBSImporter.cpp -> obs-studio-33.0.0.tar.xz/frontend/importer/OBSImporter.cpp
Changed
@@ -92,8 +92,7 @@ ui->tableView->resizeColumnsToContents(); QModelIndex index = optionsModel->createIndex(optionsModel->rowCount() - 1, 2); - QMetaObject::invokeMethod(ui->tableView, "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(const QModelIndex &, index)); + QMetaObject::invokeMethod(ui->tableView, &QTableView::setCurrentIndex, Qt::QueuedConnection, index); } void OBSImporter::addImportOption(QString path, bool automatic)
View file
obs-studio-32.2.2.tar.xz/frontend/oauth/TwitchAuth.cpp -> obs-studio-33.0.0.tar.xz/frontend/oauth/TwitchAuth.cpp
Changed
@@ -9,6 +9,7 @@ #include <qt-wrappers.hpp> #include <ui-config.h> +#include <QTimer> #include <QUuid> #include "moc_TwitchAuth.cpp" @@ -440,9 +441,9 @@ } if (!found) { - QMetaObject::invokeMethod(&this_->uiLoadTimer, "start"); + QMetaObject::invokeMethod(this_, this_() { this_->uiLoadTimer.start(); }); } else { - QMetaObject::invokeMethod(this_, "LoadSecondaryUIPanes"); + QMetaObject::invokeMethod(this_, &TwitchAuth::LoadSecondaryUIPanes); } };
View file
obs-studio-32.2.2.tar.xz/frontend/oauth/YoutubeAuth.cpp -> obs-studio-33.0.0.tar.xz/frontend/oauth/YoutubeAuth.cpp
Changed
@@ -245,7 +245,7 @@ dlg.setText(text); dlg.setTextFormat(Qt::RichText); dlg.setStandardButtons(QMessageBox::StandardButton::Cancel); -#if defined(__APPLE__) && QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) +#if defined(__APPLE__) /* We can't show clickable links with the native NSAlert, so let's * force the old non-native dialog instead. */ dlg.setOption(QMessageBox::Option::DontUseNativeDialog); @@ -280,14 +280,7 @@ QScopedPointer<QThread> thread(CreateQThread(open_external_browser)); thread->start(); -#if defined(__APPLE__) && QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) && QT_VERSION < QT_VERSION_CHECK(6, 6, 0) - const bool nativeDialogs = qApp->testAttribute(Qt::AA_DontUseNativeDialogs); - App()->setAttribute(Qt::AA_DontUseNativeDialogs, true); dlg.exec(); - App()->setAttribute(Qt::AA_DontUseNativeDialogs, nativeDialogs); -#else - dlg.exec(); -#endif if (dlg.result() == QMessageBox::Cancel || dlg.result() == QDialog::Rejected) { return nullptr;
View file
obs-studio-32.2.2.tar.xz/frontend/obs-main.cpp -> obs-studio-33.0.0.tar.xz/frontend/obs-main.cpp
Changed
@@ -115,8 +115,7 @@ logFile << msg << endl; logfile_mutex.unlock(); - QMetaObject::invokeMethod(App(), "addLogLine", Qt::QueuedConnection, Q_ARG(int, log_level), - Q_ARG(QString, QString(msg.c_str()))); + QMetaObject::invokeMethod(App(), &OBSApp::addLogLine, Qt::QueuedConnection, log_level, QString(msg.c_str())); } static inline void LogStringChunk(fstream &logFile, char *str, int log_level)
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/InstalledPluginRow.cpp
Added
@@ -0,0 +1,169 @@ +/****************************************************************************** + Copyright (C) 2026 by Warchamp7 <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "InstalledPluginRow.hpp" + +#include <OBSApp.hpp> +#include <components/InfoChip.hpp> + +#include <Idian/InlineButton.hpp> + +constexpr std::string_view kLegacyPluginInfoLink{"https://obsproject.com/go/legacy-plugin-locations"}; + +namespace OBS { +InstalledPluginRow::InstalledPluginRow(QWidget *parent, const PluginManagerWindow::Entry &entry) : idian::Row(parent) +{ + const OBS::ModuleInfo &metadata = entry.module; + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + QString name = entry.name; + + QString version = !metadata.version.empty() ? metadata.version.c_str() : ""; + + auto *moduleText = new QWidget{this}; + moduleText->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + auto *infoLayout = new QVBoxLayout{moduleText}; + infoLayout->setContentsMargins(0, 0, 0, 0); + moduleText->setLayout(infoLayout); + + auto *headerLayout = new QHBoxLayout{}; + headerLayout->setContentsMargins(0, 0, 0, 0); + headerLayout->setAlignment(Qt::AlignLeft); + infoLayout->addLayout(headerLayout); + + auto nameLabel = new QLabel{name, moduleText}; + nameLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); + nameLabel->setIndent(0); + idian::Utils::addClass(nameLabel, "title"); + if (!metadata.enabledAtLaunch) { + idian::Utils::addClass(nameLabel, "text-muted"); + } + headerLayout->addWidget(nameLabel); + + if (!version.isEmpty()) { + auto versionLabel = new QLabel{version, moduleText}; + versionLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); + idian::Utils::addClass(versionLabel, "description"); + headerLayout->addWidget(versionLabel); + } + + QVBoxLayout *detailsLayout = new QVBoxLayout{}; + detailsLayout->setContentsMargins(0, 0, 0, 0); + infoLayout->addLayout(detailsLayout); + + if (!entry.isLegacy) { + // TODO: Awaiting further implementation of module manifest data. + } + + this->addWidget(moduleText); + + InfoChip *statusChip{nullptr}; + if (obs_frontend_is_safe_mode_enabled()) { + idian::Utils::addClass(nameLabel, "text-muted"); + + statusChip = new InfoChip{QTStr("PluginManager.Status.Disabled"), moduleText}; + idian::Utils::addClass(statusChip, "bg-info"); + idian::Utils::addClass(statusChip, "text-muted"); + } else if (entry.category == PluginManagerWindow::Category::Error) { + idian::Utils::addClass(nameLabel, "text-muted"); + + statusChip = new InfoChip{QTStr("PluginManager.Status.Error"), moduleText}; + idian::Utils::addClass(statusChip, "bg-warning"); + idian::Utils::addClass(statusChip, "text-warning"); + } else if (entry.category == PluginManagerWindow::Category::Missing) { + idian::Utils::addClass(nameLabel, "text-muted"); + + statusChip = new InfoChip{QTStr("PluginManager.Status.Missing"), moduleText}; + idian::Utils::addClass(statusChip, "bg-danger"); + idian::Utils::addClass(statusChip, "text-danger"); + } else { + if (entry.isLegacy) { + auto legacyChip = new InfoChip{QTStr("PluginManager.Status.Legacy"), moduleText}; + idian::Utils::addClass(legacyChip, "bg-primary"); + + headerLayout->insertWidget(0, legacyChip); + + auto legacyNotice = new QWidget{}; + legacyNotice->setLayout(new QHBoxLayout{}); + legacyNotice->layout()->setContentsMargins(0, 0, 0, 0); + + // TODO: https://github.com/obsproject/obs-studio/issues/14029 + // Re-enable this icon before the major version where we remove legacy plugin paths. + //auto warningIcon = new QLabel{moduleText}; + //warningIcon->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + //warningIcon->setPixmap(getWarningIcon().pixmap(16, 16)); + + auto legacyInfo = + new QLabel{QTStr("PluginManager.Status.Legacy.Description").arg(kLegacyPluginInfoLink), + moduleText}; + legacyInfo->setTextInteractionFlags(Qt::LinksAccessibleByMouse); + legacyInfo->setOpenExternalLinks(true); + idian::Utils::addClass(legacyInfo, "description"); + + //legacyNotice->layout()->addWidget(warningIcon); + legacyNotice->layout()->addWidget(legacyInfo); + + detailsLayout->addWidget(legacyNotice); + } + + if (!metadata.enabledAtLaunch) { + statusChip = new InfoChip{QTStr("PluginManager.Status.Disabled"), moduleText}; + idian::Utils::addClass(statusChip, "bg-info"); + idian::Utils::addClass(statusChip, "text-muted"); + } + } + + if (statusChip) { + headerLayout->addWidget(statusChip); + } + + if (entry.hasLoadedBefore) { + auto toggleSwitch = new idian::ToggleSwitch(this); + toggleSwitch->setChecked(metadata.enabled); + addWidget(toggleSwitch); + toggleSwitch->setAccessibleDescription(QTStr("PluginManager.Button.Enable").arg(name)); + + connect(toggleSwitch, &idian::ToggleSwitch::toggled, this, + this(bool checked) { emit toggleChanged(checked); }); + } + + if (entry.category == PluginManagerWindow::Category::Missing) { + auto removeButton = new idian::InlineButton(this); + removeButton->setAccessibleName(QTStr("Remove")); + removeButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + removeButton->setIcon(getTrashIcon()); + idian::Utils::addClass(removeButton, "icon-trash"); + addWidget(removeButton); + + connect(removeButton, &QAbstractButton::clicked, this, this() { + setEnabled(false); + + emit trashClicked(); + }); + } +} +const QIcon &InstalledPluginRow::getWarningIcon() +{ + static const QIcon &icon = *new QIcon(":/res/images/warning.svg"); + return icon; +} +const QIcon &InstalledPluginRow::getTrashIcon() +{ + static const QIcon &icon = *new QIcon(":/res/images/trash.svg"); + return icon; +} +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/InstalledPluginRow.hpp
Added
@@ -0,0 +1,40 @@ +/****************************************************************************** + Copyright (C) 2026 by Warchamp7 <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <plugin-manager/PluginManagerWindow.hpp> + +#include <Idian/Row.hpp> + +namespace OBS { + +class InstalledPluginRow : public idian::Row { + Q_OBJECT + +public: + InstalledPluginRow(QWidget *parent, const PluginManagerWindow::Entry &entry); + +signals: + void toggleChanged(bool enabled); + void trashClicked(); + +private: + static const QIcon &getWarningIcon(); + static const QIcon &getTrashIcon(); +}; +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/LoaderPaths_BSD.hpp.in
Added
@@ -0,0 +1,28 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <string_view> + +namespace OBS::Constants { +inline constexpr std::string_view kPlatformInstallPath{"@OBS_PLATFORM_INSTALL_PATH@"}; +inline constexpr std::string_view kPlatformLibraryPath{"@OBS_PLATFORM_LIBRARY_PATH@"}; +inline constexpr std::string_view kPlatformDataPath{"@OBS_PLATFORM_DATA_PATH@"}; +inline constexpr std::string_view kPlatformPluginModulePath{"@OBS_PLATFORM_PLUGIN_MODULE_PATH@"}; +inline constexpr std::string_view kPlatformPluginDataPath{"@OBS_PLATFORM_PLUGIN_DATA_PATH@"}; +} // namespace OBS::Constants
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/LoaderPaths_Flatpak.hpp.in
Added
@@ -0,0 +1,30 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <string_view> + +namespace OBS::Constants { +inline constexpr std::string_view kPlatformInstallPath{"@OBS_PLATFORM_INSTALL_PATH@"}; +inline constexpr std::string_view kPlatformLibraryPath{"@OBS_PLATFORM_LIBRARY_PATH@"}; +inline constexpr std::string_view kPlatformDataPath{"@OBS_PLATFORM_DATA_PATH@"}; +inline constexpr std::string_view kPlatformPluginModulePath{"@OBS_PLATFORM_PLUGIN_MODULE_PATH@"}; +inline constexpr std::string_view kPlatformPluginDataPath{"@OBS_PLATFORM_PLUGIN_DATA_PATH@"}; +inline constexpr std::string_view kXDGConfigHomeVariable{"XDG_CONFIG_HOME"}; +inline constexpr std::string_view kXDGDataHomeVariable{"XDG_DATA_HOME"}; +} // namespace OBS::Constants
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/LoaderPaths_Linux.hpp.in
Added
@@ -0,0 +1,30 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <string_view> + +namespace OBS::Constants { +inline constexpr std::string_view kPlatformInstallPath{"@OBS_PLATFORM_INSTALL_PATH@"}; +inline constexpr std::string_view kPlatformLibraryPath{"@OBS_PLATFORM_LIBRARY_PATH@"}; +inline constexpr std::string_view kPlatformDataPath{"@OBS_PLATFORM_DATA_PATH@"}; +inline constexpr std::string_view kPlatformPluginModulePath{"@OBS_PLATFORM_PLUGIN_MODULE_PATH@"}; +inline constexpr std::string_view kPlatformPluginDataPath{"@OBS_PLATFORM_PLUGIN_DATA_PATH@"}; +inline constexpr std::string_view kXDGConfigHomeVariable{"XDG_CONFIG_HOME"}; +inline constexpr std::string_view kXDGDataHomeVariable{"XDG_DATA_HOME"}; +} // namespace OBS::Constants
View file
obs-studio-32.2.2.tar.xz/frontend/plugin-manager/PluginManager.cpp -> obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginManager.cpp
Changed
@@ -39,7 +39,7 @@ std::string moduleName = obs_get_module_file_name(newModule); moduleName = moduleName.substr(0, moduleName.rfind(".")); - if (!obs_get_module_allow_disable(moduleName.c_str())) { + if (obs_is_core_module(newModule)) { return; } @@ -67,7 +67,7 @@ void PluginManager::preLoad() { - loadModules_(); + loadModuleConfiguration_(); disableModules_(); } @@ -82,6 +82,38 @@ linkUnloadedModules_(); } +void PluginManager::loadAllPlugins(bool usePortableMode) +{ + preLoad(); + bool coreModuleLoadSuccess = obs_load_core_modules(); + + if (!coreModuleLoadSuccess) { + loadState_ = State::Failure; + //TODO: Replace with structured exception type - https://github.com/obsproject/obs-studio/issues/13394 + throw "Failed to load core OBS modules. OBS cannot run without these modules. Please try reinstalling OBS."; + } else { + if (loadMode_ == Mode::Full) { + blog(LOG_INFO, "---------------------------------"); + State pluginState = loadPlugins(usePortableMode); + State legacyPluginState = loadLegacyPlugins(usePortableMode); + + if (pluginState && legacyPluginState) { + loadState_ = State::Success; + } else { + loadState_ = State::PartialFailure; + } + } else { + loadState_ = State::Success; + } + } + + blog(LOG_INFO, "---------------------------------"); + obs_log_loaded_modules(); + blog(LOG_INFO, "---------------------------------"); + obs_post_load_modules(); + postLoad(); +} + std::filesystem::path PluginManager::getConfigFilePath_() { std::filesystem::path path = App()->userPluginManagerSettingsLocation / @@ -90,7 +122,7 @@ return path; } -void PluginManager::loadModules_() +void PluginManager::loadModuleConfiguration_() { auto modulesFile = getConfigFilePath_(); if (std::filesystem::exists(modulesFile)) { @@ -282,31 +314,73 @@ void PluginManager::open() { auto main = OBSBasic::Get(); - PluginManagerWindow pluginManagerWindow(modules_, main); - auto result = pluginManagerWindow.exec(); - if (result == QDialog::Accepted) { - modules_ = pluginManagerWindow.result(); - saveModules_(); - - bool changed = false; - - for (auto const &moduleInfo : modules_) { - if (moduleInfo.enabled != moduleInfo.enabledAtLaunch) { - changed = true; - break; - } - } + auto *pluginManagerWindow = new PluginManagerWindow(modules_, failedModules_, main); + + QObject::connect(pluginManagerWindow, &QDialog::finished, pluginManagerWindow, + this, pluginManagerWindow, main(int result) { + if (result == QDialog::Accepted) { + modules_ = pluginManagerWindow->getModules(); + saveModules_(); + + bool changed = pluginManagerWindow->isEnabledPluginsChanged(); + if (changed) { + QMessageBox::StandardButton button = OBSMessageBox::question( + main, QTStr("Restart"), QTStr("NeedsRestart")); + + if (button == QMessageBox::Yes) { + restart = true; + main->close(); + } + } + } + + pluginManagerWindow->deleteLater(); + }); + + pluginManagerWindow->setModal(true); + pluginManagerWindow->show(); +} - if (changed) { - QMessageBox::StandardButton button = - OBSMessageBox::question(main, QTStr("Restart"), QTStr("NeedsRestart")); +}; // namespace OBS - if (button == QMessageBox::Yes) { - restart = true; - main->close(); - } - } +bool operator&&(const OBS::PluginManager::State &lhs, const OBS::PluginManager::State &rhs) +{ + using State = OBS::PluginManager::State; + + if (lhs == State::Success && rhs == State::Success) { + return true; } + + return false; } -}; // namespace OBS +bool operator&&(const OBS::PluginManager::State &lhs, bool rhs) +{ + return (lhs == OBS::PluginManager::State::Success && rhs); +} + +bool operator&&(bool lhs, const OBS::PluginManager::State &rhs) +{ + return (lhs && rhs == OBS::PluginManager::State::Success); +} + +bool operator||(const OBS::PluginManager::State &lhs, const OBS::PluginManager::State &rhs) +{ + using State = OBS::PluginManager::State; + + if (lhs == State::Success || rhs == State::Success) { + return true; + } + + return false; +} + +bool operator||(const OBS::PluginManager::State &lhs, bool rhs) +{ + return (lhs == OBS::PluginManager::State::Success || rhs); +} + +bool operator||(bool lhs, const OBS::PluginManager::State &rhs) +{ + return (lhs || rhs == OBS::PluginManager::State::Success); +}
View file
obs-studio-32.2.2.tar.xz/frontend/plugin-manager/PluginManager.hpp -> obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginManager.hpp
Changed
@@ -43,22 +43,41 @@ }; class PluginManager { +public: + using ModuleList = std::vector<std::string>; + enum class Mode { CoreOnly, Full }; + enum class State { Failure, PartialFailure, Success }; + private: + Mode loadMode_{Mode::Full}; + State loadState_{State::Failure}; + std::vector<ModuleInfo> modules_ = {}; - std::vector<std::string> disabledSources_ = {}; - std::vector<std::string> disabledOutputs_ = {}; - std::vector<std::string> disabledServices_ = {}; - std::vector<std::string> disabledEncoders_ = {}; + ModuleList failedModules_ = {}; + ModuleList disabledSources_ = {}; + ModuleList disabledOutputs_ = {}; + ModuleList disabledServices_ = {}; + ModuleList disabledEncoders_ = {}; std::filesystem::path getConfigFilePath_(); - void loadModules_(); + void loadModuleConfiguration_(); void saveModules_(); void disableModules_(); void addModuleTypes_(); void linkUnloadedModules_(); + State loadPlugins(bool usePortableMode); + State loadLegacyPlugins(bool usePortableMode); + public: + Mode pluginMode() { return loadMode_; } + void setPluginMode(Mode mode) { loadMode_ = mode; } + + State loadState() { return loadState_; } + + void disablePlugins(); void preLoad(); void postLoad(); + void loadAllPlugins(bool usePortableMode); void open(); friend void addModuleToPluginManagerImpl(void *param, obs_module_t *newModule); @@ -68,6 +87,14 @@ }; // namespace OBS +bool operator&&(const OBS::PluginManager::State &lhs, const OBS::PluginManager::State &rhs); +bool operator&&(const OBS::PluginManager::State &lhs, bool rhs); +bool operator&&(bool lhs, const OBS::PluginManager::State &rhs); + +bool operator||(const OBS::PluginManager::State &lhs, const OBS::PluginManager::State &rhs); +bool operator||(const OBS::PluginManager::State &lhs, bool rhs); +bool operator||(bool lhs, const OBS::PluginManager::State &rhs); + // Anonymous namespace function to add module to plugin manager // via libobs's module enumeration. namespace {
View file
obs-studio-32.2.2.tar.xz/frontend/plugin-manager/PluginManagerWindow.cpp -> obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginManagerWindow.cpp
Changed
@@ -18,22 +18,47 @@ #include "PluginManagerWindow.hpp" #include <OBSApp.hpp> +#include <plugin-manager/InstalledPluginRow.hpp> + +#include <Idian/ListHeader.hpp> +#include <Idian/RowList.hpp> +#include <Idian/Utils.hpp> #include <QCheckBox> #include <QDialogButtonBox> #include <QHBoxLayout> #include <QLabel> +#include <QPushButton> #include <QScrollArea> #include <QString> +#include <QTimer> #include <QVBoxLayout> #include "moc_PluginManagerWindow.cpp" extern bool safe_mode; +namespace { +using Category = OBS::PluginManagerWindow::Category; +constexpr int getCategorySortOrder(Category c) +{ + switch (c) { + case Category::Installed: + return 0; + case Category::Error: + return 1; + case Category::Missing: + return 2; + default: + return 3; + } +} +} // namespace + namespace OBS { +PluginManagerWindow::PluginManagerWindow(std::vector<ModuleInfo> const &modules, + std::vector<std::string> const &failedModules, QWidget *parent) -PluginManagerWindow::PluginManagerWindow(std::vector<ModuleInfo> const &modules, QWidget *parent) : QDialog(parent), modules_(modules), ui(new Ui::PluginManagerWindow) @@ -42,9 +67,6 @@ ui->setupUi(this); - ui->modulesListContainer->viewport()->setAutoFillBackground(false); - ui->modulesListContents->setAutoFillBackground(false); - // Set up sidebar entries ui->sectionList->clear(); ui->sectionList->setSelectionMode(QAbstractItemView::SingleSelection); @@ -67,106 +89,226 @@ updates->setToolTip(QTStr("ComingSoon")); ui->sectionList->addItem(updates); - setSection(ui->sectionList->indexFromItem(installed)); + setupInstalledPage(failedModules); - std::sort(modules_.begin(), modules_.end(), (const ModuleInfo &a, const ModuleInfo &b) { - std::string aName = !a.display_name.empty() ? a.display_name : a.module_name; - std::string bName = !b.display_name.empty() ? b.display_name : b.module_name; - return aName < bName; - }); + setPage(Page::Installed); - std::sort(modules_.begin(), modules_.end(), (const ModuleInfo &a, const ModuleInfo &b) { - bool missingA = !obs_get_module(a.module_name.c_str()) && - !obs_get_disabled_module(a.module_name.c_str()); - bool missingB = !obs_get_module(b.module_name.c_str()) && - !obs_get_disabled_module(b.module_name.c_str()); + ui->manageRestartLabel->setVisible(isEnabledPluginsChanged()); - return !missingA && missingB; - }); + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(ui->buttonBox->button(QDialogButtonBox::Discard), &QPushButton::clicked, this, &QDialog::close); +} - int row = 0; - int missingIndex = -1; +void PluginManagerWindow::setupInstalledPage(std::vector<std::string> failedModules) +{ + ui->modulesListContainer->viewport()->setAutoFillBackground(false); + ui->modulesListOuter->layout()->setAlignment(Qt::AlignTop | Qt::AlignHCenter); + ui->modulesListOuter->setAutoFillBackground(false); + + // Set up Idian sections + auto installedPluginList = new idian::RowList(ui->modulesList); + auto installedHeader = new idian::ListHeader(installedPluginList, QTStr("PluginManager.Section.Manage.Title"), + QTStr("PluginManager.Section.Manage.Description")); + installedPluginList->addHeader(installedHeader); + + auto errorPluginList = new idian::RowList(ui->modulesList); + auto errorHeader = new idian::ListHeader(errorPluginList, QTStr("PluginManager.Section.Errors.Title"), + QTStr("PluginManager.Section.Errors.Description")); + errorPluginList->addHeader(errorHeader); + + auto missingPluginList = new idian::RowList(ui->modulesList); + auto missingHeader = new idian::ListHeader(missingPluginList, QTStr("PluginManager.Section.Missing.Title"), + QTStr("PluginManager.Section.Missing.Description")); + missingPluginList->addHeader(missingHeader); + + bool isSafeMode = obs_frontend_is_safe_mode_enabled(); + if (isSafeMode) { + auto *safeModeFrame = new QFrame{}; + safeModeFrame->setLayout(new QVBoxLayout); + safeModeFrame->layout()->setContentsMargins(0, 0, 0, 0); + safeModeFrame->setProperty("class", "frame-notice"); + + auto *safeModeLabel = new QLabel(ui->modulesList); + safeModeLabel->setText(QTStr("PluginManager.SafeMode")); + safeModeLabel->setAlignment(Qt::AlignCenter); + safeModeLabel->setIndent(0); + + safeModeFrame->layout()->addWidget(safeModeLabel); + ui->installedPage->layout()->addWidget(safeModeFrame); + } + + ui->modulesList->layout()->addWidget(installedPluginList); + ui->modulesList->layout()->addWidget(errorPluginList); + ui->modulesList->layout()->addWidget(missingPluginList); + + installedPluginEntries.reserve(modules_.size() + failedModules.size()); for (auto &metadata : modules_) { - std::string id = metadata.module_name; + std::string_view module_name{metadata.module_name}; + // Check if the module is missing: - bool missing = !obs_get_module(id.c_str()) && !obs_get_disabled_module(id.c_str()); + obs_module_t *moduleData = obs_get_module(module_name.data()); + + Category category{Category::Installed}; + + bool isLoaded = moduleData != nullptr; + if (!isLoaded) { + category = Category::Missing; + moduleData = obs_get_disabled_module(module_name.data()); + } + + bool isDisabled = moduleData != nullptr; + if (isDisabled) { + // This module is disabled but check if it also failed to load. + auto failedModuleIterator = std::find(failedModules.begin(), failedModules.end(), module_name); + if (failedModuleIterator != failedModules.end()) { + // This module is in the plugin manager cache so it has loaded properly before but now failed. + // Remove entry from the failedModules list so we don't create a dummy entry for it. + category = Category::Error; + failedModules.erase(failedModuleIterator); + } else { + // Module is disabled but did not fail to load. + category = Category::Installed; + } + } + + bool isLegacyModule = obs_is_legacy_module(moduleData); QString name = !metadata.display_name.empty() ? metadata.display_name.c_str() : metadata.module_name.c_str(); + QString version = !metadata.version.empty() ? metadata.version.c_str() : ""; - if (missing && missingIndex == -1) { - missingIndex = row; + Entry newEntry{metadata, name, category, isLegacyModule}; + installedPluginEntries.push_back(newEntry); + } + + for (const std::string &moduleName : failedModules) { + // This failed module is not in the plugin manager cache which means it has never been loaded successfully. + // Create a dummy visual entry for it. + OBS::ModuleInfo dummyModule; + QString name = QString::fromStdString(moduleName.data()); + Category category{Category::Error}; + bool isLegacy{false}; + bool hasLoadedBefore{false}; + + dummyModule.module_name = moduleName; + dummyModule.enabled = false; + dummyModule.enabledAtLaunch = false; + + Entry newEntry{dummyModule, name, category, isLegacy, hasLoadedBefore}; + installedPluginEntries.push_back(newEntry); + } + + std::sort(installedPluginEntries.begin(), installedPluginEntries.end(), (const Entry &a, const Entry &b) { + if (a.category != b.category) { + return getCategorySortOrder(a.category) < getCategorySortOrder(b.category); } - auto item = new QCheckBox(name); - item->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - item->setChecked(metadata.enabled); + return a.name.toLower() < b.name.toLower(); + }); - if (!metadata.enabledAtLaunch || missing) { - item->setProperty("class", "text-muted"); + QWidget *previousRow{nullptr}; + for (Entry &entry : installedPluginEntries) { + if (isSafeMode) { + entry.category = Category::Installed; } + auto newRow = new InstalledPluginRow(ui->modulesList, entry); - ui->modulesList->layout()->addWidget(item); + if (!previousRow) { + setTabOrder(ui->modulesListContainer, newRow); + } else { + setTabOrder(previousRow, newRow); + } + + previousRow = newRow; + + if (entry.category == Category::Installed) { + installedPluginList->addRow(newRow); + } else if (entry.category == Category::Error) { + errorPluginList->addRow(newRow); + } else if (entry.category == Category::Missing) { + missingPluginList->addRow(newRow); + + connect(newRow, &InstalledPluginRow::trashClicked, this, this, entry() { + auto it = std::find_if(modules_.begin(), modules_.end(), + &entry(const ModuleInfo &module) { + return module.module_name == entry.module.module_name; + }); + + if (it != modules_.end()) { + modules_.erase(it); + } + }); + } + + connect(newRow, &InstalledPluginRow::toggleChanged, this, this, entry(bool enabled) { + auto it = std::find_if(modules_.begin(), modules_.end(), &entry(const ModuleInfo &module) { + return module.module_name == entry.module.module_name; + }); + + if (it != modules_.end()) { + it->enabled = enabled; + } - connect(item, &QCheckBox::toggled, this, this, row(bool checked) { - modules_row.enabled = checked; ui->manageRestartLabel->setVisible(isEnabledPluginsChanged()); }); - - row++; } - QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(ui->modulesList->layout()); - if (safe_mode) { - QLabel *safeModeLabel = new QLabel(ui->modulesList); - safeModeLabel->setText(QTStr("PluginManager.SafeMode")); - safeModeLabel->setProperty("class", "text-muted text-italic"); - safeModeLabel->setIndent(0); - - layout->insertWidget(0, safeModeLabel); - } else if (missingIndex != -1) { - QLabel *missingLabel = new QLabel(ui->modulesList); - missingLabel->setText(QTStr("PluginManager.MissingPlugin")); - missingLabel->setProperty("class", "text-warning text-bold"); - missingLabel->setIndent(0); + setTabOrder(previousRow, ui->buttonBox); - layout->insertWidget(missingIndex, new QLabel("", ui->modulesList)); - layout->insertWidget(missingIndex + 1, missingLabel); + if (installedPluginList->count() == 0) { + installedHeader->setDescription(QTStr("PluginManager.Section.Manage.NoPlugins")); } - ui->modulesList->adjustSize(); - ui->modulesListContents->adjustSize(); + if (errorPluginList->count() == 0) { + errorPluginList->setVisible(false); + } - ui->manageRestartLabel->setVisible(isEnabledPluginsChanged()); + if (missingPluginList->count() == 0) { + missingPluginList->setVisible(false); + } - connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + // Qt is weird about how styling from dynamic properties affects certain widgets such as scroll areas. + // This forces a recalculation after the items have all been added. + // TODO: https://github.com/obsproject/obs-studio/issues/13920 + // Rip this out after #13920 has been done. + { + ui->modulesList->style()->polish(ui->modulesList); + QEvent event(QEvent::StyleChange); + QApplication::sendEvent(ui->modulesList, &event); + } } void PluginManagerWindow::sectionSelectionChanged() { auto selected = ui->sectionList->selectedItems(); if (selected.count() != 1) { - setSection(activeSectionIndex); + setSection(activeSectionIndex.row()); } else { auto selectionIndex = ui->sectionList->indexFromItem(selected.first()); - setSection(selectionIndex); + setSection(selectionIndex.row()); } } -void PluginManagerWindow::setSection(QPersistentModelIndex index) +void PluginManagerWindow::setSection(int sidebarRow) { - if (ui->sectionList->itemFromIndex(index)) { - activeSectionIndex = index; - ui->sectionList->setCurrentIndex(index); + if (auto item = ui->sectionList->item(sidebarRow)) { + activeSectionIndex = ui->sectionList->indexFromItem(item); + ui->sectionList->setCurrentIndex(activeSectionIndex); + + ui->stackedContents->setCurrentIndex(sidebarRow); } } bool PluginManagerWindow::isEnabledPluginsChanged() { + if (obs_frontend_is_safe_mode_enabled()) { + return false; + } + bool result = false; - for (auto &metadata : modules_) { - if (metadata.enabledAtLaunch != metadata.enabled) { + for (auto &entry : installedPluginEntries) { + // Only prompt for restart when a loadable plugin entry changed. + if (entry.category == Category::Installed && entry.module.enabledAtLaunch != entry.module.enabled) { result = true; break; } @@ -175,4 +317,14 @@ return result; } +void PluginManagerWindow::setPage(Page page) +{ + switch (page) { + case Page::Installed: + setSection(1); + break; + default: + break; + } +} }; // namespace OBS
View file
obs-studio-32.2.2.tar.xz/frontend/plugin-manager/PluginManagerWindow.hpp -> obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginManagerWindow.hpp
Changed
@@ -17,12 +17,13 @@ #pragma once -#include "ui_PluginManagerWindow.h" #include "PluginManager.hpp" #include <QDialog> #include <QWidget> +#include "ui_PluginManagerWindow.h" + namespace OBS { class PluginManagerWindow : public QDialog { @@ -30,17 +31,35 @@ std::unique_ptr<Ui::PluginManagerWindow> ui; public: - explicit PluginManagerWindow(std::vector<ModuleInfo> const &modules, QWidget *parent = nullptr); - inline std::vector<ModuleInfo> const result() { return modules_; } + enum class Category { Invalid = 0, Installed, Error, Missing }; + + struct Entry { + OBS::ModuleInfo module; + QString name{}; + Category category{Category::Invalid}; + bool isLegacy{false}; + bool hasLoadedBefore{true}; + }; + + enum class Page { Installed }; + + explicit PluginManagerWindow(std::vector<ModuleInfo> const &modules, + std::vector<std::string> const &failedModules, QWidget *parent = nullptr); + + std::vector<ModuleInfo> const getModules() { return modules_; } + bool isEnabledPluginsChanged(); + + void setPage(Page page); private: std::vector<ModuleInfo> modules_; + std::vector<Entry> installedPluginEntries; + + void setupInstalledPage(std::vector<std::string> failedModules); void sectionSelectionChanged(); QPersistentModelIndex activeSectionIndex; - void setSection(QPersistentModelIndex index); - - bool isEnabledPluginsChanged(); + void setSection(int sidebarRow); }; }; // namespace OBS
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginModuleLoader.hpp
Added
@@ -0,0 +1,66 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <obs.h> + +#include <memory> +#include <string> +#include <string_view> +#include <vector> + +using FailureInfo = obs_module_failure_info; +using ModuleLoadInfo = obs_runtime_module_info; +using ModuleList = std::vector<std::string>; + +inline constexpr std::string_view kPathVariable{"OBS_PLUGINS_PATH"}; +inline constexpr std::string_view kLegacyBinaryPathVariable{"OBS_LEGACY_PLUGINS_PATH"}; +inline constexpr std::string_view kLegacyDataPathVariable{"OBS_LEGACY_PLUGINS_DATA_PATH"}; + +inline std::string getEnvironmentVariable(std::string_view variableName) +{ + std::unique_ptr<char> variablePointer{}; + variablePointer.reset(getenv(variableName.data())); + + if (!variablePointer) { + return {}; + } + + std::string result{variablePointer.release()}; + + return result; +} + +inline int loadPluginsByInfo(const ModuleLoadInfo &info, ModuleList &failedModules) +{ + FailureInfo result = {0}; + + obs_load_plugins(const_cast<ModuleLoadInfo *>(std::addressof(info)), std::addressof(result)); + + for (size_t i = 0; i < result.count; ++i) { + const char *failedPluginName = result.failed_modulesi; + + if (failedPluginName && *failedPluginName) { + failedModules.emplace_back(failedPluginName); + } + } + + obs_module_failure_info_free(std::addressof(result)); + + return static_cast<int>(result.count); +}
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginModuleLoader_BSD.cpp
Added
@@ -0,0 +1,220 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "PluginModuleLoader.hpp" +#include "PluginManager.hpp" +#include <LoaderPaths_BSD.hpp> + +#include <obs.h> +#include <util/dstr.h> +#include <util/platform.h> + +#include <array> +#include <string> +#include <string_view> +#include <vector> + +// BSD Third-Party Plugin Locations +// +// * User Path: <Environment Variable> +// * Binary: <Environment Variable>/<Plugin>/<Plugin>.so +// * Data: <Environment Variable>/<Plugin>/data +// +// * System Root Path: /usr +// * Binary: <System Root Path>/<System Library>/obs-modules/plugins/<Plugin>.so +// * Data: <System Root Path>/share/obs/obs-modules/plugins/<Plugin> +// +// * User Root Path: /home/<User>/.config +// * Binary: <User Root Path>/obs-studio/plugins/<Plugin>/<Plugin>.so +// * Data: <User Root Path>/obs-studio/plugins/<Plugin>/data +// +// * Legacy User Path: <Environment Variable> + <Environment Data Variable> +// * Binary: <Environment Variable>/<Plugin>.so +// * Data: <Environment Data Variable>/<Plugin> +// +// * Legacy System Root Path: /usr +// * Binary: <Legacy System Root Path>/<System Library>/obs-plugins/<Plugin>.so +// * Data: <Legacy System Root Path>/share/obs/obs-plugins/<Plugin> +// +// * Legacy User Root Path: /home/<User>/.config +// * Binary: <Legacy User Root Path>/obs-studio/plugins/<Plugin>/bin/64bit/<Plugin>.so +// * Data: <Legacy User Root Path>/obs-studio/plugins/<Plugin>/data +// +// * Legacy Fallback Path: <OBS Binary Location> +// * Binary: <Legacy Fallback Path>/../../obs-plugins/64bit/<Plugin>.so +// * Data: <Legacy System Root Path>/share/obs/obs-plugins/<Plugin> +// + +using State = OBS::PluginManager::State; +using ModuleType = obs_runtime_module_type; + +namespace Constants = OBS::Constants; + +constexpr std::string_view kModulePathSuffix{"/%module%/"}; +constexpr std::string_view kModuleDataPathSuffix{"/%module%/data/"}; +constexpr std::string_view kConfigBinaryPath{"/obs-studio/plugins/%module%/"}; +constexpr std::string_view kConfigDataPath{"/obs-studio/plugins/%module%/data/"}; + +constexpr std::string_view kLegacyConfigBinaryPath{"/obs-studio/plugins/%module%/bin/64bit"}; +constexpr std::string_view kLegacyConfigDataPath{"/obs-studio/plugins/%module%/data"}; + +constexpr bool hasSystemPluginPath = !Constants::kPlatformPluginModulePath.empty() && + !Constants::kPlatformPluginDataPath.empty(); + +namespace { +State pluginLoadHelper(const ModuleLoadInfo &info, ModuleList &failedModules) +{ + int failedModuleCount = loadPluginsByInfo(info, failedModules); + + State result = (failedModuleCount > 0) ? State::PartialFailure : State::Success; + + return result; +} +} // namespace + +namespace OBS { +State PluginManager::loadPlugins(bool usePortableMode) +{ + State userPluginState = State::Failure; + std::string userPluginPath = getEnvironmentVariable(kPathVariable); + + if (!userPluginPath.empty()) { + std::string binaryPath{userPluginPath}; + std::string dataPath{userPluginPath}; + binaryPath.append(kModulePathSuffix); + dataPath.append(kModuleDataPathSuffix); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_PLUGIN, + .name = nullptr}; + + userPluginState = pluginLoadHelper(info, failedModules_); + } else { + userPluginState = State::Success; + } + + State systemPluginState = State::Failure; + + if constexpr (hasSystemPluginPath) { + std::string binaryPath{Constants::kPlatformPluginModulePath}; + std::string dataPath{Constants::kPlatformPluginDataPath}; + + dataPath.append(kModulePathSuffix); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_PLUGIN, + .name = nullptr}; + + systemPluginState = pluginLoadHelper(info, failedModules_); + } else { + systemPluginState = State::Success; + } + + State configPluginState = State::Failure; + + if (!usePortableMode) { + std::string userConfigPath{}; + userConfigPath.resize(PATH_MAX); + int bufferSize = os_get_config_path(userConfigPath.data(), userConfigPath.size(), nullptr); + + if (bufferSize > 0) { + userConfigPath.resize(bufferSize); + std::string binaryPath{userConfigPath}; + std::string dataPath{userConfigPath}; + + binaryPath.append(kConfigBinaryPath); + dataPath.append(kConfigDataPath); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_PLUGIN, + .name = nullptr}; + configPluginState = pluginLoadHelper(info, failedModules_); + } + } else { + configPluginState = State::Success; + } + + return (userPluginState && systemPluginState && configPluginState) ? State::Success : State::PartialFailure; +} + +State PluginManager::loadLegacyPlugins(bool usePortableMode) +{ + State userPluginState = State::Failure; + + std::string userPluginPath = getEnvironmentVariable(kLegacyBinaryPathVariable); + std::string userDataPath = getEnvironmentVariable(kLegacyDataPathVariable); + + if (!userPluginPath.empty() && !userDataPath.empty()) { + std::string binaryPath{userPluginPath}; + std::string dataPath{userDataPath}; + + dataPath.append(kModulePathSuffix); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr}; + + userPluginState = pluginLoadHelper(info, failedModules_); + } else { + userPluginState = State::Success; + } + + State systemPluginState = State::Failure; + + { + std::string binaryPath{Constants::kPlatformInstallPath}; + std::string dataPath{Constants::kPlatformInstallPath}; + binaryPath.append(Constants::kPlatformLibraryPath); + binaryPath.append("obs-plugins/"); + dataPath.append(Constants::kPlatformDataPath); + dataPath.append("obs/obs-plugins/%module%"); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr}; + + systemPluginState = pluginLoadHelper(info, failedModules_); + } + + State configPluginState = State::Failure; + + if (!usePortableMode) { + std::string userConfigPath{}; + userConfigPath.resize(PATH_MAX); + int bufferSize = os_get_config_path(userConfigPath.data(), userConfigPath.size(), nullptr); + + if (bufferSize > 0) { + userConfigPath.resize(bufferSize); + std::string binaryPath{userConfigPath}; + std::string dataPath{userConfigPath}; + + binaryPath.append(kLegacyConfigBinaryPath); + dataPath.append(kLegacyConfigDataPath); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr}; + + configPluginState = pluginLoadHelper(info, failedModules_); + } else { + configPluginState = State::Success; + } + } + + return (userPluginState && systemPluginState && configPluginState) ? State::Success : State::PartialFailure; +} +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginModuleLoader_Flatpak.cpp
Added
@@ -0,0 +1,142 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "PluginModuleLoader.hpp" +#include "PluginManager.hpp" +#include <LoaderPaths_Flatpak.hpp> + +#include <obs.h> +#include <util/dstr.h> +#include <util/platform.h> + +#include <array> +#include <string> +#include <string_view> +#include <vector> + +// Flatpak Third-Party Plugin Locations +// +// * Flatpak Extension Point Path: /app/plugins +// * Binary: /app/plugins/<System Library Path>/obs-modules/plugins/<Plugin>.so +// * Data: /app/plugins/<System Data Path>/share/obs/obs-modules/plugins/<Plugin> +// +// * Legacy Flatpak Root Path: /app/plugins +// * Binary: <Legacy Flatpak Root Path>/<System Library Path>/obs-plugins/<Plugin>.so +// * Data: <Legacy Flatpak Root Path>/share/obs/obs-plugins/<Plugin> +// +// * XDG Data Home Path: +// * Binary: <XDG Data Home Path>/obs-studio/plugins/<Plugin>/<Plugin>.so +// * Data: <XDG Data Home Path>/obs-studio/plugins/<Plugin>/data +// +// * XDG Config Home Path: +// * Binary: <Legacy User Root Path>/obs-studio/plugins/<Plugin>/bin/64bit/<Plugin>.so +// * Data: <Legacy User Root Path>/obs-studio/plugins/<Plugin>/data + +using State = OBS::PluginManager::State; +using ModuleType = obs_runtime_module_type; + +namespace Constants = OBS::Constants; + +constexpr std::string_view kConfigBinaryPath{"/obs-studio/plugins/%module%/"}; +constexpr std::string_view kConfigDataPath{"/obs-studio/plugins/%module%/data/"}; +constexpr std::string_view kLegacyConfigBinaryPath{"/obs-studio/plugins/%module%/bin/64bit"}; +constexpr std::string_view kLegacyConfigDataPath{"/obs-studio/plugins/%module%/data"}; +constexpr std::string_view kFlatpakBasePath{"/app/plugins/"}; + +namespace { +State pluginLoadHelper(const ModuleLoadInfo &info, ModuleList &failedModules) +{ + int failedModuleCount = loadPluginsByInfo(info, failedModules); + + State result = (failedModuleCount > 0) ? State::PartialFailure : State::Success; + + return result; +} +} // namespace + +namespace OBS { +State PluginManager::loadPlugins(bool /*usePortableMode*/) +{ + State flatpakPluginState = State::Failure; + + { + std::string binaryPath{kFlatpakBasePath}; + std::string dataPath{kFlatpakBasePath}; + binaryPath.append(Constants::kPlatformLibraryPath); + binaryPath.append("obs-modules/plugins/"); + dataPath.append(Constants::kPlatformDataPath); + dataPath.append("obs-modules/plugins/%module%"); + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_PLUGIN, + .name = nullptr}; + + flatpakPluginState = pluginLoadHelper(info, failedModules_); + } + + State xdgDataHomeState = State::Failure; + std::string xdgDataHomePath = getEnvironmentVariable(Constants::kXDGDataHomeVariable); + if (!xdgDataHomePath.empty()) { + std::string binaryPath{xdgDataHomePath}; + std::string dataPath{xdgDataHomePath}; + binaryPath.append(kConfigBinaryPath); + dataPath.append(kConfigDataPath); + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_PLUGIN, + .name = nullptr}; + + xdgDataHomeState = pluginLoadHelper(info, failedModules_); + } else { + xdgDataHomeState = State::Success; + } + + return (flatpakPluginState && xdgDataHomeState) ? State::Success : State::PartialFailure; +} + +State PluginManager::loadLegacyPlugins(bool /*usePortableMode*/) +{ + State flatpakPluginState = State::Failure; + + { + std::string binaryPath{kFlatpakBasePath}; + std::string dataPath{kFlatpakBasePath}; + binaryPath.append(Constants::kPlatformLibraryPath); + binaryPath.append("obs-plugins/"); + dataPath.append(Constants::kPlatformDataPath); + dataPath.append("obs/obs-plugins/%module%"); + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr}; + + flatpakPluginState = pluginLoadHelper(info, failedModules_); + } + + State xdgDataConfigState = State::Failure; + std::string xdgConfigHomePath = getEnvironmentVariable(Constants::kXDGConfigHomeVariable); + if (!xdgConfigHomePath.empty()) { + std::string binaryPath{xdgConfigHomePath}; + std::string dataPath{xdgConfigHomePath}; + binaryPath.append(kLegacyConfigBinaryPath); + dataPath.append(kLegacyConfigDataPath); + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr}; + xdgDataConfigState = pluginLoadHelper(info, failedModules_); + } + + return (flatpakPluginState && xdgDataConfigState) ? State::Success : State::PartialFailure; +} +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginModuleLoader_Linux.cpp
Added
@@ -0,0 +1,224 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "PluginModuleLoader.hpp" +#include "PluginManager.hpp" +#include <LoaderPaths_Linux.hpp> + +#include <obs.h> +#include <util/dstr.h> +#include <util/platform.h> + +#include <array> +#include <string> +#include <string_view> +#include <vector> + +// Linux Third-Party Plugin Locations +// +// * User Path: <Environment Variable> +// * Binary: <Environment Variable>/<Plugin>/<Plugin>.so +// * Data: <Environment Variable>/<Plugin>/data +// +// * System Root Path: /usr +// * Binary: <System Root Path>/<System Library>/obs-modules/plugins/<Plugin>.so +// * Data: <System Root Path>/share/obs/obs-modules/plugins/<Plugin> +// +// * User Root Path: $XDG_DATA_HOME +// * Binary: <User Root Path>/obs-studio/plugins/<Plugin>/<Plugin>.so +// * Data: <User Root Path>/obs-studio/plugins/<Plugin>/data +// +// * Legacy User Path: <Environment Variable> + <Environment Data Variable> +// * Binary: <Environment Variable>/<Plugin>.so +// * Data: <Environment Data Variable>/<Plugin> +// +// * Legacy System Root Path: /usr +// * Binary: <Legacy System Root Path>/<System Library>/obs-plugins/<Plugin>.so +// * Data: <Legacy System Root Path>/share/obs/obs-plugins/<Plugin> +// +// * Legacy User Root Path: $XDG_CONFIG_HOME +// * Binary: <Legacy User Root Path>/obs-studio/plugins/<Plugin>/bin/64bit/<Plugin>.so +// * Data: <Legacy User Root Path>/obs-studio/plugins/<Plugin>/data +// +// * Legacy Fallback Path: <OBS Binary Location> +// * Binary: <Legacy Fallback Path>/../../obs-plugins/64bit/<Plugin>.so +// * Data: <Legacy System Root Path>/share/obs/obs-plugins/<Plugin> + +using State = OBS::PluginManager::State; +using ModuleType = obs_runtime_module_type; + +namespace Constants = OBS::Constants; + +constexpr std::string_view kModulePathSuffix{"/%module%/"}; +constexpr std::string_view kModuleDataPathSuffix{"/%module%/data/"}; +constexpr std::string_view kXdgBinaryPath{"/obs-studio/plugins/%module%/"}; +constexpr std::string_view kXdgDataPath{"/obs-studio/plugins/%module%/data/"}; + +constexpr std::string_view kLegacyXdgBinaryPath{"/obs-studio/plugins/%module%/bin/64bit"}; +constexpr std::string_view kLegacyXdgDataPath{"/obs-studio/plugins/%module%/data"}; + +constexpr bool hasSystemPluginPath = !Constants::kPlatformPluginModulePath.empty() && + !Constants::kPlatformPluginDataPath.empty(); + +namespace { +State pluginLoadHelper(const ModuleLoadInfo &info, ModuleList &failedModules) +{ + int failedModuleCount = loadPluginsByInfo(info, failedModules); + + State result = (failedModuleCount > 0) ? State::PartialFailure : State::Success; + + return result; +} +} // namespace + +namespace OBS { +State PluginManager::loadPlugins(bool usePortableMode) +{ + State userPluginState = State::Failure; + std::string userPluginPath = getEnvironmentVariable(kPathVariable); + + if (!userPluginPath.empty()) { + std::string binaryPath{userPluginPath}; + std::string dataPath{userPluginPath}; + binaryPath.append(kModulePathSuffix); + dataPath.append(kModuleDataPathSuffix); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_PLUGIN, + .name = nullptr}; + + userPluginState = pluginLoadHelper(info, failedModules_); + } else { + userPluginState = State::Success; + } + + State systemPluginState = State::Failure; + + if constexpr (hasSystemPluginPath) { + std::string binaryPath{Constants::kPlatformPluginModulePath}; + std::string dataPath{Constants::kPlatformPluginDataPath}; + + dataPath.append(kModulePathSuffix); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_PLUGIN, + .name = nullptr}; + + systemPluginState = pluginLoadHelper(info, failedModules_); + } else { + systemPluginState = State::Success; + } + + State xdgPluginState = State::Failure; + + if (!usePortableMode) { + std::string xdgDataHomePath = getEnvironmentVariable(Constants::kXDGDataHomeVariable); + if (xdgDataHomePath.empty()) { + std::string homePath = getEnvironmentVariable("HOME"); + if (!homePath.empty()) { + xdgDataHomePath = homePath + "/.local/share"; + } + } + if (!xdgDataHomePath.empty()) { + std::string binaryPath{xdgDataHomePath}; + std::string dataPath{xdgDataHomePath}; + binaryPath.append(kXdgBinaryPath); + dataPath.append(kXdgDataPath); + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_PLUGIN, + .name = nullptr}; + + xdgPluginState = pluginLoadHelper(info, failedModules_); + } else { + xdgPluginState = State::Success; + } + } else { + xdgPluginState = State::Success; + } + + return (userPluginState && systemPluginState && xdgPluginState) ? State::Success : State::PartialFailure; +} + +State PluginManager::loadLegacyPlugins(bool usePortableMode) +{ + State userPluginState = State::Failure; + + std::string userPluginPath = getEnvironmentVariable(kLegacyBinaryPathVariable); + std::string userDataPath = getEnvironmentVariable(kLegacyDataPathVariable); + + if (!userPluginPath.empty() && !userDataPath.empty()) { + std::string binaryPath{userPluginPath}; + std::string dataPath{userDataPath}; + + dataPath.append(kModulePathSuffix); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr}; + + userPluginState = pluginLoadHelper(info, failedModules_); + } else { + userPluginState = State::Success; + } + + State systemPluginState = State::Failure; + + { + std::string binaryPath{Constants::kPlatformInstallPath}; + std::string dataPath{Constants::kPlatformInstallPath}; + binaryPath.append(Constants::kPlatformLibraryPath); + binaryPath.append("obs-plugins/"); + dataPath.append(Constants::kPlatformDataPath); + dataPath.append("obs/obs-plugins/%module%"); + + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr}; + + systemPluginState = pluginLoadHelper(info, failedModules_); + } + + State xdgPluginState = State::Failure; + + if (!usePortableMode) { + std::string xdgConfigHomePath = getEnvironmentVariable(Constants::kXDGConfigHomeVariable); + if (xdgConfigHomePath.empty()) { + std::string homePath = getEnvironmentVariable("HOME"); + if (!homePath.empty()) { + xdgConfigHomePath = homePath + "/.config"; + } + } + if (!xdgConfigHomePath.empty()) { + std::string binaryPath{xdgConfigHomePath}; + std::string dataPath{xdgConfigHomePath}; + binaryPath.append(kLegacyXdgBinaryPath); + dataPath.append(kLegacyXdgDataPath); + ModuleLoadInfo info = {.path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr}; + + xdgPluginState = pluginLoadHelper(info, failedModules_); + } else { + xdgPluginState = State::Success; + } + } else { + xdgPluginState = State::Success; + } + + return (userPluginState && systemPluginState && xdgPluginState) ? State::Success : State::PartialFailure; +} +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginModuleLoader_MacOS.mm
Added
@@ -0,0 +1,196 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "PluginModuleLoader.hpp" +#include "PluginManager.hpp" + +#include <obs.h> +#include <util/dstr.h> +#include <util/platform.h> + +#include <string> +#include <string_view> +#include <vector> + +// macOS Third-Party Plugin Locations +// +// * User Path: <Environment Variable> +// * Binary: <Environment Variable>/<Plugin>.plugin/Contents/MacOS +// * Data: <Environment Variable>/<Plugin>.plugin/Contents/Resources +// +// * Root Path: <User>/Library/Application Support +// * Binary: <Root Path>/obs-studio/plugins/<Plugin>.plugin/Contents/MacOS/<Plugin> +// * Data: <Root Path>/obs-studio/plugins/<Plugin>.plugin/Contents/Resources +// +// * Legacy User Path: <Environment Variable> + <Data Environment Variable> +// * Binary: <Environment Variable>/<Plugin>.plugin/Contents/MacOS/<Plugin> +// * Data: <Data Environment Variable>/<Plugin>.plugin/Contents/Resources +// +// * Legacy System Root Path: /Library/Application Support +// * Legacy binary: <Legacy System Root Path>/obs-studio/plugins/<Plugin>/bin/<Plugin>.so +// * Legacy data: <Legacy System Root Path>/obs-studio/plugins/<Plugin>/data +// +// * Legacy User Root Path: <User>/Library/Application Support +// * Legacy binary: <Legacy User Root Path>/obs-studio/plugins/<Plugin>/bin/<Plugin>.so +// * Legacy data: <Legacy User Root Path>/obs-studio/plugins/<Plugin>/data +// + +using State = OBS::PluginManager::State; +using ModuleType = obs_runtime_module_type; + +constexpr std::string_view kPluginPathSuffix {"obs-studio/plugins/%module%.plugin"}; +constexpr std::string_view kUserPluginPathSuffix {"/%module%.plugin"}; +constexpr std::string_view kLegacyPluginPathSuffix {"obs-studio/plugins/%module%"}; + +#ifdef __aarch64__ +constexpr bool kIsAppleSilicon = true; +#else +constexpr bool kIsAppleSilicon = false; +#endif + +namespace { + State loadPluginsFromPath(const std::string &pathString, ModuleType type, ModuleList &failedModules) + { + std::string binaryPath {pathString}; + std::string dataPath {pathString}; + + switch (type) { + case OBS_MODULE_TYPE_LEGACY_PLUGIN: { + binaryPath.append("/bin"); + dataPath.append("/data"); + break; + } + default: { + binaryPath.append("/Contents/MacOS"); + dataPath.append("/Contents/Resources"); + break; + } + } + + ModuleLoadInfo info = { + .path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = type, + .name = nullptr + }; + + int failedModuleCount = loadPluginsByInfo(info, failedModules); + + State result = (failedModuleCount > 0) ? State::PartialFailure : State::Success; + + return result; + } + + State loadPluginsFromLegacyPaths(const std::string &binaryPathString, const std::string &dataPathString, + ModuleList &failedModules) + { + std::string binaryPath {binaryPathString}; + std::string dataPath {dataPathString}; + + binaryPath.append("/%module%.plugin/Contents/MacOS"); + dataPath.append("/%module%.plugin/Contents/Resources"); + + ModuleLoadInfo info = { + .path_info = {.binary = binaryPath.c_str(), .data = dataPath.c_str()}, + .type = OBS_MODULE_TYPE_LEGACY_PLUGIN, + .name = nullptr + }; + + int failedModuleCount = loadPluginsByInfo(info, failedModules); + + State result = (failedModuleCount > 0) ? State::PartialFailure : State::Success; + + return result; + } + +} // namespace + +namespace OBS { + State PluginManager::loadPlugins(bool usePortableMode __unused) + { + State userPluginState = State::Failure; + std::string userPluginPath = getEnvironmentVariable(kPathVariable); + + if (!userPluginPath.empty()) { + userPluginPath.append(kUserPluginPathSuffix); + + userPluginState = loadPluginsFromPath(userPluginPath, OBS_MODULE_TYPE_PLUGIN, failedModules_); + } else { + userPluginState = State::Success; + } + + State libraryPluginState = State::Failure; + + std::string appLibraryPath {}; + appLibraryPath.resize(PATH_MAX); + int bufferSize = os_get_config_path(appLibraryPath.data(), appLibraryPath.size(), kPluginPathSuffix.data()); + if (bufferSize > 0) { + appLibraryPath.resize(bufferSize); + + libraryPluginState = loadPluginsFromPath(appLibraryPath, OBS_MODULE_TYPE_PLUGIN, failedModules_); + } + + return (userPluginState && libraryPluginState) ? State::Success : State::PartialFailure; + } + + State PluginManager::loadLegacyPlugins(bool usePortableMode __unused) + { + State userPluginState = State::Failure; + + std::string userPluginPath = getEnvironmentVariable(kLegacyBinaryPathVariable); + std::string userDataPath = getEnvironmentVariable(kLegacyDataPathVariable); + + if (!userPluginPath.empty() && !userDataPath.empty()) { + userPluginState = loadPluginsFromLegacyPaths(userPluginPath, userDataPath, failedModules_); + } else { + userPluginState = State::Success; + } + + State legacyPluginState = State::Failure; + + if constexpr (!kIsAppleSilicon) { + State systemLibraryState = State::Failure; + + std::string systemLibraryPath {}; + systemLibraryPath.resize(PATH_MAX); + int bufferSize = os_get_program_data_path(systemLibraryPath.data(), systemLibraryPath.size(), + kLegacyPluginPathSuffix.data()); + + if (bufferSize > 0) { + systemLibraryPath.resize(bufferSize); + systemLibraryState = + loadPluginsFromPath(systemLibraryPath, OBS_MODULE_TYPE_LEGACY_PLUGIN, failedModules_); + } + + State appLibrayState = State::Failure; + std::string appLibraryPath {}; + appLibraryPath.resize(PATH_MAX); + bufferSize = + os_get_config_path(appLibraryPath.data(), appLibraryPath.size(), kLegacyPluginPathSuffix.data()); + + if (bufferSize > 0) { + appLibraryPath.resize(bufferSize); + appLibrayState = loadPluginsFromPath(appLibraryPath, OBS_MODULE_TYPE_LEGACY_PLUGIN, failedModules_); + } + + legacyPluginState = (systemLibraryState && appLibrayState) ? State::Success : State::PartialFailure; + } else { + legacyPluginState = State::Success; + } + + return (userPluginState && legacyPluginState) ? State::Success : State::PartialFailure; + } +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/frontend/plugin-manager/PluginModuleLoader_Windows.cpp
Added
@@ -0,0 +1,196 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "PluginModuleLoader.hpp" +#include "PluginManager.hpp" + +#include <obs.h> +#include <util/dstr.h> +#include <util/platform.h> + +#include <string> +#include <string_view> +#include <vector> + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#undef WIN32_LEAN_AND_MEAN + +// Windows Third-Party Plugin Locations +// +// * User Path: <Environment Variable> +// * Binary: <Environment Variable>/<Plugin>/<Plugin>.dll +// * Data: <Environment Variable>/<Plugin>/data +// +// * Root Path: C:/ProgramData +// * Binary: <Root Path>/obs-studio/plugins/<Plugin>/<Plugin>.dll +// * Data: <Root Path>/obs-studio/plugins/<Plugin>/data +// +// * Portable Root Path: <OBS Binary Location> +// * Binary: <Portable Root Path>/../../plugins/<Plugin>/<Plugin>.dll +// * Data: <Portable Root Path>/../../plugins/<Plugin>/data +// +// * Legacy User Path: <Environment Variable> + <Environment Data Variable> +// * Binary: <Environment Variable>/<Plugin>.dll +// * Data: <Environment Data Variable>/<Plugin>/data +// +// * Legacy Root Path: <OBS Binary Location> +// * Binary: <Legacy Root Path>/../../obs-plugins/<Plugin>.dll +// * Data: <Legacy Root Path>/../../data/obs-plugins/<Plugin> +// +// * Legacy Portable Path: <OBS Binary Location> +// * Binary: <Legacy Root Path>/../../obs-plugins/<Plugin>.dll +// * Data: <Legacy Root Path>/../../data/obs-plugins/<Plugin> +// +// * Legacy System Path: C:/ProgramData +// * Binary: <Legacy System Path>/obs-studio/plugins/<Plugin>/bin/<Plugin>.dll +// * Data: <Legacy System Path>/obs-studio/plugins/<Plugin>/data +// + +using State = OBS::PluginManager::State; +using ModuleType = obs_runtime_module_type; + +constexpr std::string_view kPluginPathSuffix{"obs-studio/plugins/%module%"}; +constexpr std::string_view kUserPluginPathSuffix{"/%module%"}; +constexpr std::string_view kPortablePluginPath{"../../plugins/%module%"}; + +constexpr std::string_view kLegacyPortableBinaryPath{"../../obs-plugins/64bit/"}; +constexpr std::string_view kLegacyPortableDataPath{"../../data/obs-plugins/%module%"}; + +namespace { +State loadPluginsFromPath(const std::string &pathString, ModuleType type, ModuleList &failedModules) +{ + std::string binaryPath{pathString}; + std::string dataPath{pathString}; + + switch (type) { + case OBS_MODULE_TYPE_LEGACY_PLUGIN: { + binaryPath.append("/bin/64bit"); + dataPath.append("/data"); + break; + } + default: { + dataPath.append("/data"); + break; + } + } + + ModuleLoadInfo info = {0}; + info.path_info.binary = binaryPath.c_str(); + info.path_info.data = dataPath.c_str(); + info.type = type; + info.name = nullptr; + + int failedModuleCount = loadPluginsByInfo(info, failedModules); + + State result = (failedModuleCount > 0) ? State::PartialFailure : State::Success; + + return result; +} +} // namespace + +namespace OBS { +State PluginManager::loadPlugins(bool usePortableMode) +{ + State userPluginState = State::Failure; + std::string userPluginPath = getEnvironmentVariable(kPathVariable); + + if (!userPluginPath.empty()) { + userPluginPath.append(kUserPluginPathSuffix); + + userPluginState = loadPluginsFromPath(userPluginPath, OBS_MODULE_TYPE_PLUGIN, failedModules_); + } else { + userPluginState = State::Success; + } + + State libraryPluginState = State::Failure; + std::string appLibraryPath{}; + + if (!usePortableMode) { + appLibraryPath.resize(MAX_PATH); + int bufferSize = os_get_program_data_path(appLibraryPath.data(), appLibraryPath.size(), + kPluginPathSuffix.data()); + if (bufferSize > 0) { + appLibraryPath.resize(bufferSize); + } + } else { + appLibraryPath = kPortablePluginPath; + } + + libraryPluginState = loadPluginsFromPath(appLibraryPath, OBS_MODULE_TYPE_PLUGIN, failedModules_); + + return (userPluginState && libraryPluginState) ? State::Success : State::PartialFailure; +} + +State PluginManager::loadLegacyPlugins(bool usePortableMode) +{ + State userPluginState = State::Failure; + + std::string userPluginPath = getEnvironmentVariable(kLegacyBinaryPathVariable); + std::string userDataPath = getEnvironmentVariable(kLegacyDataPathVariable); + + if (!userPluginPath.empty() && !userDataPath.empty()) { + userDataPath.append(kUserPluginPathSuffix); + + ModuleLoadInfo info = {0}; + info.path_info.binary = userPluginPath.c_str(); + info.path_info.data = userDataPath.c_str(); + info.type = OBS_MODULE_TYPE_LEGACY_PLUGIN; + info.name = nullptr; + + int failedModuleCount = loadPluginsByInfo(info, failedModules_); + + userPluginState = (failedModuleCount > 0) ? State::PartialFailure : State::Success; + } else { + userPluginState = State::Success; + } + + State portablePluginState = State::Failure; + + { + ModuleLoadInfo info = {0}; + info.path_info.binary = kLegacyPortableBinaryPath.data(); + info.path_info.data = kLegacyPortableDataPath.data(); + info.type = OBS_MODULE_TYPE_LEGACY_PLUGIN; + info.name = nullptr; + + int failedModuleCount = loadPluginsByInfo(info, failedModules_); + + portablePluginState = (failedModuleCount > 0) ? State::PartialFailure : State::Success; + } + + State libraryPluginState = State::Failure; + + if (!usePortableMode) { + std::string appLibraryPath{}; + appLibraryPath.resize(MAX_PATH); + int bufferSize = os_get_program_data_path(appLibraryPath.data(), appLibraryPath.size(), + kPluginPathSuffix.data()); + if (bufferSize > 0) { + appLibraryPath.resize(bufferSize); + libraryPluginState = + loadPluginsFromPath(appLibraryPath, OBS_MODULE_TYPE_LEGACY_PLUGIN, failedModules_); + } + } else { + libraryPluginState = State::Success; + } + + return (userPluginState && portablePluginState && libraryPluginState) ? State::Success : State::PartialFailure; +} +} // namespace OBS
View file
obs-studio-32.2.2.tar.xz/frontend/settings/OBSBasicSettings.cpp -> obs-studio-33.0.0.tar.xz/frontend/settings/OBSBasicSettings.cpp
Changed
@@ -723,7 +723,7 @@ return; } - QMetaObject::invokeMethod(settings, "ReloadAudioSources", Qt::QueuedConnection); + QMetaObject::invokeMethod(settings, &OBSBasicSettings::ReloadAudioSources, Qt::QueuedConnection); }; sourceCreated.Connect(obs_get_signal_handler(), "source_create", ReloadAudioSources, this); channelChanged.Connect(obs_get_signal_handler(), "channel_change", ReloadAudioSources, this); @@ -732,14 +732,14 @@ auto ReloadHotkeys = (void *data, calldata_t *) { auto settings = static_cast<OBSBasicSettings *>(data); - QMetaObject::invokeMethod(settings, "ReloadHotkeys"); + QMetaObject::invokeMethod(settings, &OBSBasicSettings::ReloadHotkeys, OBS_INVALID_HOTKEY_ID); }; hotkeyRegistered.Connect(obs_get_signal_handler(), "hotkey_register", ReloadHotkeys, this); auto ReloadHotkeysIgnore = (void *data, calldata_t *param) { auto settings = static_cast<OBSBasicSettings *>(data); auto key = static_cast<obs_hotkey_t *>(calldata_ptr(param, "key")); - QMetaObject::invokeMethod(settings, "ReloadHotkeys", Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key))); + QMetaObject::invokeMethod(settings, &OBSBasicSettings::ReloadHotkeys, obs_hotkey_get_id(key)); }; hotkeyUnregistered.Connect(obs_get_signal_handler(), "hotkey_unregister", ReloadHotkeysIgnore, this); @@ -776,11 +776,7 @@ connect(ui->simpleOutputABitrate, &QComboBox::currentIndexChanged, this, &OBSBasicSettings::SimpleReplayBufferChanged); connect(ui->simpleRBSecMax, &QSpinBox::valueChanged, this, &OBSBasicSettings::SimpleReplayBufferChanged); -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) connect(ui->advOutSplitFile, &QCheckBox::checkStateChanged, this, &OBSBasicSettings::AdvOutSplitFileChanged); -#else - connect(ui->advOutSplitFile, &QCheckBox::stateChanged, this, &OBSBasicSettings::AdvOutSplitFileChanged); -#endif connect(ui->advOutSplitFileType, &QComboBox::currentIndexChanged, this, &OBSBasicSettings::AdvOutSplitFileChanged); connect(ui->advReplayBuf, &QCheckBox::toggled, this, &OBSBasicSettings::AdvReplayBufferChanged); @@ -1298,13 +1294,8 @@ config_get_bool(App()->GetUserConfig(), "BasicWindow", "HideOBSWindowsFromCapture"); ui->hideOBSFromCapture->setChecked(hideWindowFromCapture); -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) connect(ui->hideOBSFromCapture, &QCheckBox::checkStateChanged, this, &OBSBasicSettings::HideOBSWindowWarning); -#else - connect(ui->hideOBSFromCapture, &QCheckBox::stateChanged, this, - &OBSBasicSettings::HideOBSWindowWarning); -#endif } #endif @@ -2442,29 +2433,33 @@ audioSourceSignals.emplace_back( handler, "push_to_mute_changed", (void *data, calldata_t *param) { - QMetaObject::invokeMethod(static_cast<QObject *>(data), "setCheckedSilently", - Q_ARG(bool, calldata_bool(param, "enabled"))); + auto checkBox = static_cast<SilentUpdateCheckBox *>(data); + bool enabled = calldata_bool(param, "enabled"); + QMetaObject::invokeMethod(checkBox, &SilentUpdateCheckBox::setCheckedSilently, enabled); }, ptmCB); audioSourceSignals.emplace_back( handler, "push_to_mute_delay", (void *data, calldata_t *param) { - QMetaObject::invokeMethod(static_cast<QObject *>(data), "setValueSilently", - Q_ARG(int, calldata_int(param, "delay"))); + auto spinBox = static_cast<SilentUpdateSpinBox *>(data); + auto delay = static_cast<int>(calldata_int(param, "delay")); + QMetaObject::invokeMethod(spinBox, &SilentUpdateSpinBox::setValueSilently, delay); }, ptmSB); audioSourceSignals.emplace_back( handler, "push_to_talk_changed", (void *data, calldata_t *param) { - QMetaObject::invokeMethod(static_cast<QObject *>(data), "setCheckedSilently", - Q_ARG(bool, calldata_bool(param, "enabled"))); + auto checkBox = static_cast<SilentUpdateCheckBox *>(data); + bool enabled = calldata_bool(param, "enabled"); + QMetaObject::invokeMethod(checkBox, &SilentUpdateCheckBox::setCheckedSilently, enabled); }, pttCB); audioSourceSignals.emplace_back( handler, "push_to_talk_delay", (void *data, calldata_t *param) { - QMetaObject::invokeMethod(static_cast<QObject *>(data), "setValueSilently", - Q_ARG(int, calldata_int(param, "delay"))); + auto spinBox = static_cast<SilentUpdateSpinBox *>(data); + auto delay = static_cast<int>(calldata_int(param, "delay")); + QMetaObject::invokeMethod(spinBox, &SilentUpdateSpinBox::setValueSilently, delay); }, pttSB); @@ -2475,9 +2470,9 @@ label->setMinimumSize(QSize(170, 0)); label->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter); connect(label, &OBSSourceLabel::removed, this, - this() { QMetaObject::invokeMethod(this, "ReloadAudioSources"); }); + this() { QMetaObject::invokeMethod(this, &OBSBasicSettings::ReloadAudioSources); }); connect(label, &OBSSourceLabel::destroyed, this, - this() { QMetaObject::invokeMethod(this, "ReloadAudioSources"); }); + this() { QMetaObject::invokeMethod(this, &OBSBasicSettings::ReloadAudioSources); }); layout->addRow(label, form); return true; @@ -3745,16 +3740,6 @@ const char *json = obs_data_get_json(data); config_set_string(config, "Hotkeys", hw.name.c_str(), json); } - - if (!main->outputHandler || !main->outputHandler->replayBuffer) { - return; - } - - const char *id = obs_obj_get_id(main->outputHandler->replayBuffer); - if (strcmp(id, "replay_buffer") == 0) { - OBSDataAutoRelease hotkeys = obs_hotkeys_save_output(main->outputHandler->replayBuffer); - config_set_string(config, "Hotkeys", "ReplayBuffer", obs_data_get_json(hotkeys)); - } } #define MINOR_SEPARATOR "------------------------------------------------" @@ -4392,11 +4377,7 @@ UpdateAudioWarnings(); } -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) void OBSBasicSettings::HideOBSWindowWarning(Qt::CheckState state) -#else -void OBSBasicSettings::HideOBSWindowWarning(int state) -#endif { if (loading || state == Qt::Unchecked) { return; @@ -4764,29 +4745,6 @@ } } -#if defined(__APPLE__) && QT_VERSION < QT_VERSION_CHECK(6, 5, 1) -// Workaround for QTBUG-56064 on macOS -static void ResetInvalidSelection(QComboBox *cbox) -{ - int idx = cbox->currentIndex(); - if (idx < 0) { - return; - } - - QStandardItemModel *model = dynamic_cast<QStandardItemModel *>(cbox->model()); - QStandardItem *item = model->item(idx); - - if (item->isEnabled()) { - return; - } - - // Reset to "invalid" state if item was disabled - cbox->blockSignals(true); - cbox->setCurrentIndex(-1); - cbox->blockSignals(false); -} -#endif - void OBSBasicSettings::AdvOutRecCheckWarnings() { auto Checked = (QCheckBox *box) { @@ -4830,12 +4788,6 @@ ui->autoRemux->setText(QTStr("Basic.Settings.Advanced.AutoRemux").arg("mp4")); } -#if defined(__APPLE__) && QT_VERSION < QT_VERSION_CHECK(6, 5, 1) - // Workaround for QTBUG-56064 on macOS - ResetInvalidSelection(ui->advOutRecEncoder); - ResetInvalidSelection(ui->advOutRecAEncoder); -#endif - // Show warning if codec selection was reset to an invalid state if (ui->advOutRecEncoder->currentIndex() == -1 || ui->advOutRecAEncoder->currentIndex() == -1) { if (!warningMsg.isEmpty()) { @@ -5572,8 +5524,8 @@ button = OBSMessageBox::question(this, QTStr(MULTI_CHANNEL_WARNING ".Title"), warningString); if (button == QMessageBox::No) { - QMetaObject::invokeMethod(ui->channelSetup, "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(int, lastChannelSetupIdx)); + QMetaObject::invokeMethod(ui->channelSetup, &QComboBox::setCurrentIndex, Qt::QueuedConnection, + lastChannelSetupIdx); return; } } @@ -5616,14 +5568,14 @@ auto button = OBSMessageBox::question(this, QTStr(LL_BUFFERING_WARNING ".Title"), warningStr); if (button == QMessageBox::No) { - QMetaObject::invokeMethod(ui->lowLatencyBuffering, "setChecked", Qt::QueuedConnection, - Q_ARG(bool, false)); + QMetaObject::invokeMethod(ui->lowLatencyBuffering, &QCheckBox::setChecked, Qt::QueuedConnection, + false); return; } } - QMetaObject::invokeMethod(this, "UpdateAudioWarnings", Qt::QueuedConnection); - QMetaObject::invokeMethod(this, "AudioChangedRestart"); + QMetaObject::invokeMethod(this, &OBSBasicSettings::UpdateAudioWarnings, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasicSettings::AudioChangedRestart); } void OBSBasicSettings::SimpleRecordingQualityLosslessWarning(int idx) @@ -5648,8 +5600,8 @@ button = OBSMessageBox::question(this, SIMPLE_OUTPUT_WARNING("Lossless.Title"), warningString); if (button == QMessageBox::No) { - QMetaObject::invokeMethod(ui->simpleOutRecQuality, "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(int, lastSimpleRecQualityIdx)); + QMetaObject::invokeMethod(ui->simpleOutRecQuality, &QComboBox::setCurrentIndex, + Qt::QueuedConnection, lastSimpleRecQualityIdx); return; } }
View file
obs-studio-32.2.2.tar.xz/frontend/settings/OBSBasicSettings.hpp -> obs-studio-33.0.0.tar.xz/frontend/settings/OBSBasicSettings.hpp
Changed
@@ -388,11 +388,7 @@ void GeneralChanged(); -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) void HideOBSWindowWarning(Qt::CheckState state); -#else - void HideOBSWindowWarning(int state); -#endif void AudioChanged(); void AudioChangedRestart(); void ReloadAudioSources();
View file
obs-studio-32.2.2.tar.xz/frontend/settings/OBSBasicSettings_Stream.cpp -> obs-studio-33.0.0.tar.xz/frontend/settings/OBSBasicSettings_Stream.cpp
Changed
@@ -241,7 +241,7 @@ loading = false; - QMetaObject::invokeMethod(this, "UpdateResFPSLimits", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasicSettings::UpdateResFPSLimits, Qt::QueuedConnection); } #define SRT_PROTOCOL "srt" @@ -1140,8 +1140,7 @@ #undef ENFORCE_WARNING if (button == QMessageBox::No) { - QMetaObject::invokeMethod(ui->ignoreRecommended, "setChecked", Qt::QueuedConnection, - Q_ARG(bool, false)); + QMetaObject::invokeMethod(ui->ignoreRecommended, &QCheckBox::setChecked, Qt::QueuedConnection, false); return; } @@ -1317,11 +1316,11 @@ if (button == QMessageBox::No) { if (idx != lastServiceIdx) { - QMetaObject::invokeMethod(ui->service, "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(int, lastServiceIdx)); + QMetaObject::invokeMethod(ui->service, &QComboBox::setCurrentIndex, + Qt::QueuedConnection, lastServiceIdx); } else { - QMetaObject::invokeMethod(ui->ignoreRecommended, "setChecked", Qt::QueuedConnection, - Q_ARG(bool, true)); + QMetaObject::invokeMethod(ui->ignoreRecommended, &QCheckBox::setChecked, + Qt::QueuedConnection, true); } return false; } @@ -1636,11 +1635,11 @@ if (button == QMessageBox::No) { if (lastServiceIdx == 0 && lastServiceIdx == ui->service->currentIndex()) { - QMetaObject::invokeMethod(ui->customServer, "setText", Qt::QueuedConnection, - Q_ARG(QString, lastCustomServer)); + QMetaObject::invokeMethod(ui->customServer, &QLineEdit::setText, Qt::QueuedConnection, + lastCustomServer); } else { - QMetaObject::invokeMethod(ui->service, "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(int, lastServiceIdx)); + QMetaObject::invokeMethod(ui->service, &QComboBox::setCurrentIndex, Qt::QueuedConnection, + lastServiceIdx); } return false; }
View file
obs-studio-32.2.2.tar.xz/frontend/settings/OBSHotkeyEdit.cpp -> obs-studio-33.0.0.tar.xz/frontend/settings/OBSHotkeyEdit.cpp
Changed
@@ -204,7 +204,7 @@ layoutChanged = {obs_get_signal_handler(), "hotkey_layout_change", (void *this_, calldata_t *) { auto edit = static_cast<OBSHotkeyEdit *>(this_); - QMetaObject::invokeMethod(edit, "ReloadKeyLayout"); + QMetaObject::invokeMethod(edit, &OBSHotkeyEdit::ReloadKeyLayout); }, this}; }
View file
obs-studio-32.2.2.tar.xz/frontend/settings/OBSHotkeyWidget.cpp -> obs-studio-33.0.0.tar.xz/frontend/settings/OBSHotkeyWidget.cpp
Changed
@@ -190,7 +190,7 @@ auto widget = static_cast<OBSHotkeyWidget *>(data); auto key = static_cast<obs_hotkey_t *>(calldata_ptr(param, "key")); - QMetaObject::invokeMethod(widget, "HandleChangedBindings", Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key))); + QMetaObject::invokeMethod(widget, &OBSHotkeyWidget::HandleChangedBindings, obs_hotkey_get_id(key)); } void OBSHotkeyWidget::HandleChangedBindings(obs_hotkey_id id_)
View file
obs-studio-32.2.2.tar.xz/frontend/updater/init-hook-files.c -> obs-studio-33.0.0.tar.xz/frontend/updater/init-hook-files.c
Changed
@@ -106,9 +106,11 @@ } while (false) #define IMPLICIT_LAYERS L"SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers" -#define HOOK_LOCATION L"\\data\\obs-plugins\\win-capture\\" -static bool update_hook_file(bool b64) +#define LEGACY_HOOK_LOCATION L"\\data\\obs-plugins\\win-capture\\" +#define CORE_HOOK_LOCATION L"\\core\\win-capture\\data\\" + +static bool update_hook_file(LPCWSTR location, bool b64) { wchar_t tempMAX_PATH; wchar_t srcMAX_PATH; @@ -117,11 +119,11 @@ wchar_t dst_jsonMAX_PATH; GetCurrentDirectoryW(_countof(src_json), src_json); - StringCbCat(src_json, sizeof(src_json), HOOK_LOCATION); + StringCbCat(src_json, sizeof(src_json), location); make_filename(src_json, L"obs-vulkan", L".json"); GetCurrentDirectoryW(_countof(src), src); - StringCbCat(src, sizeof(src), HOOK_LOCATION); + StringCbCat(src, sizeof(src), location); make_filename(src, L"graphics-hook", L".dll"); get_programdata_path(temp, L"obs-studio-hook\\"); @@ -184,10 +186,18 @@ RegCloseKey(key); } +void UpdateHookFilesLegacy(void) +{ + if (update_hook_file(LEGACY_HOOK_LOCATION, true)) + update_vulkan_registry(true); + if (update_hook_file(LEGACY_HOOK_LOCATION, false)) + update_vulkan_registry(false); +} + void UpdateHookFiles(void) { - if (update_hook_file(true)) + if (update_hook_file(CORE_HOOK_LOCATION, true)) update_vulkan_registry(true); - if (update_hook_file(false)) + if (update_hook_file(CORE_HOOK_LOCATION, false)) update_vulkan_registry(false); }
View file
obs-studio-32.2.2.tar.xz/frontend/updater/updater.cpp -> obs-studio-33.0.0.tar.xz/frontend/updater/updater.cpp
Changed
@@ -42,6 +42,7 @@ constexpr const wchar_t *kPatchManifestURL = L"https://obsproject.com/update_studio/getpatchmanifest"; constexpr const wchar_t *kVSRedistURL = L"https://aka.ms/vs/17/release/vc_redist.x64.exe"; constexpr const wchar_t *kMSHostname = L"aka.ms"; +constexpr const uint8_t kNewCorePluginsLocationVersionMajor = 33; /* ----------------------------------------------------------------------- */ @@ -740,8 +741,11 @@ static bool NonCorePackageInstalled(const char *name) { + // While this function is still called, the check for obs-browser is not hit as it has been part of core for a while. + // Keeping it around and updated for now in case either of these things change in the future. if (strcmp(name, "obs-browser") == 0) { - return FileExists(L"obs-plugins\\64bit\\obs-browser.dll"); + return FileExists(L"obs-plugins\\64bit\\obs-browser.dll") || + FileExists(L"core\\obs-browser\\obs-browser.dll"); } return false; @@ -1356,6 +1360,7 @@ } } +extern "C" void UpdateHookFilesLegacy(void); extern "C" void UpdateHookFiles(void); static bool Update(wchar_t *cmdLine) @@ -1744,7 +1749,12 @@ StringCbCat(regsvr, sizeof(regsvr), L"\\regsvr32.exe"); StringCbCopy(src, sizeof(src), obs_base_directory); - StringCbCat(src, sizeof(src), L"\\data\\obs-plugins\\win-dshow\\"); + + if (manifest.version_major >= kNewCorePluginsLocationVersionMajor) { + StringCbCat(src, sizeof(src), L"\\core\\win-dshow\\data\\"); + } else { + StringCbCat(src, sizeof(src), L"\\data\\obs-plugins\\win-dshow\\"); + } StringCbCopy(tmp, sizeof(tmp), L"\""); StringCbCat(tmp, sizeof(tmp), regsvr); @@ -1765,7 +1775,11 @@ * Update hook files and vulkan registry */ Status(L"Updating Game Capture hooks..."); - UpdateHookFiles(); + if (manifest.version_major >= kNewCorePluginsLocationVersionMajor) { + UpdateHookFiles(); + } else { + UpdateHookFilesLegacy(); + } /* ------------------------------------- * * Clear shader cache */
View file
obs-studio-32.2.2.tar.xz/frontend/utility/AdvancedOutput.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/AdvancedOutput.cpp
Changed
@@ -87,15 +87,7 @@ } else { bool useReplayBuffer = config_get_bool(main->Config(), "AdvOut", "RecRB"); if (useReplayBuffer) { - OBSDataAutoRelease hotkey; - const char *str = config_get_string(main->Config(), "Hotkeys", "ReplayBuffer"); - if (str) { - hotkey = obs_data_create_from_json(str); - } else { - hotkey = nullptr; - } - - replayBuffer = obs_output_create("replay_buffer", Str("ReplayBuffer"), nullptr, hotkey); + replayBuffer = obs_output_create("replay_buffer", Str("ReplayBuffer"), nullptr, nullptr); if (!replayBuffer) { throw "Failed to create replay buffer output "
View file
obs-studio-32.2.2.tar.xz/frontend/utility/AutoUpdateThread.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/AutoUpdateThread.cpp
Changed
@@ -6,6 +6,7 @@ #include <updater/manifest.hpp> #include <utility/WhatsNewInfoThread.hpp> #include <utility/update-helpers.hpp> +#include <widgets/OBSBasic.hpp> #include <qt-wrappers.hpp> @@ -138,8 +139,7 @@ void AutoUpdateThread::info(const QString &title, const QString &text) { - QMetaObject::invokeMethod(this, "infoMsg", Qt::BlockingQueuedConnection, Q_ARG(QString, title), - Q_ARG(QString, text)); + QMetaObject::invokeMethod(this, &AutoUpdateThread::infoMsg, Qt::BlockingQueuedConnection, title, text); } int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate, const QString &text) @@ -152,8 +152,8 @@ { int ret = OBSUpdate::No; QString text = text_utf8; - QMetaObject::invokeMethod(this, "queryUpdateSlot", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, ret), - Q_ARG(bool, localManualUpdate), Q_ARG(QString, text)); + QMetaObject::invokeMethod(this, &AutoUpdateThread::queryUpdateSlot, Qt::BlockingQueuedConnection, + qReturnArg(ret), localManualUpdate, text); return ret; } @@ -169,7 +169,8 @@ bool AutoUpdateThread::queryRepair() { bool ret = false; - QMetaObject::invokeMethod(this, "queryRepairSlot", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ret)); + QMetaObject::invokeMethod(this, &AutoUpdateThread::queryRepairSlot, Qt::BlockingQueuedConnection, + Q_RETURN_ARG(bool, ret)); return ret; } @@ -182,7 +183,10 @@ bool updatesAvailable = false; struct FinishedTrigger { - inline ~FinishedTrigger() { QMetaObject::invokeMethod(App()->GetMainWindow(), "updateCheckFinished"); } + inline ~FinishedTrigger() + { + QMetaObject::invokeMethod(OBSBasic::Get(), &OBSBasic::updateCheckFinished); + } } finishedTrigger; /* ----------------------------------- * @@ -344,7 +348,7 @@ config_set_int(App()->GetAppConfig(), "General", "LastUpdateCheck", 0); config_set_string(App()->GetAppConfig(), "General", "SkipUpdateVersion", "0"); - QMetaObject::invokeMethod(App()->GetMainWindow(), "close"); + QMetaObject::invokeMethod(OBSBasic::Get(), &OBSBasic::close); } catch (string &text) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
View file
obs-studio-32.2.2.tar.xz/frontend/utility/BasicOutputHandler.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/BasicOutputHandler.cpp
Changed
@@ -32,7 +32,7 @@ } output->delayActive = true; - QMetaObject::invokeMethod(output->main, "StreamDelayStarting", Q_ARG(int, sec)); + QMetaObject::invokeMethod(output->main, &OBSBasic::StreamDelayStarting, sec); } void OBSStreamStopping(void *data, calldata_t *params) @@ -42,9 +42,9 @@ int sec = (int)obs_output_get_active_delay(obj); if (sec == 0) { - QMetaObject::invokeMethod(output->main, "StreamStopping"); + QMetaObject::invokeMethod(output->main, &OBSBasic::StreamStopping); } else { - QMetaObject::invokeMethod(output->main, "StreamDelayStopping", Q_ARG(int, sec)); + QMetaObject::invokeMethod(output->main, &OBSBasic::StreamDelayStopping, sec); } } @@ -53,7 +53,7 @@ BasicOutputHandler *output = static_cast<BasicOutputHandler *>(data); output->streamingActive = true; os_atomic_set_bool(&streaming_active, true); - QMetaObject::invokeMethod(output->main, "StreamingStart"); + QMetaObject::invokeMethod(output->main, &OBSBasic::StreamingStart); } void OBSStopStreaming(void *data, calldata_t *params) @@ -68,7 +68,7 @@ output->delayActive = false; output->multitrackVideoActive = false; os_atomic_set_bool(&streaming_active, false); - QMetaObject::invokeMethod(output->main, "StreamingStop", Q_ARG(int, code), Q_ARG(QString, arg_last_error)); + QMetaObject::invokeMethod(output->main, &OBSBasic::StreamingStop, code, arg_last_error); } void OBSStartRecording(void *data, calldata_t * /* params */) @@ -77,7 +77,7 @@ output->recordingActive = true; os_atomic_set_bool(&recording_active, true); - QMetaObject::invokeMethod(output->main, "RecordingStart"); + QMetaObject::invokeMethod(output->main, &OBSBasic::RecordingStart); } void OBSStopRecording(void *data, calldata_t *params) @@ -91,13 +91,13 @@ output->recordingActive = false; os_atomic_set_bool(&recording_active, false); os_atomic_set_bool(&recording_paused, false); - QMetaObject::invokeMethod(output->main, "RecordingStop", Q_ARG(int, code), Q_ARG(QString, arg_last_error)); + QMetaObject::invokeMethod(output->main, &OBSBasic::RecordingStop, code, arg_last_error); } void OBSRecordStopping(void *data, calldata_t * /* params */) { BasicOutputHandler *output = static_cast<BasicOutputHandler *>(data); - QMetaObject::invokeMethod(output->main, "RecordStopping"); + QMetaObject::invokeMethod(output->main, &OBSBasic::RecordStopping); } void OBSRecordFileChanged(void *data, calldata_t *params) @@ -107,7 +107,7 @@ QString arg_last_file = QString::fromUtf8(output->lastRecordingPath.c_str()); - QMetaObject::invokeMethod(output->main, "RecordingFileChanged", Q_ARG(QString, arg_last_file)); + QMetaObject::invokeMethod(output->main, &OBSBasic::RecordingFileChanged, arg_last_file); output->lastRecordingPath = next_file; } @@ -118,7 +118,7 @@ output->replayBufferActive = true; os_atomic_set_bool(&replaybuf_active, true); - QMetaObject::invokeMethod(output->main, "ReplayBufferStart"); + QMetaObject::invokeMethod(output->main, &OBSBasic::ReplayBufferStart); } void OBSStopReplayBuffer(void *data, calldata_t *params) @@ -128,19 +128,19 @@ output->replayBufferActive = false; os_atomic_set_bool(&replaybuf_active, false); - QMetaObject::invokeMethod(output->main, "ReplayBufferStop", Q_ARG(int, code)); + QMetaObject::invokeMethod(output->main, &OBSBasic::ReplayBufferStop, code); } void OBSReplayBufferStopping(void *data, calldata_t * /* params */) { BasicOutputHandler *output = static_cast<BasicOutputHandler *>(data); - QMetaObject::invokeMethod(output->main, "ReplayBufferStopping"); + QMetaObject::invokeMethod(output->main, &OBSBasic::ReplayBufferStopping); } void OBSReplayBufferSaved(void *data, calldata_t * /* params */) { BasicOutputHandler *output = static_cast<BasicOutputHandler *>(data); - QMetaObject::invokeMethod(output->main, "ReplayBufferSaved", Qt::QueuedConnection); + QMetaObject::invokeMethod(output->main, &OBSBasic::ReplayBufferSaved, Qt::QueuedConnection); } static void OBSStartVirtualCam(void *data, calldata_t * /* params */) @@ -149,7 +149,7 @@ output->virtualCamActive = true; os_atomic_set_bool(&virtualcam_active, true); - QMetaObject::invokeMethod(output->main, "OnVirtualCamStart"); + QMetaObject::invokeMethod(output->main, &OBSBasic::OnVirtualCamStart); } static void OBSStopVirtualCam(void *data, calldata_t *params) @@ -159,7 +159,7 @@ output->virtualCamActive = false; os_atomic_set_bool(&virtualcam_active, false); - QMetaObject::invokeMethod(output->main, "OnVirtualCamStop", Q_ARG(int, code)); + QMetaObject::invokeMethod(output->main, &OBSBasic::OnVirtualCamStop, code); } static void OBSDeactivateVirtualCam(void *data, calldata_t * /* params */)
View file
obs-studio-32.2.2.tar.xz/frontend/utility/ExtraBrowsersModel.hpp -> obs-studio-33.0.0.tar.xz/frontend/utility/ExtraBrowsersModel.hpp
Changed
@@ -20,7 +20,7 @@ inline ExtraBrowsersModel(QObject *parent = nullptr) : QAbstractTableModel(parent) { Reset(); - QMetaObject::invokeMethod(this, "Init", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &ExtraBrowsersModel::Init, Qt::QueuedConnection); } int rowCount(const QModelIndex &parent = QModelIndex()) const override;
View file
obs-studio-32.2.2.tar.xz/frontend/utility/RemoteTextThread.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/RemoteTextThread.cpp
Changed
@@ -22,6 +22,8 @@ #include <qt-wrappers.hpp> #include <util/curl/curl-helper.h> +#include <iterator> + #include "moc_RemoteTextThread.cpp" using namespace std;
View file
obs-studio-32.2.2.tar.xz/frontend/utility/ScreenshotObj.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/ScreenshotObj.cpp
Changed
@@ -32,25 +32,15 @@ #include "moc_ScreenshotObj.cpp" -namespace { -void renderTick(void *param, float) -{ - ScreenshotObj *self = static_cast<ScreenshotObj *>(param); - if (self->stage() == ScreenshotObj::Stage::Finished) { - return; - } - - obs_enter_graphics(); - self->processStage(); - obs_leave_graphics(); -} -} // namespace - -ScreenshotObj::ScreenshotObj(obs_source_t *source) : weakSource(OBSGetWeakRef(source)) +ScreenshotObj::ScreenshotObj(obs_source_t *source, const Options &options) + : weakSource(OBSGetWeakRef(source)), + options(options) { obs_add_tick_callback(renderTick, this); } +ScreenshotObj::ScreenshotObj(obs_source_t *source) : ScreenshotObj(source, {}) {} + ScreenshotObj::~ScreenshotObj() { obs_enter_graphics(); @@ -61,6 +51,18 @@ obs_remove_tick_callback(renderTick, this); } +void ScreenshotObj::renderTick(void *param, float) +{ + ScreenshotObj *self = static_cast<ScreenshotObj *>(param); + if (self->stage() == ScreenshotObj::Stage::Finished) { + return; + } + + obs_enter_graphics(); + self->processStage(); + obs_leave_graphics(); +} + void ScreenshotObj::renderScreenshot() { OBSSourceAutoRelease source = OBSGetStrongRef(weakSource); @@ -94,8 +96,8 @@ #endif const enum gs_color_format format = gs_get_format_from_space(space); - outputWidth = customSize.isValid() ? customSize.width() : sourceWidth; - outputHeight = customSize.isValid() ? customSize.height() : sourceHeight; + outputWidth = options.size.isValid() ? options.size.width() : sourceWidth; + outputHeight = options.size.isValid() ? options.size.height() : sourceHeight; texrender = gs_texrender_create(format, GS_ZS_NONE); stagesurf = gs_stagesurface_create(outputWidth, outputHeight, format); @@ -198,7 +200,7 @@ void ScreenshotObj::saveToFile() { - if (!outputToFile) { + if (!options.outputToFile) { QMetaObject::invokeMethod(this, &ScreenshotObj::onFinished, Qt::QueuedConnection); return; } @@ -352,12 +354,8 @@ } if (outputWidth > 0 && outputHeight > 0) { - if (outputToFile) { - OBSBasic *main = OBSBasic::Get(); - main->ShowStatusBarMessage( - QTStr("Basic.StatusBar.ScreenshotSavedTo").arg(QT_UTF8(path.c_str()))); - main->lastScreenshot = path; - main->OnEvent(OBS_FRONTEND_EVENT_SCREENSHOT_TAKEN); + if (options.outputToFile) { + emit imageSaved(path); } emit imageReady(image.copy()); @@ -366,21 +364,6 @@ this->deleteLater(); } -void ScreenshotObj::setSize(QSize size) -{ - customSize = size; -} - -void ScreenshotObj::setSize(int width, int height) -{ - setSize(QSize(width, height)); -} - -void ScreenshotObj::setSaveToFile(bool save) -{ - outputToFile = save; -} - void ScreenshotObj::handleSave() { saveToFile();
View file
obs-studio-32.2.2.tar.xz/frontend/utility/ScreenshotObj.hpp -> obs-studio-33.0.0.tar.xz/frontend/utility/ScreenshotObj.hpp
Changed
@@ -29,12 +29,23 @@ Q_OBJECT public: + struct Options { + QSize size{}; + bool outputToFile{true}; + }; + + ScreenshotObj(obs_source_t *source, const Options &options); ScreenshotObj(obs_source_t *source); ~ScreenshotObj() override; enum class Stage { Render, Download, Output, Finished }; + Stage stage() { return stage_; } + +private: + static void renderTick(void *param, float seconds); void processStage(); + void renderScreenshot(); void downloadData(); void copyData(); @@ -42,33 +53,27 @@ void muxFile(); void onFinished(); - Stage stage() { return stage_; } - void setStage(Stage stage) { stage_ = stage; } - - void setSize(QSize size); - void setSize(int width, int height); - void setSaveToFile(bool save); + OBSWeakSource weakSource; -private: Stage stage_ = Stage::Render; + Options options; gs_texrender_t *texrender = nullptr; gs_stagesurf_t *stagesurf = nullptr; - OBSWeakSource weakSource; + std::string path; QImage image; std::vector<uint8_t> half_bytes; - QSize customSize; + uint32_t sourceWidth = 0; uint32_t sourceHeight = 0; uint32_t outputWidth = 0; uint32_t outputHeight = 0; std::thread thread; - std::shared_ptr<QImage> imagePtr; - bool outputToFile = true; signals: + void imageSaved(std::string path); void imageReady(QImage image); private slots:
View file
obs-studio-32.2.2.tar.xz/frontend/utility/SimpleOutput.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/SimpleOutput.cpp
Changed
@@ -223,15 +223,7 @@ const char *recFormat = config_get_string(main->Config(), "SimpleOutput", "RecFormat2"); if (useReplayBuffer) { - OBSDataAutoRelease hotkey; - const char *str = config_get_string(main->Config(), "Hotkeys", "ReplayBuffer"); - if (str) { - hotkey = obs_data_create_from_json(str); - } else { - hotkey = nullptr; - } - - replayBuffer = obs_output_create("replay_buffer", Str("ReplayBuffer"), nullptr, hotkey); + replayBuffer = obs_output_create("replay_buffer", Str("ReplayBuffer"), nullptr, nullptr); if (!replayBuffer) { throw "Failed to create replay buffer output " @@ -392,14 +384,25 @@ void SimpleOutput::UpdateRecordingAudioSettings() { OBSDataAutoRelease settings = obs_data_create(); - obs_data_set_int(settings, "bitrate", 192); obs_data_set_string(settings, "rate_control", "CBR"); + const char *audioEncoder = config_get_string(main->Config(), "SimpleOutput", "RecAudioEncoder"); int tracks = config_get_int(main->Config(), "SimpleOutput", "RecTracks"); const char *recFormat = config_get_string(main->Config(), "SimpleOutput", "RecFormat2"); const char *quality = config_get_string(main->Config(), "SimpleOutput", "RecQuality"); bool flv = strcmp(recFormat, "flv") == 0; + constexpr int kDefaultStereoBitrateKbps{192}; + constexpr int kStereoChannelCount{2}; + + int channels = (int)audio_output_get_channels(obs_get_audio()); + int channelScaledBitrate{kDefaultStereoBitrateKbps * channels / kStereoChannelCount}; + + int bitrate = strcmp(audioEncoder, "opus") == 0 ? FindClosestAvailableSimpleOpusBitrate(channelScaledBitrate) + : FindClosestAvailableSimpleAACBitrate(channelScaledBitrate); + + obs_data_set_int(settings, "bitrate", bitrate); + if (flv || strcmp(quality, "Stream") == 0) { obs_encoder_update(audioRecording, settings); } else {
View file
obs-studio-32.2.2.tar.xz/frontend/utility/ThumbnailItem.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/ThumbnailItem.cpp
Changed
@@ -185,9 +185,11 @@ return false; } - auto *obj = new ScreenshotObj(source); - obj->setSaveToFile(false); - obj->setSize(kDefaultWidth, kDefaultHeight); + ScreenshotObj::Options options; + options.outputToFile = false; + options.size = {kDefaultWidth, kDefaultHeight}; + + auto *obj = new ScreenshotObj(source, options); connect(obj, &ScreenshotObj::imageReady, this, &ThumbnailItem::updatePixmapFromImage); }
View file
obs-studio-32.2.2.tar.xz/frontend/utility/WhatsNewInfoThread.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/WhatsNewInfoThread.cpp
Changed
@@ -10,6 +10,7 @@ #include <blake2.h> #include <fstream> +#include <mutex> #include "moc_WhatsNewInfoThread.cpp"
View file
obs-studio-32.2.2.tar.xz/frontend/utility/item-widget-helpers.cpp -> obs-studio-33.0.0.tar.xz/frontend/utility/item-widget-helpers.cpp
Changed
@@ -40,11 +40,6 @@ void ClearListItems(QListWidget *widget) { -#if QT_VERSION < QT_VERSION_CHECK(6, 4, 3) - // Workaround for the SceneTree workaround for QTBUG-105870 - widget->setProperty("clearing", true); -#endif - widget->setCurrentItem(nullptr, QItemSelectionModel::Clear); for (int i = 0; i < widget->count(); i++) { @@ -52,8 +47,4 @@ } widget->clear(); -#if QT_VERSION < QT_VERSION_CHECK(6, 4, 3) - // Workaround for the SceneTree workaround for QTBUG-105870 - widget->setProperty("clearing", false); -#endif }
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/AudioMixer.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/AudioMixer.cpp
Changed
@@ -629,8 +629,9 @@ OBSSource source = OBSGetStrongRef(control->weakSource()); if (!source) { - const char *cachedName = control->getCachedName().toUtf8().constData(); - blog(LOG_INFO, "Tried to sort VolumeControl for '%s' but source is null", cachedName); + const QByteArray cachedName = control->getCachedName().toUtf8(); + blog(LOG_INFO, "Tried to sort VolumeControl for '%s' but source is null", + cachedName.constData()); continue; } @@ -1017,9 +1018,8 @@ if (flags & OBS_SOURCE_AUDIO) { auto mixer = static_cast<AudioMixer *>(data); auto uuidPointer = obs_source_get_uuid(source); - - QMetaObject::invokeMethod(mixer, "updateControlVisibility", Qt::QueuedConnection, - Q_ARG(QString, QString::fromUtf8(uuidPointer))); + QMetaObject::invokeMethod(mixer, &AudioMixer::updateControlVisibility, Qt::QueuedConnection, + QString::fromUtf8(uuidPointer)); } } @@ -1031,9 +1031,8 @@ if (flags & OBS_SOURCE_AUDIO) { auto mixer = static_cast<AudioMixer *>(data); auto uuidPointer = obs_source_get_uuid(source); - - QMetaObject::invokeMethod(mixer, "updateControlVisibility", Qt::QueuedConnection, - Q_ARG(QString, QString::fromUtf8(uuidPointer))); + QMetaObject::invokeMethod(mixer, &AudioMixer::updateControlVisibility, Qt::QueuedConnection, + QString::fromUtf8(uuidPointer)); } } @@ -1046,9 +1045,8 @@ if (flags & OBS_SOURCE_AUDIO && audioActive) { auto mixer = static_cast<AudioMixer *>(data); auto uuidPointer = obs_source_get_uuid(source); - - QMetaObject::invokeMethod(mixer, "addSource", Qt::QueuedConnection, - Q_ARG(QString, QString::fromUtf8(uuidPointer))); + QMetaObject::invokeMethod(mixer, &AudioMixer::addSource, Qt::QueuedConnection, + QString::fromUtf8(uuidPointer)); } } @@ -1060,9 +1058,8 @@ if (flags & OBS_SOURCE_AUDIO) { auto mixer = static_cast<AudioMixer *>(data); auto uuidPointer = obs_source_get_uuid(source); - - QMetaObject::invokeMethod(mixer, "updateControlVisibility", Qt::QueuedConnection, - Q_ARG(QString, QString::fromUtf8(uuidPointer))); + QMetaObject::invokeMethod(mixer, &AudioMixer::updateControlVisibility, Qt::QueuedConnection, + QString::fromUtf8(uuidPointer)); } } @@ -1075,9 +1072,8 @@ if (flags & OBS_SOURCE_AUDIO && audioActive) { auto mixer = static_cast<AudioMixer *>(data); auto uuidPointer = obs_source_get_uuid(source); - - QMetaObject::invokeMethod(mixer, "addSource", Qt::QueuedConnection, - Q_ARG(QString, QString::fromUtf8(uuidPointer))); + QMetaObject::invokeMethod(mixer, &AudioMixer::addSource, Qt::QueuedConnection, + QString::fromUtf8(uuidPointer)); } } @@ -1089,9 +1085,8 @@ if (flags & OBS_SOURCE_AUDIO) { auto mixer = static_cast<AudioMixer *>(data); auto uuidPointer = obs_source_get_uuid(source); - - QMetaObject::invokeMethod(mixer, "removeSource", Qt::QueuedConnection, - Q_ARG(QString, QString::fromUtf8(uuidPointer))); + QMetaObject::invokeMethod(mixer, &AudioMixer::removeSource, Qt::QueuedConnection, + QString::fromUtf8(uuidPointer)); } } @@ -1099,7 +1094,7 @@ { auto mixer = static_cast<AudioMixer *>(data); - QMetaObject::invokeMethod(mixer, "queueLayoutUpdate", Qt::QueuedConnection); + QMetaObject::invokeMethod(mixer, &AudioMixer::queueLayoutUpdate, Qt::QueuedConnection); } void AudioMixer::obsSceneItemVisibleChange(void *data, calldata_t *params) @@ -1117,11 +1112,12 @@ uint32_t flags = obs_source_get_output_flags(source); if (flags & OBS_SOURCE_AUDIO) { - QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "updatePreviewSources", - Qt::QueuedConnection); + auto mixer = static_cast<AudioMixer *>(data); + + QMetaObject::invokeMethod(mixer, &AudioMixer::updatePreviewSources, Qt::QueuedConnection); auto uuidPointer = obs_source_get_uuid(source); - QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "updateControlVisibility", - Qt::QueuedConnection, Q_ARG(QString, QString::fromUtf8(uuidPointer))); + QMetaObject::invokeMethod(mixer, &AudioMixer::updateControlVisibility, Qt::QueuedConnection, + QString::fromUtf8(uuidPointer)); } }
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic.cpp
Changed
@@ -41,6 +41,7 @@ #include <settings/OBSBasicSettings.hpp> #include <utility/QuickTransition.hpp> #include <utility/SceneRenameDelegate.hpp> +#include <utility/ScreenshotObj.hpp> #if defined(_WIN32) || defined(WHATSNEW_ENABLED) #include <utility/WhatsNewInfoThread.hpp> #endif @@ -61,11 +62,8 @@ #include <QWidgetAction> #include <mutex> -#ifdef _WIN32 #include <sstream> -#endif #include <string> -#include <unordered_set> #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -112,121 +110,6 @@ std::once_flag saveOnceFlag; } -static void AddExtraModulePaths() -{ - string plugins_path, plugins_data_path; - char *s; - - s = getenv("OBS_PLUGINS_PATH"); - if (s) { - plugins_path = s; - } - - s = getenv("OBS_PLUGINS_DATA_PATH"); - if (s) { - plugins_data_path = s; - } - - if (!plugins_path.empty() && !plugins_data_path.empty()) { -#if defined(__APPLE__) - plugins_path += "/%module%.plugin/Contents/MacOS"; - plugins_data_path += "/%module%.plugin/Contents/Resources"; - obs_add_module_path(plugins_path.c_str(), plugins_data_path.c_str()); -#else - string data_path_with_module_suffix; - data_path_with_module_suffix += plugins_data_path; - data_path_with_module_suffix += "/%module%"; - obs_add_module_path(plugins_path.c_str(), data_path_with_module_suffix.c_str()); -#endif - } - - if (portable_mode) { - return; - } - - char base_module_dir512; -#if defined(_WIN32) - int ret = GetProgramDataPath(base_module_dir, sizeof(base_module_dir), "obs-studio/plugins/%module%"); -#elif defined(__APPLE__) - int ret = GetAppConfigPath(base_module_dir, sizeof(base_module_dir), "obs-studio/plugins/%module%.plugin"); -#else - int ret = GetAppConfigPath(base_module_dir, sizeof(base_module_dir), "obs-studio/plugins/%module%"); -#endif - - if (ret <= 0) { - return; - } - - string path = base_module_dir; -#if defined(__APPLE__) - /* User Application Support Search Path */ - obs_add_module_path((path + "/Contents/MacOS").c_str(), (path + "/Contents/Resources").c_str()); - -#ifndef __aarch64__ - /* Legacy System Library Search Path */ - char system_legacy_module_dirPATH_MAX; - GetProgramDataPath(system_legacy_module_dir, sizeof(system_legacy_module_dir), "obs-studio/plugins/%module%"); - std::string path_system_legacy = system_legacy_module_dir; - obs_add_module_path((path_system_legacy + "/bin").c_str(), (path_system_legacy + "/data").c_str()); - - /* Legacy User Application Support Search Path */ - char user_legacy_module_dirPATH_MAX; - GetAppConfigPath(user_legacy_module_dir, sizeof(user_legacy_module_dir), "obs-studio/plugins/%module%"); - std::string path_user_legacy = user_legacy_module_dir; - obs_add_module_path((path_user_legacy + "/bin").c_str(), (path_user_legacy + "/data").c_str()); -#endif -#else -#if ARCH_BITS == 64 - obs_add_module_path((path + "/bin/64bit").c_str(), (path + "/data").c_str()); -#else - obs_add_module_path((path + "/bin/32bit").c_str(), (path + "/data").c_str()); -#endif -#endif -} - -/* First-party modules considered to be potentially unsafe to load in Safe Mode - * due to them allowing external code (e.g. scripts) to modify OBS's state. */ -static const unordered_set<string> unsafe_modules = { - "frontend-tools", // Scripting - "obs-websocket", // Allows outside modifications -}; - -static void SetSafeModuleNames() -{ -#ifndef SAFE_MODULES - return; -#else - string module; - stringstream modules_(SAFE_MODULES); - - while (getline(modules_, module, '|')) { - /* When only disallowing third-party plugins, still add - * "unsafe" bundled modules to the safe list. */ - if (disable_3p_plugins || !unsafe_modules.count(module)) { - obs_add_safe_module(module.c_str()); - } - } -#endif -} - -static void SetCoreModuleNames() -{ -#ifndef SAFE_MODULES - throw "SAFE_MODULES not defined"; -#else - std::string safeModules = SAFE_MODULES; - if (safeModules.empty()) { - throw "SAFE_MODULES is empty"; - } - string module; - stringstream modules_(SAFE_MODULES); - - while (getline(modules_, module, '|')) { - obs_add_core_module(module.c_str()); - } -#endif -} - extern void setupDockAction(QDockWidget *dock); OBSBasic::OBSBasic(QWidget *parent) : OBSMainWindow(parent), undo_s(ui), ui(new Ui::OBSBasic) @@ -937,14 +820,14 @@ signalHandlers.emplace_back( obs_get_signal_handler(), "source_filter_add", (void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "UpdateEditMenu", + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::UpdateEditMenu, Qt::QueuedConnection); }, this); signalHandlers.emplace_back( obs_get_signal_handler(), "source_filter_remove", (void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "UpdateEditMenu", + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::UpdateEditMenu, Qt::QueuedConnection); }, this); @@ -1035,27 +918,15 @@ #if defined(_WIN32) && !defined(_DEBUG) LoadLibraryW(L"Qt6Network"); #endif - struct obs_module_failure_info mfi; - - // Safe Mode disables third-party plugins so we don't need to add each path outside the OBS bundle/installation. - if (safe_mode || disable_3p_plugins) { - SetSafeModuleNames(); - } else { - AddExtraModulePaths(); - } - - // Core modules are not allowed to be disabled by the user via plugin manager. - SetCoreModuleNames(); - - /* Modules can access frontend information (i.e. profile and scene collection data) during their initialization, and some modules (e.g. obs-websockets) are known to use the filesystem location of the current profile in their own code. - - Thus the profile and scene collection discovery needs to happen before any access to that information (but after initializing global settings) to ensure legacy code gets valid path information. - */ + // Modules can access frontend information (i.e., profile and scene collection data) during their initialization, + // and some modules (e.g., obs-websockets) are known to use the filesystem location of the current profile in their + // own code. + // + // Thus, the profile and scene collection discovery needs to happen before any access to that information happens, + // but after initializing global settings, to ensure legacy code gets valid path information. RefreshSceneCollections(true); - App()->loadAppModules(mfi); - - BPtr<char *> failed_modules = mfi.failed_modules; + App()->loadAppModules(); #ifdef BROWSER_AVAILABLE cef = obs_browser_init_panel(); @@ -1149,10 +1020,9 @@ previewEnabled = config_get_bool(App()->GetUserConfig(), "BasicWindow", "PreviewEnabled"); if (!previewEnabled && !IsPreviewProgramMode()) { - QMetaObject::invokeMethod(this, "EnablePreviewDisplay", Qt::QueuedConnection, - Q_ARG(bool, previewEnabled)); + QMetaObject::invokeMethod(this, &OBSBasic::EnablePreviewDisplay, Qt::QueuedConnection, previewEnabled); } else if (!previewEnabled && IsPreviewProgramMode()) { - QMetaObject::invokeMethod(this, "EnablePreviewDisplay", Qt::QueuedConnection, Q_ARG(bool, true)); + QMetaObject::invokeMethod(this, &OBSBasic::EnablePreviewDisplay, Qt::QueuedConnection, true); } disableSaving--; @@ -1293,7 +1163,7 @@ } if (!first_run && !has_last_version && !Active()) { - QMetaObject::invokeMethod(this, "on_autoConfigure_triggered", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::on_autoConfigure_triggered, Qt::QueuedConnection); } #if (defined(_WIN32) || defined(__APPLE__)) && (OBS_RELEASE_CANDIDATE > 0 || OBS_BETA > 0) @@ -1374,22 +1244,7 @@ activateWindow(); } - /* ------------------------------------------- */ - /* display warning message for failed modules */ - - if (mfi.count) { - QString failed_plugins; - - char **plugin = mfi.failed_modules; - while (*plugin) { - failed_plugins += *plugin; - failed_plugins += "\n"; - plugin++; - } - - QString failed_msg = QTStr("PluginsFailedToLoad.Text").arg(failed_plugins); - OBSMessageBox::warning(this, QTStr("PluginsFailedToLoad.Title"), failed_msg); - } + App()->handlePluginLoadState(); } void OBSBasic::OnFirstLoad() @@ -2052,9 +1907,9 @@ emit mainWindowClosed(); - QMetaObject::invokeMethod(App(), "quit", Qt::QueuedConnection); + QMetaObject::invokeMethod(App(), &OBSApp::quit, Qt::QueuedConnection); #else - QMetaObject::invokeMethod(App(), "quit", Qt::QueuedConnection); + QMetaObject::invokeMethod(App(), &OBSApp::quit, Qt::QueuedConnection); #endif }
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic.hpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic.hpp
Changed
@@ -40,6 +40,7 @@ #include <util/util.hpp> #include <QAccessible> +#include <QPointer> #include <QSystemTrayIcon> #include <deque> @@ -57,6 +58,7 @@ class OBSLogViewer; class OBSMissingFiles; class OBSProjector; +class ScreenshotObj; class VolumeControl; #ifdef YOUTUBE_ENABLED class YouTubeAppDock; @@ -215,7 +217,6 @@ friend class OBSYoutubeActions; friend struct BasicOutputHandler; friend struct OBSStudioAPI; - friend class ScreenshotObj; enum class MoveDir { Up, Down, Left, Right }; @@ -423,6 +424,7 @@ void SourceToolBarActionsSetEnabled(); void copyActionsDynamicProperties(); + std::optional<QWidget *> createContextBarWidget(obs_source_t *source); private slots: void on_toggleContextBar_toggled(bool visible); @@ -494,7 +496,7 @@ obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, pauseHotkeys, replayBufHotkeys, vcamHotkeys, togglePreviewHotkeys, contextBarHotkeys; - obs_hotkey_id forceStreamingStopHotkey, splitFileHotkey, addChapterHotkey; + obs_hotkey_id forceStreamingStopHotkey, splitFileHotkey, addChapterHotkey, saveReplayBufferHotkey; void InitHotkeys(); void CreateHotkeys(); @@ -595,6 +597,10 @@ QPointer<QWidgetAction> colorWidgetAction; QPointer<ColorSelect> colorSelect; +#ifdef ENABLE_IDIAN_PLAYGROUND + QPointer<QDialog> playground; +#endif + QList<QDialog *> visDialogs; QList<QDialog *> modalDialogs; QList<QMessageBox *> visMsgBoxes; @@ -654,9 +660,8 @@ void logUploadFinished(const std::string &text, const std::string &error, OBS::LogFileType uploadType); - void updateCheckFinished(); - public slots: + void updateCheckFinished(); void on_actionAdvAudioProperties_triggered(); public: @@ -873,6 +878,7 @@ void TogglePreview(); public: + void addSnapGuide(SnapGuide guide); inline void GetDisplayRect(int &x, int &y, int &cx, int &cy) { x = previewX; @@ -917,6 +923,7 @@ std::vector<std::string> GetRestartRequirements(const ConfigFile &config) const; void ResetProfileData(); void CheckForSimpleModeX264Fallback(); + void CheckForMissingEncoders(); public: inline const OBSProfileCache &GetProfileCache() const noexcept { return profiles; }; @@ -1331,7 +1338,7 @@ * ------------------------------------- */ private: - QPointer<QObject> screenshotData; + QPointer<ScreenshotObj> screenshotData; std::string lastScreenshot; private slots: @@ -1499,8 +1506,8 @@ std::unordered_map<std::string, std::string> transitionNameToUuids; int transitionDuration; std::string currentTransitionUuid; - obs_source_t *fadeTransition; - obs_source_t *cutTransition; + obs_source_t *fadeTransition = nullptr; + obs_source_t *cutTransition = nullptr; std::vector<QuickTransition> quickTransitions; bool swapScenesMode = true;
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasicPreview.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasicPreview.cpp
Changed
@@ -9,6 +9,19 @@ #define HANDLE_SEL_RADIUS (HANDLE_RADIUS * 1.5f) #define HELPER_ROT_BREAKPOINT 45.0f +namespace { +bool tryEdgeSnapForOffset(float moveAxis, float checkAxis, float clampDistance, float &offset) +{ + double dist = fabsf(checkAxis - moveAxis); + if (dist < clampDistance && fabsf(offset) < EPSILON) { + offset = checkAxis - moveAxis; + return true; + } + + return false; +} +} // namespace + /* TODO: make C++ math classes and clean up code here later */ OBSBasicPreview::OBSBasicPreview(QWidget *parent, Qt::WindowFlags flags) : OBSQTDisplay(parent, flags) @@ -130,6 +143,9 @@ if (obs_sceneitem_locked(item)) { return true; } + if (!obs_sceneitem_visible(item)) { + return true; + } vec3_set(&pos3, data->pos.x, data->pos.y, 0.0f); @@ -177,6 +193,11 @@ return size; } +void OBSBasicPreview::addSnapGuide(SnapGuide guide) +{ + snapGuides.push_back(guide); +} + vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br) { OBSBasic *main = OBSBasic::Get(); @@ -198,32 +219,62 @@ const float centerX = br.x - (br.x - tl.x) / 2.0f; const float centerY = br.y - (br.y - tl.y) / 2.0f; - // Left screen edge. - if (screenSnap && fabsf(tl.x) < clampDist) { - clampOffset.x = -tl.x; - } - // Right screen edge. - if (screenSnap && fabsf(clampOffset.x) < EPSILON && fabsf(screenSize.x - br.x) < clampDist) { - clampOffset.x = screenSize.x - br.x; - } - // Horizontal center. - if (centerSnap && fabsf(screenSize.x - (br.x - tl.x)) > clampDist && - fabsf(screenSize.x / 2.0f - centerX) < clampDist) { - clampOffset.x = screenSize.x / 2.0f - centerX; - } + if (screenSnap) { + // Left screen edge. + if (tryEdgeSnapForOffset(tl.x, 0, clampDist, clampOffset.x)) { + vec2 startPoint{0, 0}; + vec2 endPoint{0, screenSize.y}; + SnapGuide guide{startPoint, endPoint}; + main->addSnapGuide(guide); + } - // Top screen edge. - if (screenSnap && fabsf(tl.y) < clampDist) { - clampOffset.y = -tl.y; - } - // Bottom screen edge. - if (screenSnap && fabsf(clampOffset.y) < EPSILON && fabsf(screenSize.y - br.y) < clampDist) { - clampOffset.y = screenSize.y - br.y; + // Right screen edge. + if (tryEdgeSnapForOffset(br.x, screenSize.x, clampDist, clampOffset.x)) { + vec2 startPoint{screenSize.x, 0}; + vec2 endPoint{screenSize.x, screenSize.y}; + SnapGuide guide{startPoint, endPoint}; + main->addSnapGuide(guide); + } + + // Top screen edge. + if (tryEdgeSnapForOffset(tl.y, 0, clampDist, clampOffset.y)) { + vec2 startPoint{0, 0}; + vec2 endPoint{screenSize.x, 0}; + SnapGuide guide{startPoint, endPoint}; + main->addSnapGuide(guide); + } + + // Bottom screen edge. + if (tryEdgeSnapForOffset(br.y, screenSize.y, clampDist, clampOffset.y)) { + vec2 startPoint{0, screenSize.y}; + vec2 endPoint{screenSize.x, screenSize.y}; + SnapGuide guide{startPoint, endPoint}; + main->addSnapGuide(guide); + } } - // Vertical center. - if (centerSnap && fabsf(screenSize.y - (br.y - tl.y)) > clampDist && - fabsf(screenSize.y / 2.0f - centerY) < clampDist) { - clampOffset.y = screenSize.y / 2.0f - centerY; + + if (centerSnap) { + // Horizontal center. + if (fabsf(screenSize.x - (br.x - tl.x)) > clampDist && + fabsf(screenSize.x / 2.0f - centerX) < clampDist) { + clampOffset.x = screenSize.x / 2.0f - centerX; + + vec2 startPoint{screenSize.x / 2.0f, 0}; + vec2 endPoint{screenSize.x / 2.0f, screenSize.y}; + SnapGuide guide{startPoint, endPoint}; + main->addSnapGuide(guide); + } + + // Vertical center. + if (fabsf(screenSize.y - (br.y - tl.y)) > clampDist && + fabsf(screenSize.y / 2.0f - centerY) < clampDist) { + clampOffset.y = screenSize.y / 2.0f - centerY; + + vec2 startPoint{0, screenSize.y / 2.0f}; + vec2 endPoint{screenSize.x, screenSize.y / 2.0f}; + SnapGuide guide{startPoint, endPoint}; + main->addSnapGuide(guide); + } } return clampOffset; @@ -754,6 +805,7 @@ return; } + OBSBasic *main = OBSBasic::Get(); if (mouseDown) { vec2 pos = GetMouseEventPos(event); @@ -807,8 +859,9 @@ hoveredPreviewItems.clear(); hoveredPreviewItems.push_back(item); selectedItems.clear(); + snapGuides.clear(); } - OBSBasic *main = OBSBasic::Get(); + OBSDataAutoRelease rwrapper = obs_scene_save_transform_states(main->GetCurrentScene(), true); auto undo_redo = (const std::string &data) { @@ -893,15 +946,32 @@ struct OffsetData { float clampDist; vec3 tl, br, offset; + + float left() { return tl.x; } + float top() { return tl.y; } + float right() { return br.x; } + float bottom() { return br.y; } + + vec2 center() + { + const float centerX = right() - (right() - left()) / 2.0f; + const float centerY = bottom() - (bottom() - top()) / 2.0f; + + return {centerX, centerY}; + } }; static bool GetSourceSnapOffset(obs_scene_t * /* scene */, obs_sceneitem_t *item, void *param) { + OBSBasic *main = OBSBasic::Get(); OffsetData *data = static_cast<OffsetData *>(param); if (obs_sceneitem_selected(item)) { return true; } + if (!obs_sceneitem_visible(item)) { + return true; + } matrix4 boxTransform; obs_sceneitem_get_box_transform(item, &boxTransform); @@ -924,20 +994,66 @@ } } - // Snap to other source edges -#define EDGE_SNAP(l, r, x, y) \ - do { \ - double dist = fabsf(l.x - data->r.x); \ - if (dist < data->clampDist && fabsf(data->offset.x) < EPSILON && data->tl.y < br.y && \ - data->br.y > tl.y && (fabsf(data->offset.x) > dist || data->offset.x < EPSILON)) \ - data->offset.x = l.x - data->r.x; \ - } while (false) + const auto screen = GetOBSScreenSize(); + + QRectF moveRect{data->left(), data->top(), data->right() - data->left(), data->bottom() - data->top()}; + QRectF itemRect{tl.x, tl.y, br.x - tl.x, br.y - tl.y}; + + const QPointF centerDelta{moveRect.center().x() - itemRect.center().x(), + moveRect.center().y() - itemRect.center().y()}; + + vec2 itemEdge{}; + vec2 movingEdge{}; + + itemEdge.x = centerDelta.x() < 0 ? itemRect.left() : itemRect.right(); + movingEdge.x = centerDelta.x() < 0 ? moveRect.left() : moveRect.right(); + + itemEdge.y = centerDelta.y() < 0 ? itemRect.top() : itemRect.bottom(); + movingEdge.y = centerDelta.y() < 0 ? moveRect.top() : moveRect.bottom(); + + // Horizontal snapping + // Check if the delta between centers is larger than the sum of half widths minus the clamp distance. + // Subtracting the clamp distance allows snapping from the "inner" edges when overlapping. + if (std::fabs(centerDelta.x()) > (moveRect.width() + itemRect.width() - (data->clampDist * 2)) / 2) { + // Moving item is not overlapping + movingEdge.x = centerDelta.x() < 0 ? moveRect.right() : moveRect.left(); + } else if (moveRect.width() > itemRect.width()) { + // Moving item is overlapping but larger, invert checked edges + itemEdge.x = centerDelta.x() > 0 ? itemRect.left() : itemRect.right(); + movingEdge.x = centerDelta.x() > 0 ? moveRect.left() : moveRect.right(); + } + + // Vertical snapping + // Check if the delta between centers is larger than the sum of half widths minus the clamp distance. + // Subtracting the clamp distance allows snapping from the "inner" edges when overlapping. + if (std::fabs(centerDelta.y()) > (moveRect.height() + itemRect.height() - (data->clampDist * 2)) / 2) { + // Moving item is not overlapping + movingEdge.y = centerDelta.y() < 0 ? moveRect.bottom() : moveRect.top(); + } else if (moveRect.height() > itemRect.height()) { + // Moving item is overlapping but larger, invert checked edges + itemEdge.y = centerDelta.y() > 0 ? itemRect.top() : itemRect.bottom(); + movingEdge.y = centerDelta.y() > 0 ? moveRect.top() : moveRect.bottom(); + } + + if (tryEdgeSnapForOffset(movingEdge.x, itemEdge.x, data->clampDist, data->offset.x)) { + SnapGuide guide{{itemEdge.x, 0.0f}, {itemEdge.x, screen.y}}; + main->addSnapGuide(guide); + } else if (tryEdgeSnapForOffset(moveRect.center().x(), itemRect.center().x(), data->clampDist, + data->offset.x)) { + float itemCenterX = static_cast<float>(itemRect.center().x()); + SnapGuide guide{{itemCenterX, 0.0f}, {itemCenterX, screen.y}}; + main->addSnapGuide(guide); + } - EDGE_SNAP(tl, br, x, y); - EDGE_SNAP(tl, br, y, x); - EDGE_SNAP(br, tl, x, y); - EDGE_SNAP(br, tl, y, x); -#undef EDGE_SNAP + if (tryEdgeSnapForOffset(movingEdge.y, itemEdge.y, data->clampDist, data->offset.y)) { + SnapGuide guide{{0.0f, itemEdge.y}, {screen.x, itemEdge.y}}; + main->addSnapGuide(guide); + } else if (tryEdgeSnapForOffset(moveRect.center().y(), itemRect.center().y(), data->clampDist, + data->offset.y)) { + float itemCenterY = static_cast<float>(itemRect.center().y()); + SnapGuide guide{{0.0f, itemCenterY}, {screen.x, itemCenterY}}; + main->addSnapGuide(guide); + } return true; } @@ -1632,6 +1748,8 @@ pos.x = std::round(pos.x); pos.y = std::round(pos.y); + snapGuides.clear(); + if (stretchHandle != ItemHandle::None) { if (obs_sceneitem_locked(stretchItem)) { return; @@ -2180,6 +2298,58 @@ return true; } +void OBSBasicPreview::DrawSnapGuides() +{ + if (snapGuides.empty()) { + return; + } + + OBSBasic *main = OBSBasic::Get(); + + vec2 viewport; + vec2_set(&viewport, main->previewCX, main->previewCY); + + float pixelRatio = main->GetDevicePixelRatio(); + + matrix4 transform; + matrix4_identity(&transform); + transform.x.x = viewport.x; + transform.y.y = viewport.y; + + gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); + gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); + + vec4 snapColor; + vec4_set(&snapColor, 0.0f, 1.0f, 1.0f, 0.8f); + + gs_effect_set_vec4(gs_effect_get_param_by_name(solid, "color"), &snapColor); + + gs_technique_begin(tech); + gs_technique_begin_pass(tech, 0); + + gs_matrix_push(); + gs_matrix_mul(&transform); + + for (const SnapGuide &guide : snapGuides) { + vec2 start, end; + + vec2_div(&start, &guide.start, &viewport); + vec2_div(&end, &guide.end, &viewport); + + vec2_mulf(&start, &start, main->previewScale); + vec2_mulf(&end, &end, main->previewScale); + + DrawLine(start.x, start.y, end.x, end.y, HANDLE_RADIUS * pixelRatio / 2, viewport); + } + + gs_matrix_pop(); + + gs_load_vertexbuffer(nullptr); + + gs_technique_end_pass(tech); + gs_technique_end(tech); +} + void OBSBasicPreview::DrawOverflow() { if (locked) {
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasicPreview.hpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasicPreview.hpp
Changed
@@ -31,6 +31,17 @@ Rot = ITEM_ROT }; +struct SnapGuide { + vec2 start; + vec2 end; + + explicit SnapGuide(vec2 start, vec2 end) + { + this->start = start; + this->end = end; + } +}; + class OBSBasicPreview : public OBSQTDisplay { Q_OBJECT @@ -80,6 +91,7 @@ bool updatingXScrollBar = false; bool updatingYScrollBar = false; + std::vector<SnapGuide> snapGuides; std::vector<obs_sceneitem_t *> hoveredPreviewItems; std::vector<obs_sceneitem_t *> selectedItems; std::mutex selectMutex; @@ -190,6 +202,8 @@ OBSSourceAutoRelease spacerLabel4; int spacerPx4 = {0}; + void addSnapGuide(SnapGuide guide); + void DrawSnapGuides(); void DrawSpacingHelpers(); void ClampScrollingOffsets(); void UpdateXScrollBar(float cx);
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasicStatusBar.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasicStatusBar.cpp
Changed
@@ -389,14 +389,14 @@ OBSBasicStatusBar *statusBar = static_cast<OBSBasicStatusBar *>(data); int seconds = (int)calldata_int(params, "timeout_sec"); - QMetaObject::invokeMethod(statusBar, "Reconnect", Q_ARG(int, seconds)); + QMetaObject::invokeMethod(statusBar, &OBSBasicStatusBar::Reconnect, seconds); } void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data, calldata_t *) { OBSBasicStatusBar *statusBar = static_cast<OBSBasicStatusBar *>(data); - QMetaObject::invokeMethod(statusBar, "ReconnectSuccess"); + QMetaObject::invokeMethod(statusBar, &OBSBasicStatusBar::ReconnectSuccess); } void OBSBasicStatusBar::Reconnect(int seconds)
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Canvases.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Canvases.cpp
Changed
@@ -19,8 +19,8 @@ void OBSBasic::CanvasRemoved(void *data, calldata_t *params) { - obs_canvas_t *canvas = static_cast<obs_canvas_t *>(calldata_ptr(params, "canvas")); - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "RemoveCanvas", Q_ARG(OBSCanvas, OBSCanvas(canvas))); + OBSCanvas canvas = static_cast<obs_canvas_t *>(calldata_ptr(params, "canvas")); + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::RemoveCanvas, canvas); } const OBS::Canvas &OBSBasic::AddCanvas(const std::string &name, obs_video_info *ovi, int flags)
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Clipboard.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Clipboard.cpp
Changed
@@ -284,6 +284,7 @@ return OBS::ItemPasteType::Invalid; } + bool allowPastingReference = true; bool allowPastingDuplicate = true; for (size_t i = clipboard.size(); i > 0; i--) { const size_t idx = i - 1; @@ -296,6 +297,19 @@ if (allowPastingDuplicate && obs_source_get_output_flags(strong) & OBS_SOURCE_DO_NOT_DUPLICATE) { allowPastingDuplicate = false; } + + if (allowPastingReference && obs_source_is_group(strong)) { + allowPastingReference = false; + } } - return allowPastingDuplicate ? OBS::ItemPasteType::Both : OBS::ItemPasteType::Reference; + + if (allowPastingReference && allowPastingDuplicate) { + return OBS::ItemPasteType::Both; + } else if (allowPastingReference) { + return OBS::ItemPasteType::Reference; + } else if (allowPastingDuplicate) { + return OBS::ItemPasteType::Duplicate; + } + + return OBS::ItemPasteType::Invalid; }
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_ContextToolbar.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_ContextToolbar.cpp
Changed
@@ -105,7 +105,7 @@ void OBSBasic::UpdateContextBarDeferred(bool force) { - QMetaObject::invokeMethod(this, "UpdateContextBar", Qt::QueuedConnection, Q_ARG(bool, force)); + QMetaObject::invokeMethod(this, &OBSBasic::UpdateContextBar, Qt::QueuedConnection, force); } void OBSBasic::SourceToolBarActionsSetEnabled() @@ -135,6 +135,73 @@ RefreshToolBarStyling(ui->sourcesToolbar); } +std::optional<QWidget *> OBSBasic::createContextBarWidget(obs_source_t *source) +{ + uint32_t flags = obs_source_get_output_flags(source); + const char *id = obs_source_get_unversioned_id(source); + + if (obs_source_load_state(id) != OBS_MODULE_ENABLED) { + return std::nullopt; + } + + if (flags & OBS_SOURCE_CONTROLLABLE_MEDIA) { + if (!is_network_media_source(source, id)) { + MediaControls *contextBarWidget = new MediaControls(ui->emptySpace); + contextBarWidget->SetSource(source); + return contextBarWidget; + } + } else if (strcmp(id, "browser_source") == 0) { + BrowserToolbar *contextBarWidget = new BrowserToolbar(ui->emptySpace, source); + return contextBarWidget; + + } else if (strcmp(id, "wasapi_input_capture") == 0 || strcmp(id, "wasapi_output_capture") == 0 || + strcmp(id, "coreaudio_input_capture") == 0 || strcmp(id, "coreaudio_output_capture") == 0 || + strcmp(id, "pulse_input_capture") == 0 || strcmp(id, "pulse_output_capture") == 0 || + strcmp(id, "alsa_input_capture") == 0) { + AudioCaptureToolbar *contextBarWidget = new AudioCaptureToolbar(ui->emptySpace, source); + contextBarWidget->Init(); + return contextBarWidget; + + } else if (strcmp(id, "wasapi_process_output_capture") == 0) { + ApplicationAudioCaptureToolbar *contextBarWidget = + new ApplicationAudioCaptureToolbar(ui->emptySpace, source); + contextBarWidget->Init(); + return contextBarWidget; + + } else if (strcmp(id, "window_capture") == 0 || strcmp(id, "xcomposite_input") == 0) { + WindowCaptureToolbar *contextBarWidget = new WindowCaptureToolbar(ui->emptySpace, source); + contextBarWidget->Init(); + return contextBarWidget; + + } else if (strcmp(id, "monitor_capture") == 0 || strcmp(id, "display_capture") == 0 || + strcmp(id, "xshm_input") == 0) { + DisplayCaptureToolbar *contextBarWidget = new DisplayCaptureToolbar(ui->emptySpace, source); + contextBarWidget->Init(); + return contextBarWidget; + + } else if (strcmp(id, "dshow_input") == 0) { + DeviceCaptureToolbar *contextBarWidget = new DeviceCaptureToolbar(ui->emptySpace, source); + return contextBarWidget; + + } else if (strcmp(id, "game_capture") == 0) { + GameCaptureToolbar *contextBarWidget = new GameCaptureToolbar(ui->emptySpace, source); + return contextBarWidget; + + } else if (strcmp(id, "image_source") == 0) { + ImageSourceToolbar *contextBarWidget = new ImageSourceToolbar(ui->emptySpace, source); + return contextBarWidget; + + } else if (strcmp(id, "color_source") == 0) { + ColorSourceToolbar *contextBarWidget = new ColorSourceToolbar(ui->emptySpace, source); + return contextBarWidget; + + } else if (strcmp(id, "text_ft2_source") == 0 || strcmp(id, "text_gdiplus") == 0) { + TextSourceToolbar *contextBarWidget = new TextSourceToolbar(ui->emptySpace, source); + return contextBarWidget; + } + return std::nullopt; +} + void OBSBasic::UpdateContextBar(bool force) { SourceToolBarActionsSetEnabled(); @@ -164,68 +231,13 @@ const char *id = obs_source_get_unversioned_id(source); uint32_t flags = obs_source_get_output_flags(source); - ui->sourceInteractButton->setVisible(flags & OBS_SOURCE_INTERACTION); if (contextBarSize >= ContextBarSize_Reduced && (updateNeeded || force)) { ClearContextBar(); - if (flags & OBS_SOURCE_CONTROLLABLE_MEDIA) { - if (!is_network_media_source(source, id)) { - MediaControls *mediaControls = new MediaControls(ui->emptySpace); - mediaControls->SetSource(source); - - ui->emptySpace->layout()->addWidget(mediaControls); - } - } else if (strcmp(id, "browser_source") == 0) { - BrowserToolbar *c = new BrowserToolbar(ui->emptySpace, source); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "wasapi_input_capture") == 0 || - strcmp(id, "wasapi_output_capture") == 0 || - strcmp(id, "coreaudio_input_capture") == 0 || - strcmp(id, "coreaudio_output_capture") == 0 || - strcmp(id, "pulse_input_capture") == 0 || strcmp(id, "pulse_output_capture") == 0 || - strcmp(id, "alsa_input_capture") == 0) { - AudioCaptureToolbar *c = new AudioCaptureToolbar(ui->emptySpace, source); - c->Init(); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "wasapi_process_output_capture") == 0) { - ApplicationAudioCaptureToolbar *c = - new ApplicationAudioCaptureToolbar(ui->emptySpace, source); - c->Init(); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "window_capture") == 0 || strcmp(id, "xcomposite_input") == 0) { - WindowCaptureToolbar *c = new WindowCaptureToolbar(ui->emptySpace, source); - c->Init(); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "monitor_capture") == 0 || strcmp(id, "display_capture") == 0 || - strcmp(id, "xshm_input") == 0) { - DisplayCaptureToolbar *c = new DisplayCaptureToolbar(ui->emptySpace, source); - c->Init(); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "dshow_input") == 0) { - DeviceCaptureToolbar *c = new DeviceCaptureToolbar(ui->emptySpace, source); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "game_capture") == 0) { - GameCaptureToolbar *c = new GameCaptureToolbar(ui->emptySpace, source); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "image_source") == 0) { - ImageSourceToolbar *c = new ImageSourceToolbar(ui->emptySpace, source); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "color_source") == 0) { - ColorSourceToolbar *c = new ColorSourceToolbar(ui->emptySpace, source); - ui->emptySpace->layout()->addWidget(c); - - } else if (strcmp(id, "text_ft2_source") == 0 || strcmp(id, "text_gdiplus") == 0) { - TextSourceToolbar *c = new TextSourceToolbar(ui->emptySpace, source); - ui->emptySpace->layout()->addWidget(c); + std::optional<QWidget *> contextBarWidget = createContextBarWidget(source); + if (contextBarWidget.has_value()) { + ui->emptySpace->layout()->addWidget(contextBarWidget.value()); } } else if (contextBarSize == ContextBarSize_Minimized) { ClearContextBar();
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Hotkeys.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Hotkeys.cpp
Changed
@@ -67,8 +67,8 @@ t.escape = Str("Hotkeys.Escape"); obs_hotkeys_set_translations(&t); - obs_hotkeys_set_audio_hotkeys_translations(Str("Mute"), Str("Unmute"), Str("Push-to-mute"), - Str("Push-to-talk")); + obs_hotkeys_set_audio_hotkeys_translations(Str("Mute"), Str("Unmute"), Str("Push-to-mute"), Str("Push-to-talk"), + Str("MonitorOn"), Str("MonitorOff")); obs_hotkeys_set_sceneitem_hotkeys_translations(Str("SceneItemShow"), Str("SceneItemHide")); @@ -84,7 +84,7 @@ void OBSBasic::HotkeyTriggered(void *data, obs_hotkey_id id, bool pressed) { OBSBasic &basic = *static_cast<OBSBasic *>(data); - QMetaObject::invokeMethod(&basic, "ProcessHotkey", Q_ARG(obs_hotkey_id, id), Q_ARG(bool, pressed)); + QMetaObject::invokeMethod(&basic, &OBSBasic::ProcessHotkey, id, pressed); } void OBSBasic::CreateHotkeys() @@ -210,6 +210,30 @@ this, this); LoadHotkeyPair(replayBufHotkeys, "OBSBasic.StartReplayBuffer", "OBSBasic.StopReplayBuffer"); + auto replayBufferCallback = (void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) { + OBSBasic *basic = static_cast<OBSBasic *>(data); + if (basic->outputHandler->ReplayBufferActive() && pressed) { + blog(LOG_INFO, "Saving replay buffer due to hotkey"); + basic->ReplayBufferSave(); + } + }; + + saveReplayBufferHotkey = obs_hotkey_register_frontend("OBSBasic.SaveReplayBuffer", Str("Basic.Main.SaveReplay"), + replayBufferCallback, this); + + bool hasSaveReplayHotkey = config_has_user_value(activeConfiguration, "Hotkeys", "OBSBasic.SaveReplayBuffer"); + if (hasSaveReplayHotkey) { + LoadHotkey(saveReplayBufferHotkey, "OBSBasic.SaveReplayBuffer"); + } else { + OBSDataArrayAutoRelease array = obs_data_get_array(LoadHotkeyData("ReplayBuffer"), "ReplayBuffer.Save"); + obs_hotkey_load(saveReplayBufferHotkey, array); + + OBSDataAutoRelease newData = obs_data_create(); + obs_data_set_array(newData, "bindings", array); + config_set_string(activeConfiguration, "Hotkeys", "OBSBasic.SaveReplayBuffer", + obs_data_get_json(newData)); + } + if (vcamEnabled) { vcamHotkeys = obs_hotkey_pair_register_frontend( "OBSBasic.StartVirtualCam", Str("Basic.Main.StartVirtualCam"), "OBSBasic.StopVirtualCam", @@ -249,7 +273,7 @@ auto transition = (void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) { if (pressed) { - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "TransitionClicked", + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::TransitionClicked, Qt::QueuedConnection); } }; @@ -259,7 +283,7 @@ auto resetStats = (void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) { if (pressed) { - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "ResetStatsHotkey", + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::ResetStatsHotkey, Qt::QueuedConnection); } }; @@ -270,7 +294,8 @@ auto screenshot = (void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) { if (pressed) { - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "Screenshot", Qt::QueuedConnection); + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::Screenshot, + Qt::QueuedConnection, nullptr); } }; @@ -279,7 +304,7 @@ auto screenshotSource = (void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) { if (pressed) { - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "ScreenshotSelectedSource", + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::ScreenshotSelectedSource, Qt::QueuedConnection); } }; @@ -297,6 +322,7 @@ obs_hotkey_unregister(splitFileHotkey); obs_hotkey_unregister(addChapterHotkey); obs_hotkey_pair_unregister(replayBufHotkeys); + obs_hotkey_unregister(saveReplayBufferHotkey); obs_hotkey_pair_unregister(vcamHotkeys); obs_hotkey_pair_unregister(togglePreviewHotkeys); obs_hotkey_pair_unregister(contextBarHotkeys);
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_MainControls.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_MainControls.cpp
Changed
@@ -50,9 +50,7 @@ #include <nlohmann/json.hpp> #include <QDesktopServices> -#ifdef _WIN32 #include <sstream> -#endif extern bool restart; extern bool restart_safe; @@ -492,7 +490,7 @@ CloseDialogs(); #endif - QMetaObject::invokeMethod(this, "ToggleAlwaysOnTop", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::ToggleAlwaysOnTop, Qt::QueuedConnection); } void OBSBasic::ToggleAlwaysOnTop() @@ -670,10 +668,11 @@ void OBSBasic::on_idianPlayground_triggered() { #ifdef ENABLE_IDIAN_PLAYGROUND - OBSIdianPlayground playground(this); - playground.setModal(true); - playground.show(); - playground.exec(); + if (!playground) { + playground = new OBSIdianPlayground(this); + playground->setAttribute(Qt::WA_DeleteOnClose); + playground->show(); + } #endif }
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Preview.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Preview.cpp
Changed
@@ -195,6 +195,8 @@ window->ui->preview->DrawSpacingHelpers(); } + window->ui->preview->DrawSnapGuides(); + /* --------------------------------------- */ gs_projection_pop(); @@ -273,6 +275,11 @@ EnablePreviewDisplay(previewEnabled); } +void OBSBasic::addSnapGuide(SnapGuide guide) +{ + ui->preview->addSnapGuide(guide); +} + void OBSBasic::EnablePreview() { if (previewProgramMode) {
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Profiles.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Profiles.cpp
Changed
@@ -23,10 +23,13 @@ #include <wizards/AutoConfig.hpp> #include <qt-wrappers.hpp> +#include <util/pipe.h> #include <QDir> #include <QFile> +#include <unordered_set> + // MARK: Constant Expressions constexpr std::string_view OBSProfilePath = "/obs-studio/basic/profiles/"; @@ -40,6 +43,7 @@ extern void DuplicateCurrentCookieProfile(ConfigFile &config); extern void CheckExistingCookieId(); extern void DeleteCookies(); +extern const char *get_simple_output_encoder(const char *name); // MARK: - Anonymous Namespace namespace { @@ -554,7 +558,8 @@ const QString sourceDirectory = SelectDirectory(this, QTStr("Basic.MainMenu.Profile.Import"), home); if (!sourceDirectory.isEmpty() && !sourceDirectory.isNull()) { - const std::filesystem::path sourcePath = std::filesystem::u8path(sourceDirectory.toStdString()); + const std::filesystem::path sourcePath = + std::filesystem::u8path(QDir::cleanPath(sourceDirectory).toStdString()); const std::string directoryName = sourcePath.filename().u8string(); if (auto profile = GetProfileByDirectoryName(directoryName)) { @@ -704,6 +709,9 @@ ResetProfileData(); } + // Ensure defaults and updates are saved to disk + activeConfiguration.SaveSafe("tmp"); + RefreshProfiles(); UpdateTitleBar(); @@ -736,6 +744,7 @@ void OBSBasic::UpdateProfileEncoders() { InitBasicConfigDefaults2(); + CheckForMissingEncoders(); CheckForSimpleModeX264Fallback(); } @@ -912,3 +921,203 @@ activeConfiguration.SaveSafe("tmp"); } } + +namespace { +using OsProcessArgs = std::unique_ptr<os_process_args_t, decltype(&os_process_args_destroy)>; + +struct ErrorDetails { + // HTML breadcrumb to section in knowledge base article, may be empty + QString breadcrumb; + // Human-readable/localized error message + QString message; +}; +using CheckResult = std::optional<ErrorDetails>; + +#ifndef __APPLE__ +CheckResult CheckNVENCInternal(const std::unordered_set<std::string_view> &missing_encoders) +{ + const std::vector<std::pair<std::string_view, std::string_view>> nvencFailureReasons = { + {"nvml_lib", "EncoderMissing.NVENC.Reason.NvmlLoad"}, + // Some error messages are a prefix + numeric error code + {"nvml_init", "EncoderMissing.NVENC.Reason.NvmlInit"}, + {"nvenc_lib", "EncoderMissing.NVENC.Reason.NvencLoad"}, + {"nvenc_init", "EncoderMissing.NVENC.Reason.NvencInit"}, + {"cuda_lib", "EncoderMissing.NVENC.Reason.CudaLoad"}, + {"cuda_init", "EncoderMissing.NVENC.Reason.CudaInit"}, + {"no_cuda_version", "EncoderMissing.NVENC.Reason.CudaVersion"}, + {"no_devices", "EncoderMissing.NVENC.NoDevices"}, + {"no_nvenc_version", "EncoderMissing.NVENC.Reason.NvencVersion"}, + {"outdated_driver", "EncoderMissing.NVENC.Reason.DriverOutdated"}, + {"no_supported_devices", "EncoderMissing.NVENC.Reason.NoSupportedDevices"}, + {"session_limit", "EncoderMissing.NVENC.Reason.SessionLimitExceeded"}, + }; + + // Most basic check: Is the module even loaded? + if (!obs_get_module("obs-nvenc")) { + return ErrorDetails{"plugin_not_loaded", QTStr("EncoderMissing.MissingModule").arg("obs-nvenc")}; + } + +#ifdef _WIN32 + BPtr testBinary = os_get_executable_path_ptr("obs-nvenc-test.exe"); +#else + BPtr testBinary = os_get_executable_path_ptr("obs-nvenc-test"); +#endif + + OsProcessArgs args{os_process_args_create(testBinary), os_process_args_destroy}; + + os_process_pipe_t *pp = os_process_pipe_create2(args.get(), "r"); + if (!pp) { + return ErrorDetails{"nvenc_test_failure", QTStr("EncoderMissing.NVENC.TestProgramFailedStartup")}; + } + + std::string caps_result; + for (;;) { + char data4096; + const size_t len = os_process_pipe_read(pp, reinterpret_cast<uint8_t *>(data), sizeof(data)); + if (!len) { + break; + } + + caps_result.append(data, len); + } + + int exitCode = os_process_pipe_destroy(pp); + + if (caps_result.empty()) { + return ErrorDetails{"nvenc_test_failure", + QTStr("EncoderMissing.NVENC.TestProgramExitWithError").arg(exitCode)}; + } + + auto config = ConfigFile(); + if (config.OpenString(caps_result.c_str()) != CONFIG_SUCCESS) { + return ErrorDetails{"nvenc_test_failure", + QTStr("EncoderMissing.NVENC.TestProgramReadFailure").arg(exitCode)}; + } + + // Read devices and attempt to find reason for failure + auto numDevices = config_get_uint(config, "general", "cuda_devices"); + if (!numDevices) { + return ErrorDetails{"no_device", QTStr("EncoderMissing.NVENC.NoDevices")}; + } + + // Check device generation (architecture) + for (uint64_t i = 0; i < numDevices; i++) { + std::string section = "device." + std::to_string(i); + + if (!config_has_user_value(config, section.c_str(), "name")) { + continue; + } + + const QString name(config_get_string(config, section.c_str(), "name")); + const std::string_view arch = config_get_string(config, section.c_str(), "architecture_name"); + + if (arch == "Kepler") { + return ErrorDetails{"kepler", QTStr("EncoderMissing.NVENC.Unsupported.Kepler").arg(name)}; + } + } + + // All other specific failures of the test binary + if (config_has_user_value(config, "general", "reason")) { + const std::string_view reason = config_get_string(config, "general", "reason"); + + for (auto &code, desc : nvencFailureReasons) { + if (reason.find(code) == std::string_view::npos) { + continue; + } + + return ErrorDetails{code.data(), + QTStr("EncoderMissing.NVENC.TestProgramError").arg(QTStr(desc.data()))}; + } + } + + // Finally, if everything else looks good but the encoder missing is AV1, and AV1 is not supported on any GPUs, + // that's probably the issue the user is having (for example, when copying a profile from another machine). + if (!config_get_bool(config, "av1", "codec_supported") && + (missing_encoders.count("obs_nvenc_av1_cuda") || missing_encoders.count("obs_nvenc_av1_soft") || + missing_encoders.count("obs_nvenc_av1_tex"))) { + return ErrorDetails{"no_av1", QTStr("EncoderMissing.NVENC.Reason.AV1Unsupported")}; + } + + return std::nullopt; +} + +CheckResult CheckNVENC(const std::unordered_set<std::string_view> &missing_encoders) +{ + static auto result = CheckNVENCInternal(missing_encoders); + return result; +} +#endif + +CheckResult CheckX264() +{ + static const bool module_loaded = obs_get_module("obs-x264") != nullptr; + // This should be the only failure mode possible here. + if (!module_loaded) { + return ErrorDetails{"plugin_not_loaded", QTStr("EncoderMissing.MissingModule").arg("obs-x264")}; + } + + return std::nullopt; +} +} // namespace + +void OBSBasic::CheckForMissingEncoders() +{ + constexpr QStringView kbURL(u"https://obsproject.com/kb/encoder-missing#%1"); + const QString encoderListItem = QTStr("EncoderMissing.ItemText"); + const QString unknownErrorText = QTStr("EncoderMissing.Unknown"); + + const char *outputMode = config_get_string(activeConfiguration, "Output", "Mode"); + + std::unordered_set<std::string_view> missing_encoders; + if (strcmp(outputMode, "Advanced") != 0) { + missing_encoders = { + get_simple_output_encoder( + config_get_string(activeConfiguration, "SimpleOutput", "StreamEncoder")), + get_simple_output_encoder(config_get_string(activeConfiguration, "SimpleOutput", "RecEncoder")), + }; + } else { + missing_encoders = { + config_get_string(activeConfiguration, "AdvOut", "Encoder"), + config_get_string(activeConfiguration, "AdvOut", "RecEncoder"), + }; + } + + size_t idx = 0; + const char *id; + while (obs_enum_encoder_types(idx++, &id)) { + missing_encoders.erase(id); + } + + if (missing_encoders.empty() || (missing_encoders.size() == 1 && missing_encoders.count("none"))) { + return; + } + + QString crumb; + QStringList encoderList; + + for (auto &encoder : missing_encoders) { + CheckResult res; + + if (encoder.find("x264") != std::string_view::npos) { + res = CheckX264(); +#ifndef __APPLE__ + } else if (encoder.find("nvenc") != std::string_view::npos) { + res = CheckNVENC(missing_encoders); +#endif + } + + if (res) { + encoderList += encoderListItem.arg(encoder.data()).arg(res->message).arg(res->breadcrumb); + if (crumb.isEmpty() && !res->breadcrumb.isEmpty()) { + crumb = res->breadcrumb; + } + } else { + encoderList += encoderListItem.arg(encoder.data()).arg(unknownErrorText).arg("unknown"); + } + } + + // Format and show error message + const QString encoderMissingMessage = + QTStr("EncoderMissing.Text").arg(encoderList.join("\n")).arg(kbURL.arg(crumb)); + OBSMessageBox::warning(nullptr, QTStr("EncoderMissing.Title"), encoderMissingMessage, true); +}
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_ReplayBuffer.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_ReplayBuffer.cpp
Changed
@@ -61,7 +61,7 @@ bool warned = config_get_bool(App()->GetUserConfig(), "General", "WarnedAboutReplayBufferPausing"); if (!warned) { - QMetaObject::invokeMethod(App(), "Exec", Qt::QueuedConnection, Q_ARG(VoidFunc, msgBox)); + QMetaObject::invokeMethod(App(), &OBSApp::Exec, Qt::QueuedConnection, msgBox); } } @@ -160,6 +160,8 @@ return; } + OnEvent(OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVING); + calldata_t cd = {0}; proc_handler_t *ph = obs_output_get_proc_handler(outputHandler->replayBuffer); proc_handler_call(ph, "save", &cd);
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_SceneCollections.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_SceneCollections.cpp
Changed
@@ -1021,12 +1021,9 @@ const char *source_name = obs_source_get_name(source); blog(LOG_INFO, "Loaded global audio device: '%s'", source_name); obs_source_enum_filters(source, LogFilter, (void *)(intptr_t)1); - obs_monitoring_type monitoring_type = obs_source_get_monitoring_type(source); - if (monitoring_type != OBS_MONITORING_TYPE_NONE) { - const char *type = (monitoring_type == OBS_MONITORING_TYPE_MONITOR_ONLY) ? "monitor only" - : "monitor and output"; - - blog(LOG_INFO, " - monitoring: %s", type); + bool monitoring = obs_source_get_monitoring_enabled(source); + if (monitoring) { + blog(LOG_INFO, " - monitoring: enabled"); } } @@ -1064,7 +1061,8 @@ indent += " "; } - blog(LOG_INFO, "%s- filter: '%s' (%s)", indent.c_str(), name, id); + blog(LOG_INFO, "%s- filter: '%s' (%s)%s", indent.c_str(), name, id, + obs_source_enabled(filter) ? "" : " (disabled)"); } static bool LogSceneItem(obs_scene_t *, obs_sceneitem_t *item, void *v_val) @@ -1079,15 +1077,13 @@ indent += " "; } - blog(LOG_INFO, "%s- source: '%s' (%s)", indent.c_str(), name, id); - - obs_monitoring_type monitoring_type = obs_source_get_monitoring_type(source); + blog(LOG_INFO, "%s- source: '%s' (%s)%s", indent.c_str(), name, id, + obs_sceneitem_visible(item) ? "" : " (disabled)"); - if (monitoring_type != OBS_MONITORING_TYPE_NONE) { - const char *type = (monitoring_type == OBS_MONITORING_TYPE_MONITOR_ONLY) ? "monitor only" - : "monitor and output"; + bool monitoring = obs_source_get_monitoring_enabled(source); - blog(LOG_INFO, " %s- monitoring: %s", indent.c_str(), type); + if (monitoring) { + blog(LOG_INFO, " %s- monitoring: enabled", indent.c_str()); } int child_indent = 1 + indent_count; obs_source_enum_filters(source, LogFilter, (void *)(intptr_t)child_indent); @@ -1483,23 +1479,23 @@ if (opt_start_streaming && !safe_mode) { blog(LOG_INFO, "Starting stream due to command line parameter"); - QMetaObject::invokeMethod(this, "StartStreaming", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::StartStreaming, Qt::QueuedConnection); opt_start_streaming = false; } if (opt_start_recording && !safe_mode) { blog(LOG_INFO, "Starting recording due to command line parameter"); - QMetaObject::invokeMethod(this, "StartRecording", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::StartRecording, Qt::QueuedConnection); opt_start_recording = false; } if (opt_start_replaybuffer && !safe_mode) { - QMetaObject::invokeMethod(this, "StartReplayBuffer", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::StartReplayBuffer, Qt::QueuedConnection); opt_start_replaybuffer = false; } if (opt_start_virtualcam && !safe_mode) { - QMetaObject::invokeMethod(this, "StartVirtualCam", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::StartVirtualCam, Qt::QueuedConnection); opt_start_virtualcam = false; } @@ -1536,7 +1532,7 @@ } projectChanged = true; - QMetaObject::invokeMethod(this, "SaveProjectDeferred", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::SaveProjectDeferred, Qt::QueuedConnection); } void OBSBasic::SaveProjectDeferred()
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_SceneItems.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_SceneItems.cpp
Changed
@@ -199,32 +199,30 @@ void OBSBasic::SourceCreated(void *data, calldata_t *params) { - obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); + OBSSource source = (obs_source_t *)calldata_ptr(params, "source"); if (obs_scene_from_source(source) != NULL) { - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "AddScene", WaitConnection(), - Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::AddScene, WaitConnection(), source); } } void OBSBasic::SourceRemoved(void *data, calldata_t *params) { - obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); + OBSSource source = (obs_source_t *)calldata_ptr(params, "source"); if (obs_scene_from_source(source) != NULL) { - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "RemoveScene", - Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::RemoveScene, source); } } void OBSBasic::SourceRenamed(void *data, calldata_t *params) { - obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); + OBSSource source = (obs_source_t *)calldata_ptr(params, "source"); const char *newName = calldata_string(params, "new_name"); const char *prevName = calldata_string(params, "prev_name"); - QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "RenameSources", Q_ARG(OBSSource, source), - Q_ARG(QString, QT_UTF8(newName)), Q_ARG(QString, QT_UTF8(prevName))); + QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), &OBSBasic::RenameSources, source, QT_UTF8(newName), + QT_UTF8(prevName)); blog(LOG_INFO, "Source '%s' renamed to '%s'", prevName, newName); }
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Scenes.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Scenes.cpp
Changed
@@ -484,7 +484,7 @@ obs_scene_t *scene = (obs_scene_t *)calldata_ptr(params, "scene"); - QMetaObject::invokeMethod(window, "ReorderSources", Q_ARG(OBSScene, OBSScene(scene))); + QMetaObject::invokeMethod(window, &OBSBasic::ReorderSources, OBSScene(scene)); } void OBSBasic::SceneRefreshed(void *data, calldata_t *params) @@ -493,7 +493,7 @@ obs_scene_t *scene = (obs_scene_t *)calldata_ptr(params, "scene"); - QMetaObject::invokeMethod(window, "RefreshSources", Q_ARG(OBSScene, OBSScene(scene))); + QMetaObject::invokeMethod(window, &OBSBasic::RefreshSources, OBSScene(scene)); } void OBSBasic::SceneItemAdded(void *data, calldata_t *params) @@ -502,7 +502,7 @@ obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(params, "item"); - QMetaObject::invokeMethod(window, "AddSceneItem", Q_ARG(OBSSceneItem, OBSSceneItem(item))); + QMetaObject::invokeMethod(window, &OBSBasic::AddSceneItem, OBSSceneItem(item)); } void OBSBasic::on_scenes_currentItemChanged(QListWidgetItem *current, QListWidgetItem *)
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Screenshots.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Screenshots.cpp
Changed
@@ -30,6 +30,13 @@ } screenshotData = new ScreenshotObj(source); + + connect(screenshotData, &ScreenshotObj::imageSaved, this, this(std::string path) { + ShowStatusBarMessage(QTStr("Basic.StatusBar.ScreenshotSavedTo").arg(QT_UTF8(path.c_str()))); + lastScreenshot = path; + + OnEvent(OBS_FRONTEND_EVENT_SCREENSHOT_TAKEN); + }); } void OBSBasic::ScreenshotSelectedSource()
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Streaming.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Streaming.cpp
Changed
@@ -67,7 +67,7 @@ no_broadcast.exec(); if (no_broadcast.clickedButton() == SetupBroadcast) { - QMetaObject::invokeMethod(this, "SetupBroadcast"); + QMetaObject::invokeMethod(this, &OBSBasic::SetupBroadcast); } return; } @@ -384,7 +384,7 @@ SetBroadcastFlowEnabled(auth && auth->broadcastFlow()); } if (should_reconnect) { - QMetaObject::invokeMethod(this, "StartStreaming", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::StartStreaming, Qt::QueuedConnection); } }
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_Transitions.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_Transitions.cpp
Changed
@@ -73,6 +73,14 @@ } } + // We require transitions in order to function, so exit with an error if + // obs-transitions failed to load for whatever reason. + if (!fadeTransition || !cutTransition) { + // FIXME: https://github.com/obsproject/obs-studio/issues/13394 + throw "InitDefaultTransitions: Could not load default transitions. Try re-installing OBS Studio from " + "<a href=\"https://obsproject.com/\">obsproject.com</a>."; + } + for (OBSSource &tr : defaultTransitions) { std::string uuid = obs_source_get_uuid(tr); @@ -99,7 +107,7 @@ OBSBasic *main = OBSBasic::Get(); if (pressed) { - QMetaObject::invokeMethod(main, "TriggerQuickTransition", Qt::QueuedConnection, Q_ARG(int, id)); + QMetaObject::invokeMethod(main, &OBSBasic::TriggerQuickTransition, Qt::QueuedConnection, id); } }; @@ -133,17 +141,17 @@ { auto onTransitionStart = (void *data, calldata_t *) { OBSBasic *window = (OBSBasic *)data; - QMetaObject::invokeMethod(window, "TransitionStarted", Qt::QueuedConnection); + QMetaObject::invokeMethod(window, &OBSBasic::TransitionStarted, Qt::QueuedConnection); }; auto onTransitionStop = (void *data, calldata_t *) { OBSBasic *window = (OBSBasic *)data; - QMetaObject::invokeMethod(window, "TransitionStopped", Qt::QueuedConnection); + QMetaObject::invokeMethod(window, &OBSBasic::TransitionStopped, Qt::QueuedConnection); }; auto onTransitionFullStop = (void *data, calldata_t *) { OBSBasic *window = (OBSBasic *)data; - QMetaObject::invokeMethod(window, "TransitionFullyStopped", Qt::QueuedConnection); + QMetaObject::invokeMethod(window, &OBSBasic::TransitionFullyStopped, Qt::QueuedConnection); }; signal_handler_t *handler = obs_source_get_signal_handler(transition); @@ -1144,8 +1152,7 @@ duration->setValue(qt ? qt->duration : 300); if (qt) { - connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged, this, - &OBSBasic::QuickTransitionChangeDuration); + connect(duration, &QSpinBox::valueChanged, this, &OBSBasic::QuickTransitionChangeDuration); } action = menu->addAction(QTStr("FadeToBlack"));
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSBasic_YouTube.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSBasic_YouTube.cpp
Changed
@@ -50,7 +50,7 @@ emit BroadcastStreamReady(broadcastReady); if (startNow) { - QMetaObject::invokeMethod(this, "StartStreaming"); + QMetaObject::invokeMethod(this, &OBSBasic::StartStreaming); } } @@ -59,7 +59,7 @@ YoutubeApiWrappers *apiYouTube(dynamic_cast<YoutubeApiWrappers *>(GetAuth())); if (!apiYouTube) { /* technically we should never get here -Lain */ - QMetaObject::invokeMethod(this, "ForceStopStreaming", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::ForceStopStreaming, Qt::QueuedConnection); youtubeStreamCheckThread->deleteLater(); blog(LOG_ERROR, "=========================================="); blog(LOG_ERROR, "%s: Uh, hey, we got here", __FUNCTION__); @@ -73,13 +73,13 @@ while (StreamingActive()) { if (timeout == 14) { - QMetaObject::invokeMethod(this, "ForceStopStreaming", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::ForceStopStreaming, Qt::QueuedConnection); break; } if (!apiYouTube->FindStream(id, json)) { - QMetaObject::invokeMethod(this, "DisplayStreamStartError", Qt::QueuedConnection); - QMetaObject::invokeMethod(this, "StopStreaming", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::DisplayStreamStartError, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSBasic::StopStreaming, Qt::QueuedConnection); break; } @@ -119,7 +119,7 @@ bool warned = config_get_bool(App()->GetUserConfig(), "General", "WarnedAboutYouTubeAutoStart"); if (!warned) { - QMetaObject::invokeMethod(App(), "Exec", Qt::QueuedConnection, Q_ARG(VoidFunc, msgBox)); + QMetaObject::invokeMethod(App(), &OBSApp::Exec, Qt::QueuedConnection, msgBox); } } #endif @@ -187,7 +187,7 @@ broadcastReady = false; autoStopBroadcast = true; - QMetaObject::invokeMethod(this, "StopStreaming"); + QMetaObject::invokeMethod(this, &OBSBasic::StopStreaming); emit BroadcastStreamReady(broadcastReady); SetBroadcastFlowEnabled(true); }
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSProjector.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSProjector.cpp
Changed
@@ -215,16 +215,16 @@ void OBSProjector::OBSSourceRenamed(void *data, calldata_t *params) { OBSProjector *window = static_cast<OBSProjector *>(data); - QString oldName = calldata_string(params, "prev_name"); - QString newName = calldata_string(params, "new_name"); + QString oldName = QString::fromUtf8(calldata_string(params, "prev_name")); + QString newName = QString::fromUtf8(calldata_string(params, "new_name")); - QMetaObject::invokeMethod(window, "RenameProjector", Q_ARG(QString, oldName), Q_ARG(QString, newName)); + QMetaObject::invokeMethod(window, &OBSProjector::RenameProjector, oldName, newName); } void OBSProjector::OBSSourceDestroyed(void *data, calldata_t *) { OBSProjector *window = static_cast<OBSProjector *>(data); - QMetaObject::invokeMethod(window, "EscapeTriggered"); + QMetaObject::invokeMethod(window, &OBSProjector::EscapeTriggered); } void OBSProjector::mouseDoubleClickEvent(QMouseEvent *event)
View file
obs-studio-32.2.2.tar.xz/frontend/widgets/OBSQTDisplay.cpp -> obs-studio-33.0.0.tar.xz/frontend/widgets/OBSQTDisplay.cpp
Changed
@@ -10,9 +10,6 @@ #include <QWindow> #ifdef ENABLE_WAYLAND #include <QApplication> -#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0) -#include <qpa/qplatformnativeinterface.h> -#endif #endif #ifdef _WIN32 @@ -52,12 +49,7 @@ break; #ifdef ENABLE_WAYLAND case OBS_NIX_PLATFORM_WAYLAND: { -#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0) - QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface(); - gswindow.display = native->nativeResourceForWindow("surface", window); -#else gswindow.display = (void *)window->winId(); -#endif success = gswindow.display != nullptr; break; }
View file
obs-studio-32.2.2.tar.xz/frontend/wizards/AutoConfigTestPage.cpp -> obs-studio-33.0.0.tar.xz/frontend/wizards/AutoConfigTestPage.cpp
Changed
@@ -103,7 +103,7 @@ TestMode testMode; testMode.SetVideo(128, 128, 60, 1); - QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, 0)); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::Progress, 0); /* * create encoders @@ -111,7 +111,7 @@ * test for 10 seconds */ - QMetaObject::invokeMethod(this, "UpdateMessage", Q_ARG(QString, QStringLiteral(""))); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::UpdateMessage, QStringLiteral("")); /* -----------------------------------*/ /* create obs objects */ @@ -247,7 +247,7 @@ /* If none, fail */ if (!output_type) { - QMetaObject::invokeMethod(this, "Failure", Q_ARG(QString, QTStr(TEST_BW_NO_OUTPUT))); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::Failure, QTStr(TEST_BW_NO_OUTPUT)); return; } } @@ -322,9 +322,9 @@ stopped = false; int per = int((i + 1) * 100 / servers.size()); - QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per)); - QMetaObject::invokeMethod(this, "UpdateMessage", - Q_ARG(QString, QTStr(TEST_BW_CONNECTING).arg(server.name.c_str()))); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::Progress, per); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::UpdateMessage, + QTStr(TEST_BW_CONNECTING).arg(server.name.c_str())); obs_data_set_string(service_settings, "server", server.address.c_str()); obs_service_update(service, service_settings); @@ -351,8 +351,8 @@ continue; } - QMetaObject::invokeMethod(this, "UpdateMessage", - Q_ARG(QString, QTStr(TEST_BW_SERVER).arg(server.name.c_str()))); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::UpdateMessage, + QTStr(TEST_BW_SERVER).arg(server.name.c_str())); /* ignore first 2.5 seconds due to possible buffering skewing * the result */ @@ -401,7 +401,7 @@ } if (!success) { - QMetaObject::invokeMethod(this, "Failure", Q_ARG(QString, QTStr(TEST_BW_CONNECT_FAIL))); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::Failure, QTStr(TEST_BW_CONNECT_FAIL)); return; } @@ -425,7 +425,7 @@ wiz->serverName = std::move(bestServerName); wiz->idealBitrate = bestBitrate; - QMetaObject::invokeMethod(this, "NextStage"); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::NextStage); } /* this is used to estimate the lower bitrate limit for a given @@ -485,7 +485,7 @@ bool AutoConfigTestPage::TestSoftwareEncoding() { TestMode testMode; - QMetaObject::invokeMethod(this, "UpdateMessage", Q_ARG(QString, QStringLiteral(""))); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::UpdateMessage, QStringLiteral("")); /* -----------------------------------*/ /* create obs objects */ @@ -583,7 +583,7 @@ auto testRes = &(int cy, int fps_num, int fps_den, bool force) { int per = ++i * 100 / count; - QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per)); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::Progress, per); if (cy > baseCY) { return true; @@ -628,8 +628,8 @@ QString fpsStr = (fps_den > 1) ? QString::number(fps, 'f', 2) : QString::number(fps, 'g', 2); - QMetaObject::invokeMethod(this, "UpdateMessage", - Q_ARG(QString, QTStr(TEST_RES_VAL).arg(cxStr, cyStr, fpsStr))); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::UpdateMessage, + QTStr(TEST_RES_VAL).arg(cxStr, cyStr, fpsStr)); unique_lock<mutex> ul(m); if (cancel) { @@ -637,7 +637,7 @@ } if (!obs_output_start(output)) { - QMetaObject::invokeMethod(this, "Failure", Q_ARG(QString, QTStr(TEST_RES_FAIL))); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::Failure, QTStr(TEST_RES_FAIL)); return false; } @@ -913,7 +913,7 @@ FindIdealHardwareResolution(); } - QMetaObject::invokeMethod(this, "NextStage"); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::NextStage); } void AutoConfigTestPage::TestRecordingEncoderThread() @@ -953,7 +953,7 @@ } } - QMetaObject::invokeMethod(this, "NextStage"); + QMetaObject::invokeMethod(this, &AutoConfigTestPage::NextStage); } #define ENCODER_TEXT(x) "Basic.Settings.Output.Simple.Encoder." x
View file
obs-studio-32.2.2.tar.xz/libobs-d3d11/d3d11-shader.cpp -> obs-studio-33.0.0.tar.xz/libobs-d3d11/d3d11-shader.cpp
Changed
@@ -27,6 +27,21 @@ #include <filesystem> #include <fstream> #include <d3dcompiler.h> +#include <system_error> + +namespace { + +void removeCacheFile(const std::filesystem::path &cachePath, const char *reason) noexcept +{ + blog(LOG_WARNING, "Discarding shader cache file %s: %s", + reinterpret_cast<const char *>(cachePath.u8string().c_str()), reason); + + // Intentionally ignored - we don't care about failure here, we just don't want exceptions + std::error_code ec; + std::filesystem::remove(cachePath, ec); +} + +} // namespace void gs_vertex_shader::GetBuffersExpected(const std::vector<D3D11_INPUT_ELEMENT_DESC> &inputs) { @@ -239,41 +254,47 @@ // Increment if on-disk format changes cachePath += ".v2"; - std::fstream cacheFile; - cacheFile.exceptions(std::fstream::badbit | std::fstream::eofbit); + std::ifstream cacheFile{cachePath, std::ios::binary | std::ios::ate}; + if (cacheFile.is_open()) { + uint64_t checksum = 0; - if (std::filesystem::exists(cachePath) && !std::filesystem::is_empty(cachePath)) { - cacheFile.open(cachePath, std::ios::in | std::ios::binary | std::ios::ate); - } + std::streamoff len = cacheFile.tellg(); - if (cacheFile.is_open()) { - uint64_t checksum; + // Not enough data for checksum + shader + if (len < 0 || len <= static_cast<std::streamoff>(sizeof(checksum))) { + cacheFile.close(); + removeCacheFile(cachePath, "truncated or unreadable"); + } else { + len -= sizeof(checksum); - try { - std::streampos len = cacheFile.tellg(); - // Not enough data for checksum + shader - if (len <= sizeof(checksum)) { - throw std::length_error("File truncated"); - } + hr = D3DCreateBlob(len, shader); + if (FAILED(hr)) { + cacheFile.close(); + removeCacheFile(cachePath, "cache blob allocation failed"); + } else { + cacheFile.seekg(0, std::ios::beg); + cacheFile.read(static_cast<char *>((*shader)->GetBufferPointer()), len); + cacheFile.read(reinterpret_cast<char *>(&checksum), sizeof(checksum)); - cacheFile.seekg(0, std::ios::beg); + const bool success = static_cast<bool>(cacheFile); - len -= sizeof(checksum); - D3DCreateBlob(len, shader); - cacheFile.read((char *)(*shader)->GetBufferPointer(), len); - uint64_t calculated_checksum = fnv1a_hash((char *)(*shader)->GetBufferPointer(), len); + if (success) { + uint64_t calculated_checksum = + fnv1a_hash(static_cast<char *>((*shader)->GetBufferPointer()), len); - cacheFile.read((char *)&checksum, sizeof(checksum)); - if (calculated_checksum != checksum) { - throw std::exception("Checksum mismatch"); - } + if (calculated_checksum == checksum) { + is_cached = true; + } + } - is_cached = true; - } catch (const std::exception &e) { - // Something went wrong reading the cache file, delete it - blog(LOG_WARNING, "Loading shader cache file failed with \"%s\": %s", e.what(), file); - cacheFile.close(); - std::filesystem::remove(cachePath); + if (!is_cached) { + (*shader)->Release(); + *shader = nullptr; + + cacheFile.close(); + removeCacheFile(cachePath, !success ? "read error" : "checksum mismatch"); + } + } } } @@ -288,18 +309,17 @@ } } - cacheFile.open(cachePath, std::ios::out | std::ios::binary); - if (cacheFile.is_open()) { - try { - uint64_t calculated_checksum = - fnv1a_hash((char *)(*shader)->GetBufferPointer(), (*shader)->GetBufferSize()); + std::ofstream outFile{cachePath, std::ios::binary | std::ios::trunc}; + if (outFile.is_open()) { + uint64_t calculated_checksum = fnv1a_hash(static_cast<char *>((*shader)->GetBufferPointer()), + (*shader)->GetBufferSize()); - cacheFile.write((char *)(*shader)->GetBufferPointer(), (*shader)->GetBufferSize()); - cacheFile.write((char *)&calculated_checksum, sizeof(calculated_checksum)); - } catch (const std::exception &e) { - blog(LOG_WARNING, "Writing shader cache file failed with \"%s\": %s", e.what(), file); - cacheFile.close(); - std::filesystem::remove(cachePath); + outFile.write(static_cast<char *>((*shader)->GetBufferPointer()), (*shader)->GetBufferSize()); + outFile.write(reinterpret_cast<char *>(&calculated_checksum), sizeof(calculated_checksum)); + outFile.close(); + + if (outFile.fail()) { + removeCacheFile(cachePath, "write error"); } } }
View file
obs-studio-32.2.2.tar.xz/libobs-metal/MetalDevice.swift -> obs-studio-33.0.0.tar.xz/libobs-metal/MetalDevice.swift
Changed
@@ -149,38 +149,43 @@ func blitSwapChains() { guard swapChains.count > 0 else { return } - guard let commandBuffer = commandQueue.makeCommandBuffer(), - let encoder = commandBuffer.makeBlitCommandEncoder() - else { - return - } - self.swapChainQueue.sync { swapChains = swapChains.filter { $0.discard == false } } - for swapChain in swapChains { - guard let renderTarget = swapChain.renderTarget, let drawable = swapChain.layer.nextDrawable() else { - continue - } - - guard renderTarget.texture.width == drawable.texture.width, - renderTarget.texture.height == drawable.texture.height, - renderTarget.texture.pixelFormat == drawable.texture.pixelFormat + autoreleasepool { + guard let commandBuffer = commandQueue.makeCommandBuffer(), + let encoder = commandBuffer.makeBlitCommandEncoder() else { - continue + return } - autoreleasepool { + var drawablesToPresent: CAMetalDrawable = + for swapChain in swapChains { + guard let renderTarget = swapChain.renderTarget, let drawable = swapChain.layer.nextDrawable() else { + continue + } + + guard renderTarget.texture.width == drawable.texture.width, + renderTarget.texture.height == drawable.texture.height, + renderTarget.texture.pixelFormat == drawable.texture.pixelFormat + else { + continue + } + encoder.waitForFence(swapChain.fence) encoder.copy(from: renderTarget.texture, to: drawable.texture) + drawablesToPresent.append(drawable) + } + encoder.endEncoding() + + for drawable in drawablesToPresent { commandBuffer.present(drawable) } - } - encoder.endEncoding() - commandBuffer.commit() + commandBuffer.commit() + } } /// Simulates an explicit "clear" command commonly used in OpenGL or Direct3D11 implementations.
View file
obs-studio-32.2.2.tar.xz/libobs-opengl/gl-cocoa.m -> obs-studio-33.0.0.tar.xz/libobs-opengl/gl-cocoa.m
Changed
@@ -495,6 +495,12 @@ texture_type = GL_UNSIGNED_INT_8_8_8_8_REV; break; } + case kCVPixelFormatType_64RGBAHalf: { + color_format = GL_RGBA; + internal_format = GL_RGBA_FLOAT16_APPLE; + texture_type = GL_HALF_APPLE; + break; + } default: blog(LOG_ERROR, "Unexpected pixel format: %d (%c%c%c%c)", pixelFormat, pixelFormat >> 24, pixelFormat >> 16, pixelFormat >> 8, pixelFormat); @@ -579,6 +585,7 @@ switch (pixelFormat) { case kCVPixelFormatType_ARGB2101010LEPacked: case kCVPixelFormatType_32BGRA: + case kCVPixelFormatType_64RGBAHalf: break; case 0: blog(LOG_ERROR, "Invalid IOSurface Buffer");
View file
obs-studio-32.2.2.tar.xz/libobs/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/libobs/CMakeLists.txt
Changed
@@ -7,10 +7,12 @@ return() endif() +include(cmake/obs-core-modules.cmake) + find_package(SIMDe REQUIRED) find_package(Threads REQUIRED) -find_package(FFmpeg 6.1 REQUIRED avformat avutil swscale swresample OPTIONAL_COMPONENTS avcodec) +find_package(FFmpeg 8.0 REQUIRED avformat avutil swscale swresample OPTIONAL_COMPONENTS avcodec) find_package(ZLIB REQUIRED) find_package(Uthash REQUIRED) @@ -37,6 +39,10 @@ obs-avc.h obs-canvas.c obs-config.h + $<$<PLATFORM_ID:Darwin>:obs-core-modules-loader-mac.m> + $<$<PLATFORM_ID:Windows>:obs-core-modules-loader-win.c> + $<$<PLATFORM_ID:Linux,FreeBSD,OpenBSD>:obs-core-modules-loader-nix.c> + obs-core-modules-loader.h obs-data.c obs-data.h obs-defs.h @@ -190,8 +196,10 @@ graphics/image-file.c graphics/image-file.h graphics/input.h - graphics/libnsgif/libnsgif.c - graphics/libnsgif/libnsgif.h + graphics/libnsgif/gif.c + graphics/libnsgif/lzw.c + graphics/libnsgif/lzw.h + graphics/libnsgif/nsgif.h graphics/math-defs.h graphics/math-extra.c graphics/math-extra.h @@ -240,6 +248,7 @@ libobs PRIVATE OBS::caption + OBS::libobs-core-modules OBS::libobs-version FFmpeg::avcodec FFmpeg::avformat @@ -282,7 +291,7 @@ graphics/graphics.h graphics/image-file.h graphics/input.h - graphics/libnsgif/libnsgif.h + graphics/libnsgif/nsgif.h graphics/math-defs.h graphics/math-extra.h graphics/matrix3.h
View file
obs-studio-33.0.0.tar.xz/libobs/cmake/obs-core-modules.cmake
Added
@@ -0,0 +1,8 @@ +add_library(libobs-core-modules OBJECT) +add_library(OBS::libobs-core-modules ALIAS libobs-core-modules) + +target_sources(libobs-core-modules PRIVATE obs-core-modules.c PUBLIC obs-core-modules.h) + +target_include_directories(libobs-core-modules PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>") + +set_target_properties(libobs-core-modules PROPERTIES FOLDER core POSITION_INDEPENDENT_CODE TRUE)
View file
obs-studio-32.2.2.tar.xz/libobs/cmake/os-windows.cmake -> obs-studio-33.0.0.tar.xz/libobs/cmake/os-windows.cmake
Changed
@@ -67,6 +67,14 @@ PROPERTIES COMPILE_DEFINITIONS OBS_VERSION="${OBS_VERSION_CANONICAL}" ) +set_source_files_properties( + graphics/libnsgif/gif.c + graphics/libnsgif/lzw.c + graphics/libnsgif/lzw.h + graphics/libnsgif/nsgif.h + PROPERTIES COMPILE_OPTIONS "/wd4244;/wd4267" +) + target_link_libraries( libobs PRIVATE Avrt Dwmapi Dxgi winmm Rpcrt4 OBS::obfuscate OBS::winhandle OBS::COMutils
View file
obs-studio-32.2.2.tar.xz/libobs/graphics/image-file.c -> obs-studio-33.0.0.tar.xz/libobs/graphics/image-file.c
Changed
@@ -20,9 +20,23 @@ #include "../util/platform.h" #include "../util/dstr.h" #include "vec4.h" +#include "libnsgif/nsgif.h" #define blog(level, format, ...) blog(level, "%s: " format, __FUNCTION__, __VA_ARGS__) +struct gs_image_file_internal { + nsgif_t *gif; + const nsgif_info_t *gif_info; + const uint8_t *gif_frame_image; + nsgif_bitmap_cb_vt bitmap_callbacks; + + uint8_t *gif_data; + uint8_t **animation_frame_cache; + uint8_t *animation_frame_data; + + int last_decoded_frame; +}; + static void *bi_def_bitmap_create(int width, int height) { return bmalloc((size_t)4 * width * height); @@ -55,37 +69,40 @@ UNUSED_PARAMETER(bitmap); } -static inline int get_full_decoded_gif_size(gs_image_file_t *image) +static inline int get_full_decoded_gif_size(gs_image_file_ex_t *image) { - return image->gif.width * image->gif.height * 4 * image->gif.frame_count; + return image->internal->gif_info->width * image->internal->gif_info->height * 4 * + image->internal->gif_info->frame_count; } -static inline void *alloc_mem(gs_image_file_t *image, uint64_t *mem_usage, size_t size) +static inline void *alloc_mem(gs_image_file_ex_t *image, uint64_t *mem_usage, size_t size) { UNUSED_PARAMETER(image); if (mem_usage) *mem_usage += size; + return bzalloc(size); } -static bool init_animated_gif(gs_image_file_t *image, const char *path, uint64_t *mem_usage, +static bool init_animated_gif(gs_image_file_ex_t *image, const char *path, uint64_t *mem_usage, enum gs_image_alpha_mode alpha_mode) { bool is_animated_gif = true; - gif_result result; + nsgif_error result; uint64_t max_size; size_t size, size_read; FILE *file; + nsgif_bitmap_t *bitmap; - image->bitmap_callbacks.bitmap_create = bi_def_bitmap_create; - image->bitmap_callbacks.bitmap_destroy = bi_def_bitmap_destroy; - image->bitmap_callbacks.bitmap_get_buffer = bi_def_bitmap_get_buffer; - image->bitmap_callbacks.bitmap_modified = bi_def_bitmap_modified; - image->bitmap_callbacks.bitmap_set_opaque = bi_def_bitmap_set_opaque; - image->bitmap_callbacks.bitmap_test_opaque = bi_def_bitmap_test_opaque; + image->internal->bitmap_callbacks.create = bi_def_bitmap_create; + image->internal->bitmap_callbacks.destroy = bi_def_bitmap_destroy; + image->internal->bitmap_callbacks.get_buffer = bi_def_bitmap_get_buffer; + image->internal->bitmap_callbacks.modified = bi_def_bitmap_modified; + image->internal->bitmap_callbacks.set_opaque = bi_def_bitmap_set_opaque; + image->internal->bitmap_callbacks.test_opaque = bi_def_bitmap_test_opaque; - gif_create(&image->gif, &image->bitmap_callbacks); + nsgif_create(&image->internal->bitmap_callbacks, NSGIF_BITMAP_FMT_R8G8B8A8, &image->internal->gif); file = os_fopen(path, "rb"); if (!file) { @@ -97,15 +114,15 @@ size = (size_t)os_ftelli64(file); fseek(file, 0, SEEK_SET); - image->gif_data = bmalloc(size); - size_read = fread(image->gif_data, 1, size, file); + image->internal->gif_data = bmalloc(size); + size_read = fread(image->internal->gif_data, 1, size, file); if (size_read != size) { blog(LOG_WARNING, "Failed to fully read gif file '%s'.", path); goto fail; } do { - result = gif_initialise(&image->gif, size, image->gif_data); + result = nsgif_data_scan(image->internal->gif, size, image->internal->gif_data); if (result < 0) { blog(LOG_WARNING, "Failed to initialize gif '%s', " @@ -113,39 +130,45 @@ path); goto fail; } - } while (result != GIF_OK); + } while (result != NSGIF_OK); + + nsgif_data_complete(image->internal->gif); + + image->internal->gif_info = nsgif_get_info(image->internal->gif); - if (image->gif.width > 4096 || image->gif.height > 4096) { - blog(LOG_WARNING, "Bad texture dimensions (%dx%d) in '%s'", image->gif.width, image->gif.height, path); + if (image->internal->gif_info->width > 4096 || image->internal->gif_info->height > 4096) { + blog(LOG_WARNING, "Bad texture dimensions (%dx%d) in '%s'", image->internal->gif_info->width, + image->internal->gif_info->height, path); goto fail; } - max_size = (uint64_t)image->gif.width * (uint64_t)image->gif.height * (uint64_t)image->gif.frame_count * 4LLU; + max_size = (uint64_t)image->internal->gif_info->width * (uint64_t)image->internal->gif_info->height * + (uint64_t)image->internal->gif_info->frame_count * 4LLU; if ((uint64_t)get_full_decoded_gif_size(image) != max_size) { blog(LOG_WARNING, "Gif '%s' overflowed maximum pointer size", path); goto fail; } - image->is_animated_gif = (image->gif.frame_count > 1 && result >= 0); + image->is_animated_gif = (image->internal->gif_info->frame_count > 1 && result >= 0); if (image->is_animated_gif) { - gif_decode_frame(&image->gif, 0); + nsgif_frame_decode(image->internal->gif, 0, &bitmap); - image->animation_frame_cache = alloc_mem(image, mem_usage, image->gif.frame_count * sizeof(uint8_t *)); - image->animation_frame_data = alloc_mem(image, mem_usage, get_full_decoded_gif_size(image)); + image->internal->animation_frame_cache = + alloc_mem(image, mem_usage, image->internal->gif_info->frame_count * sizeof(uint8_t *)); + image->internal->animation_frame_data = alloc_mem(image, mem_usage, get_full_decoded_gif_size(image)); - for (unsigned int i = 0; i < image->gif.frame_count; i++) { - if (gif_decode_frame(&image->gif, i) != GIF_OK) - blog(LOG_WARNING, - "Couldn't decode frame %u " - "of '%s'", - i, path); + for (unsigned int i = 0; i < image->internal->gif_info->frame_count; i++) { + if (nsgif_frame_decode(image->internal->gif, i, &bitmap) != NSGIF_OK) + blog(LOG_WARNING, "Couldn't decode frame %u of '%s'", i, path); } - gif_decode_frame(&image->gif, 0); + nsgif_frame_decode(image->internal->gif, 0, &bitmap); - image->cx = (uint32_t)image->gif.width; - image->cy = (uint32_t)image->gif.height; + image->internal->gif_frame_image = (const uint8_t *)bitmap; + + image->cx = (uint32_t)image->internal->gif_info->width; + image->cy = (uint32_t)image->internal->gif_info->height; image->format = GS_RGBA; if (mem_usage) { @@ -154,14 +177,14 @@ } if (alpha_mode == GS_IMAGE_ALPHA_PREMULTIPLY_SRGB) { - gs_premultiply_xyza_srgb_loop(image->gif.frame_image, (size_t)image->cx * image->cy); + gs_premultiply_xyza_srgb_loop((uint8_t *)bitmap, (size_t)image->cx * image->cy); } else if (alpha_mode == GS_IMAGE_ALPHA_PREMULTIPLY) { - gs_premultiply_xyza_loop(image->gif.frame_image, (size_t)image->cx * image->cy); + gs_premultiply_xyza_loop((uint8_t *)bitmap, (size_t)image->cx * image->cy); } } else { - gif_finalise(&image->gif); - bfree(image->gif_data); - image->gif_data = NULL; + nsgif_destroy(image->internal->gif); + bfree(image->internal->gif_data); + image->internal->gif_data = NULL; is_animated_gif = false; goto not_animated; } @@ -170,7 +193,8 @@ fail: if (!image->loaded) - gs_image_file_free(image); + gs_image_file_ex_free(image); + not_animated: if (file) fclose(file); @@ -178,8 +202,8 @@ return is_animated_gif; } -static void gs_image_file_init_internal(gs_image_file_t *image, const char *file, uint64_t *mem_usage, - enum gs_color_space *space, enum gs_image_alpha_mode alpha_mode) +static void gs_image_file_ex_init_internal(gs_image_file_ex_t *image, const char *file, uint64_t *mem_usage, + enum gs_color_space *space, enum gs_image_alpha_mode alpha_mode) { size_t len; @@ -191,6 +215,8 @@ if (!file) return; + image->internal = bzalloc(sizeof(struct gs_image_file_internal)); + len = strlen(file); if (len > 4 && astrcmpi(file + len - 4, ".gif") == 0) { @@ -209,64 +235,50 @@ image->loaded = !!image->texture_data; if (!image->loaded) { blog(LOG_WARNING, "Failed to load file '%s'", file); - gs_image_file_free(image); + gs_image_file_ex_free(image); } } -void gs_image_file_init(gs_image_file_t *image, const char *file) +void gs_image_file_ex_init(gs_image_file_ex_t *image, const char *file, enum gs_image_alpha_mode alpha_mode) { enum gs_color_space unused; - gs_image_file_init_internal(image, file, NULL, &unused, GS_IMAGE_ALPHA_STRAIGHT); + gs_image_file_ex_init_internal(image, file, NULL, &unused, alpha_mode); } -void gs_image_file_free(gs_image_file_t *image) +void gs_image_file_ex_free(gs_image_file_ex_t *image) { if (!image) return; if (image->loaded) { - if (image->is_animated_gif) { - gif_finalise(&image->gif); - bfree(image->animation_frame_cache); - bfree(image->animation_frame_data); + if (image->is_animated_gif && image->internal) { + nsgif_destroy(image->internal->gif); + bfree(image->internal->animation_frame_cache); + bfree(image->internal->animation_frame_data); } gs_texture_destroy(image->texture); } bfree(image->texture_data); - bfree(image->gif_data); + if (image->internal) { + bfree(image->internal->gif_data); + bfree(image->internal); + } memset(image, 0, sizeof(*image)); } -void gs_image_file2_init(gs_image_file2_t *if2, const char *file) -{ - enum gs_color_space unused; - gs_image_file_init_internal(&if2->image, file, &if2->mem_usage, &unused, GS_IMAGE_ALPHA_STRAIGHT); -} - -void gs_image_file3_init(gs_image_file3_t *if3, const char *file, enum gs_image_alpha_mode alpha_mode) -{ - enum gs_color_space unused; - gs_image_file_init_internal(&if3->image2.image, file, &if3->image2.mem_usage, &unused, alpha_mode); - if3->alpha_mode = alpha_mode; -} - -void gs_image_file4_init(gs_image_file4_t *if4, const char *file, enum gs_image_alpha_mode alpha_mode) -{ - gs_image_file_init_internal(&if4->image3.image2.image, file, &if4->image3.image2.mem_usage, &if4->space, - alpha_mode); - if4->image3.alpha_mode = alpha_mode; -} - -void gs_image_file_init_texture(gs_image_file_t *image) +void gs_image_file_ex_init_texture(gs_image_file_ex_t *image) { if (!image->loaded) return; + if (!image->internal) + image->internal = bzalloc(sizeof(struct gs_image_file_internal)); + if (image->is_animated_gif) { image->texture = gs_texture_create(image->cx, image->cy, image->format, 1, - (const uint8_t **)&image->gif.frame_image, GS_DYNAMIC); + (const uint8_t **)&image->internal->gif_frame_image, GS_DYNAMIC); } else { image->texture = gs_texture_create(image->cx, image->cy, image->format, 1, @@ -276,15 +288,17 @@ } } -static inline uint64_t get_time(gs_image_file_t *image, int i) +static inline uint64_t get_time(gs_image_file_ex_t *image, int i) { - uint64_t val = (uint64_t)image->gif.framesi.frame_delay * 10000000ULL; + const nsgif_frame_info_t *gif_frame_info = nsgif_get_frame_info(image->internal->gif, i); + uint64_t val = (uint64_t)gif_frame_info->delay * 10000000ULL; if (!val) val = 100000000; + return val; } -static inline int calculate_new_frame(gs_image_file_t *image, uint64_t elapsed_time_ns, int loops) +static inline int calculate_new_frame(gs_image_file_ex_t *image, uint64_t elapsed_time_ns, int loops) { int new_frame = image->cur_frame; @@ -295,7 +309,7 @@ break; image->cur_time -= t; - if ((unsigned int)++new_frame == image->gif.frame_count) { + if ((unsigned int)++new_frame == image->internal->gif_info->frame_count) { if (!loops || ++image->cur_loop < loops) { new_frame = 0; } else if (image->cur_loop == loops) { @@ -308,50 +322,55 @@ return new_frame; } -static void decode_new_frame(gs_image_file_t *image, int new_frame, enum gs_image_alpha_mode alpha_mode) +static void decode_new_frame(gs_image_file_ex_t *image, int new_frame, enum gs_image_alpha_mode alpha_mode) { - if (!image->animation_frame_cachenew_frame) { + if (!image->internal->animation_frame_cachenew_frame) { int last_frame; + nsgif_bitmap_t *bitmap; /* if looped, decode frame 0 */ - last_frame = (new_frame < image->last_decoded_frame) ? 0 : image->last_decoded_frame + 1; + last_frame = + (new_frame < image->internal->last_decoded_frame) ? 0 : image->internal->last_decoded_frame + 1; /* decode missed frames */ for (int i = last_frame; i < new_frame; i++) { - if (gif_decode_frame(&image->gif, i) != GIF_OK) + if (nsgif_frame_decode(image->internal->gif, i, &bitmap) != NSGIF_OK) return; } /* decode actual desired frame */ - if (gif_decode_frame(&image->gif, new_frame) == GIF_OK) { - const size_t area = (size_t)image->gif.width * image->gif.height; + if (nsgif_frame_decode(image->internal->gif, new_frame, &bitmap) == NSGIF_OK) { + const size_t area = + (size_t)image->internal->gif_info->width * image->internal->gif_info->height; size_t pos = new_frame * area * 4; - image->animation_frame_cachenew_frame = image->animation_frame_data + pos; + image->internal->animation_frame_cachenew_frame = image->internal->animation_frame_data + pos; if (alpha_mode == GS_IMAGE_ALPHA_PREMULTIPLY_SRGB) { - gs_premultiply_xyza_srgb_loop(image->gif.frame_image, area); + gs_premultiply_xyza_srgb_loop((uint8_t *)bitmap, area); } else if (alpha_mode == GS_IMAGE_ALPHA_PREMULTIPLY) { - gs_premultiply_xyza_loop(image->gif.frame_image, area); + gs_premultiply_xyza_loop((uint8_t *)bitmap, area); } - memcpy(image->animation_frame_cachenew_frame, image->gif.frame_image, area * 4); + image->internal->gif_frame_image = (const uint8_t *)bitmap; + + memcpy(image->internal->animation_frame_cachenew_frame, (const uint8_t *)bitmap, area * 4); - image->last_decoded_frame = new_frame; + image->internal->last_decoded_frame = new_frame; } } image->cur_frame = new_frame; } -static bool gs_image_file_tick_internal(gs_image_file_t *image, uint64_t elapsed_time_ns, - enum gs_image_alpha_mode alpha_mode) +static bool gs_image_file_ex_tick_internal(gs_image_file_ex_t *image, uint64_t elapsed_time_ns, + enum gs_image_alpha_mode alpha_mode) { int loops; - if (!image->is_animated_gif || !image->loaded) + if (!image->is_animated_gif || !image->loaded || !image->internal) return false; - loops = image->gif.loop_count; + loops = image->internal->gif_info->loop_max; if (loops >= 0xFFFF) loops = 0; @@ -367,54 +386,24 @@ return false; } -bool gs_image_file_tick(gs_image_file_t *image, uint64_t elapsed_time_ns) -{ - return gs_image_file_tick_internal(image, elapsed_time_ns, false); -} - -bool gs_image_file2_tick(gs_image_file2_t *if2, uint64_t elapsed_time_ns) +bool gs_image_file_ex_tick(gs_image_file_ex_t *image, uint64_t elapsed_time_ns) { - return gs_image_file_tick_internal(&if2->image, elapsed_time_ns, false); + return gs_image_file_ex_tick_internal(image, elapsed_time_ns, false); } -bool gs_image_file3_tick(gs_image_file3_t *if3, uint64_t elapsed_time_ns) +static void gs_image_file_ex_update_texture_internal(gs_image_file_ex_t *image, enum gs_image_alpha_mode alpha_mode) { - return gs_image_file_tick_internal(&if3->image2.image, elapsed_time_ns, if3->alpha_mode); -} - -bool gs_image_file4_tick(gs_image_file4_t *if4, uint64_t elapsed_time_ns) -{ - return gs_image_file_tick_internal(&if4->image3.image2.image, elapsed_time_ns, if4->image3.alpha_mode); -} - -static void gs_image_file_update_texture_internal(gs_image_file_t *image, enum gs_image_alpha_mode alpha_mode) -{ - if (!image->is_animated_gif || !image->loaded) + if (!image->is_animated_gif || !image->loaded || !image->internal) return; - if (!image->animation_frame_cacheimage->cur_frame) + if (!image->internal->animation_frame_cacheimage->cur_frame) decode_new_frame(image, image->cur_frame, alpha_mode); - gs_texture_set_image(image->texture, image->animation_frame_cacheimage->cur_frame, image->gif.width * 4, - false); -} - -void gs_image_file_update_texture(gs_image_file_t *image) -{ - gs_image_file_update_texture_internal(image, false); -} - -void gs_image_file2_update_texture(gs_image_file2_t *if2) -{ - gs_image_file_update_texture_internal(&if2->image, false); -} - -void gs_image_file3_update_texture(gs_image_file3_t *if3) -{ - gs_image_file_update_texture_internal(&if3->image2.image, if3->alpha_mode); + gs_texture_set_image(image->texture, image->internal->animation_frame_cacheimage->cur_frame, + image->internal->gif_info->width * 4, false); } -void gs_image_file4_update_texture(gs_image_file4_t *if4) +void gs_image_file_ex_update_texture(gs_image_file_ex_t *image) { - gs_image_file_update_texture_internal(&if4->image3.image2.image, if4->image3.alpha_mode); + gs_image_file_ex_update_texture_internal(image, false); }
View file
obs-studio-32.2.2.tar.xz/libobs/graphics/image-file.h -> obs-studio-33.0.0.tar.xz/libobs/graphics/image-file.h
Changed
@@ -18,13 +18,12 @@ #pragma once #include "graphics.h" -#include "libnsgif/libnsgif.h" #ifdef __cplusplus extern "C" { #endif -struct gs_image_file { +struct gs_image_file_ex { gs_texture_t *texture; enum gs_color_format format; uint32_t cx; @@ -33,91 +32,26 @@ bool frame_updated; bool loaded; - gif_animation gif; - uint8_t *gif_data; - uint8_t **animation_frame_cache; - uint8_t *animation_frame_data; + struct gs_image_file_internal *internal; + uint64_t cur_time; int cur_frame; int cur_loop; - int last_decoded_frame; uint8_t *texture_data; - gif_bitmap_callback_vt bitmap_callbacks; -}; - -struct gs_image_file2 { - struct gs_image_file image; uint64_t mem_usage; -}; - -struct gs_image_file3 { - struct gs_image_file2 image2; enum gs_image_alpha_mode alpha_mode; -}; - -struct gs_image_file4 { - struct gs_image_file3 image3; enum gs_color_space space; }; -typedef struct gs_image_file gs_image_file_t; -typedef struct gs_image_file2 gs_image_file2_t; -typedef struct gs_image_file3 gs_image_file3_t; -typedef struct gs_image_file4 gs_image_file4_t; - -EXPORT void gs_image_file_init(gs_image_file_t *image, const char *file); -EXPORT void gs_image_file_free(gs_image_file_t *image); - -EXPORT void gs_image_file_init_texture(gs_image_file_t *image); -EXPORT bool gs_image_file_tick(gs_image_file_t *image, uint64_t elapsed_time_ns); -EXPORT void gs_image_file_update_texture(gs_image_file_t *image); - -EXPORT void gs_image_file2_init(gs_image_file2_t *if2, const char *file); - -EXPORT bool gs_image_file2_tick(gs_image_file2_t *if2, uint64_t elapsed_time_ns); -EXPORT void gs_image_file2_update_texture(gs_image_file2_t *if2); - -EXPORT void gs_image_file3_init(gs_image_file3_t *if3, const char *file, enum gs_image_alpha_mode alpha_mode); - -EXPORT bool gs_image_file3_tick(gs_image_file3_t *if3, uint64_t elapsed_time_ns); -EXPORT void gs_image_file3_update_texture(gs_image_file3_t *if3); +typedef struct gs_image_file_ex gs_image_file_ex_t; -EXPORT void gs_image_file4_init(gs_image_file4_t *if4, const char *file, enum gs_image_alpha_mode alpha_mode); +EXPORT void gs_image_file_ex_init(gs_image_file_ex_t *image, const char *file, enum gs_image_alpha_mode alpha_mode); +EXPORT void gs_image_file_ex_free(gs_image_file_ex_t *image); -EXPORT bool gs_image_file4_tick(gs_image_file4_t *if4, uint64_t elapsed_time_ns); -EXPORT void gs_image_file4_update_texture(gs_image_file4_t *if4); - -static inline void gs_image_file2_free(gs_image_file2_t *if2) -{ - gs_image_file_free(&if2->image); - if2->mem_usage = 0; -} - -static inline void gs_image_file2_init_texture(gs_image_file2_t *if2) -{ - gs_image_file_init_texture(&if2->image); -} - -static inline void gs_image_file3_free(gs_image_file3_t *if3) -{ - gs_image_file2_free(&if3->image2); -} - -static inline void gs_image_file3_init_texture(gs_image_file3_t *if3) -{ - gs_image_file2_init_texture(&if3->image2); -} - -static inline void gs_image_file4_free(gs_image_file4_t *if4) -{ - gs_image_file3_free(&if4->image3); -} - -static inline void gs_image_file4_init_texture(gs_image_file4_t *if4) -{ - gs_image_file3_init_texture(&if4->image3); -} +EXPORT void gs_image_file_ex_init_texture(gs_image_file_ex_t *image); +EXPORT bool gs_image_file_ex_tick(gs_image_file_ex_t *image, uint64_t elapsed_time_ns); +EXPORT void gs_image_file_ex_update_texture(gs_image_file_ex_t *image); #ifdef __cplusplus }
View file
obs-studio-33.0.0.tar.xz/libobs/graphics/libnsgif/gif.c
Added
@@ -0,0 +1,2076 @@ +/* + * Copyright 2004 Richard Wilson <richard.wilson@netsurf-browser.org> + * Copyright 2008 Sean Fox <dyntryx@gmail.com> + * Copyright 2013-2022 Michael Drake <tlsa@netsurf-browser.org> + * + * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ + * Licenced under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + */ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + +#include "lzw.h" +#include "nsgif.h" + +/** Default minimum allowable frame delay in cs. */ +#define NSGIF_FRAME_DELAY_MIN 2 + +/** + * Default frame delay to apply. + * + * Used when a frame delay lower than the minimum is requested. + */ +#define NSGIF_FRAME_DELAY_DEFAULT 10 + +/** GIF frame data */ +typedef struct nsgif_frame { + struct nsgif_frame_info info; + + /** offset (in bytes) to the GIF frame data */ + size_t frame_offset; + /** whether the frame has previously been decoded. */ + bool decoded; + /** whether the frame is totally opaque */ + bool opaque; + /** whether a full image redraw is required */ + bool redraw_required; + + /** Amount of LZW data found in scan */ + uint32_t lzw_data_length; + + /** the index designating a transparent pixel */ + uint32_t transparency_index; + + /** offset to frame colour table */ + uint32_t colour_table_offset; + + /* Frame flags */ + uint32_t flags; +} nsgif_frame; + +/** Pixel format: colour component order. */ +struct nsgif_colour_layout { + uint8_t r; /**< Byte offset within pixel to red component. */ + uint8_t g; /**< Byte offset within pixel to green component. */ + uint8_t b; /**< Byte offset within pixel to blue component. */ + uint8_t a; /**< Byte offset within pixel to alpha component. */ +}; + +/** GIF animation data */ +struct nsgif { + struct nsgif_info info; + + /** LZW decode context */ + void *lzw_ctx; + /** callbacks for bitmap functions */ + nsgif_bitmap_cb_vt bitmap; + /** decoded frames */ + nsgif_frame *frames; + /** current frame */ + uint32_t frame; + /** current frame decoded to bitmap */ + uint32_t decoded_frame; + + /** currently decoded image; stored as bitmap from bitmap_create callback */ + nsgif_bitmap_t *frame_image; + /** Row span of frame_image in pixels. */ + uint32_t rowspan; + + /** Minimum allowable frame delay. */ + uint16_t delay_min; + + /** Frame delay to apply when delay is less than \ref delay_min. */ + uint16_t delay_default; + + /** number of animation loops so far */ + int loop_count; + + /** number of frames partially decoded */ + uint32_t frame_count_partial; + + /** + * Whether all the GIF data has been supplied, or if there may be + * more to come. + */ + bool data_complete; + + /** pointer to GIF data */ + const uint8_t *buf; + /** current index into GIF data */ + size_t buf_pos; + /** total number of bytes of GIF data available */ + size_t buf_len; + + /** current number of frame holders */ + uint32_t frame_holders; + /** background index */ + uint32_t bg_index; + /** image aspect ratio (ignored) */ + uint32_t aspect_ratio; + /** size of global colour table (in entries) */ + uint32_t colour_table_size; + + /** current colour table */ + uint32_t *colour_table; + /** Client's colour component order. */ + struct nsgif_colour_layout colour_layout; + /** global colour table */ + uint32_t global_colour_tableNSGIF_MAX_COLOURS; + /** local colour table */ + uint32_t local_colour_tableNSGIF_MAX_COLOURS; + + /** previous frame for NSGIF_FRAME_RESTORE */ + void *prev_frame; + /** previous frame index */ + uint32_t prev_index; +}; + +/** + * Helper macro to get number of elements in an array. + * + * \paramin _a Array to count elements of. + * \return NUlber of elements in array. + */ +#define NSGIF_ARRAY_LEN(_a) ((sizeof(_a)) / (sizeof(*_a))) + +/** + * + * \file + * \brief GIF image decoder + * + * The GIF format is thoroughly documented; a full description can be found at + * http://www.w3.org/Graphics/GIF/spec-gif89a.txt + * + * \todo Plain text and comment extensions should be implemented. + */ + +/** Internal flag that the colour table needs to be processed */ +#define NSGIF_PROCESS_COLOURS 0xaa000000 + +/** Internal flag that a frame is invalid/unprocessed */ +#define NSGIF_FRAME_INVALID UINT32_MAX + +/** Transparent colour */ +#define NSGIF_TRANSPARENT_COLOUR 0x00 + +/** No transparency */ +#define NSGIF_NO_TRANSPARENCY (0xFFFFFFFFu) + +/* GIF Flags */ +#define NSGIF_COLOUR_TABLE_MASK 0x80 +#define NSGIF_COLOUR_TABLE_SIZE_MASK 0x07 +#define NSGIF_BLOCK_TERMINATOR 0x00 +#define NSGIF_TRAILER 0x3b + +/** + * Convert an LZW result code to equivalent GIF result code. + * + * \paramin l_res LZW response code. + * \return GIF result code. + */ +static nsgif_error nsgif__error_from_lzw(lzw_result l_res) +{ + static const nsgif_error g_res = { + LZW_OK = NSGIF_OK, + LZW_NO_MEM = NSGIF_ERR_OOM, + LZW_OK_EOD = NSGIF_ERR_END_OF_DATA, + LZW_NO_DATA = NSGIF_ERR_END_OF_DATA, + LZW_EOI_CODE = NSGIF_ERR_DATA_FRAME, + LZW_BAD_ICODE = NSGIF_ERR_DATA_FRAME, + LZW_BAD_CODE = NSGIF_ERR_DATA_FRAME, + }; + assert(l_res != LZW_BAD_PARAM); + assert(l_res != LZW_NO_COLOUR); + return g_resl_res; +} + +/** + * Updates the sprite memory size + * + * \param gif The animation context + * \param width The width of the sprite + * \param height The height of the sprite + * \return NSGIF_ERR_OOM for a memory error NSGIF_OK for success + */ +static nsgif_error nsgif__initialise_sprite( + struct nsgif *gif, + uint32_t width, + uint32_t height) +{ + /* Already allocated? */ + if (gif->frame_image) { + return NSGIF_OK; + } + + assert(gif->bitmap.create); + gif->frame_image = gif->bitmap.create(width, height); + if (gif->frame_image == NULL) { + return NSGIF_ERR_OOM; + } + + return NSGIF_OK; +} + +/** + * Helper to get the rendering bitmap for a gif. + * + * \paramin gif The gif object we're decoding. + * \return Client pixel buffer for rendering into. + */ +static inline uint32_t* nsgif__bitmap_get( + struct nsgif *gif) +{ + nsgif_error ret; + + /* Make sure we have a buffer to decode to. */ + ret = nsgif__initialise_sprite(gif, gif->info.width, gif->info.height); + if (ret != NSGIF_OK) { + return NULL; + } + + gif->rowspan = gif->info.width; + if (gif->bitmap.get_rowspan) { + gif->rowspan = gif->bitmap.get_rowspan(gif->frame_image); + } + + /* Get the frame data */ + assert(gif->bitmap.get_buffer); + return (void *)gif->bitmap.get_buffer(gif->frame_image); +} + +/** + * Helper to tell the client that their bitmap was modified. + * + * \paramin gif The gif object we're decoding. + */ +static inline void nsgif__bitmap_modified( + const struct nsgif *gif) +{ + if (gif->bitmap.modified) { + gif->bitmap.modified(gif->frame_image); + } +} + +/** + * Helper to tell the client that whether the bitmap is opaque. + * + * \paramin gif The gif object we're decoding. + * \paramin frame The frame that has been decoded. + */ +static inline void nsgif__bitmap_set_opaque( + const struct nsgif *gif, + const struct nsgif_frame *frame) +{ + if (gif->bitmap.set_opaque) { + gif->bitmap.set_opaque( + gif->frame_image, frame->opaque); + } +} + +/** + * Helper to get the client to determine if the bitmap is opaque. + * + * \todo: We don't really need to get the client to do this for us. + * + * \paramin gif The gif object we're decoding. + * \return true if the bitmap is opaque, false otherwise. + */ +static inline bool nsgif__bitmap_get_opaque( + const struct nsgif *gif) +{ + if (gif->bitmap.test_opaque) { + return gif->bitmap.test_opaque( + gif->frame_image); + } + + return false; +} + +static void nsgif__record_frame( + struct nsgif *gif, + const uint32_t *bitmap) +{ + size_t pixel_bytes = sizeof(*bitmap); + size_t height = gif->info.height; + size_t width = gif->info.width; + uint32_t *prev_frame; + + if (gif->decoded_frame == NSGIF_FRAME_INVALID || + gif->decoded_frame == gif->prev_index) { + /* No frame to copy, or already have this frame recorded. */ + return; + } + + bitmap = nsgif__bitmap_get(gif); + if (bitmap == NULL) { + return; + } + + if (gif->prev_frame == NULL) { + prev_frame = realloc(gif->prev_frame, + width * height * pixel_bytes); + if (prev_frame == NULL) { + return; + } + } else { + prev_frame = gif->prev_frame; + } + + memcpy(prev_frame, bitmap, width * height * pixel_bytes); + + gif->prev_frame = prev_frame; + gif->prev_index = gif->decoded_frame; +} + +static nsgif_error nsgif__recover_frame( + const struct nsgif *gif, + uint32_t *bitmap) +{ + const uint32_t *prev_frame = gif->prev_frame; + size_t pixel_bytes = sizeof(*bitmap); + size_t height = gif->info.height; + size_t width = gif->info.width; + + memcpy(bitmap, prev_frame, height * width * pixel_bytes); + + return NSGIF_OK; +} + +/** + * Get the next line for GIF decode. + * + * Note that the step size must be initialised to 24 at the start of the frame + * (when y == 0). This is because of the first two passes of the frame have + * the same step size of 8, and the step size is used to determine the current + * pass. + * + * \paramin height Frame height in pixels. + * \paramin,out y Current row, starting from 0, updated on exit. + * \paramin,out step Current step starting with 24, updated on exit. + * \return true if there is a row to process, false at the end of the frame. + */ +static inline bool nsgif__deinterlace(uint32_t height, uint32_t *y, uint8_t *step) +{ + *y += *step & 0xf; + + if (*y < height) return true; + + switch (*step) { + case 24: *y = 4; *step = 8; if (*y < height) return true; + /* Fall through. */ + case 8: *y = 2; *step = 4; if (*y < height) return true; + /* Fall through. */ + case 4: *y = 1; *step = 2; if (*y < height) return true; + /* Fall through. */ + default: + break; + } + + return false; +} + +/** + * Get the next line for GIF decode. + * + * \paramin interlace Non-zero if the frame is not interlaced. + * \paramin height Frame height in pixels. + * \paramin,out y Current row, starting from 0, updated on exit. + * \paramin,out step Current step starting with 24, updated on exit. + * \return true if there is a row to process, false at the end of the frame. + */ +static inline bool nsgif__next_row(uint32_t interlace, + uint32_t height, uint32_t *y, uint8_t *step) +{ + if (!interlace) { + return (++*y != height); + } else { + return nsgif__deinterlace(height, y, step); + } +} + +/** + * Get any frame clip adjustment for the image extent. + * + * \paramin frame_off Frame's X or Y offset. + * \paramin frame_dim Frame width or height. + * \paramin image_ext Image width or height constraint. + * \return the amount the frame needs to be clipped to fit the image in given + * dimension. + */ +static inline uint32_t gif__clip( + uint32_t frame_off, + uint32_t frame_dim, + uint32_t image_ext) +{ + uint32_t frame_ext = frame_off + frame_dim; + + if (frame_ext <= image_ext) { + return 0; + } + + return frame_ext - image_ext; +} + +/** + * Perform any jump over decoded data, to accommodate clipped portion of frame. + * + * \paramin,out skip Number of pixels of data to jump. + * \paramin,out available Number of pixels of data currently available. + * \paramin,out pos Position in decoded pixel value data. + */ +static inline void gif__jump_data( + uint32_t *skip, + uint32_t *available, + const uint8_t **pos) +{ + uint32_t jump = (*skip < *available) ? *skip : *available; + + *skip -= jump; + *available -= jump; + *pos += jump; +} + +static nsgif_error nsgif__decode_complex( + struct nsgif *gif, + uint32_t width, + uint32_t height, + uint32_t offset_x, + uint32_t offset_y, + uint32_t interlace, + const uint8_t *data, + uint32_t transparency_index, + uint32_t *restrict frame_data, + uint32_t *restrict colour_table) +{ + lzw_result res; + nsgif_error ret = NSGIF_OK; + uint32_t clip_x = gif__clip(offset_x, width, gif->info.width); + uint32_t clip_y = gif__clip(offset_y, height, gif->info.height); + const uint8_t *uncompressed; + uint32_t available = 0; + uint8_t step = 24; + uint32_t skip = 0; + uint32_t y = 0; + + if (offset_x >= gif->info.width || + offset_y >= gif->info.height) { + return NSGIF_OK; + } + + width -= clip_x; + height -= clip_y; + + if (width == 0 || height == 0) { + return NSGIF_OK; + } + + /* Initialise the LZW decoding */ + res = lzw_decode_init(gif->lzw_ctx, data0, + gif->buf, gif->buf_len, + data + 1 - gif->buf); + if (res != LZW_OK) { + return nsgif__error_from_lzw(res); + } + + do { + uint32_t x; + uint32_t *frame_scanline; + + frame_scanline = frame_data + offset_x + + (y + offset_y) * gif->rowspan; + + x = width; + while (x > 0) { + unsigned row_available; + while (available == 0) { + if (res != LZW_OK) { + /* Unexpected end of frame, try to recover */ + if (res == LZW_OK_EOD || + res == LZW_EOI_CODE) { + ret = NSGIF_OK; + } else { + ret = nsgif__error_from_lzw(res); + } + return ret; + } + res = lzw_decode(gif->lzw_ctx, + &uncompressed, &available); + + if (available == 0) { + return NSGIF_OK; + } + gif__jump_data(&skip, &available, &uncompressed); + } + + row_available = x < available ? x : available; + x -= row_available; + available -= row_available; + if (transparency_index > 0xFF) { + while (row_available-- > 0) { + *frame_scanline++ = + colour_table*uncompressed++; + } + } else { + while (row_available-- > 0) { + register uint32_t colour; + colour = *uncompressed++; + if (colour != transparency_index) { + *frame_scanline = + colour_tablecolour; + } + frame_scanline++; + } + } + } + + skip = clip_x; + gif__jump_data(&skip, &available, &uncompressed); + } while (nsgif__next_row(interlace, height, &y, &step)); + + return ret; +} + +static nsgif_error nsgif__decode_simple( + struct nsgif *gif, + uint32_t height, + uint32_t offset_y, + const uint8_t *data, + uint32_t transparency_index, + uint32_t *restrict frame_data, + uint32_t *restrict colour_table) +{ + uint32_t pixels; + uint32_t written = 0; + nsgif_error ret = NSGIF_OK; + lzw_result res; + + if (offset_y >= gif->info.height) { + return NSGIF_OK; + } + + height -= gif__clip(offset_y, height, gif->info.height); + + if (height == 0) { + return NSGIF_OK; + } + + /* Initialise the LZW decoding */ + res = lzw_decode_init_map(gif->lzw_ctx, data0, + transparency_index, colour_table, + gif->buf, gif->buf_len, + data + 1 - gif->buf); + if (res != LZW_OK) { + return nsgif__error_from_lzw(res); + } + + frame_data += (offset_y * gif->info.width); + pixels = gif->info.width * height; + + while (pixels > 0) { + res = lzw_decode_map(gif->lzw_ctx, + frame_data, pixels, &written); + pixels -= written; + frame_data += written; + if (res != LZW_OK) { + /* Unexpected end of frame, try to recover */ + if (res == LZW_OK_EOD || res == LZW_EOI_CODE) { + ret = NSGIF_OK; + } else { + ret = nsgif__error_from_lzw(res); + } + break; + } + } + + if (pixels == 0) { + ret = NSGIF_OK; + } + + return ret; +} + +static inline nsgif_error nsgif__decode( + struct nsgif *gif, + struct nsgif_frame *frame, + const uint8_t *data, + uint32_t *restrict frame_data) +{ + nsgif_error ret; + uint32_t width = frame->info.rect.x1 - frame->info.rect.x0; + uint32_t height = frame->info.rect.y1 - frame->info.rect.y0; + uint32_t offset_x = frame->info.rect.x0; + uint32_t offset_y = frame->info.rect.y0; + uint32_t transparency_index = frame->transparency_index; + uint32_t *restrict colour_table = gif->colour_table; + + if (frame->info.interlaced == false && offset_x == 0 && + width == gif->info.width && + width == gif->rowspan) { + ret = nsgif__decode_simple(gif, height, offset_y, + data, transparency_index, + frame_data, colour_table); + } else { + ret = nsgif__decode_complex(gif, width, height, + offset_x, offset_y, frame->info.interlaced, + data, transparency_index, + frame_data, colour_table); + } + + if (gif->data_complete && ret == NSGIF_ERR_END_OF_DATA) { + /* This is all the data there is, so make do. */ + ret = NSGIF_OK; + } + + return ret; +} + +/** + * Restore a GIF to the background colour. + * + * \paramin gif The gif object we're decoding. + * \paramin frame The frame to clear, or NULL. + * \paramin bitmap The bitmap to clear the frame in. + */ +static void nsgif__restore_bg( + struct nsgif *gif, + struct nsgif_frame *frame, + uint32_t *bitmap) +{ + size_t pixel_bytes = sizeof(*bitmap); + + if (frame == NULL) { + size_t width = gif->info.width; + size_t height = gif->info.height; + + memset(bitmap, NSGIF_TRANSPARENT_COLOUR, + width * height * pixel_bytes); + } else { + uint32_t width = frame->info.rect.x1 - frame->info.rect.x0; + uint32_t height = frame->info.rect.y1 - frame->info.rect.y0; + uint32_t offset_x = frame->info.rect.x0; + uint32_t offset_y = frame->info.rect.y0; + + if (frame->info.display == false || + frame->info.rect.x0 >= gif->info.width || + frame->info.rect.y0 >= gif->info.height) { + return; + } + + width -= gif__clip(offset_x, width, gif->info.width); + height -= gif__clip(offset_y, height, gif->info.height); + + if (frame->info.transparency) { + for (uint32_t y = 0; y < height; y++) { + uint32_t *scanline = bitmap + offset_x + + (offset_y + y) * gif->info.width; + memset(scanline, NSGIF_TRANSPARENT_COLOUR, + width * pixel_bytes); + } + } else { + for (uint32_t y = 0; y < height; y++) { + uint32_t *scanline = bitmap + offset_x + + (offset_y + y) * gif->info.width; + for (uint32_t x = 0; x < width; x++) { + scanlinex = gif->info.background; + } + } + } + } +} + +static nsgif_error nsgif__update_bitmap( + struct nsgif *gif, + struct nsgif_frame *frame, + const uint8_t *data, + uint32_t frame_idx) +{ + nsgif_error ret; + uint32_t *bitmap; + + gif->decoded_frame = frame_idx; + + bitmap = nsgif__bitmap_get(gif); + if (bitmap == NULL) { + return NSGIF_ERR_OOM; + } + + /* Handle any bitmap clearing/restoration required before decoding this + * frame. */ + if (frame_idx == 0 || gif->decoded_frame == NSGIF_FRAME_INVALID) { + nsgif__restore_bg(gif, NULL, bitmap); + + } else { + struct nsgif_frame *prev = &gif->framesframe_idx - 1; + + if (prev->info.disposal == NSGIF_DISPOSAL_RESTORE_BG) { + nsgif__restore_bg(gif, prev, bitmap); + + } else if (prev->info.disposal == NSGIF_DISPOSAL_RESTORE_PREV) { + ret = nsgif__recover_frame(gif, bitmap); + if (ret != NSGIF_OK) { + nsgif__restore_bg(gif, prev, bitmap); + } + } + } + + if (frame->info.disposal == NSGIF_DISPOSAL_RESTORE_PREV) { + /* Store the previous frame for later restoration */ + nsgif__record_frame(gif, bitmap); + } + + ret = nsgif__decode(gif, frame, data, bitmap); + + nsgif__bitmap_modified(gif); + + if (!frame->decoded) { + frame->opaque = nsgif__bitmap_get_opaque(gif); + frame->decoded = true; + } + nsgif__bitmap_set_opaque(gif, frame); + + return ret; +} + +/** + * Parse the graphic control extension + * + * \paramin frame The gif frame object we're decoding. + * \paramin data The data to decode. + * \paramin len Byte length of data. + * \return NSGIF_ERR_END_OF_DATA if more data is needed, + * NSGIF_OK for success. + */ +static nsgif_error nsgif__parse_extension_graphic_control( + struct nsgif_frame *frame, + const uint8_t *data, + size_t len) +{ + enum { + GIF_MASK_TRANSPARENCY = 0x01, + GIF_MASK_DISPOSAL = 0x1c, + }; + + /* 6-byte Graphic Control Extension is: + * + * +0 CHAR Graphic Control Label + * +1 CHAR Block Size + * +2 CHAR __Packed Fields__ + * 3BITS Reserved + * 3BITS Disposal Method + * 1BIT User Input Flag + * 1BIT Transparent Color Flag + * +3 SHORT Delay Time + * +5 CHAR Transparent Color Index + */ + if (len < 6) { + return NSGIF_ERR_END_OF_DATA; + } + + frame->info.delay = data3 | (data4 << 8); + + if (data2 & GIF_MASK_TRANSPARENCY) { + frame->info.transparency = true; + frame->transparency_index = data5; + } + + frame->info.disposal = ((data2 & GIF_MASK_DISPOSAL) >> 2); + /* I have encountered documentation and GIFs in the + * wild that use 0x04 to restore the previous frame, + * rather than the officially documented 0x03. I + * believe some (older?) software may even actually + * export this way. We handle this as a type of + * "quirks" mode. */ + if (frame->info.disposal == NSGIF_DISPOSAL_RESTORE_QUIRK) { + frame->info.disposal = NSGIF_DISPOSAL_RESTORE_PREV; + } + + /* if we are clearing the background then we need to + * redraw enough to cover the previous frame too. */ + frame->redraw_required = + frame->info.disposal == NSGIF_DISPOSAL_RESTORE_BG || + frame->info.disposal == NSGIF_DISPOSAL_RESTORE_PREV; + + return NSGIF_OK; +} + +/** + * Check an app ext identifier and authentication code for loop count extension. + * + * \paramin data The data to decode. + * \paramin len Byte length of data. + * \return true if extension is a loop count extension. + */ +static bool nsgif__app_ext_is_loop_count( + const uint8_t *data, + size_t len) +{ + enum { + EXT_LOOP_COUNT_BLOCK_SIZE = 0x0b, + }; + + assert(len > 13); + (void)(len); + + if (data1 == EXT_LOOP_COUNT_BLOCK_SIZE) { + if (strncmp((const char *)data + 2, "NETSCAPE2.0", 11) == 0 || + strncmp((const char *)data + 2, "ANIMEXTS1.0", 11) == 0) { + return true; + } + } + + return false; +} + +/** + * Parse the application extension + * + * \paramin gif The gif object we're decoding. + * \paramin data The data to decode. + * \paramin len Byte length of data. + * \return NSGIF_ERR_END_OF_DATA if more data is needed, + * NSGIF_OK for success. + */ +static nsgif_error nsgif__parse_extension_application( + struct nsgif *gif, + const uint8_t *data, + size_t len) +{ + /* 14-byte+ Application Extension is: + * + * +0 CHAR Application Extension Label + * +1 CHAR Block Size + * +2 8CHARS Application Identifier + * +10 3CHARS Appl. Authentication Code + * +13 1-256 Application Data (Data sub-blocks) + */ + if (len < 17) { + return NSGIF_ERR_END_OF_DATA; + } + + if (nsgif__app_ext_is_loop_count(data, len)) { + enum { + EXT_LOOP_COUNT_SUB_BLOCK_SIZE = 0x03, + EXT_LOOP_COUNT_SUB_BLOCK_ID = 0x01, + }; + if ((data13 == EXT_LOOP_COUNT_SUB_BLOCK_SIZE) && + (data14 == EXT_LOOP_COUNT_SUB_BLOCK_ID)) { + gif->info.loop_max = data15 | (data16 << 8); + + /* The value in the source data means repeat N times + * after the first implied play. A value of zero has + * the special meaning of loop forever. (The only way + * to play the animation once is not to have this + * extension at all. */ + if (gif->info.loop_max > 0) { + gif->info.loop_max++; + } + } + } + + return NSGIF_OK; +} + +/** + * Parse the frame's extensions + * + * \paramin gif The gif object we're decoding. + * \paramin frame The frame to parse extensions for. + * \paramin pos Current position in data, updated on exit. + * \paramin decode Whether to decode or skip over the extension. + * \return NSGIF_ERR_END_OF_DATA if more data is needed, + * NSGIF_OK for success. + */ +static nsgif_error nsgif__parse_frame_extensions( + struct nsgif *gif, + struct nsgif_frame *frame, + const uint8_t **pos, + bool decode) +{ + enum { + GIF_EXT_INTRODUCER = 0x21, + GIF_EXT_GRAPHIC_CONTROL = 0xf9, + GIF_EXT_COMMENT = 0xfe, + GIF_EXT_PLAIN_TEXT = 0x01, + GIF_EXT_APPLICATION = 0xff, + }; + const uint8_t *nsgif_data = *pos; + const uint8_t *nsgif_end = gif->buf + gif->buf_len; + int nsgif_bytes = nsgif_end - nsgif_data; + + /* Initialise the extensions */ + while (nsgif_bytes > 0 && nsgif_data0 == GIF_EXT_INTRODUCER) { + bool block_step = true; + nsgif_error ret; + + nsgif_data++; + nsgif_bytes--; + + if (nsgif_bytes == 0) { + return NSGIF_ERR_END_OF_DATA; + } + + /* Switch on extension label */ + switch (nsgif_data0) { + case GIF_EXT_GRAPHIC_CONTROL: + if (decode) { + ret = nsgif__parse_extension_graphic_control( + frame, + nsgif_data, + nsgif_bytes); + if (ret != NSGIF_OK) { + return ret; + } + } + break; + + case GIF_EXT_APPLICATION: + if (decode) { + ret = nsgif__parse_extension_application( + gif, nsgif_data, nsgif_bytes); + if (ret != NSGIF_OK) { + return ret; + } + } + break; + + case GIF_EXT_COMMENT: + /* Move the pointer to the first data sub-block Skip 1 + * byte for the extension label. */ + ++nsgif_data; + block_step = false; + break; + + default: + break; + } + + if (block_step) { + /* Move the pointer to the first data sub-block Skip 2 + * bytes for the extension label and size fields Skip + * the extension size itself + */ + if (nsgif_bytes < 2) { + return NSGIF_ERR_END_OF_DATA; + } + nsgif_data += 2 + nsgif_data1; + } + + /* Repeatedly skip blocks until we get a zero block or run out + * of data. This data is ignored by this gif decoder. */ + while (nsgif_data < nsgif_end && nsgif_data0 != NSGIF_BLOCK_TERMINATOR) { + nsgif_data += nsgif_data0 + 1; + if (nsgif_data >= nsgif_end) { + return NSGIF_ERR_END_OF_DATA; + } + } + nsgif_data++; + nsgif_bytes = nsgif_end - nsgif_data; + } + + if (nsgif_data > nsgif_end) { + nsgif_data = nsgif_end; + } + + /* Set buffer position and return */ + *pos = nsgif_data; + return NSGIF_OK; +} + +/** + * Parse a GIF Image Descriptor. + * + * The format is: + * + * +0 CHAR Image Separator (0x2c) + * +1 SHORT Image Left Position + * +3 SHORT Image Top Position + * +5 SHORT Width + * +7 SHORT Height + * +9 CHAR __Packed Fields__ + * 1BIT Local Colour Table Flag + * 1BIT Interlace Flag + * 1BIT Sort Flag + * 2BITS Reserved + * 3BITS Size of Local Colour Table + * + * \paramin gif The gif object we're decoding. + * \paramin frame The frame to parse an image descriptor for. + * \paramin pos Current position in data, updated on exit. + * \paramin decode Whether to decode the image descriptor. + * \return NSGIF_OK on success, appropriate error otherwise. + */ +static nsgif_error nsgif__parse_image_descriptor( + struct nsgif *gif, + struct nsgif_frame *frame, + const uint8_t **pos, + bool decode) +{ + const uint8_t *data = *pos; + size_t len = gif->buf + gif->buf_len - data; + enum { + NSGIF_IMAGE_DESCRIPTOR_LEN = 10u, + NSGIF_IMAGE_SEPARATOR = 0x2Cu, + NSGIF_MASK_INTERLACE = 0x40u, + }; + + assert(gif != NULL); + assert(frame != NULL); + + if (len < NSGIF_IMAGE_DESCRIPTOR_LEN) { + return NSGIF_ERR_END_OF_DATA; + } + + if (decode) { + uint32_t x, y, w, h; + + if (data0 != NSGIF_IMAGE_SEPARATOR) { + return NSGIF_ERR_DATA_FRAME; + } + + x = data1 | (data2 << 8); + y = data3 | (data4 << 8); + w = data5 | (data6 << 8); + h = data7 | (data8 << 8); + frame->flags = data9; + + frame->info.rect.x0 = x; + frame->info.rect.y0 = y; + frame->info.rect.x1 = x + w; + frame->info.rect.y1 = y + h; + + frame->info.interlaced = frame->flags & NSGIF_MASK_INTERLACE; + + /* Allow first frame to grow image dimensions. */ + if (gif->info.frame_count == 0) { + if (x + w > gif->info.width) { + gif->info.width = x + w; + } + if (y + h > gif->info.height) { + gif->info.height = y + h; + } + } + } + + *pos += NSGIF_IMAGE_DESCRIPTOR_LEN; + return NSGIF_OK; +} + +/** + * Extract a GIF colour table into a LibNSGIF colour table buffer. + * + * \paramin colour_table The colour table to populate. + * \paramin layout la. + * \paramin colour_table_entries The number of colour table entries. + * \paramin data Raw colour table data. + */ +static void nsgif__colour_table_decode( + uint32_t colour_tableNSGIF_MAX_COLOURS, + const struct nsgif_colour_layout *layout, + size_t colour_table_entries, + const uint8_t *data) +{ + uint8_t *entry = (uint8_t *)colour_table; + + while (colour_table_entries--) { + /* Gif colour map contents are r,g,b. + * + * We want to pack them bytewise into the colour table, + * according to the client colour layout. + */ + + entrylayout->r = *data++; + entrylayout->g = *data++; + entrylayout->b = *data++; + entrylayout->a = 0xff; + + entry += sizeof(uint32_t); + } +} + +/** + * Extract a GIF colour table into a LibNSGIF colour table buffer. + * + * \paramin colour_table The colour table to populate. + * \paramin layout The target pixel format to decode to. + * \paramin colour_table_entries The number of colour table entries. + * \paramin data Current position in data. + * \paramin data_len The available length of `data`. + * \paramout used Number of colour table bytes read. + * \paramin decode Whether to decode the colour table. + * \return NSGIF_OK on success, appropriate error otherwise. + */ +static inline nsgif_error nsgif__colour_table_extract( + uint32_t colour_tableNSGIF_MAX_COLOURS, + const struct nsgif_colour_layout *layout, + size_t colour_table_entries, + const uint8_t *data, + size_t data_len, + size_t *used, + bool decode) +{ + if (data_len < colour_table_entries * 3) { + return NSGIF_ERR_END_OF_DATA; + } + + if (decode) { + nsgif__colour_table_decode(colour_table, layout, + colour_table_entries, data); + } + + *used = colour_table_entries * 3; + return NSGIF_OK; +} + +/** + * Get a frame's colour table. + * + * Sets up gif->colour_table for the frame. + * + * \paramin gif The gif object we're decoding. + * \paramin frame The frame to get the colour table for. + * \paramin pos Current position in data, updated on exit. + * \paramin decode Whether to decode the colour table. + * \return NSGIF_OK on success, appropriate error otherwise. + */ +static nsgif_error nsgif__parse_colour_table( + struct nsgif *gif, + struct nsgif_frame *frame, + const uint8_t **pos, + bool decode) +{ + nsgif_error ret; + const uint8_t *data = *pos; + size_t len = gif->buf + gif->buf_len - data; + size_t used_bytes; + + assert(gif != NULL); + assert(frame != NULL); + + if ((frame->flags & NSGIF_COLOUR_TABLE_MASK) == 0) { + gif->colour_table = gif->global_colour_table; + return NSGIF_OK; + } + + if (decode == false) { + frame->colour_table_offset = *pos - gif->buf; + } + + ret = nsgif__colour_table_extract( + gif->local_colour_table, &gif->colour_layout, + 2 << (frame->flags & NSGIF_COLOUR_TABLE_SIZE_MASK), + data, len, &used_bytes, decode); + if (ret != NSGIF_OK) { + return ret; + } + *pos += used_bytes; + + if (decode) { + gif->colour_table = gif->local_colour_table; + } else { + frame->info.local_palette = true; + } + + return NSGIF_OK; +} + +/** + * Parse the image data for a gif frame. + * + * Sets up gif->colour_table for the frame. + * + * \paramin gif The gif object we're decoding. + * \paramin frame The frame to parse image data for. + * \paramin pos Current position in data, updated on exit. + * \paramin decode Whether to decode the image data. + * \return NSGIF_OK on success, appropriate error otherwise. + */ +static nsgif_error nsgif__parse_image_data( + struct nsgif *gif, + struct nsgif_frame *frame, + const uint8_t **pos, + bool decode) +{ + const uint8_t *data = *pos; + size_t len = gif->buf + gif->buf_len - data; + uint32_t frame_idx = frame - gif->frames; + uint8_t minimum_code_size; + nsgif_error ret; + + assert(gif != NULL); + assert(frame != NULL); + + if (!decode) { + gif->frame_count_partial = frame_idx + 1; + } + + /* Ensure sufficient data remains. A gif trailer or a minimum lzw code + * followed by a gif trailer is treated as OK, although without any + * image data. */ + switch (len) { + default: if (data0 == NSGIF_TRAILER) return NSGIF_OK; + break; + case 2: if (data1 == NSGIF_TRAILER) return NSGIF_OK; + /* Fall through. */ + case 1: if (data0 == NSGIF_TRAILER) return NSGIF_OK; + /* Fall through. */ + case 0: return NSGIF_ERR_END_OF_DATA; + } + + minimum_code_size = data0; + if (minimum_code_size >= LZW_CODE_MAX) { + return NSGIF_ERR_DATA_FRAME; + } + + if (decode) { + ret = nsgif__update_bitmap(gif, frame, data, frame_idx); + } else { + uint32_t block_size = 0; + + /* Skip the minimum code size. */ + data++; + len--; + + while (block_size != 1) { + if (len < 1) { + return NSGIF_ERR_END_OF_DATA; + } + block_size = data0 + 1; + /* Check if the frame data runs off the end of the file */ + if (block_size > len) { + frame->lzw_data_length += len; + return NSGIF_ERR_END_OF_DATA; + } + + len -= block_size; + data += block_size; + frame->lzw_data_length += block_size; + } + + *pos = data; + + gif->info.frame_count = frame_idx + 1; + gif->framesframe_idx.info.display = true; + + return NSGIF_OK; + } + + return ret; +} + +static struct nsgif_frame *nsgif__get_frame( + struct nsgif *gif, + uint32_t frame_idx) +{ + struct nsgif_frame *frame; + + if (gif->frame_holders > frame_idx) { + frame = &gif->framesframe_idx; + } else { + /* Allocate more memory */ + size_t count = frame_idx + 1; + struct nsgif_frame *temp; + + temp = realloc(gif->frames, count * sizeof(*frame)); + if (temp == NULL) { + return NULL; + } + gif->frames = temp; + gif->frame_holders = count; + + frame = &gif->framesframe_idx; + + frame->info.local_palette = false; + frame->info.transparency = false; + frame->info.display = false; + frame->info.disposal = 0; + frame->info.delay = 10; + + frame->transparency_index = NSGIF_NO_TRANSPARENCY; + frame->frame_offset = gif->buf_pos; + frame->redraw_required = false; + frame->lzw_data_length = 0; + frame->decoded = false; + } + + return frame; +} + +/** + * Attempts to initialise the next frame + * + * \paramin gif The animation context + * \paramin frame_idx The frame number to decode. + * \paramin decode Whether to decode the graphical image data. + * \return NSGIF_OK on success, appropriate error otherwise. +*/ +static nsgif_error nsgif__process_frame( + struct nsgif *gif, + uint32_t frame_idx, + bool decode) +{ + nsgif_error ret; + const uint8_t *pos; + const uint8_t *end; + struct nsgif_frame *frame; + + frame = nsgif__get_frame(gif, frame_idx); + if (frame == NULL) { + return NSGIF_ERR_OOM; + } + + end = gif->buf + gif->buf_len; + + if (decode) { + pos = gif->buf + frame->frame_offset; + + /* Ensure this frame is supposed to be decoded */ + if (frame->info.display == false) { + return NSGIF_OK; + } + + /* Ensure the frame is in range to decode */ + if (frame_idx > gif->frame_count_partial) { + return NSGIF_ERR_END_OF_DATA; + } + + /* Done if frame is already decoded */ + if (frame_idx == gif->decoded_frame) { + return NSGIF_OK; + } + } else { + pos = gif->buf + gif->buf_pos; + + /* Check if we've finished */ + if (pos < end && pos0 == NSGIF_TRAILER) { + return NSGIF_OK; + } + } + + ret = nsgif__parse_frame_extensions(gif, frame, &pos, !decode); + if (ret != NSGIF_OK) { + goto cleanup; + } + + ret = nsgif__parse_image_descriptor(gif, frame, &pos, !decode); + if (ret != NSGIF_OK) { + goto cleanup; + } + + ret = nsgif__parse_colour_table(gif, frame, &pos, decode); + if (ret != NSGIF_OK) { + goto cleanup; + } + + ret = nsgif__parse_image_data(gif, frame, &pos, decode); + if (ret != NSGIF_OK) { + goto cleanup; + } + +cleanup: + if (!decode) { + gif->buf_pos = pos - gif->buf; + } + + return ret; +} + +/* exported function documented in nsgif.h */ +void nsgif_destroy(nsgif_t *gif) +{ + if (gif == NULL) { + return; + } + + /* Release all our memory blocks */ + if (gif->frame_image) { + assert(gif->bitmap.destroy); + gif->bitmap.destroy(gif->frame_image); + gif->frame_image = NULL; + } + + free(gif->frames); + gif->frames = NULL; + + free(gif->prev_frame); + gif->prev_frame = NULL; + + lzw_context_destroy(gif->lzw_ctx); + gif->lzw_ctx = NULL; + + free(gif); +} + +/** + * Check whether the host is little endian. + * + * Checks whether least significant bit is in the first byte of a `uint16_t`. + * + * \return true if host is little endian. + */ +static inline bool nsgif__host_is_little_endian(void) +{ + const uint16_t test = 1; + + return ((const uint8_t *) &test)0; +} + +static struct nsgif_colour_layout nsgif__bitmap_fmt_to_colour_layout( + nsgif_bitmap_fmt_t bitmap_fmt) +{ + bool le = nsgif__host_is_little_endian(); + + /* Map endian-dependant formats to byte-wise format for the host. */ + switch (bitmap_fmt) { + case NSGIF_BITMAP_FMT_RGBA8888: + bitmap_fmt = (le) ? NSGIF_BITMAP_FMT_A8B8G8R8 + : NSGIF_BITMAP_FMT_R8G8B8A8; + break; + case NSGIF_BITMAP_FMT_BGRA8888: + bitmap_fmt = (le) ? NSGIF_BITMAP_FMT_A8R8G8B8 + : NSGIF_BITMAP_FMT_B8G8R8A8; + break; + case NSGIF_BITMAP_FMT_ARGB8888: + bitmap_fmt = (le) ? NSGIF_BITMAP_FMT_B8G8R8A8 + : NSGIF_BITMAP_FMT_A8R8G8B8; + break; + case NSGIF_BITMAP_FMT_ABGR8888: + bitmap_fmt = (le) ? NSGIF_BITMAP_FMT_R8G8B8A8 + : NSGIF_BITMAP_FMT_A8B8G8R8; + break; + default: + break; + } + + /* Set up colour component order for bitmap format. */ + switch (bitmap_fmt) { + default: + /* Fall through. */ + case NSGIF_BITMAP_FMT_R8G8B8A8: + return (struct nsgif_colour_layout) { + .r = 0, + .g = 1, + .b = 2, + .a = 3, + }; + + case NSGIF_BITMAP_FMT_B8G8R8A8: + return (struct nsgif_colour_layout) { + .b = 0, + .g = 1, + .r = 2, + .a = 3, + }; + + case NSGIF_BITMAP_FMT_A8R8G8B8: + return (struct nsgif_colour_layout) { + .a = 0, + .r = 1, + .g = 2, + .b = 3, + }; + + case NSGIF_BITMAP_FMT_A8B8G8R8: + return (struct nsgif_colour_layout) { + .a = 0, + .b = 1, + .g = 2, + .r = 3, + }; + } +} + +/* exported function documented in nsgif.h */ +nsgif_error nsgif_create( + const nsgif_bitmap_cb_vt *bitmap_vt, + nsgif_bitmap_fmt_t bitmap_fmt, + nsgif_t **gif_out) +{ + nsgif_t *gif; + + gif = calloc(1, sizeof(*gif)); + if (gif == NULL) { + return NSGIF_ERR_OOM; + } + + gif->bitmap = *bitmap_vt; + gif->decoded_frame = NSGIF_FRAME_INVALID; + gif->prev_index = NSGIF_FRAME_INVALID; + + gif->delay_min = NSGIF_FRAME_DELAY_MIN; + gif->delay_default = NSGIF_FRAME_DELAY_DEFAULT; + + gif->colour_layout = nsgif__bitmap_fmt_to_colour_layout(bitmap_fmt); + + *gif_out = gif; + return NSGIF_OK; +} + +/* exported function documented in nsgif.h */ +void nsgif_set_frame_delay_behaviour( + nsgif_t *gif, + uint16_t delay_min, + uint16_t delay_default) +{ + gif->delay_min = delay_min; + gif->delay_default = delay_default; +} + +/** + * Read GIF header. + * + * 6-byte GIF file header is: + * + * +0 3CHARS Signature ('GIF') + * +3 3CHARS Version ('87a' or '89a') + * + * \paramin gif The GIF object we're decoding. + * \paramin,out pos The current buffer position, updated on success. + * \paramin strict Whether to require a known GIF version. + * \return NSGIF_OK on success, appropriate error otherwise. + */ +static nsgif_error nsgif__parse_header( + struct nsgif *gif, + const uint8_t **pos, + bool strict) +{ + const uint8_t *data = *pos; + size_t len = gif->buf + gif->buf_len - data; + + if (len < 6) { + return NSGIF_ERR_END_OF_DATA; + } + + if (strncmp((const char *) data, "GIF", 3) != 0) { + return NSGIF_ERR_DATA; + } + data += 3; + + if (strict == true) { + if ((strncmp((const char *) data, "87a", 3) != 0) && + (strncmp((const char *) data, "89a", 3) != 0)) { + return NSGIF_ERR_DATA; + } + } + data += 3; + + *pos = data; + return NSGIF_OK; +} + +/** + * Read Logical Screen Descriptor. + * + * 7-byte Logical Screen Descriptor is: + * + * +0 SHORT Logical Screen Width + * +2 SHORT Logical Screen Height + * +4 CHAR __Packed Fields__ + * 1BIT Global Colour Table Flag + * 3BITS Colour Resolution + * 1BIT Sort Flag + * 3BITS Size of Global Colour Table + * +5 CHAR Background Colour Index + * +6 CHAR Pixel Aspect Ratio + * + * \paramin gif The GIF object we're decoding. + * \paramin,out pos The current buffer position, updated on success. + * \return NSGIF_OK on success, appropriate error otherwise. + */ +static nsgif_error nsgif__parse_logical_screen_descriptor( + struct nsgif *gif, + const uint8_t **pos) +{ + const uint8_t *data = *pos; + size_t len = gif->buf + gif->buf_len - data; + + if (len < 7) { + return NSGIF_ERR_END_OF_DATA; + } + + gif->info.width = data0 | (data1 << 8); + gif->info.height = data2 | (data3 << 8); + gif->info.global_palette = data4 & NSGIF_COLOUR_TABLE_MASK; + gif->colour_table_size = 2 << (data4 & NSGIF_COLOUR_TABLE_SIZE_MASK); + gif->bg_index = data5; + gif->aspect_ratio = data6; + gif->info.loop_max = 1; + + *pos += 7; + return NSGIF_OK; +} + +/* exported function documented in nsgif.h */ +nsgif_error nsgif_data_scan( + nsgif_t *gif, + size_t size, + const uint8_t *data) +{ + const uint8_t *nsgif_data; + nsgif_error ret; + uint32_t frames; + + if (gif->data_complete) { + return NSGIF_ERR_DATA_COMPLETE; + } + + /* Initialize values */ + gif->buf_len = size; + gif->buf = data; + + /* Get our current processing position */ + nsgif_data = gif->buf + gif->buf_pos; + + /* See if we should initialise the GIF */ + if (gif->buf_pos == 0) { + /* We want everything to be NULL before we start so we've no + * chance of freeing bad pointers (paranoia) + */ + gif->frame_image = NULL; + gif->frames = NULL; + gif->frame_holders = 0; + + /* The caller may have been lazy and not reset any values */ + gif->info.frame_count = 0; + gif->frame_count_partial = 0; + gif->decoded_frame = NSGIF_FRAME_INVALID; + gif->frame = NSGIF_FRAME_INVALID; + + ret = nsgif__parse_header(gif, &nsgif_data, false); + if (ret != NSGIF_OK) { + return ret; + } + + ret = nsgif__parse_logical_screen_descriptor(gif, &nsgif_data); + if (ret != NSGIF_OK) { + return ret; + } + + /* Remember we've done this now */ + gif->buf_pos = nsgif_data - gif->buf; + + /* Some broken GIFs report the size as the screen size they + * were created in. As such, we detect for the common cases and + * set the sizes as 0 if they are found which results in the + * GIF being the maximum size of the frames. + */ + if (((gif->info.width == 640) && (gif->info.height == 480)) || + ((gif->info.width == 640) && (gif->info.height == 512)) || + ((gif->info.width == 800) && (gif->info.height == 600)) || + ((gif->info.width == 1024) && (gif->info.height == 768)) || + ((gif->info.width == 1280) && (gif->info.height == 1024)) || + ((gif->info.width == 1600) && (gif->info.height == 1200)) || + ((gif->info.width == 0) || (gif->info.height == 0)) || + ((gif->info.width > 2048) || (gif->info.height > 2048))) { + gif->info.width = 1; + gif->info.height = 1; + } + + /* Set the first colour to a value that will never occur in + * reality so we know if we've processed it + */ + gif->global_colour_table0 = NSGIF_PROCESS_COLOURS; + + /* Check if the GIF has no frame data (13-byte header + 1-byte + * termination block) Although generally useless, the GIF + * specification does not expressly prohibit this + */ + if (gif->buf_len == gif->buf_pos + 1) { + if (nsgif_data0 == NSGIF_TRAILER) { + return NSGIF_OK; + } + } + } + + /* Do the colour map if we haven't already. As the top byte is always + * 0xff or 0x00 depending on the transparency we know if it's been + * filled in. + */ + if (gif->global_colour_table0 == NSGIF_PROCESS_COLOURS) { + /* Check for a global colour map signified by bit 7 */ + if (gif->info.global_palette) { + size_t remaining = gif->buf + gif->buf_len - nsgif_data; + size_t used; + + ret = nsgif__colour_table_extract( + gif->global_colour_table, + &gif->colour_layout, + gif->colour_table_size, + nsgif_data, remaining, &used, true); + if (ret != NSGIF_OK) { + return ret; + } + + nsgif_data += used; + gif->buf_pos = (nsgif_data - gif->buf); + } else { + /* Create a default colour table with the first two + * colours as black and white. */ + uint8_t *entry = (uint8_t *)gif->global_colour_table; + + /* Black */ + entrygif->colour_layout.r = 0x00; + entrygif->colour_layout.g = 0x00; + entrygif->colour_layout.b = 0x00; + entrygif->colour_layout.a = 0xFF; + + entry += sizeof(uint32_t); + + /* White */ + entrygif->colour_layout.r = 0xFF; + entrygif->colour_layout.g = 0xFF; + entrygif->colour_layout.b = 0xFF; + entrygif->colour_layout.a = 0xFF; + + gif->colour_table_size = 2; + } + + if (gif->info.global_palette && + gif->bg_index < gif->colour_table_size) { + size_t bg_idx = gif->bg_index; + gif->info.background = gif->global_colour_tablebg_idx; + } else { + gif->info.background = gif->global_colour_table0; + } + } + + if (gif->lzw_ctx == NULL) { + lzw_result res = lzw_context_create( + (struct lzw_ctx **)&gif->lzw_ctx); + if (res != LZW_OK) { + return nsgif__error_from_lzw(res); + } + } + + /* Try to initialise all frames. */ + do { + frames = gif->info.frame_count; + ret = nsgif__process_frame(gif, frames, false); + } while (gif->info.frame_count > frames); + + if (ret == NSGIF_ERR_END_OF_DATA && gif->info.frame_count > 0) { + ret = NSGIF_OK; + } + + return ret; +} + +/* exported function documented in nsgif.h */ +void nsgif_data_complete( + nsgif_t *gif) +{ + if (gif->data_complete == false) { + uint32_t start = gif->info.frame_count; + uint32_t end = gif->frame_count_partial; + + for (uint32_t f = start; f < end; f++) { + nsgif_frame *frame = &gif->framesf; + + if (frame->lzw_data_length > 0) { + frame->info.display = true; + gif->info.frame_count = f + 1; + + if (f == 0) { + frame->info.transparency = true; + } + break; + } + } + } + + gif->data_complete = true; +} + +static void nsgif__redraw_rect_extend( + const nsgif_rect_t *frame, + nsgif_rect_t *redraw) +{ + if (redraw->x1 == 0 || redraw->y1 == 0) { + *redraw = *frame; + } else { + if (redraw->x0 > frame->x0) { + redraw->x0 = frame->x0; + } + if (redraw->x1 < frame->x1) { + redraw->x1 = frame->x1; + } + if (redraw->y0 > frame->y0) { + redraw->y0 = frame->y0; + } + if (redraw->y1 < frame->y1) { + redraw->y1 = frame->y1; + } + } +} + +static uint32_t nsgif__frame_next( + const nsgif_t *gif, + bool partial, + uint32_t frame) +{ + uint32_t frames = partial ? + gif->frame_count_partial : + gif->info.frame_count; + + if (frames == 0) { + return NSGIF_FRAME_INVALID; + } + + frame++; + return (frame >= frames) ? 0 : frame; +} + +static nsgif_error nsgif__next_displayable_frame( + const nsgif_t *gif, + uint32_t *frame, + uint32_t *delay) +{ + uint32_t next = *frame; + + do { + next = nsgif__frame_next(gif, false, next); + if (next <= *frame && *frame != NSGIF_FRAME_INVALID && + gif->data_complete == false) { + return NSGIF_ERR_END_OF_DATA; + + } else if (next == *frame || next == NSGIF_FRAME_INVALID) { + return NSGIF_ERR_FRAME_DISPLAY; + } + + if (delay != NULL) { + *delay += gif->framesnext.info.delay; + } + + } while (gif->framesnext.info.display == false); + + *frame = next; + return NSGIF_OK; +} + +static inline bool nsgif__animation_complete(int count, int max) +{ + if (max == 0) { + return false; + } + + return (count >= max); +} + +nsgif_error nsgif_reset( + nsgif_t *gif) +{ + gif->loop_count = 0; + gif->frame = NSGIF_FRAME_INVALID; + + return NSGIF_OK; +} + +/* exported function documented in nsgif.h */ +nsgif_error nsgif_frame_prepare( + nsgif_t *gif, + nsgif_rect_t *area, + uint32_t *delay_cs, + uint32_t *frame_new) +{ + nsgif_error ret; + nsgif_rect_t rect = { + .x1 = 0, + .y1 = 0, + }; + uint32_t delay = 0; + uint32_t frame = gif->frame; + + if (gif->frame != NSGIF_FRAME_INVALID && + gif->frame < gif->info.frame_count && + gif->framesgif->frame.info.display) { + rect = gif->framesgif->frame.info.rect; + } + + if (nsgif__animation_complete( + gif->loop_count, + gif->info.loop_max)) { + return NSGIF_ERR_ANIMATION_END; + } + + ret = nsgif__next_displayable_frame(gif, &frame, &delay); + if (ret != NSGIF_OK) { + return ret; + } + + if (gif->frame != NSGIF_FRAME_INVALID && frame < gif->frame) { + gif->loop_count++; + } + + if (gif->data_complete) { + /* Check for last frame, which has infinite delay. */ + + if (gif->info.frame_count == 1) { + delay = NSGIF_INFINITE; + } else if (gif->info.loop_max != 0) { + uint32_t frame_next = frame; + + ret = nsgif__next_displayable_frame(gif, + &frame_next, NULL); + if (ret != NSGIF_OK) { + return ret; + } + + if (gif->data_complete && frame_next < frame) { + if (nsgif__animation_complete( + gif->loop_count + 1, + gif->info.loop_max)) { + delay = NSGIF_INFINITE; + } + } + } + } + + gif->frame = frame; + nsgif__redraw_rect_extend(&gif->framesframe.info.rect, &rect); + + if (delay < gif->delay_min) { + delay = gif->delay_default; + } + + *frame_new = gif->frame; + *delay_cs = delay; + *area = rect; + + return NSGIF_OK; +} + +/* exported function documented in nsgif.h */ +nsgif_error nsgif_frame_decode( + nsgif_t *gif, + uint32_t frame, + nsgif_bitmap_t **bitmap) +{ + uint32_t start_frame; + nsgif_error ret = NSGIF_OK; + + if (frame >= gif->info.frame_count) { + return NSGIF_ERR_BAD_FRAME; + } + + if (gif->decoded_frame == frame) { + *bitmap = gif->frame_image; + return NSGIF_OK; + + } else if (gif->decoded_frame >= frame || + gif->decoded_frame == NSGIF_FRAME_INVALID) { + /* Can skip to first frame or restart. */ + start_frame = 0; + } else { + start_frame = nsgif__frame_next( + gif, false, gif->decoded_frame); + } + + for (uint32_t f = start_frame; f <= frame; f++) { + ret = nsgif__process_frame(gif, f, true); + if (ret != NSGIF_OK) { + return ret; + } + } + + *bitmap = gif->frame_image; + return ret; +} + +/* exported function documented in nsgif.h */ +const nsgif_info_t *nsgif_get_info(const nsgif_t *gif) +{ + return &gif->info; +} + +/* exported function documented in nsgif.h */ +const nsgif_frame_info_t *nsgif_get_frame_info( + const nsgif_t *gif, + uint32_t frame) +{ + if (frame >= gif->info.frame_count) { + return NULL; + } + + return &gif->framesframe.info; +} + +/* exported function documented in nsgif.h */ +void nsgif_global_palette( + const nsgif_t *gif, + uint32_t tableNSGIF_MAX_COLOURS, + size_t *entries) +{ + size_t len = sizeof(*table) * NSGIF_MAX_COLOURS; + + memcpy(table, gif->global_colour_table, len); + *entries = gif->colour_table_size; +} + +/* exported function documented in nsgif.h */ +bool nsgif_local_palette( + const nsgif_t *gif, + uint32_t frame, + uint32_t tableNSGIF_MAX_COLOURS, + size_t *entries) +{ + const nsgif_frame *f; + + if (frame >= gif->frame_count_partial) { + return false; + } + + f = &gif->framesframe; + if (f->info.local_palette == false) { + return false; + } + + *entries = 2 << (f->flags & NSGIF_COLOUR_TABLE_SIZE_MASK); + nsgif__colour_table_decode(table, &gif->colour_layout, + *entries, gif->buf + f->colour_table_offset); + + return true; +} + +/* exported function documented in nsgif.h */ +const char *nsgif_strerror(nsgif_error err) +{ + static const char *const str = { + NSGIF_OK = "Success", + NSGIF_ERR_OOM = "Out of memory", + NSGIF_ERR_DATA = "Invalid source data", + NSGIF_ERR_BAD_FRAME = "Requested frame does not exist", + NSGIF_ERR_DATA_FRAME = "Invalid frame data", + NSGIF_ERR_END_OF_DATA = "Unexpected end of GIF source data", + NSGIF_ERR_DATA_COMPLETE = "Can't add data to completed GIF", + NSGIF_ERR_FRAME_DISPLAY = "Frame can't be displayed", + NSGIF_ERR_ANIMATION_END = "Animation complete", + }; + + if (err >= NSGIF_ARRAY_LEN(str) || strerr == NULL) { + return "Unknown error"; + } + + return strerr; +} + +/* exported function documented in nsgif.h */ +const char *nsgif_str_disposal(enum nsgif_disposal disposal) +{ + static const char *const str = { + NSGIF_DISPOSAL_UNSPECIFIED = "Unspecified", + NSGIF_DISPOSAL_NONE = "None", + NSGIF_DISPOSAL_RESTORE_BG = "Restore background", + NSGIF_DISPOSAL_RESTORE_PREV = "Restore previous", + NSGIF_DISPOSAL_RESTORE_QUIRK = "Restore quirk", + }; + + if (disposal >= NSGIF_ARRAY_LEN(str) || strdisposal == NULL) { + return "Unspecified"; + } + + return strdisposal; +}
View file
obs-studio-33.0.0.tar.xz/libobs/graphics/libnsgif/lzw.c
Added
@@ -0,0 +1,613 @@ +/* + * This file is part of NetSurf's LibNSGIF, http://www.netsurf-browser.org/ + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * + * Copyright 2017 Michael Drake <michael.drake@codethink.co.uk> + * Copyright 2021 Michael Drake <tlsa@netsurf-browser.org> + */ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdbool.h> + +#include "lzw.h" + +/** + * \file + * \brief LZW decompression (implementation) + * + * Decoder for GIF LZW data. + */ + +/** Maximum number of lzw table entries. */ +#define LZW_TABLE_ENTRY_MAX (1u << LZW_CODE_MAX) + +/** + * Context for reading LZW data. + * + * LZW data is split over multiple sub-blocks. Each sub-block has a + * byte at the start, which says the sub-block size, and then the data. + * Zero-size sub-blocks have no data, and the biggest sub-block size is + * 255, which means there are 255 bytes of data following the sub-block + * size entry. + * + * Note that an individual LZW code can be split over up to three sub-blocks. + */ +struct lzw_read_ctx { + const uint8_t *restrict data; /**< Pointer to start of input data */ + size_t data_len; /**< Input data length */ + size_t data_sb_next; /**< Offset to sub-block size */ + + const uint8_t *sb_data; /**< Pointer to current sub-block in data */ + size_t sb_bit; /**< Current bit offset in sub-block */ + uint32_t sb_bit_count; /**< Bit count in sub-block */ +}; + +/** + * LZW table entry. + * + * Records in the table are composed of 1 or more entries. + * Entries refer to the entry they extend which can be followed to compose + * the complete record. To compose the record in reverse order, take + * the `value` from each entry, and move to the entry it extends. + * If the extended entries index is < the current clear_code, then it + * is the last entry in the record. + */ +struct lzw_table_entry { + uint8_t value; /**< Last value for record ending at entry. */ + uint8_t first; /**< First value in entry's entire record. */ + uint16_t count; /**< Count of values in this entry's record. */ + uint16_t extends; /**< Offset in table to previous entry. */ +}; + +/** + * LZW decompression context. + */ +struct lzw_ctx { + struct lzw_read_ctx input; /**< Input reading context */ + + uint16_t prev_code; /**< Code read from input previously. */ + uint16_t prev_code_first; /**< First value of previous code. */ + uint16_t prev_code_count; /**< Total values for previous code. */ + + uint8_t initial_code_size; /**< Starting LZW code size. */ + + uint8_t code_size; /**< Current LZW code size. */ + uint16_t code_max; /**< Max code value for current code size. */ + + uint16_t clear_code; /**< Special Clear code value */ + uint16_t eoi_code; /**< Special End of Information code value */ + + uint16_t table_size; /**< Next position in table to fill. */ + + uint16_t output_code; /**< Code that has been partially output. */ + uint16_t output_left; /**< Number of values left for output_code. */ + + bool has_transparency; /**< Whether the image is opaque. */ + uint8_t transparency_idx; /**< Index representing transparency. */ + const uint32_t *restrict colour_map; /**< Index to colour mapping. */ + + /** LZW code table. Generated during decode. */ + struct lzw_table_entry tableLZW_TABLE_ENTRY_MAX; + + /** Output value stack. */ + uint8_t stack_baseLZW_TABLE_ENTRY_MAX; +}; + +/* Exported function, documented in lzw.h */ +lzw_result lzw_context_create(struct lzw_ctx **ctx) +{ + struct lzw_ctx *c = malloc(sizeof(*c)); + if (c == NULL) { + return LZW_NO_MEM; + } + + *ctx = c; + return LZW_OK; +} + +/* Exported function, documented in lzw.h */ +void lzw_context_destroy(struct lzw_ctx *ctx) +{ + free(ctx); +} + +/** + * Advance the context to the next sub-block in the input data. + * + * \paramin ctx LZW reading context, updated on success. + * \return LZW_OK or LZW_OK_EOD on success, appropriate error otherwise. + */ +static lzw_result lzw__block_advance(struct lzw_read_ctx *restrict ctx) +{ + size_t block_size; + size_t next_block_pos = ctx->data_sb_next; + const uint8_t *data_next = ctx->data + next_block_pos; + + if (next_block_pos >= ctx->data_len) { + return LZW_NO_DATA; + } + + block_size = *data_next; + + if ((next_block_pos + block_size) >= ctx->data_len) { + return LZW_NO_DATA; + } + + ctx->sb_bit = 0; + ctx->sb_bit_count = block_size * 8; + + if (block_size == 0) { + ctx->data_sb_next += 1; + return LZW_OK_EOD; + } + + ctx->sb_data = data_next + 1; + ctx->data_sb_next += block_size + 1; + + return LZW_OK; +} + +/** + * Get the next LZW code of given size from the raw input data. + * + * Reads codes from the input data stream coping with GIF data sub-blocks. + * + * \paramin ctx LZW reading context, updated. + * \paramin code_size Size of LZW code to get from data. + * \paramout code_out Returns an LZW code on success. + * \return LZW_OK or LZW_OK_EOD on success, appropriate error otherwise. + */ +static inline lzw_result lzw__read_code( + struct lzw_read_ctx *restrict ctx, + uint16_t code_size, + uint16_t *restrict code_out) +{ + uint32_t code = 0; + uint32_t current_bit = ctx->sb_bit & 0x7; + + if (ctx->sb_bit + 24 <= ctx->sb_bit_count) { + /* Fast path: read three bytes from this sub-block */ + const uint8_t *data = ctx->sb_data + (ctx->sb_bit >> 3); + code |= *data++ << 0; + code |= *data++ << 8; + code |= *data << 16; + ctx->sb_bit += code_size; + } else { + /* Slow path: code spans sub-blocks */ + uint8_t byte_advance = (current_bit + code_size) >> 3; + uint8_t byte = 0; + uint8_t bits_remaining_0 = (code_size < (8u - current_bit)) ? + code_size : (8u - current_bit); + uint8_t bits_remaining_1 = code_size - bits_remaining_0; + uint8_t bits_used3 = { + 0 = bits_remaining_0, + 1 = bits_remaining_1 < 8 ? bits_remaining_1 : 8, + 2 = bits_remaining_1 - 8, + }; + + assert(byte_advance <= 2); + + while (true) { + const uint8_t *data = ctx->sb_data; + lzw_result res; + + /* Get any data from end of this sub-block */ + while (byte <= byte_advance && + ctx->sb_bit < ctx->sb_bit_count) { + code |= datactx->sb_bit >> 3 << (byte << 3); + ctx->sb_bit += bits_usedbyte; + byte++; + } + + /* Check if we have all we need */ + if (byte > byte_advance) { + break; + } + + /* Move to next sub-block */ + res = lzw__block_advance(ctx); + if (res != LZW_OK) { + return res; + } + } + } + + *code_out = (code >> current_bit) & ((1 << code_size) - 1); + return LZW_OK; +} + +/** + * Handle clear code. + * + * \paramin ctx LZW reading context, updated. + * \paramout code_out Returns next code after a clear code. + * \return LZW_OK or error code. + */ +static inline lzw_result lzw__handle_clear( + struct lzw_ctx *ctx, + uint16_t *code_out) +{ + uint16_t code; + + /* Reset table building context */ + ctx->code_size = ctx->initial_code_size; + ctx->code_max = (1 << ctx->initial_code_size) - 1; + ctx->table_size = ctx->eoi_code + 1; + + /* There might be a sequence of clear codes, so process them all */ + do { + lzw_result res = lzw__read_code(&ctx->input, + ctx->code_size, &code); + if (res != LZW_OK) { + return res; + } + } while (code == ctx->clear_code); + + /* The initial code must be from the initial table. */ + if (code > ctx->clear_code) { + return LZW_BAD_ICODE; + } + + *code_out = code; + return LZW_OK; +} + +/* Exported function, documented in lzw.h */ +lzw_result lzw_decode_init( + struct lzw_ctx *ctx, + uint8_t minimum_code_size, + const uint8_t *input_data, + size_t input_length, + size_t input_pos) +{ + struct lzw_table_entry *table = ctx->table; + lzw_result res; + uint16_t code; + + if (minimum_code_size >= LZW_CODE_MAX) { + return LZW_BAD_ICODE; + } + + /* Initialise the input reading context */ + ctx->input.data = input_data; + ctx->input.data_len = input_length; + ctx->input.data_sb_next = input_pos; + + ctx->input.sb_bit = 0; + ctx->input.sb_bit_count = 0; + + /* Initialise the table building context */ + ctx->initial_code_size = minimum_code_size + 1; + + ctx->clear_code = (1 << minimum_code_size) + 0; + ctx->eoi_code = (1 << minimum_code_size) + 1; + + ctx->output_left = 0; + + /* Initialise the standard table entries */ + for (uint16_t i = 0; i < ctx->clear_code; i++) { + tablei.first = i; + tablei.value = i; + tablei.count = 1; + } + + res = lzw__handle_clear(ctx, &code); + if (res != LZW_OK) { + return res; + } + + /* Store details of this code as "previous code" to the context. */ + ctx->prev_code_first = ctx->tablecode.first; + ctx->prev_code_count = ctx->tablecode.count; + ctx->prev_code = code; + + /* Add code to context for immediate output. */ + ctx->output_code = code; + ctx->output_left = 1; + + ctx->has_transparency = false; + ctx->transparency_idx = 0; + ctx->colour_map = NULL; + + return LZW_OK; +} + +/* Exported function, documented in lzw.h */ +lzw_result lzw_decode_init_map( + struct lzw_ctx *ctx, + uint8_t minimum_code_size, + uint32_t transparency_idx, + const uint32_t *colour_table, + const uint8_t *input_data, + size_t input_length, + size_t input_pos) +{ + lzw_result res; + + if (colour_table == NULL) { + return LZW_BAD_PARAM; + } + + res = lzw_decode_init(ctx, minimum_code_size, + input_data, input_length, input_pos); + if (res != LZW_OK) { + return res; + } + + ctx->has_transparency = (transparency_idx <= 0xFF); + ctx->transparency_idx = transparency_idx; + ctx->colour_map = colour_table; + + return LZW_OK; +} + +/** + * Create new table entry. + * + * \paramin ctx LZW reading context, updated. + * \paramin code Last value code for new table entry. + */ +static inline void lzw__table_add_entry( + struct lzw_ctx *ctx, + uint16_t code) +{ + struct lzw_table_entry *entry = &ctx->tablectx->table_size; + + entry->value = code; + entry->first = ctx->prev_code_first; + entry->count = ctx->prev_code_count + 1; + entry->extends = ctx->prev_code; + + ctx->table_size++; +} + +typedef uint32_t (*lzw_writer_fn)( + struct lzw_ctx *ctx, + void *restrict output_data, + uint32_t output_length, + uint32_t output_pos, + uint16_t code, + uint16_t left); + +/** + * Get the next LZW code and write its value(s) to output buffer. + * + * \paramin ctx LZW reading context, updated. + * \paramin write_fn Function for writing pixels to output. + * \paramin output_data Array to write output values into. + * \paramin output_length Size of output array. + * \paramin,out output_written Number of values written. Updated on exit. + * \return LZW_OK on success, or appropriate error code otherwise. + */ +static inline lzw_result lzw__decode( + struct lzw_ctx *ctx, + lzw_writer_fn write_fn, + void *restrict output_data, + uint32_t output_length, + uint32_t *restrict output_written) +{ + lzw_result res; + uint16_t code; + + /* Get a new code from the input */ + res = lzw__read_code(&ctx->input, ctx->code_size, &code); + if (res != LZW_OK) { + return res; + } + + /* Handle the new code */ + if (code == ctx->eoi_code) { + /* Got End of Information code */ + return LZW_EOI_CODE; + + } else if (code > ctx->table_size) { + /* Code is invalid */ + return LZW_BAD_CODE; + + } else if (code == ctx->clear_code) { + res = lzw__handle_clear(ctx, &code); + if (res != LZW_OK) { + return res; + } + + } else if (ctx->table_size < LZW_TABLE_ENTRY_MAX) { + uint16_t size = ctx->table_size; + lzw__table_add_entry(ctx, (code < size) ? + ctx->tablecode.first : + ctx->prev_code_first); + + /* Ensure code size is increased, if needed. */ + if (size == ctx->code_max && ctx->code_size < LZW_CODE_MAX) { + ctx->code_size++; + ctx->code_max = (1 << ctx->code_size) - 1; + } + } + + *output_written += write_fn(ctx, + output_data, output_length, *output_written, + code, ctx->tablecode.count); + + /* Store details of this code as "previous code" to the context. */ + ctx->prev_code_first = ctx->tablecode.first; + ctx->prev_code_count = ctx->tablecode.count; + ctx->prev_code = code; + + return LZW_OK; +} + +/** + * Write values for this code to the output stack. + * + * If there isn't enough space in the output stack, this function will write + * the as many as it can into the output. If `ctx->output_left > 0` after + * this call, then there is more data for this code left to output. The code + * is stored to the context as `ctx->output_code`. + * + * \paramin ctx LZW reading context, updated. + * \paramin output_data Array to write output values into. + * \paramin output_length length Size of output array. + * \paramin output_used Current position in output array. + * \paramin code LZW code to output values for. + * \paramin left Number of values remaining to output for this code. + * \return Number of pixel values written. + */ +static inline uint32_t lzw__write_fn(struct lzw_ctx *ctx, + void *restrict output_data, + uint32_t output_length, + uint32_t output_used, + uint16_t code, + uint16_t left) +{ + uint8_t *restrict output_pos = (uint8_t *)output_data + output_used; + const struct lzw_table_entry * const table = ctx->table; + uint32_t space = output_length - output_used; + uint16_t count = left; + + if (count > space) { + left = count - space; + count = space; + } else { + left = 0; + } + + ctx->output_code = code; + ctx->output_left = left; + + /* Skip over any values we don't have space for. */ + for (unsigned i = left; i != 0; i--) { + const struct lzw_table_entry *entry = table + code; + code = entry->extends; + } + + output_pos += count; + for (unsigned i = count; i != 0; i--) { + const struct lzw_table_entry *entry = table + code; + *--output_pos = entry->value; + code = entry->extends; + } + + return count; +} + +/* Exported function, documented in lzw.h */ +lzw_result lzw_decode(struct lzw_ctx *ctx, + const uint8_t *restrict *const restrict output_data, + uint32_t *restrict output_written) +{ + const uint32_t output_length = sizeof(ctx->stack_base); + + *output_written = 0; + *output_data = ctx->stack_base; + + if (ctx->output_left != 0) { + *output_written += lzw__write_fn(ctx, + ctx->stack_base, output_length, *output_written, + ctx->output_code, ctx->output_left); + } + + while (*output_written != output_length) { + lzw_result res = lzw__decode(ctx, lzw__write_fn, + ctx->stack_base, output_length, output_written); + if (res != LZW_OK) { + return res; + } + } + + return LZW_OK; +} + +/** + * Write colour mapped values for this code to the output. + * + * If there isn't enough space in the output stack, this function will write + * the as many as it can into the output. If `ctx->output_left > 0` after + * this call, then there is more data for this code left to output. The code + * is stored to the context as `ctx->output_code`. + * + * \paramin ctx LZW reading context, updated. + * \paramin output_data Array to write output values into. + * \paramin output_length Size of output array. + * \paramin output_used Current position in output array. + * \paramin code LZW code to output values for. + * \paramin left Number of values remaining to output for code. + * \return Number of pixel values written. + */ +static inline uint32_t lzw__map_write_fn(struct lzw_ctx *ctx, + void *restrict output_data, + uint32_t output_length, + uint32_t output_used, + uint16_t code, + uint16_t left) +{ + uint32_t *restrict output_pos = (uint32_t *)output_data + output_used; + const struct lzw_table_entry * const table = ctx->table; + uint32_t space = output_length - output_used; + uint16_t count = left; + + if (count > space) { + left = count - space; + count = space; + } else { + left = 0; + } + + ctx->output_code = code; + ctx->output_left = left; + + for (unsigned i = left; i != 0; i--) { + const struct lzw_table_entry *entry = table + code; + code = entry->extends; + } + + output_pos += count; + if (ctx->has_transparency) { + for (unsigned i = count; i != 0; i--) { + const struct lzw_table_entry *entry = table + code; + --output_pos; + if (entry->value != ctx->transparency_idx) { + *output_pos = ctx->colour_mapentry->value; + } + code = entry->extends; + } + } else { + for (unsigned i = count; i != 0; i--) { + const struct lzw_table_entry *entry = table + code; + *--output_pos = ctx->colour_mapentry->value; + code = entry->extends; + } + } + + return count; +} + +/* Exported function, documented in lzw.h */ +lzw_result lzw_decode_map(struct lzw_ctx *ctx, + uint32_t *restrict output_data, + uint32_t output_length, + uint32_t *restrict output_written) +{ + *output_written = 0; + + if (ctx->colour_map == NULL) { + return LZW_NO_COLOUR; + } + + if (ctx->output_left != 0) { + *output_written += lzw__map_write_fn(ctx, + output_data, output_length, *output_written, + ctx->output_code, ctx->output_left); + } + + while (*output_written != output_length) { + lzw_result res = lzw__decode(ctx, lzw__map_write_fn, + output_data, output_length, output_written); + if (res != LZW_OK) { + return res; + } + } + + return LZW_OK; +}
View file
obs-studio-33.0.0.tar.xz/libobs/graphics/libnsgif/lzw.h
Added
@@ -0,0 +1,137 @@ +/* + * This file is part of NetSurf's LibNSGIF, http://www.netsurf-browser.org/ + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * + * Copyright 2017 Michael Drake <michael.drake@codethink.co.uk> + * Copyright 2021 Michael Drake <tlsa@netsurf-browser.org> + */ + +#ifndef LZW_H_ +#define LZW_H_ + +/** + * \file + * \brief LZW decompression (interface) + * + * Decoder for GIF LZW data. + */ + +/** Maximum LZW code size in bits */ +#define LZW_CODE_MAX 12 + +/* Declare lzw internal context structure */ +struct lzw_ctx; + +/** LZW decoding response codes */ +typedef enum lzw_result { + LZW_OK, /**< Success */ + LZW_OK_EOD, /**< Success; reached zero-length sub-block */ + LZW_NO_MEM, /**< Error: Out of memory */ + LZW_NO_DATA, /**< Error: Out of data */ + LZW_EOI_CODE, /**< Error: End of Information code */ + LZW_NO_COLOUR, /**< Error: No colour map provided. */ + LZW_BAD_ICODE, /**< Error: Bad initial LZW code */ + LZW_BAD_PARAM, /**< Error: Bad function parameter. */ + LZW_BAD_CODE, /**< Error: Bad LZW code */ +} lzw_result; + +/** + * Create an LZW decompression context. + * + * \paramout ctx Returns an LZW decompression context. Caller owned, + * free with lzw_context_destroy(). + * \return LZW_OK on success, or appropriate error code otherwise. + */ +lzw_result lzw_context_create( + struct lzw_ctx **ctx); + +/** + * Destroy an LZW decompression context. + * + * \paramin ctx The LZW decompression context to destroy. + */ +void lzw_context_destroy( + struct lzw_ctx *ctx); + +/** + * Initialise an LZW decompression context for decoding. + * + * \paramin ctx The LZW decompression context to initialise. + * \paramin minimum_code_size The LZW Minimum Code Size. + * \paramin input_data The compressed data. + * \paramin input_length Byte length of compressed data. + * \paramin input_pos Start position in data. Must be position + * of a size byte at sub-block start. + * \return LZW_OK on success, or appropriate error code otherwise. + */ +lzw_result lzw_decode_init( + struct lzw_ctx *ctx, + uint8_t minimum_code_size, + const uint8_t *input_data, + size_t input_length, + size_t input_pos); + +/** + * Read input codes until end of LZW context owned output buffer. + * + * Ensure anything in output is used before calling this, as anything + * there before this call will be trampled. + * + * \paramin ctx LZW reading context, updated. + * \paramout output_data Returns pointer to array of output values. + * \paramout output_written Returns the number of values written to data. + * \return LZW_OK on success, or appropriate error code otherwise. + */ +lzw_result lzw_decode(struct lzw_ctx *ctx, + const uint8_t *restrict *const restrict output_data, + uint32_t *restrict output_written); + +/** + * Initialise an LZW decompression context for decoding to colour map values. + * + * For transparency to work correctly, the given client buffer must have + * the values from the previous frame. The transparency_idx should be a value + * of 256 or above, if the frame does not have transparency. + * + * \paramin ctx The LZW decompression context to initialise. + * \paramin minimum_code_size The LZW Minimum Code Size. + * \paramin transparency_idx Index representing transparency. + * \paramin colour_table Index to pixel colour mapping. + * \paramin input_data The compressed data. + * \paramin input_length Byte length of compressed data. + * \paramin input_pos Start position in data. Must be position + * of a size byte at sub-block start. + * \return LZW_OK on success, or appropriate error code otherwise. + */ +lzw_result lzw_decode_init_map( + struct lzw_ctx *ctx, + uint8_t minimum_code_size, + uint32_t transparency_idx, + const uint32_t *colour_table, + const uint8_t *input_data, + size_t input_length, + size_t input_pos); + +/** + * Read LZW codes into client buffer, mapping output to colours. + * + * The context must have been initialised using \ref lzw_decode_init_map + * before calling this function, in order to provide the colour mapping table + * and any transparency index. + * + * Ensure anything in output is used before calling this, as anything + * there before this call will be trampled. + * + * \paramin ctx LZW reading context, updated. + * \paramin output_data Client buffer to fill with colour mapped values. + * \paramin output_length Size of output array. + * \paramout output_written Returns the number of values written to data. + * \return LZW_OK on success, or appropriate error code otherwise. + */ +lzw_result lzw_decode_map(struct lzw_ctx *ctx, + uint32_t *restrict output_data, + uint32_t output_length, + uint32_t *restrict output_written); + +#endif
View file
obs-studio-33.0.0.tar.xz/libobs/graphics/libnsgif/nsgif.h
Added
@@ -0,0 +1,527 @@ +/* + * Copyright 2004 Richard Wilson <richard.wilson@netsurf-browser.org> + * Copyright 2008 Sean Fox <dyntryx@gmail.com> + * Copyright 2013-2022 Michael Drake <tlsa@netsurf-browser.org> + * + * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ + * Licenced under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + */ + +/** + * \file + * Interface to progressive animated GIF file decoding. + */ + +#ifndef NSNSGIF_H +#define NSNSGIF_H + +#include <stdint.h> +#include <stdbool.h> +#include <inttypes.h> + +/** Representation of infinity. */ +#define NSGIF_INFINITE (UINT32_MAX) + +/** Maximum colour table size */ +#define NSGIF_MAX_COLOURS 256 + +/** + * Opaque type used by LibNSGIF to represent a GIF object in memory. + */ +typedef struct nsgif nsgif_t; + +/** + * LibNSGIF rectangle structure. + * + * * Top left coordinate is `(x0, y0)`. + * * Width is `x1 - x0`. + * * Height is `y1 - y0`. + * * Units are pixels. + */ +typedef struct nsgif_rect { + /** x co-ordinate of redraw rectangle, left */ + uint32_t x0; + /** y co-ordinate of redraw rectangle, top */ + uint32_t y0; + /** x co-ordinate of redraw rectangle, right */ + uint32_t x1; + /** y co-ordinate of redraw rectangle, bottom */ + uint32_t y1; +} nsgif_rect_t; + +/** + * LibNSGIF return codes. + */ +typedef enum { + /** + * Success. + */ + NSGIF_OK, + + /** + * Out of memory error. + */ + NSGIF_ERR_OOM, + + /** + * GIF source data is invalid, and no frames are recoverable. + */ + NSGIF_ERR_DATA, + + /** + * Frame number is not valid. + */ + NSGIF_ERR_BAD_FRAME, + + /** + * GIF source data contained an error in a frame. + */ + NSGIF_ERR_DATA_FRAME, + + /** + * Unexpected end of GIF source data. + */ + NSGIF_ERR_END_OF_DATA, + + /** + * Can't supply more data after calling \ref nsgif_data_complete. + */ + NSGIF_ERR_DATA_COMPLETE, + + /** + * The current frame cannot be displayed. + */ + NSGIF_ERR_FRAME_DISPLAY, + + /** + * Indicates an animation is complete, and \ref nsgif_reset must be + * called to restart the animation from the beginning. + */ + NSGIF_ERR_ANIMATION_END, +} nsgif_error; + +/** + * NSGIF \ref nsgif_bitmap_t pixel format. + * + * All pixel formats are 32 bits per pixel (bpp). The different formats + * allow control over the ordering of the colour channels. All colour + * channels are 8 bits wide. + * + * Note that the GIF file format only supports an on/off mask, so the + * alpha (A) component (opacity) will always have a value of `0` (fully + * transparent) or `255` (fully opaque). + */ +typedef enum nsgif_bitmap_fmt { + /** Bite-wise RGBA: Byte order: 0xRR, 0xGG, 0xBB, 0xAA. */ + NSGIF_BITMAP_FMT_R8G8B8A8, + + /** Bite-wise BGRA: Byte order: 0xBB, 0xGG, 0xRR, 0xAA. */ + NSGIF_BITMAP_FMT_B8G8R8A8, + + /** Bite-wise ARGB: Byte order: 0xAA, 0xRR, 0xGG, 0xBB. */ + NSGIF_BITMAP_FMT_A8R8G8B8, + + /** Bite-wise ABGR: Byte order: 0xAA, 0xBB, 0xGG, 0xRR. */ + NSGIF_BITMAP_FMT_A8B8G8R8, + + /** + * 32-bit RGBA (0xRRGGBBAA). + * + * * On little endian host, same as \ref NSGIF_BITMAP_FMT_A8B8G8R8. + * * On big endian host, same as \ref NSGIF_BITMAP_FMT_R8G8B8A8. + */ + NSGIF_BITMAP_FMT_RGBA8888, + + /** + * 32-bit BGRA (0xBBGGRRAA). + * + * * On little endian host, same as \ref NSGIF_BITMAP_FMT_A8R8G8B8. + * * On big endian host, same as \ref NSGIF_BITMAP_FMT_B8G8R8A8. + */ + NSGIF_BITMAP_FMT_BGRA8888, + + /** + * 32-bit ARGB (0xAARRGGBB). + * + * * On little endian host, same as \ref NSGIF_BITMAP_FMT_B8G8R8A8. + * * On big endian host, same as \ref NSGIF_BITMAP_FMT_A8R8G8B8. + */ + NSGIF_BITMAP_FMT_ARGB8888, + + /** + * 32-bit BGRA (0xAABBGGRR). + * + * * On little endian host, same as \ref NSGIF_BITMAP_FMT_R8G8B8A8. + * * On big endian host, same as \ref NSGIF_BITMAP_FMT_A8B8G8R8. + */ + NSGIF_BITMAP_FMT_ABGR8888, +} nsgif_bitmap_fmt_t; + +/** + * Client bitmap type. + * + * These are client-created and destroyed, via the \ref nsgif_bitmap_cb_vt + * callbacks, but they are owned by a \ref nsgif_t. + * + * See \ref nsgif_bitmap_fmt for pixel format information. + * + * The bitmap may have a row_span greater than the bitmap width, but the + * difference between row span and width must be a whole number of pixels + * (a multiple of four bytes). + */ +typedef void nsgif_bitmap_t; + +/** Bitmap callbacks function table */ +typedef struct nsgif_bitmap_cb_vt { + /** + * Callback to create a bitmap with the given dimensions. + * + * \paramin width Required bitmap width in pixels. + * \paramin height Required bitmap height in pixels. + * \return pointer to client's bitmap structure or NULL on error. + */ + nsgif_bitmap_t* (*create)(int width, int height); + + /** + * Callback to free a bitmap. + * + * \paramin bitmap The bitmap to destroy. + */ + void (*destroy)(nsgif_bitmap_t *bitmap); + + /** + * Get pointer to pixel buffer in a bitmap. + * + * The pixel buffer must be `(width + N) * height * sizeof(uint32_t)`. + * Where `N` is any number greater than or equal to 0. + * Note that the returned pointer to uint8_t must be 4-byte aligned. + * + * \paramin bitmap The bitmap. + * \return pointer to bitmap's pixel buffer. + */ + uint8_t* (*get_buffer)(nsgif_bitmap_t *bitmap); + + /* The following functions are optional. */ + + /** + * Set whether a bitmap can be plotted opaque. + * + * \paramin bitmap The bitmap. + * \paramin opaque Whether the current frame is opaque. + */ + void (*set_opaque)(nsgif_bitmap_t *bitmap, bool opaque); + + /** + * Tests whether a bitmap has an opaque alpha channel. + * + * \paramin bitmap The bitmap. + * \return true if the bitmap is opaque, false otherwise. + */ + bool (*test_opaque)(nsgif_bitmap_t *bitmap); + + /** + * Bitmap modified notification. + * + * \paramin bitmap The bitmap. + */ + void (*modified)(nsgif_bitmap_t *bitmap); + + /** + * Get row span in pixels. + * + * If this callback is not provided, LibNSGIF will use the width. + * + * If row span is greater than width, this callback must be provided. + * + * \paramin bitmap The bitmap. + */ + uint32_t (*get_rowspan)(nsgif_bitmap_t *bitmap); +} nsgif_bitmap_cb_vt; + +/** + * Convert an error code to a string. + * + * \paramin err The error code to convert. + * \return String representation of given error code. + */ +const char *nsgif_strerror(nsgif_error err); + +/** + * Create the NSGIF object. + * + * \paramin bitmap_vt Bitmap operation functions v-table. + * \paramin bitmap_fmt Bitmap pixel format specification. + * \paramout gif_out Return \ref nsgif_t object on success. + * + * \return NSGIF_OK on success, or appropriate error otherwise. + */ +nsgif_error nsgif_create( + const nsgif_bitmap_cb_vt *bitmap_vt, + nsgif_bitmap_fmt_t bitmap_fmt, + nsgif_t **gif_out); + +/** + * Free a NSGIF object. + * + * \paramin gif The NSGIF to free. + */ +void nsgif_destroy(nsgif_t *gif); + +/** + * Scan the source image data. + * + * This is used to feed the source data into LibNSGIF. This must be called + * before calling \ref nsgif_frame_decode. + * + * It can be called multiple times with, with increasing sizes. If it is called + * several times, as more data is available (e.g. slow network fetch) the data + * already given to \ref nsgif_data_scan must be provided each time. + * + * Once all the data has been provided, call \ref nsgif_data_complete. + * + * For example, if you call \ref nsgif_data_scan with 25 bytes of data, and then + * fetch another 10 bytes, you would need to call \ref nsgif_data_scan with a + * size of 35 bytes, and the whole 35 bytes must be contiguous memory. It is + * safe to `realloc` the source buffer between calls to \ref nsgif_data_scan. + * (The actual data pointer is allowed to be different.) + * + * If an error occurs, all previously scanned frames are retained. + * + * Note that an error returned from this function is purely informational. + * So long as at least one frame is available, you can display frames. + * + * \paramin gif The \ref nsgif_t object. + * \paramin size Number of bytes in data. + * \paramin data Raw source GIF data. + * + * \return NSGIF_OK on success, or appropriate error otherwise. + */ +nsgif_error nsgif_data_scan( + nsgif_t *gif, + size_t size, + const uint8_t *data); + +/** + * Tell libnsgif that all the gif data has been provided. + * + * Call this after calling \ref nsgif_data_scan with the the entire GIF + * source data. You can call \ref nsgif_data_scan multiple times up until + * this is called, and after this is called, \ref nsgif_data_scan will + * return an error. + * + * You can decode a GIF before this is called, however, it will fail to + * decode any truncated final frame data and will not perform loops when + * driven via \ref nsgif_frame_prepare (because it doesn't know if there + * will be more frames supplied in future data). + * + * \paramin gif The \ref nsgif_t object. + */ +void nsgif_data_complete( + nsgif_t *gif); + +/** + * Prepare to show a frame. + * + * If this is the last frame of an animation with a finite loop count, the + * returned `delay_cs` will be \ref NSGIF_INFINITE, indicating that the frame + * should be shown forever. + * + * Note that if \ref nsgif_data_complete has not been called on this gif, + * animated GIFs will not loop back to the start. Instead it will return + * \ref NSGIF_ERR_END_OF_DATA. + * + * \paramin gif The \ref nsgif_t object. + * \paramout area The area in pixels that must be redrawn. + * \paramout delay_cs Time to wait after frame_new before next frame in cs. + * \paramout frame_new The frame to decode. + * + * \return NSGIF_OK on success, or appropriate error otherwise. + */ +nsgif_error nsgif_frame_prepare( + nsgif_t *gif, + nsgif_rect_t *area, + uint32_t *delay_cs, + uint32_t *frame_new); + +/** + * Decodes a GIF frame. + * + * \paramin gif The \ref nsgif_t object. + * \paramin frame The frame number to decode. + * \paramout bitmap On success, returns pointer to the client-allocated, + * nsgif-owned client bitmap structure. + * + * \return NSGIF_OK on success, or appropriate error otherwise. + */ +nsgif_error nsgif_frame_decode( + nsgif_t *gif, + uint32_t frame, + nsgif_bitmap_t **bitmap); + +/** + * Reset a GIF animation. + * + * Some animations are only meant to loop N times, and then show the + * final frame forever. This function resets the loop and frame counters, + * so that the animation can be replayed without the overhead of recreating + * the \ref nsgif_t object and rescanning the raw data. + * + * \paramin gif A \ref nsgif_t object. + * + * \return NSGIF_OK on success, or appropriate error otherwise. + */ +nsgif_error nsgif_reset( + nsgif_t *gif); + +/** + * Information about a GIF. + */ +typedef struct nsgif_info { + /** width of GIF (may increase during decoding) */ + uint32_t width; + /** height of GIF (may increase during decoding) */ + uint32_t height; + /** number of frames decoded */ + uint32_t frame_count; + /** number of times to play animation (zero means loop forever) */ + int loop_max; + /** background colour in same pixel format as \ref nsgif_bitmap_t. */ + uint32_t background; + /** whether the GIF has a global colour table */ + bool global_palette; +} nsgif_info_t; + +/** + * Frame disposal method. + * + * Clients do not need to know about this, it is provided purely for dumping + * raw information about GIF frames. + */ +enum nsgif_disposal { + NSGIF_DISPOSAL_UNSPECIFIED, /**< No disposal method specified. */ + NSGIF_DISPOSAL_NONE, /**< Frame remains. */ + NSGIF_DISPOSAL_RESTORE_BG, /**< Clear frame to background colour. */ + NSGIF_DISPOSAL_RESTORE_PREV, /**< Restore previous frame. */ + NSGIF_DISPOSAL_RESTORE_QUIRK, /**< Alias for NSGIF_DISPOSAL_RESTORE_PREV. */ +}; + +/** + * Convert a disposal method to a string. + * + * \paramin disposal The disposal method to convert. + * \return String representation of given disposal method. + */ +const char *nsgif_str_disposal(enum nsgif_disposal disposal); + +/** + * Information about a GIF frame. + */ +typedef struct nsgif_frame_info { + /** whether the frame should be displayed/animated */ + bool display; + /** whether the frame may have transparency */ + bool transparency; + /** whether the frame has a local colour table */ + bool local_palette; + /** whether the frame is interlaced */ + bool interlaced; + /** Disposal method for previous frame; affects plotting */ + uint8_t disposal; + /** delay (in cs) before animating the frame */ + uint32_t delay; + + /** Frame's redraw rectangle. */ + nsgif_rect_t rect; +} nsgif_frame_info_t; + +/** + * Get information about a GIF from an \ref nsgif_t object. + * + * \paramin gif The \ref nsgif_t object to get info for. + * + * \return The gif info, or NULL on error. + */ +const nsgif_info_t *nsgif_get_info(const nsgif_t *gif); + +/** + * Get information about a GIF from an \ref nsgif_t object. + * + * \paramin gif The \ref nsgif_t object to get frame info for. + * \paramin frame The frame number to get info for. + * + * \return The gif frame info, or NULL on error. + */ +const nsgif_frame_info_t *nsgif_get_frame_info( + const nsgif_t *gif, + uint32_t frame); + +/** + * Get the global colour palette. + * + * If the GIF has no global colour table, this will return the default + * colour palette. + * + * Colours in same pixel format as \ref nsgif_bitmap_t. + * + * \paramin gif The \ref nsgif_t object. + * \paramout table Client buffer to hold the colour table. + * \paramout entries The number of used entries in the colour table. + */ +void nsgif_global_palette( + const nsgif_t *gif, + uint32_t tableNSGIF_MAX_COLOURS, + size_t *entries); + +/** + * Get the local colour palette for a frame. + * + * Frames may have no local palette. In this case they use the global palette. + * This function returns false if the frame has no local palette. + * + * Colours in same pixel format as \ref nsgif_bitmap_t. + * + * \paramin gif The \ref nsgif_t object. + * \paramin frame The frame to get the palette for. + * \paramout table Client buffer to hold the colour table. + * \paramout entries The number of used entries in the colour table. + * \return true if a palette is returned, false otherwise. + */ +bool nsgif_local_palette( + const nsgif_t *gif, + uint32_t frame, + uint32_t tableNSGIF_MAX_COLOURS, + size_t *entries); + +/** + * Configure handling of small frame delays. + * + * Historically people created GIFs with a tiny frame delay, however the slow + * hardware of the time meant they actually played much slower. As computers + * sped up, to prevent animations playing faster than intended, decoders came + * to ignore overly small frame delays. + * + * By default a \ref nsgif_frame_prepare() managed animation will override + * frame delays of less than 2 centiseconds with a default frame delay of + * 10 centiseconds. This matches the behaviour of web browsers and other + * renderers. + * + * Both the minimum and the default values can be overridden for a given GIF + * by the client. To get frame delays exactly as specified by the GIF file, set + * `delay_min` to zero. + * + * Note that this does not affect the frame delay in the frame info + * (\ref nsgif_frame_info_t) structure, which will always contain values + * specified by the GIF. + * + * \paramin gif The \ref nsgif_t object to configure. + * \paramin delay_min The minimum frame delay in centiseconds. + * \paramin delay_default The delay to use if a frame delay is less than + * `delay_min`. + */ +void nsgif_set_frame_delay_behaviour( + nsgif_t *gif, + uint16_t delay_min, + uint16_t delay_default); + +#endif
View file
obs-studio-32.2.2.tar.xz/libobs/obs-audio.c -> obs-studio-33.0.0.tar.xz/libobs/obs-audio.c
Changed
@@ -493,18 +493,15 @@ static inline void execute_audio_tasks(void) { struct obs_core_audio *audio = &obs->audio; - bool tasks_remaining = true; - - while (tasks_remaining) { - pthread_mutex_lock(&audio->task_mutex); - if (audio->tasks.size) { - struct obs_task_info info; - deque_pop_front(&audio->tasks, &info, sizeof(info)); - info.task(info.param); - } - tasks_remaining = !!audio->tasks.size; + pthread_mutex_lock(&audio->task_mutex); + while (audio->tasks.size) { + struct obs_task_info info; + deque_pop_front(&audio->tasks, &info, sizeof(info)); pthread_mutex_unlock(&audio->task_mutex); + info.task(info.param); + pthread_mutex_lock(&audio->task_mutex); } + pthread_mutex_unlock(&audio->task_mutex); } /* In case monitoring and an 'Audio Output Capture' source have the same device, one silences all the monitored @@ -517,15 +514,11 @@ if (!dup_src || !obs_source_active(dup_src)) return false; - if (dup_src->monitoring_type == OBS_MONITORING_TYPE_MONITOR_ONLY) - return false; - bool fader_muted = close_float(audio->monitoring_duplicating_source->volume, 0.0f, 0.0001f); bool output_capture_unmuted = !audio->monitoring_duplicating_source->muted && !fader_muted; if (output_capture_unmuted) { - if (source->monitoring_type == OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT && - source != audio->monitoring_duplicating_source) { + if (source->monitoring_enabled && source != audio->monitoring_duplicating_source) { return true; } }
View file
obs-studio-32.2.2.tar.xz/libobs/obs-canvas.c -> obs-studio-33.0.0.tar.xz/libobs/obs-canvas.c
Changed
@@ -43,17 +43,17 @@ NULL, }; -static inline void canvas_dosignal(obs_canvas_t *canvas, const char *signal_obs, const char *signal_source) +static inline void canvas_dosignal(obs_canvas_t *canvas, const char *signal_obs, const char *signal_canvas) { struct calldata data; uint8_t stack128; calldata_init_fixed(&data, stack, sizeof(stack)); calldata_set_ptr(&data, "canvas", canvas); - if (signal_obs) + if (signal_obs && !canvas->context.private) signal_handler_signal(obs->signals, signal_obs, &data); - if (signal_source) - signal_handler_signal(canvas->context.signals, signal_source, &data); + if (signal_canvas) + signal_handler_signal(canvas->context.signals, signal_canvas, &data); } static inline void canvas_dosignal_source(const char *signal, obs_canvas_t *canvas, obs_source_t *source) @@ -403,7 +403,7 @@ bool obs_canvas_reset_video(obs_canvas_t *canvas, struct obs_video_info *ovi) { - if (!ovi || canvas->flags & MAIN || obs_video_active()) + if (!ovi || canvas->flags & MAIN || obs_canvas_video_active(canvas)) return false; return obs_canvas_reset_video_internal(canvas, ovi); @@ -590,3 +590,27 @@ { obs_view_render(&canvas->view); } + +bool obs_canvas_video_active(obs_canvas_t *canvas) +{ + bool result = false; + + if (!canvas || !canvas->mix) + return result; + + pthread_mutex_lock(&obs->video.mixes_mutex); + for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { + struct obs_core_video_mix *video = obs->video.mixes.arrayi; + if (video != canvas->mix) + continue; + + if (os_atomic_load_long(&video->raw_active) > 0 || + os_atomic_load_long(&video->gpu_encoder_active) > 0) { + result = true; + break; + } + } + pthread_mutex_unlock(&obs->video.mixes_mutex); + + return result; +}
View file
obs-studio-32.2.2.tar.xz/libobs/obs-cocoa.m -> obs-studio-33.0.0.tar.xz/libobs/obs-cocoa.m
Changed
@@ -35,15 +35,6 @@ return ""; } -void add_default_module_paths(void) -{ - NSURL *pluginURL = NSBundle mainBundle builtInPlugInsURL; - NSString *pluginModulePath = pluginURL path stringByAppendingString:@"/%module%.plugin/Contents/MacOS/"; - NSString *pluginDataPath = pluginURL path stringByAppendingString:@"/%module%.plugin/Contents/Resources/"; - - obs_add_module_path(pluginModulePath.UTF8String, pluginDataPath.UTF8String); -} - char *find_libobs_data_file(const char *file) { NSBundle *frameworkBundle = NSBundle bundleWithIdentifier:@"com.obsproject.libobs";
View file
obs-studio-32.2.2.tar.xz/libobs/obs-config.h -> obs-studio-33.0.0.tar.xz/libobs/obs-config.h
Changed
@@ -27,21 +27,21 @@ /* * Increment if major breaking API changes */ -#define LIBOBS_API_MAJOR_VER 32 +#define LIBOBS_API_MAJOR_VER 33 /* * Increment if backward-compatible additions * * Reset to zero each major version */ -#define LIBOBS_API_MINOR_VER 2 +#define LIBOBS_API_MINOR_VER 0 /* * Increment if backward-compatible bug fix * * Reset to zero each major or minor version */ -#define LIBOBS_API_PATCH_VER 2 +#define LIBOBS_API_PATCH_VER 0 #define MAKE_SEMANTIC_VERSION(major, minor, patch) ((major << 24) | (minor << 16) | patch)
View file
obs-studio-33.0.0.tar.xz/libobs/obs-core-modules-loader-mac.m
Added
@@ -0,0 +1,60 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#import "obs-core-modules.h" + +#import <obs-internal.h> +#import <obs.h> +#import <util/dstr.h> +#import <util/platform.h> + +#import <Foundation/Foundation.h> + +extern bool find_core_module(struct obs_runtime_module_info *info, obs_find_module_callback2_t callback, void *data); + +void load_core_modules(obs_find_module_callback2_t callback, void *data) +{ + NSURL *pluginURL = NSBundle mainBundle builtInPlugInsURL; + NSString *pluginBasePath = pluginURL path; + + for (unsigned int i = 0; i < obs_core_modules_count; i++) { + const char *name = obs_core_modulesi; + NSString *moduleName = NSString stringWithUTF8String:name; + + NSString *binPath = + NSString stringWithFormat:@"%@/%@.plugin/Contents/MacOS/%@", pluginBasePath, moduleName, moduleName; + + NSString *dataPath = + NSString stringWithFormat:@"%@/%@.plugin/Contents/Resources/", pluginBasePath, moduleName; + + if (!NSFileManager defaultManager fileExistsAtPath:binPath) { + blog(LOG_ERROR, "Core Module %s required but missing!", name); + return; + } + + struct obs_runtime_module_info module_info = { + .path_info = {.binary = binPath UTF8String, .data = dataPath UTF8String}, + .type = OBS_MODULE_TYPE_CORE, + .name = name + }; + + if (!find_core_module(&module_info, callback, data)) { + blog(LOG_ERROR, "Failed to load core module %s", name); + return; + } + } +}
View file
obs-studio-33.0.0.tar.xz/libobs/obs-core-modules-loader-nix.c
Added
@@ -0,0 +1,62 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "obs-core-modules.h" + +#include <obs-internal.h> +#include <obs.h> +#include <util/dstr.h> +#include <util/platform.h> + +const char *core_module_bin = "../" OBS_PLUGIN_PATH "/%module%"; +const char *core_module_data = "../" OBS_DATA_PATH "/obs-modules/core/%module%"; + +extern bool find_core_module(struct obs_runtime_module_info *info, obs_find_module_callback2_t callback, void *data); + +void load_core_modules(obs_find_module_callback2_t callback, void *data) +{ + char *core_bin_path = os_get_executable_path_ptr(core_module_bin); + char *core_data_path = os_get_executable_path_ptr(core_module_data); + + for (unsigned int i = 0; i < obs_core_modules_count; i++) { + const char *name = obs_core_modulesi; + struct dstr bin_path; + struct dstr data_path; + dstr_init_copy(&bin_path, core_bin_path); + dstr_init_copy(&data_path, core_data_path); + dstr_replace(&bin_path, "%module%", name); + dstr_replace(&data_path, "%module%", name); + + struct obs_runtime_module_info module_info = {.path_info = {.binary = bin_path.array, + .data = data_path.array}, + .type = OBS_MODULE_TYPE_CORE, + .name = name}; + + bool found = find_core_module(&module_info, callback, data); + + dstr_free(&bin_path); + dstr_free(&data_path); + + if (!found) { + blog(LOG_ERROR, "Failed to load core module %s", name); + break; + } + } + + bfree(core_bin_path); + bfree(core_data_path); +}
View file
obs-studio-33.0.0.tar.xz/libobs/obs-core-modules-loader-win.c
Added
@@ -0,0 +1,66 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "obs-core-modules.h" + +#include <obs-internal.h> +#include <obs.h> +#include <util/dstr.h> +#include <util/platform.h> + +const char *core_module_bin = "../../core/%module%/%module%"; +const char *core_module_data = "../../core/%module%/data"; + +extern bool find_core_module(struct obs_runtime_module_info *info, obs_find_module_callback2_t callback, void *data); + +void load_core_modules(obs_find_module_callback2_t callback, void *data) +{ + char *core_bin_path = os_get_abs_path_ptr(core_module_bin); + char *core_data_path = os_get_abs_path_ptr(core_module_data); + + for (unsigned int i = 0; i < obs_core_modules_count; i++) { + const char *name = obs_core_modulesi; + struct dstr bin_path; + struct dstr data_path; + dstr_init_copy(&bin_path, core_bin_path); + dstr_init_copy(&data_path, core_data_path); + dstr_replace(&bin_path, "%module%", name); + dstr_replace(&data_path, "%module%", name); + + // Convert Windows backslash to forward slash + dstr_replace(&bin_path, "\\", "/"); + dstr_replace(&data_path, "\\", "/"); + + struct obs_runtime_module_info module_info = {.path_info = {.binary = bin_path.array, + .data = data_path.array}, + .type = OBS_MODULE_TYPE_CORE, + .name = name}; + + bool found = find_core_module(&module_info, callback, data); + + dstr_free(&bin_path); + dstr_free(&data_path); + + if (!found) { + blog(LOG_ERROR, "Failed to load core module %s", name); + break; + } + } + + bfree(core_bin_path); + bfree(core_data_path); +}
View file
obs-studio-33.0.0.tar.xz/libobs/obs-core-modules-loader.h
Added
@@ -0,0 +1,22 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <obs-internal.h> + +extern void load_core_modules(obs_find_module_callback2_t callback, void *data);
View file
obs-studio-33.0.0.tar.xz/libobs/obs-core-modules.c.in
Added
@@ -0,0 +1,34 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <string.h> +#include <obs-core-modules.h> + +const char *obs_core_modules = { +@OBS_CORE_MODULE_LIST@ +}; + +const unsigned int obs_core_modules_count = @OBS_CORE_MODULE_COUNT@; + +bool obs_in_core_module_list(const char *name) { + for (unsigned int i = 0; i < obs_core_modules_count; i++) { + if(strcmp(obs_core_modulesi, name) == 0) { + return true; + } + } + return false; +}
View file
obs-studio-33.0.0.tar.xz/libobs/obs-core-modules.h
Added
@@ -0,0 +1,25 @@ +/****************************************************************************** + Copyright (C) 2026 by FiniteSingularity <finitesingularityttv@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <stdbool.h> + +extern const char *obs_core_modules; +extern const unsigned int obs_core_modules_count; + +extern bool obs_in_core_module_list(const char *name);
View file
obs-studio-32.2.2.tar.xz/libobs/obs-hotkey.c -> obs-studio-33.0.0.tar.xz/libobs/obs-hotkey.c
Changed
@@ -1374,7 +1374,8 @@ } void obs_hotkeys_set_audio_hotkeys_translations(const char *mute, const char *unmute, const char *push_to_mute, - const char *push_to_talk) + const char *push_to_talk, const char *monitor_on, + const char *monitor_off) { #define SET_T(n) \ bfree(obs->hotkeys.n); \ @@ -1383,6 +1384,8 @@ SET_T(unmute); SET_T(push_to_mute); SET_T(push_to_talk); + SET_T(monitor_on); + SET_T(monitor_off); #undef SET_T }
View file
obs-studio-32.2.2.tar.xz/libobs/obs-hotkey.h -> obs-studio-33.0.0.tar.xz/libobs/obs-hotkey.h
Changed
@@ -134,7 +134,8 @@ obs_hotkeys_set_translations_s(translations, sizeof(struct obs_hotkeys_translations)) EXPORT void obs_hotkeys_set_audio_hotkeys_translations(const char *mute, const char *unmute, const char *push_to_mute, - const char *push_to_talk); + const char *push_to_talk, const char *monitor_on, + const char *monitor_off); EXPORT void obs_hotkeys_set_sceneitem_hotkeys_translations(const char *show, const char *hide);
View file
obs-studio-32.2.2.tar.xz/libobs/obs-internal.h -> obs-studio-33.0.0.tar.xz/libobs/obs-internal.h
Changed
@@ -135,6 +135,8 @@ DARRAY(char *) outputs; DARRAY(char *) encoders; DARRAY(char *) services; + + enum obs_runtime_module_type module_type; }; struct obs_disabled_module { @@ -156,6 +158,7 @@ struct obs_module_path { char *bin; char *data; + enum obs_runtime_module_type type; }; static inline void free_module_path(struct obs_module_path *omp) @@ -537,6 +540,8 @@ char *push_to_talk; char *sceneitem_show; char *sceneitem_hide; + char *monitor_on; + char *monitor_off; }; typedef DARRAY(struct obs_source_info) obs_source_info_array_t; @@ -548,7 +553,6 @@ DARRAY(struct obs_module_path) module_paths; DARRAY(char *) safe_modules; DARRAY(char *) disabled_modules; - DARRAY(char *) core_modules; obs_source_info_array_t source_types; obs_source_info_array_t input_types; @@ -576,6 +580,8 @@ os_task_queue_t *destruction_task_thread; obs_task_handler_t ui_task_handler; + + bool core_modules_loaded; }; extern struct obs_core *obs; @@ -991,6 +997,8 @@ /* audio monitoring */ struct audio_monitor *monitor; enum obs_monitoring_type monitoring_type; + bool monitoring_enabled; + obs_hotkey_pair_id monitor_on_off_key; /* media action queue */ DARRAY(struct media_action) media_actions;
View file
obs-studio-32.2.2.tar.xz/libobs/obs-module.c -> obs-studio-33.0.0.tar.xz/libobs/obs-module.c
Changed
@@ -15,12 +15,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ -#include "util/platform.h" -#include "util/dstr.h" - +#include "obs-core-modules-loader.h" +#include "obs-core-modules.h" #include "obs-defs.h" #include "obs-internal.h" #include "obs-module.h" +#include "util/dstr.h" +#include "util/platform.h" extern const char *get_module_extension(void); @@ -63,7 +64,8 @@ bool obs_module_get_locale_string(const obs_module_t *mod, const char *lookup_string, const char **translated_string) { - if (mod->get_string) { + assert(mod); + if (mod && mod->get_string) { return mod->get_string(lookup_string, translated_string); } @@ -424,15 +426,6 @@ da_push_back(obs->safe_modules, &item); } -void obs_add_core_module(const char *name) -{ - if (!obs || !name) - return; - - char *item = bstrdup(name); - da_push_back(obs->core_modules, &item); -} - void obs_add_disabled_module(const char *name) { if (!obs || !name) @@ -464,12 +457,7 @@ static bool is_core_module(const char *name) { - for (size_t i = 0; i < obs->core_modules.num; i++) { - if (strcmp(name, obs->core_modules.arrayi) == 0) - return true; - } - - return false; + return obs_in_core_module_list(name); } static bool is_disabled_module(const char *name) @@ -511,12 +499,32 @@ return; } - if (is_disabled_module(info->name)) { + if (info->type != OBS_MODULE_TYPE_CORE && is_disabled_module(info->name)) { obs_create_disabled_module(&disabled_module, info->bin_path, info->data_path, OBS_MODULE_DISABLED); blog(LOG_WARNING, "Skipping module '%s', is disabled", info->name); return; } + /* This is a necessary check until legacy plugin loading is removed in a future update. + * It covers portable installs where the old core modules still live in `obs-plugins`. + */ + if (info->type == OBS_MODULE_TYPE_LEGACY_PLUGIN && is_core_module(info->name)) { + blog(LOG_WARNING, "Skipping module '%s', is a legacy core module", info->name); + return; + } + + obs_module_t *existing_module = obs_get_module(info->name); + if (info->type != OBS_MODULE_TYPE_CORE && existing_module != NULL) { + if (info->type == OBS_MODULE_TYPE_LEGACY_PLUGIN) { + blog(LOG_WARNING, "Skipping legacy plugin '%s' at '%s', already loaded from '%s'", info->name, + info->bin_path, existing_module->bin_path); + } else { + blog(LOG_WARNING, "Skipping plugin '%s' at '%s', already loaded from '%s'", info->name, + info->bin_path, existing_module->bin_path); + } + return; + } + int code = obs_open_module(&module, info->bin_path, info->data_path); switch (code) { case MODULE_MISSING_EXPORTS: @@ -543,6 +551,9 @@ free_module(module); obs_create_disabled_module(&disabled_module, info->bin_path, info->data_path, OBS_MODULE_FAILED_TO_INITIALIZE); + disabled_module->module_type = info->type; + } else { + module->module_type = info->type; } UNUSED_PARAMETER(param); @@ -556,42 +567,45 @@ } } -static const char *obs_load_all_modules_name = "obs_load_all_modules"; -#ifdef _WIN32 -static const char *reset_win32_symbol_paths_name = "reset_win32_symbol_paths"; -#endif +void obs_load_all_modules(void) {} -void obs_load_all_modules(void) +void obs_load_all_modules2(struct obs_module_failure_info *mfi) { - profile_start(obs_load_all_modules_name); - obs_find_modules2(load_all_callback, NULL); -#ifdef _WIN32 - profile_start(reset_win32_symbol_paths_name); - reset_win32_symbol_paths(); - profile_end(reset_win32_symbol_paths_name); -#endif - profile_end(obs_load_all_modules_name); + UNUSED_PARAMETER(mfi); } -static const char *obs_load_all_modules2_name = "obs_load_all_modules2"; +bool obs_load_core_modules(void) +{ + if (obs->core_modules_loaded) { + return true; + } -void obs_load_all_modules2(struct obs_module_failure_info *mfi) + struct fail_info error = {0}; + + load_core_modules(load_all_callback, &error); + + obs->core_modules_loaded = error.fail_count == 0; + + dstr_free(&error.fail_modules); + + return obs->core_modules_loaded; +} + +static void find_modules_in_path(struct obs_module_path *omp, obs_find_module_callback2_t callback, void *param); + +void obs_load_plugins(struct obs_runtime_module_info *info, struct obs_module_failure_info *error) { - struct fail_info fail_info = {0}; - memset(mfi, 0, sizeof(*mfi)); + struct obs_module_path omp = {.bin = (char *)info->path_info.binary, + .data = (char *)info->path_info.data, + .type = info->type}; - profile_start(obs_load_all_modules2_name); - obs_find_modules2(load_all_callback, &fail_info); -#ifdef _WIN32 - profile_start(reset_win32_symbol_paths_name); - reset_win32_symbol_paths(); - profile_end(reset_win32_symbol_paths_name); -#endif - profile_end(obs_load_all_modules2_name); + struct fail_info failure = {0}; + + find_modules_in_path(&omp, load_all_callback, &failure); - mfi->count = fail_info.fail_count; - mfi->failed_modules = strlist_split(fail_info.fail_modules.array, ';', false); - dstr_free(&fail_info.fail_modules); + error->count = failure.fail_count; + error->failed_modules = strlist_split(failure.fail_modules.array, ';', false); + dstr_free(&failure.fail_modules); } void obs_module_failure_info_free(struct obs_module_failure_info *mfi) @@ -602,8 +616,17 @@ } } +#ifdef _WIN32 +static const char *reset_win32_symbol_paths_name = "reset_win32_symbol_paths"; +#endif + void obs_post_load_modules(void) { +#ifdef _WIN32 + profile_start(reset_win32_symbol_paths_name); + reset_win32_symbol_paths(); + profile_end(reset_win32_symbol_paths_name); +#endif for (obs_module_t *mod = obs->first_module; !!mod; mod = mod->next) if (mod->post_load) mod->post_load(); @@ -632,6 +655,62 @@ return parsed_data_dir.array; } +/* Function to find a specifically defined module. Used for loading core modules by name. + * info->path_info.binary should be path to the module binary, without its file extension. + * info->path_info.data should be path to the module data directory including the module name. + */ +bool find_core_module(struct obs_runtime_module_info *info, obs_find_module_callback2_t callback, void *data) +{ + const char *file_name = strrchr(info->path_info.binary, '/'); + const char *name = file_name ? (file_name + 1) : info->path_info.binary; + info->name = name; + + if (info->type != OBS_MODULE_TYPE_CORE) { + blog(LOG_WARNING, "Module %s is not a core module, and must be loaded with the plugin loader.", name); + return false; + } + + bool found = false; + + struct dstr module_path; + dstr_init_copy(&module_path, info->path_info.binary); + dstr_cat(&module_path, get_module_extension()); + + char *parsed_data_directory; + parsed_data_directory = make_data_directory(name, info->path_info.data); + + if (os_file_exists(module_path.array)) { + struct obs_module_info2 callback_info = {.bin_path = module_path.array, + .data_path = parsed_data_directory, + .name = name, + .type = info->type}; + + callback(data, &callback_info); + found = true; + } + + bfree(parsed_data_directory); + dstr_free(&module_path); + + return found; +} + +bool obs_is_core_module(obs_module_t *module) +{ + if (!module) + return false; + return module->module_type == OBS_MODULE_TYPE_CORE; +} + +bool obs_is_legacy_module(obs_module_t *module) +{ + if (!module) { + return false; + } + + return module->module_type == OBS_MODULE_TYPE_LEGACY_PLUGIN; +} + static bool parse_binary_from_directory(struct dstr *parsed_bin_path, const char *bin_path, const char *file) { struct dstr directory = {0}; @@ -705,6 +784,7 @@ info.bin_path = parsed_bin_path.array; info.data_path = parsed_data_dir; info.name = name.array; + info.type = omp->type; callback(param, &info); } @@ -721,7 +801,6 @@ os_glob_t *gi; dstr_copy(&search_path, omp->bin); - module_start = strstr(search_path.array, "%module%"); if (module_start) { dstr_resize(&search_path, module_start - search_path.array);
View file
obs-studio-32.2.2.tar.xz/libobs/obs-module.h -> obs-studio-33.0.0.tar.xz/libobs/obs-module.h
Changed
@@ -100,7 +100,21 @@ */ MODULE_EXPORT bool obs_module_load(void); -/** Optional: Called when the module is unloaded. */ +/** + * Optional: Called when libobs is shutting down and the module is about + * to be unloaded. All libobs objects are still active and valid at this + * point. Use this function to save user settings and release any strong + * references that the module itself is holding to libobs objects (sources, + * canvases, outputs, encoders, and services). + * + * Do not attempt to release or destroy any still-active objects provided + * by the module - ensure that they can continue functioning even after + * returning from this function, as libobs may still need to call into the + * module's callbacks (e.g., destroy) to clean up any remaining instances. + * + * After this function returns, do not make any further libobs API calls + * outside of libobs callbacks. + */ MODULE_EXPORT void obs_module_unload(void); /** Optional: Called when all modules have finished loading */
View file
obs-studio-32.2.2.tar.xz/libobs/obs-nix.c -> obs-studio-33.0.0.tar.xz/libobs/obs-nix.c
Changed
@@ -47,49 +47,8 @@ return ".so"; } -#define FLATPAK_PLUGIN_PATH "/app/plugins" - -static const char *module_bin = { - "../../obs-plugins/64bit", - OBS_INSTALL_PREFIX "/" OBS_PLUGIN_DESTINATION, - FLATPAK_PLUGIN_PATH "/" OBS_PLUGIN_DESTINATION, -}; - -static const char *module_data = { - OBS_DATA_PATH "/obs-plugins/%module%", - OBS_INSTALL_DATA_PATH "/obs-plugins/%module%", - FLATPAK_PLUGIN_PATH "/share/obs/obs-plugins/%module%", -}; - -static const int module_patterns_size = sizeof(module_bin) / sizeof(module_bin0); - static const struct obs_nix_hotkeys_vtable *hotkeys_vtable = NULL; -void add_default_module_paths(void) -{ - char *module_bin_path = os_get_executable_path_ptr("../" OBS_PLUGIN_PATH); - char *module_data_path = os_get_executable_path_ptr("../" OBS_DATA_PATH "/obs-plugins/%module%"); - - if (module_bin_path && module_data_path) { - char *abs_module_bin_path = os_get_abs_path_ptr(module_bin_path); - char *abs_module_install_path = os_get_abs_path_ptr(OBS_INSTALL_PREFIX "/" OBS_PLUGIN_DESTINATION); - - if (abs_module_bin_path && - (!abs_module_install_path || strcmp(abs_module_bin_path, abs_module_install_path) != 0)) { - obs_add_module_path(module_bin_path, module_data_path); - } - bfree(abs_module_install_path); - bfree(abs_module_bin_path); - } - - bfree(module_bin_path); - bfree(module_data_path); - - for (int i = 0; i < module_patterns_size; i++) { - obs_add_module_path(module_bini, module_datai); - } -} - /* * /usr/local/share/libobs * /usr/share/libobs
View file
obs-studio-32.2.2.tar.xz/libobs/obs-properties.c -> obs-studio-33.0.0.tar.xz/libobs/obs-properties.c
Changed
@@ -590,7 +590,7 @@ data->type = type; data->default_path = bstrdup(default_path); - if (data->type == OBS_PATH_FILE) + if (data->type == OBS_PATH_FILE || data->type == OBS_PATH_FILE_SAVE) data->filter = bstrdup(filter); return p;
View file
obs-studio-32.2.2.tar.xz/libobs/obs-scene.c -> obs-studio-33.0.0.tar.xz/libobs/obs-scene.c
Changed
@@ -1961,7 +1961,8 @@ for (size_t i = 0; i < items.num; i++) { item = items.arrayi; - source = make_unique ? dup_child(&items, i, new_scene, make_private) : new_ref(item->source); + source = (make_unique || item->is_group) ? dup_child(&items, i, new_scene, make_private) + : new_ref(item->source); if (source) { struct obs_scene_item *new_item = obs_scene_add(new_scene, source);
View file
obs-studio-32.2.2.tar.xz/libobs/obs-source.c -> obs-studio-33.0.0.tar.xz/libobs/obs-source.c
Changed
@@ -96,6 +96,7 @@ "void audio_balance(ptr source, in out float balance)", "void audio_mixers(ptr source, in out int mixers)", "void audio_monitoring(ptr source, int type)", + "void monitor(ptr source, bool monitor)", "void audio_activate(ptr source)", "void audio_deactivate(ptr source)", "void filter_add(ptr source, ptr filter)", @@ -348,10 +349,40 @@ source->user_push_to_talk_pressed = pressed; } +static bool obs_source_hotkey_monitor_on(void *data, obs_hotkey_pair_id id, obs_hotkey_t *key, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(key); + + struct obs_source *source = data; + + if (!pressed || obs_source_get_monitoring_enabled(source)) + return false; + + obs_source_set_monitoring_enabled(source, true); + return true; +} + +static bool obs_source_hotkey_monitor_off(void *data, obs_hotkey_pair_id id, obs_hotkey_t *key, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(key); + + struct obs_source *source = data; + + if (!pressed || !obs_source_get_monitoring_enabled(source)) + return false; + + obs_source_set_monitoring_enabled(source, false); + return true; +} + static void obs_source_init_audio_hotkeys(struct obs_source *source) { if (!(source->info.output_flags & OBS_SOURCE_AUDIO) || source->info.type != OBS_SOURCE_TYPE_INPUT) { - source->mute_unmute_key = OBS_INVALID_HOTKEY_ID; + source->mute_unmute_key = OBS_INVALID_HOTKEY_PAIR_ID; + source->monitor_on_off_key = OBS_INVALID_HOTKEY_PAIR_ID; + source->push_to_mute_key = OBS_INVALID_HOTKEY_ID; source->push_to_talk_key = OBS_INVALID_HOTKEY_ID; return; } @@ -361,6 +392,10 @@ obs_source_hotkey_mute, obs_source_hotkey_unmute, source, source); + source->monitor_on_off_key = obs_hotkey_pair_register_source( + source, "libobs.monitor-on", obs->hotkeys.monitor_on, "libobs.monitor-off", obs->hotkeys.monitor_off, + obs_source_hotkey_monitor_on, obs_source_hotkey_monitor_off, source, source); + source->push_to_mute_key = obs_hotkey_register_source(source, "libobs.push-to-mute", obs->hotkeys.push_to_mute, obs_source_hotkey_push_to_mute, source); @@ -458,6 +493,7 @@ } source->mute_unmute_key = OBS_INVALID_HOTKEY_PAIR_ID; + source->monitor_on_off_key = OBS_INVALID_HOTKEY_PAIR_ID; source->push_to_mute_key = OBS_INVALID_HOTKEY_ID; source->push_to_talk_key = OBS_INVALID_HOTKEY_ID; source->last_obs_ver = last_obs_ver; @@ -784,6 +820,7 @@ obs_hotkey_unregister(source->push_to_talk_key); obs_hotkey_unregister(source->push_to_mute_key); obs_hotkey_pair_unregister(source->mute_unmute_key); + obs_hotkey_pair_unregister(source->monitor_on_off_key); for (i = 0; i < source->async_cache.num; i++) obs_source_frame_decref(source->async_cache.arrayi.frame); @@ -5556,28 +5593,39 @@ pthread_mutex_unlock(&source->audio_cb_mutex); } -void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type) +void obs_source_set_monitoring_enabled(obs_source_t *source, bool enabled) { struct calldata data; + struct calldata compat_data; uint8_t stack128; + enum obs_monitoring_type compat_type; bool was_on; - bool now_on; - if (!obs_source_valid(source, "obs_source_set_monitoring_type")) + if (!obs_source_valid(source, "obs_source_set_monitoring_enabled")) return; - if (source->monitoring_type == type) + + if (source->monitoring_enabled == enabled) return; + compat_type = enabled ? OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT : OBS_MONITORING_TYPE_NONE; + calldata_init_fixed(&data, stack, sizeof(stack)); calldata_set_ptr(&data, "source", source); - calldata_set_int(&data, "type", type); + calldata_set_bool(&data, "monitor", enabled); + + signal_handler_signal(source->context.signals, "monitor", &data); - signal_handler_signal(source->context.signals, "audio_monitoring", &data); + calldata_init_fixed(&compat_data, stack, sizeof(stack)); + calldata_set_ptr(&compat_data, "source", source); + calldata_set_int(&compat_data, "type", compat_type); - was_on = source->monitoring_type != OBS_MONITORING_TYPE_NONE; - now_on = type != OBS_MONITORING_TYPE_NONE; + signal_handler_signal(source->context.signals, "audio_monitoring", &compat_data); - if (was_on != now_on) { + was_on = source->monitoring_enabled; + source->monitoring_enabled = enabled; + source->monitoring_type = compat_type; + + if (was_on != enabled) { if (!was_on) { source->monitor = audio_monitor_create(source); } else { @@ -5585,12 +5633,29 @@ source->monitor = NULL; } } +} - source->monitoring_type = type; +bool obs_source_get_monitoring_enabled(const obs_source_t *source) +{ + return obs_source_valid(source, "obs_source_get_monitoring_enabled") ? source->monitoring_enabled : false; +} + +void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type) +{ + if (!obs_source_valid(source, "obs_source_set_monitoring_type")) + return; + + blog(LOG_WARNING, + "obs_source_set_monitoring_type is deprecated. Use obs_source_set_monitoring_enabled instead."); + + obs_source_set_monitoring_enabled(source, type != OBS_MONITORING_TYPE_NONE); } enum obs_monitoring_type obs_source_get_monitoring_type(const obs_source_t *source) { + blog(LOG_WARNING, + "obs_source_get_monitoring_type is deprecated. Use obs_source_get_monitoring_enabled instead."); + return obs_source_valid(source, "obs_source_get_monitoring_type") ? source->monitoring_type : OBS_MONITORING_TYPE_NONE; }
View file
obs-studio-32.2.2.tar.xz/libobs/obs-video.c -> obs-studio-33.0.0.tar.xz/libobs/obs-video.c
Changed
@@ -957,18 +957,15 @@ static void execute_graphics_tasks(void) { struct obs_core_video *video = &obs->video; - bool tasks_remaining = true; - - while (tasks_remaining) { - pthread_mutex_lock(&video->task_mutex); - if (video->tasks.size) { - struct obs_task_info info; - deque_pop_front(&video->tasks, &info, sizeof(info)); - info.task(info.param); - } - tasks_remaining = !!video->tasks.size; + pthread_mutex_lock(&video->task_mutex); + while (video->tasks.size) { + struct obs_task_info info; + deque_pop_front(&video->tasks, &info, sizeof(info)); pthread_mutex_unlock(&video->task_mutex); + info.task(info.param); + pthread_mutex_lock(&video->task_mutex); } + pthread_mutex_unlock(&video->task_mutex); } #ifdef _WIN32
View file
obs-studio-32.2.2.tar.xz/libobs/obs-windows.c -> obs-studio-33.0.0.tar.xz/libobs/obs-windows.c
Changed
@@ -34,18 +34,6 @@ return ".dll"; } -static const char *module_bin = {"../../obs-plugins/64bit"}; - -static const char *module_data = {"../../data/obs-plugins/%module%"}; - -static const int module_patterns_size = sizeof(module_bin) / sizeof(module_bin0); - -void add_default_module_paths(void) -{ - for (int i = 0; i < module_patterns_size; i++) - obs_add_module_path(module_bini, module_datai); -} - /* on windows, points to base directory/data/libobs */ char *find_libobs_data_file(const char *file) {
View file
obs-studio-32.2.2.tar.xz/libobs/obs.c -> obs-studio-33.0.0.tar.xz/libobs/obs.c
Changed
@@ -27,7 +27,6 @@ static THREAD_LOCAL bool is_ui_thread = false; -extern void add_default_module_paths(void); extern char *find_libobs_data_file(const char *file); static inline void make_video_info(struct video_output_info *vi, struct obs_video_info *ovi) @@ -645,10 +644,14 @@ gs_enter_context(obs->video.graphics); - if (video->gpu_conversion && !obs_init_gpu_conversion(video)) + if (video->gpu_conversion && !obs_init_gpu_conversion(video)) { + gs_leave_context(); return OBS_VIDEO_FAIL; - if (!obs_init_textures(video)) + } + if (!obs_init_textures(video)) { + gs_leave_context(); return OBS_VIDEO_FAIL; + } gs_leave_context(); @@ -1195,6 +1198,8 @@ bfree(hotkeys->push_to_talk); bfree(hotkeys->sceneitem_show); bfree(hotkeys->sceneitem_hide); + bfree(hotkeys->monitor_on); + bfree(hotkeys->monitor_off); obs_hotkey_name_map_free(); @@ -1261,7 +1266,8 @@ obs_register_source(&scene_info); obs_register_source(&group_info); obs_register_source(&audio_line_info); - add_default_module_paths(); + + obs->core_modules_loaded = false; return true; } @@ -1457,11 +1463,6 @@ } da_free(obs->disabled_modules); - for (size_t i = 0; i < obs->core_modules.num; i++) { - bfree(obs->core_modules.arrayi); - } - da_free(obs->core_modules); - if (obs->name_store_owned) profiler_name_store_free(obs->name_store); @@ -2354,7 +2355,12 @@ obs_source_set_audio_mixers(source, 0x3F); } } - obs_source_set_monitoring_type(source, (enum obs_monitoring_type)monitoring_type); + + obs_data_set_default_bool(source_data, "monitoring_enabled", false); + if (prev_ver < MAKE_SEMANTIC_VERSION(33, 0, 0)) { + obs_data_set_bool(source_data, "monitoring_enabled", monitoring_type != OBS_MONITORING_TYPE_NONE); + } + obs_source_set_monitoring_enabled(source, obs_data_get_bool(source_data, "monitoring_enabled")); obs_data_release(source->private_settings); source->private_settings = obs_data_get_obj(source_data, "private_settings"); @@ -2456,7 +2462,7 @@ uint64_t ptm_delay = obs_source_get_push_to_mute_delay(source); bool push_to_talk = obs_source_push_to_talk_enabled(source); uint64_t ptt_delay = obs_source_get_push_to_talk_delay(source); - int m_type = (int)obs_source_get_monitoring_type(source); + bool monitoring = obs_source_get_monitoring_enabled(source); int di_mode = (int)obs_source_get_deinterlace_mode(source); int di_order = (int)obs_source_get_deinterlace_field_order(source); obs_canvas_t *canvas = obs_source_get_canvas(source); @@ -2492,7 +2498,9 @@ obs_data_set_obj(source_data, "hotkeys", hotkey_data); obs_data_set_int(source_data, "deinterlace_mode", di_mode); obs_data_set_int(source_data, "deinterlace_field_order", di_order); - obs_data_set_int(source_data, "monitoring_type", m_type); + obs_data_set_int(source_data, "monitoring_type", + monitoring ? (int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT : (int)OBS_MONITORING_TYPE_NONE); + obs_data_set_bool(source_data, "monitoring_enabled", monitoring); if (canvas) { obs_data_set_string(source_data, "canvas_uuid", obs_canvas_get_uuid(canvas));
View file
obs-studio-32.2.2.tar.xz/libobs/obs.h -> obs-studio-33.0.0.tar.xz/libobs/obs.h
Changed
@@ -173,6 +173,26 @@ OBS_MODULE_FAILED_TO_INITIALIZE, }; +enum obs_runtime_module_type { + OBS_MODULE_TYPE_UNDEFINED, + OBS_MODULE_TYPE_CORE, + OBS_MODULE_TYPE_PLUGIN, + OBS_MODULE_TYPE_LEGACY_PLUGIN, +}; + +#ifndef SWIG +struct obs_runtime_module_path { + const char *binary; + const char *data; +}; + +struct obs_runtime_module_info { + struct obs_runtime_module_path path_info; + enum obs_runtime_module_type type; + const char *name; +}; +#endif + struct obs_transform_info { struct vec2 pos; float rot; @@ -566,16 +586,8 @@ */ EXPORT void obs_add_safe_module(const char *name); -/** - * Adds a module to the list of core modules (which cannot be disabled). - * If the list is empty, all modules are allowed. - * - * @param name Specifies the module's name (filename sans extension). - */ -EXPORT void obs_add_core_module(const char *name); - /** Automatically loads all modules from module paths (convenience function) */ -EXPORT void obs_load_all_modules(void); +OBS_DEPRECATED EXPORT void obs_load_all_modules(void); struct obs_module_failure_info { char **failed_modules; @@ -583,7 +595,7 @@ }; EXPORT void obs_module_failure_info_free(struct obs_module_failure_info *mfi); -EXPORT void obs_load_all_modules2(struct obs_module_failure_info *mfi); +OBS_DEPRECATED EXPORT void obs_load_all_modules2(struct obs_module_failure_info *mfi); /** Notifies modules that all modules have been loaded. This function should * be called after all modules have been loaded. */ @@ -603,12 +615,29 @@ const char *bin_path; const char *data_path; const char *name; + enum obs_runtime_module_type type; }; typedef void (*obs_find_module_callback2_t)(void *param, const struct obs_module_info2 *info); /** Finds all modules within the search paths added by obs_add_module_path. */ EXPORT void obs_find_modules2(obs_find_module_callback2_t callback, void *param); + +/** Loads all registered core modules. */ +EXPORT bool obs_load_core_modules(void); + +/** Loads plugins at a given path. omp defines if modern or legacy plugins at path. */ +EXPORT void obs_load_plugins(struct obs_runtime_module_info *info, struct obs_module_failure_info *error); + +/** Returns true if a module is a core module. */ +EXPORT bool obs_is_core_module(obs_module_t *module); + +EXPORT bool obs_is_legacy_module(obs_module_t *module); + +/** Finds and loads a particular core module. + * Returns false if module cant be found. */ +bool find_core_module(struct obs_runtime_module_info *info, obs_find_module_callback2_t callback, void *data); + #endif typedef void (*obs_enum_module_callback_t)(void *param, obs_module_t *module); @@ -1074,11 +1103,13 @@ /** The 'hidden' flag is not the same as a sceneitem's visibility. It is a * property the determines if it can be found through searches. **/ +/** TODO: Remove both functions and temp_removed in 34.0 (https://github.com/obsproject/obs-studio/issues/13768) */ + /** Simply sets a 'hidden' flag when the source is still alive but shouldn't be found */ -EXPORT void obs_source_set_hidden(obs_source_t *source, bool hidden); +OBS_DEPRECATED EXPORT void obs_source_set_hidden(obs_source_t *source, bool hidden); /** Returns the current 'hidden' state on the source */ -EXPORT bool obs_source_is_hidden(obs_source_t *source); +OBS_DEPRECATED EXPORT bool obs_source_is_hidden(obs_source_t *source); /** Returns capability flags of a source */ EXPORT uint32_t obs_source_get_output_flags(const obs_source_t *source); @@ -1363,8 +1394,11 @@ OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT, }; -EXPORT void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type); -EXPORT enum obs_monitoring_type obs_source_get_monitoring_type(const obs_source_t *source); +EXPORT void obs_source_set_monitoring_enabled(obs_source_t *source, bool enabled); +EXPORT bool obs_source_get_monitoring_enabled(const obs_source_t *source); + +OBS_DEPRECATED EXPORT void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type); +OBS_DEPRECATED EXPORT enum obs_monitoring_type obs_source_get_monitoring_type(const obs_source_t *source); /** Gets private front-end settings data. This data is saved/loaded * automatically. Returns an incremented reference. */ @@ -2692,6 +2726,8 @@ EXPORT bool obs_canvas_get_video_info(const obs_canvas_t *canvas, struct obs_video_info *ovi); /** Renders the sources of this canvas's view context */ EXPORT void obs_canvas_render(obs_canvas_t *canvas); +/** Returns true if video of the canvas is active, false otherwise */ +EXPORT bool obs_canvas_video_active(obs_canvas_t *canvas); #ifdef __cplusplus }
View file
obs-studio-32.2.2.tar.xz/plugins/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/CMakeLists.txt
Changed
@@ -1,20 +1,32 @@ cmake_minimum_required(VERSION 3.28...3.30) -option(ENABLE_PLUGINS "Enable building OBS plugins" ON) +if(NOT TARGET libobs) + message(FATAL_ERROR "OBS Core modules require 'libobs' target.") +endif() + +option(ENABLE_CORE_MODULES "Enable building OBS Core Modules" ON) +set_property(GLOBAL PROPERTY ENABLE_PLUGINS ${ENABLE_CORE_MODULES}) -if(NOT ENABLE_PLUGINS) - set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_DISABLED "Plugin Support") +# FIXME: Remove with OBS 34.0.0 +if(DEFINED ENABLE_PLUGINS) + message(DEPRECATION "The ENABLE_PLUGINS cache variable is deprecated, use 'ENABLE_CORE_MODULES' instead") + set(ENABLE_CORE_MODULES ${ENABLE_PLUGINS}) +endif() + +if(NOT ENABLE_CORE_MODULES) + set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_DISABLED "Core Modules") + set_obs_core_modules() return() endif() -set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_ENABLED "Plugin Support") +set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_ENABLED "Core Modules") macro(check_obs_browser) if((OS_WINDOWS AND CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)") OR OS_MACOS OR OS_LINUX) if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/obs-browser/CMakeLists.txt") message(FATAL_ERROR "Required submodule 'obs-browser' not available.") else() - add_subdirectory(obs-browser) + add_core_module(obs-browser) endif() else() add_custom_target(obs-browser) @@ -26,81 +38,83 @@ if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/obs-websocket/CMakeLists.txt") message(FATAL_ERROR "Required submodule 'obs-websocket' not available.") else() - add_subdirectory(obs-websocket) + add_core_module(obs-websocket) endif() endmacro() # Add plugins in alphabetical order to retain order in IDE projects -add_obs_plugin( +add_core_module( aja PLATFORMS WINDOWS MACOS LINUX WITH_MESSAGE ) -add_obs_plugin(aja-output-ui PLATFORMS WINDOWS MACOS LINUX WITH_MESSAGE) -add_obs_plugin(coreaudio-encoder PLATFORMS WINDOWS MACOS) -add_obs_plugin( +add_core_module(aja-output-ui PLATFORMS WINDOWS MACOS LINUX WITH_MESSAGE) +add_core_module(coreaudio-encoder PLATFORMS WINDOWS MACOS) +add_core_module( decklink PLATFORMS WINDOWS MACOS LINUX WITH_MESSAGE ) -add_obs_plugin( +add_core_module( decklink-captions PLATFORMS WINDOWS MACOS LINUX WITH_MESSAGE ) -add_obs_plugin( +add_core_module( decklink-output-ui PLATFORMS WINDOWS MACOS LINUX WITH_MESSAGE ) -add_obs_plugin( +add_core_module( frontend-tools PLATFORMS WINDOWS MACOS LINUX WITH_MESSAGE ) -add_obs_plugin(image-source) -add_obs_plugin(linux-alsa PLATFORMS LINUX FREEBSD OPENBSD) -add_obs_plugin(linux-capture PLATFORMS LINUX FREEBSD OPENBSD) -add_obs_plugin(linux-jack PLATFORMS LINUX FREEBSD OPENBSD) -add_obs_plugin(linux-pipewire PLATFORMS LINUX FREEBSD OPENBSD) -add_obs_plugin(linux-pulseaudio PLATFORMS LINUX FREEBSD OPENBSD) -add_obs_plugin(linux-v4l2 PLATFORMS LINUX FREEBSD OPENBSD) -add_obs_plugin(mac-avcapture PLATFORMS MACOS) -add_obs_plugin(mac-capture PLATFORMS MACOS) -add_obs_plugin(mac-syphon PLATFORMS MACOS) -add_obs_plugin(mac-videotoolbox PLATFORMS MACOS) -add_obs_plugin(mac-virtualcam PLATFORMS MACOS) -add_obs_plugin(nv-filters PLATFORMS WINDOWS) +add_core_module(image-source) +add_core_module(linux-alsa PLATFORMS LINUX FREEBSD OPENBSD) +add_core_module(linux-capture PLATFORMS LINUX FREEBSD OPENBSD) +add_core_module(linux-jack PLATFORMS LINUX FREEBSD OPENBSD) +add_core_module(linux-pipewire PLATFORMS LINUX FREEBSD OPENBSD) +add_core_module(linux-pulseaudio PLATFORMS LINUX FREEBSD OPENBSD) +add_core_module(linux-v4l2 PLATFORMS LINUX FREEBSD OPENBSD) +add_core_module(mac-avcapture PLATFORMS MACOS) +add_core_module(mac-capture PLATFORMS MACOS) +add_core_module(mac-syphon PLATFORMS MACOS) +add_core_module(mac-videotoolbox PLATFORMS MACOS) +add_core_module(mac-virtualcam PLATFORMS MACOS) +add_core_module(nv-filters PLATFORMS WINDOWS) check_obs_browser() -add_obs_plugin(obs-ffmpeg) -add_obs_plugin(obs-filters) -add_obs_plugin(obs-libfdk) -add_obs_plugin(obs-nvenc PLATFORMS WINDOWS LINUX ARCHITECTURES x64 x86_64) -add_obs_plugin(obs-outputs) -add_obs_plugin( +add_core_module(obs-ffmpeg) +add_core_module(obs-filters) +add_core_module(obs-libfdk) +add_core_module(obs-nvenc PLATFORMS WINDOWS LINUX) +add_core_module(obs-outputs) +add_core_module( obs-qsv11 PLATFORMS WINDOWS LINUX ARCHITECTURES x64 x86_64 ) -add_obs_plugin(obs-text PLATFORMS WINDOWS) -add_obs_plugin(obs-transitions) -add_obs_plugin( +add_core_module(obs-text PLATFORMS WINDOWS) +add_core_module(obs-transitions) +add_core_module( obs-vst PLATFORMS WINDOWS MACOS LINUX WITH_MESSAGE ) -add_obs_plugin(obs-webrtc) +add_core_module(obs-webrtc) check_obs_websocket() -add_obs_plugin(obs-x264) -add_obs_plugin(oss-audio PLATFORMS FREEBSD OPENBSD) -add_obs_plugin(rtmp-services) -add_obs_plugin(sndio PLATFORMS LINUX FREEBSD OPENBSD) -add_obs_plugin(text-freetype2) -add_obs_plugin(vlc-video WITH_MESSAGE) -add_obs_plugin(win-capture PLATFORMS WINDOWS) -add_obs_plugin(win-dshow PLATFORMS WINDOWS) -add_obs_plugin(win-wasapi PLATFORMS WINDOWS) +add_core_module(obs-x264) +add_core_module(oss-audio PLATFORMS FREEBSD OPENBSD) +add_core_module(rtmp-services) +add_core_module(sndio PLATFORMS LINUX FREEBSD OPENBSD) +add_core_module(text-freetype2) +add_core_module(vlc-video WITH_MESSAGE) +add_core_module(win-capture PLATFORMS WINDOWS) +add_core_module(win-dshow PLATFORMS WINDOWS) +add_core_module(win-wasapi PLATFORMS WINDOWS) + +set_obs_core_modules()
View file
obs-studio-32.2.2.tar.xz/plugins/aja-output-ui/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/aja-output-ui/CMakeLists.txt
Changed
@@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.28...3.30) if(NOT ENABLE_AJA) - target_disable(aja-output-ui) return() endif()
View file
obs-studio-33.0.0.tar.xz/plugins/aja-output-ui/data/locale/fi-FI.ini
Added
@@ -0,0 +1,1 @@ +AJAOutput.MiscOutput="Lisäasetukset"
View file
obs-studio-33.0.0.tar.xz/plugins/aja-output-ui/data/locale/he-IL.ini
Added
@@ -0,0 +1,6 @@ +AJAOutput.Device="פלט התקן AJA I/O" +AJAOutput.ProgramOutput="פלט תוכנית" +AJAOutput.PreviewOutput="פלט תצוגה מקדימה" +AJAOutput.MiscOutput="הגדרות נוספות" +AJAOutput.MultiViewEnable="הפעלת תצוגה כוללנית" +AJAOutput.MultiViewAudioSource="מקור שמע תצוגה כוללנית"
View file
obs-studio-33.0.0.tar.xz/plugins/aja-output-ui/data/locale/hi-IN.ini
Added
@@ -0,0 +1,6 @@ +AJAOutput.Device="AJA I/O डिवाइस आउटपुट" +AJAOutput.ProgramOutput="प्रोग्राम आउटपुट" +AJAOutput.PreviewOutput="पूर्वावलोकन आउटपुट" +AJAOutput.MiscOutput="अतिरिक्त सेटिंग" +AJAOutput.MultiViewEnable="अनेक दृश्य सक्षम करें" +AJAOutput.MultiViewAudioSource="अनेक दृश्य ऑडियो स्रोत"
View file
obs-studio-33.0.0.tar.xz/plugins/aja-output-ui/data/locale/kaa.ini
Added
@@ -0,0 +1,1 @@ +AJAOutput.MultiViewEnable="Мульти көринисти қосыў"
View file
obs-studio-32.2.2.tar.xz/plugins/aja-output-ui/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/aja-output-ui/data/locale/tr-TR.ini
Changed
@@ -1,5 +1,5 @@ AJAOutput.Device="AJA I/O Cihaz Çıktısı" -AJAOutput.ProgramOutput="Program Çıktısı" +AJAOutput.ProgramOutput="Ana Yayın Çıktısı" AJAOutput.PreviewOutput="Önizleme Çıktısı" AJAOutput.MiscOutput="Ek Ayarlar" AJAOutput.MultiViewEnable="Çoklu Görünümü Etkinleştir"
View file
obs-studio-33.0.0.tar.xz/plugins/aja-output-ui/data/locale/uk-UA.ini
Added
@@ -0,0 +1,6 @@ +AJAOutput.Device="Пристрій виводу AJA I/O" +AJAOutput.ProgramOutput="Програмний вивід" +AJAOutput.PreviewOutput="Попередній перегляд виводу" +AJAOutput.MiscOutput="Додаткові Налаштування" +AJAOutput.MultiViewEnable="Увімкнути мультиперегляд" +AJAOutput.MultiViewAudioSource="Джерело звуку мультиперегляд"
View file
obs-studio-33.0.0.tar.xz/plugins/aja-output-ui/data/locale/vi-VN.ini
Added
@@ -0,0 +1,3 @@ +AJAOutput.Device="Đầu ra thiết bị AJA I/O" +AJAOutput.PreviewOutput="Đầu ra Xem trước" +AJAOutput.MiscOutput="Cài đặt Bổ sung"
View file
obs-studio-32.2.2.tar.xz/plugins/aja/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/aja/CMakeLists.txt
Changed
@@ -3,7 +3,6 @@ option(ENABLE_AJA "Build OBS with aja support" ON) if(NOT ENABLE_AJA) - set_property(GLOBAL APPEND PROPERTY OBS_MODULES_DISABLED aja) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/aja/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/plugins/aja/data/locale/et-EE.ini
Changed
@@ -7,7 +7,7 @@ VideoFormat="Video formaat" PixelFormat="Piksli formaat" AutoDetect="Automaatne tuvastamine" -Interlaced="Põimitud" +Interlaced="Ülerealaotusega" AutoStart="Automaatne startimine käivitamisel" Buffering="Kasuta puhverdamist" DeactivateWhenNotShowing="Laadi maha kui ei ole nähtav"
View file
obs-studio-32.2.2.tar.xz/plugins/aja/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/aja/data/locale/kaa.ini
Changed
@@ -1,17 +1,18 @@ -AJACapture.Device="AJA I/O qamtıp alıw qurılması" -AJAOutput.Device="AJA I/O shıǵarıw qurılması" -Device="Qurılma" -Output="Shıǵıw" +Device="Қурылма" +Output="Шығыс" +Input="Кирис" Mode="Режим" +VideoFormat="Видео форматы" PixelFormat="Пиксель форматы" -AutoDetect="Avtomat tárizde anıqlaw" IOSelect="Таңлаў..." -Auto="Avtomat tárizde" +SDITransport="Транспорт SDI" +SDITransport4K="Транспорт SDI 4K" +Auto="Автоматикалық" ChannelFormat="Канал" ChannelFormat.None="Жоқ" -ChannelFormat.2_0ch="2 kanallı" -ChannelFormat.2_1ch="2.1 kanallı" -ChannelFormat.4_0ch="4 kanallı" -ChannelFormat.4_1ch="4.1 kanallı" -ChannelFormat.5_1ch="5.1 kanallı" -ChannelFormat.7_1ch="7.1 kanallı" +ChannelFormat.2_0ch="2 каналлы" +ChannelFormat.2_1ch="2.1 каналлы" +ChannelFormat.4_0ch="4 каналлы" +ChannelFormat.4_1ch="4.1 каналлы" +ChannelFormat.5_1ch="5.1 каналлы" +ChannelFormat.7_1ch="7.1 каналлы"
View file
obs-studio-32.2.2.tar.xz/plugins/aja/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/aja/data/locale/tr-TR.ini
Changed
@@ -3,12 +3,12 @@ Device="Cihaz" Output="Çıktı" Input="Girdi" -Mode="Mod" +Mode="Kip" VideoFormat="Video Biçimi" PixelFormat="Piksel Biçimi" AutoDetect="Otomatik Algıla" Interlaced="Geçişli" -AutoStart="Açılışta otomatik olarak başlat" +AutoStart="Açılışta kendiliğinden başlat" Buffering="Arabelleğe Almayı Kullan" DeactivateWhenNotShowing="Gösterilmediğinde devre dışı bırak" IOSelect="Seç..." @@ -17,11 +17,11 @@ Auto="Otomatik" ChannelFormat="Kanal" ChannelFormat.None="Hiçbiri" -ChannelFormat.2_0ch="2knl" -ChannelFormat.2_1ch="2.1knl" +ChannelFormat.2_0ch="2 knl" +ChannelFormat.2_1ch="2.1 knl" ChannelFormat.4_0ch="4knl" -ChannelFormat.4_1ch="4.1knl" -ChannelFormat.5_1ch="5.1knl" -ChannelFormat.7_1ch="7.1knl" +ChannelFormat.4_1ch="4.1 knl" +ChannelFormat.5_1ch="5.1 knl" +ChannelFormat.7_1ch="7.1 knl" SwapFC-LFE="FC ile LFE'yi Değiştir" SwapFC-LFE.Tooltip="Ön Merkez Kanalı ile LFE Kanalını Değiştir"
View file
obs-studio-33.0.0.tar.xz/plugins/aja/data/locale/uz-UZ.ini
Added
@@ -0,0 +1,27 @@ +AJACapture.Device="AJA K/Ch (Kirish/Chiqish) qurilmasidan signal olish" +AJAOutput.Device="AJA K/Ch (Kirish/Chiqish) qurilmasiga signal chiqarish" +Device="Qurilma" +Output="Chiqish" +Input="Kiritish maydoni" +Mode="Tartib" +VideoFormat="Video formati" +PixelFormat="Piksel formati" +AutoDetect="Avtomatik payqash" +Interlaced="Qator oralatib" +AutoStart="Ishga tushirilganda avtomatik boshlash" +Buffering="Buferlashdan foydalanish" +DeactivateWhenNotShowing="Ko‘rsatilmayotganda faolsizlantirish" +IOSelect="Tanlash..." +SDITransport="SDI uzatish usuli" +SDITransport4K="SDI 4K uzatish usuli" +Auto="Avtomatik" +ChannelFormat="Kanal" +ChannelFormat.None="Yo‘q (Bo‘sh)" +ChannelFormat.2_0ch="2 kanal" +ChannelFormat.2_1ch="2.1 kanal" +ChannelFormat.4_0ch="4 kanal" +ChannelFormat.4_1ch="4.1 kanal" +ChannelFormat.5_1ch="5.1 kanal" +ChannelFormat.7_1ch="7.1 kanal" +SwapFC-LFE="Old markaziy kanal (FC) va past chastotali effektlar (LFE) kanallarini almashtirish" +SwapFC-LFE.Tooltip="Old markaziy kanal (FC) va past chastotali effektlar kanalini (LFE) almashtirish"
View file
obs-studio-32.2.2.tar.xz/plugins/coreaudio-encoder/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/coreaudio-encoder/CMakeLists.txt
Changed
@@ -3,7 +3,6 @@ if(OS_WINDOWS) option(ENABLE_COREAUDIO_ENCODER "Enable building with CoreAudio encoder (Windows)" ON) if(NOT ENABLE_COREAUDIO_ENCODER) - target_disable(coreaudio-encoder) return() endif() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/coreaudio-encoder/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/coreaudio-encoder/data/locale/kaa.ini
Changed
@@ -1,1 +1,2 @@ -Bitrate="Bit tezligi" +Bitrate="Битрейт" +AllowHEAAC="HE-AAC руқсат бериў"
View file
obs-studio-32.2.2.tar.xz/plugins/coreaudio-encoder/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/coreaudio-encoder/data/locale/tr-TR.ini
Changed
@@ -1,4 +1,4 @@ Bitrate="Bit hızı" AllowHEAAC="HE-ACC'ye izin ver" -OutputSamplerate="Çıkış örnek hızı" +OutputSamplerate="Çıktı Örnekleme Hızı" UseInputSampleRate="Giriş (OBS) Örnekleme Hızını Kullan (desteklenmeyen bit hızları listelenebilir)"
View file
obs-studio-32.2.2.tar.xz/plugins/decklink-captions/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/decklink-captions/CMakeLists.txt
Changed
@@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.28...3.30) if(NOT ENABLE_DECKLINK) - target_disable(decklink-captions) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/decklink-output-ui/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/decklink-output-ui/CMakeLists.txt
Changed
@@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.28...3.30) if(NOT ENABLE_DECKLINK) - target_disable(decklink-output-ui) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/decklink/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/decklink/CMakeLists.txt
Changed
@@ -2,7 +2,6 @@ option(ENABLE_DECKLINK "Build OBS with Decklink support" ON) if(NOT ENABLE_DECKLINK) - target_disable(decklink) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/decklink/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/decklink/data/locale/kaa.ini
Changed
@@ -1,20 +1,23 @@ -BlackmagicDevice="Blackmagic qurılması" -Device="Qurılma" -Mode="Rejim" -PixelFormat="Piksel formatı" -ColorSpace="Reń maydanı" -ColorSpace.Default="Aldınnan ornatılǵan" -ColorRange="Reń aralıǵı" -ColorRange.Default="Aldınnan ornatılǵan" -ColorRange.Partial="Sheklengen" -ColorRange.Full="Tolıq" -ChannelFormat="Kanal" -ChannelFormat.None="Joq" -ChannelFormat.2_0ch="2 kanallı" -ChannelFormat.2_1ch="2.1 kanallı" -ChannelFormat.4_0ch="4 kanallı" -ChannelFormat.4_1ch="4.1 kanallı" -ChannelFormat.5_1ch="5.1 kanallı" -ChannelFormat.7_1ch="7.1 kanallı" -VideoConnection="Video jalǵanıw" -AudioConnection="Audio jalǵanıw" +BlackmagicDevice="Blackmagic қурылмасы" +Device="Қурылма" +Mode="Режим" +Buffering="Буферизацияны қолланыў" +PixelFormat="Пиксель форматы" +ColorSpace="Рең майданы" +ColorSpace.Default="Әдепки" +ColorRange="Рең аралығы" +ColorRange.Default="Әдепки" +ColorRange.Partial="Шекленген" +ColorRange.Full="Толық" +ChannelFormat="Канал" +ChannelFormat.None="Жоқ" +ChannelFormat.2_0ch="2 каналлы" +ChannelFormat.2_1ch="2.1 каналлы" +ChannelFormat.4_0ch="4 каналлы" +ChannelFormat.4_1ch="4.1 каналлы" +ChannelFormat.5_1ch="5.1 каналлы" +ChannelFormat.7_1ch="7.1 каналлы" +ForceSDR="SDR-ды мәжбүрий қолланыў" +VideoConnection="Видео жалғаныў" +AudioConnection="Аудио жалғаныў" +Allow10Bit="10 битке руқсат бериў (SDI субтитрлери ушын керек, өнимдарлықты төменлетиўи мүмкин)"
View file
obs-studio-32.2.2.tar.xz/plugins/decklink/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/decklink/data/locale/tr-TR.ini
Changed
@@ -1,6 +1,6 @@ BlackmagicDevice="Blackmagic Aygıtı" Device="Aygıt" -Mode="Mod" +Mode="Kip" Buffering="Arabelleğe Almayı Kullan" PixelFormat="Piksel Biçimi" ColorSpace="Renk Uzayı" @@ -11,6 +11,9 @@ ColorRange.Full="Tam" ChannelFormat="Kanal" ChannelFormat.None="Hiçbiri" +ChannelFormat.2_0ch="2 knl" +ChannelFormat.4_0ch="4 knl" +ChannelFormat.4_1ch="4.1knl" DeactivateWhenNotShowing="Gösterilmediğinde devre dışı bırak" AutoStart="Açılışta otomatik olarak başlat" ForceSDR="SDR'yi Zorla"
View file
obs-studio-32.2.2.tar.xz/plugins/decklink/linux/platform.cpp -> obs-studio-33.0.0.tar.xz/plugins/decklink/linux/platform.cpp
Changed
@@ -1,5 +1,7 @@ #include "../platform.hpp" +#include <cstdlib> + bool DeckLinkStringToStdString(decklink_string_t input, std::string &output) { if (input == nullptr) {
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/data/locale/es-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/data/locale/es-ES.ini
Changed
@@ -38,3 +38,9 @@ PythonSettings.PythonNotLoaded="Python no está cargado actualmente" PythonSettings.AlreadyLoaded.Title="Python ya está cargado" PythonSettings.AlreadyLoaded.Message="Una copia de Python %1 ya está cargada. Para cargar la nueva versión de Python seleccionada, reinicie OBS." +ScriptLogWindow="Registros de script" +Description="Descripción" +ScriptDescriptionLink.Text="¿Abrir este enlace en tu navegador predeterminado?" +ScriptDescriptionLink.OpenURL="Abrir URL" +FileFilter.ScriptFiles="Archivos de Scripts" +FileFilter.AllFiles="Todos los archivos"
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/data/locale/et-EE.ini
Changed
@@ -2,18 +2,27 @@ SceneSwitcher.OnNoMatch="Kui ükski aken ei sobi:" SceneSwitcher.OnNoMatch.DontSwitch="Ära vaheta" SceneSwitcher.OnNoMatch.SwitchTo="Vaheta:" +SceneSwitcher.CheckInterval="Kontrolli aktiivse akna peakirja iga:" SceneSwitcher.ActiveOrNotActive="Stseeni vahetaja on:" +InvalidRegex.Title="Kehtetu regulaaravaldis" +InvalidRegex.Text="Sisestatud regulaaravaldis on kehtetu." Active="Aktiivne" Inactive="Mitteaktiivne" Start="Alusta" Stop="Peata" +Captions="Subtiitrid (eksperimentaalne)" Captions.AudioSource="Heliallikas" +Captions.CurrentSystemLanguage="Praegune süsteemi keel (%1)" Captions.Provider="Pakkuja" Captions.Error.GenericFail="Subtiitrite käivitamine ebaõnnestus" +OutputTimer="Väljundi taimer" OutputTimer.Stream="Lõpeta voogedastus pärast:" OutputTimer.Record="Lõpeta salvestamine pärast:" OutputTimer.Stream.StoppingIn="Voogedastus lõppeb:" OutputTimer.Record.StoppingIn="Salvestamine lõppeb:" +OutputTimer.Stream.EnableEverytime="Lülita voogedastuse taimer alati sisse" +OutputTimer.Record.EnableEverytime="Lülita salvestuse taimer alati sisse" +OutputTimer.Record.PauseTimer="Peata taimer, kui salvestamine on peatatud" Scripts="Skriptid" LoadedScripts="Lisatud skriptid" AddScripts="Lisa skripte" @@ -23,3 +32,16 @@ Reload="Lae uuesti" OpenFileLocation="Ava faili asukoht" PythonSettings="Pythoni seaded" +PythonSettings.PythonInstallPath32bit="Pythoni installitee (32bit)" +PythonSettings.PythonInstallPath64bit="Pythoni installitee (64bit)" +PythonSettings.BrowsePythonPath="Sirvi Pythoni teed" +PythonSettings.PythonVersion="Laaditud Pythoni versioon: %1" +PythonSettings.PythonNotLoaded="Python ei ole laaditud" +PythonSettings.AlreadyLoaded.Title="Python on juba laaditud" +PythonSettings.AlreadyLoaded.Message="Pythoni koopia %1 on juba laaditud. Uue valitud Pythoni versiooni laadimiseks käivita OBS uuesti." +ScriptLogWindow="Skripti logi" +Description="Kirjeldus" +ScriptDescriptionLink.Text="Ava see link oma vaikimisi veebibrauseris?" +ScriptDescriptionLink.OpenURL="Ava URL" +FileFilter.ScriptFiles="Skriptifailid" +FileFilter.AllFiles="Kõik failid"
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/data/locale/fi-FI.ini -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/data/locale/fi-FI.ini
Changed
@@ -1,6 +1,7 @@ InvalidRegex.Title="Virheellinen säännöllinen lauseke" Start="Käynnistä" Stop="Pysäytä" +Captions.AudioSource="Äänilähde" Captions.CurrentSystemLanguage="Nykyinen järjestelmän kieli (%1)" OpenFileLocation="Avaa tiedoston sijainti" PythonSettings="Python-asetukset"
View file
obs-studio-33.0.0.tar.xz/plugins/frontend-tools/data/locale/he-IL.ini
Added
@@ -0,0 +1,48 @@ +SceneSwitcher="מחליף סצנה אוטומטי" +SceneSwitcher.OnNoMatch="כאשר אין חלון מתאים:" +SceneSwitcher.OnNoMatch.DontSwitch="לא להחליף" +SceneSwitcher.OnNoMatch.SwitchTo="להחליף ל־:" +SceneSwitcher.CheckInterval="לבדוק כותרת חלון פעיל כל:" +SceneSwitcher.ActiveOrNotActive="מחליף הסצנות הוא:" +InvalidRegex.Title="ביטוי רגולרי שגוי" +InvalidRegex.Text="הביטוי הרגולרי שמילאת שגוי." +Active="פעיל" +Inactive="לא פעיל" +Start="התחלה" +Stop="עצירה" +Captions="כיתובים (ניסיוני)" +Captions.AudioSource="מקור שמע" +Captions.CurrentSystemLanguage="שפת המערכת הנוכחית (%1)" +Captions.Provider="ספק" +Captions.Error.GenericFail="הפעלת כיתובים נכשלה" +OutputTimer="פלט מתזמן" +OutputTimer.Stream="סיום ההזרמה תוך:" +OutputTimer.Record="סיום ההקלטה תוך:" +OutputTimer.Stream.StoppingIn="ההזרמה תיעצר בעוד:" +OutputTimer.Record.StoppingIn="ההקלטה תיעצר בעוד:" +OutputTimer.Stream.EnableEverytime="הפעלת מתזמן להזרמות בכל פעם" +OutputTimer.Record.EnableEverytime="הפעלת מתזמן להקלטות בכל פעם" +OutputTimer.Record.PauseTimer="להשהות את המתזמן כשההקלטה מושהית" +Scripts="סקריפטים" +LoadedScripts="סקריפטים שנטענו" +AddScripts="הוספת סקריפטים" +RemoveScripts="הסרת סקריפטים" +ReloadScripts="ריענון סקריפטים" +EditScript="עריכת סקריפט" +Reload="ריענון" +OpenFileLocation="פתיחת מקום קובץ" +PythonSettings="הגדרות Python" +PythonSettings.PythonInstallPath32bit="נתיב התקנת Python (32 סיביות)" +PythonSettings.PythonInstallPath64bit="נתיב התקנת Python (64 סיביות)" +PythonSettings.BrowsePythonPath="עיון לאיתור נתיב Python" +PythonSettings.PythonVersion="גרסת Python שנטענה: %1" +PythonSettings.PythonNotLoaded="Python לא טעון כרגע" +PythonSettings.AlreadyLoaded.Title="Python כבר נטען" +PythonSettings.AlreadyLoaded.Message="עותק של Python %1 כבר טעון כרגע. כדי לטעון את ה־Python החדש שנבחר, נא להפעיל את OBS מחדש." +ScriptLogWindow="יומן סקריפט" +Description="תיאור" +ScriptDescriptionLink.Text="לפתוח את הקישור הזה בדפדפן ברירת המחדל שלך?" +ScriptDescriptionLink.Text.Url="כתובת: %1" +ScriptDescriptionLink.OpenURL="פתיחת כתובת" +FileFilter.ScriptFiles="קובצי סקריפט" +FileFilter.AllFiles="כל הקבצים"
View file
obs-studio-33.0.0.tar.xz/plugins/frontend-tools/data/locale/kaa.ini
Added
@@ -0,0 +1,18 @@ +Active="Актив" +Inactive="Актив емес" +Start="Иске түсириў" +Stop="Тоқтатыў" +Captions.AudioSource="Даўыс дереги" +Scripts="Скриптлер" +LoadedScripts="Жүкленген скриптлер" +EditScript="Скриптти өзгертиў" +Reload="Жаңалаў" +PythonSettings="Python сазлаўлары" +PythonSettings.PythonInstallPath32bit="Python орнатыў жолы (32 бит)" +PythonSettings.PythonInstallPath64bit="Python орнатыў жолы (64 бит)" +Description="Баян" +ScriptDescriptionLink.Text="Бул силтеме әдепки браузериңизде ашылсын ба?" +ScriptDescriptionLink.Text.Url="Силтеме: %1" +ScriptDescriptionLink.OpenURL="Силтемени ашыў" +FileFilter.ScriptFiles="Скрипт файллары" +FileFilter.AllFiles="Барлық файл"
View file
obs-studio-33.0.0.tar.xz/plugins/frontend-tools/data/locale/uk-UA.ini
Added
@@ -0,0 +1,48 @@ +SceneSwitcher="Автоматичний перемикач сцен" +SceneSwitcher.OnNoMatch="Якщо жодне вікно не відповідає:" +SceneSwitcher.OnNoMatch.DontSwitch="Не перемикати" +SceneSwitcher.OnNoMatch.SwitchTo="Перемкнути на:" +SceneSwitcher.CheckInterval="Перевіряти назву активного вікна кожні:" +SceneSwitcher.ActiveOrNotActive="Стан перемикача сцен:" +InvalidRegex.Title="Некоректний регулярний вираз" +InvalidRegex.Text="Введений регулярний вираз некоректний" +Active="Активно" +Inactive="Неактивно" +Start="Почати" +Stop="Зупинити" +Captions="Субтитри (експериментально)" +Captions.AudioSource="Джерело звуку" +Captions.CurrentSystemLanguage="Поточна мова системи (%1)" +Captions.Provider="Провайдер" +Captions.Error.GenericFail="Не вдалось запустити субтитри" +OutputTimer="Таймер виводу" +OutputTimer.Stream="Зупинити трансляцію після:" +OutputTimer.Record="Зупинити запис після:" +OutputTimer.Stream.StoppingIn="Трансляція зупиниться через:" +OutputTimer.Record.StoppingIn="Запис зупиниться через:" +OutputTimer.Stream.EnableEverytime="Вмикати таймер трансляції щоразу" +OutputTimer.Record.EnableEverytime="Вмикати таймер запису щоразу" +OutputTimer.Record.PauseTimer="Призупиняти таймер, коли запис на паузі" +Scripts="Скрипти" +LoadedScripts="Завантажені скрипти" +AddScripts="Додати скрипти" +RemoveScripts="Видалити скрипти" +ReloadScripts="Перезавантажити скрипти" +EditScript="Редагувати скрипт" +Reload="Перезавантажити" +OpenFileLocation="Відкрити розташування файлу" +PythonSettings="Налаштування Python" +PythonSettings.PythonInstallPath32bit="Шлях встановлення Python (32 біт)" +PythonSettings.PythonInstallPath64bit="Шлях встановлення Python (64 біт)" +PythonSettings.BrowsePythonPath="Огляд шляху Python" +PythonSettings.PythonVersion="Завантажена версія Python: %1" +PythonSettings.PythonNotLoaded="Python зараз не завантажено" +PythonSettings.AlreadyLoaded.Title="Python уже завантажено" +PythonSettings.AlreadyLoaded.Message="Копія Python %1 вже завантажена. Щоб завантажити новообрану версію Python, будь ласка, перезавантажте OBS." +ScriptLogWindow="Журнал скрипту" +Description="Опис" +ScriptDescriptionLink.Text="Відкрити це посилання у вашому вебпереглядачі за замовчуванням?" +ScriptDescriptionLink.Text.Url="Посилання: %1" +ScriptDescriptionLink.OpenURL="Відкрити посилання" +FileFilter.ScriptFiles="Файли скриптів" +FileFilter.AllFiles="Усі файли"
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/data/locale/vi-VN.ini -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/data/locale/vi-VN.ini
Changed
@@ -1,8 +1,46 @@ +SceneSwitcher="Tự động chuyển cảnh" +SceneSwitcher.OnNoMatch="Khi cửa sổ không khớp:" +SceneSwitcher.OnNoMatch.DontSwitch="Không chuyển" +SceneSwitcher.OnNoMatch.SwitchTo="Chuyển sang:" +SceneSwitcher.CheckInterval="Kiểm tra tiêu đề cửa sổ mỗi:" +SceneSwitcher.ActiveOrNotActive="Chuyển cảnh đang:" +InvalidRegex.Title="Cụm từ thông dụng không hợp lệ" +InvalidRegex.Text="Cụm từ thông dụng mà bạn đã nhập không hợp lệ." +Active="Đang hoạt động" +Inactive="Không hoạt động" Start="Bắt đầu" Stop="Dừng" +Captions="Phụ đề (Thử nghiệm)" Captions.AudioSource="Nguồn âm thanh" +Captions.CurrentSystemLanguage="Ngôn ngữ hiện tại của máy tính (%1)" +Captions.Provider="Nhà cung cấp" +Captions.Error.GenericFail="Thất bại trong việc bắt đầu phụ đề" +OutputTimer="Hẹn giờ đầu ra" +OutputTimer.Stream="Dừng stream sau:" +OutputTimer.Record="Dừng ghi video sau:" +OutputTimer.Stream.StoppingIn="Stream sẽ dừng trong:" +OutputTimer.Record.StoppingIn="Quay video sẽ dừng trong:" +OutputTimer.Stream.EnableEverytime="Bật hẹn giờ streaming mỗi lần" +OutputTimer.Record.EnableEverytime="Bật hẹn giờ ghi mỗi lần" +Scripts="Scripts - Kịch bản" +LoadedScripts="Kịch bản đã nạp" +AddScripts="Thêm script" +RemoveScripts="Gỡ bỏ kịch bản" +ReloadScripts="Nạp lại kịch bản" +EditScript="Chỉnh sửa kịch bản" Reload="Tải lại" +OpenFileLocation="Mở vị trí tệp" PythonSettings="Thiết đặt Python" PythonSettings.PythonInstallPath32bit="Đường dẫn cài đặt Python (32bit)" PythonSettings.PythonInstallPath64bit="Đường dẫn cài đặt Python (64bit)" PythonSettings.BrowsePythonPath="Duyệt đường dẫn Python" +PythonSettings.PythonVersion="Phiên bản Python đã tải: %1" +PythonSettings.PythonNotLoaded="Python hiện chưa được nạp" +PythonSettings.AlreadyLoaded.Title="Python đã được tải" +PythonSettings.AlreadyLoaded.Message="Phiên bản Python %1 đang trong sử dụng. Để load lại phiên bản Python mới, vui lòng restart lại OBS." +ScriptLogWindow="Bản ghi kịch bản" +Description="Mô tả" +ScriptDescriptionLink.Text="Mở liên kết trên trình duyệt web mặc định?" +ScriptDescriptionLink.OpenURL="Mở URL" +FileFilter.ScriptFiles="Tập tin script" +FileFilter.AllFiles="Tất cả tệp"
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/data/scripts/clock-source.lua -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/data/scripts/clock-source.lua
Changed
@@ -7,13 +7,13 @@ function image_source_load(image, file) obs.obs_enter_graphics(); - obs.gs_image_file_free(image); + obs.gs_image_file_ex_free(image); obs.obs_leave_graphics(); - obs.gs_image_file_init(image, file); + obs.gs_image_file_ex_init(image, file, obs.GS_IMAGE_ALPHA_STRAIGHT); obs.obs_enter_graphics(); - obs.gs_image_file_init_texture(image); + obs.gs_image_file_ex_init_texture(image); obs.obs_leave_graphics(); if not image.loaded then @@ -27,10 +27,10 @@ source_def.create = function(source, settings) local data = {} - data.image = obs.gs_image_file() - data.hour_image = obs.gs_image_file() - data.minute_image = obs.gs_image_file() - data.second_image = obs.gs_image_file() + data.image = obs.gs_image_file_ex() + data.hour_image = obs.gs_image_file_ex() + data.minute_image = obs.gs_image_file_ex() + data.second_image = obs.gs_image_file_ex() image_source_load(data.image, script_path() .. "clock-source/dial.png") image_source_load(data.hour_image, script_path() .. "clock-source/hour.png") @@ -42,10 +42,10 @@ source_def.destroy = function(data) obs.obs_enter_graphics(); - obs.gs_image_file_free(data.image); - obs.gs_image_file_free(data.hour_image); - obs.gs_image_file_free(data.minute_image); - obs.gs_image_file_free(data.second_image); + obs.gs_image_file_ex_free(data.image); + obs.gs_image_file_ex_free(data.hour_image); + obs.gs_image_file_ex_free(data.minute_image); + obs.gs_image_file_ex_free(data.second_image); obs.obs_leave_graphics(); end
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/forms/auto-scene-switcher.ui -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/forms/auto-scene-switcher.ui
Changed
@@ -100,7 +100,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -115,10 +115,10 @@ <item> <layout class="QFormLayout" name="formLayout"> <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> + <enum>QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow</enum> </property> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTop|Qt::AlignmentFlag::AlignTrailing</set> </property> <item row="0" column="0"> <widget class="QLabel" name="label"> @@ -132,7 +132,7 @@ <string>SceneSwitcher.OnNoMatch</string> </property> <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set> </property> </widget> </item> @@ -240,7 +240,7 @@ <item row="3" column="0"> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -260,10 +260,10 @@ <item row="4" column="1"> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> + <enum>QSizePolicy::Policy::Preferred</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -282,7 +282,7 @@ </item> </layout> </item> - <item alignment="Qt::AlignRight"> + <item alignment="Qt::AlignmentFlag::AlignRight"> <widget class="QPushButton" name="close"> <property name="text"> <string>Close</string>
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/forms/captions.ui -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/forms/captions.ui
Changed
@@ -17,7 +17,7 @@ <item> <layout class="QFormLayout" name="formLayout"> <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set> </property> <item row="1" column="0"> <widget class="QLabel" name="label"> @@ -32,7 +32,7 @@ <item row="1" column="1"> <widget class="QComboBox" name="source"> <property name="insertPolicy"> - <enum>QComboBox::InsertAlphabetically</enum> + <enum>QComboBox::InsertPolicy::InsertAlphabetically</enum> </property> </widget> </item> @@ -59,7 +59,7 @@ <item row="3" column="1"> <widget class="QComboBox" name="provider"> <property name="insertPolicy"> - <enum>QComboBox::InsertAlphabetically</enum> + <enum>QComboBox::InsertPolicy::InsertAlphabetically</enum> </property> </widget> </item> @@ -75,7 +75,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -90,7 +90,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -110,7 +110,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/forms/output-timer.ui -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/forms/output-timer.ui
Changed
@@ -196,7 +196,7 @@ <item row="7" column="8"> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Close</set> + <set>QDialogButtonBox::StandardButton::Close</set> </property> </widget> </item>
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/forms/scripts.ui -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/forms/scripts.ui
Changed
@@ -45,7 +45,7 @@ <item> <widget class="QListWidget" name="scripts"> <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> + <enum>Qt::ContextMenuPolicy::CustomContextMenu</enum> </property> <property name="spacing"> <number>1</number> @@ -153,7 +153,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -269,7 +269,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -288,7 +288,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size>
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/frontend-tools.c -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/frontend-tools.c
Changed
@@ -1,4 +1,5 @@ #include <obs-module.h> +#include <obs-frontend-api.h> OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("frontend-tools", "en-US") @@ -27,7 +28,11 @@ InitSceneSwitcher(); InitOutputTimer(); #if defined(ENABLE_SCRIPTING) - InitScripts(); + if (obs_frontend_is_safe_mode_enabled()) { + blog(LOG_WARNING, "Scripting is disabled in Safe Mode"); + } else { + InitScripts(); + } #endif return true; } @@ -40,6 +45,7 @@ FreeSceneSwitcher(); FreeOutputTimer(); #if defined(ENABLE_SCRIPTING) - FreeScripts(); + if (!obs_frontend_is_safe_mode_enabled()) + FreeScripts(); #endif }
View file
obs-studio-32.2.2.tar.xz/plugins/frontend-tools/scripts.cpp -> obs-studio-33.0.0.tar.xz/plugins/frontend-tools/scripts.cpp
Changed
@@ -634,7 +634,7 @@ qmsg = QStringLiteral("Unknown Script %1").arg(message); } - QMetaObject::invokeMethod(scriptLogWindow, "AddLogMsg", Q_ARG(int, log_level), Q_ARG(QString, qmsg)); + QMetaObject::invokeMethod(scriptLogWindow, &ScriptLogWindow::AddLogMsg, log_level, qmsg); } extern "C" void InitScripts()
View file
obs-studio-32.2.2.tar.xz/plugins/image-source/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/image-source/data/locale/kaa.ini
Changed
@@ -1,20 +1,25 @@ -ImageInput="Súwret" -File="Súwret faylı" -SlideShow.TransitionSpeed="Ótiw tezligi" -SlideShow.Files="Súwret faylları" -SlideShow.CustomSize.Auto="Avtomat tárizde" -SlideShow.Loop="Qaytalaw" -SlideShow.Transition="Ótiw" -SlideShow.Transition.Cut="Qıyıw" +ImageInput="Суўрет" +File="Суўрет файлы" +SlideShow="Слайдшоу" +SlideShow.TransitionSpeed="Өтиў тезлиги" +SlideShow.Files="Суўрет файллары" +SlideShow.CustomSize.Auto="Автоматикалық" +SlideShow.Loop="Қайталаў" +SlideShow.Transition="Өтиў" SlideShow.PlaybackBehavior="Kórinis qásiyeti" SlideShow.PlaybackBehavior.StopRestart="Kórinbeytuǵın bolsa toqtatıw, kórinetuǵın bolsa bastan baslaw" SlideShow.PlaybackBehavior.AlwaysPlay="Hámiyshe qoyıw, hátteki kórinbeytuǵın bolsa da" -SlideShow.SlideMode.Auto="Avtomat tárizde" -SlideShow.PlayPause="Qoyıw/Pauza" -SlideShow.Restart="Qayta iske túsiriw" -SlideShow.Stop="Toqtatıw" -SlideShow.NextSlide="Keyingi slayd" -SlideShow.PreviousSlide="Aldıńǵı slayd" -ColorSource.Color="Reń" -ColorSource.Width="Eni" -ColorSource.Height="Uzınlıǵı" +SlideShow.SlideMode.Auto="Автоматикалық" +SlideShow.PlayPause="Қойыў/Пауза" +SlideShow.Restart="Қайта иске түсириў" +SlideShow.Stop="Тоқтатыў" +SlideShow.NextSlide="Кейинги слайд" +SlideShow.PreviousSlide="Алдыңғы слайд" +SlideShow.HideWhenDone="Слайдшоу таўсылғанда жасырыў" +SlideShow.PlaybackMode="Қойыў режими" +SlideShow.PlaybackMode.Once="Бир мәрте" +SlideShow.PlaybackMode.Loop="Қайталаў" +ColorSource="Рең" +ColorSource.Color="Рең" +ColorSource.Width="Ени" +ColorSource.Height="Узынлығы"
View file
obs-studio-32.2.2.tar.xz/plugins/image-source/image-source.c -> obs-studio-33.0.0.tar.xz/plugins/image-source/image-source.c
Changed
@@ -27,7 +27,7 @@ volatile bool file_decoded; volatile bool texture_loaded; - gs_image_file4_t if4; + gs_image_file_ex_t image; }; static time_t get_modified_timestamp(const char *filename) @@ -35,6 +35,7 @@ struct stat stats; if (os_stat(filename, &stats) != 0) return -1; + return stats.st_mtime; } @@ -51,8 +52,8 @@ return; context->file_timestamp = get_modified_timestamp(context->file); - gs_image_file4_init(&context->if4, context->file, - context->linear_alpha ? GS_IMAGE_ALPHA_PREMULTIPLY_SRGB : GS_IMAGE_ALPHA_PREMULTIPLY); + gs_image_file_ex_init(&context->image, context->file, + context->linear_alpha ? GS_IMAGE_ALPHA_PREMULTIPLY_SRGB : GS_IMAGE_ALPHA_PREMULTIPLY); os_atomic_set_bool(&context->file_decoded, true); } @@ -65,11 +66,12 @@ debug("loading texture '%s'", context->file); obs_enter_graphics(); - gs_image_file4_init_texture(&context->if4); + gs_image_file_ex_init_texture(&context->image); obs_leave_graphics(); - if (!context->if4.image3.image2.image.loaded) + if (!context->image.loaded) warn("failed to load texture '%s'", context->file); + context->update_time_elapsed = 0; os_atomic_set_bool(&context->texture_loaded, true); } @@ -81,7 +83,7 @@ os_atomic_set_bool(&context->texture_loaded, false); obs_enter_graphics(); - gs_image_file4_free(&context->if4); + gs_image_file_ex_free(&context->image); obs_leave_graphics(); } @@ -105,6 +107,7 @@ if (context->file) bfree(context->file); + context->file = bstrdup(file); context->persistent = !unload; context->linear_alpha = linear_alpha; @@ -146,13 +149,13 @@ { struct image_source *context = data; - if (context->if4.image3.image2.image.is_animated_gif) { - context->if4.image3.image2.image.cur_frame = 0; - context->if4.image3.image2.image.cur_loop = 0; - context->if4.image3.image2.image.cur_time = 0; + if (context->image.is_animated_gif) { + context->image.cur_frame = 0; + context->image.cur_loop = 0; + context->image.cur_time = 0; obs_enter_graphics(); - gs_image_file4_update_texture(&context->if4); + gs_image_file_ex_update_texture(&context->image); obs_leave_graphics(); context->restart_gif = false; @@ -182,19 +185,20 @@ if (context->file) bfree(context->file); + bfree(context); } static uint32_t image_source_getwidth(void *data) { struct image_source *context = data; - return context->if4.image3.image2.image.cx; + return context->image.cx; } static uint32_t image_source_getheight(void *data) { struct image_source *context = data; - return context->if4.image3.image2.image.cy; + return context->image.cy; } static void image_source_render(void *data, gs_effect_t *effect) @@ -203,7 +207,7 @@ if (!os_atomic_load_bool(&context->texture_loaded)) return; - struct gs_image_file *const image = &context->if4.image3.image2.image; + gs_image_file_ex_t *const image = &context->image; gs_texture_t *const texture = image->texture; if (!texture) return; @@ -251,8 +255,9 @@ if (obs_source_showing(context->source)) { if (!context->active) { - if (context->if4.image3.image2.image.is_animated_gif) + if (context->image.is_animated_gif) context->last_time = frame_time; + context->active = true; } @@ -268,13 +273,13 @@ return; } - if (context->last_time && context->if4.image3.image2.image.is_animated_gif) { + if (context->last_time && context->image.is_animated_gif) { uint64_t elapsed = frame_time - context->last_time; - bool updated = gs_image_file4_tick(&context->if4, elapsed); + bool updated = gs_image_file_ex_tick(&context->image, elapsed); if (updated) { obs_enter_graphics(); - gs_image_file4_update_texture(&context->if4); + gs_image_file_ex_update_texture(&context->image); obs_leave_graphics(); } } @@ -316,7 +321,7 @@ uint64_t image_source_get_memory_usage(void *data) { struct image_source *s = data; - return s->if4.image3.image2.mem_usage; + return s->image.mem_usage; } static void missing_file_callback(void *src, const char *new_path, void *data) @@ -356,8 +361,8 @@ UNUSED_PARAMETER(preferred_spaces); struct image_source *const s = data; - gs_image_file4_t *const if4 = &s->if4; - return if4->image3.image2.image.texture ? if4->space : GS_CS_SRGB; + gs_image_file_ex_t *const image = &s->image; + return image->texture ? image->space : GS_CS_SRGB; } static struct obs_source_info image_source_info = {
View file
obs-studio-32.2.2.tar.xz/plugins/linux-alsa/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/linux-alsa/CMakeLists.txt
Changed
@@ -3,7 +3,6 @@ option(ENABLE_ALSA "Build OBS with ALSA support" ON) if(NOT ENABLE_ALSA) - target_disable(linux-alsa) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/linux-alsa/alsa-input.c -> obs-studio-33.0.0.tar.xz/plugins/linux-alsa/alsa-input.c
Changed
@@ -51,6 +51,7 @@ os_event_t *abort_event; volatile bool listen; volatile bool reopen; + volatile bool shutdown; /* alsa */ snd_pcm_t *handle; @@ -121,6 +122,7 @@ data->handle = NULL; data->listen = false; data->reopen = false; + data->shutdown = false; data->listen_thread = 0; data->reopen_thread = 0; @@ -154,6 +156,8 @@ { struct alsa_data *data = vptr; + os_atomic_set_bool(&data->shutdown, true); + if (data->handle) _alsa_close(data); @@ -342,6 +346,9 @@ { _alsa_stop_reopen(data); + if (os_atomic_load_bool(&data->shutdown)) + return false; + if (_alsa_open(data)) return true; @@ -352,6 +359,9 @@ bool _alsa_open(struct alsa_data *data) { + if (os_atomic_load_bool(&data->shutdown)) + return false; + pthread_attr_t attr; int err; @@ -501,6 +511,9 @@ void _alsa_start_reopen(struct alsa_data *data) { + if (os_atomic_load_bool(&data->shutdown)) + return; + pthread_attr_t attr; int err;
View file
obs-studio-32.2.2.tar.xz/plugins/linux-alsa/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/linux-alsa/data/locale/kaa.ini
Changed
@@ -1,2 +1,4 @@ -Custom="Arnawlı" -Device="Qurılma" +Default="Әдепки" +Custom="Арнаўлы" +Device="Қурылма" +Rate="Частота"
View file
obs-studio-32.2.2.tar.xz/plugins/linux-alsa/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/linux-alsa/data/locale/tr-TR.ini
Changed
@@ -1,5 +1,5 @@ -AlsaInput="Ses yakalama cihazı (ALSA)" +AlsaInput="Ses Yakalama Aygıtı (ALSA)" Default="Varsayılan" Custom="Özel" -Device="Cihaz" -Rate="Frekans" +Device="Aygıt" +Rate="Sıklık"
View file
obs-studio-32.2.2.tar.xz/plugins/linux-capture/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/linux-capture/data/locale/kaa.ini
Changed
@@ -1,5 +1,6 @@ -AdvancedSettings="Qosımsha sazlawlar" -Window="Ayna" +Display="Экран" +XServer="X-сервер" +Window="Айна" CropTop="Joqarı tárepti qıyıw" CropLeft="Shep tárepti qıyıw" CropRight="Oń tárepti qıyıw"
View file
obs-studio-32.2.2.tar.xz/plugins/linux-capture/data/locale/sv-SE.ini -> obs-studio-33.0.0.tar.xz/plugins/linux-capture/data/locale/sv-SE.ini
Changed
@@ -11,6 +11,6 @@ CropBottom="Beskär nederkant" IncludeXBorder="Inkludera X Border" ExcludeAlpha="Använd alfalöst texturformat (lösning för Mesa)" -SelectAWindow="Välj ett fönster att fånga" -SelectADisplay="Välj en skärm att fånga" +SelectAWindow="Välj ett fönster att visa" +SelectADisplay="Välj en skärm att visa" UnknownWindow="Okänt fönster"
View file
obs-studio-32.2.2.tar.xz/plugins/linux-jack/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/linux-jack/CMakeLists.txt
Changed
@@ -2,7 +2,6 @@ option(ENABLE_JACK "Build OBS with JACK support" OFF) if(NOT ENABLE_JACK) - target_disable(linux-jack) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/linux-jack/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/linux-jack/data/locale/kaa.ini
Changed
@@ -1,2 +1,3 @@ -StartJACKServer="JACK serverin iske túsiriw" -Channels="Kanallar sanı" +StartJACKServer="JACK серверин иске түсириў" +Channels="Каналлар саны" +JACKInput="JACK кириў клиенти"
View file
obs-studio-32.2.2.tar.xz/plugins/linux-pipewire/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/linux-pipewire/CMakeLists.txt
Changed
@@ -2,7 +2,6 @@ option(ENABLE_PIPEWIRE "Enable PipeWire support" ON) if(NOT ENABLE_PIPEWIRE) - target_disable(linux-pipewire) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/linux-pipewire/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/linux-pipewire/data/locale/kaa.ini
Changed
@@ -1,3 +1,5 @@ -PipeWireSelectMonitor="Monitordı tańlaw" -PipeWireSelectWindow="Aynanı tańlaw" -ShowCursor="Kórsetkishdi kórsetiw" +PipeWireCameraDevice="Қурылма" +PipeWireSelectMonitor="Мониторды таңлаў" +PipeWireSelectWindow="Айнаны таңлаў" +ShowCursor="Курсорды көрсетиў" +VideoFormat="Видео форматы"
View file
obs-studio-32.2.2.tar.xz/plugins/linux-pipewire/screencast-portal.c -> obs-studio-33.0.0.tar.xz/plugins/linux-pipewire/screencast-portal.c
Changed
@@ -692,7 +692,7 @@ const struct obs_source_info screencast_portal_desktop_capture_info = { .id = "pipewire-desktop-capture-source", .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CAP_OBSOLETE, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_DO_NOT_DUPLICATE | OBS_SOURCE_CAP_OBSOLETE, .get_name = screencast_portal_desktop_capture_get_name, .create = screencast_portal_desktop_capture_create, .destroy = screencast_portal_capture_destroy, @@ -714,7 +714,7 @@ const struct obs_source_info screencast_portal_window_capture_info = { .id = "pipewire-window-capture-source", .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CAP_OBSOLETE, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_DO_NOT_DUPLICATE | OBS_SOURCE_CAP_OBSOLETE, .get_name = screencast_portal_window_capture_get_name, .create = screencast_portal_window_capture_create, .destroy = screencast_portal_capture_destroy, @@ -736,7 +736,7 @@ const struct obs_source_info screencast_portal_capture_info = { .id = "pipewire-screen-capture-source", .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_DO_NOT_DUPLICATE, .get_name = screencast_portal_desktop_capture_get_name, .create = screencast_portal_capture_create, .destroy = screencast_portal_capture_destroy,
View file
obs-studio-32.2.2.tar.xz/plugins/linux-pulseaudio/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/linux-pulseaudio/CMakeLists.txt
Changed
@@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.28...3.30) if(NOT ENABLE_PULSEAUDIO) - target_disable(linux-pulseaudio) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/linux-pulseaudio/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/linux-pulseaudio/data/locale/kaa.ini
Changed
@@ -1,1 +1,2 @@ -Device="Qurılma" +Device="Қурылма" +Default="Әдепки"
View file
obs-studio-32.2.2.tar.xz/plugins/linux-v4l2/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/linux-v4l2/CMakeLists.txt
Changed
@@ -4,12 +4,11 @@ option(ENABLE_UDEV "Build linux-v4l2 with UDEV support" ON) if(NOT ENABLE_V4L2) - target_disable(linux-v4l2) return() endif() find_package(Libv4l2 REQUIRED) -find_package(FFmpeg REQUIRED COMPONENTS avcodec avutil avformat) +find_package(FFmpeg 8.0 REQUIRED COMPONENTS avcodec avutil avformat) if(OS_FREEBSD OR OS_OPENBSD) set(CMAKE_REQUIRED_INCLUDES "/usr/local/include")
View file
obs-studio-32.2.2.tar.xz/plugins/linux-v4l2/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/linux-v4l2/data/locale/kaa.ini
Changed
@@ -1,10 +1,5 @@ -Device="Qurılma" -VideoFormat="Video format" -VideoStandard="Standart video" -Resolution="Kólem" -LeaveUnchanged="Ózgerissiz qaldırıw" -ColorRange="Reń aralıǵı" -ColorRange.Default="Aldınnan ornatılǵan" -ColorRange.Partial="Sheklengen" -ColorRange.Full="Tolıq" -CameraCtrls="Kamera basqarıwı" +Device="Қурылма" +ColorRange="Рең аралығы" +ColorRange.Default="Әдепки" +ColorRange.Partial="Шекленген" +ColorRange.Full="Толық"
View file
obs-studio-32.2.2.tar.xz/plugins/linux-v4l2/v4l2-decoder.c -> obs-studio-33.0.0.tar.xz/plugins/linux-v4l2/v4l2-decoder.c
Changed
@@ -78,9 +78,6 @@ } if (decoder->context) { -#if LIBAVCODEC_VERSION_MAJOR < 61 - avcodec_close(decoder->context); -#endif avcodec_free_context(&decoder->context); } }
View file
obs-studio-32.2.2.tar.xz/plugins/mac-avcapture/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/mac-avcapture/CMakeLists.txt
Changed
@@ -26,6 +26,7 @@ XCODE_ATTRIBUTE_CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION YES XCODE_ATTRIBUTE_GCC_WARN_SHADOW YES ) +target_enable(mac-avcapture-legacy) add_library(mac-avcapture MODULE) add_library(OBS::avcapture ALIAS mac-avcapture)
View file
obs-studio-32.2.2.tar.xz/plugins/mac-avcapture/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/mac-avcapture/data/locale/kaa.ini
Changed
@@ -1,10 +1,7 @@ -AVCapture="Video qamtıp alıw qurılması" -Device="Qurılma" +Device="Қурылма" UsePreset="Sazlawlar jıyındısın qollanıw" -Preset="Sazlawlar jıyındısı" -ColorSpace="Reń maydanı" -VideoRange.Partial="Sheklengen" -VideoRange.Full="Tolıq" -Auto="Avtomat tárizde" -Unknown="Belgisiz (%1)" -Resolution="Kólem" +ColorSpace="Рең майданы" +VideoRange.Partial="Шекленген" +VideoRange.Full="Толық" +Auto="Автоматикалық" +Unknown="Белгисиз (%1)"
View file
obs-studio-32.2.2.tar.xz/plugins/mac-avcapture/data/locale/ko-KR.ini -> obs-studio-33.0.0.tar.xz/plugins/mac-avcapture/data/locale/ko-KR.ini
Changed
@@ -1,6 +1,6 @@ AVCapture="비디오 캡쳐 장치" AVCapture_Fast="캡쳐 카드 장치" -AVCapture_Legacy="비디오 캡쳐 장치" +AVCapture_Legacy="비디오 캡쳐 장치 (구식)" Device="장치" UsePreset="사전 설정 사용" Preset="사전 설정"
View file
obs-studio-32.2.2.tar.xz/plugins/mac-avcapture/data/locale/pt-PT.ini -> obs-studio-33.0.0.tar.xz/plugins/mac-avcapture/data/locale/pt-PT.ini
Changed
@@ -1,6 +1,6 @@ AVCapture="Dispositivo de captura de vídeo" AVCapture_Fast="Dispositivo de placa de captura" -AVCapture_Legacy="Dispositivo de captura de vídeo (legada)" +AVCapture_Legacy="Dispositivo de captura de vídeo (obsoleto)" Device="Dispositivo" UsePreset="Utilizar predefinição" Preset="Predefinição"
View file
obs-studio-32.2.2.tar.xz/plugins/mac-capture/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/mac-capture/data/locale/kaa.ini
Changed
@@ -1,28 +1,13 @@ -CoreAudio.Device="Qurılma" -CoreAudio.Device.Default="Aldınnan ornatılǵan" -ApplicationCapture="Qosımshanı qamtıp alıw" -ApplicationAudioCapture="Qosımsha dawısın qamtıp alıw" -DisplayCapture="Ekrandı qamtıp alıw" -DisplayCapture.Display="Ekran" -DisplayCapture.ShowCursor="Kórsetkishdi kórsetiw" -DisplayCapture.HideOBS="OBStı jazıp alıw waqtında jasırıw" -WindowCapture="Aynanı qamtıw" -Application="Baǵdarlama" -WindowUtils.Window="Ayna" -WindowUtils.ShowHidden="Tolıq ekranlı hám jasırın aynalardı kórsetiw / qosımshalar" -CropMode="Qırqıw" -CropMode.None="Joq" -CropMode.Manual="Qolda" -CropMode.ToWindow="Aynaǵa qarap" -CropMode.ToWindowAndManual="Aynaǵa qarap hám qolda" -Crop.origin.x="Shep tárepti qıyıw" -Crop.origin.y="Joqarı tárepti qıyıw" -Crop.size.width="Oń tárepti qıyıw" -Crop.size.height="Tómengi tárepti qıyıw" -SCK.Name="macOS ekranın qamtıp alıw" -SCK.Name.Beta="macOS ekranın qamtıp alıw (BETA)" -SCK.Audio.Name="macOS dawısın qamtıp alıw" -SCK.AudioUnavailable="Dawıstı qamtıp alıw macOS 13 yamasa odanda jańasın talap etedi." -SCK.CaptureTypeUnavailable="Tańlanǵan qamtıw usılı macOS 13 yamasa odanda jańasın talap etedi." -SCK.Method="Metod" -SCK.Restart="Qamtıp alıwdı qayta iske túsiriw" +CoreAudio.Device="Қурылма" +CoreAudio.Device.Default="Әдепки" +CoreAudio.Channel="Канал" +CoreAudio.Channel.Default="Әдепки" +CoreAudio.Channel.Unnamed="Атамасыз" +CoreAudio.Channel.Device="Қурылма каналы" +CoreAudio.None="Жоқ" +DisplayCapture.Display="Экран" +DisplayCapture.ShowCursor="Курсорды көрсетиў" +Application="Қосымша" +WindowUtils.Window="Айна" +CropMode.None="Жоқ" +SCK.Method="Усыл"
View file
obs-studio-32.2.2.tar.xz/plugins/mac-capture/mac-sck-video-capture.m -> obs-studio-33.0.0.tar.xz/plugins/mac-capture/mac-sck-video-capture.m
Changed
@@ -209,9 +209,13 @@ } else { blog(LOG_WARNING, "Unable to retrieve OBS output FPS when initializing macOS Screen Capture"); } - FourCharCode l10r_type = 0; - l10r_type = ('l' << 24) | ('1' << 16) | ('0' << 8) | 'r'; - sc->stream_properties setPixelFormat:l10r_type; + // Use 64RGBAHalf where available, for superior 16-bit float color and alpha depth. On prior macOS versions where + // 64RGBAHalf is unavailable, fall back to 32BGRA (8-bit UInt color and alpha). + if (@available(macOS 15.0, *)) { + sc->stream_properties setPixelFormat:kCVPixelFormatType_64RGBAHalf; + } else { + sc->stream_properties setPixelFormat:kCVPixelFormatType_32BGRA; + } if (@available(macOS 13.0, *)) { sc->stream_properties setCapturesAudio:YES;
View file
obs-studio-32.2.2.tar.xz/plugins/mac-syphon/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/mac-syphon/CMakeLists.txt
Changed
@@ -2,7 +2,6 @@ option(ENABLE_SYPHON "Enable Syphon sharing support" ON) if(NOT ENABLE_SYPHON) - target_disable(mac-syphon) target_disable_feature(mac-syphon "Syphon sharing support") return() else()
View file
obs-studio-32.2.2.tar.xz/plugins/mac-syphon/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/mac-syphon/data/locale/kaa.ini
Changed
@@ -1,7 +1,9 @@ -Source="Derek" -SyphonLicense="Syphon licenziyası" -Crop="Qıyıw" -Crop.origin.x="Shep tárepti qıyıw" -Crop.origin.y="Joqarı tárepti qıyıw" -Crop.size.width="Oń tárepti qıyıw" -Crop.size.height="Tómengi tárepti qıyıw" +Syphon="Клиент Syphon" +Source="Дерек" +SyphonLicense="Syphon лицензиясы" +Crop="Қырқыў" +Crop.origin.x="Шептен қырқыў" +Crop.origin.y="Жоқарыдан қырқыў" +Crop.size.width="Оңнан қырқыў" +Crop.size.height="Төменнен қырқыў" +AllowTransparency="Мөлдирликке руқсат бериў"
View file
obs-studio-32.2.2.tar.xz/plugins/mac-videotoolbox/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/mac-videotoolbox/data/locale/kaa.ini
Changed
@@ -1,10 +1,17 @@ -VTH264EncHW="Apple VT H264 apparatlıq kodlawshısı" -VTHEVCEncHW="Apple VT HEVC apparatlıq kodlawshısı" -VTHEVCEncT2="Apple VT HEVC T2 apparatlıq kodlawshısı" -VTProResEncHW="Apple VT ProRes apparatlıq kodlawshısı" -Bitrate="Bit tezligi" -Quality="Sapası" -UseMaxBitrate="Bit tezligin sheklew" -Profile="Profil" -UseBFrames="B-kadrlardı qollanıw" -ProResCodec="ProRes kodeki" +VTH264EncHW="Apple VT H264 аппаратлық кодлаўшысы" +VTH264EncSW="Apple VT H264 программалық кодлаўшысы" +VTHEVCEncHW="Apple VT HEVC аппаратлық кодлаўшысы" +VTHEVCEncT2="Apple VT HEVC T2 аппаратлық кодлаўшысы" +VTHEVCEncSW="Apple VT HEVC программалық кодлаўшысы" +VTProResEncHW="Apple VT ProRes аппаратлық кодлаўшысы" +VTProResEncSW="Apple VT ProRes программалық кодлаўшысы" +Bitrate="Битрейт" +Quality="Сапа" +UseMaxBitrate="Битрейтти шеклеў" +MaxBitrate="Максимал битрейт" +Profile="Профиль" +UseBFrames="B-кадрлардан қолланыў" +SpatialAQ.Auto="Автоматикалық" +SpatialAQ.Disabled="Өширилген" +SpatialAQ.Enabled="Қосылған" +ProResCodec="Кодек ProRes"
View file
obs-studio-32.2.2.tar.xz/plugins/mac-virtualcam/src/obs-plugin/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/mac-virtualcam/src/obs-plugin/data/locale/kaa.ini
Changed
@@ -1,8 +1,1 @@ -Plugin_Name="macOS Vırtual Veb-kamerası" -Error.SystemExtension.NotInstalled="Virtual kamera ornatılmadı.\n\nÓtinish, OBSǵa sistema baǵdarlamaların ornatıwǵa ruqsat beriń: \"Sistema sazlawları → Qupiyalıq hám qáwipsizlik → Qáwipsizlik\"\n\nEger bul xabar onnan keyinde kórsetilse, OBStı qayta iske túsiriw kerek bolıwı múmkin." -Error.SystemExtension.CameraNotStarted="Virtual kameranı iske túsiriw múmkinshiligi bolmadı.\n\nÓtinish, qayta urınıp kóriń." -Error.SystemExtension.InstallationError="Virtual kameranı ornatıw waqtında qátelik kelip shıqtı:" -Error.SystemExtension.WrongLocation="Eger OBS \"/Applications\" papkasında bolmasa, virtual kameranı ornata almaydı. Ótinish, OBStı \"/Applications\" papkasına jayǵastırıń." -Error.SystemExtension.CompleteAfterReboot="Virtual kameranı ornatıw sistemanı qayta iske túsirgennen soń juwmaqlanadı." -Error.DAL.NotInstalled="Virtual kameranı ornatıw yamasa jańalaw ámelge aspadı.\n\nÓtinish, soraw payda bolǵanda administrator atın hám parolin kirgiziń hám qayta urınıp kóriń" -Error.DAL.NotUninstalled="Eskirgen virtual kameranı óshiriw ámelge aspadı.\n\nÓtinish, soraw payda bolǵanda administrator atın hám parolin kirgiziń hám qayta urınıp kóriń." +Plugin_Name="macOS виртуал веб камерасы"
View file
obs-studio-32.2.2.tar.xz/plugins/mac-virtualcam/src/obs-plugin/data/locale/pt-PT.ini -> obs-studio-33.0.0.tar.xz/plugins/mac-virtualcam/src/obs-plugin/data/locale/pt-PT.ini
Changed
@@ -7,4 +7,4 @@ Error.SystemExtension.WrongLocation="O OBS não pode instalar a câmera virtual se não estiver na pasta \"/Applications\". Mova o OBS para a pasta \"/Applications\"." Error.SystemExtension.CompleteAfterReboot="A instalação da câmera virtual será concluída após o reinício do sistema." Error.DAL.NotInstalled="Não foi possível instalar ou atualizar a câmera virtual.\n\nPor favor, tente de novo e introduza o nome e a senha de administrador, quando pedida." -Error.DAL.NotUninstalled="Não foi possível remover a câmera virtual legada.\n\nPor favor, tente de novo e introduza o nome e a senha de administrador, quando pedida." +Error.DAL.NotUninstalled="Não foi possível remover a câmera virtual obsoleta.\n\nPor favor, tente de novo e introduza o nome e a senha de administrador, quando pedida."
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/ar-SA.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/ar-SA.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="مزيل إزعاج إنفيديا" Nvafx.Method.Dereverb="NVIDIA إزالة صدى الغرفة " Nvafx.Method.DenoiserPlusDereverb="NVIDIA إزالة الضوضاء + إزالة صدى الغرفة" -Nvafx.OutdatedSDK="تحذير: الرجاء ترقية كل من الفيديو والـ SDK NVIDIA . الإصدار الحالي من ملف SDK للصوت قديم ." Nvafx.VAD="صوت محسّن" Nvvfx.Method.Greenscreen="NVIDIA إزالة الخلفية " Nvvfx.Method.Greenscreen.Mode="النمط" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="الجودة (إستخدام أعلى لكارت الشاشة، جودة أفضل) + إزالة Chair" Nvvfx.Method.Greenscreen.Performance.Chair="الجودة (إستخدام أقل لكارت الشاشة، جودة جيدة) + Chair" Nvvfx.Method.Greenscreen.Threshold="الحد الاقصى" -Nvvfx.OutdatedSDK="تحذير: يرجى ترقية مجموعة أدوات تطوير البرامج لـNVIDIA لكل من الفيديو والصوت. نسختك الحالية لمجموعة أدوات تطوير البرامج للفيديو قديمة." Nvvfx.Method.Greenscreen.Processing="إقناع تردد التحديث في الأطر" Nvvfx.Method.Greenscreen.Processing.Hint="هذا يخفف من حمولة وحدة معالجة الرسومات عن طريق إنشاء قناع كل إطارات N فقط (2 بشكل افتراضي)." Nvvfx.Method.BlurFilter="مرشح طمس NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/az-AZ.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/az-AZ.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="NVIDIA Küy Təmizləmə" Nvafx.Method.Dereverb="NVIDIA Otaq Exosu Təmizləmə" Nvafx.Method.DenoiserPlusDereverb="NVIDIA Küy Təmizləmə + Otaq Exosu Təmizləmə" -Nvafx.OutdatedSDK="XƏBƏRDARLIQ: Zəhmət olmasa, həm NVIDIA Video, həm də Audio SDK-lərini yeniləyin. Sizin Audio SDK versiyanız köhnəlib." Nvafx.VAD="Səs Optimallaşdırılıb" Nvvfx.Method.Greenscreen="NVIDIA Arxa Fon Təmizləmə" Nvvfx.Method.Greenscreen.Mode="Rejim" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Keyfiyyət (daha yüksək GPU istifadəsi, daha yaxşı keyfiyyət) + Oturacaq silmə" Nvvfx.Method.Greenscreen.Performance.Chair="Performans (daha aşağı GPU istifadəsi, yaxşı keyfiyyət) + Oturacaq silmə" Nvvfx.Method.Greenscreen.Threshold="Hədd" -Nvvfx.OutdatedSDK="XƏBƏRDARLIQ: Zəhmət olmasa, həm NVIDIA Video, həm də Audio SDK-lərini yeniləyin. Sizin Video SDK versiyanız köhnəlib." Nvvfx.Method.Greenscreen.Processing="Maska yenilənmə tezliyi (kadrla)" Nvvfx.Method.Greenscreen.Processing.Hint="Bu, yalnız hər N kadrda bir maska yaradaraq GPU yükünü azaldır (susmaya görə 2)." Nvvfx.Method.BlurFilter="NVIDIA Bulanlıq Filtri"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/be-BY.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/be-BY.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Выдаленне шуму NVIDIA" Nvafx.Method.Dereverb="Выдаленне пакаёвага рэха NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Выдаленне шуму і пакаёвага рэха NVIDIA" -Nvafx.OutdatedSDK="УВАГА: Абнавіце NVIDIA Video і Audio SDK. Бягучая версія Audio SDK састарэла." +Nvafx.OutdatedSDK="УВАГА: Абнавіце NVIDIA Video і Audio SDK. Бягучая версія Audio SDK састарэла. Гэта можа прывесці да збояў аўдыяэфектаў і/або відэаэфектаў." Nvafx.VAD="Аптымізацыя голасу" Nvvfx.Method.Greenscreen="Выдаленне фону NVIDIA" Nvvfx.Method.Greenscreen.Mode="Рэжым" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Якасць (вышэйшае спажыванне рэсурсаў ГП, лепшая якасць) + Выдаленне крэсла" Nvvfx.Method.Greenscreen.Performance.Chair="Прадукцыйнасць (ніжэйшае спажыванне рэсурсаў ГП, добрая якасць) + Выдаленне крэсла" Nvvfx.Method.Greenscreen.Threshold="Парог" -Nvvfx.OutdatedSDK="УВАГА: Абнавіце NVIDIA Video і Audio SDK. Бягучая версія Video SDK састарэла." +Nvvfx.OutdatedSDK="УВАГА: Абнавіце NVIDIA Video і Audio SDK. Бягучая версія Video SDK састарэла. Гэта можа прывесці да збояў аўдыяэфектаў і/або відэаэфектаў." Nvvfx.Method.Greenscreen.Processing="Частата абнаўлення маскі ў кадрах" Nvvfx.Method.Greenscreen.Processing.Hint="Маска генеруецца толькі адзін раз на N кадраў (па змаўчанні 2), памяншаючы нагрузку ГП." Nvvfx.Method.BlurFilter="Фільтр размытасці NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/ca-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/ca-ES.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Supressió de soroll d'NVIDIA" Nvafx.Method.Dereverb="Supressió d'eco d'habitació d'NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Supressió de soroll + eco d'habitació d'NVIDIA" -Nvafx.OutdatedSDK="AVÍS: actualitzeu l'SDK de vídeo i d'àudio de NVIDIA. La vostra versió actual de l'SDK d'àudio està obsoleta." +Nvafx.OutdatedSDK="AVÍS: actualitzeu tant l'SDK de vídeo com el d'àudio de NVIDIA. La versió actual de l'SDK d'àudio està obsoleta. Això pot fer que deixin de funcionar els efectes d'àudio, de vídeo o tots dos." Nvafx.VAD="Veu optimitzada" Nvvfx.Method.Greenscreen="Supressió de fons d'NVIDIA" Nvvfx.Method.Greenscreen.Quality="Qualitat (ús alt de GPU, la millor qualitat)" @@ -13,7 +13,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Qualitat (ús més alt de la GPU, millor qualitat) + eliminació de cadires\n" Nvvfx.Method.Greenscreen.Performance.Chair="Rendiment (baix ús de la GPU, bona qualitat) + eliminació de cadires" Nvvfx.Method.Greenscreen.Threshold="Llindar" -Nvvfx.OutdatedSDK="AVÍS: actualitzeu l'SDK de vídeo i d'àudio de NVIDIA. La vostra versió actual de l'SDK de vídeo està obsoleta." +Nvvfx.OutdatedSDK="AVÍS: actualitzeu tant l'SDK de vídeo com el d'àudio de NVIDIA. La versió actual de l'SDK de vídeo està obsoleta. Això pot fer que deixin de funcionar els efectes d'àudio, de vídeo o tots dos." Nvvfx.Method.Greenscreen.Processing="Freqüència d'actualització de la màscara en fotogrames" Nvvfx.Method.Greenscreen.Processing.Hint="Això alleuja la càrrega de la GPU generant una màscara cada N fotogrames només (2 per defecte)." Nvvfx.Method.BlurFilter="Filtre de desenfocament NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/cs-CZ.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/cs-CZ.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="NVIDIA Odstranění šumu" Nvafx.Method.Dereverb="NVIDIA Odstranění ozvěny místnosti" Nvafx.Method.DenoiserPlusDereverb="NVIDIA Odstranění šumu a ozvěny místnosti" -Nvafx.OutdatedSDK="VAROVÁNÍ: Aktualizujte NVIDIA Video & Audio SDK. Vaše aktuální verze Audio SDK je zastaralá." Nvafx.VAD="Optimalizováno pro hlas" Nvvfx.Method.Greenscreen="NVIDIA Odstranění zvuku pozadí" Nvvfx.Method.Greenscreen.Mode="Režim" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Kvalita (vyšší využití GPU, lepší kvalita) + odstranění židle" Nvvfx.Method.Greenscreen.Performance.Chair="Výkon (nižší využití GPU, dobrá kvalita) + odstranění židle" Nvvfx.Method.Greenscreen.Threshold="Práh" -Nvvfx.OutdatedSDK="VAROVÁNÍ: Aktualizujte NVIDIA Video & Audio SDK. Vaše aktuální verze Video SDK je zastaralá." Nvvfx.Method.Greenscreen.Processing="Obnovovací frekvence masky ve snímcích" Nvvfx.Method.Greenscreen.Processing.Hint="Snižuje zatížení GPU generováním masky pouze každý N-tý snímek (výchoze 2)." Nvvfx.Method.BlurFilter="Filtr rozostření NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/da-DK.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/da-DK.ini
Changed
@@ -5,13 +5,11 @@ Nvafx.Method.Denoiser="NVIDIA Støjreduktion" Nvafx.Method.Dereverb="NVIDIA Rumekko fjernelse" Nvafx.Method.DenoiserPlusDereverb="NVIDIA støjfjernelse + rumekkoo fjernelse" -Nvafx.OutdatedSDK="ADVARSEL: Opgrader venligst både NVIDIA Video & Audio SDK. Din nuværende version af Audio SDK er forældet." Nvvfx.Method.Greenscreen="NVIDIA baggrundsfjernelse" Nvvfx.Method.Greenscreen.Mode="Tilstand" Nvvfx.Method.Greenscreen.Quality="Kvalitet (højere GPU-forbrug, bedre kvalitet)" Nvvfx.Method.Greenscreen.Performance="Ydeevne (lavere GPU-forbrug, god kvalitet)" Nvvfx.Method.Greenscreen.Threshold="Grænse" -Nvvfx.OutdatedSDK="ADVARSEL: Opgrader venligst både NVIDIA Video & Audio SDK. Din nuværende version af Video SDK er forældet." Nvvfx.Method.Greenscreen.Processing="Masker opdateringsfrekvens i billeder" Nvvfx.Method.Greenscreen.Processing.Hint="Dette lindrer GPU-pres ved generering af maskering kun på hvert N'te billede (2 som standard)" Nvvfx.Method.BlurFilter="NVIDIA Sløringsfilter"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/de-DE.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/de-DE.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA-Rauschentfernung" Nvafx.Method.Dereverb="NVIDIA-Raumechoentfernung" Nvafx.Method.DenoiserPlusDereverb="NVIDIA-Rauschentfernung + -Raumechoentfernung" -Nvafx.OutdatedSDK="Achtung: Die Version Ihres Audio-SDK ist veraltet. Aktualisieren Sie sowohl Ihr NVIDIA-Video- als auch -Audio-SDK." +Nvafx.OutdatedSDK="WARNUNG: Bitte aktualisieren Sie die NVIDIA Video & Audio SDK. Die installierte NVIDIA Video & Audio SDK ist veraltet. Dies kann zum Ausfallen der Audioeffekte und Videoeffekte führen." Nvafx.VAD="Stimme optimiert" Nvvfx.Method.Greenscreen="NVIDIA-Hintergrundentfernung" Nvvfx.Method.Greenscreen.Mode="Modus" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Qualität (höhere GPU-Nutzung, bessere Qualität) + Stuhlentfernung" Nvvfx.Method.Greenscreen.Performance.Chair="Leistung (niedrigere GPU-Nutzung, gute Qualität) + Stuhlentfernung" Nvvfx.Method.Greenscreen.Threshold="Schwellwert" -Nvvfx.OutdatedSDK="Achtung: Die Version Ihres Video-SDK ist veraltet. Aktualisieren Sie sowohl Ihr NVIDIA-Video- als auch -Audio-SDK." +Nvvfx.OutdatedSDK="WARNUNG: Bitte aktualisieren Sie die NVIDIA Video & Audio SDK. Die installierte NVIDIA Video & Audio SDK ist veraltet. Dies kann zum Ausfallen der Audioeffekte und Videoeffekte führen." Nvvfx.Method.Greenscreen.Processing="Masken-Aktualisierungshäufigkeit in Frames" Nvvfx.Method.Greenscreen.Processing.Hint="Dies verringert die GPU-Auslastung, indem eine Maske nur alle N Frames erzeugt wird (2 auf Voreinstellung)." Nvvfx.Method.BlurFilter="NVIDIA-Weichzeichnenfilter"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/en-US.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/en-US.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA Noise Removal" Nvafx.Method.Dereverb="NVIDIA Room Echo Removal" Nvafx.Method.DenoiserPlusDereverb="NVIDIA Noise Removal + Room Echo Removal" -Nvafx.OutdatedSDK="WARNING: Please upgrade both NVIDIA Video & Audio SDK. Your current version of Audio SDK is outdated." +Nvafx.OutdatedSDK="WARNING: Please upgrade both NVIDIA Video & Audio SDK. Your current version of Audio SDK is outdated. This can break Audio FX, Video FX, or both." Nvafx.VAD="Voice Optimized" Nvvfx.Method.Greenscreen="NVIDIA Background Removal" Nvvfx.Method.Greenscreen.Mode="Mode" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Quality (higher GPU usage, better quality) + Chair removal" Nvvfx.Method.Greenscreen.Performance.Chair="Performance (lower GPU usage, good quality) + Chair removal" Nvvfx.Method.Greenscreen.Threshold="Threshold" -Nvvfx.OutdatedSDK="WARNING: Please upgrade both NVIDIA Video & Audio SDK. Your current version of Video SDK is outdated." +Nvvfx.OutdatedSDK="WARNING: Please upgrade both NVIDIA Video & Audio SDK. Your current version of Video SDK is outdated. This can break Audio FX, Video FX, or both." Nvvfx.Method.Greenscreen.Processing="Mask refresh frequency in frames" Nvvfx.Method.Greenscreen.Processing.Hint="This alleviates GPU load by generating a mask every N frames only (2 on default)." Nvvfx.Method.BlurFilter="NVIDIA Blur Filter"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/es-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/es-ES.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Eliminación de ruido de NVIDIA" Nvafx.Method.Dereverb="Eliminación de eco de la habitación de NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Eliminación de ruido + Eliminación de eco de la habitación de NVIDIA" -Nvafx.OutdatedSDK="ADVERTENCIA: Actualice el SDK de vídeo y audio de NVIDIA. Su versión actual del SDK de audio está desactualizada." +Nvafx.OutdatedSDK="ADVERTENCIA: Por favor, actualiza tanto NVIDIA Video SDK como Audio SDK. Tu versión actual de Audio SDK está desactualizada. Esto puede corromper Audio FX, Video FX o ambos." Nvafx.VAD="Voz optimizada" Nvvfx.Method.Greenscreen="Eliminación de fondo de NVIDIA" Nvvfx.Method.Greenscreen.Mode="Modo" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Calidad (mayor uso de GPU, mejor calidad) + eliminación de silla" Nvvfx.Method.Greenscreen.Performance.Chair="Rendimiento (menor uso de GPU, buena calidad) + eliminación de silla" Nvvfx.Method.Greenscreen.Threshold="Umbral" -Nvvfx.OutdatedSDK="ADVERTENCIA: Actualice el SDK de vídeo y audio de NVIDIA. Su versión actual del SDK de vídeo está desactualizada." +Nvvfx.OutdatedSDK="ADVERTENCIA: Por favor, actualiza tanto NVIDIA Video SDK como Audio SDK. Tu versión actual de Video SDK está desactualizada. Esto puede corromper Audio FX, Video FX o ambos." Nvvfx.Method.Greenscreen.Processing="Frecuencia de actualización de la máscara en fotogramas" Nvvfx.Method.Greenscreen.Processing.Hint="Esto alivia la carga de la GPU generando una máscara solo cada N fotogramas (2 por defecto)." Nvvfx.Method.BlurFilter="Filtro de desenfoque NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/et-EE.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA müra eemaldus" Nvafx.Method.Dereverb="NVIDIA ruumi kaja eemaldus" Nvafx.Method.DenoiserPlusDereverb="NVIDIA müra eemaldus + ruumi kaja eemaldus" -Nvafx.OutdatedSDK="HOIATUS: Palun uuendada nii NVIDIA Video kui ka Audio SDK. Teie praegune Audio SDK versioon on vananenud." +Nvafx.OutdatedSDK="HOIATUS: Palun uuenda nii NVIDIA Video SDK kui ka Audio SDK. Sinu praegune Audio SDK versioon on aegunud. See võib põhjustada Audio FX-i, Video FX-i või mõlema rikkeid." Nvafx.VAD="Hääl optimeeritud" Nvvfx.Method.Greenscreen="NVIDIA tausta eemaldus" Nvvfx.Method.Greenscreen.Mode="Režiim" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Kvaliteet (suurem GPU kasutamine, parem kvaliteet) + tooli eemaldamine" Nvvfx.Method.Greenscreen.Performance.Chair="Jõudlus (väiksem GPU kasutamine, hea kvaliteet) + tooli eemaldamine" Nvvfx.Method.Greenscreen.Threshold="Lävend" -Nvvfx.OutdatedSDK="HOIATUS: Palun uuendada nii NVIDIA Video kui ka Audio SDK. Teie praegune Video SDK versioon on vananenud." +Nvvfx.OutdatedSDK="HOIATUS: Palun uuenda nii NVIDIA Video SDK kui ka Audio SDK. Sinu praegune Video SDK versioon on aegunud. See võib põhjustada Audio FX-i, Video FX-i või mõlema rikkeid." Nvvfx.Method.Greenscreen.Processing="Maski värskendussagedus kaadrites" Nvvfx.Method.Greenscreen.Processing.Hint="See vähendab GPU koormust, genereerides maski ainult iga n kaadri järel (vaikimisi 2)." Nvvfx.Method.BlurFilter="NVIDIA hägustamise filter"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/fa-IR.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/fa-IR.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="حذف نویز NVIDIA" Nvafx.Method.Dereverb="حذف اکو اتاق NVIDIA" Nvafx.Method.DenoiserPlusDereverb="حذف نویز NVIDIA + حذف اکو اتاق" -Nvafx.OutdatedSDK="اخطار: لطفا SDK ویدیویی و صوتی NVIDIA را ارتقا دهید. نسخه فعلی SDK صوتی شما قدیمی است." +Nvafx.OutdatedSDK="هشدار: لطفاً هر دو کیت توسعه نرمافزار (SDK) ویدیو و صدای NVIDIA را بهروزرسانی کنید. نسخه فعلی Audio SDK شما قدیمی است. این مسئله میتواند باعث اختلال در عملکرد Audio FX، Video FX یا هر دوی آنها شود." Nvafx.VAD="صدا بهینهسازی شد" Nvvfx.Method.Greenscreen="حذف پس زمینه NVIDIA" Nvvfx.Method.Greenscreen.Mode="حالت" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="کیفیت (استفاده بیشتر از پردازنده گرافیکی، کیفیت بهتر) + حذف صندلی" Nvvfx.Method.Greenscreen.Performance.Chair="عملکرد (استفاده کمتر از پردازنده گرافیکی، کیفیت خوب) + حذف صندلی" Nvvfx.Method.Greenscreen.Threshold="آستانه" -Nvvfx.OutdatedSDK="اخطار: لطفا SDK ویدیویی و صوتی NVIDIA را ارتقا دهید. نسخه فعلی SDK ویدیویی شما قدیمی است." +Nvvfx.OutdatedSDK="هشدار: لطفاً هر دو کیت توسعه نرمافزار (SDK) ویدیو و صدای NVIDIA را بهروزرسانی کنید. نسخه فعلی Video SDK شما قدیمی است. این مسئله میتواند باعث اختلال در عملکرد Audio FX، Video FX یا هر دوی آنها شود." Nvvfx.Method.Greenscreen.Processing="فرکانس تازه سازی ماسک در فریم ها" Nvvfx.Method.Greenscreen.Processing.Hint="این کار با ایجاد یک ماسک فقط در هر N فریم (2 در حالت پیش فرض) بار GPU را کاهش می دهد." Nvvfx.Method.BlurFilter="فیلتر تاری NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/fi-FI.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/fi-FI.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="NVIDIA-kohinanpoisto" Nvafx.Method.Dereverb="NVIDIA-huonekaiun poisto" Nvafx.Method.DenoiserPlusDereverb="NVIDIA-kohinanpoisto + huonekaiun poisto" -Nvafx.OutdatedSDK="VAROITUS: Päivitä molemmat NVIDIA Video & Audio SDK. Nykyinen Audio SDK versiosi on vanhentunut." Nvafx.VAD="Äänioptimoitu" Nvvfx.Method.Greenscreen="NVIDIA-taustanpoisto" Nvvfx.Method.Greenscreen.Mode="Tila" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Laatu (suurempi GPU-kuormitus, parempi kuvanlaatu) + tuolin poisto" Nvvfx.Method.Greenscreen.Performance.Chair="Suorituskyky (pienempi GPU-kuormitus, hyvä kuvanlaatu) + tuolin poisto" Nvvfx.Method.Greenscreen.Threshold="Kynnysarvo" -Nvvfx.OutdatedSDK="VAROITUS: Päivitä molemmat NVIDIA Video & Audio SDK. Nykyinen Audio SDK versiosi on vanhentunut." Nvvfx.Method.Greenscreen.Processing="Maskin päivitysväli ruuduissa" Nvvfx.Method.Greenscreen.Processing.Hint="Tämä vähentää GPU-kuormitusta, koska maski generoidaan vain joka N:n ruudun välein (oletus 2)." Nvvfx.Method.BlurFilter="NVIDIA-sumennussuodatin"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/fr-FR.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/fr-FR.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Suppression de Bruit NVIDIA" Nvafx.Method.Dereverb="Suppression d'Echo en salle NVIDIA " Nvafx.Method.DenoiserPlusDereverb="Suppression de bruit + Suppression d'Écho NVIDIA" -Nvafx.OutdatedSDK="ATTENTION : Veuillez mettre à jour les SDK Audio et Vidéo NVIDIA. La version actuelle de votre SDK Audio n'est pas à jour. " +Nvafx.OutdatedSDK="AVERTISSEMENT : Veuillez mettre à jour les SDK NVIDIA Video et Audio. Votre version actuelle du SDK Audio est obsolète. Cela peut entraîner des problèmes avec les effets audio, les effets vidéo, ou les deux." Nvafx.VAD="Optimisation vocale" Nvvfx.Method.Greenscreen="Suppression d'arrière-plan NVIDIA" Nvvfx.Method.Greenscreen.Quality="Mode Qualité (Utilisation GPU élevée, meilleure qualité)" @@ -13,7 +13,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Mode Qualité (Utilisation GPU élevée, meilleure qualité)" Nvvfx.Method.Greenscreen.Performance.Chair="Mode Performance (Utilisation GPU faible, bonne qualité)" Nvvfx.Method.Greenscreen.Threshold="Seuil" -Nvvfx.OutdatedSDK="ATTENTION : Veuillez mettre à jour les SDK Audio et Vidéo NVIDIA. La version actuelle de votre SDK Vidéo n'est pas à jour. " +Nvvfx.OutdatedSDK="AVERTISSEMENT : Veuillez mettre à jour les SDK NVIDIA Video et Audio. Votre version actuelle du SDK Video est obsolète. Cela peut entraîner des problèmes avec les effets audio, les effets vidéo, ou les deux." Nvvfx.Method.Greenscreen.Processing="Fréquence de rafraîchissement du masque en nombre d'images" Nvvfx.Method.Greenscreen.Processing.Hint="Ceci allègera la charge GPU en générant un masque tous les N images" Nvvfx.Method.BlurFilter="Filtre Flou NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/gl-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/gl-ES.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Eliminación de Ruído NVIDIA" Nvafx.Method.Dereverb="Eliminación de Eco de Sala NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Eliminación de Ruído NVIDIA + Eliminación de Eco de Sala" -Nvafx.OutdatedSDK="AVISO: Actualiza tanto o vídeo de NVIDIA como o de son SDK. A túa versión actual do SDK de son está desactualizada." +Nvafx.OutdatedSDK="AVISO: Actualiza tanto o NVIDIA Video SDK como o Audio SDK. A versión actual do teu Audio SDK está desactualizada. Isto pode provocar que Audio FX, Video FX ou ambos deixen de funcionar correctamente." Nvafx.VAD="Optimizado para voz" Nvvfx.Method.Greenscreen="Eliminación de Fondo de NVIDIA" Nvvfx.Method.Greenscreen.Mode="Modo" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Calidade (maior uso de GPU, mellor calidade) + eliminación de cadeira" Nvvfx.Method.Greenscreen.Performance.Chair="Rendemento (menor uso de GPU, boa calidade) + eliminación de cadeira" Nvvfx.Method.Greenscreen.Threshold="Limiar" -Nvvfx.OutdatedSDK="AVISO: Actualiza tanto o vídeo de NVIDIA como o de son SDK. A túa versión actual do SDK de son non está actualizada." +Nvvfx.OutdatedSDK="AVISO: Actualiza tanto o NVIDIA Video SDK como o Audio SDK. A versión actual do teu Video SDK está desactualizada. Isto pode provocar que Audio FX, Video FX ou ambos deixen de funcionar correctamente." Nvvfx.Method.Greenscreen.Processing="Frecuencia de actualización da máscara en fotogramas" Nvvfx.Method.Greenscreen.Processing.Hint="Isto alivia a carga da GPU ao xerar unha máscara só cada N fotogramas (2 por defecto)." Nvvfx.Method.BlurFilter="Filtro de desenfoque NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/he-IL.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/he-IL.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="הסרת רעשים של NVIDIA" Nvafx.Method.Dereverb="הסרת הד חדר של NVIDIA" Nvafx.Method.DenoiserPlusDereverb="הסרת רעשים + הד חדר של NVIDIA" -Nvafx.OutdatedSDK="אזהרה: נא לשדרג את ה־SDK של השמע ושל הווידאו של NVIDIA. גרסת ה־SDK של השמע הנוכחית שלך מיושנת." Nvafx.VAD="ממוטב לקול" Nvvfx.Method.Greenscreen="הסרת רקע של NVIDIA" Nvvfx.Method.Greenscreen.Mode="מצב" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="איכות (ניצולת מעבד גבוהה יותר, איכות גבוהה יותר) + הסרת מושבים" Nvvfx.Method.Greenscreen.Performance.Chair="ביצועים (ניצולת מעבד נמוכה יותר, איכות טובה) + הסרת מושבים" Nvvfx.Method.Greenscreen.Threshold="סף" -Nvvfx.OutdatedSDK="אזהרה: נא לשדרג את ה־SDK של השמע ושל הווידאו של NVIDIA. גרסת ה־SDK של הווידאו הנוכחית שלך מיושנת." Nvvfx.Method.Greenscreen.Processing="מיסוך תדירות רענון בתמוניות" Nvvfx.Method.Greenscreen.Processing.Hint="מנצל יותר כוח עיבוד גרפי על ידי מיסוך כל N תמוניות בלבד (2 כברירת מחדל)." Nvvfx.Method.BlurFilter="מסנן טשטוש של NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/hi-IN.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/hi-IN.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="NVIDIA शोर हटाना" Nvafx.Method.Dereverb="NVIDIA कक्ष गूंज हटाना" Nvafx.Method.DenoiserPlusDereverb="NVIDIA शोर हटाना + कक्ष गूंज हटाना" -Nvafx.OutdatedSDK="चेतावनी: कृपया NVIDIA वीडियो व ऑडियो SDK दोनों को अपग्रेड करें. ऑडियो SDK का आपका वर्तमान संस्करण पुराना है." Nvafx.VAD="आवाज अनुकूलित" Nvvfx.Method.Greenscreen="NVIDIA पृष्ठभूमि हटाना" Nvvfx.Method.Greenscreen.Mode="मोड" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="गुणवत्ता (उच्च GPU उपयोग, बेहतर गुणवत्ता) + कुर्सी हटाना" Nvvfx.Method.Greenscreen.Performance.Chair="प्रदर्शन (कम GPU उपयोग, अच्छी गुणवत्ता) + कुर्सी हटाना" Nvvfx.Method.Greenscreen.Threshold="परिसीमा" -Nvvfx.OutdatedSDK="चेतावनी: कृपया NVIDIA वीडियो और ऑडियो SDK दोनों को अपग्रेड करें. वीडियो SDK का आपका वर्तमान संस्करण पुराना हो चुका है." Nvvfx.Method.Greenscreen.Processing="फ़्रेम्स में मास्क रीफ्रेश की आवृत्ति" Nvvfx.Method.Greenscreen.Processing.Hint="यह केवल प्रत्येक N वें फ्रेम (डिफ़ॉल्ट रूप से 2) में मास्क निर्माण कर GPU लोड को कम करता है." Nvvfx.Method.BlurFilter="NVIDIA धुंध फ़िल्टर"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/hr-HR.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/hr-HR.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="Uklanjanje šuma NVIDIA" Nvafx.Method.Dereverb="Uklanjanje odjeka u sobi NVIDIA" Nvafx.Method.DenoiserPlusDereverb="NVIDIA uklanjanje šuma + uklanjanje odjeka u sobi" -Nvafx.OutdatedSDK="UPOZORENJE: Molimo vas da ažurirate NVIDIA Video i Audio SDK. Vaša trenutna verzija Audio SDK-a je zastarjela." Nvafx.VAD="Optimiziano za glas" Nvvfx.Method.Greenscreen="Uklanjanje pozadine NVIDIA" Nvvfx.Method.Greenscreen.Mode="Način" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Kvaliteta (veća potrošnja GPU-a, bolja kvaliteta) + uklanjanje stolice" Nvvfx.Method.Greenscreen.Performance.Chair="Performanse (manja upotreba GPU-a, dobra kvaliteta) + uklanjanje stolice" Nvvfx.Method.Greenscreen.Threshold="Prag" -Nvvfx.OutdatedSDK="UPOZORENJE: Molimo vas da ažurirate i NVIDIA Video i Audio SDK. Vaša trenutna verzija Video SDK-a je zastarjela." Nvvfx.Method.Greenscreen.Processing="Frekvencija osvježavanja maske u okvirima" Nvvfx.Method.Greenscreen.Processing.Hint="To smanjuje opterećenje GPU-a generiranjem maske samo svakih N okvira (2 prema zadanim postavkama)." Nvvfx.Method.BlurFilter="NVIDIA filtar zamućenja"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/hu-HU.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/hu-HU.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA zajeltávolító" Nvafx.Method.Dereverb="NVIDIA szobavisszhang-eltávolító" Nvafx.Method.DenoiserPlusDereverb="NVIDIA zajeltávolító + szobavisszhang-eltávolító" -Nvafx.OutdatedSDK="FIGYELMEZTETÉS: Frissítse az NVIDIA Video & Audio SDK-t. Az Audio SDK jelenlegi verziója elavult." +Nvafx.OutdatedSDK="FIGYELMEZTETÉS: Frissítse mind az NVIDIA Video SDK-t, mind az Audio SDK-t. Az Audio SDK jelenlegi verziója elavult. Ez az Audio FX, a Video FX vagy mindkettő működésének zavarát okozhatja." Nvafx.VAD="Optimalizált beszédhang" Nvvfx.Method.Greenscreen="NVIDIA háttéreltávolító" Nvvfx.Method.Greenscreen.Mode="Mód" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Minőség (magasabb GPU-használat, jobb minőség) + székeltávolítás" Nvvfx.Method.Greenscreen.Performance.Chair="Teljesítmény (alacsonyabb GPU-használat, jó minőség) + székeltávolítás" Nvvfx.Method.Greenscreen.Threshold="Küszöbérték" -Nvvfx.OutdatedSDK="FIGYELMEZTETÉS: Frissítse az NVIDIA Video és Audio SDK-t. A Video SDK jelenlegi verziója elavult." +Nvvfx.OutdatedSDK="FIGYELMEZTETÉS: Frissítse mind az NVIDIA Video SDK-t, mind az Audio SDK-t. A Video SDK jelenlegi verziója elavult. Ez az Audio FX, a Video FX vagy mindkettő működésének zavarát okozhatja." Nvvfx.Method.Greenscreen.Processing="Maszkfrissítés gyakorisága képkockaszámban" Nvvfx.Method.Greenscreen.Processing.Hint="Ez csökkenti a GPU-terhelést, mert csak minden N. képkocka esetén állít elő maszkot (alapértelmezetten N=2)." Nvvfx.Method.BlurFilter="NVIDIA életlenítő szűrő"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/id-ID.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/id-ID.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Penghapus Bising NVIDIA" Nvafx.Method.Dereverb="Penghapus Ruang Gema NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Penghapus Bising NVIDIA + Penghapus Ruang Gema" -Nvafx.OutdatedSDK="PERINGATAN: Mohon perbarui kedua SDK Video & Audio NVIDIA nya. Versi SDK Audio Anda saat ini sudah usang." +Nvafx.OutdatedSDK="PERINGATAN: Mohon perbarui NVIDIA Video & Audio SDK. Versi Audio SDK Anda saat ini sudah usang. Ini akan merusak Audio FX, Video FX, atau keduanya sekaligus." Nvafx.VAD="Suara Teroptimalisasi" Nvvfx.Method.Greenscreen="Penghapus Latar Belakang NVIDIA" Nvvfx.Method.Greenscreen.Quality="Mutu (penggunaan GPU tinggi, mutu lebih baik)" @@ -13,7 +13,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Mutu (penggunaan GPU tinggi, mutu lebih baik) + Menghapus kursi" Nvvfx.Method.Greenscreen.Performance.Chair="Kinerja (penggunaan GPU rendah, mutu bagus) + Menghapus kursi" Nvvfx.Method.Greenscreen.Threshold="Ambang Batas" -Nvvfx.OutdatedSDK="PERINGATAN: Mohon perbarui kedua SDK Video & Audio NVIDIA nya. Versi SDK Video Anda saat ini sudah usang." +Nvvfx.OutdatedSDK="PERINGATAN: Mohon perbarui NVIDIA Video & Audio SDK. Versi Video SDK Anda saat ini sudah usang. Ini akan merusak Audio FX, Video FX, atau keduanya sekaligus." Nvvfx.Method.Greenscreen.Processing="Memasker ulang penyegaran frekuensi dalam bingkai" Nvvfx.Method.Greenscreen.Processing.Hint="Ini meringankan beban GPU dengan memasker hanya di setiap bingkai N (bawaan = 2)" Nvvfx.Method.BlurFilter="Filter Buram NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/it-IT.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/it-IT.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Rimozione rumore NVIDIA" Nvafx.Method.Dereverb="Rimozione eco ambientale NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Rimozione rumore + rimozione eco ambientale NVIDIA" -Nvafx.OutdatedSDK="ATTENZIONE: aggiorna l'SDK NVIDIA sia video che audio. La versione attuale di SDK NVIDIA audio è obsoleta." +Nvafx.OutdatedSDK="ATTENZIONE: aggiorna sia l'SDK video che audio NVIDIA. La versione attuale di SDK audio è obsoleta. Ciò può danneggiare gli effetti audio, video o entrambi." Nvafx.VAD="Voce ottimizzata" Nvvfx.Method.Greenscreen="Rimozione sfondo NVIDIA" Nvvfx.Method.Greenscreen.Mode="Modo" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Qualità (maggiore uso GPU, migliore qualità) + rimozione sedia" Nvvfx.Method.Greenscreen.Performance.Chair="Prestazioni (minore uso GPU, buona qualità) + rimozione sedia" Nvvfx.Method.Greenscreen.Threshold="Soglia" -Nvvfx.OutdatedSDK="ATTENZIONE: aggiorna l'SDK NVIDIA sia video che audio. La versione attuale di SDK NVIDIA video è obsoleta." +Nvvfx.OutdatedSDK="ATTENZIONE: aggiorna sia l'SDK video che audio NVIDIA. La versione attuale di SDK video è obsoleta. Ciò può danneggiare gli effetti audio, video o entrambi." Nvvfx.Method.Greenscreen.Processing="Frequenza aggiornamento maschera in fotogrammi" Nvvfx.Method.Greenscreen.Processing.Hint="Ciò allevia il carico della GPU generando una maschera solo ogni N fotogrammi (2 per impostazione predefinita)." Nvvfx.Method.BlurFilter="Filtro sfocatura NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/ja-JP.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/ja-JP.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA ノイズ除去" Nvafx.Method.Dereverb="NVIDIA ルームエコー除去" Nvafx.Method.DenoiserPlusDereverb="NVIDIA ノイズ除去 + NVIDIA ルームエコー除去" -Nvafx.OutdatedSDK="警告: NVIDIA ビデオ & オーディオ SDK の両方をアップグレードしてください。 現在の オーディオ SDK のバージョンは古くなっています。" +Nvafx.OutdatedSDK="警告: NVIDIA Video & Audio SDK の両方をアップグレードしてください。 現在お使いの Audio SDK のバージョンは古くなっています。 Audio FX、Video FX、またはその両方が動作しなくなる可能性があります。" Nvafx.VAD="音声最適化" Nvvfx.Method.Greenscreen="NVIDIA 背景除去" Nvvfx.Method.Greenscreen.Mode="モード" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="クオリティ (GPU使用率が高く、より高品質) + 椅子の除去" Nvvfx.Method.Greenscreen.Performance.Chair="パフォーマンス (GPU使用率が低く、高品質) + 椅子の除去" Nvvfx.Method.Greenscreen.Threshold="しきい値" -Nvvfx.OutdatedSDK="警告: NVIDIA ビデオ & オーディオ SDK の両方をアップグレードしてください。 現在の ビデオ SDK のバージョンは古くなっています。" +Nvvfx.OutdatedSDK="警告: NVIDIA Video & Audio SDK の両方をアップグレードしてください。 現在お使いの Video SDK のバージョンは古くなっています。 Audio FX、Video FX、またはその両方が動作しなくなる可能性があります。" Nvvfx.Method.Greenscreen.Processing="フレーム単位のマスク更新頻度" Nvvfx.Method.Greenscreen.Processing.Hint="これにより Nフレーム ごとに (既定値では 2) マスクを生成することでGPUの負荷が軽減されます。" Nvvfx.Method.BlurFilter="NVIDIA ぼかしフィルタ"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/ka-GE.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/ka-GE.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="NVIDIA – ხმაურის დახშობა" Nvafx.Method.Dereverb="NVIDIA – ოთახში ექოს მოცილება" Nvafx.Method.DenoiserPlusDereverb="NVIDIA – ხმაურის დახშობა + ოთახში ექოს მოცილება" -Nvafx.OutdatedSDK="ᲒᲐᲤᲠᲗᲮᲘᲚᲔᲑᲐ: გთხოვთ განაახლოთ ორივე, NVIDIA-ს ვიდეოსა და ხმის დასამუშავებელი ნაკრები (SDK). მიმდინარე აუდიო-SDK მოძველებულია." Nvafx.VAD="ხმის მოწესრიგება" Nvvfx.Method.Greenscreen="NVIDIA – ფონური ხმების მოცილება" Nvvfx.Method.Greenscreen.Mode="რეჟიმი" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="ხარისხი (გრაფიკის მეტად დატვირთვა, მაღალი ხარისხი) + სკამის გაქრობა" Nvvfx.Method.Greenscreen.Performance.Chair="წარმადობა (გრაფიკის ნაკლებ დატვირთვა, კარგი ხარისხი) + სკამის გაქრობა" Nvvfx.Method.Greenscreen.Threshold="ზღურბლი" -Nvvfx.OutdatedSDK="ᲒᲐᲤᲠᲗᲮᲘᲚᲔᲑᲐ: გთხოვთ განაახლოთ ორივე, NVIDIA-ს ვიდეოსა და ხმის დასამუშავებელი ნაკრები (SDK). მიმდინარე ვიდეო-SDK მოძველებულია." Nvvfx.Method.Greenscreen.Processing="ნიღბის განახლების სიხშირე კადრებში" Nvvfx.Method.Greenscreen.Processing.Hint="ამცირებს გრაფიკული პროცესორის დატვირთვას ნიღბის ყოველ N-კადრში წარმოებით (ნაგულისხმევადაა 2)" Nvvfx.Method.BlurFilter="NVIDIA – გაბუნდოვანების ფილტრი"
View file
obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/kaa.ini
Added
@@ -0,0 +1,2 @@ +Nvafx.Method="Усыл" +Nvvfx.Method.Greenscreen.Mode="Режим"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/ko-KR.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/ko-KR.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA 소음 제거" Nvafx.Method.Dereverb="NVIDIA 방 에코 제거" Nvafx.Method.DenoiserPlusDereverb="NVIDIA 소음 제거 + 방 에코 제거" -Nvafx.OutdatedSDK="경고: NVIDIA Video 및 Audio SDK를 모두 업그레이드하세요. 설치된 Audio SDK 버전은 최신이 아닙니다." +Nvafx.OutdatedSDK="경고: NVIDIA Video 및 Audio SDK를 모두 업그레이드하세요. 설치된 Audio SDK 버전은 최신이 아닙니다. 이로 인해 오디오나 비디오 효과, 혹은 둘 모두 작동하지 않을 수 있습니다." Nvafx.VAD="음성 최적화" Nvvfx.Method.Greenscreen="NVIDIA 배경 제거" Nvvfx.Method.Greenscreen.Mode="모드" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="품질 (높은 GPU 사용량, 고품질) + 의자 제거" Nvvfx.Method.Greenscreen.Performance.Chair="성능 (낮은 GPU 사용량, 준수한 품질) + 의자 제거" Nvvfx.Method.Greenscreen.Threshold="임계값" -Nvvfx.OutdatedSDK="경고: NVIDIA Video 및 Audio SDK를 모두 업그레이드하세요. 설치된 Video SDK 버전은 최신이 아닙니다." +Nvvfx.OutdatedSDK="경고: NVIDIA Video 및 Audio SDK를 모두 업그레이드하세요. 설치된 Video SDK 버전은 최신이 아닙니다. 이로 인해 오디오나 비디오 효과, 혹은 둘 모두 작동하지 않을 수 있습니다." Nvvfx.Method.Greenscreen.Processing="프레임 단위 마스크 업데이트 빈도" Nvvfx.Method.Greenscreen.Processing.Hint="매 N 프레임에서 마스크를 생성하여 GPU 부하를 완화합니다 (기본값: 2)." Nvvfx.Method.BlurFilter="NVIDIA 흐림 효과 필터"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/lo-LA.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/lo-LA.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="ການລົບສຽງລົບກວນ NVIDIA" Nvafx.Method.Dereverb="ການລົບສຽງສະທ້ອນໃນຫ້ອງ NVIDIA" Nvafx.Method.DenoiserPlusDereverb="ການລົບສຽງລົບກວນ NVIDIA + ການລົບສຽງສະທ້ອນໃນຫ້ອງ" -Nvafx.OutdatedSDK="ຄຳເຕືອນ: ກະລຸນາອັບເກຣດທັງ NVIDIA Video & Audio SDK. ລຸ້ນ Audio SDK ປັດຈຸບັນຂອງທ່ານນັ້ນລ້າສະໄໝແລ້ວ." Nvafx.VAD="ປັບໃຫ້ເໝາະສົມກັບສຽງເວົ້າ" Nvvfx.Method.Greenscreen="ການລົບພື້ນຫຼັງ NVIDIA" Nvvfx.Method.Greenscreen.Mode="ໂໝດ" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="ຄຸນນະພາບ (ການໃຊ້ງານ GPU ສູງກວ່າ, ຄຸນນະພາບດີກວ່າ) + ການລົບຕັ່ງ" Nvvfx.Method.Greenscreen.Performance.Chair="ປະສິດທິພາບ (ການໃຊ້ງານ GPU ຕ່ຳກວ່າ, ຄຸນນະພາບດີ) + ການລົບຕັ່ງ" Nvvfx.Method.Greenscreen.Threshold="ເກນ" -Nvvfx.OutdatedSDK="ຄຳເຕືອນ: ກະລຸນາອັບເກຣດທັງ NVIDIA Video & Audio SDK. ລຸ້ນ Video SDK ປັດຈຸບັນຂອງທ່ານນັ້ນລ້າສະໄໝແລ້ວ." Nvvfx.Method.Greenscreen.Processing="ຄວາມຖີ່ຂອງການໂຫຼດໜ້າກາກຄືນໃໝ່ເປັນເຟຣມ" Nvvfx.Method.Greenscreen.Processing.Hint="ສິ່ງນີ້ຊ່ວຍຫຼຸດຜ່ອນພາລະຂອງ GPU ໂດຍການສ້າງໜ້າກາກທຸກໆ N ເຟຣມເທົ່ານັ້ນ (ຄ່າເລີ່ມຕົ້ນແມ່ນ 2)." Nvvfx.Method.BlurFilter="ໂຕກອງຄວາມມົວ NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/lv-LV.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/lv-LV.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="NVIDIA Trokšņu Noņemšana" Nvafx.Method.Dereverb="NVIDIA Telpas Atbalss Noņemšana" Nvafx.Method.DenoiserPlusDereverb="NVIDIA Trokšņu Noņemšana + Telpas Atbalss Noņemšana" -Nvafx.OutdatedSDK="BRĪDINĀJUMS: Lūdzu, jauniniet gan NVIDIA Video, gan Audio SDK. Jūsu pašreizējā Audio SDK versija ir novecojusi." Nvafx.VAD="Balss Optimizācija" Nvvfx.Method.Greenscreen="NVIDIA Fona Noņemšana" Nvvfx.Method.Greenscreen.Mode="Režīms" @@ -14,7 +13,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Kvalitāte (lielāka GPU izmantošana, labāka kvalitāte) + Krēsla noņemšana" Nvvfx.Method.Greenscreen.Performance.Chair="Veiktspēja (mazāka GPU izmantošana, laba kvalitāte) + Krēsla noņemšana" Nvvfx.Method.Greenscreen.Threshold="Slieksnis" -Nvvfx.OutdatedSDK="BRĪDINĀJUMS: Lūdzu, jauniniet gan NVIDIA Video, gan Audio SDK. Jūsu pašreizējā Video SDK versija ir novecojusi." +Nvvfx.Method.Greenscreen.Processing="Maskēt atsvaidzināšanas frekvenci kadros" Nvvfx.Method.Greenscreen.Processing.Hint="Tas atvieglo GPU slodzi, ģenerējot masku tikai ik pēc N kadriem (2 pēc noklusējuma)." Nvvfx.Method.BlurFilter="NVIDIA Izpludināšanas Filtrs" Nvvfx.Method.BackgroundBlurFilter="NVIDIA Fona Izpludināšanas Filtrs"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/ms-MY.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/ms-MY.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Pembuangan Hingar NVIDIA" Nvafx.Method.Dereverb="Pembuangan Gema Bilik NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Pembuangan Hingar NVIDIA + Pembuangan Gema Bilik" -Nvafx.OutdatedSDK="AMARAN: Sila tatar kedua-dua SDK Video & Audio NVIDIA. Versi semasa SDK Audio anda telah lapuk." +Nvafx.OutdatedSDK="AMARAN: Sila kemas kini kedua-dua NVIDIA Video SDK dan NVIDIA Audio SDK. Versi Audio SDK yang anda gunakan sekarang sudah lapuk. Ini boleh menyebabkan Audio FX, Video FX, atau kedua-duanya tidak berfungsi." Nvafx.VAD="Suara Dioptimumkan" Nvvfx.Method.Greenscreen="Pembuangan Latar Belakang NVIDIA" Nvvfx.Method.Greenscreen.Mode="Mod" @@ -13,7 +13,7 @@ Nvvfx.Method.Greenscreen.Performance="Prestasi (penggunaan GPU lebih rendah, kualiti baik)" Nvvfx.Method.Greenscreen.Quality.Chair="Kualiti (penggunaan GPU lebih tinggi, kualiti lebih baik) + Pembuangan Chair" Nvvfx.Method.Greenscreen.Performance.Chair="Prestasi (penggunaan GPU lebih rendah, kualiti baik) + Pembuangan Chair" -Nvvfx.OutdatedSDK="AMARAN: Sila tatar kedua-dua SDK Video & Audio NVIDIA. Versi semasa SDK Video anda telah lapuk." +Nvvfx.OutdatedSDK="AMARAN: Sila kemas kini kedua-dua NVIDIA Video SDK dan NVIDIA Audio SDK. Versi Video SDK yang anda gunakan sekarang sudah lapuk. Ini boleh menyebabkan Audio FX, Video FX, atau kedua-duanya tidak berfungsi." Nvvfx.Method.Greenscreen.Processing="Frekuensi segar semula topeng dalam bingkai" Nvvfx.Method.Greenscreen.Processing.Hint="Ini mengurangkan beban GPU dengan menjana topeng (mask) setiap bingkai N sahaja (2 secara lalai)." Nvvfx.Method.BlurFilter="Penapis Kabur NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/nl-NL.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/nl-NL.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA Noise Verwijdering" Nvafx.Method.Dereverb="NVIDIA Kamergalmverwijdering" Nvafx.Method.DenoiserPlusDereverb="NVIDIA Noise Verwijdering + Kamergalmverwijdering" -Nvafx.OutdatedSDK="WAARSCHUWING: Upgrade alstublieft zowel de NVIDIA Video SDK als de NVIDIA Audio SDK. Uw huidige versie van Audio SDK is verouderd." +Nvafx.OutdatedSDK="WAARSCHUWING: Upgrade zowel de NVIDIA Video SDK als de Audio SDK. Uw huidige versie van de Audio SDK is verouderd. Dit kan leiden tot problemen met Audio FX, Video FX of beide." Nvafx.VAD="Stem geoptimaliseerd" Nvvfx.Method.Greenscreen="NVIDIA Achtergrond Verwijdering" Nvvfx.Method.Greenscreen.Mode="Modus" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Kwaliteit (hoger GPU-gebruik, betere kwaliteit) + stoel verwijderen" Nvvfx.Method.Greenscreen.Performance.Chair="Prestatie (lager GPU gebruik, goede kwaliteit) + stoel verwijderen " Nvvfx.Method.Greenscreen.Threshold="Drempel" -Nvvfx.OutdatedSDK="WAARSCHUWING: Upgrade alstublieft zowel de NVIDIA Video SDK als de NVIDIA Audio SDK. Uw huidige versie van Video SDK is verouderd." +Nvvfx.OutdatedSDK="WAARSCHUWING: Upgrade zowel de NVIDIA Video SDK als de Audio SDK. Uw huidige versie van de Video SDK is verouderd. Dit kan leiden tot problemen met Audio FX, Video FX of beide." Nvvfx.Method.Greenscreen.Processing="Masker verversfrequentie in frames" Nvvfx.Method.Greenscreen.Processing.Hint="Dit verlaagt de GPU-belasting door alleen elke N frames een masker te genereren (2 op standaard)." Nvvfx.Method.BlurFilter="NVIDIA vervaging filter"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/pl-PL.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/pl-PL.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Usuwanie szumów Nvidii" Nvafx.Method.Dereverb="Usuwanie pogłosu pomieszczenia Nvidii" Nvafx.Method.DenoiserPlusDereverb="Usuwanie szumów i pogłosu pomieszceznia Nvidii" -Nvafx.OutdatedSDK="UWAGA: proszę zaktualizować NVIDIA Video & Audio SDK. Twoja obecna wersja Audio SDK jest przestarzała." +Nvafx.OutdatedSDK="OSTRZEŻENNIE: Zaktualizuj NVIDIA Video i Audio SDK. Twoje obecne Audio SDK jest przestarzałe. To może mieć negatywny wpływ na efekty audio i/lub video." Nvafx.VAD="Zoptymalizowany pod dialogi" Nvvfx.Method.Greenscreen="Usuwanie tła Nvidii" Nvvfx.Method.Greenscreen.Mode="Tryb" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Jakość (wyższe zużycie GPU, lepsza jakość) + usuwanie fotela" Nvvfx.Method.Greenscreen.Performance.Chair="Wydajność (niższe zużycie GPU, dobra jakość) + usuwanie fotela" Nvvfx.Method.Greenscreen.Threshold="Próg" -Nvvfx.OutdatedSDK="UWAGA: proszę zaktualizować NVIDIA Video & Audio SDK. Twoja obecna wersja Video SDK jest przestarzała." +Nvvfx.OutdatedSDK="OSTRZEŻENNIE: Zaktualizuj NVIDIA Video i Audio SDK. Twoje obecne Video SDK jest przestarzałe. To może mieć negatywny wpływ na efekty audio i/lub video." Nvvfx.Method.Greenscreen.Processing="Częstotliwość odświeżania maski (w klatkach)" Nvvfx.Method.Greenscreen.Processing.Hint="Zmniejsza obciążenie GPU poprzez generowanie maskowania co N-tą klatkę (domyślnie co drugą)." Nvvfx.Method.BlurFilter="Filtr rozmycia NVIDIA "
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/pt-BR.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/pt-BR.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Remoção de Ruído NVIDIA" Nvafx.Method.Dereverb="Remoção do Eco do Ambiente NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Remoção de Ruído + Remoção do Eco do Ambiente NVIDIA" -Nvafx.OutdatedSDK="AVISO: Por favor, atualize ambos SDKs de Vídeo e Áudio NVIDIA. Sua versão atual do SDK de Áudio está desatualizada." +Nvafx.OutdatedSDK="AVISO: atualize o NVIDIA Video & Audio SDK.\ Sua versão atual do Audio SDK está desatualizada. Isso pode corromper o Audio FX, o Video FX ou ambos." Nvafx.VAD="Voz otimizada" Nvvfx.Method.Greenscreen="Remoção de Fundo NVIDIA" Nvvfx.Method.Greenscreen.Mode="Modo" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Qualidade (maior uso de GPU, qualidade ótima) + Remover cadeira" Nvvfx.Method.Greenscreen.Performance.Chair="Desempenho (menor uso de GPU, qualidade boa) + Remover cadeira" Nvvfx.Method.Greenscreen.Threshold="Limiar" -Nvvfx.OutdatedSDK="AVISO: atualize os SDKs de vídeo e áudio da NVIDIA. Sua versão atual do SDK de vídeo está desatualizada." +Nvvfx.OutdatedSDK="AVISO: atualize o NVIDIA Video & Audio SDK.\ Sua versão atual do Video SDK está desatualizada. Isso pode corromper o Audio FX, o Video FX ou ambos." Nvvfx.Method.Greenscreen.Processing="Mascarar frequência de atualização em quadros" Nvvfx.Method.Greenscreen.Processing.Hint="Isso alivia a carga da GPU gerando uma máscara a cada N quadros apenas (2 por padrão)." Nvvfx.Method.BlurFilter="Filtro de Desfoque da NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/pt-PT.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/pt-PT.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Remoção de ruído — NVIDIA" Nvafx.Method.Dereverb="Remoção de eco da divisão — NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Remoção de ruído e de eco — NDIVIA" -Nvafx.OutdatedSDK="AVISO: Por favor, atualize os SDK de vídeo e áudio NVIDIA. A sua versão atual do SDK de áudio está desatualizada." +Nvafx.OutdatedSDK="AVISO: atualize os SDK NVIDIA Vídeo e Áudio. A sua versão atual do SDK de Áudio está desatualizada. Isso pode corromper o Audio FX, o Video FX ou ambos." Nvafx.VAD="Voz otimizada" Nvvfx.Method.Greenscreen="Remoção de fundo — NVIDIA" Nvvfx.Method.Greenscreen.Mode="Modo" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Qualidade (maior uso da GPU, melhor qualidade) + Remoção da cadeira" Nvvfx.Method.Greenscreen.Performance.Chair="Desempenho (menor uso da GPU, boa qualidade) + Remoção da cadeira" Nvvfx.Method.Greenscreen.Threshold="Limiar" -Nvvfx.OutdatedSDK="AVISO: Por favor, atualize os SDK de vídeo e áudio NVIDIA. A sua versão atual do SDK de vídeo está desatualizada." +Nvvfx.OutdatedSDK="AVISO: atualize os SDK NVIDIA Vídeo e Áudio. A sua versão atual do SDK de Vídeo está desatualizada. Isso pode corromper o Audio FX, o Video FX ou ambos." Nvvfx.Method.Greenscreen.Processing="Frequência de atualização da máscara em fotogramas" Nvvfx.Method.Greenscreen.Processing.Hint="Isto reduz a carga da GPU gerando uma máscara apenas a cada N fotogramas (2 por predefinição)." Nvvfx.Method.BlurFilter="Desfocagem - Filtro NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/ru-RU.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/ru-RU.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Шумоподавление NVIDIA" Nvafx.Method.Dereverb="Подавление комнатного эхо NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Шумоподавление + подавление комнатного эхо NVIDIA" -Nvafx.OutdatedSDK="ПРЕДУПРЕЖДЕНИЕ: Пожалуйста, обновите видео и аудио SDK NVIDIA. Текущая версия SDK аудио устарела." +Nvafx.OutdatedSDK="ПРЕДУПРЕЖДЕНИЕ: Пожалуйста, обновите SDK NVIDIA для видео и аудио. Ваша текущая версия SDK аудио устарела. Это может нарушить работу эффектов аудио и видео." Nvafx.VAD="Оптимизация голоса" Nvvfx.Method.Greenscreen="Удаление фона NVIDIA" Nvvfx.Method.Greenscreen.Mode="Режим" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Качество (высокая нагрузка на ГП, лучшее качество) + удаление кресла" Nvvfx.Method.Greenscreen.Performance.Chair="Производительность (низкая нагрузка на ГП, хорошее качество) + удаление кресла" Nvvfx.Method.Greenscreen.Threshold="Порог" -Nvvfx.OutdatedSDK="ПРЕДУПРЕЖДЕНИЕ: Пожалуйста, обновите SDK NVIDIA для видео и аудио. Текущая версия SDK видео устарела." +Nvvfx.OutdatedSDK="ПРЕДУПРЕЖДЕНИЕ: Пожалуйста, обновите SDK NVIDIA для видео и аудио. Ваша текущая версия SDK видео устарела. Это может нарушить работу эффектов аудио и видео." Nvvfx.Method.Greenscreen.Processing="Маскировать частоту обновления в кадрах" Nvvfx.Method.Greenscreen.Processing.Hint="Это облегчает загрузку видеокарты, создавая маску только для каждого N-го кадра (по умолчанию — 2)." Nvvfx.Method.BlurFilter="Фильтр Размытия NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/sk-SK.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/sk-SK.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA Odstránenie šumu" Nvafx.Method.Dereverb="NVIDIA Odstránenie echa miestnosti" Nvafx.Method.DenoiserPlusDereverb="NVIDIA Odstránenie šumu + Odstránenie echa miestnosti" -Nvafx.OutdatedSDK="VAROVANIE: Prosím inovujte obe NVIDIA Video & Audio SDK. Vaša momentálna verzia Audio SDK je zastaralá." +Nvafx.OutdatedSDK="VAROVANIE: Prosím aktualizujte si obe NVIDIA Video a Audio SDK. Aktuálna verzia Audio SDK je zastaralá. Môže to narušiť Audio FX, Video FX alebo oboje." Nvafx.VAD="Optimalizovaný hlas" Nvvfx.Method.Greenscreen="NVIDIA Odstránenie pozadia" Nvvfx.Method.Greenscreen.Mode="Režim" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Kvalita (vyššie využitie GPU, lepšia kvalita) + Odstránenie stoličky" Nvvfx.Method.Greenscreen.Performance.Chair="Výkon (nižšie využitie GPU, dobrá kvalita) + Odstránenie stoličky" Nvvfx.Method.Greenscreen.Threshold="Hranica" -Nvvfx.OutdatedSDK="VAROVANIE: Prosím inovujte obe NVIDIA Video & Audio SDK. Vaša momentálna verzia Video SDK je zastaralá." +Nvvfx.OutdatedSDK="VAROVANIE: Prosím aktualizujte si obe NVIDIA Video a Audio SDK. Aktuálna verzia Video SDK je zastaralá. Môže to narušiť Audio FX, Video FX alebo oboje." Nvvfx.Method.Greenscreen.Processing="Obnovovacia frekvencia masky v snímkoch" Nvvfx.Method.Greenscreen.Processing.Hint="Toto znižuje záťaž GPU generovaním masky iba každých N snímkov (štandardne 2)." Nvvfx.Method.BlurFilter="NVIDIA Filter rozmazania"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/sr-SP.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/sr-SP.ini
Changed
@@ -5,13 +5,11 @@ Nvafx.Method.Denoiser="NVIDIA уклањање шума" Nvafx.Method.Dereverb="NVIDIA уклањање одјека у соби" Nvafx.Method.DenoiserPlusDereverb="NVIDIA уклањање буке + уклањање одјека у соби" -Nvafx.OutdatedSDK="УПОЗОРЕЊЕ: Молимо вас да ажурирате и NVIDIA видео и аудио SDK. Ваша тренутна верзија Audio SDK-а је застарела." Nvvfx.Method.Greenscreen="Уклањање позадине NVIDIA" Nvvfx.Method.Greenscreen.Mode="Режим" Nvvfx.Method.Greenscreen.Quality="Квалитет (већа употреба графичке картице, бољи квалитет)" Nvvfx.Method.Greenscreen.Performance="Перформансе (мања потрошња графичког процесора, добар квалитет)" Nvvfx.Method.Greenscreen.Threshold="Праг" -Nvvfx.OutdatedSDK="УПОЗОРЕЊЕ: Молимо вас да ажурирате и NVIDIA видео и аудио SDK. Ваша тренутна верзија Video SDK-а је застарела." Nvvfx.Method.Greenscreen.Processing="Фреквенција освежавања маске у фрејмовима" Nvvfx.Method.Greenscreen.Processing.Hint="Ово смањује оптерећење графичког процесора генерисањем маске само сваких N фрејмова (2 подразумевано)." Nvvfx.Method.BlurFilter="NVIDIA филтер за замућење"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/sv-SE.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/sv-SE.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA:s brusborttagning" Nvafx.Method.Dereverb="NVIDIA:s rumsekoborttagning" Nvafx.Method.DenoiserPlusDereverb="NVIDIA:s brusborttagning + rumsekoborttagning" -Nvafx.OutdatedSDK="VARNING: Uppgradera både NVIDIA Video och Audio SDK. Din nuvarande version av Audio SDK är föråldrad." +Nvafx.OutdatedSDK="VARNING: Uppgradera både NVIDIA Video SDK och Audio SDK. Din nuvarande version av Audio SDK är föråldrad. Detta kan orsaka problem med Audio FX, Video FX eller båda." Nvafx.VAD="Röstoptimerad" Nvvfx.Method.Greenscreen="NVIDIA:s bakgrundsborttagning" Nvvfx.Method.Greenscreen.Mode="Läge" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Kvalitet (högre grafikprocessoranvändning, bättre kvalitet) + stolborttagning" Nvvfx.Method.Greenscreen.Performance.Chair="Prestanda (lägre grafikprocessoranvändning, god kvalitet) + stolborttagning" Nvvfx.Method.Greenscreen.Threshold="Tröskel" -Nvvfx.OutdatedSDK="VARNING: Uppgradera både NVIDIA Video och Audio SDK. Din nuvarande version av Video SDK är föråldrad." +Nvvfx.OutdatedSDK="VARNING: Uppgradera både NVIDIA Video SDK och Audio SDK. Din nuvarande version av Video SDK är föråldrad. Detta kan orsaka problem med Audio FX, Video FX eller båda." Nvvfx.Method.Greenscreen.Processing="Maskens uppdateringsfrekvens i bildrutor" Nvvfx.Method.Greenscreen.Processing.Hint="Detta minskar belastningen på grafikprocessorn genom att endast generera en mask efter N bildrutor (2 som standard)." Nvvfx.Method.BlurFilter="NVIDIA:s oskärpefilter"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/th-TH.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/th-TH.ini
Changed
@@ -4,7 +4,6 @@ Nvafx.Method.Denoiser="ระบบตัดเสียงรบกวนของ NVIDIA" Nvafx.Method.Dereverb="ระบบตัดเสียงสะท้อนในห้องของ NVIDIA" Nvafx.Method.DenoiserPlusDereverb="ระดับตัดเสียงรบกวนและระบบตัดเสียงสะท้อนในห้องของ NVIDIA" -Nvafx.OutdatedSDK="คำเตือน: โปรดอัปเกรดทั้ง NVIDIA Video และ Audio SDK Video SDK เวอร์ชันปัจจุบันของคุณล้าสมัยแล้ว" Nvafx.VAD="ปรับให้เหมาะกับเสียงพูด" Nvvfx.Method.Greenscreen="การลบพื้นหลัง NVIDIA" Nvvfx.Method.Greenscreen.Mode="โหมด" @@ -13,7 +12,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="คุณภาพ (ใช้ GPU มากขึ้น ให้คุณภาพดีขึ้น) + การลบภาพเก้าอี้" Nvvfx.Method.Greenscreen.Performance.Chair="ประสิทธิภาพ (ใช้ GPU น้อยลง ให้คุณภาพดี) + การลบภาพเก้าอี้" Nvvfx.Method.Greenscreen.Threshold="ขีดเริ่ม" -Nvvfx.OutdatedSDK="คำเตือน: โปรดอัปเกรดทั้ง NVIDIA Video และ Audio SDK Video SDK เวอร์ชันปัจจุบันของคุณล้าสมัยแล้ว" Nvvfx.Method.Greenscreen.Processing="ความถี่รีเฟรชมาสก์ในหน่วยเฟรม" Nvvfx.Method.Greenscreen.Processing.Hint="ตัวเลือกนี้ช่วยลดภาระให้กับ GPU ด้วยการสร้างมาสก์ทุกๆ N เฟรมเท่านั้น (2 ในค่าเริ่มต้น)" Nvvfx.Method.BlurFilter="ฟิลเตอร์เบลอ NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/tr-TR.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA Ses Kaldırıcı" Nvafx.Method.Dereverb="NVIDIA Oda Ekosu Kaldırıcı" Nvafx.Method.DenoiserPlusDereverb="NVIDIA Gürültü Giderme + Oda Yankısı Giderme" -Nvafx.OutdatedSDK="UYARI: Lütfen NVIDIA Video & Ses SDK sürümlerini yükseltin. Mevcut Ses SDK sürümünüz güncelliğini yitirmiş." +Nvafx.OutdatedSDK="UYARI: Lütfen NVIDIA Video & Ses Yazılım Geliştirme Kitlerini güncelleyiniz. Halihazırda kullandığınız Ses Yazılım Geliştirme Kiti'nin versiyonu geride kalmış. Bu Ses veya Video efektlerinizi bozabilir." Nvafx.VAD="Ses Optimizesi" Nvvfx.Method.Greenscreen="NVIDIA Arkaplan Kaldırıcı" Nvvfx.Method.Greenscreen.Mode="Mod" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Kalite (Daha yüksek GPU kullanımı, daha iyi kalite) + Kaldırılmış sandalye" Nvvfx.Method.Greenscreen.Performance.Chair="Performans (Daha yüksek GPU kullanımı, daha iyi kalite) + Kaldırılmış sandalye" Nvvfx.Method.Greenscreen.Threshold="Eşik" -Nvvfx.OutdatedSDK="UYARI: Lütfen NVIDIA Video & Ses SDK sürümlerini yükseltin. Mevcut Ses SDK sürümünüz güncelliğini yitirmiş." +Nvvfx.OutdatedSDK="UYARI: Lütfen NVIDIA Video & Ses Yazılım Geliştirme Kitlerini güncelleyiniz. Halihazırda kullandığınız Video Yazılım Geliştirme Kiti'nin versiyonu geride kalmış. Bu Ses veya Video efektlerinizi bozabilir." Nvvfx.Method.Greenscreen.Processing="Karelerdeki yenileme sıklığını maskele" Nvvfx.Method.Greenscreen.Processing.Hint="Her N karede bir maske oluşturarak GPU yükünü hafifletir (Varsayılan 2)" Nvvfx.Method.BlurFilter="NVIDIA Bulanıklaştırma Filtreleri"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/ug-CN.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/ug-CN.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA شاۋقۇن چىقىرىۋەت" Nvafx.Method.Dereverb="NVIDIA ئۆيدىكى ئەكس سادانى چىقىرىۋەت" Nvafx.Method.DenoiserPlusDereverb="NVIDIA شاۋقۇن چىقىرىۋەت + ئۆيدىكى ئەكس سادانى چىقىرىۋەت" -Nvafx.OutdatedSDK="ئاگاھلاندۇرۇش: NVIDIA سىن ۋە ئۈن SDK نىڭ ھەر ئىككىلىسىنى يۈكسەلتىڭ. سىز نۆۋەتتە ئىشلىتىۋاتقان ئۈن SDK نىڭ ۋاقتى ئۆتكەن." +Nvafx.OutdatedSDK="ئاگاھلاندۇرۇش: NVIDIA سىن ۋە ئۈن SDK نىڭ ھەر ئىككىلىسىنى يۈكسەلتىڭ. سىز نۆۋەتتە ئىشلىتىۋاتقان ئۈن SDK نىڭ ۋاقتى ئۆتكەن. بۇ ئۈن FX، سىن FX ياكى ھەر ئىككىسىنىڭ بۇزۇلۇشىنى كەلتۈرۈپ چىقىرىشى مۇمكىن." Nvafx.VAD="ئاۋاز ئەلالاشتۇرۇلدى" Nvvfx.Method.Greenscreen="NVIDIA تەگلىكىنى چىقىرىۋەت" Nvvfx.Method.Greenscreen.Mode="ھالىتى" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="سۈپىتى (GPU ئىشلىتىشى يۇقىرى، سۈپىتى ياخشىراق) + ئورۇندۇق چىقىرىۋېتىش" Nvvfx.Method.Greenscreen.Performance.Chair="ئۈنۈمى (GPU ئىشلىتىشى تۆۋەن، سۈپىتى ياخشى) + ئورۇندۇق چىقىرىۋېتىش" Nvvfx.Method.Greenscreen.Threshold="بوسۇغا قىممىتى" -Nvvfx.OutdatedSDK="ئاگاھلاندۇرۇش: NVIDIA سىن ۋە ئۈن SDK نىڭ ھەر ئىككىلىسىنى يۈكسەلتىڭ. سىز نۆۋەتتە ئىشلىتىۋاتقان سىن SDK نىڭ ۋاقتى ئۆتكەن." +Nvvfx.OutdatedSDK="ئاگاھلاندۇرۇش: NVIDIA سىن ۋە ئۈن SDK نىڭ ھەر ئىككىلىسىنى يۈكسەلتىڭ. سىز نۆۋەتتە ئىشلىتىۋاتقان سىن SDK نىڭ ۋاقتى ئۆتكەن. بۇ ئۈن FX، سىن FX ياكى ھەر ئىككىسىنىڭ بۇزۇلۇشىنى كەلتۈرۈپ چىقىرىشى مۇمكىن." Nvvfx.Method.Greenscreen.Processing="نىقاب يېڭىلاش چاستوتىسى كاندۇك" Nvvfx.Method.Greenscreen.Processing.Hint="ھەر قېتىم بىر قانچە كاندۇك ئۆتكەندە ئاندىن نىقاب ھاسىللاپ GPU نىڭ يۈكىنى تۆۋەنلىتىدۇ (كۆڭۈلدىكى قىممىتى 2)." Nvvfx.Method.BlurFilter="NVIDIA غۇۋا سۈزگۈچ"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/uk-UA.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/uk-UA.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="Видалення шуму NVIDIA" Nvafx.Method.Dereverb="Видалення відлуння кімнати NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Видалення шуму + видалення відлуння кімнати NVIDIA" -Nvafx.OutdatedSDK="ПОПЕРЕДЖЕННЯ: Оновіть NVIDIA Video & Audio SDK. Ваша поточна версія Audio SDK застаріла." +Nvafx.OutdatedSDK="УВАГА: Будь ласка, оновіть як відео-, так і аудіо-SDK від NVIDIA. Ваша поточна версія аудіо-SDK застаріла. Це може призвести до порушення роботи аудіо- та відеоефектів або обох одночасно." Nvafx.VAD="Голос оптимізовано" Nvvfx.Method.Greenscreen="Видалення тла NVIDIA" Nvvfx.Method.Greenscreen.Mode="Режим" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Якість (високе використання GPU, краща якість) + Видалення стільця" Nvvfx.Method.Greenscreen.Performance.Chair="Швидкодія (менше використання GPU, хороша якість) + Видалення стільця" Nvvfx.Method.Greenscreen.Threshold="Поріг" -Nvvfx.OutdatedSDK="УВАГА: будь ласка, оновіть NVIDIA Video & Audio SDK. Ваша поточна версія Video SDK застаріла." +Nvvfx.OutdatedSDK="УВАГА: Будь ласка, оновіть як NVIDIA Video SDK, так і NVIDIA Audio SDK. Ваша поточна версія Video SDK застаріла. Це може призвести до порушення роботи аудіоефектів, відеоефектів або й тих, і інших." Nvvfx.Method.Greenscreen.Processing="Частота оновлення маски у кадрах" Nvvfx.Method.Greenscreen.Processing.Hint="Це зменшує навантаження на графічний процесор, генеруючи маску лише кожні Ц кадрів (2 за стандартом)." Nvvfx.Method.BlurFilter="Фільтр розмиття NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/vi-VN.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/vi-VN.ini
Changed
@@ -5,7 +5,6 @@ Nvafx.Method.Denoiser="Loại bỏ tiếng ồn NVIDIA" Nvafx.Method.Dereverb="Loại bỏ tiếng vang phòng NVIDIA" Nvafx.Method.DenoiserPlusDereverb="Loại bỏ tiếng ồn + Loại bỏ tiếng vang trong phòng NVIDIA" -Nvafx.OutdatedSDK="CẢNH BÁO: Hãy cập nhật SDK NVIDIA hình ảnh và âm thanh. Phiên bản hiện tại của SDK âm thanh đã cũ." Nvafx.VAD="Tối ưu cho giọng nói" Nvvfx.Method.Greenscreen="Xóa nền NVIDIA" Nvvfx.Method.Greenscreen.Mode="Chế độ" @@ -14,7 +13,6 @@ Nvvfx.Method.Greenscreen.Quality.Chair="Chất lượng (sử dụng nhiều GPU hơn, chất lượng tốt hơn) + Xoá ghế" Nvvfx.Method.Greenscreen.Performance.Chair="Hiệu năng (sử dụng ít GPU hơn, chất lượng tốt) + Xoá ghế" Nvvfx.Method.Greenscreen.Threshold="Ngưỡng" -Nvvfx.OutdatedSDK="CẢNH BÁO: Hãy cập nhật SDK NVIDIA hình ảnh và âm thanh. Phiên bản hiện tại của SDK hình ảnh đã cũ." Nvvfx.Method.Greenscreen.Processing="Tần suất làm mới Mặt-nạ trong Khung" Nvvfx.Method.Greenscreen.Processing.Hint="Điều này làm giảm tải GPU bằng cách chỉ tạo Mặt-nạ cho mỗi N khung hình (mặc định là 2)." Nvvfx.Method.BlurFilter="Bộ lọc mờ NVIDIA"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/zh-CN.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/zh-CN.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA 噪声消除" Nvafx.Method.Dereverb="NVIDIA 室内回声消除" Nvafx.Method.DenoiserPlusDereverb="NVIDIA 噪声消除 + 室内回声消除" -Nvafx.OutdatedSDK="警告:请升级 NVIDIA 视频和音频 SDK。您当前的音频 SDK 版本已过时。" +Nvafx.OutdatedSDK="警告:请同时升级 NVIDIA 视频和音频 SDK。您当前的音频 SDK 版本已过时,这可能会导致音频 FX、视频 FX 或两者均无法正常工作。" Nvafx.VAD="语音优化" Nvvfx.Method.Greenscreen="NVIDIA 背景移除" Nvvfx.Method.Greenscreen.Mode="模式" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="质量(GPU 使用率较高,质量更好)+ 移除椅子" Nvvfx.Method.Greenscreen.Performance.Chair="性能(GPU 使用率较低,质量较好)+ 移除椅子" Nvvfx.Method.Greenscreen.Threshold="阈值" -Nvvfx.OutdatedSDK="警告:请升级 NVIDIA 视频和音频 SDK。您当前的视频 SDK 版本已过时。" +Nvvfx.OutdatedSDK="警告:请同时升级 NVIDIA 视频和音频 SDK。您当前的视频 SDK 版本已过时,这可能会导致音频 FX、视频 FX 或两者均无法正常工作。" Nvvfx.Method.Greenscreen.Processing="蒙版刷新频率 (帧)" Nvvfx.Method.Greenscreen.Processing.Hint="每过 N 帧生成一个蒙版 (默认为 2 帧),可减轻 GPU 负载。" Nvvfx.Method.BlurFilter="NVIDIA 模糊滤镜"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/data/locale/zh-TW.ini -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/data/locale/zh-TW.ini
Changed
@@ -5,7 +5,7 @@ Nvafx.Method.Denoiser="NVIDIA 噪音去除" Nvafx.Method.Dereverb="NVIDIA 空間回音去除" Nvafx.Method.DenoiserPlusDereverb="NVIDIA 噪音去除 + 空間回音去除" -Nvafx.OutdatedSDK="警告:請同時升級 NVIDIA 視訊與音訊 SDK。目前您使用的音訊 SDK 版本已經過時。" +Nvafx.OutdatedSDK="警告:請同時升級 NVIDIA 視訊和音訊 SDK。您目前的音訊 SDK 版本已過時。這可能會導致音訊特效、視訊特效或兩者都無法正常運作。" Nvafx.VAD="語音最佳化" Nvvfx.Method.Greenscreen="NVIDIA 背景去除" Nvvfx.Method.Greenscreen.Mode="模式" @@ -14,7 +14,7 @@ Nvvfx.Method.Greenscreen.Quality.Chair="品質優先(GPU 用量較高,品質較好)+ 移除椅子" Nvvfx.Method.Greenscreen.Performance.Chair="效能優先(GPU 用量較低,品質尚可)+ 移除椅子" Nvvfx.Method.Greenscreen.Threshold="閾值" -Nvvfx.OutdatedSDK="警告:請同時升級 NVIDIA 視訊與音訊 SDK。目前您使用的視訊 SDK 版本已經過時。" +Nvvfx.OutdatedSDK="警告:請更新您的NVDIA視頻和音頻的SDK。您所使用的SDK版本已經過時,這將損害音頻特效、視頻特效或兩者" Nvvfx.Method.Greenscreen.Processing="影格中的遮罩重新整理速率" Nvvfx.Method.Greenscreen.Processing.Hint="藉由限制每 N 個影格只產生一次遮罩,來降低 GPU 的負載(預設值為 2 個影格)。" Nvvfx.Method.BlurFilter="NVIDIA 模糊濾鏡"
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/nv-filters.c -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/nv-filters.c
Changed
@@ -23,7 +23,6 @@ bool obs_module_load(void) { #ifdef LIBNVAFX_ENABLED - /* load nvidia audio fx dll */ if (load_nvidia_afx()) obs_register_source(&nvidia_audiofx_filter); #endif
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/nv_sdk_versions.h -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/nv_sdk_versions.h
Changed
@@ -1,2 +1,7 @@ #define MIN_VFX_SDK_VERSION (0 << 24 | 7 << 16 | 6 << 8 | 0 << 0) +#define MIN_VFX_LOGGER_VERSION (0 << 24 | 7 << 16 | 6 << 8 | 0 << 0) +#define MIN_ARM_VFX_SDK_VERSION (1 << 24 | 3 << 16 | 0 << 8 | 0 << 0) + #define MIN_AFX_SDK_VERSION (1 << 24 | 6 << 16 | 1 << 8 | 2 << 0) +#define MIN_AFX_LOGGER_VERSION (1 << 24 | 6 << 16 | 1 << 8 | 2 << 0) // also gates VAD feature +#define MIN_ARM_AFX_SDK_VERSION (3 << 24 | 0 << 16 | 0 << 8 | 49 << 0)
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/nvafx-load.h -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/nvafx-load.h
Changed
@@ -12,43 +12,43 @@ #ifdef LIBNVAFX_ENABLED static HMODULE nv_audiofx = NULL; +static HMODULE nv_denoiserfx = NULL; +static HMODULE nv_dereverbfx = NULL; +static HMODULE nv_dereverbdenoiserfx = NULL; /** Effects @ref NvAFX_EffectSelector */ #define NVAFX_EFFECT_DENOISER "denoiser" #define NVAFX_EFFECT_DEREVERB "dereverb" #define NVAFX_EFFECT_DEREVERB_DENOISER "dereverb_denoiser" -#define NVAFX_EFFECT_AEC "aec" -#define NVAFX_EFFECT_SUPERRES "superres" /** Model paths */ #define NVAFX_EFFECT_DENOISER_MODEL "\\models\\denoiser_48k.trtpkg" #define NVAFX_EFFECT_DEREVERB_MODEL "\\models\\dereverb_48k.trtpkg" #define NVAFX_EFFECT_DEREVERB_DENOISER_MODEL "\\models\\dereverb_denoiser_48k.trtpkg" -#define NVAFX_CHAINED_EFFECT_DENOISER_16k_SUPERRES_16k_TO_48k "denoiser16k_superres16kto48k" -#define NVAFX_CHAINED_EFFECT_DEREVERB_16k_SUPERRES_16k_TO_48k "dereverb16k_superres16kto48k" -#define NVAFX_CHAINED_EFFECT_DEREVERB_DENOISER_16k_SUPERRES_16k_TO_48k "dereverb_denoiser16k_superres16kto48k" -#define NVAFX_CHAINED_EFFECT_SUPERRES_8k_TO_16k_DENOISER_16k "superres8kto16k_denoiser16k" -#define NVAFX_CHAINED_EFFECT_SUPERRES_8k_TO_16k_DEREVERB_16k "superres8kto16k_dereverb16k" -#define NVAFX_CHAINED_EFFECT_SUPERRES_8k_TO_16k_DEREVERB_DENOISER_16k "superres8kto16k_dereverb_denoiser16k" - /** Parameter selectors */ - #define NVAFX_PARAM_NUM_STREAMS "num_streams" #define NVAFX_PARAM_USE_DEFAULT_GPU "use_default_gpu" #define NVAFX_PARAM_USER_CUDA_CONTEXT "user_cuda_context" #define NVAFX_PARAM_DISABLE_CUDA_GRAPH "disable_cuda_graph" -#define NVAFX_PARAM_ENABLE_VAD "enable_vad" + /** Effect parameters. @ref NvAFX_ParameterSelector */ #define NVAFX_PARAM_MODEL_PATH "model_path" #define NVAFX_PARAM_INPUT_SAMPLE_RATE "input_sample_rate" #define NVAFX_PARAM_OUTPUT_SAMPLE_RATE "output_sample_rate" + #define NVAFX_PARAM_NUM_INPUT_SAMPLES_PER_FRAME "num_input_samples_per_frame" #define NVAFX_PARAM_NUM_OUTPUT_SAMPLES_PER_FRAME "num_output_samples_per_frame" +/* SDK >= 3.0.0.49: replaces the 2 previous define... */ +#define NVAFX_PARAM_NUM_SAMPLES_PER_INPUT_FRAME "num_samples_per_input_frame" +#define NVAFX_PARAM_NUM_SAMPLES_PER_OUTPUT_FRAME "num_samples_per_output_frame" + #define NVAFX_PARAM_NUM_INPUT_CHANNELS "num_input_channels" #define NVAFX_PARAM_NUM_OUTPUT_CHANNELS "num_output_channels" #define NVAFX_PARAM_INTENSITY_RATIO "intensity_ratio" #define NVAFX_PARAM_ENABLE_VAD "enable_vad" +/** SDK >= 3.0.0.49: Voice activity status (boolean) is an immutable parameter. */ +#define NVAFX_PARAM_VAD_RESULT "vad_result" #pragma deprecated(NVAFX_PARAM_DENOISER_MODEL_PATH) #define NVAFX_PARAM_DENOISER_MODEL_PATH NVAFX_PARAM_MODEL_PATH @@ -90,12 +90,32 @@ /** Model file could not be loaded */ NVAFX_STATUS_MODEL_LOAD_FAILED = 8, - /** (32 bit SDK only) COM server was not registered, please see user manual for details */ - NVAFX_STATUS_32_SERVER_NOT_REGISTERED = 9, - /** (32 bit SDK only) COM operation failed */ - NVAFX_STATUS_32_COM_ERROR = 10, + /** Model is not loaded, it needs to be loaded for this operation */ + NVAFX_STATUS_MODEL_NOT_LOADED = 9, + /** Selected model is incompatible */ + NVAFX_STATUS_INCOMPATIBLE_MODEL = 10, /** GPU supported. The SDK requires Turing and above GPU with Tensor cores */ NVAFX_STATUS_GPU_UNSUPPORTED = 11, + /** No supported GPU found on the system */ + NVAFX_STATUS_NO_SUPPORTED_GPU_FOUND = 12, + /** Current GPU is not the one selected */ + NVAFX_STATUS_WRONG_GPU = 13, + /** Cuda operation failure */ + NVAFX_STATUS_CUDA_ERROR = 14, + /** Invalid operation performed **/ + NVAFX_STATUS_INVALID_OPERATION = 15, + /** CUDA runtime is less than supported version*/ + NVAFX_UNSUPPORTED_RUNTIME = 16, + /** (32 bit SDK only) COM server was not registered, please see user manual for details */ + NVAFX_STATUS_32_SERVER_NOT_REGISTERED = 17, + /** (32 bit SDK only) COM operation failed */ + NVAFX_STATUS_32_COM_ERROR = 18, + /** Cuda Context Failure Error */ + NVAFX_STATUS_CUDA_CONTEXT_CREATION_FAILED = 19, + /** Dynamic Load Library Error */ + NVAFX_STATUS_LIBRARY_ERROR = 20, + /** Dynamic Load Library out of memory error */ + NVAFX_STATUS_OUT_OF_MEMORY = 21, } NvAFX_Status; #define NVAFX_TRUE 1 @@ -131,30 +151,18 @@ typedef const char *NvAFX_ParameterSelector; typedef void *NvAFX_Handle; -typedef NvAFX_Status NVAFX_API (*NvAFX_GetEffectList_t)(int *num_effects, NvAFX_EffectSelector *effects); typedef NvAFX_Status NVAFX_API (*NvAFX_CreateEffect_t)(NvAFX_EffectSelector code, NvAFX_Handle *effect); -typedef NvAFX_Status NVAFX_API (*NvAFX_CreateChainedEffect_t)(NvAFX_EffectSelector code, NvAFX_Handle *effect); typedef NvAFX_Status NVAFX_API (*NvAFX_DestroyEffect_t)(NvAFX_Handle effect); typedef NvAFX_Status NVAFX_API (*NvAFX_SetU32_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, unsigned int val); -typedef NvAFX_Status NVAFX_API (*NvAFX_SetU32List_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, - unsigned int *val, unsigned int size); typedef NvAFX_Status NVAFX_API (*NvAFX_SetString_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, const char *val); -typedef NvAFX_Status NVAFX_API (*NvAFX_SetStringList_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, - const char **val, unsigned int size); typedef NvAFX_Status NVAFX_API (*NvAFX_SetFloat_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, float val); -typedef NvAFX_Status NVAFX_API (*NvAFX_SetFloatList_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, - float *val, unsigned int size); typedef NvAFX_Status NVAFX_API (*NvAFX_GetU32_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, unsigned int *val); typedef NvAFX_Status NVAFX_API (*NvAFX_GetString_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, char *val, int max_length); -typedef NvAFX_Status NVAFX_API (*NvAFX_GetStringList_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, - char **val, int *max_length, unsigned int size); typedef NvAFX_Status NVAFX_API (*NvAFX_GetFloat_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, float *val); -typedef NvAFX_Status NVAFX_API (*NvAFX_GetFloatList_t)(NvAFX_Handle effect, NvAFX_ParameterSelector param_name, - float *val, unsigned int size); typedef NvAFX_Status NVAFX_API (*NvAFX_Load_t)(NvAFX_Handle effect); typedef NvAFX_Status NVAFX_API (*NvAFX_GetSupportedDevices_t)(NvAFX_Handle effect, int *num, int *devices); typedef NvAFX_Status NVAFX_API (*NvAFX_Run_t)(NvAFX_Handle effect, const float **input, float **output, @@ -166,21 +174,14 @@ const char *filename, logging_cb_t cb, void *userdata); typedef NvAFX_Status NVAFX_API (*NvAFX_UninitializeLogger_t)(); -static NvAFX_GetEffectList_t NvAFX_GetEffectList = NULL; static NvAFX_CreateEffect_t NvAFX_CreateEffect = NULL; -static NvAFX_CreateChainedEffect_t NvAFX_CreateChainedEffect = NULL; static NvAFX_DestroyEffect_t NvAFX_DestroyEffect = NULL; static NvAFX_SetU32_t NvAFX_SetU32 = NULL; -static NvAFX_SetU32List_t NvAFX_SetU32List = NULL; static NvAFX_SetString_t NvAFX_SetString = NULL; -static NvAFX_SetStringList_t NvAFX_SetStringList = NULL; static NvAFX_SetFloat_t NvAFX_SetFloat = NULL; -static NvAFX_SetFloatList_t NvAFX_SetFloatList = NULL; static NvAFX_GetU32_t NvAFX_GetU32 = NULL; static NvAFX_GetString_t NvAFX_GetString = NULL; -static NvAFX_GetStringList_t NvAFX_GetStringList = NULL; static NvAFX_GetFloat_t NvAFX_GetFloat = NULL; -static NvAFX_GetFloatList_t NvAFX_GetFloatList = NULL; static NvAFX_Load_t NvAFX_Load = NULL; static NvAFX_GetSupportedDevices_t NvAFX_GetSupportedDevices = NULL; static NvAFX_Run_t NvAFX_Run = NULL; @@ -189,23 +190,16 @@ static NvAFX_InitializeLogger_t NvAFX_InitializeLogger = NULL; static NvAFX_UninitializeLogger_t NvAFX_UninitializeLogger = NULL; -void release_lib(void) +static inline void release_afx_lib(void) { - NvAFX_GetEffectList = NULL; NvAFX_CreateEffect = NULL; - NvAFX_CreateChainedEffect = NULL; NvAFX_DestroyEffect = NULL; NvAFX_SetU32 = NULL; - NvAFX_SetU32List = NULL; NvAFX_SetString = NULL; - NvAFX_SetStringList = NULL; NvAFX_SetFloat = NULL; - NvAFX_SetFloatList = NULL; NvAFX_GetU32 = NULL; NvAFX_GetString = NULL; - NvAFX_GetStringList = NULL; NvAFX_GetFloat = NULL; - NvAFX_GetFloatList = NULL; NvAFX_Load = NULL; NvAFX_GetSupportedDevices = NULL; NvAFX_Run = NULL; @@ -213,10 +207,23 @@ /* SDK >= 1.6.0 */ NvAFX_InitializeLogger = NULL; NvAFX_UninitializeLogger = NULL; + if (nv_audiofx) { FreeLibrary(nv_audiofx); nv_audiofx = NULL; } + if (nv_denoiserfx) { + FreeLibrary(nv_denoiserfx); + nv_denoiserfx = NULL; + } + if (nv_dereverbfx) { + FreeLibrary(nv_dereverbfx); + nv_dereverbfx = NULL; + } + if (nv_dereverbdenoiserfx) { + FreeLibrary(nv_dereverbdenoiserfx); + nv_dereverbdenoiserfx = NULL; + } } static inline bool nvafx_get_sdk_path(char *buffer, const size_t len) @@ -224,6 +231,9 @@ DWORD ret = GetEnvironmentVariableA("NVAFX_SDK_DIR", buffer, (DWORD)len); if (!ret || ret >= len - 1) { + ret = GetEnvironmentVariableA("AFX_SDK_DIR", buffer, (DWORD)len); + } + if (!ret || ret >= len - 1) { char pathMAX_PATH; if (!GetEnvironmentVariableA("ProgramFiles", path, MAX_PATH)) { buffer0 = 0; @@ -240,25 +250,6 @@ return true; } -static inline bool load_lib() -{ - char sdkPathMAX_PATH; - char effectsPathMAX_PATH; - - if (!nvafx_get_sdk_path(sdkPath, MAX_PATH)) { - return false; - } - - if (_snprintf_s(effectsPath, _countof(effectsPath), _TRUNCATE, "%s\\NVAudioEffects.dll", sdkPath) == -1) { - return false; - } - - nv_audiofx = - LoadLibraryExA(effectsPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - - return !!nv_audiofx; -} - static unsigned int get_lib_version(void) { static unsigned int version = 0; @@ -287,4 +278,42 @@ return version; } +static inline bool load_afx_module(HMODULE *module, const char *sdk_path, const char *filename) +{ + char pathMAX_PATH; + + if (*module) { + return true; + } + + if (_snprintf_s(path, _countof(path), _TRUNCATE, "%s\\%s", sdk_path, filename) < 0) { + return false; + } + + *module = LoadLibraryExA(path, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + return *module != NULL; +} + +static inline bool load_lib(unsigned int version) +{ + char sdk_pathMAX_PATH; + + if (!nvafx_get_sdk_path(sdk_path, _countof(sdk_path))) + return false; + + if (!load_afx_module(&nv_audiofx, sdk_path, "NVAudioEffects.dll")) + return false; + + if (version < MIN_ARM_AFX_SDK_VERSION) + return true; + + if (!load_afx_module(&nv_denoiserfx, sdk_path, "nvafxdenoiser.dll") || + !load_afx_module(&nv_dereverbfx, sdk_path, "nvafxdereverb.dll") || + !load_afx_module(&nv_dereverbdenoiserfx, sdk_path, "nvafxdereverbdenoiser.dll")) { + return false; + } + + return true; +} + #endif
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/nvidia-audiofx-filter.c -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/nvidia-audiofx-filter.c
Changed
@@ -49,8 +49,6 @@ #define ssize_t intptr_t #endif -bool nvafx_new_sdk = false; - struct nvidia_audio_data { obs_source_t *context; @@ -116,8 +114,9 @@ struct obs_audio_data output_audio; DARRAY(float) output_data; - /* Optimization for Voice Audio Data (VAD) ; requires SDK >= 0.7.6 */ + /* Optimization for Voice Audio Data (VAD) ; requires SDK >= 1.6.2 */ bool vad; + unsigned int sdk_version; }; static const char *nvidia_audio_name(void *unused) @@ -136,7 +135,7 @@ if (ng->nvidia_sdk_dir_found) pthread_mutex_lock(&ng->nvafx_mutex); - if (nvafx_new_sdk) + if (ng->sdk_version >= MIN_AFX_LOGGER_VERSION) NvAFX_UninitializeLogger(); for (size_t i = 0; i < ng->channels; i++) { @@ -180,32 +179,6 @@ #pragma warning(push) #pragma warning(disable : 4706) #endif -void release_afxlib(void) -{ - NvAFX_GetEffectList = NULL; - NvAFX_CreateEffect = NULL; - NvAFX_CreateChainedEffect = NULL; - NvAFX_DestroyEffect = NULL; - NvAFX_SetU32 = NULL; - NvAFX_SetU32List = NULL; - NvAFX_SetString = NULL; - NvAFX_SetStringList = NULL; - NvAFX_SetFloat = NULL; - NvAFX_SetFloatList = NULL; - NvAFX_GetU32 = NULL; - NvAFX_GetString = NULL; - NvAFX_GetStringList = NULL; - NvAFX_GetFloat = NULL; - NvAFX_GetFloatList = NULL; - NvAFX_Load = NULL; - NvAFX_GetSupportedDevices = NULL; - NvAFX_Run = NULL; - NvAFX_Reset = NULL; - if (nv_audiofx) { - FreeLibrary(nv_audiofx); - nv_audiofx = NULL; - } -} bool load_nvidia_afx(void) { @@ -224,9 +197,10 @@ (MIN_VFX_SDK_VERSION >> 16) & 0x00ff, (MIN_VFX_SDK_VERSION >> 8) & 0x0000ff); } } - if (!load_lib()) { + if (!load_lib(version)) { blog(LOG_INFO, "NVIDIA Audio Effects: NVIDIA denoiser disabled, redistributable not found or could not be loaded."); + release_afx_lib(); return false; } @@ -239,47 +213,24 @@ goto unload_everything; \ } -#define LOAD_SYM_FROM_LIB2(sym, lib, dll) \ - if (!(sym = (sym##_t)GetProcAddress(lib, #sym))) { \ - DWORD err = GetLastError(); \ - printf("NVIDIA Audio Effects:: Couldn't load " #sym " from " dll ": %lu (0x%lx)", err, err); \ - nvafx_new_sdk = false; \ - } else { \ - nvafx_new_sdk = true; \ - } - #define LOAD_SYM(sym) LOAD_SYM_FROM_LIB(sym, nv_audiofx, "NVAudioEffects.dll") - LOAD_SYM(NvAFX_GetEffectList); LOAD_SYM(NvAFX_CreateEffect); - LOAD_SYM(NvAFX_CreateChainedEffect); LOAD_SYM(NvAFX_DestroyEffect); LOAD_SYM(NvAFX_SetU32); - LOAD_SYM(NvAFX_SetU32List); LOAD_SYM(NvAFX_SetString); - LOAD_SYM(NvAFX_SetStringList); LOAD_SYM(NvAFX_SetFloat); - LOAD_SYM(NvAFX_SetFloatList); LOAD_SYM(NvAFX_GetU32); LOAD_SYM(NvAFX_GetString); - LOAD_SYM(NvAFX_GetStringList); LOAD_SYM(NvAFX_GetFloat); - LOAD_SYM(NvAFX_GetFloatList); LOAD_SYM(NvAFX_Load); LOAD_SYM(NvAFX_GetSupportedDevices); LOAD_SYM(NvAFX_Run); LOAD_SYM(NvAFX_Reset); -#undef LOAD_SYM -#define LOAD_SYM(sym) LOAD_SYM_FROM_LIB2(sym, nv_audiofx, "NVAudioEffects.dll") LOAD_SYM(NvAFX_InitializeLogger); - bool new_sdk = nvafx_new_sdk; LOAD_SYM(NvAFX_UninitializeLogger); - if (!nvafx_new_sdk || !new_sdk) { - blog(LOG_INFO, "NVIDIA AUDIO FX: SDK loaded but old redistributable detected. Please upgrade."); - nvafx_new_sdk = false; - } #undef LOAD_SYM - NvAFX_Status err; + NvAFX_Status err; NvAFX_Handle h = NULL; err = NvAFX_CreateEffect(NVAFX_EFFECT_DENOISER, &h); @@ -303,7 +254,7 @@ return true; unload_everything: - release_afxlib(); + release_afx_lib(); return false; } @@ -313,7 +264,7 @@ void unload_nvidia_afx(void) { - release_afxlib(); + release_afx_lib(); if (nvidia_afx_initializer_mutex_initialized) { pthread_mutex_destroy(&nvidia_afx_initializer_mutex); @@ -352,8 +303,9 @@ } // Set VAD (Voice Audio Data) - if (nvafx_new_sdk) { + if (get_lib_version() >= MIN_AFX_LOGGER_VERSION && strcmp(ng->fx, NVAFX_EFFECT_DEREVERB) != 0) { err = NvAFX_SetU32(ng->handlei, NVAFX_PARAM_ENABLE_VAD, ng->vad); + if (err != NVAFX_STATUS_SUCCESS) { do_log(LOG_ERROR, "NvAFX_SetU32(VAD: %i) failed, error %i", ng->vad, err); goto failure; @@ -415,7 +367,10 @@ do_log(LOG_ERROR, "The number of channels is not 1 in the sdk any more ==> update code"); goto failure; } - NvAFX_Status err = NvAFX_GetU32(ng->handle0, NVAFX_PARAM_NUM_INPUT_SAMPLES_PER_FRAME, + bool updated_string = ng->sdk_version >= MIN_ARM_AFX_SDK_VERSION; + NvAFX_Status err = NvAFX_GetU32(ng->handle0, + updated_string ? NVAFX_PARAM_NUM_SAMPLES_PER_INPUT_FRAME + : NVAFX_PARAM_NUM_INPUT_SAMPLES_PER_FRAME, &ng->num_samples_per_frame); if (err != NVAFX_STATUS_SUCCESS) { do_log(LOG_ERROR, "NvAFX_GetU32() failed to get the number of samples per frame, error %i", @@ -529,7 +484,7 @@ pthread_mutex_unlock(&ng->nvafx_mutex); } /* updating for VAD toggled on or off */ - if (nvafx_new_sdk) { + if (ng->sdk_version >= MIN_AFX_LOGGER_VERSION && strcmp(ng->fx, NVAFX_EFFECT_DEREVERB) != 0) { if (vad != ng->vad && (strcmp(ng->fx, method) == 0)) { NvAFX_Status err; ng->vad = vad; @@ -599,7 +554,7 @@ ng->nvafx_initialized = false; ng->nvafx_loading = false; ng->fx = NULL; - + ng->sdk_version = get_lib_version(); pthread_mutex_init(&ng->nvafx_mutex, NULL); info("NVAFX SDK redist path was found here %s", sdk_path); @@ -656,7 +611,7 @@ nvidia_audio_update(ng, settings); /* Setup NVIDIA logger */ - if (nvafx_new_sdk) { + if (ng->sdk_version >= MIN_AFX_LOGGER_VERSION) { NvAFX_Status err = NvAFX_InitializeLogger(NVAFX_LOG_LEVEL_ERROR, LOG_TARGET_CALLBACK, NULL, &nvafx_logger_callback, ng); if (err != NVAFX_STATUS_SUCCESS) { @@ -853,10 +808,23 @@ { obs_data_set_default_double(s, S_NVAFX_INTENSITY, 1.0); obs_data_set_default_string(s, S_METHOD, S_METHOD_NVAFX_DENOISER); - if (nvafx_new_sdk) + if (get_lib_version() >= MIN_AFX_LOGGER_VERSION) obs_data_set_default_bool(s, S_NVAFX_VAD, 1); } +static bool nvidia_audio_method_modified(void *data, obs_properties_t *props, obs_property_t *property, + obs_data_t *settings) +{ + const struct nvidia_audio_data *ng = data; + const char *method = obs_data_get_string(settings, S_METHOD); + + bool visible = ng->sdk_version >= MIN_AFX_LOGGER_VERSION && (strcmp(method, S_METHOD_NVAFX_DEREVERB) != 0); + obs_property_set_visible(obs_properties_get(props, S_NVAFX_VAD), visible); + + UNUSED_PARAMETER(property); + return true; +} + static obs_properties_t *nvidia_audio_properties(void *data) { obs_properties_t *ppts = obs_properties_create(); @@ -870,9 +838,8 @@ S_METHOD_NVAFX_DEREVERB_DENOISER); obs_property_t *slider = obs_properties_add_float_slider(ppts, S_NVAFX_INTENSITY, TEXT_NVAFX_INTENSITY, 0.0f, 1.0f, 0.01f); - obs_property_t *vad = obs_properties_add_bool(ppts, S_NVAFX_VAD, TEXT_NVAFX_VAD); - if (!nvafx_new_sdk) - obs_property_set_visible(vad, 0); + obs_properties_add_bool(ppts, S_NVAFX_VAD, TEXT_NVAFX_VAD); + obs_property_set_modified_callback2(method, nvidia_audio_method_modified, ng); unsigned int version = get_lib_version(); obs_property_t *warning = obs_properties_add_text(ppts, "deprecation", NULL, OBS_TEXT_INFO);
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/nvidia-videofx-filter.c -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/nvidia-videofx-filter.c
Changed
@@ -48,7 +48,6 @@ enum nvvfx_fx_id { S_FX_AIGS, S_FX_BLUR, S_FX_BG_BLUR }; bool nvvfx_loaded = false; -bool nvvfx_new_sdk = false; /* clang-format off */ struct nvvfx_data { @@ -317,7 +316,6 @@ uint8_t minor = (filter->version >> 16) & 0x00ff; uint8_t build = (filter->version >> 8) & 0x0000ff; uint8_t revision = (filter->version >> 0) & 0x000000ff; - nvvfx_new_sdk = filter->version >= MIN_VFX_SDK_VERSION && nvvfx_new_sdk; } #endif /* 1. Create FX */ @@ -343,7 +341,7 @@ obs_leave_graphics(); /* 4. Allocate state for the AIGS & background blur */ - if (nvvfx_new_sdk && id != S_FX_BLUR) { + if (get_lib_version() >= MIN_VFX_LOGGER_VERSION && id != S_FX_BLUR) { vfxErr = NvVFX_AllocateState(filter->handle, &filter->stateObjectHandle); if (NVCV_SUCCESS != vfxErr) return log_nverror_destroy(filter, vfxErr); @@ -360,7 +358,7 @@ nvvfx_filter_update(filter, settings); /* Setup NVIDIA logger */ - if (nvvfx_new_sdk) + if (get_lib_version() >= MIN_VFX_LOGGER_VERSION) vfxErr = NvVFX_ConfigureLogger(NVCV_LOG_ERROR, NULL, &nvvfx_logger_callback, filter); return filter; @@ -1087,7 +1085,6 @@ bool load_nvidia_vfx(void) { - bool old_sdk_loaded = false; unsigned int version = get_lib_version(); uint8_t major = (version >> 24) & 0xff; uint8_t minor = (version >> 16) & 0x00ff; @@ -1101,7 +1098,7 @@ "NVIDIA VIDEO FX: NVIDIA VIDEO Effects SDK is outdated. Please update both audio & video SDK."); } } - if (!load_nv_vfx_libs()) { + if (!load_nv_vfx_libs(version)) { blog(LOG_INFO, "NVIDIA VIDEO FX: FX disabled, redistributable not found or could not be loaded."); return false; } @@ -1110,19 +1107,9 @@ if (!(sym = (sym##_t)GetProcAddress(lib, #sym))) { \ DWORD err = GetLastError(); \ printf("NVIDIA VIDEO FX: Couldn't load " #sym " from " dll ": %lu (0x%lx)", err, err); \ - release_nv_vfx(); \ goto unload_everything; \ } -#define LOAD_SYM_FROM_LIB2(sym, lib, dll) \ - if (!(sym = (sym##_t)GetProcAddress(lib, #sym))) { \ - DWORD err = GetLastError(); \ - printf("NVIDIA VIDEO FX: Couldn't load " #sym " from " dll ": %lu (0x%lx)", err, err); \ - nvvfx_new_sdk = false; \ - } else { \ - nvvfx_new_sdk = true; \ - } - #define LOAD_SYM(sym) LOAD_SYM_FROM_LIB(sym, nv_videofx, "NVVideoEffects.dll") LOAD_SYM(NvVFX_GetVersion); LOAD_SYM(NvVFX_CreateEffect); @@ -1153,42 +1140,20 @@ LOAD_SYM(NvVFX_AllocateState); LOAD_SYM(NvVFX_DeallocateState); LOAD_SYM(NvVFX_ResetState); - old_sdk_loaded = true; + LOAD_SYM(NvVFX_ConfigureLogger); #undef LOAD_SYM #define LOAD_SYM(sym) LOAD_SYM_FROM_LIB(sym, nv_cvimage, "NVCVImage.dll") LOAD_SYM(NvCV_GetErrorStringFromCode); LOAD_SYM(NvCVImage_Init); - LOAD_SYM(NvCVImage_InitView); LOAD_SYM(NvCVImage_Alloc); LOAD_SYM(NvCVImage_Realloc); - LOAD_SYM(NvCVImage_Dealloc); LOAD_SYM(NvCVImage_Create); LOAD_SYM(NvCVImage_Destroy); - LOAD_SYM(NvCVImage_ComponentOffsets); LOAD_SYM(NvCVImage_Transfer); - LOAD_SYM(NvCVImage_TransferRect); - LOAD_SYM(NvCVImage_TransferFromYUV); - LOAD_SYM(NvCVImage_TransferToYUV); LOAD_SYM(NvCVImage_MapResource); LOAD_SYM(NvCVImage_UnmapResource); - LOAD_SYM(NvCVImage_Composite); - LOAD_SYM(NvCVImage_CompositeRect); - LOAD_SYM(NvCVImage_CompositeOverConstant); - LOAD_SYM(NvCVImage_FlipY); - LOAD_SYM(NvCVImage_GetYUVPointers); LOAD_SYM(NvCVImage_InitFromD3D11Texture); - LOAD_SYM(NvCVImage_ToD3DFormat); - LOAD_SYM(NvCVImage_FromD3DFormat); - LOAD_SYM(NvCVImage_ToD3DColorSpace); - LOAD_SYM(NvCVImage_FromD3DColorSpace); -#undef LOAD_SYM - -#define LOAD_SYM(sym) LOAD_SYM_FROM_LIB2(sym, nv_videofx, "NVVideoEffects.dll") - LOAD_SYM(NvVFX_ConfigureLogger); - if (!nvvfx_new_sdk) { - blog(LOG_INFO, "NVIDIA VIDEO FX: SDK loaded but old redistributable detected. Please upgrade."); - } #undef LOAD_SYM int err; @@ -1212,13 +1177,13 @@ unload_everything: nvvfx_loaded = false; blog(LOG_INFO, "NVIDIA VIDEO FX: disabled, redistributable not found"); - release_nv_vfx(); + release_vfx_lib(); return false; } void unload_nvidia_vfx(void) { - release_nv_vfx(); + release_vfx_lib(); } struct obs_source_info nvidia_greenscreen_filter_info = {
View file
obs-studio-32.2.2.tar.xz/plugins/nv-filters/nvvfx-load.h -> obs-studio-33.0.0.tar.xz/plugins/nv-filters/nvvfx-load.h
Changed
@@ -37,13 +37,11 @@ #endif // _WIN32 or linux #endif //NvCV_API -#define CUDARTAPI - #ifdef LIBNVVFX_ENABLED static HMODULE nv_videofx = NULL; static HMODULE nv_cvimage = NULL; -static HMODULE nv_cudart = NULL; -static HMODULE nv_cuda = NULL; +static HMODULE nv_greenscreen = NULL; +static HMODULE nv_blur = NULL; //! Status codes returned from APIs. typedef enum NvCV_Status { @@ -392,142 +390,6 @@ typedef NvCV_Status NvCV_API (*NvCVImage_InitFromD3D11Texture_t)(NvCVImage *im, struct ID3D11Texture2D *tx); typedef NvCV_Status NvCV_API (*NvCVImage_InitFromD3DTexture_t)(NvCVImage *im, struct ID3D11Texture2D *tx); -/* cuda runtime */ -typedef enum cudaError { - cudaSuccess = 0, - cudaErrorInvalidValue = 1, - cudaErrorMemoryAllocation = 2, - cudaErrorInitializationError = 3, - cudaErrorCudartUnloading = 4, - cudaErrorProfilerDisabled = 5, - cudaErrorProfilerNotInitialized = 6, - cudaErrorProfilerAlreadyStarted = 7, - cudaErrorProfilerAlreadyStopped = 8, - cudaErrorInvalidConfiguration = 9, - cudaErrorInvalidPitchValue = 12, - cudaErrorInvalidSymbol = 13, - cudaErrorInvalidHostPointer = 16, - cudaErrorInvalidDevicePointer = 17, - cudaErrorInvalidTexture = 18, - cudaErrorInvalidTextureBinding = 19, - cudaErrorInvalidChannelDescriptor = 20, - cudaErrorInvalidMemcpyDirection = 21, - cudaErrorAddressOfConstant = 22, - cudaErrorTextureFetchFailed = 23, - cudaErrorTextureNotBound = 24, - cudaErrorSynchronizationError = 25, - cudaErrorInvalidFilterSetting = 26, - cudaErrorInvalidNormSetting = 27, - cudaErrorMixedDeviceExecution = 28, - cudaErrorNotYetImplemented = 31, - cudaErrorMemoryValueTooLarge = 32, - cudaErrorStubLibrary = 34, - cudaErrorInsufficientDriver = 35, - cudaErrorCallRequiresNewerDriver = 36, - cudaErrorInvalidSurface = 37, - cudaErrorDuplicateVariableName = 43, - cudaErrorDuplicateTextureName = 44, - cudaErrorDuplicateSurfaceName = 45, - cudaErrorDevicesUnavailable = 46, - cudaErrorIncompatibleDriverContext = 49, - cudaErrorMissingConfiguration = 52, - cudaErrorPriorLaunchFailure = 53, - cudaErrorLaunchMaxDepthExceeded = 65, - cudaErrorLaunchFileScopedTex = 66, - cudaErrorLaunchFileScopedSurf = 67, - cudaErrorSyncDepthExceeded = 68, - cudaErrorLaunchPendingCountExceeded = 69, - cudaErrorInvalidDeviceFunction = 98, - cudaErrorNoDevice = 100, - cudaErrorInvalidDevice = 101, - cudaErrorDeviceNotLicensed = 102, - cudaErrorSoftwareValidityNotEstablished = 103, - cudaErrorStartupFailure = 127, - cudaErrorInvalidKernelImage = 200, - cudaErrorDeviceUninitialized = 201, - cudaErrorMapBufferObjectFailed = 205, - cudaErrorUnmapBufferObjectFailed = 206, - cudaErrorArrayIsMapped = 207, - cudaErrorAlreadyMapped = 208, - cudaErrorNoKernelImageForDevice = 209, - cudaErrorAlreadyAcquired = 210, - cudaErrorNotMapped = 211, - cudaErrorNotMappedAsArray = 212, - cudaErrorNotMappedAsPointer = 213, - cudaErrorECCUncorrectable = 214, - cudaErrorUnsupportedLimit = 215, - cudaErrorDeviceAlreadyInUse = 216, - cudaErrorPeerAccessUnsupported = 217, - cudaErrorInvalidPtx = 218, - cudaErrorInvalidGraphicsContext = 219, - cudaErrorNvlinkUncorrectable = 220, - cudaErrorJitCompilerNotFound = 221, - cudaErrorUnsupportedPtxVersion = 222, - cudaErrorJitCompilationDisabled = 223, - cudaErrorInvalidSource = 300, - cudaErrorFileNotFound = 301, - cudaErrorSharedObjectSymbolNotFound = 302, - cudaErrorSharedObjectInitFailed = 303, - cudaErrorOperatingSystem = 304, - cudaErrorInvalidResourceHandle = 400, - cudaErrorIllegalState = 401, - cudaErrorSymbolNotFound = 500, - cudaErrorNotReady = 600, - cudaErrorIllegalAddress = 700, - cudaErrorLaunchOutOfResources = 701, - cudaErrorLaunchTimeout = 702, - cudaErrorLaunchIncompatibleTexturing = 703, - cudaErrorPeerAccessAlreadyEnabled = 704, - cudaErrorPeerAccessNotEnabled = 705, - cudaErrorSetOnActiveProcess = 708, - cudaErrorContextIsDestroyed = 709, - cudaErrorAssert = 710, - cudaErrorTooManyPeers = 711, - cudaErrorHostMemoryAlreadyRegistered = 712, - cudaErrorHostMemoryNotRegistered = 713, - cudaErrorHardwareStackError = 714, - cudaErrorIllegalInstruction = 715, - cudaErrorMisalignedAddress = 716, - cudaErrorInvalidAddressSpace = 717, - cudaErrorInvalidPc = 718, - cudaErrorLaunchFailure = 719, - cudaErrorCooperativeLaunchTooLarge = 720, - cudaErrorNotPermitted = 800, - cudaErrorNotSupported = 801, - cudaErrorSystemNotReady = 802, - cudaErrorSystemDriverMismatch = 803, - cudaErrorCompatNotSupportedOnDevice = 804, - cudaErrorStreamCaptureUnsupported = 900, - cudaErrorStreamCaptureInvalidated = 901, - cudaErrorStreamCaptureMerge = 902, - cudaErrorStreamCaptureUnmatched = 903, - cudaErrorStreamCaptureUnjoined = 904, - cudaErrorStreamCaptureIsolation = 905, - cudaErrorStreamCaptureImplicit = 906, - cudaErrorCapturedEvent = 907, - cudaErrorStreamCaptureWrongThread = 908, - cudaErrorTimeout = 909, - cudaErrorGraphExecUpdateFailure = 910, - cudaErrorUnknown = 999, - cudaErrorApiFailureBase = 10000 -} cudaError; - -typedef enum cudaMemcpyKind { - cudaMemcpyHostToHost = 0, /**< Host -> Host */ - cudaMemcpyHostToDevice = 1, /**< Host -> Device */ - cudaMemcpyDeviceToHost = 2, /**< Device -> Host */ - cudaMemcpyDeviceToDevice = 3, /**< Device -> Device */ - cudaMemcpyDefault = 4 -} cudaMemcpyKind; - -typedef enum cudaError cudaError_t; - -typedef cudaError_t CUDARTAPI (*cudaMalloc_t)(void **devPtr, size_t size); -typedef cudaError_t CUDARTAPI (*cudaStreamSynchronize_t)(CUstream stream); -typedef cudaError_t CUDARTAPI (*cudaFree_t)(void *devPtr); -typedef cudaError_t CUDARTAPI (*cudaMemsetAsync_t)(void *devPtr, int value, size_t count, CUstream stream); -typedef cudaError_t CUDARTAPI (*cudaMemcpy_t)(void *dst, const void *src, size_t count, enum cudaMemcpyKind kind); - /* NVVFX */ static NvVFX_GetVersion_t NvVFX_GetVersion = NULL; static NvVFX_CreateEffect_t NvVFX_CreateEffect = NULL; @@ -569,38 +431,17 @@ static NvCVImage_InitView_t NvCVImage_InitView = NULL; static NvCVImage_Alloc_t NvCVImage_Alloc = NULL; static NvCVImage_Realloc_t NvCVImage_Realloc = NULL; -static NvCVImage_Dealloc_t NvCVImage_Dealloc = NULL; static NvCVImage_Create_t NvCVImage_Create = NULL; static NvCVImage_Destroy_t NvCVImage_Destroy = NULL; -static NvCVImage_ComponentOffsets_t NvCVImage_ComponentOffsets = NULL; static NvCVImage_Transfer_t NvCVImage_Transfer = NULL; -static NvCVImage_TransferRect_t NvCVImage_TransferRect = NULL; -static NvCVImage_TransferFromYUV_t NvCVImage_TransferFromYUV = NULL; -static NvCVImage_TransferToYUV_t NvCVImage_TransferToYUV = NULL; static NvCVImage_MapResource_t NvCVImage_MapResource = NULL; static NvCVImage_UnmapResource_t NvCVImage_UnmapResource = NULL; -static NvCVImage_Composite_t NvCVImage_Composite = NULL; -static NvCVImage_CompositeRect_t NvCVImage_CompositeRect = NULL; -static NvCVImage_CompositeOverConstant_t NvCVImage_CompositeOverConstant = NULL; -static NvCVImage_FlipY_t NvCVImage_FlipY = NULL; -static NvCVImage_GetYUVPointers_t NvCVImage_GetYUVPointers = NULL; /* nvcvimage D3D*/ -static NvCVImage_ToD3DFormat_t NvCVImage_ToD3DFormat = NULL; -static NvCVImage_FromD3DFormat_t NvCVImage_FromD3DFormat = NULL; -static NvCVImage_ToD3DColorSpace_t NvCVImage_ToD3DColorSpace = NULL; -static NvCVImage_FromD3DColorSpace_t NvCVImage_FromD3DColorSpace = NULL; static NvCVImage_InitFromD3D11Texture_t NvCVImage_InitFromD3D11Texture = NULL; /* error codes */ static NvCV_GetErrorStringFromCode_t NvCV_GetErrorStringFromCode = NULL; -/* cuda runtime */ -static cudaMalloc_t cudaMalloc = NULL; -static cudaStreamSynchronize_t cudaStreamSynchronize = NULL; -static cudaFree_t cudaFree = NULL; -static cudaMemcpy_t cudaMemcpy = NULL; -static cudaMemsetAsync_t cudaMemsetAsync = NULL; - -static inline void release_nv_vfx() +static inline void release_vfx_lib(void) { NvVFX_CreateEffect = NULL; NvVFX_CudaStreamCreate = NULL; @@ -638,33 +479,27 @@ nv_videofx = NULL; } NvCVImage_Alloc = NULL; - NvCVImage_ComponentOffsets = NULL; - NvCVImage_Composite = NULL; - NvCVImage_CompositeRect = NULL; - NvCVImage_CompositeOverConstant = NULL; NvCVImage_Create = NULL; - NvCVImage_Dealloc = NULL; NvCVImage_Destroy = NULL; NvCVImage_Init = NULL; NvCVImage_InitView = NULL; NvCVImage_Realloc = NULL; NvCVImage_Transfer = NULL; - NvCVImage_TransferRect = NULL; - NvCVImage_TransferFromYUV = NULL; - NvCVImage_TransferToYUV = NULL; NvCVImage_MapResource = NULL; NvCVImage_UnmapResource = NULL; NvCVImage_InitFromD3D11Texture = NULL; - NvCVImage_FlipY = NULL; - NvCVImage_GetYUVPointers = NULL; - NvCVImage_ToD3DFormat = NULL; - NvCVImage_FromD3DFormat = NULL; - NvCVImage_ToD3DColorSpace = NULL; - NvCVImage_FromD3DColorSpace = NULL; if (nv_cvimage) { FreeLibrary(nv_cvimage); nv_cvimage = NULL; } + if (nv_greenscreen) { + FreeLibrary(nv_greenscreen); + nv_greenscreen = NULL; + } + if (nv_blur) { + FreeLibrary(nv_blur); + nv_blur = NULL; + } } static inline bool nvvfx_get_sdk_path(char *buffer, const size_t len) @@ -688,31 +523,39 @@ return true; } -static inline bool load_nv_vfx_libs() +static inline bool load_vfx_module(HMODULE *module, const char *sdk_path, const char *filename) { - char sdkPathMAX_PATH; - char effectsPathMAX_PATH; - char imagePathMAX_PATH; + char pathMAX_PATH; - if (!nvvfx_get_sdk_path(sdkPath, MAX_PATH)) { + if (_snprintf_s(path, _countof(path), _TRUNCATE, "%s\\%s", sdk_path, filename) == -1) return false; - } - if (_snprintf_s(effectsPath, _countof(effectsPath), _TRUNCATE, "%s\\NVVideoEffects.dll", sdkPath) == -1) { + *module = LoadLibraryExA(path, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + return *module != NULL; +} + +static inline bool load_nv_vfx_libs(unsigned int version) +{ + char sdk_pathMAX_PATH; + + if (!nvvfx_get_sdk_path(sdk_path, MAX_PATH)) return false; - } - if (_snprintf_s(imagePath, _countof(imagePath), _TRUNCATE, "%s\\NVCVImage.dll", sdkPath) == -1) { + if (!load_vfx_module(&nv_cvimage, sdk_path, "NVCVImage.dll") || + !load_vfx_module(&nv_videofx, sdk_path, "NVVideoEffects.dll")) { + release_vfx_lib(); return false; } - nv_videofx = - LoadLibraryExA(effectsPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + if (version < MIN_ARM_VFX_SDK_VERSION) + return true; - nv_cvimage = - LoadLibraryExA(imagePath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - - return !!nv_videofx && !!nv_cvimage; + if (!load_vfx_module(&nv_greenscreen, sdk_path, "nvVFXGreenScreen.dll") || + !load_vfx_module(&nv_blur, sdk_path, "nvVFXBackgroundBlur.dll")) { + release_vfx_lib(); + return false; + } + return true; } static unsigned int get_lib_version(void)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/.clang-format -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/.clang-format
Changed
@@ -1,6 +1,5 @@ # please use clang-format version 16 or later -Standard: c++17 AccessModifierOffset: -8 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false @@ -106,6 +105,10 @@ - 'DARRAY' UseTab: ForContinuationAndIndentation --- +Language: Cpp +Standard: c++17 +InsertBraces: true +--- Language: ObjC AccessModifierOffset: 2 AlignArrayOfStructures: Right @@ -207,3 +210,4 @@ Standard: c++17 TabWidth: 4 UseTab: Never +...
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/.github/actions/run-clang-format/action.yaml -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/.github/actions/run-clang-format/action.yaml
Changed
@@ -35,7 +35,7 @@ echo ::group::Install Dependencies eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH - echo "/home/linuxbrew/.linuxbrew/opt/clang-format@19/bin" >> $GITHUB_PATH + echo "/home/linuxbrew/.linuxbrew/opt/clang-format@22/bin" >> $GITHUB_PATH brew install --quiet zsh echo ::endgroup:: @@ -49,12 +49,12 @@ run: | : Run clang-format 🐉 if (( ${+RUNNER_DEBUG} )) setopt XTRACE - - print ::group::Install clang-format-19 - brew install --quiet obsproject/tools/clang-format@19 + + print ::group::Install clang-format-22 + brew install --quiet obsproject/tools/clang-format@22 print ::endgroup:: - print ::group::Run clang-format-19 + print ::group::Run clang-format-22 local -a changes=(${(s:,:)CHANGED_FILES//\\\'\"/}) ./build-aux/run-clang-format --fail-${{ inputs.failCondition }} --check ${changes} print ::endgroup::
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/.github/workflows/check-format.yaml -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/.github/workflows/check-format.yaml
Changed
@@ -5,7 +5,7 @@ clang-format: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: clang-format Check 🐉
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/CMakeLists.txt
Changed
@@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16...3.25) +cmake_minimum_required(VERSION 3.28...3.30) option(ENABLE_BROWSER "Enable browser source plugin (required Chromium Embedded Framework)" OFF) @@ -21,28 +21,31 @@ target_sources( obs-browser PRIVATE # cmake-format: sortable - browser-app.cpp - browser-app.hpp - browser-client.cpp - browser-client.hpp - browser-scheme.cpp - browser-scheme.hpp - browser-version.h - cef-headers.hpp - deps/base64/base64.cpp - deps/base64/base64.hpp - deps/ip-string.hpp - deps/signal-restore.cpp - deps/signal-restore.hpp - deps/wide-string.cpp - deps/wide-string.hpp - obs-browser-plugin.cpp - obs-browser-source.cpp - obs-browser-source.hpp) + browser-app.cpp + browser-app.hpp + browser-client.cpp + browser-client.hpp + browser-dummy-client.cpp + browser-dummy-client.hpp + browser-scheme.cpp + browser-scheme.hpp + browser-version.h + cef-headers.hpp + deps/base64/base64.cpp + deps/base64/base64.hpp + deps/ip-string.hpp + deps/signal-restore.cpp + deps/signal-restore.hpp + deps/wide-string.cpp + deps/wide-string.hpp + obs-browser-plugin.cpp + obs-browser-source.cpp + obs-browser-source.hpp +) target_include_directories(obs-browser PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/deps") -target_compile_features(obs-browser PRIVATE cxx_std_17) +target_compile_features(obs-browser PRIVATE cxx_std_20) target_link_libraries(obs-browser PRIVATE OBS::libobs OBS::frontend-api OBS::websocket-api nlohmann_json::nlohmann_json) if(OS_WINDOWS)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/browser-app.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/browser-app.cpp
Changed
@@ -38,6 +38,12 @@ } #endif +#ifdef _WIN32 +constexpr bool kIsPlatformWindows = true; +#else +constexpr bool kIsPlatformWindows = false; +#endif + CefRefPtr<CefRenderProcessHandler> BrowserApp::GetRenderProcessHandler() { return this; @@ -48,11 +54,62 @@ return this; } +CefRefPtr<CefClient> BrowserApp::GetDefaultClient() +{ + return GetDummy(); +} + void BrowserApp::OnRegisterCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar) { registrar->AddCustomScheme("http", CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_CORS_ENABLED); } +void BrowserApp::OnContextInitialized() +{ + // Without a default client, CefBrowser is unmanaged, allowing full-blown Chromium windows outside of our control. + // We don't actually want those, so define a dummy client which will automatically close any such windows. + dummy = new BrowserDummyClient(); + + CefRefPtr<CefRequestContext> requestContext = CefRequestContext::GetGlobalContext(); + CefString errorMessage; + CefRefPtr<CefValue> optionValue = CefValue::Create(); + + constexpr std::array<std::string_view, 20> kBrowserFeaturesToDisable{ + "autofill.credit_card_enabled", + "autofill.enabled", + "autofill.iban_enabled", + "autofill.payment_card_benefits", + "autofill.payment_cvc_storage", + "autofill.profile_enabled", + "autologin.enabled", + "browser_labs_enabled", + "credentials_enable_autosignin", + "credentials_enable_service", + "payments.can_make_payment_enabled", + "printing.enabled", + "search.suggest_enabled", + "shopping_list_enabled", + "side_panel.google_search_side_panel_enabled", + "side_search.enabled", + "signin.allowed", + "signin.allowed_on_next_startup", + "translate", + "url_keyed_anonymized_data_collection.enabled"}; + + constexpr std::array<std::string_view, 2> kBrowserFeaturesToEnable{"extensions.block_external_extensions", + "extensions.disabled"}; + + optionValue->SetBool(false); + for (std::string_view feature : kBrowserFeaturesToDisable) { + requestContext->SetPreference(feature.data(), optionValue.get(), errorMessage); + } + + optionValue->SetBool(true); + for (std::string_view feature : kBrowserFeaturesToEnable) { + requestContext->SetPreference(feature.data(), optionValue.get(), errorMessage); + } +} + void BrowserApp::OnBeforeChildProcessLaunch(CefRefPtr<CefCommandLine> command_line) { #ifdef _WIN32 @@ -74,24 +131,41 @@ } } + // See https://github.com/chromiumembedded/cef/issues/3966 for 'StorageNotificationService' requirement. + constexpr std::string_view kDefaultDisabledFeatures{ + "CalculateNativeWinOcclusion,GlobalShortcutsPortal,HardwareMediaKeyHandling,LiveCaption," + "LocalNetworkAccessChecksWebSockets,MediaRouter,StorageNotificationService,WebBluetooth," + "EnableWindowsGamingInputDataFetcher"}; + + std::string disableFeatures{}; + + if constexpr (kIsPlatformWindows) { + disableFeatures.append(kDefaultDisabledFeatures); + command_line->AppendSwitch("do-not-de-elevate"); + } else { + constexpr std::string_view kWindowsFeature{",EnableWindowsGamingInputDataFetcher"}; + constexpr size_t kNonWindowsLength = kDefaultDisabledFeatures.size() - kWindowsFeature.size(); + disableFeatures.append(kDefaultDisabledFeatures.substr(0, kNonWindowsLength)); + } + if (command_line->HasSwitch("disable-features")) { // Don't override existing, as this can break OSR - std::string disableFeatures = command_line->GetSwitchValue("disable-features"); - disableFeatures += ",HardwareMediaKeyHandling"; -#ifdef _WIN32 - disableFeatures += ",EnableWindowsGamingInputDataFetcher"; -#endif - disableFeatures += ",WebBluetooth"; - command_line->AppendSwitchWithValue("disable-features", disableFeatures); + disableFeatures.append(","); + disableFeatures.append(command_line->GetSwitchValue("disable-features")); + } + + if (command_line->HasSwitch("disable-blink-features")) { + std::string disableBlinkFeatures = command_line->GetSwitchValue("disable-blink-features"); + disableBlinkFeatures += ",DocumentPictureInPictureAPI"; + command_line->AppendSwitchWithValue("disable-blink-features", disableBlinkFeatures); } else { - command_line->AppendSwitchWithValue("disable-features", "WebBluetooth," -#ifdef _WIN32 - "EnableWindowsGamingInputDataFetcher," -#endif - "HardwareMediaKeyHandling"); + command_line->AppendSwitchWithValue("disable-blink-features", "DocumentPictureInPictureAPI"); } command_line->AppendSwitchWithValue("autoplay-policy", "no-user-gesture-required"); + command_line->AppendSwitch("disable-extensions"); + command_line->AppendSwitchWithValue("disable-features", disableFeatures); + command_line->AppendSwitch("hide-crash-restore-bubble"); #ifdef __APPLE__ command_line->AppendSwitch("use-mock-keychain"); #elif !defined(_WIN32) @@ -144,8 +218,9 @@ CefRefPtr<CefV8Value> obsStudioObj = globalObj->GetValue("obsstudio"); CefRefPtr<CefV8Value> jsFunction = obsStudioObj->GetValue(functionName); - if (jsFunction && jsFunction->IsFunction()) + if (jsFunction && jsFunction->IsFunction()) { jsFunction->ExecuteFunction(nullptr, arguments); + } context->Exit(); } @@ -227,8 +302,9 @@ nlohmann::json payloadJson = nlohmann::json::parse(args->GetString(1).ToString(), nullptr, false); nlohmann::json wrapperJson; - if (args->GetSize() > 1) + if (args->GetSize() > 1) { wrapperJson"detail" = payloadJson; + } std::string wrapperJsonString = wrapperJson.dump(); std::string script; @@ -287,8 +363,9 @@ args.push_back(retval); - if (callback) + if (callback) { callback->ExecuteFunction(nullptr, args); + } context->Exit(); @@ -324,19 +401,21 @@ /* Pass on arguments */ for (u_long l = 0; l < arguments.size(); l++) { u_long pos; - if (arguments0->IsFunction()) + if (arguments0->IsFunction()) { pos = l; - else + } else { pos = l + 1; + } - if (argumentsl->IsString()) + if (argumentsl->IsString()) { args->SetString(pos, argumentsl->GetStringValue()); - else if (argumentsl->IsInt()) + } else if (argumentsl->IsInt()) { args->SetInt(pos, argumentsl->GetIntValue()); - else if (argumentsl->IsBool()) + } else if (argumentsl->IsBool()) { args->SetBool(pos, argumentsl->GetBoolValue()); - else if (argumentsl->IsDouble()) + } else if (argumentsl->IsDouble()) { args->SetDouble(pos, argumentsl->GetDoubleValue()); + } } CefRefPtr<CefBrowser> browser = CefV8Context::GetCurrentContext()->GetBrowser(); @@ -367,8 +446,9 @@ Task nextTask; { std::lock_guard<std::mutex> lock(browserTaskMutex); - if (!browserTasks.size()) + if (!browserTasks.size()) { return false; + } nextTask = browserTasks0; browserTasks.pop_front(); @@ -385,10 +465,11 @@ void MessageObject::DoCefMessageLoop(int ms) { - if (ms) + if (ms) { QTimer::singleShot((int)ms + 2, () { CefDoMessageLoopWork(); }); - else + } else { CefDoMessageLoopWork(); + } } void MessageObject::Process() @@ -409,10 +490,11 @@ void BrowserApp::OnScheduleMessagePumpWork(int64_t delay_ms) #endif { - if (delay_ms < 0) + if (delay_ms < 0) { delay_ms = 0; - else if (delay_ms > MAX_DELAY) + } else if (delay_ms > MAX_DELAY) { delay_ms = MAX_DELAY; + } if (!frameTimer.isActive()) { QObject::connect(&frameTimer, &QTimer::timeout, &messageObject, &MessageObject::Process);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/browser-app.hpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/browser-app.hpp
Changed
@@ -22,6 +22,7 @@ #include <unordered_map> #include <functional> #include "cef-headers.hpp" +#include "browser-dummy-client.hpp" typedef std::function<void(CefRefPtr<CefBrowser>)> BrowserFunc; @@ -85,6 +86,8 @@ virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() override; virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() override; + virtual CefRefPtr<CefClient> GetDefaultClient() override; + virtual void OnContextInitialized() override; virtual void OnBeforeChildProcessLaunch(CefRefPtr<CefCommandLine> command_line) override; virtual void OnRegisterCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar) override; virtual void OnBeforeCommandLineProcessing(const CefString &process_type, @@ -106,5 +109,9 @@ QTimer frameTimer; #endif + CefRefPtr<BrowserDummyClient> dummy = nullptr; + + BrowserDummyClient *GetDummy() const { return dummy.get(); }; + IMPLEMENT_REFCOUNTING(BrowserApp); };
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/browser-client.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/browser-client.cpp
Changed
@@ -56,6 +56,13 @@ return this; } +#if CHROME_VERSION_BUILD >= 6533 +CefRefPtr<CefPermissionHandler> BrowserClient::GetPermissionHandler() +{ + return this; +} +#endif + CefRefPtr<CefLifeSpanHandler> BrowserClient::GetLifeSpanHandler() { return this; @@ -95,8 +102,9 @@ #endif ) { - if (!valid()) + if (!valid()) { return; + } #if CHROME_VERSION_BUILD >= 6367 std::string str_text = error_string; @@ -106,8 +114,9 @@ const char *sourceName = "<unknown>"; - if (bs && bs->source) + if (bs && bs->source) { sourceName = obs_source_get_name(bs->source); + } blog(LOG_ERROR, "obs-browser: '%s' Webpage has crashed unexpectedly! Reason: '%s'", sourceName, str_text.c_str()); @@ -205,12 +214,13 @@ obs_frontend_source_list_free(&transitions); - if (transition) + if (transition) { obs_frontend_set_current_transition(transition); - else + } else { blog(LOG_WARNING, "Browser source '%s' tried to change the current transition to '%s' which doesn't exist", obs_source_get_name(bs->source), transition_name.c_str()); + } } fallthrough; case ControlLevel::Basic: @@ -232,12 +242,14 @@ } else if (name == "getCurrentScene") { OBSSourceAutoRelease current_scene = obs_frontend_get_current_scene(); - if (!current_scene) + if (!current_scene) { return false; + } const char *name = obs_source_get_name(current_scene); - if (!name) + if (!name) { return false; + } json = {{"name", name}, {"width", obs_source_get_width(current_scene)}, @@ -301,6 +313,21 @@ return true; } +#if CHROME_VERSION_BUILD >= 6533 +/* CefPermissionHandler */ +bool BrowserClient::OnShowPermissionPrompt(CefRefPtr<CefBrowser>, uint64_t, const CefString &, + uint32_t requested_permissions, + CefRefPtr<CefPermissionPromptCallback> callback) +{ + // Implicitly allow Localhost access to retain previous behavior for now + if ((requested_permissions & CEF_PERMISSION_TYPE_LOOPBACK_NETWORK) != 0) { + callback->Continue(CEF_PERMISSION_RESULT_ACCEPT); + return true; + } + return false; +} +#endif + void BrowserClient::OnPaint(CefRefPtr<CefBrowser>, PaintElementType type, const RectList &, const void *buffer, int width, int height) { @@ -386,14 +413,16 @@ } #if !defined(_WIN32) && !defined(__APPLE__) - if (info.plane_count == 0) + if (info.plane_count == 0) { return; + } struct obs_cef_video_format format = obs_cef_format_from_cef_type(info.format); uint64_t modifier = info.modifier; - if (format.gs_format == GS_UNKNOWN) + if (format.gs_format == GS_UNKNOWN) { return; + } uint32_t *strides = (uint32_t *)alloca(info.plane_count * sizeof(uint32_t)); uint32_t *offsets = (uint32_t *)alloca(info.plane_count * sizeof(uint32_t)); @@ -402,8 +431,9 @@ /* NOTE: This a workaround under X11 where the modifier is always invalid where it can mean "no modifier" in * Chromium's code. */ - if (obs_get_nix_platform() == OBS_NIX_PLATFORM_X11_EGL && modifier == DRM_FORMAT_MOD_INVALID) + if (obs_get_nix_platform() == OBS_NIX_PLATFORM_X11_EGL && modifier == DRM_FORMAT_MOD_INVALID) { modifier = DRM_FORMAT_MOD_LINEAR; + } for (size_t i = 0; i < kAcceleratedPaintMaxPlanes; i++) { auto *plane = &info.planesi; @@ -417,8 +447,9 @@ #endif #if !defined(_WIN32) && CHROME_VERSION_BUILD < 6367 - if (shared_handle == bs->last_handle) + if (shared_handle == bs->last_handle) { return; + } #endif obs_enter_graphics(); @@ -553,8 +584,9 @@ const uint8_t **pcm = (const uint8_t **)data; speaker_layout speakers = GetSpeakerLayout(channel_layout); int speaker_count = get_audio_channels(speakers); - for (int i = 0; i < speaker_count; i++) + for (int i = 0; i < speaker_count; i++) { audio.datai = pcmi; + } audio.samples_per_sec = sample_rate; audio.frames = frames; audio.format = AUDIO_FORMAT_FLOAT_PLANAR; @@ -606,6 +638,17 @@ return true; } +void BrowserClient::OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, TransitionType) +{ + if (!valid()) { + return; + } + + if (reroute_audio && frame->IsMain()) { + browser->GetHost()->SetAudioMuted(true); + } +} + void BrowserClient::OnLoadEnd(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame> frame, int) { if (!valid()) { @@ -626,6 +669,22 @@ } } +void BrowserClient::OnLoadError(CefRefPtr<CefBrowser>, maybe_unused CefRefPtr<CefFrame> frame, + maybe_unused CefLoadHandler::ErrorCode errorCode, const CefString &, + const CefString &) +{ +#if CHROME_VERSION_BUILD > 6533 + if (errorCode == ERR_ABORTED) { + return; + } + + // CEF doesn't currently provide a way to properly disable/override the default Chrome error page. + // https://github.com/obsproject/obs-studio/issues/13499 + // FIXME: https://github.com/chromiumembedded/cef/issues/3852 + frame->ExecuteJavaScript("document.querySelector('html').innerText = '';", "", 0); +#endif +} + bool BrowserClient::OnConsoleMessage(CefRefPtr<CefBrowser>, cef_log_severity_t level, const CefString &message, const CefString &source, int line) { @@ -646,8 +705,9 @@ const char *sourceName = "<unknown>"; - if (bs && bs->source) + if (bs && bs->source) { sourceName = obs_source_get_name(bs->source); + } blog(errorLevel, "obs-browser: '%s' %s: %s (%s:%d)", sourceName, code, message.ToString().c_str(), source.ToString().c_str(), line);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/browser-client.hpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/browser-client.hpp
Changed
@@ -27,6 +27,9 @@ class BrowserClient : public CefClient, public CefDisplayHandler, +#if CHROME_VERSION_BUILD >= 6533 + public CefPermissionHandler, +#endif public CefLifeSpanHandler, public CefRequestHandler, public CefResourceRequestHandler, @@ -66,6 +69,9 @@ virtual CefRefPtr<CefLoadHandler> GetLoadHandler() override; virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override; virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() override; +#if CHROME_VERSION_BUILD >= 6533 + virtual CefRefPtr<CefPermissionHandler> GetPermissionHandler() override; +#endif virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override; virtual CefRefPtr<CefRequestHandler> GetRequestHandler() override; virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override; @@ -80,6 +86,13 @@ const CefString &source, int line) override; virtual bool OnTooltip(CefRefPtr<CefBrowser> browser, CefString &text) override; + /* CefPermissionHandler */ +#if CHROME_VERSION_BUILD >= 6533 + virtual bool OnShowPermissionPrompt(CefRefPtr<CefBrowser> browser, uint64_t prompt_id, + const CefString &requesting_origin, uint32_t requested_permissions, + CefRefPtr<CefPermissionPromptCallback> callback) override; +#endif + /* CefLifeSpanHandler */ virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, #if CHROME_VERSION_BUILD >= 6834 @@ -144,7 +157,13 @@ virtual bool GetAudioParameters(CefRefPtr<CefBrowser> browser, CefAudioParameters ¶ms) override; /* CefLoadHandler */ + virtual void OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, + TransitionType transition_type) override; virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int httpStatusCode) override; + virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, + CefLoadHandler::ErrorCode errorCode, const CefString &errorText, + const CefString &failedUrl) override; + IMPLEMENT_REFCOUNTING(BrowserClient); };
View file
obs-studio-33.0.0.tar.xz/plugins/obs-browser/browser-dummy-client.cpp
Added
@@ -0,0 +1,87 @@ +/****************************************************************************** + Copyright (C) 2026 by Matt Gajownik <matt@volunteer.obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "browser-dummy-client.hpp" + +CefRefPtr<CefCommandHandler> BrowserDummyClient::GetCommandHandler() +{ + return this; +} + +CefRefPtr<CefRequestHandler> BrowserDummyClient::GetRequestHandler() +{ + return this; +} + +CefRefPtr<CefLifeSpanHandler> BrowserDummyClient::GetLifeSpanHandler() +{ + return this; +} + +bool BrowserDummyClient::OnChromeCommand(CefRefPtr<CefBrowser>, int, cef_window_open_disposition_t) +{ + return true; +} + +bool BrowserDummyClient::IsChromeAppMenuItemVisible(CefRefPtr<CefBrowser>, int) +{ + return false; +} + +bool BrowserDummyClient::IsChromeToolbarButtonVisible(cef_chrome_toolbar_button_type_t) +{ + return false; +} + +bool BrowserDummyClient::IsChromePageActionIconVisible(cef_chrome_page_action_icon_type_t) +{ + return false; +} + +bool BrowserDummyClient::IsChromeAppMenuItemEnabled(CefRefPtr<CefBrowser>, int) +{ + return false; +} + +bool BrowserDummyClient::OnBeforePopup(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>, +#if CHROME_VERSION_BUILD >= 6834 + int, +#endif + const CefString &, const CefString &, cef_window_open_disposition_t, bool, + const CefPopupFeatures &, CefWindowInfo &, CefRefPtr<CefClient> &, + CefBrowserSettings &, CefRefPtr<CefDictionaryValue> &, bool *) +{ + return true; +} + +void BrowserDummyClient::OnAfterCreated(CefRefPtr<CefBrowser> browser) +{ + if (browser && browser->GetHost()) { + browser->GetHost()->CloseBrowser(false); + } +} + +bool BrowserDummyClient::OnOpenURLFromTab(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>, const CefString &, + CefRequestHandler::WindowOpenDisposition, bool) +{ + return true; +} + +bool BrowserDummyClient::OnBeforeBrowse(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>, CefRefPtr<CefRequest>, bool, bool) +{ + return true; +}
View file
obs-studio-33.0.0.tar.xz/plugins/obs-browser/browser-dummy-client.hpp
Added
@@ -0,0 +1,64 @@ +/****************************************************************************** + Copyright (C) 2026 by Matt Gajownik <matt@volunteer.obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include "cef-headers.hpp" + +class BrowserDummyClient : public CefClient, + public CefCommandHandler, + public CefRequestHandler, + public CefLifeSpanHandler { +public: + virtual CefRefPtr<CefCommandHandler> GetCommandHandler() override; + virtual CefRefPtr<CefRequestHandler> GetRequestHandler() override; + virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override; + + /* CefCommandHandler */ + virtual bool OnChromeCommand(CefRefPtr<CefBrowser> browser, int command_id, + cef_window_open_disposition_t disposition) override; + virtual bool IsChromeAppMenuItemVisible(CefRefPtr<CefBrowser> browser, int command_id) override; + virtual bool IsChromeToolbarButtonVisible(cef_chrome_toolbar_button_type_t button_type) override; + + virtual bool IsChromePageActionIconVisible(cef_chrome_page_action_icon_type_t icon_type) override; + + virtual bool IsChromeAppMenuItemEnabled(CefRefPtr<CefBrowser> browser, int command_id) override; + + /* CefLifeSpanHandler */ + virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, +#if CHROME_VERSION_BUILD >= 6834 + int, +#endif + const CefString &target_url, const CefString &target_frame_name, + cef_window_open_disposition_t target_disposition, bool user_gesture, + const CefPopupFeatures &popupFeatures, CefWindowInfo &windowInfo, + CefRefPtr<CefClient> &client, CefBrowserSettings &settings, + CefRefPtr<CefDictionaryValue> &extra_info, bool *no_javascript_access) override; + + virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) override; + + /* CefRequestHandler */ + virtual bool OnOpenURLFromTab(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, + const CefString &target_url, + CefRequestHandler::WindowOpenDisposition target_disposition, + bool user_gesture) override; + + virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, + CefRefPtr<CefRequest> request, bool user_gesture, bool is_redirect) override; + + IMPLEMENT_REFCOUNTING(BrowserDummyClient); +};
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/browser-scheme.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/browser-scheme.cpp
Changed
@@ -24,8 +24,19 @@ CefRefPtr<CefResourceHandler> BrowserSchemeHandlerFactory::Create(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame>, const CefString &, CefRefPtr<CefRequest> request) { - if (!browser || !request) + if (!browser || !request) { return nullptr; + } + + CefString frameURL = browser->GetMainFrame()->GetURL(); + if (!frameURL.empty()) { + CefURLParts frameParts; + CefParseURL(frameURL, frameParts); + std::string frameOrigin = CefString(&frameParts.origin); + if (frameOrigin != "http://absolute/") { + return nullptr; + } + } CefURLParts parts; CefParseURL(request->GetURL(), parts); @@ -37,10 +48,12 @@ std::string fileExtension = path.substr(path.find_last_of(".") + 1); - for (char &ch : fileExtension) + for (char &ch : fileExtension) { ch = (char)tolower(ch); - if (fileExtension.compare("woff2") == 0) + } + if (fileExtension.compare("woff2") == 0) { fileExtension = "woff"; + } std::string filePath = path.substr(1);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/browser-version.h -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/browser-version.h
Changed
@@ -1,8 +1,8 @@ #pragma once #define OBS_BROWSER_VERSION_MAJOR 2 -#define OBS_BROWSER_VERSION_MINOR 26 -#define OBS_BROWSER_VERSION_PATCH 9 +#define OBS_BROWSER_VERSION_MINOR 27 +#define OBS_BROWSER_VERSION_PATCH 4 #ifndef MAKE_SEMANTIC_VERSION #define MAKE_SEMANTIC_VERSION(major, minor, patch) ((major << 24) | (minor << 16) | patch)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/build-aux/.run-format.zsh -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/build-aux/.run-format.zsh
Changed
@@ -33,24 +33,24 @@ case ${formatter} { clang) - if (( ${+commandsclang-format-19} )) { - local formatter=clang-format-19 + if (( ${+commandsclang-format-22} )) { + local formatter=clang-format-22 } elif (( ${+commandsclang-format} )) { local formatter=clang-format } else { - log_error "No viable clang-format version found (required 19.1.1)" + log_error "No viable clang-format version found (required 22.1.3)" exit 2 } local -a formatter_version=($(${formatter} --version)) - if ! is-at-least 19.1.1 ${formatter_version-1}; then - log_error "clang-format is not version 19.1.1 or above (found ${formatter_version-1}." + if ! is-at-least 22.1.3 ${formatter_version-1}; then + log_error "clang-format is not version 22.1.3 or above (found ${formatter_version-1}." exit 2 fi - if ! is-at-least ${formatter_version-1} 19.1.1; then - log_error "clang-format is more recent than version 19.1.1 (found ${formatter_version-1})." + if ! is-at-least ${formatter_version-1} 22.1.3; then + log_error "clang-format is more recent than version 22.1.3 (found ${formatter_version-1})." exit 2 fi
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/cmake/os-linux.cmake -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/cmake/os-linux.cmake
Changed
@@ -14,11 +14,13 @@ target_sources( browser-helper PRIVATE # cmake-format: sortable - browser-app.cpp browser-app.hpp cef-headers.hpp obs-browser-page/obs-browser-page-main.cpp) + browser-app.cpp browser-app.hpp browser-dummy-client.cpp browser-dummy-client.hpp + cef-headers.hpp obs-browser-page/obs-browser-page-main.cpp) target_include_directories(browser-helper PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/deps" "${CMAKE_CURRENT_SOURCE_DIR}/obs-browser-page") +target_compile_features(browser-helper PRIVATE cxx_std_20) target_link_libraries(browser-helper PRIVATE CEF::Wrapper CEF::Library) target_sources(obs-browser PRIVATE deps/ip-string-posix.cpp)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/cmake/os-macos.cmake -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/cmake/os-macos.cmake
Changed
@@ -24,17 +24,18 @@ set(EXECUTABLE_NAME "${target_output_name}") set(BUNDLE_ID_SUFFIX ${helper_plist}) - configure_file(cmake/macos/Info-helper.plist.in Info-Helper${helper_plist}.plist) - add_executable(${target_name} MACOSX_BUNDLE EXCLUDE_FROM_ALL) add_executable(OBS::${target_name} ALIAS ${target_name}) target_sources( ${target_name} PRIVATE # cmake-format: sortable - browser-app.cpp browser-app.hpp cef-headers.hpp obs-browser-page/obs-browser-page-main.cpp) + browser-app.cpp browser-app.hpp browser-dummy-client.cpp browser-dummy-client.hpp + cef-headers.hpp obs-browser-page/obs-browser-page-main.cpp) target_compile_definitions(${target_name} PRIVATE ENABLE_BROWSER_SHARED_TEXTURE) + target_compile_features(${target_name} PRIVATE cxx_std_20) + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 14.0.3) target_compile_options(${target_name} PRIVATE -Wno-error=unqualified-std-cast-call) endif() @@ -44,14 +45,21 @@ target_link_libraries(${target_name} PRIVATE CEF::Wrapper nlohmann_json::nlohmann_json) + string(TIMESTAMP CURRENT_YEAR "%Y") set_target_properties( ${target_name} - PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/Info-Helper${helper_plist}.plist" - OUTPUT_NAME "${target_output_name}" - FOLDER plugins/obs-browser/Helpers - XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.obsproject.obs-studio.helper${helper_plist} - XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements-helper${helper_plist}.plist") + PROPERTIES + OUTPUT_NAME "${target_output_name}" + FOLDER plugins/obs-browser/Helpers + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.obsproject.obs-studio.helper${helper_plist} + XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION ${OBS_BUILD_NUMBER} + XCODE_ATTRIBUTE_MARKETING_VERSION ${OBS_VERSION_CANONICAL} + XCODE_ATTRIBUTE_GENERATE_INFOPLIST_FILE YES + XCODE_ATTRIBUTE_INFOPLIST_KEY_CFBundleDisplayName "${target_output_name}" + XCODE_ATTRIBUTE_INFOPLIST_KEY_LSApplicationCategoryType "public.app-category.video" + XCODE_ATTRIBUTE_INFOPLIST_KEY_NSHumanReadableCopyright "(c) 2012-${CURRENT_YEAR} Lain Bailey" + XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements-helper${helper_plist}.plist" + ) endforeach() target_sources(obs-browser PRIVATE deps/ip-string-posix.cpp)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/cmake/os-windows.cmake -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/cmake/os-windows.cmake
Changed
@@ -13,8 +13,8 @@ target_sources( obs-browser-helper PRIVATE # cmake-format: sortable - browser-app.cpp browser-app.hpp cef-headers.hpp obs-browser-page.manifest - obs-browser-page/obs-browser-page-main.cpp) + browser-app.cpp browser-app.hpp browser-dummy-client.cpp browser-dummy-client.hpp + cef-headers.hpp obs-browser-page.manifest obs-browser-page/obs-browser-page-main.cpp) configure_file(cmake/windows/obs-module-helper.rc.in obs-browser-page.rc) target_sources(obs-browser-helper PRIVATE obs-browser-page.rc) @@ -24,6 +24,7 @@ target_compile_options(obs-browser-helper PRIVATE $<IF:$<CONFIG:DEBUG>,/MTd,/MT>) target_compile_definitions(obs-browser-helper PRIVATE ENABLE_BROWSER_SHARED_TEXTURE) +target_compile_features(obs-browser-helper PRIVATE cxx_std_20) target_link_libraries(obs-browser-helper PRIVATE CEF::Wrapper CEF::Library nlohmann_json::nlohmann_json) target_link_options(obs-browser-helper PRIVATE /IGNORE:4099 /SUBSYSTEM:WINDOWS)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/data/locale/hu-HU.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/data/locale/hu-HU.ini
Changed
@@ -28,6 +28,7 @@ Error.Description="Győződjön meg róla, hogy a cím helyes, és hogy nincsenek problémák az oldallal." Error.Retry="Újrapróbálkozáshoz kattintson ide" Error.Code="Hiba: %1" +Error.URL="Webcím: %2" Zoom.Reset="Nagyítás visszaállítása" Zoom.Out="Kicsinyités" Zoom.In="Nagyítás"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/data/locale/kaa.ini
Changed
@@ -1,33 +1,23 @@ -URL="URL mánzil" -Width="Enı" -Height="Uzınlıǵı" -FPS="Kadrlar tezligi (FPS)" +LocalFile="Локал файл" +URL="Силтеме" +Width="Ени" +Height="Узынлығы" CSS="CSS" -RefreshBrowserActive="Saxna aktiv bolǵanda, brauzerdi jańalaw" -RefreshNoCache="Ámeldegi bet keshin jańalaw" -BrowserSource="Brauzer" -RerouteAudio="Audionı OBS arqalı basqarıw" -Inspect="tekseriw" -CopyUrl="Ámeldegi mánzildi kóshirip alıw" -WebpageControlLevel="Bet ruqsatları" -Dialog.Alert="JavaScript eskertiw" -Dialog.Confirm="JavaScript tastıyqlaw" -Dialog.ReceivedFrom="'%1' dan alındı" -Error.Title="Bul betti júklew ámelge aspadı!" -Error.Description="Mánzil durıs ekenligine hám saytta mashqala joqlıǵına isenim kámil etiń." -Error.Retry="Qayta urınıp kórıw ushın, usı jerge basıń" -Error.Code="Qátelik: %1" -Error.URL="URL mánzil: %2" -Zoom.Reset="Masshtabtı tiklew" -Zoom.Out="Masshtabtı kishireytiriw" -Zoom.In="Masshtabti úlkenlestiriw" -ErrorCode.ERR_CONNECTION_REFUSED="Server jalǵanıwdı biykarladı" -ErrorCode.ERR_NAME_NOT_RESOLVED="Serverdıń IP mánzili tabılmadı" -ErrorCode.ERR_CONNECTION_TIMED_OUT="Jalǵanıw waqtı tawsildi" -ErrorCode.ERR_TIMED_OUT="Operatsiya waqti tawsildi" -ErrorCode.ERR_FILE_NOT_FOUND="Fayl tawılmadı" -ErrorCode.ERR_FAILED="Jalǵanıw ámelge aspadı" -ErrorCode.ERR_NETWORK_CHANGED="Tarmaq ózgertildi" -ErrorCode.ERR_SSL_VERSION_INTERFERENCE="SSL versiyası mashqalası. TLS 1.3 bloklanǵan yamasa ózgertilgen bolıwı múmkin." -ErrorCode.ERR_SSL_PROTOCOL_ERROR="SSL protokolı qáteligi. Qáwipsiz jalǵanıwdı ornatıw múmkinshiligi bolmadı." -ErrorCode.ERR_CERT_DATE_INVALID="Serverdiń SSL sertifikatı eskirgen yamasa siziń kompyuterińizdegi sáne nadurıs." +RefreshBrowserActive="Сахна актив болғанда браузерди жаңалаў" +RefreshNoCache="Әмелдеги беттиң кешин жаңалаў" +BrowserSource="Браузер" +CopyUrl="Әмелдеги мәнзилди көширип алыў" +WebpageControlLevel="Бет руқсатлары" +Dialog.Alert="JavaScript ескертиўи" +Dialog.Confirm="JavaScript тастыйықлаўы" +Dialog.BrowserDock="Браузер док-панели" +Dialog.ReceivedFrom="Кимнен алынды: '%1'" +Error.Title="Бет жүкленбеди!" +Error.Code="Қәтелик: %1" +Error.URL="Силтеме: %2" +ErrorCode.ERR_CONNECTION_REFUSED="Сервер жалғаныўды бийкарлады" +ErrorCode.ERR_NAME_NOT_RESOLVED="Сервердиң IP-мәнзили табылмады" +ErrorCode.ERR_FILE_NOT_FOUND="Файл табылмады" +ErrorCode.ERR_FAILED="Жалғаныў қәтелиги" +ErrorCode.ERR_NETWORK_CHANGED="Тармақ өзгертилди" +ErrorCode.ERR_CERT_DATE_INVALID="Сервердиң SSL сертификаты ескирген ямаса компьютерде ўақыт надурыс көрсетилген."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/data/locale/kab-KAB.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/data/locale/kab-KAB.ini
Changed
@@ -36,5 +36,5 @@ ErrorCode.ERR_FILE_NOT_FOUND="Afaylu ur yettwaf ara" ErrorCode.ERR_FAILED="Tuqqna ur teddi ara" ErrorCode.ERR_NETWORK_CHANGED="Aẓeṭṭa yettwabeddel" -ErrorCode.ERR_SSL_PROTOCOL_ERROR="Tuccḍa n uneggaf SSL. Ur yezmir ara ad yerr tuqqna taɣelsant. Aẓeṭṭa yettwabeddel" +ErrorCode.ERR_SSL_PROTOCOL_ERROR="Tuccḍa n uneggaf SSL. Ur yezmir ara ad yerr tuqqna taɣelsant. Aẓeṭṭa yettwabeddel." ErrorCode.ERR_CERT_DATE_INVALID="Aselkin n uqeddac SSL yeǧǧa-t wakud n uselkim-ik·im neɣ aselkim-ik·im d armeɣtu."
View file
obs-studio-33.0.0.tar.xz/plugins/obs-browser/data/locale/lv-LV.ini
Added
@@ -0,0 +1,14 @@ +LocalFile="Lokālais fails" +URL="Tīmekļa vietnes adrese" +Width="Platums" +Height="Augstums" +CSS="Pielāgots CSS" +ShutdownSourceNotVisible="Izslēgt avotu, kad tas nav redzams" +RefreshNoCache="Atsvaidzināt pašreizējās lapas kešatmiņu" +BrowserSource="Pārlūks" +RerouteAudio="Audio vadība, izmantojot OBS" +Inspect="Pārbaudīt" +CopyUrl="Kopēt pašreizējo adresi" +WebpageControlLevel="Lapas atļaujas" +WebpageControlLevel.Level.None="Nav piekļuves OBS" +WebpageControlLevel.Level.ReadObs="Lasīšanas piekļuve OBS statusa informācijai"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/data/locale/tr-TR.ini
Changed
@@ -8,11 +8,11 @@ RefreshNoCache="Geçerli sayfanın önbelleğini yenile" BrowserSource="Tarayıcı" CustomFrameRate="Özel kare hızı kullan" -RerouteAudio="OBS ile sesi kontrol etme" -Inspect="Denetle" -DevTools="'%1' Tarayıcı Yuvasını Denetle" +RerouteAudio="OBS ile sesi denetle" +Inspect="İncele" +DevTools="'%1' Tarayıcı Yuvasını İncele" CopyUrl="Geçerli adresi kopyala" -WebpageControlLevel="Sayfa İzinleri" +WebpageControlLevel="Sayfa izinleri" WebpageControlLevel.Level.None="OBS'ye erişim yok" WebpageControlLevel.Level.ReadObs="OBS'ye erişme durumu bilgilerini okuma" WebpageControlLevel.Level.ReadUser="Kullanıcıya erişme bilgilerini okuma (anlık Sahne Koleksiyonu, Geçişler)" @@ -22,8 +22,8 @@ Dialog.Alert="JavaScript Uyarısı" Dialog.Confirm="JavaScript Onayla" Dialog.Prompt="JavaScript İstemi" -Dialog.BrowserDock="Tarayıcı Dock" -Dialog.ReceivedFrom="Alındığı yer '%1'" +Dialog.BrowserDock="Tarayıcı Paneli" +Dialog.ReceivedFrom="Alındığı yer: '%1'" Error.Title="Sayfa yüklenemedi!" Error.Description="Adresin doğruluğunu ve sitenin sorunları olmadığından emin olun." Error.Retry="Yeniden denemek için buraya tıklayın" @@ -39,6 +39,6 @@ ErrorCode.ERR_FILE_NOT_FOUND="Dosya bulunamadı" ErrorCode.ERR_FAILED="Bağlantı kurulamadı" ErrorCode.ERR_NETWORK_CHANGED="Ağ değişti" -ErrorCode.ERR_SSL_VERSION_INTERFERENCE="SSL versiyon arayüzü. TLS 1.3 engellenmiş veya düzenlenmiş olabilir." +ErrorCode.ERR_SSL_VERSION_INTERFERENCE="SSL sürüm çakışması. TLS 1.3 engellenmiş veya düzenlenmiş olabilir." ErrorCode.ERR_SSL_PROTOCOL_ERROR="SSL protokol hatası. Güvenli iletişim sağlanamadı." ErrorCode.ERR_CERT_DATE_INVALID="Sunucunun SSL sertifikası güncel değil veya bilgisayarınızın saati yanlış."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/data/locale/uk-UA.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/data/locale/uk-UA.ini
Changed
@@ -2,6 +2,7 @@ URL="URL-адреса" Width="Ширина" Height="Висота" +FPS="Кадрів в секунду" CSS="Власний CSS" ShutdownSourceNotVisible="Вимикати джерело, коли воно не видиме" RefreshBrowserActive="Оновити браузер, коли сцена стає активною"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/data/locale/ur-PK.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/data/locale/ur-PK.ini
Changed
@@ -10,6 +10,9 @@ BrowserSource="براؤزر" CustomFrameRate="حسب ضرورت فریم ریٹ استعمال کریں" RerouteAudio="OBS کے ذریعے آڈیو کو کنٹرول کریں" +Inspect="معائنہ کرنا" +DevTools="براؤزر ڈاک '%1' کا معائنہ کریں" +CopyUrl="موجودہ پتہ کاپی کریں" WebpageControlLevel="صفحہ کی اجازت" WebpageControlLevel.Level.None="OBS تک رسائی نہیں ہے" WebpageControlLevel.Level.ReadObs="OBS کی حیثیت کی معلومات تک رسائی پڑھیں" @@ -27,6 +30,9 @@ Error.Retry="دوبارہ کوشش کرنے کے لیے یہاں کلک کریں" Error.Code="خرابی: %1" Error.URL="یو آر ایل: %2" +Zoom.Reset="زوم ری سیٹ کریں" +Zoom.Out="زوم آؤٹ" +Zoom.In="زوم اِن" ErrorCode.ERR_CONNECTION_REFUSED="سرور نے کنکشن سے انکار کر دیا" ErrorCode.ERR_NAME_NOT_RESOLVED="سرور کا IP پتہ نہیں ملا" ErrorCode.ERR_CONNECTION_TIMED_OUT="کنکشن کا وقت ختم ہوگیا"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/deps/wide-string.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/deps/wide-string.cpp
Changed
@@ -23,14 +23,16 @@ wstring to_wide(const char *utf8) { - if (!utf8 || !*utf8) + if (!utf8 || !*utf8) { return wstring(); + } size_t isize = strlen(utf8); size_t osize = os_utf8_to_wcs(utf8, isize, nullptr, 0); - if (!osize) + if (!osize) { return wstring(); + } wstring wide; wide.resize(osize); @@ -40,13 +42,15 @@ wstring to_wide(const std::string &utf8) { - if (utf8.empty()) + if (utf8.empty()) { return wstring(); + } size_t osize = os_utf8_to_wcs(utf8.c_str(), utf8.size(), nullptr, 0); - if (!osize) + if (!osize) { return wstring(); + } wstring wide; wide.resize(osize);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/drm-format.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/drm-format.cpp
Changed
@@ -28,13 +28,15 @@ enum gs_dmabuf_flags dmabuf_flags; BPtr<uint32_t> drm_formats; - if (!gs_query_dmabuf_capabilities(&dmabuf_flags, &drm_formats, &n_formats)) + if (!gs_query_dmabuf_capabilities(&dmabuf_flags, &drm_formats, &n_formats)) { return false; + } for (size_t i = 0; i < n_formats; i++) { for (size_t j = 0; j < N_SUPPORTED_FORMATS; j++) { - if (drm_formatsi != supported_formatsj.drm_format) + if (drm_formatsi != supported_formatsj.drm_format) { continue; + } blog(LOG_DEBUG, "obs-browser: CEF color type %s supported", supported_formatsj.pretty_name); n_supported++; @@ -47,8 +49,9 @@ struct obs_cef_video_format obs_cef_format_from_cef_type(cef_color_type_t cef_type) { for (size_t i = 0; i < N_SUPPORTED_FORMATS; i++) { - if (supported_formatsi.cef_type == cef_type) + if (supported_formatsi.cef_type == cef_type) { return supported_formatsi; + } } blog(LOG_ERROR, "obs-browser: Unsupported CEF color format (%d)", cef_type);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/obs-browser-page/obs-browser-page-main.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/obs-browser-page/obs-browser-page-main.cpp
Changed
@@ -85,8 +85,9 @@ CefMainArgs mainArgs(nullptr); #if CHROME_VERSION_BUILD < 5615 - if (!SetHighDPIv2Scaling()) + if (!SetHighDPIv2Scaling()) { CefEnableHighDPISupport(); + } #endif CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine(); @@ -109,8 +110,9 @@ { #if defined(__APPLE__) && !defined(ENABLE_BROWSER_LEGACY) CefScopedLibraryLoader library_loader; - if (!library_loader.LoadInHelper()) + if (!library_loader.LoadInHelper()) { return 1; + } #endif CefMainArgs mainArgs(argc, argv); #endif
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/obs-browser-plugin.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/obs-browser-plugin.cpp
Changed
@@ -79,6 +79,20 @@ bool hwaccel = false; +namespace { +// Naive conversions between char* (Ex. from libobs) and filesystem::path using the platform codepage. +std::filesystem::path pathFromUtf8(const char *path) +{ + return std::filesystem::path{reinterpret_cast<const char8_t *>(path)}; +} + +std::string utf8BytesFromPath(std::filesystem::path path) +{ + const std::u8string u8 = path.u8string(); + return std::string{u8.begin(), u8.end()}; +} +} // namespace + /* ========================================================================= */ #ifdef ENABLE_BROWSER_QT_LOOP @@ -173,8 +187,9 @@ dstr_copy(path, bs->url.c_str()); dstr_replace(path, "\\", "/"); slash = strrchr(path->array, '/'); - if (slash) + if (slash) { dstr_resize(path, slash - path->array + 1); + } } obs_property_set_modified_callback(prop, is_local_file_modified); @@ -293,6 +308,9 @@ CefString(&settings.log_file) = log_path_abs; settings.windowless_rendering_enabled = true; settings.no_sandbox = true; +#if CHROME_VERSION_BUILD > 6533 && CHROME_VERSION_BUILD <= 6613 + settings.chrome_runtime = true; +#endif uint32_t obs_ver = obs_get_version(); uint32_t obs_maj = obs_ver >> 24; @@ -341,6 +359,9 @@ settings.persist_user_preferences = 1; #endif CefString(&settings.cache_path) = conf_path_abs; +#if CHROME_VERSION_BUILD > 6533 + CefString(&settings.root_cache_path) = conf_path_abs; +#endif #if !defined(__APPLE__) || defined(ENABLE_BROWSER_LEGACY) char *abs_path = os_get_abs_path_ptr(path.c_str()); CefString(&settings.browser_subprocess_path) = abs_path; @@ -488,8 +509,9 @@ }; info.activate = (void *data) { BrowserSource *bs = static_cast<BrowserSource *>(data); - if (bs->restart) + if (bs->restart) { bs->Refresh(); + } bs->SetActive(true); }; info.deactivate = (void *data) { @@ -560,12 +582,14 @@ case OBS_FRONTEND_EVENT_SCENE_CHANGED: { OBSSourceAutoRelease source = obs_frontend_get_current_scene(); - if (!source) + if (!source) { break; + } const char *name = obs_source_get_name(source); - if (!name) + if (!name) { break; + } nlohmann::json json = {{"name", name}, {"width", obs_source_get_width(source)}, @@ -591,12 +615,14 @@ case OBS_FRONTEND_EVENT_TRANSITION_CHANGED: { OBSSourceAutoRelease source = obs_frontend_get_current_transition(); - if (!source) + if (!source) { break; + } const char *name = obs_source_get_name(source); - if (!name) + if (!name) { break; + } nlohmann::json json = {{"name", name}}; @@ -633,22 +659,26 @@ UINT i = 0; hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)&factory); - if (FAILED(hr)) + if (FAILED(hr)) { return; + } while (factory->EnumAdapters1(i++, &adapter) == S_OK) { DXGI_ADAPTER_DESC desc; hr = adapter->GetDesc(&desc); - if (FAILED(hr)) + if (FAILED(hr)) { continue; + } - if (i == 1) + if (i == 1) { deviceId = desc.Description; + } /* ignore Microsoft's 'basic' renderer' */ - if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c) + if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c) { continue; + } adapterCount++; } @@ -696,8 +726,9 @@ glVersion = gs_get_driver_version(); obs_leave_graphics(); - if (!glVersion) + if (!glVersion) { return; + } if (strstr(glVersion, "NVIDIA") != NULL) { hwaccel = false; @@ -714,8 +745,121 @@ #endif #endif +#if CHROME_VERSION_BUILD > 6533 +static void MigrateProfileConfigDir(filesystem::path oldDir, filesystem::path newDir, bool makeDirs) +{ + namespace fs = std::filesystem; + + BPtr<char> configPath = obs_module_config_path("."); + fs::path rootPath{pathFromUtf8(configPath.Get())}; + + fs::path oldPath = rootPath / oldDir; + fs::path newPath = rootPath / newDir; + + if (!fs::exists(oldPath)) { + return; + } + + try { + if (makeDirs && !fs::exists(newPath)) { + fs::create_directories(newPath); + } + const auto copyOptions = fs::copy_options::recursive; + fs::copy(oldPath, newPath, copyOptions); + } catch (const fs::filesystem_error &error) { + blog(LOG_WARNING, "obs-browser: Error migrating cookies for '%s': %s", oldPath.c_str(), error.what()); + } +} + +static void MigrateDefaultProfileSubdirs(filesystem::path parent, bool makeDirs) +{ + namespace fs = std::filesystem; + + constexpr std::array<std::u8string_view, 3> kMigrationDirectories{ + u8"Local Storage", + u8"Session Storage", + u8"Network", + }; + constexpr std::u8string_view kDefaultDirectoryPrefix{u8"Default"}; + + for (std::u8string_view directory : kMigrationDirectories) { + fs::path oldDirectory = parent / directory; + fs::path newDirectory = parent / kDefaultDirectoryPrefix / directory; + + MigrateProfileConfigDir(oldDirectory, newDirectory, makeDirs); + } +} + +static void MigrateToChromeRuntime() +{ + namespace fs = std::filesystem; + BPtr<char> defaultConfigPath = obs_module_config_path("Default"); + fs::path defaultPath{pathFromUtf8(defaultConfigPath.Get())}; + // User has already previously launched with Chrome Runtime + if (fs::exists(defaultPath)) { + blog(LOG_INFO, "obs-browser: Chrome Runtime Default profile detected. No migration necessary."); + return; + } + + BPtr<char> localPrefsConfigPath = obs_module_config_path("LocalPrefs.json"); + fs::path localPrefs{pathFromUtf8(localPrefsConfigPath.Get())}; + // User has never launched old OBS Browser before + if (!fs::exists(localPrefs)) { + blog(LOG_DEBUG, "obs-browser: Alloy Runtime preferences not found. No migration necessary."); + return; + } + + blog(LOG_INFO, "obs-browser: Migrating files to Chrome Runtime..."); + + try { + fs::create_directories(defaultPath); + } catch (const fs::filesystem_error &error) { + blog(LOG_WARNING, "obs-browser: Error creating Default profile: %s", error.what()); + } + + MigrateDefaultProfileSubdirs("", false); + + BPtr<char> newLocalPrefsConfigPath = obs_module_config_path("Local State"); + fs::path newLocalPrefs{pathFromUtf8(newLocalPrefsConfigPath.Get())}; + try { + fs::copy(localPrefs, newLocalPrefs); + } catch (const fs::filesystem_error &error) { + blog(LOG_WARNING, "obs-browser: Error migrating preferences: %s", error.what()); + } + + constexpr std::string_view prefix = "obs_profile_cookies"; + + BPtr<char> serviceProfilesPath = obs_module_config_path(prefix.data()); + fs::path serviceProfiles{pathFromUtf8(serviceProfilesPath.Get())}; + if (fs::exists(serviceProfiles)) { + // User has service integration cookies that also must be copied + for (auto const &dir_entry : std::filesystem::directory_iterator{serviceProfiles}) { + if (!dir_entry.is_directory()) { + continue; + } + fs::path name{dir_entry.path().filename()}; + + fs::path oldDir = fs::path{prefix} / name; + + fs::path newDir{prefix}; + newDir += "_"; + newDir += name; + + MigrateProfileConfigDir(oldDir, newDir, true); + + blog(LOG_INFO, "obs-browser: Migrated cookies for %s.", utf8BytesFromPath(name).c_str()); + } + } + + blog(LOG_INFO, "obs-browser: Migration of browser cookies and session completed."); +} +#endif + bool obs_module_load(void) { +#if CHROME_VERSION_BUILD > 6533 + MigrateToChromeRuntime(); +#endif #ifdef ENABLE_BROWSER_QT_LOOP qRegisterMetaType<MessageTask>("MessageTask"); #endif @@ -733,8 +877,9 @@ #if defined(__APPLE__) && !defined(ENABLE_BROWSER_LEGACY) /* Load CEF at runtime as required on macOS */ CefScopedLibraryLoader library_loader; - if (!library_loader.LoadInMain()) + if (!library_loader.LoadInMain()) { return false; + } #endif #endif blog(LOG_INFO, "obs-browser: Version %s", OBS_BROWSER_VERSION_STRING); @@ -759,13 +904,15 @@ void obs_module_post_load(void) { auto vendor = obs_websocket_register_vendor("obs-browser"); - if (!vendor) + if (!vendor) { return; + } auto emit_event_request_cb = (obs_data_t *request_data, obs_data_t *, void *) { const char *event_name = obs_data_get_string(request_data, "event_name"); - if (!event_name) + if (!event_name) { return; + } OBSDataAutoRelease event_data = obs_data_get_obj(request_data, "event_data"); const char *event_data_string = event_data ? obs_data_get_json(event_data) : "{}"; @@ -773,8 +920,9 @@ DispatchJSEvent(event_name, event_data_string, nullptr); }; - if (!obs_websocket_vendor_register_request(vendor, "emit_event", emit_event_request_cb, nullptr)) + if (!obs_websocket_vendor_register_request(vendor, "emit_event", emit_event_request_cb, nullptr)) { blog(LOG_WARNING, "obs-browser: Failed to register obs-websocket request emit_event"); + } } void obs_module_unload(void) @@ -783,8 +931,9 @@ BrowserShutdown(); #else if (manager_thread.joinable()) { - if (!QueueCEFTask(() { CefQuitMessageLoop(); })) + if (!QueueCEFTask(() { CefQuitMessageLoop(); })) { blog(LOG_DEBUG, "obs-browser: Failed to post CefQuit task to loop"); + } manager_thread.join(); }
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/obs-browser-source.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/obs-browser-source.cpp
Changed
@@ -51,8 +51,9 @@ static void SendBrowserVisibility(CefRefPtr<CefBrowser> browser, bool isVisible) { - if (!browser) + if (!browser) { return; + } if (isVisible) { browser->GetHost()->WasResized(); @@ -86,11 +87,13 @@ auto jsEventFunction = (void *p, calldata_t *calldata) { const auto eventName = calldata_string(calldata, "eventName"); - if (!eventName) + if (!eventName) { return; + } auto jsonString = calldata_string(calldata, "jsonString"); - if (!jsonString) + if (!jsonString) { jsonString = "null"; + } DispatchJSEvent(eventName, jsonString, (BrowserSource *)p); }; @@ -104,8 +107,9 @@ lock_guard<mutex> lock(browser_list_mutex); p_prev_next = &first_browser; next = first_browser; - if (first_browser) + if (first_browser) { first_browser->p_prev_next = &next; + } first_browser = this; } @@ -128,8 +132,9 @@ BrowserSource::~BrowserSource() { - if (cefBrowser) + if (cefBrowser) { ActuallyCloseBrowser(cefBrowser); + } } void BrowserSource::Destroy() @@ -138,8 +143,9 @@ DestroyTextures(); lock_guard<mutex> lock(browser_list_mutex); - if (next) + if (next) { next->p_prev_next = p_prev_next; + } *p_prev_next = next; QueueCEFTask(this() { delete this; }); @@ -150,16 +156,18 @@ if (!async) { #ifdef ENABLE_BROWSER_QT_LOOP if (QThread::currentThread() == qApp->thread()) { - if (!!cefBrowser) + if (!!cefBrowser) { func(cefBrowser); + } return; } #endif os_event_t *finishedEvent; os_event_init(&finishedEvent, OS_EVENT_TYPE_AUTO); bool success = QueueCEFTask(&() { - if (!!cefBrowser) + if (!!cefBrowser) { func(cefBrowser); + } os_event_signal(finishedEvent); }); if (success) { @@ -310,8 +318,9 @@ void BrowserSource::SendKeyClick(const struct obs_key_event *event, bool key_up) { - if (destroying) + if (destroying) { return; + } std::string text = event->text; #ifdef __linux__ @@ -363,8 +372,9 @@ void BrowserSource::SetShowing(bool showing) { - if (destroying) + if (destroying) { return; + } is_showing = showing; @@ -394,8 +404,9 @@ SendBrowserVisibility(cefBrowser, showing); - if (showing) + if (showing) { return; + } obs_enter_graphics(); @@ -489,15 +500,18 @@ size_t slash = n_url.find("%2F"); size_t colon = n_url.find("%3A"); - if (slash != std::string::npos && colon != std::string::npos && colon < slash) + if (slash != std::string::npos && colon != std::string::npos && colon < slash) { n_url.replace(colon, 3, ":"); + } #endif - while (n_url.find("%5C") != std::string::npos) + while (n_url.find("%5C") != std::string::npos) { n_url.replace(n_url.find("%5C"), 3, "/"); + } - while (n_url.find("%2F") != std::string::npos) + while (n_url.find("%2F") != std::string::npos) { n_url.replace(n_url.find("%2F"), 3, "/"); + } // Local files are routed through our custom scheme handler to give them acess to other local files n_url = "http://absolute/" + n_url; @@ -507,8 +521,9 @@ n_shutdown == shutdown_on_invisible && n_restart == restart && n_css == css && n_url == url && n_reroute == reroute_audio && n_webpage_control_level == webpage_control_level) { - if (n_width == width && n_height == height) + if (n_width == width && n_height == height) { return; + } width = n_width; height = n_height; @@ -542,23 +557,27 @@ DestroyBrowser(); DestroyTextures(); - if (!shutdown_on_invisible || obs_source_showing(source)) + if (!shutdown_on_invisible || obs_source_showing(source)) { create_browser = true; + } first_update = false; } void BrowserSource::Tick() { - if (os_event_try(cef_started_event) != 0) + if (os_event_try(cef_started_event) != 0) { return; + } - if (create_browser && CreateBrowser()) + if (create_browser && CreateBrowser()) { create_browser = false; + } #if defined(ENABLE_BROWSER_SHARED_TEXTURE) #if defined(BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED) - if (!fps_custom) + if (!fps_custom) { reset_frame = true; + } #else struct obs_video_info ovi; obs_get_video_info(&ovi); @@ -624,8 +643,9 @@ } const uint32_t flip_flag = flip ? GS_FLIP_V : 0; - while (gs_effect_loop(effect, tech)) + while (gs_effect_loop(effect, tech)) { gs_draw_sprite(draw_texture, flip_flag, 0, 0); + } gs_blend_state_pop(); @@ -672,8 +692,9 @@ SendBrowserProcessMessage(cefBrowser, PID_RENDERER, msg); }; - if (!browser) + if (!browser) { ExecuteOnAllBrowsers(jsEvent); - else + } else { ExecuteOnBrowser(jsEvent, browser); + } }
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/panel/browser-panel-client.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/panel/browser-panel-client.cpp
Changed
@@ -38,6 +38,18 @@ return this; } +#if CHROME_VERSION_BUILD >= 6533 +CefRefPtr<CefCommandHandler> QCefBrowserClient::GetCommandHandler() +{ + return this; +} + +CefRefPtr<CefPermissionHandler> QCefBrowserClient::GetPermissionHandler() +{ + return this; +} +#endif + CefRefPtr<CefRequestHandler> QCefBrowserClient::GetRequestHandler() { return this; @@ -68,20 +80,42 @@ return this; } +/* CefCommandHandler */ +#if CHROME_VERSION_BUILD >= 6533 +bool QCefBrowserClient::OnChromeCommand(CefRefPtr<CefBrowser>, int, cef_window_open_disposition_t) +{ + return true; +} + +/* CefPermissionHandler */ +bool QCefBrowserClient::OnShowPermissionPrompt(CefRefPtr<CefBrowser>, uint64_t, const CefString &, + uint32_t requested_permissions, + CefRefPtr<CefPermissionPromptCallback> callback) +{ + // Implicitly allow Localhost access to retain previous behavior for now + if ((requested_permissions & CEF_PERMISSION_TYPE_LOOPBACK_NETWORK) != 0) { + callback->Continue(CEF_PERMISSION_RESULT_ACCEPT); + return true; + } + return false; +} +#endif + /* CefDisplayHandler */ void QCefBrowserClient::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString &title) { - if (widget && widget->cefBrowser->IsSame(browser)) { + if (widget && widget->cefBrowser && widget->cefBrowser->IsSame(browser)) { std::string str_title = title; QString qt_title = QString::fromUtf8(str_title.c_str()); QMetaObject::invokeMethod(widget, "titleChanged", Q_ARG(QString, qt_title)); } else { /* handle popup title */ CefString newTitle = title; - if (title.compare("DevTools") == 0 && widget) + if (title.compare("DevTools") == 0 && widget) { newTitle = QString(obs_module_text("DevTools")) .arg(widget->parentWidget()->windowTitle()) .toUtf8() .constData(); + } #if defined(_WIN32) CefWindowHandle handl = browser->GetHost()->GetWindowHandle(); @@ -141,8 +175,9 @@ const CefString &failedUrl) { UNUSED_PARAMETER(browser); - if (errorCode == ERR_ABORTED) + if (errorCode == ERR_ABORTED) { return; + } struct dstr html; char *path = obs_module_file("error.html"); @@ -327,8 +362,9 @@ CefRefPtr<CefContextMenuParams> params, int command_id, CefContextMenuHandler::EventFlags) { - if (command_id < MENU_ID_CUSTOM_FIRST) + if (command_id < MENU_ID_CUSTOM_FIRST) { return false; + } CefRefPtr<CefBrowserHost> host = browser->GetHost(); CefWindowInfo windowInfo; QPoint pos; @@ -377,8 +413,9 @@ void QCefBrowserClient::OnLoadStart(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame> frame, TransitionType) { - if (!frame->IsMain()) + if (!frame->IsMain()) { return; + } std::string script = "window.close = () => "; script += "console.log("; @@ -389,13 +426,15 @@ void QCefBrowserClient::OnLoadEnd(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame> frame, int) { - if (!frame->IsMain()) + if (!frame->IsMain()) { return; + } - if (widget && !widget->script.empty()) + if (widget && !widget->script.empty()) { frame->ExecuteJavaScript(widget->script, CefString(), 0); - else if (!script.empty()) + } else if (!script.empty()) { frame->ExecuteJavaScript(script, CefString(), 0); + } } bool QCefBrowserClient::OnJSDialog(CefRefPtr<CefBrowser>, const CefString &, @@ -419,8 +458,9 @@ std::stringstream title; title << obs_module_text("Dialog.Prompt") << ": " << obs_module_text("Dialog.BrowserDock"); dlg->setWindowTitle(title.str().c_str()); - if (!default_value.empty()) + if (!default_value.empty()) { dlg->setTextValue(default_value.c_str()); + } auto finished = callback, dlg(int result) { callback.get()->Continue(result == QDialog::Accepted, @@ -474,8 +514,9 @@ bool QCefBrowserClient::OnPreKeyEvent(CefRefPtr<CefBrowser> browser, const CefKeyEvent &event, CefEventHandle, bool *) { - if (event.type != KEYEVENT_RAWKEYDOWN) + if (event.type != KEYEVENT_RAWKEYDOWN) { return false; + } if (event.windows_key_code == 'R' && #ifdef __APPLE__
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/panel/browser-panel-client.hpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/panel/browser-panel-client.hpp
Changed
@@ -7,6 +7,10 @@ class QCefBrowserClient : public CefClient, public CefDisplayHandler, +#if CHROME_VERSION_BUILD >= 6533 + public CefCommandHandler, + public CefPermissionHandler, +#endif public CefRequestHandler, public CefLifeSpanHandler, public CefContextMenuHandler, @@ -26,6 +30,10 @@ /* CefClient */ virtual CefRefPtr<CefLoadHandler> GetLoadHandler() override; virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() override; +#if CHROME_VERSION_BUILD >= 6533 + virtual CefRefPtr<CefCommandHandler> GetCommandHandler() override; + virtual CefRefPtr<CefPermissionHandler> GetPermissionHandler() override; +#endif virtual CefRefPtr<CefRequestHandler> GetRequestHandler() override; virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override; virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() override; @@ -33,6 +41,18 @@ virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override; virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() override; + /* CefCommandHandler */ +#if CHROME_VERSION_BUILD >= 6533 + virtual bool OnChromeCommand(CefRefPtr<CefBrowser> browser, int command_id, + cef_window_open_disposition_t disposition) override; + + /* CefPermissionHandler */ + virtual bool OnShowPermissionPrompt(CefRefPtr<CefBrowser> browser, uint64_t prompt_id, + const CefString &requesting_origin, uint32_t requested_permissions, + CefRefPtr<CefPermissionPromptCallback> callback) override; + +#endif + /* CefDisplayHandler */ virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString &title) override;
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/panel/browser-panel.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/panel/browser-panel.cpp
Changed
@@ -102,12 +102,14 @@ QCefCookieManagerInternal(const std::string &storage_path, bool persist_session_cookies) { - if (os_event_try(cef_started_event) != 0) + if (os_event_try(cef_started_event) != 0) { throw "Browser thread not initialized"; + } BPtr<char> rpath = obs_module_config_path(storage_path.c_str()); - if (os_mkdirs(rpath.Get()) == MKDIR_ERROR) + if (os_mkdirs(rpath.Get()) == MKDIR_ERROR) { throw "Failed to create cookie directory"; + } BPtr<char> path = os_get_abs_path_ptr(rpath.Get()); @@ -117,8 +119,9 @@ #endif CefString(&settings.cache_path) = path.Get(); rc = CefRequestContext::CreateContext(settings, CefRefPtr<CefRequestContextHandler>()); - if (rc) + if (rc) { cm = rc->GetCookieManager(nullptr); + } UNUSED_PARAMETER(persist_session_cookies); } @@ -139,8 +142,9 @@ #endif CefString(&settings.cache_path) = storage_path; rc = CefRequestContext::CreateContext(settings, CefRefPtr<CefRequestContextHandler>()); - if (rc) + if (rc) { cm = rc->GetCookieManager(nullptr); + } UNUSED_PARAMETER(persist_session_cookies); return true; @@ -151,8 +155,9 @@ virtual void CheckForCookie(const std::string &site, const std::string &cookie, cookie_exists_cb callback) override { - if (!cm) + if (!cm) { return; + } CefRefPtr<CookieCheck> c = new CookieCheck(callback, cookie); cm->VisitUrlCookies(site, false, c); @@ -243,11 +248,13 @@ unsigned char *data = NULL; if (XGetWindowProperty(display, w, a, 0, LONG_MAX, False, AnyPropertyType, &type, &format, &nItems, &bytesAfter, - &data) != Success) + &data) != Success) { return false; + } - if (data) + if (data) { XFree(data); + } return type != None; } @@ -261,8 +268,9 @@ */ void QCefWidgetInternal::unsetToplevelXdndProxy() { - if (!cefBrowser) + if (!cefBrowser) { return; + } CefWindowHandle browserHandle = cefBrowser->GetHost()->GetWindowHandle(); Display *xDisplay = cef_get_xdisplay(); @@ -275,11 +283,13 @@ // Find the toplevel Atom netWmPidAtom = XInternAtom(xDisplay, "_NET_WM_PID", False); do { - if (XQueryTree(xDisplay, toplevel, &root, &parent, &children, &nChildren) == 0) + if (XQueryTree(xDisplay, toplevel, &root, &parent, &children, &nChildren) == 0) { return; + } - if (children) + if (children) { XFree(children); + } if (root == parent || !XWindowHasAtom(xDisplay, parent, netWmPidAtom)) { found = true; @@ -288,8 +298,9 @@ toplevel = parent; } while (true); - if (!found) + if (!found) { return; + } // Check if the XdndProxy property is set Atom xDndProxyAtom = XInternAtom(xDisplay, "XdndProxy", False); @@ -320,8 +331,9 @@ CefWindowInfo windowInfo; /* Make sure Init isn't called more than once. */ - if (cefBrowser) + if (cefBrowser) { return; + } #ifdef __APPLE__ QSize size = this->size(); @@ -368,16 +380,22 @@ void QCefWidgetInternal::Resize() { + if (os_event_try(cef_started_event) != 0) { + return; + } + QSize size = this->size() * devicePixelRatioF(); bool success = QueueCEFTask(this, size() { - if (!cefBrowser) + if (!cefBrowser) { return; + } CefWindowHandle handle = cefBrowser->GetHost()->GetWindowHandle(); - if (!handle) + if (!handle) { return; + } #ifdef _WIN32 SetWindowPos((HWND)handle, nullptr, 0, 0, size.width(), size.height(), @@ -401,8 +419,9 @@ #endif }); - if (success && container) + if (success && container) { container->resize(size.width(), size.height()); + } #endif } @@ -438,8 +457,9 @@ void QCefWidgetInternal::reloadPage() { - if (cefBrowser) + if (cefBrowser) { cefBrowser->ReloadIgnoreCache(); + } } void QCefWidgetInternal::setStartupScript(const std::string &script_) @@ -449,8 +469,9 @@ void QCefWidgetInternal::executeJavaScript(const std::string &script_) { - if (!cefBrowser) + if (!cefBrowser) { return; + } CefRefPtr<CefFrame> frame = cefBrowser->GetMainFrame(); std::string url = frame->GetURL(); @@ -464,8 +485,9 @@ bool QCefWidgetInternal::zoomPage(int direction) { - if (!cefBrowser || direction < -1 || direction > 1) + if (!cefBrowser || direction < -1 || direction > 1) { return false; + } CefRefPtr<CefBrowserHost> host = cefBrowser->GetHost(); if (direction == 0) { @@ -484,8 +506,9 @@ } zoomIdx++; } - if (zoomIdx == zoomCount) + if (zoomIdx == zoomCount) { return false; + } int newZoomIdx = zoomIdx; if (direction == -1 && zoomIdx > 0) { @@ -526,8 +549,9 @@ bool QCefInternal::init_browser(void) { - if (os_event_try(cef_started_event) == 0) + if (os_event_try(cef_started_event) == 0) { return true; + } obs_browser_initialize(); return false; @@ -550,10 +574,31 @@ return new QCefWidgetInternal(parent, url, cmi ? cmi->rc : nullptr); } +namespace { +std::string getUpdatedCookiePath(std::string storagePath) +{ + constexpr std::string_view searchToken{"obs_profile_cookies/"}; + constexpr std::string_view replaceToken{"obs_profile_cookies_"}; + + size_t pos = storagePath.find(searchToken); + if (pos != std::string::npos) { + storagePath.replace(pos, searchToken.length(), replaceToken); + } + + return storagePath; +} +} // namespace + QCefCookieManager *QCefInternal::create_cookie_manager(const std::string &storage_path, bool persist_session_cookies) { + std::string path = storage_path; +#if CHROME_VERSION_BUILD > 6533 + // TODO: Update obs-studio to use the new path structure due to subdirectories not being supported by CEF + // https://github.com/obsproject/obs-studio/issues/13498 + path = getUpdatedCookiePath(storage_path); +#endif try { - return new QCefCookieManagerInternal(storage_path, persist_session_cookies); + return new QCefCookieManagerInternal(path, persist_session_cookies); } catch (const char *error) { blog(LOG_ERROR, "Failed to create cookie manager: %s", error); return nullptr; @@ -562,7 +607,13 @@ BPtr<char> QCefInternal::get_cookie_path(const std::string &storage_path) { - BPtr<char> rpath = obs_module_config_path(storage_path.c_str()); + std::string path = storage_path; +#if CHROME_VERSION_BUILD > 6533 + // TODO: Update obs-studio to use the new path structure due to subdirectories not being supported by CEF + // https://github.com/obsproject/obs-studio/issues/13498 + path = getUpdatedCookiePath(storage_path); +#endif + BPtr<char> rpath = obs_module_config_path(path.c_str()); return os_get_abs_path_ptr(rpath.Get()); }
View file
obs-studio-32.2.2.tar.xz/plugins/obs-browser/panel/browser-panel.hpp -> obs-studio-33.0.0.tar.xz/plugins/obs-browser/panel/browser-panel.hpp
Changed
@@ -78,13 +78,15 @@ #ifdef ENABLE_WAYLAND isWayland = obs_get_nix_platform() == OBS_NIX_PLATFORM_WAYLAND; #endif - if (isWayland) + if (isWayland) { return nullptr; + } obs_module_t *browserModule = obs_get_module("obs-browser"); - if (!browserModule) + if (!browserModule) { return nullptr; + } return obs_get_module_lib(browserModule); } @@ -94,13 +96,15 @@ void *lib = get_browser_lib(); QCef *(*create_qcef)(void) = nullptr; - if (!lib) + if (!lib) { return nullptr; + } create_qcef = (decltype(create_qcef))os_dlsym(lib, "obs_browser_create_qcef"); - if (!create_qcef) + if (!create_qcef) { return nullptr; + } return create_qcef(); } @@ -110,13 +114,15 @@ void *lib = get_browser_lib(); int (*qcef_version)(void) = nullptr; - if (!lib) + if (!lib) { return 0; + } qcef_version = (decltype(qcef_version))os_dlsym(lib, "obs_browser_qcef_version_export"); - if (!qcef_version) + if (!qcef_version) { return 0; + } return qcef_version(); }
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/af-ZA.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/af-ZA.ini
Changed
@@ -60,7 +60,6 @@ MediaFileFilter.AudioFiles="Oudiolêers" MediaFileFilter.AllFiles="Alle lêers" ReplayBuffer="Kykweerbuffer" -ReplayBuffer.Save="Bewaar kykweer" HelperProcessFailed="Kan nie die opnamehulpproses begin nie. Gaan na dat OBS-lêers nie versper of deur enige derdeparty-antivirus / sekuriteitsprogrammatuur verwyder is nie." UnableToWritePath="Kan nie na %1 skryf nie. Gaan na of u ’n opnamepad gebruik waar u gebruikersrekening na kan skryf, en dat daar voldoende skyfspasie beskikbaar is." WarnWindowsDefender="Indien Windows 10 Ransomware Protection geaktiveer is, kan dit ook die fout veroorsaak. Probeer beheerde vouertoegang in Windows Security / Virus & Threat Protection se instellings deaktiveer."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ar-SA.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ar-SA.ini
Changed
@@ -81,7 +81,6 @@ MediaFileFilter.AudioFiles="ملفات الصوت" MediaFileFilter.AllFiles="كل الملفات" ReplayBuffer="إعادة التخزين المؤقت" -ReplayBuffer.Save="حفظ الإعادة" HelperProcessFailed="غير قادر على بدء عملية مساعد التسجيل. تحقق من أن ملفات OBS لم يتم حظرها أو إزالتها من قبل أي طرف ثالث لمكافحة الفيروسات / برمجيات الأمان." UnableToWritePath="غير قادر على الكتابة إلى %1. تأكد من أنك تستخدم مسار تسجيل يسمح لحسابك بكتابته وأن هناك مساحة كافية في القرص." WarnWindowsDefender="إذا تم تمكين Windows 10 حماية البرنامج الرانسومي فإنه يمكن أيضا أن يسبب هذا الخطأ. حاول إيقاف الوصول إلى المجلد المتحكم به في إعدادات الحماية من التهديدات لنظام التشغيل Windows Security / Virus."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/az-AZ.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/az-AZ.ini
Changed
@@ -75,7 +75,6 @@ MediaFileFilter.AudioFiles="Səs Faylları" MediaFileFilter.AllFiles="Bütün Fayllar" ReplayBuffer="Təkrar Oxutma Buferi" -ReplayBuffer.Save="Təkrar Oxutmanı Saxla" HelperProcessFailed="Yazı köməkçi prosesini başlatmaq mümkün olmadı. OBS fayllarının hər hansı kənar antivirus / təhlükəsizlik proqramı tərəfindən bloklanmadığını və ya silinmədiyini yoxlayın." UnableToWritePath="%1 ünvanına yazmaq mümkün olmadı. İstifadəçi hesabınızın yazmağa icazəsi olan bir qeyd yolu istifadə etdiyinizdən və kifayət qədər disk sahəsi olduğundan əmin olun." WarnWindowsDefender="Əgər Windows 10-un Ransomware Protection funksiyası aktivdirsə, bu da xətaya səbəb ola bilər. Windows Təhlükəsizliyi / Virus və təhdidlərdən qorunma ayarlarında \"Nəzarət edilən qovluq girişi\" funksiyasını deaktiv etməyi yoxlayın."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/be-BY.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/be-BY.ini
Changed
@@ -81,7 +81,6 @@ MediaFileFilter.AudioFiles="Аўдыяфайлы" MediaFileFilter.AllFiles="Усе файлы" ReplayBuffer="Буфер паўтору" -ReplayBuffer.Save="Захаваць паўтор" HelperProcessFailed="Не атрымалася запусціць працэс дапаможніка запісу. Пераканайцеся, што файлы OBS не былі заблакіраваны або выдалены антывіруснай праграмай." UnableToWritePath="Не атрымалася запісаць у %1. Пераканайцеся, што ў якасці шляху запісу быў зададзены каталог, запіс у які дазволены вашаму ўліковаму запісу або праверце месца на дыску." WarnWindowsDefender="Гэтую памылку таксама магла выклікаць уключаная абарона ад праграм-шантажыстаў Windows 10. Паспрабуйце выключыць кантралюемы доступ да папак у наладах абароны ад вірусаў і пагроз у праграме Windows Security."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/bg-BG.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/bg-BG.ini
Changed
@@ -1,8 +1,10 @@ FFmpegOutput="FFmpeg изход" FFmpegOpts="Настройки за FFmpeg" +FFmpegOpts.ToolTip.Source="Позволява ти да зададеш настройки на FFmpeg. Приема само настройки във формата option=value.\nНяколко опции могат да бъдат въведени с разстояние между тях.\nПример: rtsp_transport=tcp rtsp_flags=prefer_tcp" Bitrate="Битрейт" MaxBitrate="Максимален битрейт" Preset="Шаблон" +Tuning="Финна настройка" Profile="Профил" RateControl="Управление на битрейт" KeyframeIntervalSec="Интервал между ключови кадри (0=автоматично)" @@ -21,13 +23,25 @@ NVENC.I010Unsupported="NVENC не поддържа I010. Използвай P010." NVENC.10bitUnsupported="Невъзможно изпъляване на 10-битово кодиране на този кодировчик." NVENC.16bitUnsupported="Невъзможно изпъляване на 16-битово кодиране на този кодировчик." +NVENC.444Unsupported="Невъзможно изпъляване на 4:4:4 кодиране на този кодировчик." +NVENC.Preset2.p1="P1: Най-бързо (Най-ниско качество)" +NVENC.Preset2.p2="P2: По-бързо (по-ниско качество)" +NVENC.Preset2.p3="P3: Бързо (ниско качество)" +NVENC.Preset2.p4="P4: Средно (средно качество)" +NVENC.Preset2.p5="P5: Бавно (добро качество)" +NVENC.Preset2.p6="P6: По-бавно (по-добро качество)" +NVENC.Preset2.p7="P7: Най-бавно (най-добро качество)" NVENC.Tuning.hq="Високо качество" NVENC.Tuning.ll="Ниска латентност" NVENC.Tuning.ull="Много ниска латентност" +NVENC.Multipass.disabled="Единично преминаване" +NVENC.Multipass.qres="Две преминавания (Четвърт резолюция)" +NVENC.Multipass.fullres="Две преминавания (Пълна резолюция)" AMF.Preset.speed="Скорост" AMF.Preset.balanced="Балансирано" AMF.Preset.quality="Качество" AMF.Preset.highQuality="Високо качество" +FFmpegSource="Медия" LocalFile="Локален файл" Looping="Преповтаряне" Input="Вход" @@ -54,7 +68,6 @@ MediaFileFilter.AudioFiles="Звукови файлове" MediaFileFilter.AllFiles="Всички файлове" ReplayBuffer="Буфер за повторение" -ReplayBuffer.Save="Записване на повторението" HelperProcessFailed="Невъзможно зареждане на помощния процес за запис. Проверете дали файловете на OBS не са били блокирани или премахнати от антивирусната или друга защитна програма." UnableToWritePath="Невъзможно записване в %1. Уверете се, че вашият акаунт има права да записва в посочената директория и че имате достатъчно място на твърдия диск." WarnWindowsDefender="Това може да се получава, ако Защитата от рансъмуеър на Windows 10 е включена. Опитайте да изключите контролирания достъп до папки в Windows Security - Virus & threat protection settings"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/bn-BD.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/bn-BD.ini
Changed
@@ -38,7 +38,6 @@ MediaFileFilter.AudioFiles="অডিও ফাইলসমূহ" MediaFileFilter.AllFiles="সকল ফাইল" ReplayBuffer="রিপ্লে বাফার" -ReplayBuffer.Save="রিপ্লে সংরক্ষণ করুন" HelperProcessFailed="রেকর্ডিং সাহায্যকারী প্রক্রিয়া শুরু করতে অক্ষম। OBS ফাইলগুলি কোনও তৃতীয় পক্ষের অ্যান্টিভাইরাস / সুরক্ষা সফ্টওয়্যার দ্বারা অবরুদ্ধ বা সরানো হয়নি তা পরীক্ষা করে দেখুন।" UnableToWritePath="%1 তে লিখতে অক্ষম। নিশ্চিত হয়ে নিন যে আপনি এমন একটি রেকর্ডিং পাথ ব্যবহার করছেন যা আপনার ব্যবহারকারীর অ্যাকাউন্টে লেখার জন্য অনুমোদিত এবং সেখানে পর্যাপ্ত ডিস্কের স্থান রয়েছে।" WarnWindowsDefender="Windows ১০ রানসমওয়্যার সুরক্ষা চালু করা থাকলে এটিও এই ত্রুটি ঘটায়। Windows সুরক্ষা / ভাইরাস এবং হুমকি সুরক্ষা সেটিংসে নিয়ন্ত্রিত ফোল্ডার অ্যাক্সেস বন্ধ করার চেষ্টা করুন।"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ca-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ca-ES.ini
Changed
@@ -81,7 +81,6 @@ MediaFileFilter.AudioFiles="Arxius d'àudio" MediaFileFilter.AllFiles="Tots els fitxers" ReplayBuffer="Memòria intermèdia de reproducció" -ReplayBuffer.Save="Desa la repetició" HelperProcessFailed="No s'ha pogut iniciar el procés d'assistència de gravació. Comproveu que els arxius d'OBS no han estat bloquejats o eliminats per qualsevol programa de seguretat de tercers." UnableToWritePath="No s'ha pogut escriure a %1. Assegureu-vos que utilitzeu una ruta de gravació a la qual el vostre compte d'usuari tingui permisos per escriure i que hi hagi prou espai al disc." WarnWindowsDefender="Si la protecció contra Ransomware del Windows 10 està activada, també pot causar aquest error. Proveu inhabilitant la protecció contra amenaces del Windows a la configuració de seguretat/virus i protecció."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/cs-CZ.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/cs-CZ.ini
Changed
@@ -78,7 +78,6 @@ MediaFileFilter.AudioFiles="Zvukové soubory" MediaFileFilter.AllFiles="Všechny soubory" ReplayBuffer="Záznam do paměti" -ReplayBuffer.Save="Uložit záznam" HelperProcessFailed="Nelze spustit pomocný proces nahrávání. Zkontrolujte prosím, zda nejsou soubory OBS blokovány či odstraněny některý z antivirových programů třetích stran." UnableToWritePath="Nelze zapsat do %1. Zkontrolujte prosím, zda používáte úložiště, do kterého může váš uživatelský účet zapisovat a je zde dostatek volného místa." WarnWindowsDefender="Pokud je zapnuta ochrana proti ransomwaru (Windows 10), může to také způsobit tuto chybu. Zkuste vypnout funkci kontrolovaných složek v nastavení Zabezpečení Windows / Ochrana proti virům."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/da-DK.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/da-DK.ini
Changed
@@ -63,7 +63,6 @@ MediaFileFilter.AudioFiles="Lydfiler" MediaFileFilter.AllFiles="Alle filer" ReplayBuffer="Genafspilningsbuffer" -ReplayBuffer.Save="Gem Genafspilning" HelperProcessFailed="Kan ikke starte optagelseshjælperprocessen. Tjek, at OBS-filer ikke blokeres eller er fjernet af 3. parts antivirus-/sikkerhedssoftware." UnableToWritePath="Kan ikke skrive til %1. Tjek, at du benytter en optagelsessti, som din brugerkonto har skriverettighed til, og at der er tilstrækkelig ledig diskplads." WarnWindowsDefender="Er Windows 10 Ransomware-beskyttelse aktiveret, kan dette også medføre denne fejl. Prøv at deaktivere kontrolleret mappeadgang i Windows-indstillingen Sikkerhed/Virus- og Trusselsbeskyttelse."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/de-DE.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/de-DE.ini
Changed
@@ -77,7 +77,6 @@ MediaFileFilter.AudioFiles="Audiodateien" MediaFileFilter.AllFiles="Alle Dateien" ReplayBuffer="Wiederholungspuffer" -ReplayBuffer.Save="Wiederholung speichern" HelperProcessFailed="Der Aufnahme-Helfer-Prozess kann nicht gestartet werden. Überprüfen Sie, ob OBS-Dateien nicht von einer Drittanbieter-Antiviren-/Sicherheitssoftware blockiert oder entfernt werden." UnableToWritePath="Es kann nicht zu %1 geschrieben werden. Stellen Sie sicher, dass Sie einen Aufnahmepfad verwenden, für den Ihr Konto Schreibrechte hat und genügend Speicherplatz zur Verfügung steht." WarnWindowsDefender="Der Fehler kann auch durch den Windows 10-Ransomware-Schutz verursacht werden, falls dieser aktiviert ist. Versuchen Sie, den überwachten Ordnerzugriff in „Windows-Sicherheit“ → „Viren- & Bedrohungsschutz“ auszuschalten."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/el-GR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/el-GR.ini
Changed
@@ -68,7 +68,6 @@ MediaFileFilter.AudioFiles="Αρχεία Ήχου" MediaFileFilter.AllFiles="Όλα τα αρχεία" ReplayBuffer="Διάρκεια μνήμης Replay" -ReplayBuffer.Save="Αποθήκευση Replay" HelperProcessFailed="Αδυναμία έναρξης τού βοηθού της διαδικασίας εγγραφής. Ελέγξτε ότι τα αρχεία OBS δεν έχουν αποκλειστεί η καταργηθεί από ένα τρίτο antivirus / λογισμικό ασφαλείας." UnableToWritePath="Αδυναμία εγγραφής %1. Βεβαιωθείτε ότι χρησιμοποιείτε μια διαδρομή εγγραφής που επιτρέπεται για εγγραφή τού λογαριασμού χρήστη και ότι υπάρχει επαρκής χώρος στον σκληρό δίσκο." WarnWindowsDefender="Εάν είναι ενεργοποιημένη η Προστασία Ransomware των Windows 10 μπορεί επίσης να προκαλέσει αυτό το σφάλμα. Δοκιμάστε να απενεργοποιήσετε την ελεγχόμενη πρόσβαση φακέλου στις ρυθμίσεις ασφαλείας των Windows / ιών και προστασίας από απειλή."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/en-US.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/en-US.ini
Changed
@@ -100,7 +100,6 @@ MediaFileFilter.AllFiles="All Files" ReplayBuffer="Replay Buffer" -ReplayBuffer.Save="Save Replay" HelperProcessFailed="Unable to start the recording helper process. Check that OBS files have not been blocked or removed by any 3rd party antivirus / security software." UnableToWritePath="Unable to write to %1. Make sure you're using a recording path which your user account is allowed to write to and that there is sufficient disk space."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/es-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/es-ES.ini
Changed
@@ -76,7 +76,6 @@ MediaFileFilter.AudioFiles="Archivos de audio" MediaFileFilter.AllFiles="Todos los Archivos" ReplayBuffer="Búfer de repetición" -ReplayBuffer.Save="Guardar repetición" HelperProcessFailed="No se pudo iniciar el proceso ayudante de grabación. Compruebe que los archivos de OBS no han sido bloqueados o eliminados por cualquier programa de seguridad externo." UnableToWritePath="No se pudo escribir a %1. Asegúrese de que utiliza una ruta de grabación que su cuenta de usuario tenga permisos para escribir y que haya suficiente espacio en disco." WarnWindowsDefender="Si la protección del Ransomware de Windows 10 está activada, también puede causar este error. Intenta desactivar el acceso controlado a la carpeta en la configuración de protección de virus y virus de Windows."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/et-EE.ini
Changed
@@ -76,7 +76,6 @@ MediaFileFilter.AudioFiles="Helifailid" MediaFileFilter.AllFiles="Kõik failid" ReplayBuffer="Taasesituse puhver" -ReplayBuffer.Save="Salvesta Taasesitus" HelperProcessFailed="Salvestusabilise protsessi käivitamine ebaõnnestus. Kontrollige, et OBS-faile poleks blokeerinud ega eemaldanud ükski kolmanda osapoole viirusetõrje-/turvatarkvara." UnableToWritePath="Kausta %1 kirjutamine ebaõnnestus. Veenduge, et kasutate salvestusrada, millele teie kasutajakontol on kirjutamisõigus ja et kettaruumi on piisavalt." WarnWindowsDefender="Kui Windows 10 lunavaratõrje on lubatud, võib see samuti seda viga põhjustada. Proovige Windowsi turvalisuse / viiruste ja ohtude kaitse sätetes kontrollitud kaustadele juurdepääsu keelata."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/eu-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/eu-ES.ini
Changed
@@ -72,7 +72,6 @@ MediaFileFilter.AudioFiles="Audio-fitxategiak" MediaFileFilter.AllFiles="Fitxategi guztiak" ReplayBuffer="Erreprodukzio bufferra" -ReplayBuffer.Save="Gorde erreprodukzioa" HelperProcessFailed="Ezin izan da grabaziorako laguntza prozesua hasi. Begiratu hirugarren beten antibirusa edo seguritate-softwareak ez duela OBS fitxategiak blokeatzen edo ezabatzen." UnableToWritePath="Ezin izan da idatzi %1-ean. Egiaztatu grabazio-tokian idazteko baimena duzula eta diskoan leku libre nahikoa dagoela." WarnWindowsDefender="Windows 10 Ransomware Protection aktibatuta egoteak errore hori ere sor dezake. Gehitu OBS Windows segurtasuna/ birus eta mehatxuen babeserako ezarpenen kontrolpeko karpeten sarbide-zerrendara."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/fa-IR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/fa-IR.ini
Changed
@@ -82,7 +82,6 @@ MediaFileFilter.AudioFiles="پروندههای صوتی" MediaFileFilter.AllFiles="تمامی پروندهها" ReplayBuffer="پخش مجدد بافر" -ReplayBuffer.Save="ذخیره پخش مجدد" HelperProcessFailed="فرآیند راهنمای ضبط شروع نمی شود. بررسی کنید که فایلهای OBS توسط هیچ یک از آنتی ویروس ها/نرم افزارهای امنیتی شخص ثالث مسدود یا حذف نشده باشند." UnableToWritePath="نوشتن در%1 امکان پذیر نیست. اطمینان حاصل کنید که از یک مسیر ضبط استفاده می کنید که حساب کاربری شما مجاز به نوشتن آن است و فضای دیسک کافی وجود دارد." WarnWindowsDefender="اگر محافظت در برابر باج افزار ویندوز 10 فعال باشد نیز می تواند باعث این خطا شود. دسترسی به پوشه کنترل شده را در امنیت ویندوز/تنظیمات محافظت در برابر تهدید خاموش کنید."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/fi-FI.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/fi-FI.ini
Changed
@@ -75,7 +75,6 @@ MediaFileFilter.AudioFiles="Äänitiedostot" MediaFileFilter.AllFiles="Kaikki tiedostot" ReplayBuffer="Toistopuskuri" -ReplayBuffer.Save="Tallenna uusinta" HelperProcessFailed="Nauhoitusavustaja-prosessin käynnistäminen ei onnistunut. Tarkista, että OBS-tiedostoja ei ole estetty tai poistettu virustutkan tai muun turvallisuusohjelman johdosta." UnableToWritePath="Ei voida kirjoittaa %1. Tarkista, että käytät oikeaa tiedostopolkua johon käyttäjätililläsi on kirjoitusoikeus. Tarkista myös, että levyllä on tarpeeksi tilaa." WarnWindowsDefender="Tämä virhe saattaa aiheutua myös jos Windowsin Hyökkäysten esto on käytössä. Yritä kytkeä valvottujen kansioiden seuranta pois päältä Windowsin suojaus / Virusten ja uhkien torjunta -asetuksissa."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/fil-PH.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/fil-PH.ini
Changed
@@ -62,7 +62,6 @@ MediaFileFilter.VideoFiles="Bidyo Files" MediaFileFilter.AllFiles="Lahat ng Files" ReplayBuffer="Ang Replay Buffer" -ReplayBuffer.Save="I-Save ang Replay" HelperProcessFailed="Hindi pwedeng simulan ang pag proseso ng recording helper. Tingan kung OBS file ay hindi hinarangan o tinanggal ng anumang 3rd part antivirus / security software." UnableToWritePath="Bigong magapagsulat sa %1. Siguraduhin na gamit ang recording path kung saan ang user account mo ay tanggap ang pagsulat at mayroon sapat na espasyo sa disk." WarnWindowsDefender="Kung ang Proteksyon ng Windows 10 laban sa Ransomware ay nakabukas, maaring maging sanhi ito ng error na ito. Subukan buwagin ang pag-access ng controlled folder sa settings ng Windows Security / Virus & Threat."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/fr-FR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/fr-FR.ini
Changed
@@ -75,7 +75,6 @@ MediaFileFilter.AudioFiles="Fichiers audio" MediaFileFilter.AllFiles="Tous les fichiers" ReplayBuffer="Tampon de relecture" -ReplayBuffer.Save="Sauvegarder la relecture" HelperProcessFailed="Impossible de démarrer le processus compagnon pour l’enregistrement. Vérifiez que les fichiers d'OBS ne sont pas bloqués/supprimés par un quelconque antivirus/logiciel de sécurité." UnableToWritePath="Impossible d’écrire dans %1. Assurez-vous que vous utilisez un chemin d’enregistrement où votre compte d’utilisateur est autorisé à écrire et qu’il y a suffisamment d’espace disque." WarnWindowsDefender="Si la Protection contre les ransomware de Windows 10 est activée, cela peut causer cette erreur. Essayez de désactiver le Dispositif d'accès contrôlé aux dossiers dans \"Sécurité Windows\" / \"Protection contre les virus et menaces\"."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/gd-GB.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/gd-GB.ini
Changed
@@ -38,7 +38,6 @@ MediaFileFilter.AudioFiles="Faidhlichean fuaime" MediaFileFilter.AllFiles="A h-uile faidhle" ReplayBuffer="Bufair na h-ath-chluiche" -ReplayBuffer.Save="Sàbhail an ath-chluiche" HelperProcessFailed="Cha b’ urrainn dhuinn pròiseas-taice a’ chlàraidh a thòiseachadh. Dearbh nach deach na faidhlichean OBS a bhacadh no a thoirt air falbh le bathar-bog tèarainteachd / an aghaidh bhìorasan aig treas-phàrtaidh." UnableToWritePath="Chan urrainn dhuinn sgrìobhadh gu %1. Dèan cinnteach gu bheil thu a’ cleachdadh slighe clàraidh a dh’fhaodas an cunntas cleachdaiche agad sgrìobhadh dhi agus gu bheil àite gu leòr air an diosg." WarnWindowsDefender="Ma tha an dìon o bhathar-èirig aig Windoes 10 an comas, dh’fhaoidte gur e sin a dh’adhbharaicheas a’ mhearachd. Feuch an cuir thu dheth “inntrigeadh do phasganan fo smachd” ann an roghainnean “Tearainteachd” / “dDìon o bhìorasan ⁊ chunnartan” aig Windows."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/gl-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/gl-ES.ini
Changed
@@ -77,7 +77,6 @@ MediaFileFilter.AudioFiles="Ficheiros de son" MediaFileFilter.AllFiles="Todos os ficheiros" ReplayBuffer="Reproducir a memoria intermedia" -ReplayBuffer.Save="Gardar a reprodución" HelperProcessFailed="Non foi posíbel iniciar o proceso do axudante de gravación. Comprobe que os ficheiros do OBS non foron bloqueados ou eliminados por un antivirus ou software de seguridade de terceiros." UnableToWritePath="Non foi posíbel escribir en %1. Asegúrese de que está a usar unha ruta de gravación na que a súa conta de usuario teña permisos de escritura e que haxa espazo abondo no disco." WarnWindowsDefender="Se a protección do Ransomware do Windows está activada tamén pode causar este erro. Tente desactivar o acceso controlado ao cartafol nos axustes de seguridade do Windows / virus e protección contra ameazas."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/he-IL.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/he-IL.ini
Changed
@@ -80,7 +80,6 @@ MediaFileFilter.AudioFiles="קובצי שמע" MediaFileFilter.AllFiles="כל הקבצים" ReplayBuffer="מטמון השמעה חוזרת" -ReplayBuffer.Save="שמירת השמעה חוזרת" HelperProcessFailed="לא ניתן להתחיל את תהליך עוזר ההקלטה. יש לבדוק שקבצים של OBS לא נחסמו או הוסרו על ידי אנטי-וירוס / תוכנת אבטחה צד-שלישי." UnableToWritePath="לא ניתן לכתוב אל %1. יש לוודא שהשתמשת בנתיב הקלטה שחשבון המשתמש שלך מורשה לכתוב בו ושיש מספיק מקום בדיסק הקשיח." WarnWindowsDefender="אם הגנת כופרה של ווינדוס 10 מופעלת זה עלול לגרום לשגיאה זו. יש לנסות לכבות את הגישה המבוקרת לתיקיות ב-אבטחת ווינדוס / הגדרות הגנה מפני וירוסים ואיומים."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/hi-IN.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/hi-IN.ini
Changed
@@ -81,7 +81,6 @@ MediaFileFilter.AudioFiles="ऑडियो फ़ाइलें" MediaFileFilter.AllFiles="सभी फ़ाइलें" ReplayBuffer="रीप्ले बफ़र" -ReplayBuffer.Save="रीप्ले सहेजें" HelperProcessFailed="रिकॉर्डिंग सहायक प्रक्रिया प्रारंभ करने में असमर्थ. जांचें कि OBS फाइलों को किसी तीसरे पक्ष के एंटीवायरस / सुरक्षा सॉफ्टवेयर द्वारा अवरुद्ध किया या हटाया नहीं गया है." UnableToWritePath="%1 में लिखने में अक्षम. सुनिश्चित करें कि आप उस रिकॉर्डिंग पथ का उपयोग कर रहे हैं जिसमें आपके उपयोगकर्ता खाते को लिखने की अनुमति है और यह भी कि डिस्क में पर्याप्त जगह है." WarnWindowsDefender="यदि विंडोज 10 रैंसमवेयर प्रोटेक्शन सक्षम है तो यह इस त्रुटि का कारण भी बन सकता है. विंडोज सुरक्षा / वायरस व खतरे से सुरक्षा सेटिंग्स में नियंत्रित फ़ोल्डर पहुंच को बंद करने का प्रयास करें."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/hr-HR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/hr-HR.ini
Changed
@@ -81,7 +81,6 @@ MediaFileFilter.AudioFiles="Zvučne datoteke" MediaFileFilter.AllFiles="Sve datoteke" ReplayBuffer="Međuspremnik za ponovnu reprodukciju" -ReplayBuffer.Save="Spremi snimku" HelperProcessFailed="Nije moguće pokrenuti proces pomoći pri snimanju. Provjerite jesu li OBS datoteke blokirane ili uklonjene od strane antivirusnog/sigurnosnog softvera treće strane." UnableToWritePath="Nije moguće pisati na %1. Provjerite koristite li putanju snimanja na koju vaš korisnički račun ima dopuštenje za pisanje i ima li dovoljno prostora na disku." WarnWindowsDefender="Ako je omogućena zaštita od ransomwarea u sustavu Windows 10, također može uzrokovati ovu pogrešku. Pokušajte isključiti kontrolirani pristup mapama u postavkama Sigurnost sustava Windows / Zaštita od virusa i prijetnji."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/hu-HU.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/hu-HU.ini
Changed
@@ -80,7 +80,6 @@ MediaFileFilter.AudioFiles="Hangfájlok" MediaFileFilter.AllFiles="Minden fájl" ReplayBuffer="Visszajátszási puffer" -ReplayBuffer.Save="Visszajátszás mentése" HelperProcessFailed="Nem lehet indítani a felvétel segítő folyamatot. Ellenőrizze, hogy az OBS fájlok nincsenek e blokkolva vagy eltávolítva bármilyen harmadik féltől származó antivírus / biztonsági szoftver által." UnableToWritePath="A(z) %1 nem írható. Győződjön meg róla, hogy a felhasználói fiók írhat-e a felvételek elérési útjára, és hogy elegendő lemezterület áll-e rendelkezésre." WarnWindowsDefender="Ha a Windows 10 zsaróprogramok elleni védelme be van kapcsolva, akkor az is képes ezt a hibát okozni. Próbálja kikapcsolni a felügyelet alatt lévő mappák elérését a Windows biztonság / Vírusok és veszélyforrások elleni védelem alatt."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/hy-AM.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/hy-AM.ini
Changed
@@ -74,7 +74,6 @@ MediaFileFilter.AudioFiles="Աուդիո ֆայլերը" MediaFileFilter.AllFiles="Բոլոր ֆայլերը" ReplayBuffer="Կրկնել բուֆերը" -ReplayBuffer.Save="Պահպանել կրկնությունը" HelperProcessFailed="Հնարավոր չէ սկսել գրելու օգնական գործընթաց: Ստուգեք, արդյոք OBS ֆայլերը արգելափակվել կամ ջնջվել են երրորդ կողմի հակավիրուսային/անվտանգության ծրագրերի կողմից:" UnableToWritePath="Հնարավոր չէ գրել %1-ին: Համոզվեք, որ ձեր հաշիվը գրելի է այս ճանապարհին, և որ սկավառակի վրա բավականաչափ ազատ տարածք կա:" WarnWindowsDefender="Եթե Windows 10 Ransomware Protection-ը միացված է, դա նույնպես կարող է առաջացնել այս սխալը: Փորձեք անջատել Վերահսկվող մուտք դեպի թղթապանակներ Windows-ի անվտանգություն / պաշտպանություն վիրուսներից և սպառնալիքներից:"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/id-ID.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/id-ID.ini
Changed
@@ -67,7 +67,6 @@ MediaFileFilter.AudioFiles="Berkas Audio" MediaFileFilter.AllFiles="Semua Berkas" ReplayBuffer="Buffer Replay" -ReplayBuffer.Save="Simpan Tayangan Ulang" HelperProcessFailed="Tidak dapat menjalankan proses bantuan rekaman. Periksa apakah berkas OBS tidak diblokir atau dihapus oleh perangkat lunak antivirus/keamanan pihak ketiga." UnableToWritePath="Tidak dapat menulis ke %1. Pastikan Anda menggunakan jalur rekaman yang dimana tempat akun pengguna Anda diizinkan menulis dan ruang penyimpanan yang cukup." WarnWindowsDefender="Jika Windows 10 Ransomware Protection diaktifkan, ini juga dapat menyebabkan kesalahan tersebut. Coba nonaktifkan akses folder yang dikontrol di pengaturan Windows Security / Pengaturan perlindungan dari virus & ancaman."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/it-IT.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/it-IT.ini
Changed
@@ -75,7 +75,6 @@ MediaFileFilter.AudioFiles="File audio" MediaFileFilter.AllFiles="Tutti i file" ReplayBuffer="Buffer di replay" -ReplayBuffer.Save="Salva il replay" HelperProcessFailed="Impossibile avviare il processo di supporto alla registrazione. Verifica che i file di OBS non siano stati bloccati o rimossi da qualche software di sicurezza o antivirus di terze parti." UnableToWritePath="Impossibile scrivere su %1. Assicurati che il tuo account utente possa accedere al percorso di registrazione, e che ci sia spazio sufficiente sul disco." WarnWindowsDefender="Se la protezione ransomware di Windows 10 è attivata, può causare questo errore. Prova a disattivare l'accesso alle cartelle controllato, lo puoi trovare in Sicurezza di Windows → Protezione da virus e minacce → Gestisci protezione ransomware."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ja-JP.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ja-JP.ini
Changed
@@ -68,7 +68,6 @@ MediaFileFilter.AudioFiles="オーディオファイル" MediaFileFilter.AllFiles="すべてのファイル" ReplayBuffer="リプレイバッファ" -ReplayBuffer.Save="リプレイを保存" HelperProcessFailed="録画の補助プロセスを開始できません。 OBSのファイルがサードパーティ製のアンチウイルス/セキュリティソフトウェアによってブロックまたは削除されていないことを確認してください。" UnableToWritePath="%1 に書き込めません。 あなたのユーザーアカウントが書き込みを許可されている録画のパスを使用していることと十分なディスク容量があることを確認してください。" WarnWindowsDefender="Windows 10 ランサムウェア保護が有効になっていると、このエラーが発生する可能性があります。Windowsのセキュリティ/ウイルス対策と脅威対策の設定で、フォルダへのアクセス制御を無効にしてみてください。"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ka-GE.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ka-GE.ini
Changed
@@ -82,7 +82,6 @@ MediaFileFilter.AudioFiles="ხმოვანი ფაილები" MediaFileFilter.AllFiles="ყველა ფაილი" ReplayBuffer="გადახვევა" -ReplayBuffer.Save="გადახვევის შენახვა" HelperProcessFailed="ჩაწერის პროცესის გაშვება ვერ ხერხდება. გადაამოწმეთ, ხომ არ არის OBS ფაილები შეზღუდული ან წაშლილი ანტივირუსის / უსაფრთხოების სხვა პროგრამების მიერ." UnableToWritePath="%1 ვერ ახერხებს ჩაწერას. დარწმუნდით, რომ ჩაწერისთვის მითითებულ მისამართზე ნებადართულია ჩაწერა თქვენი მომხმარებლით და, ამასთანავე, საკმარისი ადგილია დისკზე." WarnWindowsDefender="თუ ჩართულია Windows 10-ის დაცვა ფაილების მიმტაცებელი პროგრამებისგან (Ransomware), ამ შეცდომას ეგეც შეიძლება იწვევდეს. სცადეთ საქაღალდეებთან წვდომის შეზღუდვის მოხსნა, Windows-ის უსაფრთხოების ან ანტივირუსის პარამეტრებიდან."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/kaa.ini
Changed
@@ -1,12 +1,16 @@ -FFmpegOpts="FFmpeg sazlawları" -Bitrate="Bit tezligi" -Preset="Sazlawlar jıyındısı" -Profile="Profil" -Level="Dáreje" -FilePath="Fayl jolı" -GPU="GP" -VAAPI.Device="VAAPI qurılması" -NVENC.CQLevel="CQ dárejesi" +FFmpegALAC="FFmpeg ALAC (24 бит)" +FFmpegFLAC="FFmpeg FLAC (16 бит)" +FFmpegPCM16Bit="FFmpeg PCM (16 бит)" +FFmpegPCM24Bit="FFmpeg PCM (24 бит)" +Bitrate="Битрейт" +MaxBitrate="Максимал битрейт" +Profile="Профиль" +Lossless="Жоғалтыўсыз" +Level="Дәреже" +FilePath="Файл жолы" +GPU="Видеокарта" +VAAPI.Device="VAAPI қурылмасы" +NVENC.CQLevel="CQ дәрежеси" NVENC.Preset2.p1="P1: Júdá tez (eń tómen sapa)" NVENC.Preset2.p2="P2: Tezirek (tómenlew sapa)" NVENC.Preset2.p3="P3: Tez (tómen sapa)" @@ -14,28 +18,34 @@ NVENC.Preset2.p5="P5: Ásten (jaqsı sapa)" NVENC.Preset2.p6="P6: Ástenlew (jaqsıraq sapa)" NVENC.Preset2.p7="P7: Júdá ásten (eń jaqsı sapa)" -NVENC.Tuning.hq="Joqarı dárejeli sapa" -AMF.Preset.speed="Tezlik" +NVENC.Tuning.hq="Жоқары сапа" +NVENC.Tuning.ll="Төмен иркилис" +NVENC.Tuning.ull="Жүдә төмен иркилис" +AMF.Preset.speed="Тезлик" +AMF.Preset.balanced="Баланс" AMF.Preset.quality="Sapası" AMF.Preset.highQuality="Joqarı dárejeli sapa" -Looping="Qaytalaw" +FFmpegSource="Медиа" +LocalFile="Локал файл" +Looping="Қайталаў" +Input="Кирис" +InputFormat="Кирис форматы" ColorRange="YUV reń aralıǵı" -ColorRange.Auto="Avtomat tárizde" -ColorRange.Partial="Sheklengen" -ColorRange.Full="Tolıq" -RestartMedia="Qayta iske túsiriw" -SpeedPercentage="Tezlik" -Play="Qoyıw" -Pause="Pauza" -Stop="Toqtatıw" +ColorRange.Auto="Автоматикалық" +ColorRange.Partial="Шекленген" +ColorRange.Full="Толық" +RestartMedia="Қайта иске түсириў" +SpeedPercentage="Тезлик" +Play="Қойыў" +Pause="Пауза" +Stop="Тоқтатыў" MediaFileFilter.AllMediaFiles="Barlıq media fayllar" MediaFileFilter.VideoFiles="Videofayllar" MediaFileFilter.AudioFiles="Audiofayllar" MediaFileFilter.AllFiles="Barlıq fayllar" ReplayBuffer="Qayta qoyıw bufferi" -ReplayBuffer.Save="Qayta qoyıwdı saqlaw" Encoder.Error="Ashıw ámelge aspadı %1: %2" NVENC.Error="NVENC kodekin ashıw múmkin emes: %1" NVENC.OutdatedDriver="Ornatılǵan NVIDIA drayveri NVENCtıń bul versiyasın jebemeydi, <a href=\"https://obsproject.com/go/nvidia-drivers\">drayverdi jańalap</a> kóriń." NVENC.CheckDrivers="<a href=\"https://obsproject.com/go/nvidia-drivers\">NVIDIA drayverinıń</a> sońǵı versiyasın ornatıp kóriń." -ReconnectDelayTime="Qayta jalǵanıw irkilisi" +ReconnectDelayTime="Қайта жалғаныў иркилиси"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/kab-KAB.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/kab-KAB.ini
Changed
@@ -58,7 +58,6 @@ MediaFileFilter.AudioFiles="Ifuyla imeslawen" MediaFileFilter.AllFiles="Akk ifuyla" ReplayBuffer="Tallunt n weḥraz n tulsa n tɣuri" -ReplayBuffer.Save="Sekles tulsa n tɣuri" Encoder.Error="Yecceḍ ulday n %1: %2" Encoder.Timeout="Asettengal %1 yeṭṭef aṭas n wakud i usettengel (asrag: %2 n tasinin)" AMF.8bitUnsupportedHdr="OBS ur isefrak ara tuffɣa 8 ibiten n Rec. 2100."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/kmr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/kmr-TR.ini
Changed
@@ -70,7 +70,6 @@ MediaFileFilter.AudioFiles="Pelên dengê" MediaFileFilter.AllFiles="Hemû pel" ReplayBuffer="Ji nû ve lêdana pêşbîra demkî" -ReplayBuffer.Save="Ji nû ve lêdanê tomar bike" HelperProcessFailed="Nikare dest bi pêvajoya alîkara tomarkirinê bike. Kontrol bikin ku dosyayên OBS'ê ji aliyê ti antîvîrûs / nermalava ewlekariyê ya partiya 3. ve nehatiye astengkirin an rakirin." UnableToWritePath="Nekarî binivîse li %1. Ji xwe bawer bin ku tu riyên tomarkirinê bi kar tanî ku hesabê te yê bikarhêner destûrê dide nivîsandinê û têra xwe cihê dîskê heye." WarnWindowsDefender="Ku Parastina Ransomware Windows 10 çalak be, ew dikare bibe sedema vê çewtiyê. Di sazkariyên parastina Windows Security / Vîrus & tehdîdê de têgihîştina peldanka kontrolkirî veke."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ko-KR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ko-KR.ini
Changed
@@ -76,7 +76,6 @@ MediaFileFilter.AudioFiles="오디오 파일" MediaFileFilter.AllFiles="모든 파일" ReplayBuffer="리플레이 버퍼" -ReplayBuffer.Save="리플레이 저장" HelperProcessFailed="녹화 도우미를 시작할 수 없습니다. 백신이나 보안 소프트웨어가 OBS 파일을 차단 혹은 제거하지 않았는지 확인하십시오." UnableToWritePath="%1에 기록할 수 없습니다. 사용자 계정이 녹화 계정에 접근할 수 있는지 혹은 저장 공간이 충분한지 확인하십시오." WarnWindowsDefender="Windows 10에서 제공하는 랜섬웨어 보호 기능이 켜져 있으면 이 오류가 일어날 수 있습니다. Windows 보안 / 바이러스 및 위협 방지 설정에서 제어된 폴더 액세스를 해제해 보십시오."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/lo-LA.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/lo-LA.ini
Changed
@@ -68,7 +68,6 @@ MediaFileFilter.VideoFiles="ໄຟລ໌ວິດີໂອ" MediaFileFilter.AudioFiles="ໄຟລ໌ສຽງ" MediaFileFilter.AllFiles="ໄຟລ໌ທັງໝົດ" -ReplayBuffer.Save="ບັນທຶກ Replay" HelperProcessFailed="ບໍ່ສາມາດເລີ່ມຂະບວນການຊ່ວຍບັນທຶກໄດ້. ກວດເບິ່ງວ່າໄຟລ໌ OBS ບໍ່ໄດ້ຖືກບລັອກ ຫຼື ລົບອອກໂດຍໂປຣແກຣມປ້ອງກັນໄວຣັດ / ຄວາມປອດໄພຂອງພາກສ່ວນທີສາມ." UnableToWritePath="ບໍ່ສາມາດຂຽນລົງໃນ %1 ໄດ້. ກວດໃຫ້ແນ່ໃຈວ່າທ່ານກຳລັງໃຊ້ເສັ້ນທາງການບັນທຶກທີ່ບັນຊີຜູ້ໃຊ້ຂອງທ່ານໄດ້ຮັບອະນຸຍາດໃຫ້ຂຽນ ແລະ ມີພື້ນທີ່ດິດພຽງພໍ." WarnWindowsDefender="ຫາກເປີດໃຊ້ Windows 10 Ransomware Protection ມັນອາດຈະເຮັດໃຫ້ເກີດຂໍ້ຜິດພາດນີ້ໄດ້ເຊັ່ນກັນ. ລອງປິດການເຂົ້າເຖິງໂຟນເດີທີ່ຖືກຄວບຄຸມ (controlled folder access) ໃນການຕັ້ງຄ່າ Windows Security / Virus & threat protection."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ms-MY.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ms-MY.ini
Changed
@@ -72,7 +72,6 @@ MediaFileFilter.AudioFiles="Fail Audio" MediaFileFilter.AllFiles="Semua Fail" ReplayBuffer="Penimbal Main Semula" -ReplayBuffer.Save="Simpan Main Semula" HelperProcessFailed="Tidak dapat memulakan proses pembantu rakaman. Periksa sama ada fail-fail OBS telah disekat atau dibuang oleh mana-mana perisian keselamatan / antivirus pihak ke-3." UnableToWritePath="Tidak boleh menulis ke %1. Pastikan anda menggunakan satu laluan rakaman yang mana akaun pengguna anda boleh menulis dan ada ruang yang mencukupi." WarnWindowsDefender="Jika Perlindungan Perisian Tebusan Windows 10 dibenarkan ia juga boleh menyebabkan ralat ini. Cuba matikan capaian folder terkawal dalam tetapan perlindungan Keselamatan Windows / Virus & ancaman."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/nb-NO.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/nb-NO.ini
Changed
@@ -59,7 +59,6 @@ MediaFileFilter.AudioFiles="Lydfiler" MediaFileFilter.AllFiles="Alle filer" ReplayBuffer="Omspillingsbuffer" -ReplayBuffer.Save="Lagre omspilling" HelperProcessFailed="Kan ikke starte prosess for opptakshjelper. Sjekk at OBS ikke har noen blokkerte filer, eller at tredjeparts antivirus/sikkerhetsprogramvare har slettet noen filer." UnableToWritePath="Kan ikke skrive til %1. Kontroller at du bruker en filbane som kontoen din har rettigheter til å skrive på, og at du har nok diskplass tilgjengelig." WarnWindowsDefender="Hvis Windows 10 Ransomvare-beskyttelse er aktivert, kan dette medføre denne feilen. Forsøk å deaktivere kontrollert mappetilgang i Windows-instillingen Sikkerhet > Virus- og Trusselbeskyttelse."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/nl-NL.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/nl-NL.ini
Changed
@@ -64,7 +64,6 @@ MediaFileFilter.AudioFiles="Audiobestanden" MediaFileFilter.AllFiles="Alle bestanden" ReplayBuffer="Replaybuffer" -ReplayBuffer.Save="Replay opslaan" HelperProcessFailed="Kan het opnamehulpproces niet starten. Controleer of er geen OBS-bestanden geblokkeerd of verwijderd zijn door antivirus of beveiligingssoftware." UnableToWritePath="Kan niet naar %1 schrijven. Controller of je een opnamepad gebruikt waar je gebruikersaccount naartoe kan schrijven, en dat er voldoende schijfruimte beschikbaar is." WarnWindowsDefender="Als Windows 10 Ransomware Protection is ingeschakeld, kan dit ook deze fout veroorzaken. Probeer gecontroleerde toegang tot mappen uit te schakelen in de instellingen van Windows Security / Virus & Threat Protection."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/pl-PL.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/pl-PL.ini
Changed
@@ -76,7 +76,6 @@ MediaFileFilter.AudioFiles="Pliki audio" MediaFileFilter.AllFiles="Wszystkie pliki" ReplayBuffer="Nagrywanie powtórek" -ReplayBuffer.Save="Zapisz nagraną powtórkę" HelperProcessFailed="Nie można uruchomić procesu nagrywania. Sprawdź, czy pliki OBS nie są blokowane lub usunięte przez oprogramowanie zewnętrzne, np. antywirusowe lub chroniące system." UnableToWritePath="Nie można zapisać do %1. Sprawdź poprawność ścieżki zapisu, prawa dostępu do niej oraz wolne miejsce na dysku." WarnWindowsDefender="Błąd ten może być spowodowany również włączoną ochroną Windows 10 przed ransomware. Prosimy spróbować wyłączyć \"Kontrolowany dostęp do folderu\" w sekcji Ochrona przed wirusami i zagrożeniami."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/pt-BR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/pt-BR.ini
Changed
@@ -75,7 +75,6 @@ MediaFileFilter.AudioFiles="Arquivos de áudio" MediaFileFilter.AllFiles="Todos os arquivos" ReplayBuffer="Buffer de repetição" -ReplayBuffer.Save="Salvar replay" HelperProcessFailed="Não foi possível iniciar o processo auxiliar de gravação. Verifique se os arquivos do OBS não foram bloqueados ou removidos por outro software (ex: antivírus)." UnableToWritePath="Não foi possível escrever em %1. Certifique-se de que você está usando um caminho de gravação que sua conta de usuário possui permissão para gravar e que há espaço suficiente no disco." WarnWindowsDefender="Este erro pode acontecer também por causa da Proteção contra Ransomware do Windows 10. Experimente desligar o acesso controlado a pastas em: Configurações do Windows Defender > Proteção contra vírus e ameaças."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/pt-PT.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/pt-PT.ini
Changed
@@ -77,7 +77,6 @@ MediaFileFilter.AudioFiles="Ficheiros de áudio" MediaFileFilter.AllFiles="Todos os ficheiros" ReplayBuffer="Memória de repetição" -ReplayBuffer.Save="Guardar repetição" HelperProcessFailed="Não foi possível iniciar o processo auxiliar de gravação. Verifique se os ficheiros do OBS não bloqueados ou removidos por qualquer programa de segurança/antivírus de terceiros." UnableToWritePath="Não foi possível guardar em %1. Certifique-se de que usa um caminho de gravação onde esta conta de utilizador tenha permissão de escrita e que haja espaço suficiente em disco." WarnWindowsDefender="Se a proteção contra Ransomware do Windows 10 estiver ativa, pode ser a causa deste erro. Tente desativar o controlo de acesso a pastas nas definições de segurança/vírus do Windows."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ro-RO.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ro-RO.ini
Changed
@@ -71,7 +71,6 @@ MediaFileFilter.AudioFiles="Fișiere audio" MediaFileFilter.AllFiles="Toate fișierele" ReplayBuffer="Buffer de reluări" -ReplayBuffer.Save="Salvează reluarea" HelperProcessFailed="Nu se poate porni procesul ajutător de înregistrare. Verifică dacă fișierele OBS nu au fost blocate sau eliminate de orice software terț antivirus / de securitate." UnableToWritePath="Nu se poate scrie în %1. Asigură-te că folosești o cale de înregistrare în care contul tău de utilizator are permisiunea de a scrie și că există suficient spațiu pe disc." WarnWindowsDefender="Dacă este activată protecţia Ransomware Windows 10 poate cauza şi această eroare. Încercați să dezactivați accesul la dosarele controlate în setările de securitate / Virus și protecție împotriva amenințării."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ru-RU.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ru-RU.ini
Changed
@@ -82,7 +82,6 @@ MediaFileFilter.AudioFiles="Аудиофайлы" MediaFileFilter.AllFiles="Все файлы" ReplayBuffer="Буфер повтора" -ReplayBuffer.Save="Сохранить повтор" HelperProcessFailed="Невозможно запустить вспомогательный процесс для записи. Проверьте, не были ли заблокированы или удалены файлы OBS сторонним антивирусом / защитным ПО." UnableToWritePath="Невозможно записать в %1. Убедитесь, что для вашей учётной записи / аккаунта разрешена запись по этому пути, и что на диске достаточно свободного пространства." WarnWindowsDefender="Если включена «Защита от программ-шантажистов» Windows 10, это так же может вызывать эту ошибку. Попробуйте отключить контролируемый доступ к папкам в параметрах «Безопасности Windows / Защита от вирусов и угроз»."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/si-LK.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/si-LK.ini
Changed
@@ -44,7 +44,6 @@ MediaFileFilter.AudioFiles="හඬපට ගොනු" MediaFileFilter.AllFiles="සියළු ගොනු" ReplayBuffer="අන්තරාචය යළි වාදනය" -ReplayBuffer.Save="යළි ධාවනය සුරකින්න" HelperProcessFailed="පටිගත උපකාරක ක්රියාවලිය ඇරඹීමට නොහැකියි. කිසිම තෙවන පාර්ශව ප්රතිවෛරස / ආරක්ෂණ මෘදුකාංග මගින් ඕබීඑස් අවහිර හෝ ඉවත් කර නැති බව පරීක්ෂා කරන්න." UnableToWritePath="%1 වෙත ලිවීමට නොහැකිය. ඔබගේ පරිශීලක ගිණුම සඳහා ලිවීමට ඉඩ දී තිබෙන පටිගත මාර්ගයක් භාවිතා කරන බවත් ප්රමාණවත් ඉඩක් තැටියේ ඇතිදැයි බලන්න." WarnWindowsDefender="වින්ඩෝස් 10 කප්පම්මෘදුකාංග ආරක්ෂණය සක්රිය කර ඇත්නම් එය ද මෙම දෝෂයට හේතු විය හැකිය. වින්ඩෝස් ආරක්ෂාව/වෛරස හා තර්ජන රැකවරණ සැකසුම් තුළින් පාලිත බහාලුම වෙත ප්රවේශය අක්රිය කරන්න."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/sk-SK.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/sk-SK.ini
Changed
@@ -66,7 +66,6 @@ MediaFileFilter.AudioFiles="Zvukové súbory" MediaFileFilter.AllFiles="Všetky súbory" ReplayBuffer="Medzipamäť záznamu" -ReplayBuffer.Save="Uložiť záznam" HelperProcessFailed="Nepodarilo sa spustiť pomocný proces nahrávania. Skontrolujte, či neboli súbory OBS zablokované alebo odstránené zabezpečovacím softvérom/antivírusom tretej strany." UnableToWritePath="Nedá sa zapisovať do %1. Uistite sa, že v ceste nahrávania má váš používateľský účet právo na zápis a že máte dostatok miesta na disku." WarnWindowsDefender="Ak je ochrana proti Ransomwaru Windows 10 zapnutá, tak to môže taktiež spôsobiť túto chybu. Skúste vypnúť kontrolovaný prístup do priečinkov vo Windows Zabezpečení / Ochrana pred vírusmi a hrozbami."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/sl-SI.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/sl-SI.ini
Changed
@@ -78,7 +78,6 @@ MediaFileFilter.AudioFiles="Zvočne datoteke" MediaFileFilter.AllFiles="Vse datoteke" ReplayBuffer="Medpomn. za ponovitev" -ReplayBuffer.Save="Shrani ponovitev" HelperProcessFailed="Pomožnega opravila za snemanje ni bilo mogoče začeti. Preverite, da protivirusni/varnostni program ni blokiral ali odstranil datotek OBS." UnableToWritePath="Ni mogoče pisati v %1. Prepričajte se, da uporabljate pot za snemanje, na katero lahko vaš uporabniški račun zapisuje in da imate dovolj prostora na disku." WarnWindowsDefender="To napako lahko povzroči tudi omogočena zaščita sistema Windows 10 proti izsiljevanju. V nastavitvah za varnost/zaščito proti virusom in grožnjami sistema Windows poizkusite izklopiti nadziran dostop do map."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/sr-CS.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/sr-CS.ini
Changed
@@ -31,7 +31,6 @@ MediaFileFilter.AudioFiles="Zvučne datoteke" MediaFileFilter.AllFiles="Sve datoteke" ReplayBuffer="Bafer za ponovno reprodukovanje" -ReplayBuffer.Save="Sačuvaj ponovno reprodukovanje" HelperProcessFailed="Nemoguće je pokrenuti pomoć za snimanje. Proverite da li su OBS fajlovi blokirani ili premešteni od strane nekog antivirus softvera/softvera za zaštitu." UnableToWritePath="Nemoguće je pisati na %1. Proverite da li koristite putanju kojoj vaš nalog ima pravo da pristupi i da li imate dovoljno prostora na disku." WarnWindowsDefender="Ova greška takođe može da nastane ako je Windows 10 Ransomware Protection uključen. Pokušajte da isključite kontrolisani pristup folderu u podešavanjima za Windows Sigurnost/Zaštitu od virusa."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/sr-SP.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/sr-SP.ini
Changed
@@ -79,7 +79,6 @@ MediaFileFilter.AudioFiles="Звучне датотеке" MediaFileFilter.AllFiles="Све датотеке" ReplayBuffer="Бафер за поновно репродуковање" -ReplayBuffer.Save="Сачувај поновно репродуковање" HelperProcessFailed="Немогуће је покренути помоћ за снимање. Проверите да ли су OBS фајлови блокирани или премештени од стране неког антивирус софтвера/софтвера за заштиту." UnableToWritePath="Немогуће је писати на %1. Проверите да ли користите путању којој ваш налог има право да приступи и да ли имате довољно простора на диску." WarnWindowsDefender="Ова грешка такође може да настане ако је Windows 10 Ransomware Protection укључен. Покушајте да искључите контролисани приступ фолдеру у подешавањима за Windows Сигурност/Заштиту од вируса."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/sv-SE.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/sv-SE.ini
Changed
@@ -80,7 +80,6 @@ MediaFileFilter.AudioFiles="Ljudfiler" MediaFileFilter.AllFiles="Alla filer" ReplayBuffer="Reprisbuffert" -ReplayBuffer.Save="Spara repris" HelperProcessFailed="Kan inte spela in hjälpprocessen. Kontrollera att OBS-filer inte har blockerats eller tagits bort av antivirus-/säkerhetsprogram från tredjepart." UnableToWritePath="Kan inte skriva till %1. Se till att du använder en inspelningssökväg som ditt användarkonto har tillåtelse att skriva till och att det finns tillräckligt mycket diskutrymme." WarnWindowsDefender="Om skyddet mot ransomware i Windows 10 är aktiverat kan det också orsaka detta fel. Försök att inaktivera kontrollerad mappåtkomst i Windows-säkerhet / Inställningar för skydd mot virus & hot."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/th-TH.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/th-TH.ini
Changed
@@ -78,7 +78,6 @@ MediaFileFilter.AudioFiles="ไฟล์เสียง" MediaFileFilter.AllFiles="ไฟล์ทั้งหมด" ReplayBuffer="รีเพลย์บัพเฟอร์" -ReplayBuffer.Save="บันทึกการเล่น" HelperProcessFailed="ไม่สามารถเริ่มกระบวนการตัวช่วยบันทึกได้ ตรวจสอบว่าไฟล์ OBS ไม่ถูกบล็อกหรือลบโดยซอฟต์แวร์ป้องกันไวรัส/ความปลอดภัยของบุคคลที่สาม" UnableToWritePath="ไม่สามารถเขียนถึง %1 ตรวจสอบให้แน่ใจว่าคุณใช้เส้นทางการบันทึกซึ่งบัญชีผู้ใช้ของคุณได้รับอนุญาตให้เขียนและมีพื้นที่ดิสก์เพียงพอ" WarnWindowsDefender="หากเปิดใช้งาน Windows 10 Ransomware Protection ก็อาจทำให้เกิดข้อผิดพลาดนี้ได้ ลองปิดการเข้าถึงโฟลเดอร์ที่ควบคุมในการตั้งค่าความปลอดภัยของ Windows / ไวรัสและภัยคุกคาม"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/tl-PH.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/tl-PH.ini
Changed
@@ -24,6 +24,5 @@ MediaFileFilter.AudioFiles="Ang mga Audio File" MediaFileFilter.AllFiles="Lahat ng mga File" ReplayBuffer="I-replay ang Buffer" -ReplayBuffer.Save="Iimbak ang Baliking Pagpapalabas" HelperProcessFailed="Hindi magawang simulan ang pagtatala ng proseso ng katulong. Suriin na ang mga file ng OBS ay hindi na-block o inalis ng anumang 3rd party antivirus / seguridad ng software." UnableToWritePath="Bigong makapagsulat sa %1. Tiyaking gumagamit ka ng landas na may pahintulot sa iyong akawnt na makapagsulat at sapat ang lawak ng disk."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/tr-TR.ini
Changed
@@ -78,7 +78,6 @@ MediaFileFilter.AudioFiles="Ses Dosyaları" MediaFileFilter.AllFiles="Tüm Dosyalar" ReplayBuffer="Tekrar Oynatma Arabelleği" -ReplayBuffer.Save="Yeniden Oynatmayı Kaydet" HelperProcessFailed="Kayıt yardımcısı işlemi başlatılamadı. OBS dosyalarının herhangi bir 3. taraf antivirüs / güvenlik yazılımı tarafından engellenmediğini veya kaldırılmadığını kontrol edin." UnableToWritePath="%1 yazılamadı. Kullanıcı hesabınızın yazmasına izin verilen bir kayıt konumu kullanıyor olduğunuzdan ve yeterli disk alanı olduğundan emin olun." WarnWindowsDefender="Eğer Windows 10 Fidye Virüsü koruması etkinse bu hataya neden olabilir. Windows Güvenlik / Virüs & tehdit koruması ayarlarından kontrollü klasör erişimini kapatmayı dene."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/ug-CN.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/ug-CN.ini
Changed
@@ -76,7 +76,6 @@ MediaFileFilter.AudioFiles="ئۈن ھۆججەتلىرى" MediaFileFilter.AllFiles="بارلىق ھۆججەتلەر" ReplayBuffer="يىغلەكنى قايتا قوي" -ReplayBuffer.Save="قايتا قويۇشنى ساقلا" HelperProcessFailed="سىن خاتىرىلەش ياردەمچى جەريانىنى قوزغىتالمايدۇ. OBS ھۆججەتنىڭ ئۈچىنچى تەرەپ ۋىرۇسخور/بىخەتەرلىك يۇمشاق دېتالىنىڭ توسقان ياكى ئۆچۈرگەنلىكى تەكشۈرۈلىدۇ." UnableToWritePath="%1 غا يازالمايدۇ. ئىشلىتىۋاتقان سىن خاتىرىلەش يولىغا ھېساباتىڭىزنىڭ يېزىش ئىجازىتى بارلىقى ھەمدە دىسكا بوشلۇقىنىڭ يېتەرلىك ئىكەنلىكىگە كاپالەتلىك قىلىڭ." WarnWindowsDefender="ئەگەر Windows 10 نىڭ قاقتى-سوقتى يۇمشاق دېتالدىن قوغداش قوزغىتىلغان بولسا مۇشۇنداق خاتالىق كۆرۈلۈشى مۇمكىن. Windows بىخەتەرلىك مەركىزى - ۋىرۇس تەھدىتتىن قوغداش تەڭشىكىدىكى قىسقۇچ زىيارىتى چەكلىمىسىنى تاقاش كېرەك."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/uk-UA.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/uk-UA.ini
Changed
@@ -78,7 +78,6 @@ MediaFileFilter.AudioFiles="Аудіо" MediaFileFilter.AllFiles="Усі файли" ReplayBuffer="Буфер повторів" -ReplayBuffer.Save="Зберегти повтор" HelperProcessFailed="Не вдається запустити допоміжний процес для запису. Переконайтеся, що файли OBS не були заблоковані чи видалені стороннім антивірусом / ПЗ для захисту." UnableToWritePath="Не вдається записати в %1. Переконайтеся, що ваш обліковий запис має дозвіл на запис по цьому шляху, і що на диску достатньо вільного місця." WarnWindowsDefender="Якщо Windows 10 Ransomware Protection (захист від програм-вимагачів) увімкнено – це також може спричинити цю помилку. Спробуйте вимкнути керований доступ до папок у «Безпека у Windows» - «Захист від вірусів і загроз»."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/vi-VN.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/vi-VN.ini
Changed
@@ -74,7 +74,6 @@ MediaFileFilter.VideoFiles="Tập tin video" MediaFileFilter.AudioFiles="Tập tin âm thanh" MediaFileFilter.AllFiles="Tất cả tập tin" -ReplayBuffer.Save="Lưu bản phát lại" HelperProcessFailed="Không thể khởi động quá trình trợ giúp ghi âm. Hãy kiểm tra xem tập tin OBS có bị chặn hoặc xóa bởi bất kỳ phần mềm diệt virus / bảo mật bên thứ ba nào không." UnableToWritePath="Không thể viết vào %1. Hãy đảm bảo rằng bạn đang sử dụng đường dẫn ghi mà tài khoản người dùng của bạn được phép ghi và có đủ không gian đĩa." WarnWindowsDefender="Nếu Windows 10 Ransomware Protection đang bật thì có thể gây ra lỗi này. Thử tắt Controlled Folder Access trong cài đặt Windows Security / Virus & threat protection."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/zh-CN.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/zh-CN.ini
Changed
@@ -81,7 +81,6 @@ MediaFileFilter.AudioFiles="音频文件" MediaFileFilter.AllFiles="所有文件" ReplayBuffer="回放缓存" -ReplayBuffer.Save="保存回放" HelperProcessFailed="无法启动录制助手进程。检查 OBS 文件未被任何第三方防病毒 / 安全软件阻止或删除。" UnableToWritePath="无法写入到 %1。请确保您使用的录像路径允许您的用户账户写入,并且磁盘空间充足。" WarnWindowsDefender="Windows 10 的勒索软件防护机制也可能导致该错误的发生。请尝试关闭Windows 安全中心中勒索软件防护功能的文件夹限制访问选项。"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/data/locale/zh-TW.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/data/locale/zh-TW.ini
Changed
@@ -78,7 +78,6 @@ MediaFileFilter.AudioFiles="音訊檔案" MediaFileFilter.AllFiles="所有檔案" ReplayBuffer="重播緩衝區" -ReplayBuffer.Save="儲存重播" HelperProcessFailed="無法啟動錄影協助程式。請確定 OBS 檔案沒有被防毒/安全軟體阻擋或移除。" UnableToWritePath="無法寫入到 %1。請確定使用者帳戶可以寫入錄影檔路徑以及有足夠的磁碟空間。" WarnWindowsDefender="如果啟用了 Windows 10 勒索軟體保護,也可能會導致此錯誤。試試將 Windows 安全性 > 病毒與威脅防護 設定中的 受控資料夾存取權 關閉。"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/ffmpeg-mux/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/ffmpeg-mux/CMakeLists.txt
Changed
@@ -2,7 +2,7 @@ option(ENABLE_FFMPEG_MUX_DEBUG "Enable FFmpeg-mux debugging" OFF) -find_package(FFmpeg REQUIRED COMPONENTS avcodec avutil avformat) +find_package(FFmpeg 8.0 REQUIRED COMPONENTS avcodec avutil avformat) add_executable(obs-ffmpeg-mux) add_executable(OBS::ffmpeg-mux ALIAS obs-ffmpeg-mux)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
Changed
@@ -817,11 +817,7 @@ return 0; } -#if LIBAVFORMAT_VERSION_MAJOR >= 61 static int ffmpeg_mux_write_av_buffer(void *opaque, const uint8_t *buf, int buf_size) -#else -static int ffmpeg_mux_write_av_buffer(void *opaque, uint8_t *buf, int buf_size) -#endif { struct ffmpeg_mux *ffm = opaque;
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c
Changed
@@ -239,15 +239,10 @@ const enum AVSampleFormat *sample_fmts = NULL; const int *supported_samplerates = NULL; -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(61, 13, 100) - sample_fmts = enc->codec->sample_fmts; - supported_samplerates = enc->codec->supported_samplerates; -#else avcodec_get_supported_config(enc->context, enc->codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, (const void **)&sample_fmts, NULL); avcodec_get_supported_config(enc->context, enc->codec, AV_CODEC_CONFIG_SAMPLE_RATE, 0, (const void **)&supported_samplerates, NULL); -#endif if (sample_fmts) { /* Check if the requested format is actually available for the specified
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c
Changed
@@ -371,11 +371,7 @@ return err; } -#if LIBAVFORMAT_VERSION_MAJOR >= 61 typedef int (*write_packet_cb)(void *, const uint8_t *, int); -#else -typedef int (*write_packet_cb)(void *, uint8_t *, int); -#endif static inline int allocate_custom_aviocontext(struct ffmpeg_output *stream, bool is_rist) {
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/obs-ffmpeg-mux.c -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/obs-ffmpeg-mux.c
Changed
@@ -914,20 +914,16 @@ return obs_module_text("ReplayBuffer"); } -static void replay_buffer_hotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, bool pressed) +static void save_replay_proc(void *data, calldata_t *cd) { - UNUSED_PARAMETER(id); - UNUSED_PARAMETER(hotkey); - - if (!pressed) - return; + UNUSED_PARAMETER(cd); struct ffmpeg_muxer *stream = data; if (os_atomic_load_bool(&stream->active)) { obs_encoder_t *vencoder = obs_output_get_video_encoder(stream->output); if (obs_encoder_paused(vencoder)) { - info("Could not save buffer because encoders paused"); + info("Could not save buffer because the encoder is paused"); return; } @@ -935,12 +931,6 @@ } } -static void save_replay_proc(void *data, calldata_t *cd) -{ - replay_buffer_hotkey(data, 0, NULL, true); - UNUSED_PARAMETER(cd); -} - static void get_last_replay(void *data, calldata_t *cd) { struct ffmpeg_muxer *stream = data; @@ -954,24 +944,19 @@ struct ffmpeg_muxer *stream = bzalloc(sizeof(*stream)); stream->output = output; - stream->hotkey = obs_hotkey_register_output(output, "ReplayBuffer.Save", obs_module_text("ReplayBuffer.Save"), - replay_buffer_hotkey, stream); - proc_handler_t *ph = obs_output_get_proc_handler(output); proc_handler_add(ph, "void save()", save_replay_proc, stream); proc_handler_add(ph, "void get_last_replay(out string path)", get_last_replay, stream); signal_handler_t *sh = obs_output_get_signal_handler(output); signal_handler_add(sh, "void saved()"); + signal_handler_add(sh, "void saving(ptr output)"); return stream; } static void replay_buffer_destroy(void *data) { - struct ffmpeg_muxer *stream = data; - if (stream->hotkey) - obs_hotkey_unregister(stream->hotkey); ffmpeg_mux_destroy(data); } @@ -1176,6 +1161,12 @@ audio_dts_offsets); } + calldata_t cd = {0}; + calldata_set_ptr(&cd, "output", stream->output); + signal_handler_t *sh = obs_output_get_signal_handler(stream->output); + signal_handler_signal(sh, "saving", &cd); + calldata_free(&cd); + generate_filename(stream, &stream->path, true); os_atomic_set_bool(&stream->muxing, true);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/obs-ffmpeg-output.c -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/obs-ffmpeg-output.c
Changed
@@ -194,12 +194,8 @@ context->colorspace = data->config.colorspace; context->thread_count = 0; -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(61, 13, 100) - pix_fmts = data->vcodec->pix_fmts; -#else avcodec_get_supported_config(context, data->vcodec, AV_CODEC_CONFIG_PIX_FORMAT, 0, (const void **)&pix_fmts, NULL); -#endif closest_format = data->config.format; if (pix_fmts) { @@ -333,12 +329,8 @@ if (aoi.speakers == SPEAKERS_4POINT1) context->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT1; -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(61, 13, 100) - sample_fmts = data->acodec->sample_fmts; -#else avcodec_get_supported_config(context, data->acodec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, (const void **)&sample_fmts, NULL); -#endif context->sample_fmt = sample_fmts ? sample_fmts0 : AV_SAMPLE_FMT_FLTP;
View file
obs-studio-32.2.2.tar.xz/plugins/obs-ffmpeg/texture-amf.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-ffmpeg/texture-amf.cpp
Changed
@@ -1720,8 +1720,8 @@ amf_int64 b_max = 0; if (get_avc_property(enc, B_PIC_PATTERN, &b_frames) && - get_avc_property(enc, MAX_CONSECUTIVE_BPICTURES, &b_max)) { - enc->dts_offset = b_frames + 1; + get_avc_property(enc, MAX_CONSECUTIVE_BPICTURES, &b_max) && b_frames > 0) { + enc->dts_offset = std::min(b_frames, b_max) + 1; } else { enc->dts_offset = 0; } @@ -2543,18 +2543,6 @@ if (res == AMF_OK && p.type == AMF_VARIANT_INTERFACE) { enc->header = AMFBufferPtr(p.pInterface); } - - if (enc->bframes_supported) { - amf_int64 b_frames = 0; - amf_int64 b_max = 0; - - if (get_av1_property(enc, B_PIC_PATTERN, &b_frames) && - get_av1_property(enc, MAX_CONSECUTIVE_BPICTURES, &b_max)) { - enc->dts_offset = b_frames + 1; - } else { - enc->dts_offset = 0; - } - } } static void *amf_av1_create_texencode(obs_data_t *settings, obs_encoder_t *encoder)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-filters/color-grade-filter.c -> obs-studio-33.0.0.tar.xz/plugins/obs-filters/color-grade-filter.c
Changed
@@ -30,7 +30,7 @@ gs_effect_t *effect; gs_texture_t *target; - gs_image_file_t image; + gs_image_file_ex_t image; uint32_t cube_width; void *cube_data; @@ -243,7 +243,7 @@ filter->cube_data = NULL; obs_enter_graphics(); - gs_image_file_free(&filter->image); + gs_image_file_ex_free(&filter->image); gs_voltexture_destroy(filter->target); filter->target = NULL; obs_leave_graphics(); @@ -261,7 +261,7 @@ filter->cube_data = load_cube_file(path, &filter->cube_width, &filter->domain_min, &filter->domain_max, &clut_dim); } else { - gs_image_file_init(&filter->image, path); + gs_image_file_ex_init(&filter->image, path, GS_IMAGE_ALPHA_STRAIGHT); filter->cube_width = LUT_WIDTH; } @@ -384,7 +384,7 @@ obs_enter_graphics(); gs_effect_destroy(filter->effect); gs_voltexture_destroy(filter->target); - gs_image_file_free(&filter->image); + gs_image_file_ex_free(&filter->image); obs_leave_graphics(); bfree(filter->cube_data);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-filters/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-filters/data/locale/et-EE.ini
Changed
@@ -55,6 +55,8 @@ HdrTonemap.SdrOutputMaximum="SDR väljundi maksimum" SdrOnHdr.Description="OBS saab SDR-i kuvada HDR-režiimis automaatselt. Kasuta seda filtrit ainult siis, kui vajad konkreetse allika jaoks täiendavat kontrolli.\nSellel filtril ei ole HDR-allikate puhul mingit mõju." SdrOnHdr.SdrWhiteLevel="SDR valge värvi tase" +SdrOnHdr.GammaPower="Võimsus" +SdrOnHdr.Power="Võimsus" ScrollFilter.SpeedX="Horisontaalne kiirus" ScrollFilter.SpeedY="Vertikaalne kiirus" ScrollFilter.LimitWidth="Piira laiust"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-filters/data/locale/ja-JP.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-filters/data/locale/ja-JP.ini
Changed
@@ -4,6 +4,7 @@ AsyncDelayFilter="映像の遅延 (非同期)" CropFilter="クロップ/パッド" HdrTonemapFilter="HDRトーンマッピング (上書き)" +SdrOnHdrFilter="SDRをHDRに合成 (上書き)" ScrollFilter="スクロール" ChromaKeyFilter="クロマキー" ColorKeyFilter="カラーキー"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-filters/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-filters/data/locale/kaa.ini
Changed
@@ -1,12 +1,16 @@ ColorGradeFilter="LUTtı qollanıw" -Gain="Kúsheytiw" -DelayMs="Irkilis" +ChromaKeyFilter="Хромакей" +NoiseSuppress="Шаўқымды басыў (Noise Suppression)" +Gain="Күшейтиў (Gain)" +DelayMs="Иркилис" Type="Túr" Path="Jol" Color="Reń" ColorAdd="Reń qosıw" Opacity="Móldirlik" +Contrast="Контраст" Brightness="Jarıqlıq" +Gamma="Гамма" SdrOnlyInfo="Maǵlıwmat: sazlawlar tek SDR videoǵa qollanıladı." BrowsePath.Images="Barlıq súwret faylları" BrowsePath.AllFiles="Barlıq fayllar"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-filters/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-filters/data/locale/tr-TR.ini
Changed
@@ -15,15 +15,15 @@ UndistortCenter="Ultra genişten boyutlandırırken görüntü merkezindeki bozulmayı düzelt" NoiseGate="Gürültü Filtresi" NoiseSuppress="Gürültü Bastırma" -InvertPolarity="Polariteyi ters çevir" +InvertPolarity="Kutupsallığı Ters Çevir" Gain="Kazanç" DelayMs="Gecikme" Type="Türü" MaskBlendType.MaskColor="Alfa Maskesi (Renk Kanalı)" MaskBlendType.MaskAlpha="Alfa Maskesi (Alfa Kanalı)" -MaskBlendType.BlendMultiply="Blend (Çoğaltma)" -MaskBlendType.BlendAddition="Blend (Ekleme)" -MaskBlendType.BlendSubtraction="Blend (Çıkarma)" +MaskBlendType.BlendMultiply="Harmanla (Çoğaltma)" +MaskBlendType.BlendAddition="Harmanla (Ekleme)" +MaskBlendType.BlendSubtraction="Harmanla (Çıkarma)" Path="Dosya Yolu" Color="Renk" ColorMultiply="Renk Katsayısı"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-filters/mask-filter.c -> obs-studio-33.0.0.tar.xz/plugins/obs-filters/mask-filter.c
Changed
@@ -37,7 +37,7 @@ float update_time_elapsed; gs_texture_t *target; - gs_image_file_t image; + gs_image_file_ex_t image; struct vec4 color; bool lock_aspect; }; @@ -47,6 +47,7 @@ struct stat stats; if (os_stat(filename, &stats) != 0) return -1; + return stats.st_mtime; } @@ -59,7 +60,7 @@ static void mask_filter_image_unload(struct mask_filter_data *filter) { obs_enter_graphics(); - gs_image_file_free(&filter->image); + gs_image_file_ex_free(&filter->image); obs_leave_graphics(); } @@ -71,11 +72,11 @@ if (path && *path) { filter->image_file_timestamp = get_modified_timestamp(path); - gs_image_file_init(&filter->image, path); + gs_image_file_ex_init(&filter->image, path, GS_IMAGE_ALPHA_STRAIGHT); filter->update_time_elapsed = 0; obs_enter_graphics(); - gs_image_file_init_texture(&filter->image); + gs_image_file_ex_init_texture(&filter->image); obs_leave_graphics(); } @@ -93,12 +94,14 @@ if (filter->image_file) bfree(filter->image_file); + filter->image_file = bstrdup(path); if (srgb) vec4_from_rgba_srgb(&filter->color, color); else vec4_from_rgba(&filter->color, color); + filter->color.w = opacity; mask_filter_image_load(filter); @@ -209,7 +212,7 @@ obs_enter_graphics(); gs_effect_destroy(filter->effect); - gs_image_file_free(&filter->image); + gs_image_file_ex_free(&filter->image); obs_leave_graphics(); bfree(filter); @@ -235,9 +238,9 @@ if (!filter->last_time) filter->last_time = cur_time; - gs_image_file_tick(&filter->image, cur_time - filter->last_time); + gs_image_file_ex_tick(&filter->image, cur_time - filter->last_time); obs_enter_graphics(); - gs_image_file_update_texture(&filter->image); + gs_image_file_ex_update_texture(&filter->image); obs_leave_graphics(); filter->last_time = cur_time;
View file
obs-studio-32.2.2.tar.xz/plugins/obs-libfdk/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-libfdk/CMakeLists.txt
Changed
@@ -2,7 +2,6 @@ option(ENABLE_LIBFDK "Enable FDK AAC support" OFF) if(NOT ENABLE_LIBFDK) - target_disable(obs-libfdk) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/obs-libfdk/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-libfdk/data/locale/kaa.ini
Changed
@@ -1,1 +1,2 @@ -Bitrate="Bit tezligi" +Bitrate="Битрейт" +Afterburner="AAC Afterburner қосыў"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-nvenc/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-nvenc/CMakeLists.txt
Changed
@@ -6,7 +6,6 @@ if(NOT ENABLE_NVENC) target_disable_feature(obs-nvenc "NVIDIA Hardware Encoder") - target_disable(obs-nvenc) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/obs-nvenc/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-nvenc/data/locale/kaa.ini
Changed
@@ -1,13 +1,7 @@ -RateControl="Tezlikti baqlaw" -CBR="Turaqlı bit tezligi" -VBR="Ózgermeli bit tezligi" -CQP="Turaqlı QP" -Bitrate="Bit tezligi" -Profile="Profil" -BframeRefMode.Disabled="Iskerliksiz" -BframeRefMode.Each="Hár biri" -SplitEncode.Auto="Avtomatik" -SplitEncode.Disabled="Iskerliksiz" -SplitEncode.Enabled="Eki tárepke bóliw" -SplitEncode.ThreeWay="Úsh tárepke bóliw" -CheckDrivers="Eń sońģı <a href=\"https://obsproject.com/go/nvidia-drivers\">NVIDIA</a> drayverin ornatıp kóriń." +Bitrate="Битрейт" +Tuning.hq="Жоқары сапа" +Profile="Профиль" +BframeRefMode.Disabled="Өширилген" +SplitEncode.Auto="Автоматикалық" +SplitEncode.Disabled="Өширилген" +CQLevel="CQ дәрежеси"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-nvenc/nvenc-helpers.c -> obs-studio-33.0.0.tar.xz/plugins/obs-nvenc/nvenc-helpers.c
Changed
@@ -101,7 +101,9 @@ bool load_nvenc_lib(void) { -#ifdef _WIN32 +#if defined(_M_ARM64) + nvenc_lib = os_dlopen("nvEncodeAPI.dll"); +#elif defined(_WIN32) nvenc_lib = os_dlopen("nvEncodeAPI64.dll"); #else nvenc_lib = os_dlopen("libnvidia-encode.so.1");
View file
obs-studio-32.2.2.tar.xz/plugins/obs-outputs/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-outputs/CMakeLists.txt
Changed
@@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 3.28...3.30) -set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) -find_package(MbedTLS REQUIRED) -set(CMAKE_FIND_PACKAGE_PREFER_CONFIG FALSE) +find_package(MbedTLS 3...<4 REQUIRED) find_package(ZLIB REQUIRED) find_package(jansson REQUIRED)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-outputs/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-outputs/data/locale/kaa.ini
Changed
@@ -1,4 +1,7 @@ -FLVOutput.FilePath="Faylǵa jol" -Default="Aldınnan ornatılǵan" -IPFamily.V4Only="Tek IPv4" -IPFamily.V6Only="Tek IPv6" +FLVOutput.FilePath="Файл жолы" +Default="Әдепки" +MP4Output.FilePath="Файл жолы" +MP4Output.StartChapter="Иске түсириў" +MP4Output.UnnamedChapter="Атамасыз" +IPFamily.V4Only="Тек IPv4" +IPFamily.V6Only="Тек IPv6"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-outputs/mp4-mux.c -> obs-studio-33.0.0.tar.xz/plugins/obs-outputs/mp4-mux.c
Changed
@@ -2501,18 +2501,30 @@ if (!count) return; - /* Only iterate upt to penultimate packet so we can determine duration - * for all processed packets. */ - for (size_t i = 0; i < count - 1; i++) { + /* Unless it is the final flush, only iterate up to penultimate packet so we can determine duration for all + * processed packets. */ + const bool final_flush = mux->next_frag_pts == 0; + const size_t end_offset = final_flush ? 0 : 1; + + for (size_t i = 0; i < count - end_offset; i++) { struct encoder_packet *pkt = get_pkt_at(&track->packets, i); - if (mux->next_frag_pts && packet_pts_usec(pkt) >= mux->next_frag_pts) + if (!final_flush && packet_pts_usec(pkt) >= mux->next_frag_pts) break; - struct encoder_packet *next = get_pkt_at(&track->packets, i + 1); + uint32_t duration; + if (i < count - 1) { + /* If a next packet is available: Duration is just distance between current and next DTS. */ + struct encoder_packet *next = get_pkt_at(&track->packets, i + 1); + duration = (uint32_t)(next->dts - pkt->dts); + } else { + /* If this is the last packet, and we're doing a final flush: Reuse the previous duration */ + if (!track->fragment_samples.num) + break; /* no previous sample */ + + duration = track->fragment_samples.arraytrack->fragment_samples.num - 1.duration; + } - /* Duration is just distance between current and next DTS. */ - uint32_t duration = (uint32_t)(next->dts - pkt->dts); uint32_t sample_count = 1; uint32_t size = (uint32_t)pkt->size; int32_t offset = (int32_t)(pkt->pts - pkt->dts);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-outputs/mp4-output.c -> obs-studio-33.0.0.tar.xz/plugins/obs-outputs/mp4-output.c
Changed
@@ -51,6 +51,7 @@ struct serializer serializer; bool enable_bpm; + bool received_first_keyframe; volatile bool active; volatile bool stopping; @@ -348,8 +349,11 @@ return true; /* reached maximum duration */ - if (out->max_time > 0 && packet->dts_usec - out->start_time >= out->max_time) - return true; + if (out->max_time > 0) { + const int64_t current_runtime = packet->dts_usec - out->start_time; + /* Allow a small error in timestamps (up to 1 ms). */ + return llabs(out->max_time - current_runtime) < 1000LL; + } return false; } @@ -532,6 +536,13 @@ } } + /* Correct start time for b-frames */ + if (!out->received_first_keyframe && packet->type == OBS_ENCODER_VIDEO && packet->track_idx == 0 && + packet->keyframe) { + out->start_time = packet->dts_usec; + out->received_first_keyframe = true; + } + if (out->split_file_enabled) { if (out->split_buffer.num) { int64_t pts_usec = packet_pts_usec(packet);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-qsv11/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-qsv11/CMakeLists.txt
Changed
@@ -3,7 +3,6 @@ option(ENABLE_QSV11 "Build Intel QSV11 Hardware Encoder." TRUE) if(NOT ENABLE_QSV11) target_disable_feature(obs-qsv11 "Intel QSV11 Hardware Encoder") - target_disable(obs-qsv11) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/obs-qsv11/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-qsv11/data/locale/kaa.ini
Changed
@@ -1,10 +1,11 @@ -Bitrate="Bit tezligi" -Profile="Profil" -ICQQuality="ICQ sapası" -Latency="Iskilis" -TargetUsage.TU1="TU1: Júdá ásten (eń jaqsı sapa)" -TargetUsage.TU2="TU2: Ástenlew" -TargetUsage.TU3="TU3: ásten" -TargetUsage.TU5="TU5: Tez" -TargetUsage.TU6="TU6: Tezirek" -TargetUsage.TU7="TU7: Júdá tez (eń jaqsı tezlik)" +Bitrate="Битрейт" +MaxBitrate="Максимал битрейт" +Profile="Профиль" +ICQQuality="ICQ сапасы" +Latency="Иркилис" +TargetUsage.TU1="TU1: Жүдә әстен (ең жақсы сапа)" +TargetUsage.TU2="TU2: Әстенлеў" +TargetUsage.TU3="TU3: Әстен" +TargetUsage.TU5="TU5: Тез" +TargetUsage.TU6="TU6: Тезирек" +TargetUsage.TU7="TU7: Жүдә тез (ең жақсы тезлик)"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-text/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-text/data/locale/kaa.ini
Changed
@@ -1,29 +1,15 @@ -TextGDIPlus="Tekst (GDI+)" -Font="Shrift" -Text="Tekst" -ReadFromFile="Fayldan oqıw" -TextFile="Tekst faylı (UTF-8)" -Filter.TextFiles="Tekst fayllar" -Filter.AllFiles="Barlıq fayllar" -Color="Reń" -Opacity="Móldirlik" -Gradient.Color="Gradient reńi" -BkColor="Fon reńi" -BkOpacity="Fon móldirligi" -Alignment="Tegislew" -Alignment.Left="Shep" -Alignment.Center="Oray" -Alignment.Right="Oń" -VerticalAlignment.Top="Joqarı" -VerticalAlignment.Bottom="Tómen" -Outline="Jiyek sızıq" -Outline.Size="Jiyek sızıq qalıńlıǵı" -Outline.Color=" Jiyek sızıq reńi" -Outline.Opacity="Jiyek sızıq móldirligi" -Width="Eni" -Height="Uzınlıǵı" -Transform="Tekstti ózgertiw" -Transform.None="Heshqaysısı" -Transform.Uppercase="Bas hárip" -Transform.Lowercase="Kishi hárip" -Transform.Startcase="Hár sóz bas háripten" +TextGDIPlus="Текст (GDI+)" +Font="Шрифт" +Text="Текст" +ReadFromFile="Файлдан оқыў" +Color="Рең" +Gradient="Градиент" +Gradient.Color="Градиента реңи" +BkColor="Фон реңи" +Alignment="Тегислеў" +Width="Ени" +Height="Узынлығы" +Transform.None="Жоқ" +Transform.Uppercase="Бас ҳәрип" +Transform.Lowercase="Киши ҳәрип" +Transform.Startcase="Ҳәр сөз бас ҳәриптен"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-transitions/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-transitions/data/locale/kaa.ini
Changed
@@ -1,22 +1,18 @@ -CutTransition="Qıyıw" -Direction="Baǵdar" -Direction.Left="Shep" Direction.Right="Oń" -Direction.Up="Joqarıǵa" -Direction.Down="Tómenge" -Color="Reń" -VideoFile="Videofayl" -FileFilter.VideoFiles="Videofayllar" -FileFilter.AllFiles="Barlıq fayllar" -TransitionPointTypeTime="Waqıt" -LumaWipe.Image="Súwret" -LumaWipe.Softness="Jumsaqlıq" -LumaWipe.Type.Burst="Jarılıw" -LumaWipe.Type.Circles="Sheńberler" -LumaWipe.Type.Clock="Saat" -LumaWipe.Type.Cloud="Bult" -LumaWipe.Type.Fan="Samallatqısh" -LumaWipe.Type.Square="Kvadrat" -LumaWipe.Type.Squares="Kvadratlar" -LumaWipe.Type.Stripes="Sızıqlar" -LumaWipe.Type.Watercolor="Akvarel" +Color="Рең" +TransitionPointTypeFrame="Кадр" +TransitionPointTypeTime="Ўақыт" +LumaWipe.Image="Суўрет" +LumaWipe.Softness="Жумсақлық" +LumaWipe.Type.Burst="Жарылыў" +LumaWipe.Type.Circles="Шеңберлер" +LumaWipe.Type.Clock="Саат" +LumaWipe.Type.Cloud="Булт" +LumaWipe.Type.Fractal="Фрактал" +LumaWipe.Type.Iris="Ирис" +LumaWipe.Type.Sinus9="Синус 9" +LumaWipe.Type.Spiral="Спираль" +LumaWipe.Type.Square="Квадрат" +LumaWipe.Type.Squares="Квадратлар" +LumaWipe.Type.Stripes="Сызықлар" +LumaWipe.Type.Watercolor="Акварель"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-transitions/transition-luma-wipe.c -> obs-studio-33.0.0.tar.xz/plugins/obs-transitions/transition-luma-wipe.c
Changed
@@ -25,7 +25,7 @@ gs_eparam_t *ep_invert; gs_eparam_t *ep_softness; - gs_image_file_t luma_image; + gs_image_file_ex_t luma_image; bool invert_luma; float softness; obs_data_t *wipes_list; @@ -53,13 +53,13 @@ char *file = obs_module_file(path.array); obs_enter_graphics(); - gs_image_file_free(&lwipe->luma_image); + gs_image_file_ex_free(&lwipe->luma_image); obs_leave_graphics(); - gs_image_file_init(&lwipe->luma_image, file); + gs_image_file_ex_init(&lwipe->luma_image, file, GS_IMAGE_ALPHA_STRAIGHT); obs_enter_graphics(); - gs_image_file_init_texture(&lwipe->luma_image); + gs_image_file_ex_init_texture(&lwipe->luma_image); obs_leave_graphics(); bfree(file); @@ -117,7 +117,7 @@ struct luma_wipe_info *lwipe = data; obs_enter_graphics(); - gs_image_file_free(&lwipe->luma_image); + gs_image_file_ex_free(&lwipe->luma_image); obs_leave_graphics(); obs_data_release(lwipe->wipes_list);
View file
obs-studio-32.2.2.tar.xz/plugins/obs-transitions/transition-stinger.c -> obs-studio-33.0.0.tar.xz/plugins/obs-transitions/transition-stinger.c
Changed
@@ -29,7 +29,7 @@ float transition_b_mul; bool transitioning; bool transition_point_is_frame; - int monitoring_type; + bool monitoring; enum fade_style fade_style; bool track_matte_enabled; @@ -136,8 +136,8 @@ obs_source_set_muted(s->matte_source, true); } - s->monitoring_type = (int)obs_data_get_int(settings, "audio_monitoring"); - obs_source_set_monitoring_type(s->media_source, s->monitoring_type); + s->monitoring = obs_data_get_bool(settings, "enable_monitoring"); + obs_source_set_monitoring_enabled(s->media_source, s->monitoring); s->fade_style = (enum fade_style)obs_data_get_int(settings, "audio_fade_style"); @@ -729,14 +729,7 @@ dstr_free(&filter); // audio output settings - obs_property_t *monitor_list = obs_properties_add_list(ppts, "audio_monitoring", - obs_module_text("AudioMonitoring"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(monitor_list, obs_module_text("AudioMonitoring.None"), OBS_MONITORING_TYPE_NONE); - obs_property_list_add_int(monitor_list, obs_module_text("AudioMonitoring.MonitorOnly"), - OBS_MONITORING_TYPE_MONITOR_ONLY); - obs_property_list_add_int(monitor_list, obs_module_text("AudioMonitoring.Both"), - OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); + obs_properties_add_bool(ppts, "enable_monitoring", obs_module_text("AudioMonitoring")); // audio fade settings obs_property_t *audio_fade_style = obs_properties_add_list(
View file
obs-studio-32.2.2.tar.xz/plugins/obs-vst/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-vst/CMakeLists.txt
Changed
@@ -3,7 +3,6 @@ option(ENABLE_VST "Enable building OBS with VST plugin" ON) if(NOT ENABLE_VST) - target_disable(obs-vst) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/obs-vst/data/locale/hu-HU.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-vst/data/locale/hu-HU.ini
Changed
@@ -1,4 +1,4 @@ -OpenPluginInterface="Bővítmény interfész megnyitása" -ClosePluginInterface="Bővítmény interfész bezárása" +OpenPluginInterface="Bővítmény felületének megnyitása" +ClosePluginInterface="Bővítmény felületének bezárása" VstPlugin="VST 2.x bővítmény" OpenInterfaceWhenActive="Interfész megnyitása, amikor aktív"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-vst/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-vst/data/locale/kaa.ini
Changed
@@ -1,3 +1,3 @@ -OpenPluginInterface="Plagin interfeysin ashıw" -ClosePluginInterface="Plagin interfeysin jabıw" -VstPlugin="Plagin VST 2.x" +OpenPluginInterface="Плагин интерфейсин ашыў" +ClosePluginInterface="Плагин интерфейсин жабыў" +VstPlugin="Плагин VST 2.x"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-webrtc/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-webrtc/CMakeLists.txt
Changed
@@ -2,7 +2,6 @@ option(ENABLE_WEBRTC "Enable WebRTC Output support" ON) if(NOT ENABLE_WEBRTC) - target_disable(obs-webrtc) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/obs-webrtc/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-webrtc/data/locale/kaa.ini
Changed
@@ -1,1 +1,3 @@ +Output.Name="WHIP шығысы" Service.Name="WHIP хызмети" +Service.BearerToken="Ийелик токени"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/.github/workflows/crowdin_upload.yml -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/.github/workflows/crowdin_upload.yml
Changed
@@ -9,13 +9,13 @@ upload-language-files: name: Upload Language Files 🌐 if: github.repository_owner == 'obsproject' - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 100 - name: Upload US English Language Files 🇺🇸 - uses: obsproject/obs-crowdin-sync/upload@30b5446e3b5eb19595aa68a81ddf896a857302cf + uses: obsproject/obs-crowdin-sync/upload@4b488c7ced03aa109d9f12529bd91c26c54b3e89 env: CROWDIN_PAT: ${{ secrets.CROWDIN_SYNC_CROWDIN_PAT }} GITHUB_EVENT_BEFORE: ${{ github.event.before }}
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/.github/workflows/generate_docs.yml -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/.github/workflows/generate_docs.yml
Changed
@@ -18,7 +18,7 @@ IS_CI: "true" steps: - name: 'Checkout' - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: path: ${{ github.workspace }}/obs-websocket - name: 'Generate docs'
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/.github/workflows/lint.yml -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/.github/workflows/lint.yml
Changed
@@ -15,10 +15,11 @@ if: contains(github.event.head_commit.message, 'skip ci') != true steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Generate docs run: cd docs && ./build_docs.sh - name: Run markdownlint-cli - uses: nosborn/github-action-markdown-cli@v3.0.1 + uses: nosborn/github-action-markdown-cli@508d6cefd8f0cc99eab5d2d4685b1d5f470042c1 # v3.5.0 with: files: . + ignore_files: docs/docs/partials/introduction.md
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/CMakeLists.txt
Changed
@@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.28...3.30) -set(obs-websocket_VERSION 5.7.4) +set(obs-websocket_VERSION 5.7.6) set(OBS_WEBSOCKET_RPC_VERSION 1) include(cmake/obs-websocket-api.cmake)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/README.md -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/README.md
Changed
@@ -3,7 +3,7 @@ # obs-websocket <p align="center"> - <img src="/.github/images/obsws_logo.png" width=150 align="center"> + <img src="/.github/images/obsws_logo.png" alt="OBS WebSocket logo" width=150 align="center"> </p> WebSocket API for OBS Studio. @@ -75,19 +75,19 @@ #### Individuals -<a href="https://opencollective.com/obs-websocket-dev"><img src="https://opencollective.com/obs-websocket-dev/individuals.svg?width=890"></a> +<a href="https://opencollective.com/obs-websocket-dev"><img src="https://opencollective.com/obs-websocket-dev/individuals.svg?width=890" alt="Individual contributors to obs-websocket-dev on Open Collective"></a> #### Organizations Support this project with your organization. Your logo will show up here with a link to your website. Contribute(https://opencollective.com/obs-websocket-dev/contribute) -<a href="https://opencollective.com/obs-websocket-dev/organization/0/website"><img src="https://opencollective.com/obs-websocket-dev/organization/0/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/1/website"><img src="https://opencollective.com/obs-websocket-dev/organization/1/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/2/website"><img src="https://opencollective.com/obs-websocket-dev/organization/2/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/3/website"><img src="https://opencollective.com/obs-websocket-dev/organization/3/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/4/website"><img src="https://opencollective.com/obs-websocket-dev/organization/4/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/5/website"><img src="https://opencollective.com/obs-websocket-dev/organization/5/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/6/website"><img src="https://opencollective.com/obs-websocket-dev/organization/6/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/7/website"><img src="https://opencollective.com/obs-websocket-dev/organization/7/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/8/website"><img src="https://opencollective.com/obs-websocket-dev/organization/8/avatar.svg"></a> -<a href="https://opencollective.com/obs-websocket-dev/organization/9/website"><img src="https://opencollective.com/obs-websocket-dev/organization/9/avatar.svg"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/0/website"><img src="https://opencollective.com/obs-websocket-dev/organization/0/avatar.svg" alt="OBS WebSocket supporting organization 0"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/1/website"><img src="https://opencollective.com/obs-websocket-dev/organization/1/avatar.svg" alt="OBS WebSocket supporting organization 1"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/2/website"><img src="https://opencollective.com/obs-websocket-dev/organization/2/avatar.svg" alt="OBS WebSocket supporting organization 2"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/3/website"><img src="https://opencollective.com/obs-websocket-dev/organization/3/avatar.svg" alt="OBS WebSocket supporting organization 3"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/4/website"><img src="https://opencollective.com/obs-websocket-dev/organization/4/avatar.svg" alt="OBS WebSocket supporting organization 4"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/5/website"><img src="https://opencollective.com/obs-websocket-dev/organization/5/avatar.svg" alt="OBS WebSocket supporting organization 5"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/6/website"><img src="https://opencollective.com/obs-websocket-dev/organization/6/avatar.svg" alt="OBS WebSocket supporting organization 6"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/7/website"><img src="https://opencollective.com/obs-websocket-dev/organization/7/avatar.svg" alt="OBS WebSocket supporting organization 7"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/8/website"><img src="https://opencollective.com/obs-websocket-dev/organization/8/avatar.svg" alt="OBS WebSocket supporting organization 8"></a> +<a href="https://opencollective.com/obs-websocket-dev/organization/9/website"><img src="https://opencollective.com/obs-websocket-dev/organization/9/avatar.svg" alt="OBS WebSocket supporting organization 9"></a>
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/be-BY.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/be-BY.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Ці вы ўпэўненыя, што хочаце карыстацца сваім паролем?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Увага: памылковая канфігурацыя" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Пароль павінен утрымліваць 6 або больш сімвалаў." +OBSWebSocket.Settings.SafeModeWarning="Калі ўключаны бяспечны рэжым, сервер аўтаматычна не запускаецца." OBSWebSocket.SessionTable.Title="Злучаныя сеансы WebSocket" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Аддалены адрас" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Даўжыня сеансу"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/ca-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/ca-ES.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Segur que voleu utilitzar la vostra contrasenya?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Error: Configuració no vàlida" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Utilitzeu una contrasenya de 6 o més caràcters." +OBSWebSocket.Settings.SafeModeWarning="El servidor no s'inicia automàticament quan el mode segur està activat." OBSWebSocket.SessionTable.Title="Sessions de WebSocket connectades" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adreça remota" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durada de la sessió"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/en-US.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/en-US.ini
Changed
@@ -22,6 +22,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Are you sure you want to use your own password?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Error: Invalid Configuration" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="You must use a password that is 6 or more characters." +OBSWebSocket.Settings.SafeModeWarning="Server is not started automatically when Safe Mode is enabled." OBSWebSocket.SessionTable.Title="Connected WebSocket Sessions" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Remote Address"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/et-EE.ini
Changed
@@ -17,8 +17,9 @@ OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Hoiatus: võimalik turvaprobleem" OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket salvestab serveri salasõna lihtsa tekstina. obs-websocket'i poolt loodud salasõna kasutamine on väga soovitatav." OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Kas oled kindel, et soovid kasutada oma salasõna?" -OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Viga: vigane konfiguratsioon" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Viga: kehteetu konfiguratsioon" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Pead kasutama salasõna, mis koosneb 6 või enamast tähemärgist." +OBSWebSocket.Settings.SafeModeWarning="Turvarežiimi sisselülitamisel ei käivitu server automaatselt." OBSWebSocket.SessionTable.Title="Ühendatud WebSocket'i seansid" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Kaugjuhtimise aadress" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Seansi kestvus"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/fa-IR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/fa-IR.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="آیا مطمئن هستید که می خواهید از رمز عبور خود استفاده کنید؟" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="خطا: پیکربندی نامعتبر است" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="باید از رمز عبور 6 کاراکتر یا بیشتر استفاده کنید." +OBSWebSocket.Settings.SafeModeWarning="هنگامی که حالت ایمن فعال است، سرور بهطور خودکار راهاندازی نمیشود." OBSWebSocket.SessionTable.Title="جلسات سوکت وب متصل" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="آدرس از راه دور" OBSWebSocket.SessionTable.SessionDurationColumnTitle="مدت زمان جلسه"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/fr-FR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/fr-FR.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Êtes-vous sûr(e) de vouloir utiliser votre propre mot de passe ?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Erreur : Configuration invalide" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Vous devez utiliser un mot de passe de 6 caractères ou plus." +OBSWebSocket.Settings.SafeModeWarning="Le serveur ne démarre pas automatiquement quand le Mode Sécurisé est activé." OBSWebSocket.SessionTable.Title="Sessions WebSocket connectées" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adresse distante" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durée de session"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/hu-HU.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/hu-HU.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Biztos, hogy a saját jelszavát használja?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Hiba: Érvénytelen konfiguráció" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Legalább 6 karakterből álló jelszót kell használnia." +OBSWebSocket.Settings.SafeModeWarning="A kiszolgáló nem indul el automatikusan, ha a csökkentett mód be van kapcsolva." OBSWebSocket.SessionTable.Title="Kapcsolódott WebSocket munkamenetek" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Távoli cím" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Munkamenet hossza"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/id-ID.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/id-ID.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Apakah Anda yakin ingin menggunakan kata sandi sendiri?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Galat: Konfigurasi Tidak Berlaku" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Anda harus menggunakan kata sandi yang minimal 6 karakter atau lebih." +OBSWebSocket.Settings.SafeModeWarning="Server tidak dimulai secara otomatis ketika Mode Aman aktif." OBSWebSocket.SessionTable.Title="Sesi WebSocket yang Terhubung" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Alamat Kendali" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durasi Sesi"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/ja-JP.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/ja-JP.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="自分が設定したパスワードを使用してもよろしいですか?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="エラー: 無効な設定" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="6文字以上のパスワードを使用する必要があります。" +OBSWebSocket.Settings.SafeModeWarning="セーフモードが有効な場合、サーバーは自動的に起動しません。" OBSWebSocket.SessionTable.Title="接続されているWebSocketセッション" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="リモートアドレス" OBSWebSocket.SessionTable.SessionDurationColumnTitle="セッション時間"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/kaa.ini
Changed
@@ -1,8 +1,4 @@ -OBSWebSocket.Settings.DialogTitle="WebSocket serverinıń sazlawları" -OBSWebSocket.Settings.PluginSettingsTitle="Plagin sazlawları" -OBSWebSocket.Settings.ServerEnable="WebSocket serverin qosıw" -OBSWebSocket.Settings.DebugEnable="Nasazlıqtı ońlaw jurnalın qosıw" -OBSWebSocket.Settings.ServerSettingsTitle="Server sazlawları" +OBSWebSocket.Settings.ServerSettingsTitle="Сервер сазлаўлары" OBSWebSocket.Settings.Password="Сервер пароли" OBSWebSocket.Settings.GeneratePassword="Пароль жаратыў" OBSWebSocket.Settings.ServerPort="Сервер порты" @@ -22,4 +18,6 @@ OBSWebSocket.ConnectInfo.CopyText="Көширип алыў" OBSWebSocket.ConnectInfo.ServerPort="Сервер порты" OBSWebSocket.ConnectInfo.ServerPassword="Сервер пароли" +OBSWebSocket.ConnectInfo.QrTitle="Жалғаныў QR-коды" OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket кириў қәтелиги" +OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 клиенти кире алмады."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/kab-KAB.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/kab-KAB.ini
Changed
@@ -8,7 +8,7 @@ OBSWebSocket.Settings.AuthRequired="Seqdec asesteb" OBSWebSocket.Settings.Password="Awal n uɛeddi n uqeddac" OBSWebSocket.Settings.GeneratePassword="Sarew-d awal n uɛeddi" -OBSWebSocket.Settings.ServerPort="Asagen n uqeddac " +OBSWebSocket.Settings.ServerPort="Tawwurt n uqeddac" OBSWebSocket.Settings.ShowConnectInfo="Sken talɣut n tuqqna" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Ɣur-k·m: Atan akka tura s wudem Srid" OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Yettban-d dakken tasufeɣt (asuddem, asekles, atg.) attan termed akka tura." @@ -29,8 +29,8 @@ OBSWebSocket.ConnectInfo.ServerPassword="Awal n uɛeddi n uqeddac" OBSWebSocket.ConnectInfo.QrTitle="Qqen QR" OBSWebSocket.TrayNotification.Identified.Title="Tuqqna tamaynut n WebSocket" -OBSWebSocket.TrayNotification.Identified.Body="Amsaɣ %1 yettwasulu" +OBSWebSocket.TrayNotification.Identified.Body="Amsaɣ %1 yettwasulu." OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Tuccḍa n usesteb n WebSocket" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Amsaɣ %1 yecceḍ deg usesteb." OBSWebSocket.TrayNotification.Disconnected.Title="Amsaɣ WebSocket isenser" -OBSWebSocket.TrayNotification.Disconnected.Body="Amsaɣ %1 yesenser" +OBSWebSocket.TrayNotification.Disconnected.Body="Amsaɣ %1 yesenser."
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/ms-MY.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/ms-MY.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Adakah anda pasti mahu menggunakan kata laluan anda sendiri?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Ralat: Konfigurasi Tidak Sah" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Anda mesti guna satu kata laluan yang terdiri daripada 6 atau lebih aksara." +OBSWebSocket.Settings.SafeModeWarning="Pelayan tidak dimulakan secara automatik apabila Mod Selamat diaktifkan." OBSWebSocket.SessionTable.Title="Sesi WebSocket Bersambung" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Alamat Jauh" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Tempoh Sesi"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/nl-NL.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/nl-NL.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Weet u zeker dat u uw eigen wachtwoord wilt gebruiken?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Fout: ongeldige configuratie" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="U moet een wachtwoord gebruiken van 6 of meer tekens." +OBSWebSocket.Settings.SafeModeWarning="De server wordt niet automatisch gestart wanneer de veilige modus is ingeschakeld." OBSWebSocket.SessionTable.Title="Verbonden WebSocket Sessies" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Extern adres" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Sessie duur"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/pl-PL.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/pl-PL.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Czy na pewno chcesz użyć własnego hasła?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Błąd: nieprawidłowa konfiguracja" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Hasło musi zawierać 6 lub więcej znaków." +OBSWebSocket.Settings.SafeModeWarning="Serwer nie uruchamia się automatycznie, gdy jest włączony Tryb Awaryjny." OBSWebSocket.SessionTable.Title="Podłączone sesje WebSocket" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adres zdalny" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Czas trwania sesji"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/pt-BR.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/pt-BR.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Deseja mesmo usar a sua própria senha?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Erro: configuração inválida" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Você deve usar uma senha que tenha 6 ou mais caracteres." +OBSWebSocket.Settings.SafeModeWarning="Servidor não é iniciado automaticamente quando Modo Seguro está habilitado." OBSWebSocket.SessionTable.Title="Sessões WebSocket conectadas" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Endereço remoto" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Duração da sessão"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/ru-RU.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/ru-RU.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Уверены, что хотите использовать собственый пароль?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Ошибка: Неверная конфигурация" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Вы должны использовать пароль длиной 6 или более символов." +OBSWebSocket.Settings.SafeModeWarning="Сервер не запускается автоматически, когда включён безопасный режим." OBSWebSocket.SessionTable.Title="Подключённые сеансы WebSocket" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Удалённый адрес" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Длительность сеанса"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/sv-SE.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/sv-SE.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Är du säker på att du vill använda ditt eget lösenord?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Fel: Ogiltig konfiguration" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Du måste använda ett lösenord som har 6 eller fler tecken." +OBSWebSocket.Settings.SafeModeWarning="Servern startas inte automatiskt när säkert läge har aktiverats." OBSWebSocket.SessionTable.Title="Anslutna WebSocket-sessioner" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Fjärradress" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Sessionens varaktighet"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/tt-RU.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/tt-RU.ini
Changed
@@ -1,3 +1,4 @@ +OBSWebSocket.Settings.PluginSettingsTitle="Кушылма көйләүләре" OBSWebSocket.Settings.ServerSettingsTitle="Сервер көйләүләре" OBSWebSocket.Settings.Password="Сервер серсүзе" OBSWebSocket.Settings.GeneratePassword="Серсүзне ясау"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/ug-CN.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/ug-CN.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="راستتىنلا ئۆزىڭىز بەلگىلىگەن ئىمنى ئىشلىتەمسىز؟" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="خاتالىق: ئىناۋەتسىز سەپلىمە" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="ئىم ئۈچۈن كەم دېگەندە 6 ياكى ئۇنىڭدىن كۆپ ھەرپ ئىشلىتىش كېرەك." +OBSWebSocket.Settings.SafeModeWarning="بىخەتەر ھالەت قوزغىتىلغاندا مۇلازىمېتىر ئۆزلۈكىدىن قوزغالمايدۇ." OBSWebSocket.SessionTable.Title="باغلانغان WebSocket سۆزلىشىشى" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="يىراقتىكى ئادرېس" OBSWebSocket.SessionTable.SessionDurationColumnTitle="سۆزلىشىش داۋاملىشىش ۋاقتى"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/uk-UA.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/uk-UA.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Ви впевнені, що хочете використовувати власний пароль?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Помилка: неправильна конфігурація" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Ви повинні використовувати пароль, що складається з 6 або більше символів." +OBSWebSocket.Settings.SafeModeWarning="Сервер не запускається автоматично, коли увімкнено безпечний режим." OBSWebSocket.SessionTable.Title="Під'єднані сеанси WebSocket" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Віддалена адреса" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Тривалість сеансу"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/zh-CN.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/zh-CN.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="您确定要使用自定义密码吗?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="错误:无效的配置" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="您的密码必须包含 6 个或以上的字符。" +OBSWebSocket.Settings.SafeModeWarning="启用安全模式后,服务器不会自动启动。" OBSWebSocket.SessionTable.Title="已连接的 WebSocket 会话" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="远程地址" OBSWebSocket.SessionTable.SessionDurationColumnTitle="会话持续时间"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/data/locale/zh-TW.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/data/locale/zh-TW.ini
Changed
@@ -19,6 +19,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="您確定要使用自己的密碼嗎?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="錯誤:設定無效" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="您必須使用 6 個字元以上的密碼。" +OBSWebSocket.Settings.SafeModeWarning="啟用安全模式時,伺服器不會自動啟動。" OBSWebSocket.SessionTable.Title="連線的 WebSocket 工作階段" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="遠端地址" OBSWebSocket.SessionTable.SessionDurationColumnTitle="工作階段時長"
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/docs/docs/generate_md.py -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/docs/docs/generate_md.py
Changed
@@ -162,7 +162,7 @@ requestsOut.append(request) if not len(requestsOut): continue - categoryFragment = get_fragment(category) + categoryFragment = get_fragment(category, False) ret += '## {} Requests\n\n'.format(category) for request in requestsOut: requestType = request'requestType' @@ -227,7 +227,7 @@ eventsOut.append(event) if not len(eventsOut): continue - categoryFragment = get_fragment(category) + categoryFragment = get_fragment(category, False) ret += '## {} Events\n\n'.format(category) for event in eventsOut: eventType = event'eventType'
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/docs/generated/protocol.md -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/docs/generated/protocol.md
Changed
@@ -2663,7 +2663,7 @@ ## Requests Table of Contents -- General Requests(#general-1-requests) +- General Requests(#general-requests) - GetVersion(#getversion) - GetStats(#getstats) - BroadcastCustomEvent(#broadcastcustomevent) @@ -2672,7 +2672,7 @@ - TriggerHotkeyByName(#triggerhotkeybyname) - TriggerHotkeyByKeySequence(#triggerhotkeybykeysequence) - Sleep(#sleep) -- Config Requests(#config-1-requests) +- Config Requests(#config-requests) - GetPersistentData(#getpersistentdata) - SetPersistentData(#setpersistentdata) - GetSceneCollectionList(#getscenecollectionlist) @@ -2694,9 +2694,9 @@ - GetSourceActive(#getsourceactive) - GetSourceScreenshot(#getsourcescreenshot) - SaveSourceScreenshot(#savesourcescreenshot) -- Canvases Requests(#canvases-1-requests) +- Canvases Requests(#canvases-requests) - GetCanvasList(#getcanvaslist) -- Scenes Requests(#scenes-1-requests) +- Scenes Requests(#scenes-requests) - GetSceneList(#getscenelist) - GetGroupList(#getgrouplist) - GetCurrentProgramScene(#getcurrentprogramscene) @@ -2708,7 +2708,7 @@ - SetSceneName(#setscenename) - GetSceneSceneTransitionOverride(#getscenescenetransitionoverride) - SetSceneSceneTransitionOverride(#setscenescenetransitionoverride) -- Inputs Requests(#inputs-1-requests) +- Inputs Requests(#inputs-requests) - GetInputList(#getinputlist) - GetInputKindList(#getinputkindlist) - GetSpecialInputs(#getspecialinputs) @@ -2737,7 +2737,7 @@ - SetInputDeinterlaceFieldOrder(#setinputdeinterlacefieldorder) - GetInputPropertiesListPropertyItems(#getinputpropertieslistpropertyitems) - PressInputPropertiesButton(#pressinputpropertiesbutton) -- Transitions Requests(#transitions-1-requests) +- Transitions Requests(#transitions-requests) - GetTransitionKindList(#gettransitionkindlist) - GetSceneTransitionList(#getscenetransitionlist) - GetCurrentSceneTransition(#getcurrentscenetransition) @@ -2747,7 +2747,7 @@ - GetCurrentSceneTransitionCursor(#getcurrentscenetransitioncursor) - TriggerStudioModeTransition(#triggerstudiomodetransition) - SetTBarPosition(#settbarposition) -- Filters Requests(#filters-1-requests) +- Filters Requests(#filters-requests) - GetSourceFilterKindList(#getsourcefilterkindlist) - GetSourceFilterList(#getsourcefilterlist) - GetSourceFilterDefaultSettings(#getsourcefilterdefaultsettings) @@ -2758,7 +2758,7 @@ - SetSourceFilterIndex(#setsourcefilterindex) - SetSourceFilterSettings(#setsourcefiltersettings) - SetSourceFilterEnabled(#setsourcefilterenabled) -- Scene Items Requests(#scene-items-1-requests) +- Scene Items Requests(#scene-items-requests) - GetSceneItemList(#getsceneitemlist) - GetGroupSceneItemList(#getgroupsceneitemlist) - GetSceneItemId(#getsceneitemid) @@ -2776,7 +2776,7 @@ - SetSceneItemIndex(#setsceneitemindex) - GetSceneItemBlendMode(#getsceneitemblendmode) - SetSceneItemBlendMode(#setsceneitemblendmode) -- Outputs Requests(#outputs-1-requests) +- Outputs Requests(#outputs-requests) - GetVirtualCamStatus(#getvirtualcamstatus) - ToggleVirtualCam(#togglevirtualcam) - StartVirtualCam(#startvirtualcam) @@ -2810,12 +2810,12 @@ - ResumeRecord(#resumerecord) - SplitRecordFile(#splitrecordfile) - CreateRecordChapter(#createrecordchapter) -- Media Inputs Requests(#media-inputs-1-requests) +- Media Inputs Requests(#media-inputs-requests) - GetMediaInputStatus(#getmediainputstatus) - SetMediaInputCursor(#setmediainputcursor) - OffsetMediaInputCursor(#offsetmediainputcursor) - TriggerMediaInputAction(#triggermediainputaction) -- Ui Requests(#ui-1-requests) +- Ui Requests(#ui-requests) - GetStudioModeEnabled(#getstudiomodeenabled) - SetStudioModeEnabled(#setstudiomodeenabled) - OpenInputPropertiesDialog(#openinputpropertiesdialog)
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/src/forms/SettingsDialog.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/src/forms/SettingsDialog.cpp
Changed
@@ -48,6 +48,18 @@ ui->websocketSessionTable->horizontalHeader()->resizeSection(3, 100); // Resize Session Table column widths ui->websocketSessionTable->horizontalHeader()->resizeSection(4, 100); + if (obs_frontend_is_safe_mode_enabled()) { + QFrame *safeModeFrame = new QFrame(this); + safeModeFrame->setProperty("class", "frame-notice"); + + safeModeFrame->setLayout(new QHBoxLayout); + safeModeFrame->layout()->setContentsMargins(0, 0, 0, 0); + QLabel *safeModeText = new QLabel(obs_module_text("OBSWebSocket.Settings.SafeModeWarning"), safeModeFrame); + safeModeText->setWordWrap(true); + safeModeFrame->layout()->addWidget(safeModeText); + ui->verticalLayout->insertWidget(0, safeModeFrame); + } + // Remove the ? button on dialogs on Windows setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); @@ -56,13 +68,8 @@ connect(sessionTableTimer, &QTimer::timeout, this, &SettingsDialog::FillSessionTable); connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &SettingsDialog::DialogButtonClicked); -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) connect(ui->enableAuthenticationCheckBox, &QCheckBox::checkStateChanged, this, &SettingsDialog::EnableAuthenticationCheckBoxChanged); -#else - connect(ui->enableAuthenticationCheckBox, &QCheckBox::stateChanged, this, - &SettingsDialog::EnableAuthenticationCheckBoxChanged); -#endif connect(ui->generatePasswordButton, &QPushButton::clicked, this, &SettingsDialog::GeneratePasswordButtonClicked); connect(ui->showConnectInfoButton, &QPushButton::clicked, this, &SettingsDialog::ShowConnectInfoButtonClicked); connect(ui->serverPasswordLineEdit, &QLineEdit::textEdited, this, &SettingsDialog::PasswordEdited); @@ -123,7 +130,11 @@ return; } - ui->enableWebSocketServerCheckBox->setChecked(conf->ServerEnabled); + if (IsServerOffBySafeMode()) { + ui->enableWebSocketServerCheckBox->setChecked(false); + } else { + ui->enableWebSocketServerCheckBox->setChecked(conf->ServerEnabled); + } ui->enableSystemTrayAlertsCheckBox->setChecked(conf->AlertsEnabled); ui->enableDebugLoggingCheckBox->setChecked(conf->DebugEnabled); ui->serverPortSpinBox->setValue(conf->ServerPort); @@ -182,6 +193,8 @@ } } + ClearServerOffBySafeMode(); + bool needsRestart = (conf->ServerEnabled != ui->enableWebSocketServerCheckBox->isChecked()) || (conf->ServerPort != ui->serverPortSpinBox->value()) || (ui->enableAuthenticationCheckBox->isChecked() &&
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/src/obs-websocket.cpp -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/src/obs-websocket.cpp
Changed
@@ -47,6 +47,7 @@ WebSocketApiPtr _webSocketApi; WebSocketServerPtr _webSocketServer; SettingsDialog *_settingsDialog = nullptr; +static bool _serverOffBySafeMode = false; void OnWebSocketApiVendorEvent(std::string vendorName, std::string eventType, obs_data_t *obsEventData); void OnEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion); @@ -116,6 +117,13 @@ test_register_vendor(); #endif + if (obs_frontend_is_safe_mode_enabled()) { + _serverOffBySafeMode = true; + if (_config->ServerEnabled) + blog(LOG_INFO, "obs_module_post_load OBS is in Safe Mode. WebSocket server will not be started."); + return; + } + // Server will accept clients, but requests and events will not be served until FINISHED_LOADING occurs if (_config->ServerEnabled) { blog(LOG_INFO, "obs_module_post_load WebSocket server is enabled, starting..."); @@ -184,6 +192,16 @@ return !_config || _config->DebugEnabled; } +bool IsServerOffBySafeMode() +{ + return _serverOffBySafeMode; +} + +void ClearServerOffBySafeMode() +{ + _serverOffBySafeMode = false; +} + /** * An event has been emitted from a vendor. *
View file
obs-studio-32.2.2.tar.xz/plugins/obs-websocket/src/obs-websocket.h -> obs-studio-33.0.0.tar.xz/plugins/obs-websocket/src/obs-websocket.h
Changed
@@ -51,3 +51,6 @@ WebSocketServerPtr GetWebSocketServer(); bool IsDebugEnabled(); + +bool IsServerOffBySafeMode(); +void ClearServerOffBySafeMode();
View file
obs-studio-32.2.2.tar.xz/plugins/obs-x264/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/obs-x264/data/locale/kaa.ini
Changed
@@ -1,5 +1,5 @@ -Bitrate="Bit tezligi" +Bitrate="Битрейт" CustomBufsize="Arnawlı bufer kólemin qollanıw" -BufferSize="Bufer kólemi" -Profile="Profil" -None="(Joq)" +BufferSize="Буфер көлеми" +Profile="Профиль" +None="(Жоқ)"
View file
obs-studio-32.2.2.tar.xz/plugins/oss-audio/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/oss-audio/CMakeLists.txt
Changed
@@ -3,7 +3,6 @@ option(ENABLE_OSS "Enable building with OSS audio support" ON) if(NOT ENABLE_OSS) - target_disable(oss-audio) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/oss-audio/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/oss-audio/data/locale/kaa.ini
Changed
@@ -1,5 +1,4 @@ -CustomDSPPath="DSP arnawlı jolı" -Channels="Kanallar" -SampleFormat="Úlgi" -Default="Aldınnan ornatılǵan" -Custom="Arnawlı" +Channels="Каналлар" +SampleFormat="Үлги" +Default="Әдепки" +Custom="Арнаўлы"
View file
obs-studio-32.2.2.tar.xz/plugins/rtmp-services/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/plugins/rtmp-services/data/locale/et-EE.ini
Changed
@@ -9,4 +9,5 @@ Username="Kasutajanimi" Password="Salasõna" ShowAll="Näita kõiki teenuseid" +MultitrackVideo.Disclaimer="%1 optimeerib automaatselt sinu voogedastuse seadeid, mis võivad hõlmata mitme erineva videokvaliteedi ja/või lõuendi suuna kodeerimist. Selle valiku valimisel saadetakse %2-le teavet sinu arvuti ja tarkvara seadistuste kohta." MultitrackVideo.LearnMoreLink=" <a href='%1'>Lisateave</a>"
View file
obs-studio-32.2.2.tar.xz/plugins/rtmp-services/data/locale/it-IT.ini -> obs-studio-33.0.0.tar.xz/plugins/rtmp-services/data/locale/it-IT.ini
Changed
@@ -8,4 +8,5 @@ UseAuth="Utilizza l'autenticazione" Username="Nome utente" ShowAll="Mostra tutti i servizi" +MultitrackVideo.Disclaimer="%1 Ottimizza automaticamente le tue impostazioni per le dirette, che potrebbe includere la codifica di qualità video e/o orientamenti della tela multipli. Selezionando questa opzione invierà %2 informazioni sul tuo computer e impostazioni del software." MultitrackVideo.LearnMoreLink=" <a href='%1'>Scopri di più</a>"
View file
obs-studio-32.2.2.tar.xz/plugins/rtmp-services/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/rtmp-services/data/locale/kaa.ini
Changed
@@ -1,9 +1,9 @@ -StreamingServices="Esittiriw xızmetleri" -CustomStreamingServer="Arnawlı esittiriw serveri" -Service="Xızmet" -Server.Auto="Avtomatik (Usınıs etiledi)" -StreamKey="Esittiriw gilti" -UseAuth="Autentifikatsiyadan paydalaniw" -Username="Paydalanıwshı atı" -Password="Parol" -ShowAll="Barlıq xızmetlerdi kórsetiw" +CustomStreamingServer="Арнаўлы еситтириў сервери" +Service="Хызмет" +Server="Сервер" +Server.Auto="Автоматикалық (усыныс етиледи)" +Server.AutoRTMPS="Автоматикалық (RTMPS, усыныс етиледи)" +Server.AutoRTMP="Автоматикалық (RTMP)" +StreamKey="Трансляция гилти" +Username="Пайдаланыўшы аты" +Password="Пароль"
View file
obs-studio-32.2.2.tar.xz/plugins/rtmp-services/data/package.json -> obs-studio-33.0.0.tar.xz/plugins/rtmp-services/data/package.json
Changed
@@ -1,11 +1,11 @@ { "$schema": "schema/package-schema.json", "url": "https://obsproject.com/obs2_update/rtmp-services/v5", - "version": 286, + "version": 295, "files": { "name": "services.json", - "version": 286 + "version": 295 } }
View file
obs-studio-32.2.2.tar.xz/plugins/rtmp-services/data/services.json -> obs-studio-33.0.0.tar.xz/plugins/rtmp-services/data/services.json
Changed
@@ -11,188 +11,56 @@ "multitrack_video_learn_more_link": "https://help.twitch.tv/s/article/multiple-encodes", "servers": { - "name": "Asia: Hong Kong", - "url": "rtmp://live-hkg.twitch.tv/app" + "name": "Asia Pacific (Mumbai)", + "url": "rtmp://aps30.contribute.live-video.net/app/" }, { - "name": "Asia: Seoul, South Korea", - "url": "rtmp://live-sel.twitch.tv/app" + "name": "Asia Pacific (Seoul)", + "url": "rtmp://apn20.contribute.live-video.net/app/" }, { - "name": "Asia: Singapore", - "url": "rtmp://live-sin.twitch.tv/app" - }, - { - "name": "Asia: Taipei, Taiwan", - "url": "rtmp://live-tpe.twitch.tv/app" - }, - { - "name": "Asia: Tokyo, Japan", - "url": "rtmp://live-tyo.twitch.tv/app" - }, - { - "name": "Australia: Sydney", - "url": "rtmp://live-syd.twitch.tv/app" - }, - { - "name": "EU: Amsterdam, NL", - "url": "rtmp://live-ams.twitch.tv/app" - }, - { - "name": "EU: Berlin, DE", - "url": "rtmp://live-ber.twitch.tv/app" - }, - { - "name": "Europe: Copenhagen, DK", - "url": "rtmp://live-cph.twitch.tv/app" - }, - { - "name": "EU: Frankfurt, DE", - "url": "rtmp://live-fra.twitch.tv/app" - }, - { - "name": "EU: Helsinki, FI", - "url": "rtmp://live-hel.twitch.tv/app" - }, - { - "name": "EU: Lisbon, Portugal", - "url": "rtmp://live-lis.twitch.tv/app" - }, - { - "name": "EU: London, UK", - "url": "rtmp://live-lhr.twitch.tv/app" - }, - { - "name": "EU: Madrid, Spain", - "url": "rtmp://live-mad.twitch.tv/app" - }, - { - "name": "EU: Marseille, FR", - "url": "rtmp://live-mrs.twitch.tv/app" - }, - { - "name": "EU: Milan, Italy", - "url": "rtmp://live-mil.twitch.tv/app" - }, - { - "name": "EU: Norway, Oslo", - "url": "rtmp://live-osl.twitch.tv/app" - }, - { - "name": "EU: Paris, FR", - "url": "rtmp://live-cdg.twitch.tv/app" + "name": "Asia Pacific (Singapore)", + "url": "rtmp://aps10.contribute.live-video.net/app/" }, { - "name": "EU: Prague, CZ", - "url": "rtmp://live-prg.twitch.tv/app" + "name": "Asia Pacific (Sydney)", + "url": "rtmp://aps20.contribute.live-video.net/app/" }, { - "name": "EU: Stockholm, SE", - "url": "rtmp://live-arn.twitch.tv/app" + "name": "Asia Pacific (Tokyo)", + "url": "rtmp://apn10.contribute.live-video.net/app/" }, { - "name": "EU: Vienna, Austria", - "url": "rtmp://live-vie.twitch.tv/app" + "name": "Europe (Frankfurt)", + "url": "rtmp://euc10.contribute.live-video.net/app/" }, { - "name": "EU: Warsaw, Poland", - "url": "rtmp://live-waw.twitch.tv/app" + "name": "Europe (Ireland)", + "url": "rtmp://euw10.contribute.live-video.net/app/" }, { - "name": "NA: Mexico City", - "url": "rtmp://live-qro.twitch.tv/app" + "name": "Europe (Paris)", + "url": "rtmp://euw30.contribute.live-video.net/app/" }, { - "name": "NA: Quebec, Canada", - "url": "rtmp://live-ymq.twitch.tv/app" + "name": "Europe (Stockholm)", + "url": "rtmp://eun10.contribute.live-video.net/app/" }, { - "name": "NA: Toronto, Canada", - "url": "rtmp://live-yto.twitch.tv/app" + "name": "South America (S\u00e3o Paulo)", + "url": "rtmp://sae10.contribute.live-video.net/app/" }, { - "name": "South America: Argentina", - "url": "rtmp://live-eze.twitch.tv/app" + "name": "US East (N. Virginia)", + "url": "rtmp://use10.contribute.live-video.net/app/" }, { - "name": "South America: Chile", - "url": "rtmp://live-scl.twitch.tv/app" + "name": "US East (Ohio)", + "url": "rtmp://use20.contribute.live-video.net/app/" }, { - "name": "South America: Lima, Peru", - "url": "rtmp://live-lim.twitch.tv/app" - }, - { - "name": "South America: Medellin, Colombia", - "url": "rtmp://live-mde.twitch.tv/app" - }, - { - "name": "South America: Rio de Janeiro, Brazil", - "url": "rtmp://live-rio.twitch.tv/app" - }, - { - "name": "South America: Sao Paulo, Brazil", - "url": "rtmp://live-sao.twitch.tv/app" - }, - { - "name": "US Central: Dallas, TX", - "url": "rtmp://live-dfw.twitch.tv/app" - }, - { - "name": "US Central: Denver, CO", - "url": "rtmp://live-den.twitch.tv/app" - }, - { - "name": "US Central: Houston, TX", - "url": "rtmp://live-hou.twitch.tv/app" - }, - { - "name": "US Central: Salt Lake City, UT", - "url": "rtmp://live-slc.twitch.tv/app" - }, - { - "name": "US East: Ashburn, VA", - "url": "rtmp://live-iad.twitch.tv/app" - }, - { - "name": "US East: Atlanta, GA", - "url": "rtmp://live-atl.twitch.tv/app" - }, - { - "name": "US East: Chicago", - "url": "rtmp://live-ord.twitch.tv/app" - }, - { - "name": "US East: Miami, FL", - "url": "rtmp://live-mia.twitch.tv/app" - }, - { - "name": "US East: New York, NY", - "url": "rtmp://live-jfk.twitch.tv/app" - }, - { - "name": "US West: Los Angeles, CA", - "url": "rtmp://live-lax.twitch.tv/app" - }, - { - "name": "US West: Phoenix, AZ", - "url": "rtmp://live-phx.twitch.tv/app" - }, - { - "name": "US West: Portland, Oregon", - "url": "rtmp://live-pdx.twitch.tv/app" - }, - { - "name": "US West: San Francisco, CA", - "url": "rtmp://live-sfo.twitch.tv/app" - }, - { - "name": "US West: San Jose, CA", - "url": "rtmp://live-sjc.twitch.tv/app" - }, - { - "name": "US West: Seattle, WA", - "url": "rtmp://live-sea.twitch.tv/app" + "name": "US West (Oregon)", + "url": "rtmp://usw20.contribute.live-video.net/app/" } , "recommended": { @@ -271,43 +139,6 @@ } }, { - "name": "Loola.tv", - "common": false, - "servers": - { - "name": "US East: Virginia", - "url": "rtmp://rtmp.loola.tv/push" - }, - { - "name": "EU Central: Germany", - "url": "rtmp://rtmp-eu.loola.tv/push" - }, - { - "name": "South America: Brazil", - "url": "rtmp://rtmp-sa.loola.tv/push" - }, - { - "name": "Asia/Pacific: Singapore", - "url": "rtmp://rtmp-sg.loola.tv/push" - }, - { - "name": "Middle East: Bahrain", - "url": "rtmp://rtmp-me.loola.tv/push" - } - , - "recommended": { - "keyint": 2, - "profile": "high", - "max video bitrate": 2500, - "max audio bitrate": 160, - "bframes": 2, - "x264opts": "scenecut=0" - }, - "supported video codecs": - "h264" - - }, - { "name": "Lovecast", "servers": { @@ -355,24 +186,6 @@ }, { - "name": "Web.TV", - "servers": - { - "name": "Primary", - "url": "rtmp://live3.origins.web.tv/liveext" - } - , - "recommended": { - "keyint": 2, - "profile": "main", - "max video bitrate": 3500, - "max audio bitrate": 160 - }, - "supported video codecs": - "h264" - - }, - { "name": "GoodGame.ru", "servers": { @@ -840,51 +653,18 @@ }, { - "name": "Meridix Live Sports Platform", - "servers": - { - "name": "Primary", - "url": "rtmp://publish.meridix.com/live" - } - , - "recommended": { - "max video bitrate": 3500 - }, - "supported video codecs": - "h264" - - }, - { - "name": "SOOP Korea", + "name": "SOOP", "alt_names": "AfreecaTV", "아프리카TV", - "Afreeca.TV" + "Afreeca.TV", + "SOOP Korea", + "SOOP Global" , "servers": { - "name": "Asia : Korea", - "url": "rtmp://stream.sooplive.co.kr/app/" - }, - { - "name": "North America : US East", - "url": "rtmp://rtmp-esu.sooplive.co.kr/app/" - }, - { - "name": "North America : US West", - "url": "rtmp://rtmp-wsu.sooplive.co.kr/app/" - }, - { - "name": "South America : Brazil", - "url": "rtmp://rtmp-brz.sooplive.co.kr/app/" - }, - { - "name": "Europe : UK", - "url": "rtmp://rtmp-uk.sooplive.co.kr/app/" - }, - { - "name": "Asia : Singapore", - "url": "rtmp://rtmp-sgp.sooplive.co.kr/app/" + "name": "Default", + "url": "rtmp://stream.soop.live/app/" } , "recommended": { @@ -916,24 +696,6 @@ }, { - "name": "ePlay", - "servers": - { - "name": "ePlay Primary", - "url": "rtmp://live.eplay.link/origin" - } - , - "recommended": { - "keyint": 2, - "profile": "main", - "max video bitrate": 7500, - "max audio bitrate": 192 - }, - "supported video codecs": - "h264" - - }, - { "name": "Picarto", "servers": { @@ -1522,23 +1284,6 @@ }, { - "name": "DLive", - "servers": - { - "name": "Default", - "url": "rtmp://stream.dlive.tv/live" - } - , - "recommended": { - "keyint": 2, - "max video bitrate": 6000, - "max audio bitrate": 160 - }, - "supported video codecs": - "h264" - - }, - { "name": "Lightcast.com", "servers": { @@ -1952,24 +1697,6 @@ }, { - "name": "OPENREC.tv - Premium member (プレミアム会員)", - "stream_key_link": "https://www.openrec.tv/login?keep_login=true&url=https://www.openrec.tv/dashboard/live?from=obs", - "servers": - { - "name": "Default", - "url": "rtmp://a.station.openrec.tv:1935/live1" - } - , - "recommended": { - "keyint": 2, - "max video bitrate": 5000, - "max audio bitrate": 160 - }, - "supported video codecs": - "h264" - - }, - { "name": "nanoStream Cloud / bintu", "more_info_link": "https://www.nanocosmos.de/obs", "stream_key_link": "https://bintu-cloud-frontend.nanocosmos.de/organisation", @@ -2102,18 +1829,6 @@ }, { - "name": "Disciple Media", - "servers": - { - "name": "Default", - "url": "rtmp://rtmp.disciplemedia.com/b-fme" - } - , - "supported video codecs": - "h264" - - }, - { "name": "Jio Games", "servers": { @@ -2282,13 +1997,20 @@ "stream_key_link": "https://whowatch.tv/publish", "servers": { - "name": "default", - "url": "rtmp://live.whowatch.tv/live/" + "name": "Global - グローバル (RTMPS, recommended)", + "url": "rtmps://ingest.global-contribute.live-video.net:443/app" + }, + { + "name": "Global - グローバル (RTMP)", + "url": "rtmp://ingest.global-contribute.live-video.net/app" } , + "multitrack_video_configuration_url": "https://ingest.contribute.live-video.net/api/v3/GetClientConfiguration", "recommended": { + "profile": "baseline", "keyint": 2, - "max video bitrate": 1800, + "bframes": 0, + "max video bitrate": 6000, "max audio bitrate": 192 }, "supported video codecs": @@ -2312,8 +2034,12 @@ "url": "rtmps://stream.dal.irl.run/ingest" }, { - "name": "New York, US", - "url": "rtmps://stream.ewr.irl.run/ingest" + "name": "Chicago, US", + "url": "rtmps://stream.ord.irl.run/ingest" + }, + { + "name": "Ashburn, US", + "url": "rtmps://stream.iad.irl.run/ingest" }, { "name": "Miami, US", @@ -2332,6 +2058,10 @@ "url": "rtmps://stream.sin.irl.run/ingest" }, { + "name": "Seoul, SK", + "url": "rtmps://stream.icn.irl.run/ingest" + }, + { "name": "Tokyo, JP", "url": "rtmps://stream.tyo.irl.run/ingest" }, @@ -2505,6 +2235,8 @@ { "name": "PandaTV | 팬더티비", "common": false, + "multitrack_video_name": "시차없는 LIVE+ 화질 최적화", + "multitrack_video_configuration_url": "https://ingest.contribute.live-video.net/api/v3/GetClientConfiguration", "servers": { "name": "Default", @@ -2589,7 +2321,7 @@ "servers": { "name": "Primary", - "url": "rtmp://injest.streamway.in/LiveApp" + "url": "rtmps://injest.streamway.in:443/live" }, { "name": "Backup", @@ -2745,620 +2477,108 @@ , "servers": { - "name": "Asia: China, Hong Kong (6) (RTMPS)", - "url": "rtmps://hkg06.contribute.live-video.net/app" - }, - { - "name": "Asia: India, Bangalore (1) (RTMPS)", - "url": "rtmps://blr01.contribute.live-video.net/app" - }, - { - "name": "Asia: India, Chennai (RTMPS)", - "url": "rtmps://maa01.contribute.live-video.net/app" - }, - { - "name": "Asia: India, Hyderabad (1) (RTMPS)", - "url": "rtmps://hyd01.contribute.live-video.net/app" - }, - { - "name": "Asia: India, Mumbai (RTMPS)", - "url": "rtmps://bom01.contribute.live-video.net/app" - }, - { - "name": "Asia: India, New Delhi (RTMPS)", - "url": "rtmps://del01.contribute.live-video.net/app" - }, - { - "name": "Asia: Indonesia, Cikarang Barat (1) (RTMPS)", - "url": "rtmps://jkt01.contribute.live-video.net/app" - }, - { - "name": "Asia: Indonesia, Jakarta (2) (RTMPS)", - "url": "rtmps://jkt02.contribute.live-video.net/app" - }, - { - "name": "Asia: Japan, Osaka (1) (RTMPS)", - "url": "rtmps://osa01.contribute.live-video.net/app" - }, - { - "name": "Asia: Japan, Tokyo (3) (RTMPS)", - "url": "rtmps://tyo03.contribute.live-video.net/app" - }, - { - "name": "Asia: Japan, Tokyo (5) (RTMPS)", - "url": "rtmps://tyo05.contribute.live-video.net/app" - }, - { - "name": "Asia: Manila, Philippines (1) (RTMPS)", - "url": "rtmps://mnl01.contribute.live-video.net/app" - }, - { - "name": "Asia: Singapore (1) (RTMPS)", - "url": "rtmps://sin01.contribute.live-video.net/app" - }, - { - "name": "Asia: Singapore (4) (RTMPS)", - "url": "rtmps://sin04.contribute.live-video.net/app" - }, - { - "name": "Asia: South Korea, Seoul (3) (RTMPS)", - "url": "rtmps://sel03.contribute.live-video.net/app" - }, - { - "name": "Asia: South Korea, Seoul (4) (RTMPS)", - "url": "rtmps://sel04.contribute.live-video.net/app" - }, - { - "name": "Asia: Taiwan, Taipei (1) (RTMPS)", - "url": "rtmps://tpe01.contribute.live-video.net/app" - }, - { - "name": "Asia: Taiwan, Taipei (3) (RTMPS)", - "url": "rtmps://tpe03.contribute.live-video.net/app" - }, - { - "name": "Asia: Thailand, Bangkok (2) (RTMPS)", - "url": "rtmps://bkk02.contribute.live-video.net/app" - }, - { - "name": "Europe: Austria, Vienna (2) (RTMPS)", - "url": "rtmps://vie02.contribute.live-video.net/app" - }, - { - "name": "Europe: Czech Republic, Prague (RTMPS)", - "url": "rtmps://prg03.contribute.live-video.net/app" - }, - { - "name": "Europe: Denmark, Copenhagen (RTMPS)", - "url": "rtmps://cph.contribute.live-video.net/app" - }, - { - "name": "Europe: Finland, Helsinki (3) (RTMPS)", - "url": "rtmps://hel03.contribute.live-video.net/app" - }, - { - "name": "Europe: France, Marseille (RTMPS)", - "url": "rtmps://mrs.contribute.live-video.net/app" - }, - { - "name": "Europe: France, Marseille (2) (RTMPS)", - "url": "rtmps://mrs02.contribute.live-video.net/app" - }, - { - "name": "Europe: France, Paris (10) (RTMPS)", - "url": "rtmps://cdg10.contribute.live-video.net/app" - }, - { - "name": "Europe: France, Paris (2) (RTMPS)", - "url": "rtmps://cdg02.contribute.live-video.net/app" - }, - { - "name": "Europe: Germany, Berlin (RTMPS)", - "url": "rtmps://ber.contribute.live-video.net/app" - }, - { - "name": "Europe: Germany, Dusseldorf (1) (RTMPS)", - "url": "rtmps://dus01.contribute.live-video.net/app" - }, - { - "name": "Europe: Germany, Frankfurt (2) (RTMPS)", - "url": "rtmps://fra02.contribute.live-video.net/app" - }, - { - "name": "Europe: Germany, Frankfurt (5) (RTMPS)", - "url": "rtmps://fra05.contribute.live-video.net/app" - }, - { - "name": "Europe: Germany, Frankfurt (6) (RTMPS)", - "url": "rtmps://fra06.contribute.live-video.net/app" - }, - { - "name": "Europe: Germany, Munich (1) (RTMPS)", - "url": "rtmps://muc01.contribute.live-video.net/app" - }, - { - "name": "Europe: Italy, Milan (2) (RTMPS)", - "url": "rtmps://mil02.contribute.live-video.net/app" - }, - { - "name": "Europe: Netherlands, Amsterdam (2) (RTMPS)", - "url": "rtmps://ams02.contribute.live-video.net/app" - }, - { - "name": "Europe: Netherlands, Amsterdam (3) (RTMPS)", - "url": "rtmps://ams03.contribute.live-video.net/app" - }, - { - "name": "Europe: Norway, Oslo (RTMPS)", - "url": "rtmps://osl.contribute.live-video.net/app" - }, - { - "name": "Europe: Poland, Warsaw (2) (RTMPS)", - "url": "rtmps://waw02.contribute.live-video.net/app" - }, - { - "name": "Europe: Spain, Madrid (1) (RTMPS)", - "url": "rtmps://mad01.contribute.live-video.net/app" - }, - { - "name": "Europe: Spain, Madrid (2) (RTMPS)", - "url": "rtmps://mad02.contribute.live-video.net/app" - }, - { - "name": "Europe: Sweden, Stockholm (3) (RTMPS)", - "url": "rtmps://arn03.contribute.live-video.net/app" - }, - { - "name": "Europe: Sweden, Stockholm (4) (RTMPS)", - "url": "rtmps://arn04.contribute.live-video.net/app" - }, - { - "name": "Europe: UK, London (3) (RTMPS)", - "url": "rtmps://lhr03.contribute.live-video.net/app" - }, - { - "name": "Europe: UK, London (4) (RTMPS)", - "url": "rtmps://lhr04.contribute.live-video.net/app" - }, - { - "name": "Europe: UK, London (8) (RTMPS)", - "url": "rtmps://lhr08.contribute.live-video.net/app" - }, - { - "name": "NA: Canada, Quebec (RTMPS)", - "url": "rtmps://ymq03.contribute.live-video.net/app" - }, - { - "name": "NA: Canada, Toronto (RTMPS)", - "url": "rtmps://yto.contribute.live-video.net/app" - }, - { - "name": "NA: Mexico, Queretaro (3) (RTMPS)", - "url": "rtmps://qro03.contribute.live-video.net/app" - }, - { - "name": "NA: Mexico, Queretaro (4) (RTMPS)", - "url": "rtmps://qro04.contribute.live-video.net/app" - }, - { - "name": "Oceania: Australia, Sydney (2) (RTMPS)", - "url": "rtmps://syd02.contribute.live-video.net/app" - }, - { - "name": "Oceania: Australia, Sydney (3) (RTMPS)", - "url": "rtmps://syd03.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Fortaleza (1) (RTMPS)", - "url": "rtmps://for01.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Rio de Janeiro (3) (RTMPS)", - "url": "rtmps://rio03.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Rio de Janeiro (4) (RTMPS)", - "url": "rtmps://rio04.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Sao Paulo (RTMPS)", - "url": "rtmps://sao03.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Sao Paulo (5) (RTMPS)", - "url": "rtmps://sao05.contribute.live-video.net/app" - }, - { - "name": "South America: Buenos Aires, Argentina (1) (RTMPS)", - "url": "rtmps://bue01.contribute.live-video.net/app" - }, - { - "name": "South America: Colombia, Bogota (1) (RTMPS)", - "url": "rtmps://bog01.contribute.live-video.net/app" - }, - { - "name": "US Central: Dallas, TX (RTMPS)", - "url": "rtmps://dfw.contribute.live-video.net/app" - }, - { - "name": "US Central: Dallas, TX (2) (RTMPS)", - "url": "rtmps://dfw02.contribute.live-video.net/app" - }, - { - "name": "US Central: Denver, CO (52) (RTMPS)", - "url": "rtmps://den52.contribute.live-video.net/app" - }, - { - "name": "US Central: Garland, TX (56) (RTMPS)", - "url": "rtmps://dfw56.contribute.live-video.net/app" - }, - { - "name": "US Central: Houston, TX (50) (RTMPS)", - "url": "rtmps://iah50.contribute.live-video.net/app" - }, - { - "name": "US East: Ashburn, VA (5) (RTMPS)", - "url": "rtmps://iad05.contribute.live-video.net/app" - }, - { - "name": "US East: Atlanta, GA (RTMPS)", - "url": "rtmps://atl.contribute.live-video.net/app" - }, - { - "name": "US East: Chicago, IL (3) (RTMPS)", - "url": "rtmps://ord03.contribute.live-video.net/app" - }, - { - "name": "US East: Chicago, IL (56) (RTMPS)", - "url": "rtmps://ord56.contribute.live-video.net/app" - }, - { - "name": "US East: McAllen, TX (1) (RTMPS)", - "url": "rtmps://mfe01.contribute.live-video.net/app" - }, - { - "name": "US East: Miami, FL (5) (RTMPS)", - "url": "rtmps://mia05.contribute.live-video.net/app" - }, - { - "name": "US East: New York, NY (RTMPS)", - "url": "rtmps://jfk.contribute.live-video.net/app" - }, - { - "name": "US East: New York, NY (50) (RTMPS)", - "url": "rtmps://jfk50.contribute.live-video.net/app" - }, - { - "name": "US West: Los Angeles, CA (RTMPS)", - "url": "rtmps://lax.contribute.live-video.net/app" - }, - { - "name": "US West: Salt Lake City, UT (RTMPS)", - "url": "rtmps://slc.contribute.live-video.net/app" - }, - { - "name": "US West: San Francisco, CA (RTMPS)", - "url": "rtmps://sfo.contribute.live-video.net/app" - }, - { - "name": "US West: San Jose, California (6) (RTMPS)", - "url": "rtmps://sjc06.contribute.live-video.net/app" - }, - { - "name": "US West: Seattle, WA (RTMPS)", - "url": "rtmps://sea.contribute.live-video.net/app" - }, - { - "name": "US West: Seattle, WA (2) (RTMPS)", - "url": "rtmps://sea02.contribute.live-video.net/app" - }, - { - "name": "Asia: China, Hong Kong (6) (RTMP)", - "url": "rtmp://hkg06.contribute.live-video.net/app" - }, - { - "name": "Asia: India, Bangalore (1) (RTMP)", - "url": "rtmp://blr01.contribute.live-video.net/app" - }, - { - "name": "Asia: India, Chennai (RTMP)", - "url": "rtmp://maa01.contribute.live-video.net/app" - }, - { - "name": "Asia: India, Hyderabad (1) (RTMP)", - "url": "rtmp://hyd01.contribute.live-video.net/app" - }, - { - "name": "Asia: India, Mumbai (RTMP)", - "url": "rtmp://bom01.contribute.live-video.net/app" - }, - { - "name": "Asia: India, New Delhi (RTMP)", - "url": "rtmp://del01.contribute.live-video.net/app" - }, - { - "name": "Asia: Indonesia, Cikarang Barat (1) (RTMP)", - "url": "rtmp://jkt01.contribute.live-video.net/app" - }, - { - "name": "Asia: Indonesia, Jakarta (2) (RTMP)", - "url": "rtmp://jkt02.contribute.live-video.net/app" - }, - { - "name": "Asia: Japan, Osaka (1) (RTMP)", - "url": "rtmp://osa01.contribute.live-video.net/app" - }, - { - "name": "Asia: Japan, Tokyo (3) (RTMP)", - "url": "rtmp://tyo03.contribute.live-video.net/app" - }, - { - "name": "Asia: Japan, Tokyo (5) (RTMP)", - "url": "rtmp://tyo05.contribute.live-video.net/app" - }, - { - "name": "Asia: Manila, Philippines (1) (RTMP)", - "url": "rtmp://mnl01.contribute.live-video.net/app" - }, - { - "name": "Asia: Singapore (1) (RTMP)", - "url": "rtmp://sin01.contribute.live-video.net/app" - }, - { - "name": "Asia: Singapore (4) (RTMP)", - "url": "rtmp://sin04.contribute.live-video.net/app" - }, - { - "name": "Asia: South Korea, Seoul (3) (RTMP)", - "url": "rtmp://sel03.contribute.live-video.net/app" - }, - { - "name": "Asia: South Korea, Seoul (4) (RTMP)", - "url": "rtmp://sel04.contribute.live-video.net/app" - }, - { - "name": "Asia: Taiwan, Taipei (1) (RTMP)", - "url": "rtmp://tpe01.contribute.live-video.net/app" - }, - { - "name": "Asia: Taiwan, Taipei (3) (RTMP)", - "url": "rtmp://tpe03.contribute.live-video.net/app" - }, - { - "name": "Asia: Thailand, Bangkok (2) (RTMP)", - "url": "rtmp://bkk02.contribute.live-video.net/app" - }, - { - "name": "Europe: Austria, Vienna (2) (RTMP)", - "url": "rtmp://vie02.contribute.live-video.net/app" - }, - { - "name": "Europe: Czech Republic, Prague (RTMP)", - "url": "rtmp://prg03.contribute.live-video.net/app" - }, - { - "name": "Europe: Denmark, Copenhagen (RTMP)", - "url": "rtmp://cph.contribute.live-video.net/app" - }, - { - "name": "Europe: Finland, Helsinki (3) (RTMP)", - "url": "rtmp://hel03.contribute.live-video.net/app" - }, - { - "name": "Europe: France, Marseille (RTMP)", - "url": "rtmp://mrs.contribute.live-video.net/app" + "name": "Asia Pacific (Mumbai) (RTMPS)", + "url": "rtmps://aps30.contribute.live-video.net:443/app/" }, { - "name": "Europe: France, Marseille (2) (RTMP)", - "url": "rtmp://mrs02.contribute.live-video.net/app" + "name": "Asia Pacific (Seoul) (RTMPS)", + "url": "rtmps://apn20.contribute.live-video.net:443/app/" }, { - "name": "Europe: France, Paris (10) (RTMP)", - "url": "rtmp://cdg10.contribute.live-video.net/app" + "name": "Asia Pacific (Singapore) (RTMPS)", + "url": "rtmps://aps10.contribute.live-video.net:443/app/" }, { - "name": "Europe: France, Paris (2) (RTMP)", - "url": "rtmp://cdg02.contribute.live-video.net/app" + "name": "Asia Pacific (Sydney) (RTMPS)", + "url": "rtmps://aps20.contribute.live-video.net:443/app/" }, { - "name": "Europe: Germany, Berlin (RTMP)", - "url": "rtmp://ber.contribute.live-video.net/app" + "name": "Asia Pacific (Tokyo) (RTMPS)", + "url": "rtmps://apn10.contribute.live-video.net:443/app/" }, { - "name": "Europe: Germany, Dusseldorf (1) (RTMP)", - "url": "rtmp://dus01.contribute.live-video.net/app" + "name": "Europe (Frankfurt) (RTMPS)", + "url": "rtmps://euc10.contribute.live-video.net:443/app/" }, { - "name": "Europe: Germany, Frankfurt (2) (RTMP)", - "url": "rtmp://fra02.contribute.live-video.net/app" + "name": "Europe (Ireland) (RTMPS)", + "url": "rtmps://euw10.contribute.live-video.net:443/app/" }, { - "name": "Europe: Germany, Frankfurt (5) (RTMP)", - "url": "rtmp://fra05.contribute.live-video.net/app" + "name": "Europe (Paris) (RTMPS)", + "url": "rtmps://euw30.contribute.live-video.net:443/app/" }, { - "name": "Europe: Germany, Frankfurt (6) (RTMP)", - "url": "rtmp://fra06.contribute.live-video.net/app" + "name": "Europe (Stockholm) (RTMPS)", + "url": "rtmps://eun10.contribute.live-video.net:443/app/" }, { - "name": "Europe: Germany, Munich (1) (RTMP)", - "url": "rtmp://muc01.contribute.live-video.net/app" + "name": "South America (S\u00e3o Paulo) (RTMPS)", + "url": "rtmps://sae10.contribute.live-video.net:443/app/" }, { - "name": "Europe: Italy, Milan (2) (RTMP)", - "url": "rtmp://mil02.contribute.live-video.net/app" + "name": "US East (N. Virginia) (RTMPS)", + "url": "rtmps://use10.contribute.live-video.net:443/app/" }, { - "name": "Europe: Netherlands, Amsterdam (2) (RTMP)", - "url": "rtmp://ams02.contribute.live-video.net/app" + "name": "US East (Ohio) (RTMPS)", + "url": "rtmps://use20.contribute.live-video.net:443/app/" }, { - "name": "Europe: Netherlands, Amsterdam (3) (RTMP)", - "url": "rtmp://ams03.contribute.live-video.net/app" + "name": "US West (Oregon) (RTMPS)", + "url": "rtmps://usw20.contribute.live-video.net:443/app/" }, { - "name": "Europe: Norway, Oslo (RTMP)", - "url": "rtmp://osl.contribute.live-video.net/app" + "name": "Asia Pacific (Mumbai) (RTMP)", + "url": "rtmp://aps30.contribute.live-video.net/app/" }, { - "name": "Europe: Poland, Warsaw (2) (RTMP)", - "url": "rtmp://waw02.contribute.live-video.net/app" + "name": "Asia Pacific (Seoul) (RTMP)", + "url": "rtmp://apn20.contribute.live-video.net/app/" }, { - "name": "Europe: Spain, Madrid (1) (RTMP)", - "url": "rtmp://mad01.contribute.live-video.net/app" + "name": "Asia Pacific (Singapore) (RTMP)", + "url": "rtmp://aps10.contribute.live-video.net/app/" }, { - "name": "Europe: Spain, Madrid (2) (RTMP)", - "url": "rtmp://mad02.contribute.live-video.net/app" + "name": "Asia Pacific (Sydney) (RTMP)", + "url": "rtmp://aps20.contribute.live-video.net/app/" }, { - "name": "Europe: Sweden, Stockholm (3) (RTMP)", - "url": "rtmp://arn03.contribute.live-video.net/app" + "name": "Asia Pacific (Tokyo) (RTMP)", + "url": "rtmp://apn10.contribute.live-video.net/app/" }, { - "name": "Europe: Sweden, Stockholm (4) (RTMP)", - "url": "rtmp://arn04.contribute.live-video.net/app" + "name": "Europe (Frankfurt) (RTMP)", + "url": "rtmp://euc10.contribute.live-video.net/app/" }, { - "name": "Europe: UK, London (3) (RTMP)", - "url": "rtmp://lhr03.contribute.live-video.net/app" + "name": "Europe (Ireland) (RTMP)", + "url": "rtmp://euw10.contribute.live-video.net/app/" }, { - "name": "Europe: UK, London (4) (RTMP)", - "url": "rtmp://lhr04.contribute.live-video.net/app" + "name": "Europe (Paris) (RTMP)", + "url": "rtmp://euw30.contribute.live-video.net/app/" }, { - "name": "Europe: UK, London (8) (RTMP)", - "url": "rtmp://lhr08.contribute.live-video.net/app" + "name": "Europe (Stockholm) (RTMP)", + "url": "rtmp://eun10.contribute.live-video.net/app/" }, { - "name": "NA: Canada, Quebec (RTMP)", - "url": "rtmp://ymq03.contribute.live-video.net/app" + "name": "South America (S\u00e3o Paulo) (RTMP)", + "url": "rtmp://sae10.contribute.live-video.net/app/" }, { - "name": "NA: Canada, Toronto (RTMP)", - "url": "rtmp://yto.contribute.live-video.net/app" + "name": "US East (N. Virginia) (RTMP)", + "url": "rtmp://use10.contribute.live-video.net/app/" }, { - "name": "NA: Mexico, Queretaro (3) (RTMP)", - "url": "rtmp://qro03.contribute.live-video.net/app" + "name": "US East (Ohio) (RTMP)", + "url": "rtmp://use20.contribute.live-video.net/app/" }, { - "name": "NA: Mexico, Queretaro (4) (RTMP)", - "url": "rtmp://qro04.contribute.live-video.net/app" - }, - { - "name": "Oceania: Australia, Sydney (2) (RTMP)", - "url": "rtmp://syd02.contribute.live-video.net/app" - }, - { - "name": "Oceania: Australia, Sydney (3) (RTMP)", - "url": "rtmp://syd03.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Fortaleza (1) (RTMP)", - "url": "rtmp://for01.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Rio de Janeiro (3) (RTMP)", - "url": "rtmp://rio03.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Rio de Janeiro (4) (RTMP)", - "url": "rtmp://rio04.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Sao Paulo (RTMP)", - "url": "rtmp://sao03.contribute.live-video.net/app" - }, - { - "name": "South America: Brazil, Sao Paulo (5) (RTMP)", - "url": "rtmp://sao05.contribute.live-video.net/app" - }, - { - "name": "South America: Buenos Aires, Argentina (1) (RTMP)", - "url": "rtmp://bue01.contribute.live-video.net/app" - }, - { - "name": "South America: Colombia, Bogota (1) (RTMP)", - "url": "rtmp://bog01.contribute.live-video.net/app" - }, - { - "name": "US Central: Dallas, TX (RTMP)", - "url": "rtmp://dfw.contribute.live-video.net/app" - }, - { - "name": "US Central: Dallas, TX (2) (RTMP)", - "url": "rtmp://dfw02.contribute.live-video.net/app" - }, - { - "name": "US Central: Denver, CO (52) (RTMP)", - "url": "rtmp://den52.contribute.live-video.net/app" - }, - { - "name": "US Central: Garland, TX (56) (RTMP)", - "url": "rtmp://dfw56.contribute.live-video.net/app" - }, - { - "name": "US Central: Houston, TX (50) (RTMP)", - "url": "rtmp://iah50.contribute.live-video.net/app" - }, - { - "name": "US East: Ashburn, VA (5) (RTMP)", - "url": "rtmp://iad05.contribute.live-video.net/app" - }, - { - "name": "US East: Atlanta, GA (RTMP)", - "url": "rtmp://atl.contribute.live-video.net/app" - }, - { - "name": "US East: Chicago, IL (3) (RTMP)", - "url": "rtmp://ord03.contribute.live-video.net/app" - }, - { - "name": "US East: Chicago, IL (56) (RTMP)", - "url": "rtmp://ord56.contribute.live-video.net/app" - }, - { - "name": "US East: McAllen, TX (1) (RTMP)", - "url": "rtmp://mfe01.contribute.live-video.net/app" - }, - { - "name": "US East: Miami, FL (5) (RTMP)", - "url": "rtmp://mia05.contribute.live-video.net/app" - }, - { - "name": "US East: New York, NY (RTMP)", - "url": "rtmp://jfk.contribute.live-video.net/app" - }, - { - "name": "US East: New York, NY (50) (RTMP)", - "url": "rtmp://jfk50.contribute.live-video.net/app" - }, - { - "name": "US West: Los Angeles, CA (RTMP)", - "url": "rtmp://lax.contribute.live-video.net/app" - }, - { - "name": "US West: Salt Lake City, UT (RTMP)", - "url": "rtmp://slc.contribute.live-video.net/app" - }, - { - "name": "US West: San Francisco, CA (RTMP)", - "url": "rtmp://sfo.contribute.live-video.net/app" - }, - { - "name": "US West: San Jose, California (6) (RTMP)", - "url": "rtmp://sjc06.contribute.live-video.net/app" - }, - { - "name": "US West: Seattle, WA (RTMP)", - "url": "rtmp://sea.contribute.live-video.net/app" - }, - { - "name": "US West: Seattle, WA (2) (RTMP)", - "url": "rtmp://sea02.contribute.live-video.net/app" + "name": "US West (Oregon) (RTMP)", + "url": "rtmp://usw20.contribute.live-video.net/app/" } , "multitrack_video_configuration_url": "https://ingest.contribute.live-video.net/api/v3/GetClientConfiguration", @@ -3502,102 +2722,31 @@ } }, { - "name": "SOOP Global", - "common": false, - "more_info_link": "https://sooplive.helpshift.com/hc/en/3-soop/faq/20", - "stream_key_link": "https://www.sooplive.com/dashboard", + "name": "Spoon", "servers": { - "name": "Default", - "url": "rtmp://global-stream.sooplive.com/app" + "name": "Korea (RTMPS)", + "url": "rtmps://kr-rtmps.spooncast.net/live" + }, + { + "name": "Korea (RTMP)", + "url": "rtmp://kr-rtmp.spooncast.net/live" + }, + { + "name": "Japan (RTMPS)", + "url": "rtmps://jp-rtmps.spooncast.net/live" + }, + { + "name": "Japan (RTMP)", + "url": "rtmp://jp-rtmp.spooncast.net/live" } , - "protocol": "RTMP", - "supported video codecs": - "h264" - , "supported audio codecs": "aac" , "recommended": { - "keyint": 1, - "profile": "main", - "bframes": 0, - "supported resolutions": - "1920x1080", - "1280x720", - "960x540", - "640x360" - , - "bitrate matrix": - { - "res": "640x360", - "fps": 30, - "max bitrate": 500 - }, - { - "res": "640x360", - "fps": 60, - "max bitrate": 1000 - }, - { - "res": "960x540", - "fps": 30, - "max bitrate": 2000 - }, - { - "res": "960x540", - "fps": 60, - "max bitrate": 2000 - }, - { - "res": "1280x720", - "fps": 30, - "max bitrate": 4000 - }, - { - "res": "1280x720", - "fps": 60, - "max bitrate": 4000 - }, - { - "res": "1920x1080", - "fps": 30, - "max bitrate": 8000 - }, - { - "res": "1920x1080", - "fps": 60, - "max bitrate": 8000 - } - , - "max fps": 60, - "max video bitrate": 8000, - "max audio bitrate": 192 + "max audio bitrate": 96 } - }, - { - "name": "Sportify", - "more_info_link": "https://www.homegroundapp.com", - "servers": - { - "name": "Default", - "url": "rtmp://stream.homegroundapp.com/live" - } - , - "recommended": { - "keyint": 2, - "max video bitrate": 3500, - "max audio bitrate": 192, - "supported resolutions": - "1920x1080", - "1280x720" - , - "max fps": 30 - }, - "supported video codecs": - "h264" - } }
View file
obs-studio-32.2.2.tar.xz/plugins/rtmp-services/service-specific/twitch.c -> obs-studio-33.0.0.tar.xz/plugins/rtmp-services/service-specific/twitch.c
Changed
@@ -42,7 +42,8 @@ void load_twitch_data(void) { - struct ingest def = {.name = bstrdup("Default"), .url = bstrdup("rtmp://live.twitch.tv/app")}; + struct ingest def = {.name = bstrdup("Default"), + .url = bstrdup("rtmp://ingest.global-contribute.live-video.net/app")}; load_service_data(&twitch, "twitch_ingests.json", &def); }
View file
obs-studio-32.2.2.tar.xz/plugins/sndio/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/sndio/CMakeLists.txt
Changed
@@ -2,7 +2,6 @@ option(ENABLE_SNDIO "Build OBS with sndio support" OFF) if(NOT ENABLE_SNDIO) - target_disable(sndio) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/sndio/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/sndio/data/locale/kaa.ini
Changed
@@ -1,2 +1,2 @@ -Channels="Kanallar sanı" -Device="Qurılma" +Channels="Каналлар саны" +Device="Қурылма"
View file
obs-studio-32.2.2.tar.xz/plugins/text-freetype2/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/text-freetype2/CMakeLists.txt
Changed
@@ -3,7 +3,6 @@ option(ENABLE_FREETYPE "Enable FreeType text plugin" ON) if(NOT ENABLE_FREETYPE) - target_disable(text-freetype2) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/text-freetype2/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/text-freetype2/data/locale/kaa.ini
Changed
@@ -1,11 +1,11 @@ -TextFreetype2="Tekst (FreeType 2)" -Font="Shrift" -Text="Tekst" -TextFile="Tekst fayl" -TextFile.Encoding="UTF-8 yamasa UTF-16" -TextInputMode="Tekst kirgiziw rejimi" -TextInputMode.Manual="Qolda" -TextInputMode.FromFile="Fayldan" -TextFileFilter="Tekst fayllar (*.txt);;" -Color1="Reń 1" -Color2="Reń 2" +TextFreetype2="Текст (FreeType 2)" +Font="Шрифт" +Text="Текст" +TextFile="Текст файлы" +TextFile.Encoding="UTF-8 ямаса UTF-16" +TextInputMode.Manual="Қолда" +TextInputMode.FromFile="Файлдан" +TextFileFilter="Текст файллары (*.txt);;" +Color1="Рең 1" +Color2="Рең 2" +DropShadow="Сая"
View file
obs-studio-32.2.2.tar.xz/plugins/vlc-video/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/vlc-video/CMakeLists.txt
Changed
@@ -23,7 +23,6 @@ option(ENABLE_VLC "Build OBS with VLC plugin support" ON) if(NOT ENABLE_VLC) - target_disable(vlc-video) return() endif()
View file
obs-studio-32.2.2.tar.xz/plugins/vlc-video/data/locale/ja-JP.ini -> obs-studio-33.0.0.tar.xz/plugins/vlc-video/data/locale/ja-JP.ini
Changed
@@ -1,4 +1,4 @@ -VLCSource="VLCビデオ" +VLCSource="VLC ビデオ" Playlist="プレイリスト" LoopPlaylist="プレイリストをループ再生" Shuffle="プレイリストをシャッフルする"
View file
obs-studio-32.2.2.tar.xz/plugins/vlc-video/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/vlc-video/data/locale/kaa.ini
Changed
@@ -1,9 +1,8 @@ -PlaybackBehavior="Kórinis qásiyeti" -PlaybackBehavior.StopRestart="Kórinbeytuǵın bolsa toqtatıw, kórinetuǵın bolsa bastan baslaw" +VLCSource="VLC видео" +Playlist="Плейлист" PlaybackBehavior.AlwaysPlay="Hámiyshe qoyıw, hátteki kórinbeytuǵın bolsa da" -PlayPause="Qoyıw/Pauza" -Restart="Qayta iske túsiriw" -Stop="Toqtatıw" -PlaylistNext="Keyingi" -PlaylistPrev="Aldıńǵı" -SubtitleEnable="Subtitrlardı qosıw" +PlayPause="Қойыў/Пауза" +Restart="Қайта иске түсириў" +Stop="Тоқтатыў" +PlaylistNext="Кейинги" +PlaylistPrev="Алдыңғы"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/compatibility.json -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/compatibility.json
Changed
@@ -87,6 +87,34 @@ "url": "" }, { + "name": "Construct 3", + "translation_key": "Compatibility.WindowCapture.BitBlt.Applications.Based", + "severity": 0, + "executable": "", + "window_class": "WindowsWebview2Wrapper", + "window_title": "", + "match_flags": 4, + "game_capture": false, + "window_capture": true, + "window_capture_wgc": false, + "message": "Applications based on Chromium may not be capturable using the selected Capture Method (BitBlt).", + "url": "" + }, + { + "name": "Construct 3", + "translation_key": "Compatibility.GameCapture.Blocked.Applications.Built", + "severity": 2, + "executable": "", + "window_class": "WindowsWebview2Wrapper", + "window_title": "", + "match_flags": 4, + "game_capture": true, + "window_capture": false, + "window_capture_wgc": false, + "message": "Games built on Chromium cannot be captured using Game Capture. Use Window Capture or Display Capture instead.", + "url": "" + }, + { "name": "UWP", "translation_key": "Compatibility.WindowCapture.BitBlt.Applications", "severity": 0,
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/af-ZA.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/af-ZA.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Venster" WindowCapture.Method="Opnamemetode" WindowCapture.Method.Auto="Outomaties" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 en nuwer)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 en nuwer)" WindowCapture.Priority.Title="Venstertitel moet ooreenstem" WindowCapture.Priority.Class="Gelyk aan titel, vind anders ’n skerm van dieselfde tipe" WindowCapture.Priority.Exe="Gelyk aan titel, vind anders ’n skerm van dieselfde uitvoerbare" @@ -13,8 +11,6 @@ Monitor="Beeldskerm" PrimaryMonitor="Primêre skerm" Method="Opnamemetode" -Method.DXGI="DXGI-werkskermduplisering" -Method.WindowsGraphicsCapture="Windows 10 (1903 en nuwer)" GameCapture="Spelopname" GameCapture.AnyFullscreen="Neem enige volskermtoepassing op" GameCapture.CaptureWindow="Neem spesifieke venster op"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ar-SA.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ar-SA.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="نافذة" WindowCapture.Method="طريقة الإلتقاط" WindowCapture.Method.Auto="تلقائي" -WindowCapture.Method.BitBlt="BitBlt (ويندوز 7 وما فوق)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 وما فوق)" WindowCapture.Priority="أولوية النوافذ المختارة" WindowCapture.Priority.Title="يجب أن يتطابق مع عنوان النافذة" WindowCapture.Priority.Class="تطابق العنوان, عدا ذلك إيجاد نافذة أخرى من نفس النوع" @@ -19,8 +17,6 @@ Monitor="جهاز العرض" PrimaryMonitor="الشاشة الأساسية" Method="طريقة الإلتقاط" -Method.DXGI="ازدواجية سطح المكتب DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 وما فوق)" GameCapture="التقاط لعبة" GameCapture.AnyFullscreen="التقاط أي تطبيق في وضع ملء الشاشة" GameCapture.CaptureWindow="التقاط نافذة محددة"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/az-AZ.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/az-AZ.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Pəncərə" WindowCapture.Method="Yaxalama Metodu" WindowCapture.Method.Auto="Avtomatik" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 və yuxarı)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 və yuxarı)" WindowCapture.Priority="Pəncərə Uyğunluğu Prioriteti" WindowCapture.Priority.Title="Pəncərə başlığı uyğun gəlməlidir" WindowCapture.Priority.Class="Başlıq uyğunlaşdır, olmasa eyni növdən olan pəncərəni tap" @@ -18,8 +16,6 @@ Monitor="Ekran" PrimaryMonitor="Əsas Ekran" Method="Yaxalama Metodu" -Method.DXGI="DXGI Masaüstü Dublikasiyası" -Method.WindowsGraphicsCapture="Windows 10 (1903 və yuxarı)" GameCapture="Oyun Yaxalama" GameCapture.AnyFullscreen="İstənilən tam ekranlı tətbiqi yaxala" GameCapture.CaptureWindow="Xüsusi pəncərəni yaxala"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/be-BY.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/be-BY.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Акно" WindowCapture.Method="Метад захопу" WindowCapture.Method.Auto="Аўта" -WindowCapture.Method.BitBlt="BitBit (Windows 7 і вышэй)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 і вышэй)" +WindowCapture.Method.BitBlt="Састарэлы (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Сучасны (WGC)" WindowCapture.Priority="Прыярытэт адпаведнасці акна" WindowCapture.Priority.Title="Загаловак акна павінен супадаць" WindowCapture.Priority.Class="Супадзенне загалоўка, у іншым выпадку знаходзіць акно таго ж тыпу" @@ -19,8 +19,8 @@ Monitor="Экран" PrimaryMonitor="асноўны манітор" Method="Метад захопу" -Method.DXGI="Дубліраванне экрана DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 і вышэй)" +Method.DXGI="Састарэлы (DXGI)" +Method.WindowsGraphicsCapture="Сучасны (WGC)" GameCapture="Захоп гульні" GameCapture.AnyFullscreen="Захоп любой поўнаэкраннай праграмы" GameCapture.CaptureWindow="Захоп пэўнага акна"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/bg-BG.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/bg-BG.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Прозорец" WindowCapture.Method="Начин на заснемане" WindowCapture.Method.Auto="Автоматично" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 и нагоре)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (версия 1903 или по-нова)" WindowCapture.Priority="Приоритет на прозореца" WindowCapture.Priority.Title="Заглавие на прозорец, което трябва да съвпада" WindowCapture.Priority.Class="Сравняване на заглавия, в противен случай намери прозорец от същия тип" @@ -17,8 +15,6 @@ Monitor="Екран" PrimaryMonitor="Главен монитор" Method="Метод на прихващане" -Method.DXGI="Дублиране на дисплея с DXGI" -Method.WindowsGraphicsCapture="Windows 10 (версия 1903 или по-нова)" GameCapture="Заснемане на игра" GameCapture.AnyFullscreen="Заснемане на всяко приложение на цял екран" GameCapture.CaptureWindow="Заснемане на определен прозорец"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/bn-BD.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/bn-BD.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="উইন্ডো" WindowCapture.Method="অধিগ্রহনের ধরণ" WindowCapture.Method.Auto="স্বয়ংক্রিয়" -WindowCapture.Method.BitBlt="BitBlt (Windows ৭ এবং তার বেশি)" -WindowCapture.Method.WindowsGraphicsCapture="Windows ১০ (১৯০৩ বা তার বেশি)" WindowCapture.Priority="উইন্ডো মিল অগ্রাধিকার" WindowCapture.Priority.Title="উইন্ডোর শিরোনামটি অবশ্যই মিলবে" WindowCapture.Priority.Class="শিরোনামটি মিলান, অন্যথায় একই ধরণের উইন্ডোর সন্ধান করুন" @@ -17,8 +15,6 @@ Monitor="ডিসপ্লে" PrimaryMonitor="প্রধান মনিটর" Method="অধিগ্রহনের পদ্ধতি" -Method.DXGI="ডিএক্সজিআই ডেস্কটপ সদৃশ" -Method.WindowsGraphicsCapture="Windows ১০ (১৯০৩ বা তার বেশি)" GameCapture="গেম অধিগ্রহণ" GameCapture.AnyFullscreen="যে কোনও পূর্ণস্ক্রিন অ্যাপ্লিকেশন অধিগ্রহণ করুন" GameCapture.CaptureWindow="নির্দিষ্ট উইন্ডো অধিগ্রহন"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ca-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ca-ES.ini
Changed
@@ -3,8 +3,7 @@ WindowCapture.Window="Finestra" WindowCapture.Method="Mètode de captura" WindowCapture.Method.Auto="Automàtic" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 o superior)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 i superior)" +WindowCapture.Method.BitBlt="Legat (BitBlt)" WindowCapture.Priority="Prioritat de coincidència de pantalla" WindowCapture.Priority.Title="El títol de la finestra ha de coincidir" WindowCapture.Priority.Class="Títol del partit, altrament troba la finestra del mateix tipus" @@ -19,8 +18,7 @@ Monitor="Pantalla" PrimaryMonitor="Monitor principal" Method="Mètode de captura" -Method.DXGI="Duplicació d'escriptori DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 i superior)" +Method.DXGI="Legat (DXGI)" GameCapture="Captura de videojoc" GameCapture.AnyFullscreen="Capturar qualsevol aplicació a pantalla completa" GameCapture.CaptureWindow="Captura finestra específica"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/cs-CZ.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/cs-CZ.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Okno" WindowCapture.Method="Metoda záznamu" WindowCapture.Method.Auto="Automatická" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 a novější)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 a novější)" +WindowCapture.Method.BitBlt="Starší verze (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moderní (WGC)" WindowCapture.Priority="Priorita shody okna" WindowCapture.Priority.Title="Titulek okna se musí shodovat" WindowCapture.Priority.Class="Shoda názvu, jinak nejít okno stejného typu" @@ -19,8 +19,8 @@ Monitor="Obrazovka" PrimaryMonitor="Primární obrazovka" Method="Metoda záznamu" -Method.DXGI="DXGI Duplikace plochy" -Method.WindowsGraphicsCapture="Windows 10 (1903 a novější)" +Method.DXGI="Starší verze (DXGI)" +Method.WindowsGraphicsCapture="Moderní (WGC)" GameCapture="Záznam hry" GameCapture.AnyFullscreen="Zaznamenávat jakoukoliv aplikaci přes celou obrazovku" GameCapture.CaptureWindow="Snímat určité okno"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/da-DK.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/da-DK.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Vindue" WindowCapture.Method="Optagelsesmetode" WindowCapture.Method.Auto="Automatisk" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 og op)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 og senere)" WindowCapture.Priority="Vinduesmatchprioritet" WindowCapture.Priority.Title="Vinduestitel skal matche" WindowCapture.Priority.Class="Match titel, ellers find vindue af samme type" @@ -18,8 +16,6 @@ Monitor="Skærm" PrimaryMonitor="Primære skærm" Method="Optagemetode" -Method.DXGI="DXGI-computerdublettering" -Method.WindowsGraphicsCapture="Windows 10 (1903 og senere)" GameCapture="Spiloptager" GameCapture.AnyFullscreen="Optag ethvert fuldskærmsprogram" GameCapture.CaptureWindow="Optag specifikt vindue"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/de-DE.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/de-DE.ini
Changed
@@ -3,8 +3,7 @@ WindowCapture.Window="Fenster" WindowCapture.Method="Aufnahmemethode" WindowCapture.Method.Auto="Automatisch" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 und höher)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 und höher)" +WindowCapture.Method.BitBlt="Veraltet (BitBlt)" WindowCapture.Priority="Übereinstimmungspriorität" WindowCapture.Priority.Title="Fenstertitel muss übereinstimmen" WindowCapture.Priority.Class="Fenstertitel muss übereinstimmen, sonst Fenster desselben Typs finden" @@ -19,8 +18,7 @@ Monitor="Monitor" PrimaryMonitor="Hauptbildschirm" Method="Aufnahmemethode" -Method.DXGI="DXGI-Desktopduplikation" -Method.WindowsGraphicsCapture="Windows 10 (1903 und höher)" +Method.DXGI="Veraltet (DXGI)" GameCapture="Spielaufnahme" GameCapture.AnyFullscreen="Beliebige Vollbildanwendung erfassen" GameCapture.CaptureWindow="Bestimmtes Fenster erfassen"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/el-GR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/el-GR.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Παράθυρο" WindowCapture.Method="Μέθοδος Λήψης" WindowCapture.Method.Auto="Αυτόματο" -WindowCapture.Method.BitBlt="BitBlt (για Windows 7 και μετά)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 και άνω)" WindowCapture.Priority="Προτεραιότητα Αντιστοίχισης Παραθύρων" WindowCapture.Priority.Title="Ο τίτλος παραθύρου πρέπει να ταιριάζει" WindowCapture.Priority.Class="Αντιστοίχιση τίτλου, αλλιώς εύρεση παραθύρου ίδιου τύπου" @@ -18,8 +16,6 @@ Monitor="Οθόνη" PrimaryMonitor="Κύρια Oθόνη" Method="Μέθοδος Λήψης" -Method.DXGI="Αντιγραφή Επιφάνειας Εργασίας Dxgi" -Method.WindowsGraphicsCapture="Windows 10 (1903 και άνω)" GameCapture="Καταγραφή Παιχνιδιού" GameCapture.AnyFullscreen="Καταγραφή οποιασδήποτε εφαρμογής πλήρους οθόνης" GameCapture.CaptureWindow="Καταγραφή συγκεκριμένου παραθύρου"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/en-US.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/en-US.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Window" WindowCapture.Method="Capture Method" WindowCapture.Method.Auto="Automatic" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 and up)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 and up)" +WindowCapture.Method.BitBlt="Legacy (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Modern (WGC)" WindowCapture.Priority="Window Match Priority" WindowCapture.Priority.Title="Window title must match" WindowCapture.Priority.Class="Match title, otherwise find window of same type" @@ -19,8 +19,8 @@ Monitor="Display" PrimaryMonitor="Primary Monitor" Method="Capture Method" -Method.DXGI="DXGI Desktop Duplication" -Method.WindowsGraphicsCapture="Windows 10 (1903 and up)" +Method.DXGI="Legacy (DXGI)" +Method.WindowsGraphicsCapture="Modern (WGC)" GameCapture="Game Capture" GameCapture.AnyFullscreen="Capture any fullscreen application" GameCapture.CaptureWindow="Capture specific window"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/es-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/es-ES.ini
Changed
@@ -3,10 +3,10 @@ WindowCapture.Window="Ventana" WindowCapture.Method="Método de captura" WindowCapture.Method.Auto="Automático" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 o superior)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 o superior)" +WindowCapture.Method.BitBlt="Legado (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moderno (WGC)" WindowCapture.Priority="Prioridad de captura de ventana" -WindowCapture.Priority.Title="El titulo de la ventana debe coincidir" +WindowCapture.Priority.Title="El título de la ventana debe coincidir" WindowCapture.Priority.Class="Coincidir con el título, de lo contrario buscar ventana del mismo tipo" WindowCapture.Priority.Exe="Coincidir con el título, de lo contrario buscar ventana del mismo ejecutable" CaptureCursor="Captura de Cursor" @@ -19,8 +19,8 @@ Monitor="Pantalla" PrimaryMonitor="Monitor principal" Method="Método de captura" -Method.DXGI="Duplicación de escritorio DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 o superior)" +Method.DXGI="Legado (DXGI)" +Method.WindowsGraphicsCapture="Moderno (WGC)" GameCapture="Captura de juego" GameCapture.AnyFullscreen="Capturar cualquier aplicación de pantalla completa" GameCapture.CaptureWindow="Capturar ventana específica"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/et-EE.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/et-EE.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Aken" WindowCapture.Method="Püüdmismeetod" WindowCapture.Method.Auto="Automaatne" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ja uuemad)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ja uuemad)" +WindowCapture.Method.BitBlt="Pärand (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Kaasaegne (WGC)" WindowCapture.Priority="Akna sobitamise prioriteet" WindowCapture.Priority.Title="Akna pealkiri peab olema vastavuses" WindowCapture.Priority.Class="Vali vastav pealkiri, vastasel juhul leia sama tüüpi aken" @@ -19,8 +19,8 @@ Monitor="Kuvar" PrimaryMonitor="Esmane kuvar" Method="Püüdmismeetod" -Method.DXGI="DXGI töölaua dubleerimine" -Method.WindowsGraphicsCapture="Windows 10 (1903 ja uuemad)" +Method.DXGI="Pärand (DXGI)" +Method.WindowsGraphicsCapture="Kaasaegne (WGC)" GameCapture="Mängu hõive" GameCapture.AnyFullscreen="Mis tahes täisekraanil rakenduse jäädvustamine" GameCapture.CaptureWindow="Jäädvusta kindel aken"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/eu-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/eu-ES.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Leihoa" WindowCapture.Method="Kaptura metodoa" WindowCapture.Method.Auto="Automatikoa" -WindowCapture.Method.BitBlt="BitBit (Windows 7 eta berriagoak)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 eta handiagoa)" WindowCapture.Priority="Leihoa antzemateko lehentasuna" WindowCapture.Priority.Title="Leihoaren tituluak bat egin behar du" WindowCapture.Priority.Class="Bat egiten duen titulua, bestela bilatu mota bereko leihoa" @@ -18,8 +16,6 @@ Monitor="Pantaila" PrimaryMonitor="Monitore nagusia" Method="Kapturatzeko metodoa" -Method.DXGI="DXGI mahaigaina bikoiztea" -Method.WindowsGraphicsCapture="Windows 10 (1903 eta handiagoa)" GameCapture="Bideojoko-kaptura" GameCapture.AnyFullscreen="Kapturatu pantaila osoko edozein aplikazio" GameCapture.CaptureWindow="Kapturatu leiho zehatza"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/fa-IR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/fa-IR.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="ویندوز" WindowCapture.Method="روش ضبط" WindowCapture.Method.Auto="خودکار" -WindowCapture.Method.BitBlt="Bitblt (ویندوز 7 به بالا)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 به بالا)" +WindowCapture.Method.BitBlt="قدیمی (بیتبلیت)" +WindowCapture.Method.WindowsGraphicsCapture="مدرن (WGC)" WindowCapture.Priority="اولویت بازی پنجره" WindowCapture.Priority.Title="عنوان پنجره باید مطابقت داشته باشد" WindowCapture.Priority.Class="عنوان را انتخاب کنید، در غیر این صورت پنجره ای از همان نوع پیدا کنید" @@ -19,8 +19,8 @@ Monitor="نمایش" PrimaryMonitor="نمایشگر اصلی" Method="روش ضبط" -Method.DXGI="تکثیر دسک تاپ DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 به بالا)" +Method.DXGI="قدیمی (DXGI)" +Method.WindowsGraphicsCapture="مدرن (WGC)" GameCapture="ضبط بازی" GameCapture.AnyFullscreen="هر برنامه تمام صفحه را ضبط کنید" GameCapture.CaptureWindow="پنجره خاصی را ضبط کنید"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/fi-FI.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/fi-FI.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Ikkuna" WindowCapture.Method="Kaappausmenetelmä" WindowCapture.Method.Auto="Automaattinen" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ja uudemmat)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 tai uudempi)" WindowCapture.Priority="Ikkunan valintaperuste" WindowCapture.Priority.Title="Ikkunan otsikon on täsmättävä" WindowCapture.Priority.Class="Täsmäävä otsikko, muutoin etsitään saman tyypin ikkuna" @@ -19,8 +17,6 @@ Monitor="Monitori" PrimaryMonitor="Ensisijainen näyttö" Method="Kaappausmenetelmä" -Method.DXGI="DXGI-työpöydän monistaminen" -Method.WindowsGraphicsCapture="Windows 10 (1903 tai uudempi)" GameCapture="Pelikaappaus" GameCapture.AnyFullscreen="Kaappaa mitä tahansa koko näytön sovellusta" GameCapture.CaptureWindow="Kaappaa tietty ikkuna"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/fil-PH.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/fil-PH.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Bintana" WindowCapture.Method="Paraan ng Pagcapture" WindowCapture.Method.Auto="Kusa" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 o pataas)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 at pataas)" WindowCapture.Priority="Bintanang Tugma sa Prayoridad" WindowCapture.Priority.Title="Pamagat ng Window na mas tugma" WindowCapture.Priority.Class="Tugmang pamagat, kung hindi matatagpuan ang window sa parehong uri" @@ -18,7 +16,6 @@ Monitor="Displey" PrimaryMonitor="Pangunahing pagsubaybay" Method="Paraan ng Pagcapture" -Method.WindowsGraphicsCapture="Windows 10 (1903 at pataas)" GameCapture="Kumuha ng Laro" GameCapture.AnyFullscreen="Kumuha ng kahit na anong fullscreen ng aplikasyon" GameCapture.CaptureWindow="Kumuha ng tiyak na window"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/fr-FR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/fr-FR.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Fenêtre" WindowCapture.Method="Méthode de capture" WindowCapture.Method.Auto="Automatique" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 et supérieur)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (versions 1903 et postérieures)" +WindowCapture.Method.BitBlt="Hérité (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moderne (WGC)" WindowCapture.Priority="Critères d'association de fenêtre" WindowCapture.Priority.Title="Le nom de fenêtre doit correspondre" WindowCapture.Priority.Class="Titre correspondant, sinon trouver une fenêtre de même type" @@ -19,8 +19,8 @@ Monitor="Écran" PrimaryMonitor="Écran principal" Method="Méthode de capture" -Method.DXGI="Duplication de bureau DXGI" -Method.WindowsGraphicsCapture="Windows 10 (versions 1903 et postérieures)" +Method.DXGI="Hérité (DXGI)" +Method.WindowsGraphicsCapture="Moderne (WGC)" GameCapture="Capture de jeu" GameCapture.AnyFullscreen="Capturer les applications en plein écran" GameCapture.CaptureWindow="Capturer une fenêtre spécifique"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/gd-GB.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/gd-GB.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Uinneag" WindowCapture.Method="Modh a’ ghlacaidh" WindowCapture.Method.Auto="Fèin-obrachail" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 is nas ùire)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 is nas ùire)" WindowCapture.Priority="Prìomhachas air maidseadh na h-uinneige" WindowCapture.Priority.Title="Feumaidh tiotal na h-uinneige a bhith co-ionnann" WindowCapture.Priority.Class="Maidsich an tiotal air neo lorg uinneag dhen aon seòrsa" @@ -17,8 +15,6 @@ Monitor="Uidheam-taisbeanaidh" PrimaryMonitor="Am prìomh-mhonatair" Method="Modh a’ ghlacaidh" -Method.DXGI="Dùblachadh deasg DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 is nas ùire)" GameCapture="Glacadh geama" GameCapture.AnyFullscreen="Glac aplacaid làn-sgrìn sam bith" GameCapture.CaptureWindow="Glac uinneag shònraichte"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/gl-ES.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/gl-ES.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Xanela" WindowCapture.Method="Método de captura" WindowCapture.Method.Auto="Automático" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 e superiores)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 e superiores)" +WindowCapture.Method.BitBlt="Herdado (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moderno (WGC)" WindowCapture.Priority="Prioridade de captura da xanela" WindowCapture.Priority.Title="O título da xanela debe coincidir" WindowCapture.Priority.Class="Que coincida co título, no caso contrario atopar unha xanela do mesmo tipo" @@ -19,8 +19,8 @@ Monitor="Pantalla" PrimaryMonitor="Monitor principal" Method="Método de captura" -Method.DXGI="Duplicación de escritorio DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 e superiores)" +Method.DXGI="Herdado (DXGI)" +Method.WindowsGraphicsCapture="Moderno (WGC)" GameCapture="Captura do xogo" GameCapture.AnyFullscreen="Capturar calquera aplicación a pantalla completa" GameCapture.CaptureWindow="Capturar unha xanela específica"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/he-IL.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/he-IL.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="חלון" WindowCapture.Method="שיטת הקלטה" WindowCapture.Method.Auto="אוטומטי" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ומעלה)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ומעלה)" +WindowCapture.Method.BitBlt="מיושן (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="עדכני (WGC)" WindowCapture.Priority="חלון התאמת עדיפות" WindowCapture.Priority.Title="כותרת חלון חייבת להתאים" WindowCapture.Priority.Class="התאם כותרת, אחרת מצא חלון מאותו סוג" @@ -19,8 +19,8 @@ Monitor="צג" PrimaryMonitor="צג ראשי" Method="שיטת הקלטה" -Method.DXGI="שכפול שולחן עבודה DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 ומעלה)" +Method.DXGI="מיושן (DXGI)" +Method.WindowsGraphicsCapture="עדכני (WGC)" GameCapture="הקלטת משחקים" GameCapture.AnyFullscreen="הקלטת כל יישום מסך מלא שהוא" GameCapture.CaptureWindow="הקלטת חלון מסוים"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/hi-IN.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/hi-IN.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="विंडो" WindowCapture.Method="कैप्चर विधि" WindowCapture.Method.Auto="स्वचालित" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 और ऊपर)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 और ऊपर)" WindowCapture.Priority="विंडो मिलान प्राथमिकता" WindowCapture.Priority.Title="विंडो शीर्षक से मेल खाना चाहिए" WindowCapture.Priority.Class="शीर्षक का मिलान करें, अन्यथा उसी प्रकार की विंडो ढूंढें" @@ -19,8 +17,6 @@ Monitor="डिस्प्ले" PrimaryMonitor="प्राथमिक मॉनिटर" Method="कैप्चर विधि" -Method.DXGI="DXGI डेस्कटॉप प्रतिलिपि बनाना" -Method.WindowsGraphicsCapture="Windows 10 (1903 और ऊपर)" GameCapture="गेम कैप्चर" GameCapture.AnyFullscreen="किसी भी फ़ुलस्क्रीन एप्लिकेशन को कैप्चर करें" GameCapture.CaptureWindow="विशिष्ट विंडो कैप्चर करें"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/hr-HR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/hr-HR.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Prozor" WindowCapture.Method="Metoda snimanja" WindowCapture.Method.Auto="Automatski" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 i noviji)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 i noviji)" WindowCapture.Priority="Prioritet prozora" WindowCapture.Priority.Title="Naslov prozora mora se podudarati" WindowCapture.Priority.Class="Podudaranje naslova, inače pronađi prozor iste vrste" @@ -19,8 +17,6 @@ Monitor="Zaslon" PrimaryMonitor="Primarni monitor" Method="Metoda snimanja" -Method.DXGI="DXGI dupliciranje na radnoj površini" -Method.WindowsGraphicsCapture="Windows 10 (1903 i noviji)" GameCapture="Snimanje igre" GameCapture.AnyFullscreen="Ulaz sa bilo koje aplikacije koja je preko celog ekrana" GameCapture.CaptureWindow="Snimanje određenog prozora"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/hu-HU.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/hu-HU.ini
Changed
@@ -3,8 +3,7 @@ WindowCapture.Window="Ablak" WindowCapture.Method="Felvétel módja" WindowCapture.Method.Auto="Automatikus" -WindowCapture.Method.BitBlt="BitBlt (Windows 7-től)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 és újabb)" +WindowCapture.Method.BitBlt="Örökölt (BitBlt)" WindowCapture.Priority="Ablaktalálati prioritás" WindowCapture.Priority.Title="Az ablak címének meg kell egyeznie" WindowCapture.Priority.Class="Egyező cím, egyébként találjon ugyanolyan típusút" @@ -19,8 +18,7 @@ Monitor="Kijelző" PrimaryMonitor="Elsődleges képernyő" Method="Felvétel módja" -Method.DXGI="DXGI asztaltükrözés" -Method.WindowsGraphicsCapture="Windows 10 (1903 és újabb)" +Method.DXGI="Örökölt (DXGI)" GameCapture="Játék felvétele" GameCapture.AnyFullscreen="Teljes képernyős alkalmazás felvétele" GameCapture.CaptureWindow="Adott ablak felvétele"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/hy-AM.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/hy-AM.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Պատուհան" WindowCapture.Method="Նկարահանման մեթոդ" WindowCapture.Method.Auto="Ավտոմատ" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 և ավելի բարձր)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 և ավելի բարձր)" WindowCapture.Priority="Պատուհանների բանակցությունների առաջնահերթություն" WindowCapture.Priority.Title="Պատուհանի վերնագիրը պետք է համապատասխանի" WindowCapture.Priority.Class="Համեմատեք վերնագիրը, հակառակ դեպքում գտեք նույն տիպի պատուհան" @@ -18,8 +16,6 @@ Monitor="Էկրան" PrimaryMonitor="Առաջնային մոնիտոր" Method="Նկարահանման մեթոդ" -Method.DXGI="DXGI աշխատասեղանի կրկնօրինակում" -Method.WindowsGraphicsCapture="Windows 10 (1903 և ավելի բարձր)" GameCapture="Խաղի նկարահանումը" GameCapture.AnyFullscreen="Լուսանկարեք ցանկացած ամբողջական էկրանով հավելված" GameCapture.CaptureWindow="Առանձին պատուհանի նկարում"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/id-ID.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/id-ID.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Jendela" WindowCapture.Method="Metode Tangkapan" WindowCapture.Method.Auto="Otomatis" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ke atas)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ke atas)" +WindowCapture.Method.BitBlt="Lawas (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moderen (WGC)" WindowCapture.Priority="Prioritas Kecocokan Jendela" WindowCapture.Priority.Title="Judul jendela harus cocok" WindowCapture.Priority.Class="Sesuai judul. Jika tidak ada, cari tipe jendela yang sama" @@ -19,8 +19,8 @@ Monitor="Tampilan" PrimaryMonitor="Monitor Utama" Method="Metode Tangkapan" -Method.DXGI="Duplikasi Desktop DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 ke atas)" +Method.DXGI="Lawas (DXGI)" +Method.WindowsGraphicsCapture="Moderen (WGC)" GameCapture="Tangkapan Gim" GameCapture.AnyFullscreen="Tangkap aplikasi layar penuh apapun" GameCapture.CaptureWindow="Tangkap jendela spesifik"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/it-IT.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/it-IT.ini
Changed
@@ -3,8 +3,7 @@ WindowCapture.Window="Finestra" WindowCapture.Method="Metodo di acquisizione" WindowCapture.Method.Auto="Automatico" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 o superiore)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 e superiore)" +WindowCapture.Method.WindowsGraphicsCapture="Moderna (WGC)" WindowCapture.Priority="Tipo di ricerca della finestra" WindowCapture.Priority.Title="Il titolo della finestra deve corrispondere" WindowCapture.Priority.Class="Il titolo della finestra deve corrispondere, altrimenti cercare una finestra dello stesso tipo" @@ -19,8 +18,7 @@ Monitor="Schermo" PrimaryMonitor="Schermo principale" Method="Metodo di acquisizione" -Method.DXGI="Duplicazione Desktop DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 e superiore)" +Method.WindowsGraphicsCapture="Moderna (WGC)" GameCapture="Cattura gioco" GameCapture.AnyFullscreen="Cattura qualsiasi applicazione a schermo intero" GameCapture.CaptureWindow="Cattura una finestra specifica"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ja-JP.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ja-JP.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="ウィンドウ" WindowCapture.Method="キャプチャ方法" WindowCapture.Method.Auto="自動" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 以降)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903以降)" +WindowCapture.Method.BitBlt="旧方式 (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="新方式 (WGC)" WindowCapture.Priority="ウィンドウの一致優先順位" WindowCapture.Priority.Title="ウィンドウのタイトルに一致する必要があります" WindowCapture.Priority.Class="タイトルに一致、そうでなければ同じ種類のウィンドウを見つける" @@ -19,8 +19,8 @@ Monitor="ディスプレイ" PrimaryMonitor="プライマリモニター" Method="キャプチャ方法" -Method.DXGI="DXGI デスクトップ複製" -Method.WindowsGraphicsCapture="Windows 10 (1903以降)" +Method.DXGI="旧方式 (DXGI)" +Method.WindowsGraphicsCapture="新方式 (WGC)" GameCapture="ゲームキャプチャ" GameCapture.AnyFullscreen="フルスクリーンアプリケーションをキャプチャ" GameCapture.CaptureWindow="特定のウィンドウをキャプチャ"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ka-GE.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ka-GE.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="ფანჯარა" WindowCapture.Method="გადაღების მეთოდი" WindowCapture.Method.Auto="თვითშერჩევა" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 და ზემოთ)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 და ზემოთ)" +WindowCapture.Method.BitBlt="მოძველებული (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="ახლებური (WGC)" WindowCapture.Priority="უპირატესობა ფანჯრის შერჩევისას" WindowCapture.Priority.Title="ფანჯრის სათაურის მიხედვით" WindowCapture.Priority.Class="სათაურის მიხედვით, თუ არადა, იმავე სახის ფანჯრის მონახვა" @@ -19,8 +19,8 @@ Monitor="ეკრანი" PrimaryMonitor="ძირითადი მონიტორი" Method="გადაღების მეთოდი" -Method.DXGI="DXGI-ეკრანის გაორმაგება" -Method.WindowsGraphicsCapture="Windows 10 (1903 და ზემოთ)" +Method.DXGI="მოძველებული (DXGI)" +Method.WindowsGraphicsCapture="ახლებური (WGC)" GameCapture="თამაშის გადაღება" GameCapture.AnyFullscreen="ნებისმიერი სრულეკრანიანი პროგრამის გადაღება" GameCapture.CaptureWindow="ცალკეული ფანჯრის გადაღება"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/kaa.ini
Changed
@@ -3,17 +3,15 @@ WindowCapture.Window="Ayna" WindowCapture.Method="Qamtıw usılı" WindowCapture.Method.Auto="Avtomat tárizde" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 hám joqarı)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 hám joqarı)" CaptureCursor="Kórsetkishti qamtıw" Monitor="Ekran" PrimaryMonitor="Tiykarǵı monitor" Method="Qamtıw usılı" -Method.WindowsGraphicsCapture="Windows 10 (1903 hám joqarı)" GameCapture="Oyındı qamtıp alıw" GameCapture.HookRate.Slow="Áste" GameCapture.HookRate.Normal="Normal (usınıs etiledi)" -GameCapture.HookRate.Fast="Tez" +GameCapture.HookRate.Fast="Тез" GameCapture.HookRate.Fastest="Júdá tez" GameCapture.Rgb10a2Space="RGB10A2 reń aralıǵı" -Mode="Rejim" +Mode="Режим" +AudioSuffix="Аудио"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/kab-KAB.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/kab-KAB.ini
Changed
@@ -3,7 +3,6 @@ WindowCapture.Window="Asfaylu" WindowCapture.Method="Tarrayt n tuṭṭfa" WindowCapture.Method.Auto="Awurman" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 neɣ ugar)" WindowCapture.Priority.Title="Ilaq ad inmeɣri uzwel n usfaylu" WindowCapture.Priority.Class="Azwel inmeɣran, ma ulac af-d asfaylu ysɛan anaw kifkif" CaptureCursor="Ṭṭef taḥnaccaḍt"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/kmr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/kmr-TR.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Çarçove" WindowCapture.Method="Awayê girtinê" WindowCapture.Method.Auto="Bixweber" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 û jor)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 û jor)" WindowCapture.Priority="Pêşekiya çarçoveyê hilbijartî" WindowCapture.Priority.Title="Divê bi sernava çaçroveyê re lihevhatî bê" WindowCapture.Priority.Class="Sernav lihevhatî ye, wekî din çaçroveya ji heman cure bigere" @@ -18,8 +16,6 @@ Monitor="Dîmender" PrimaryMonitor="Dîmendera seretayî" Method="Awayê girtinê" -Method.DXGI="Dubarekirina sermaseya DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 û jor)" GameCapture="Girtina lîstikê" GameCapture.AnyFullscreen="Kîjan sepan di dîmenderê tijî de hebê bigire" GameCapture.CaptureWindow="Çarçoveya nîşankirî bigire"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ko-KR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ko-KR.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="윈도우" WindowCapture.Method="캡쳐 방식" WindowCapture.Method.Auto="자동" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 혹은 그 이상)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 이상)" +WindowCapture.Method.BitBlt="구식 (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="신식 (WGC)" WindowCapture.Priority="윈도우 일치 우선순위" WindowCapture.Priority.Title="제목이 일치하는 창 찾기" WindowCapture.Priority.Class="제목이 일치하거나, 없으면 형식이 같은 창 찾기" @@ -19,8 +19,8 @@ Monitor="디스플레이" PrimaryMonitor="주 모니터" Method="캡쳐 방식" -Method.DXGI="DXGI 데스크탑 복사" -Method.WindowsGraphicsCapture="Windows 10 (1903 이상)" +Method.DXGI="구식 (DXGI)" +Method.WindowsGraphicsCapture="신식 (WGC)" GameCapture="게임 캡쳐" GameCapture.AnyFullscreen="전체 화면 응용 프로그램 캡처" GameCapture.CaptureWindow="특정 창을 캡쳐"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/lo-LA.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/lo-LA.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="ໜ້າຕ່າງ" WindowCapture.Method="ວິທີການບັນທຶກ" WindowCapture.Method.Auto="ອັດຕະໂນມັດ" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ຂຶ້ນໄປ)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ຂຶ້ນໄປ)" WindowCapture.Priority="ລຳດັບຄວາມສຳຄັນໃນການທຽບໜ້າຕ່າງ" WindowCapture.Priority.Title="ຊື່ໜ້າຕ່າງຕ້ອງກົງກັນ" WindowCapture.Priority.Class="ທຽບຊື່, ຖ້າບໍ່ໄດ້ໃຫ້ຫາໜ້າຕ່າງປະເພດດຽວກັນ" @@ -18,7 +16,6 @@ Monitor="ຈໍສະແດງຜົນ" PrimaryMonitor="ຈໍສະແດງຜົນຫຼັກ" Method="ວິທີການບັນທຶກ" -Method.WindowsGraphicsCapture="Windows 10 (1903 ຂຶ້ນໄປ)" GameCapture="ບັນທຶກເກມ" GameCapture.AnyFullscreen="ບັນທຶກໂປຼແກຼມເຕັມຈໍໃດໜຶ່ງ" GameCapture.CaptureWindow="ບັນທຶກໜ້າຕ່າງທີ່ລະບຸ"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/lt-LT.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/lt-LT.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Langas" WindowCapture.Method="Fiksavimo Metodas" WindowCapture.Method.Auto="Automatinis" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ir naujesni)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ir naujesni)" WindowCapture.Priority="Lango Sutapimo Prioritetas" WindowCapture.Priority.Title="Lango pavadinimas privalo sutapti" WindowCapture.Priority.Class="Pavadinimai sutampa, jeigu ne, rasti to pačio tipo langą" @@ -17,8 +15,6 @@ Monitor="Ekranas" PrimaryMonitor="Pagrindinis Monitorius" Method="Fiksavimo Metodas" -Method.DXGI="DXGI Darbalaukio Dubliavimasis" -Method.WindowsGraphicsCapture="Windows 10 (1903 ir naujesni)" GameCapture="Žaidimų Fiksavimas" GameCapture.AnyFullscreen="Fiksuoti bet kurią programą kuri yra pilno ekrano režime" GameCapture.CaptureWindow="Fiksuoti specifinį langą"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ms-MY.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ms-MY.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Tetingkap" WindowCapture.Method="Kaedah Tangkap" WindowCapture.Method.Auto="Automatik" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 dan ke atas)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 dan ke atas)" +WindowCapture.Method.BitBlt="Legasi (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moden (WGC)" WindowCapture.Priority="Keutamaan Padanan Tetingkap" WindowCapture.Priority.Title="Tajuk tetingkap mesti sepadan" WindowCapture.Priority.Class="Padan tajuk, melainkan cari tetingkap bagi jenis yang serupa" @@ -19,8 +19,8 @@ Monitor="Paparan" PrimaryMonitor="Pemantau Utama" Method="Kaedah Tangkap" -Method.DXGI="Duplikasi Atas Meja DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 dan ke atas)" +Method.DXGI="Legasi (DXGI)" +Method.WindowsGraphicsCapture="Moden (WGC)" GameCapture="Tangkap Permainan" GameCapture.AnyFullscreen="Tangkap mana-mana aplikasi berskrin penuh" GameCapture.CaptureWindow="Tangkap tetingkap khusus"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/nb-NO.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/nb-NO.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Vindu" WindowCapture.Method="Opptaksmetode" WindowCapture.Method.Auto="Automatisk" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 og oppover)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 og oppover)" WindowCapture.Priority="Match vindusprioritet" WindowCapture.Priority.Title="Vindustitler må være like" WindowCapture.Priority.Class="Finn lik tittel, ellers finn vindu av samme type" @@ -18,8 +16,6 @@ Monitor="Skjerm" PrimaryMonitor="Hovedskjerm" Method="Opptaksmetode" -Method.DXGI="DXGI Skrivebordsduplisering" -Method.WindowsGraphicsCapture="Windows 10 (1903 og oppover)" GameCapture="Spillopptak" GameCapture.AnyFullscreen="Opptak av fullskjermapplikasjon" GameCapture.CaptureWindow="Ta opp et bestemt vindu"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/nl-NL.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/nl-NL.ini
Changed
@@ -3,8 +3,7 @@ WindowCapture.Window="Venster" WindowCapture.Method="Opnamemethode" WindowCapture.Method.Auto="Automatisch" -WindowCapture.Method.BitBlt="BitBit (Windows 7 en hoger)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 en hoger)" +WindowCapture.Method.BitBlt="Verouderd (BitBlt)" WindowCapture.Priority="Venster Match Prioriteit" WindowCapture.Priority.Title="Venstertitel moet overeenkomen" WindowCapture.Priority.Class="Hetzelfde als de titelbar, vind anders een scherm van hetzelfde type" @@ -18,8 +17,7 @@ Monitor="Beeldscherm" PrimaryMonitor="Primaire Monitor" Method="Opnamemethode" -Method.DXGI="DXGI-Desktopduplicatie" -Method.WindowsGraphicsCapture="Windows 10 (1903 en hoger)" +Method.DXGI="Verouderd (DXGI)" GameCapture.AnyFullscreen="Capture elke full-screen applicatie" GameCapture.CaptureWindow="Specifiek venster opnemen" GameCapture.UseHotkey="Venster op voorgrond opnemen met sneltoets"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/pl-PL.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/pl-PL.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Okno" WindowCapture.Method="Metoda przechwytywania" WindowCapture.Method.Auto="Automatycznie" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 i nowsze)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 i nowsze)" +WindowCapture.Method.BitBlt="Przestarzała (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Współczesna (WGC)" WindowCapture.Priority="Priorytet przechwytywanych okien" WindowCapture.Priority.Title="Tytuł okna musi się zgadzać" WindowCapture.Priority.Class="Tytuł okna musi się zgadzać, w przeciwnym razie znajdź okno tego samego typu" @@ -19,8 +19,8 @@ Monitor="Ekran" PrimaryMonitor="Monitor główny" Method="Metoda przechwytywania" -Method.DXGI="Duplikacja pulpitu DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 i nowsze)" +Method.DXGI="Przestarzała (DXGI)" +Method.WindowsGraphicsCapture="Współczesna (WGC)" GameCapture="Przechwytywanie gry" GameCapture.AnyFullscreen="Przechwytuj dowolną aplikację pełnoekranową" GameCapture.CaptureWindow="Przechwytuj konkretne okno"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/pt-BR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/pt-BR.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Janela" WindowCapture.Method="Método de captura" WindowCapture.Method.Auto="Automático" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ou superior)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ou superior)" +WindowCapture.Method.BitBlt="Legado (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moderno (WGC)" WindowCapture.Priority="Prioridade de correspondência da janela" WindowCapture.Priority.Title="Título da janela deve combinar" WindowCapture.Priority.Class="Combinar título, caso contrário buscar janela do mesmo tipo" @@ -19,8 +19,8 @@ Monitor="Monitor" PrimaryMonitor="Monitor principal" Method="Método de captura" -Method.DXGI="Duplicação da área de trabalho DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 ou superior)" +Method.DXGI="Legado (DXGI)" +Method.WindowsGraphicsCapture="Moderno (WGC)" GameCapture="Captura de jogo" GameCapture.AnyFullscreen="Capturar qualquer aplicativo em tela cheia" GameCapture.CaptureWindow="Capturar janela específica"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/pt-PT.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/pt-PT.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Janela" WindowCapture.Method="Método de captura" WindowCapture.Method.Auto="Automático" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ou superior)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ou superior)" +WindowCapture.Method.BitBlt="Obsoleto (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moderno (WGC)" WindowCapture.Priority="Correspondência de janela - Prioridade" WindowCapture.Priority.Title="O título da janela tem de corresponder" WindowCapture.Priority.Class="Corresponder a título, caso contrário, encontrar janela do mesmo tipo" @@ -19,8 +19,8 @@ Monitor="Monitor" PrimaryMonitor="Monitor principal" Method="Método de captura" -Method.DXGI="Duplicação do ambiente DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 ou superior)" +Method.DXGI="Obsoleto (DXGI)" +Method.WindowsGraphicsCapture="Moderno (WGC)" GameCapture="Captura de jogo" GameCapture.AnyFullscreen="Capturar qualquer aplicação de ecrã total" GameCapture.CaptureWindow="Capturar uma janela especifica"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ro-RO.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ro-RO.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Fereastră" WindowCapture.Method="Metodă de captură" WindowCapture.Method.Auto="Automată" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 și versiunile ulterioare de Windows)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 și versiunile ulterioare)" WindowCapture.Priority="Prioritate de potrivire a ferestrelor" WindowCapture.Priority.Title="Titlul ferestrei trebuie să se potrivească" WindowCapture.Priority.Class="Titlul să se potrivească, altminteri găsește o fereastră de același tip" @@ -17,8 +15,6 @@ AllowTransparency="Permite transparență" PrimaryMonitor="Monitor principal" Method="Metodă de captură" -Method.DXGI="Duplicare de desktop DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 și superior)" GameCapture="Captură de joc" GameCapture.AnyFullscreen="Capturează orice aplicație în ecran complet" GameCapture.CaptureWindow="Capturează o fereastră specifică"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ru-RU.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ru-RU.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Окно" WindowCapture.Method="Способ захвата" WindowCapture.Method.Auto="Автоматический" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 и выше)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (версия 1903 или новее)" +WindowCapture.Method.BitBlt="Устаревший (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Современный (WGC)" WindowCapture.Priority="Приоритет подбора окна" WindowCapture.Priority.Title="Заголовок окна должен совпадать" WindowCapture.Priority.Class="Сравнивать заголовок, в противном случае найти окно того же типа" @@ -19,8 +19,8 @@ Monitor="Экран" PrimaryMonitor="Основной монитор" Method="Способ захвата" -Method.DXGI="Копия рабочего стола DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 и выше)" +Method.DXGI="Устаревший (DXGI)" +Method.WindowsGraphicsCapture="Современный (WGC)" GameCapture="Захват игры" GameCapture.AnyFullscreen="Захват любого полноэкранного приложения" GameCapture.CaptureWindow="Захват отдельного окна"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/si-LK.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/si-LK.ini
Changed
@@ -3,13 +3,11 @@ WindowCapture.Window="කවුළුව" WindowCapture.Method="ග්රහණ ක්රමය" WindowCapture.Method.Auto="ස්වයංක්රීය" -WindowCapture.Method.WindowsGraphicsCapture="වින්ඩෝස් 10 (1903 සහ +)" CaptureCursor="ඊතලය ග්රහණය" ClientArea="අනුග්රාහක පෙදෙස" AllowTransparency="විනිවිදභාවයට ඉඩ දෙන්න" Monitor="දර්ශකය" PrimaryMonitor="ප්රාථමික තිරය" -Method.WindowsGraphicsCapture="වින්ඩෝස් 10 (1903 සහ +)" GameCapture="ක්රීඩාවක් ග්රහණය" GameCapture.AnyFullscreen="ඕනෑම පූර්ණ තිර යෙදුමක් ග්රහණය කරන්න" GameCapture.CaptureWindow="නිශ්චිත කවුළුවක් ග්රහණය කරන්න"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/sk-SK.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/sk-SK.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Okno" WindowCapture.Method="Metóda zachytenia" WindowCapture.Method.Auto="Automatické" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 a vyšší)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 a vyššie)" +WindowCapture.Method.BitBlt="Staršia (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Moderná (WGC)" WindowCapture.Priority="Priorita zhody okna" WindowCapture.Priority.Title="Názov okna sa musí zhodovať" WindowCapture.Priority.Class="Zhoda názvu, inak nájdi okno rovnakého typu" @@ -19,8 +19,8 @@ Monitor="Monitor" PrimaryMonitor="Primárny monitor" Method="Metóda zachytenia" -Method.DXGI="DXGI Duplikácia plochy" -Method.WindowsGraphicsCapture="Windows 10 (1903 a vyššie)" +Method.DXGI="Staršia (DXGI)" +Method.WindowsGraphicsCapture="Moderná (WGC)" GameCapture="Zachytávanie hry" GameCapture.AnyFullscreen="Zachytiť akúkoľvek celoobrazovkovú aplikáciu" GameCapture.CaptureWindow="Zachytiť špecifické okno"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/sl-SI.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/sl-SI.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Okno" WindowCapture.Method="Način zajema" WindowCapture.Method.Auto="Samodejno" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 in novejši)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 in več)" WindowCapture.Priority="Prednost ujemanja okna" WindowCapture.Priority.Title="Ujemati se mora naziv okna" WindowCapture.Priority.Class="Naziv se mora ujemati, sicer poiščite okno iste vrste" @@ -19,8 +17,6 @@ Monitor="Zaslon" PrimaryMonitor="Glavni monitor" Method="Način zajemanja" -Method.DXGI="DXGI podvajanje namizja" -Method.WindowsGraphicsCapture="Windows 10 (1903 in več)" GameCapture="Zajemanje igre" GameCapture.AnyFullscreen="Zajemaj katerikoli celozaslonski program" GameCapture.CaptureWindow="Zajemaj določeno okno"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/sq-AL.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/sq-AL.ini
Changed
@@ -1,12 +1,9 @@ WindowCapture.Window="Dritarja " WindowCapture.Method="Metoda e rregjistrimit" WindowCapture.Method.Auto="Automatike" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 dhe sipër)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 dhe sipër) " WindowCapture.Priority.Title="Titulli i dritares duhet të përputhet" CaptureCursor="Rregjistro kursorin e mausit" Method="Metoda e rregjistrimit" -Method.WindowsGraphicsCapture="Windows 10 (1903 dhe sipër) " GameCapture="Rregjistrim Loje" GameCapture.CaptureWindow="Rregjistro dritare specifike" GameCapture.HotkeyStop="Çaktivizo rregjistrimin"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/sr-SP.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/sr-SP.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Прозор" WindowCapture.Method="Метода снимања" WindowCapture.Method.Auto="Аутоматски" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 и новије)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 и новији)" WindowCapture.Priority="Приоритет прозора" WindowCapture.Priority.Title="Наслов прозора мора да се подудара" WindowCapture.Priority.Class="Ускладите наслов, или у супротном пронађите прозор истог типа" @@ -19,8 +17,6 @@ Monitor="Прикажи" PrimaryMonitor="Примарни монитор" Method="Метод снимања" -Method.DXGI="Дуплирање DXGI радне површине" -Method.WindowsGraphicsCapture="Windows 10 (1903 и новији)" GameCapture="Улаз са игре" GameCapture.AnyFullscreen="Улаз са било које апликације која је преко целог екрана" GameCapture.CaptureWindow="Снимање одређеног прозора"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/sv-SE.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/sv-SE.ini
Changed
@@ -3,8 +3,7 @@ WindowCapture.Window="Fönster" WindowCapture.Method="Uppfångstmetod" WindowCapture.Method.Auto="Automatisk" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 och senare)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 och senare)" +WindowCapture.Method.BitBlt="Äldre (BitBlt)" WindowCapture.Priority="Prioritet för fönstermatchning" WindowCapture.Priority.Title="Fönstertitel måste matcha" WindowCapture.Priority.Class="Matcha titel, hitta annars fönster av samma typ" @@ -19,8 +18,7 @@ Monitor="Bildskärm" PrimaryMonitor="Primära bildskärmen" Method="Uppfångstmetod" -Method.DXGI="DXGI-skrivbordsduplicering" -Method.WindowsGraphicsCapture="Windows 10 (1903 och senare)" +Method.DXGI="Äldre (DXGI)" GameCapture="Spelkälla" GameCapture.AnyFullscreen="Spela in alla program i fullskärm" GameCapture.CaptureWindow="Spela in specifikt fönster"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ta-IN.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ta-IN.ini
Changed
@@ -3,12 +3,9 @@ WindowCapture.Window="சாளரம்" WindowCapture.Method="பிடிப்பு முறை" WindowCapture.Method.Auto="தானியங்கி" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 மற்றும் மேல்)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 மற்றும் மேல்)" WindowCapture.Priority.Title="சாளர தலைப்புப் பொருந்த வேண்டும்" Monitor="காட்சி" PrimaryMonitor="முதன்மை காட்சித்திரை" -Method.WindowsGraphicsCapture="Windows 10 (1903 மற்றும் மேல்)" GameCapture="விளையாட்டம் பிடிப்பு" GameCapture.HookRate.Slow="மெதுவான" GameCapture.HookRate.Normal="சாதாரணம் (பரிந்துரைக்கப்படுபவை)"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/th-TH.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/th-TH.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="หน้าต่าง" WindowCapture.Method="วิธีการจับภาพ" WindowCapture.Method.Auto="อัตโนมัติ" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ขึ้นไป)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ขึ้นไป)" WindowCapture.Priority="ลำดับความสำคัญในการเทียบตรงหน้าต่าง" WindowCapture.Priority.Title="ชื่อหน้าต่างต้องตรงกัน" WindowCapture.Priority.Class="ชื่อตรงกัน ถ้าไม่ตรงให้หาหน้าต่างที่เป็นชนิดเดียวกัน" @@ -19,8 +17,6 @@ Monitor="จอภาพ" PrimaryMonitor="จอภาพหลัก" Method="วิธีการจับภาพ" -Method.DXGI="การทำซ้ำเดสก์ท็อป DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 ขึ้นไป)" GameCapture="จับภาพเกม" GameCapture.AnyFullscreen="จับภาพแอปพลิเคชันเต็มจอทั้งหมด" GameCapture.CaptureWindow="จับภาพหน้าต่างที่ระบุ"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/tr-TR.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Pencere" WindowCapture.Method="Yakalama Yöntemi" WindowCapture.Method.Auto="Otomatik" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ve üstü)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ve üstü)" WindowCapture.Priority="Pencere Eşleşme Önceliği" WindowCapture.Priority.Title="Pencere başlığı eşleşmeli" WindowCapture.Priority.Class="Başlığı eşleştir, olmazsa aynı türde pencere bul" @@ -19,8 +17,6 @@ Monitor="Görüntü" PrimaryMonitor="Birincil Ekran" Method="Yakalama Yöntemi" -Method.DXGI="DXGI Masaüstü Çoğaltma" -Method.WindowsGraphicsCapture="Windows 10 (1903 ve üstü)" GameCapture="Oyun Yakalama" GameCapture.AnyFullscreen="Tam ekran herhangi bir uygulamayı yakala" GameCapture.CaptureWindow="Belirli bir pencereyi yakala"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/tt-RU.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/tt-RU.ini
Changed
@@ -1,10 +1,7 @@ WindowCapture="Тәрәзә яздыру" WindowCapture.Window="Тәрәзә" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 яки яңарак)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 версия яки яңарак)" CaptureCursor="Күрсәткечне яздыру" Monitor="Экран" -Method.WindowsGraphicsCapture="Windows 10 (1903 версия яки яңарак)" GameCapture="Уен яздыру" GameCapture.HookRate.Normal="Нормаль (киңәш ителә)" GameCapture.HookRate.Fast="Тиз"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/ug-CN.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/ug-CN.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="كۆزنەك" WindowCapture.Method="ئېكران تۇتۇش ئۇسۇلى" WindowCapture.Method.Auto="ئاپتوماتىك" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 ياكى تېخىمۇ يۇقىرى نەشرى)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 ۋە تېخىمۇ يۇقىرى نەشرى)" +WindowCapture.Method.BitBlt="كونا (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="زامانىۋى (WGC)" WindowCapture.Priority="ئېكران ماسلىشىش ئالدىنلىقى" WindowCapture.Priority.Title="ئېكران ماۋزۇسى چوقۇم ماسلىشىدۇ" WindowCapture.Priority.Class="ماۋزۇ ماسلىشىدۇ، بولمىسا ئوخشىشىپ كېتىدىغان كۆزنەكنى ئىزدەيدۇ" @@ -19,8 +19,8 @@ Monitor="كۆرسەتكۈچ" PrimaryMonitor="ئاساسىي ئېكران" Method="ئېكران تۇتۇش ئۇسۇلى" -Method.DXGI="DXGI ئۈستەلئۈستى كۆچۈرۈش" -Method.WindowsGraphicsCapture="Windows 10 (1903 ۋە تېخىمۇ يۇقىرى نەشرى)" +Method.DXGI="كونا (DXGI)" +Method.WindowsGraphicsCapture="زامانىۋى (WGC)" GameCapture="ئويۇن ئېكرانى تۇت" GameCapture.AnyFullscreen="خالىغان پۈتۈن ئېكران پىروگراممىسىدىن ئېكران تۇتىدۇ" GameCapture.CaptureWindow="بەلگىلەنگەن كۆزنەكتىن ئېكران تۇتىدۇ"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/uk-UA.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/uk-UA.ini
Changed
@@ -3,8 +3,6 @@ WindowCapture.Window="Вікно" WindowCapture.Method="Метод захоплення" WindowCapture.Method.Auto="Автоматичний" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 та вище)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 і вище)" WindowCapture.Priority="Пріоритет відповідності вікна" WindowCapture.Priority.Title="Заголовок вікна має збігатись" WindowCapture.Priority.Class="Збіг заголовку, інакше знайти вікно такого ж типу" @@ -19,8 +17,6 @@ Monitor="Дисплей" PrimaryMonitor="Основний монітор" Method="Метод захоплення" -Method.DXGI="Дублювання стільниці DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 і вище)" GameCapture="Захоплення гри" GameCapture.AnyFullscreen="Захоплення будь-якого повноекранного застосунку" GameCapture.CaptureWindow="Захоплення конкретного вікна"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/vi-VN.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/vi-VN.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="Cửa sổ" WindowCapture.Method="Phương pháp chụp" WindowCapture.Method.Auto="Tự động" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 trở lên)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903 trở lên)" +WindowCapture.Method.BitBlt="Cũ (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="Hiện đại (WGC)" WindowCapture.Priority="Cửa sổ ưu tiên" WindowCapture.Priority.Title="Tiêu đề cửa sổ phải khớp" WindowCapture.Priority.Class="Khớp tiêu đề, nếu không tìm thấy các cửa sổ cùng loại" @@ -19,8 +19,8 @@ Monitor="Hiển thị" PrimaryMonitor="Màn hình chính" Method="Phương pháp chụp" -Method.DXGI="Sao chép desktop DXGI" -Method.WindowsGraphicsCapture="Windows 10 (1903 trở lên)" +Method.DXGI="Cũ (DXGI)" +Method.WindowsGraphicsCapture="Hiện đại (WGC)" GameCapture="Quay trò chơi" GameCapture.AnyFullscreen="Quay tất cả các ứng dụng toàn màn hình" GameCapture.CaptureWindow="Quay cửa sổ cụ thể"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/zh-CN.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/zh-CN.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="窗口" WindowCapture.Method="采集方式" WindowCapture.Method.Auto="自动" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 或更新版本)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10 (1903或更新版本)" +WindowCapture.Method.BitBlt="旧版 (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="新版 (WGC)" WindowCapture.Priority="窗口匹配优先级" WindowCapture.Priority.Title="窗口标题必须匹配" WindowCapture.Priority.Class="匹配标题,否则查找相同类型的窗口" @@ -19,8 +19,8 @@ Monitor="显示器" PrimaryMonitor="主显示器" Method="采集方式" -Method.DXGI="DXGI截屏" -Method.WindowsGraphicsCapture="Windows 10 (1903或更新版本)" +Method.DXGI="旧版 (DXGI)" +Method.WindowsGraphicsCapture="新版 (WGC)" GameCapture="游戏采集" GameCapture.AnyFullscreen="采集全屏应用程序" GameCapture.CaptureWindow="采集特定窗口"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/locale/zh-TW.ini -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/locale/zh-TW.ini
Changed
@@ -3,8 +3,8 @@ WindowCapture.Window="視窗" WindowCapture.Method="擷取方式" WindowCapture.Method.Auto="自動" -WindowCapture.Method.BitBlt="BitBlt (Windows 7 或更新版本)" -WindowCapture.Method.WindowsGraphicsCapture="Windows 10(1903 或更新版本)" +WindowCapture.Method.BitBlt="舊版 (BitBlt)" +WindowCapture.Method.WindowsGraphicsCapture="新版 (WGC)" WindowCapture.Priority="視窗匹配優先度" WindowCapture.Priority.Title="視窗標題必須相符" WindowCapture.Priority.Class="與標題相符,如沒有則找尋相同類型的視窗" @@ -19,8 +19,8 @@ Monitor="顯示器" PrimaryMonitor="主顯示器" Method="擷取方式" -Method.DXGI="DXGI 桌面複製" -Method.WindowsGraphicsCapture="Windows 10(1903 或更新版本)" +Method.DXGI="舊版 (DXGI)" +Method.WindowsGraphicsCapture="新版 (WGC)" GameCapture="遊戲擷取" GameCapture.AnyFullscreen="擷取任何全螢幕程式" GameCapture.CaptureWindow="擷取特定視窗"
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/data/package.json -> obs-studio-33.0.0.tar.xz/plugins/win-capture/data/package.json
Changed
@@ -1,11 +1,11 @@ { "$schema": "schema/package-schema.json", "url": "https://obsproject.com/obs2_update/win-capture/v1", - "version": 10, + "version": 11, "files": { "name": "compatibility.json", - "version": 10 + "version": 11 } }
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/duplicator-monitor-capture.c -> obs-studio-33.0.0.tar.xz/plugins/win-capture/duplicator-monitor-capture.c
Changed
@@ -802,9 +802,9 @@ obs_property_t *p = obs_properties_add_list(props, "method", TEXT_METHOD, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_list_add_int(p, TEXT_METHOD_AUTO, METHOD_AUTO); - obs_property_list_add_int(p, TEXT_METHOD_DXGI, METHOD_DXGI); obs_property_list_add_int(p, TEXT_METHOD_WGC, METHOD_WGC); - obs_property_list_item_disable(p, 2, !wgc_supported); + obs_property_list_add_int(p, TEXT_METHOD_DXGI, METHOD_DXGI); + obs_property_list_item_disable(p, 1, !wgc_supported); obs_property_set_modified_callback(p, display_capture_method_changed); obs_property_t *monitors = obs_properties_add_list(props, "monitor_id", TEXT_MONITOR, OBS_COMBO_TYPE_LIST,
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/game-capture-file-init.c -> obs-studio-33.0.0.tar.xz/plugins/win-capture/game-capture-file-init.c
Changed
@@ -179,9 +179,7 @@ wchar_t src_jsonMAX_PATH; wchar_t dst_jsonMAX_PATH; - StringCbCopyW(temp, sizeof(temp), - L"..\\..\\data\\obs-plugins\\" - L"win-capture\\"); + StringCbCopyW(temp, sizeof(temp), L"..\\..\\core\\win-capture\\data\\"); make_filename(temp, L"obs-vulkan", L".json"); if (_wfullpath(src_json, temp, MAX_PATH) == NULL) { @@ -189,9 +187,7 @@ return false; } - StringCbCopyW(temp, sizeof(temp), - L"..\\..\\data\\obs-plugins\\" - L"win-capture\\"); + StringCbCopyW(temp, sizeof(temp), L"..\\..\\core\\win-capture\\data\\"); make_filename(temp, L"graphics-hook", L".dll"); if (_wfullpath(src, temp, MAX_PATH) == NULL) {
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/game-capture.c -> obs-studio-33.0.0.tar.xz/plugins/win-capture/game-capture.c
Changed
@@ -1104,6 +1104,12 @@ } } +static int rects_nearly_equal(RECT first, RECT second, long delta) +{ + return abs(first.left - second.left) <= delta && abs(first.right - second.right) <= delta && + abs(first.top - second.top) <= delta && abs(first.bottom - second.bottom) <= delta; +} + static void get_fullscreen_window(struct game_capture *gc) { HWND window = GetForegroundWindow(); @@ -1137,8 +1143,11 @@ return; } - if (rect.left == mi.rcMonitor.left && rect.right == mi.rcMonitor.right && rect.bottom == mi.rcMonitor.bottom && - rect.top == mi.rcMonitor.top) { + /* Some apps extend their windows 1-2 pixels beyond the monitor's supported resolution to circumvent certain + * exclusive fullscreen-related issues caused either by their graphics library, Windows itself, or both. Thus, + * we compare the window's corner coordinates with those of the monitor using an acceptable relative margin of + * 2, allowing it to extend slightly past the edge of the monitor. */ + if (rects_nearly_equal(rect, mi.rcMonitor, 2)) { setup_window(gc, window); } else { gc->wait_for_target_startup = true;
View file
obs-studio-32.2.2.tar.xz/plugins/win-capture/window-capture.c -> obs-studio-33.0.0.tar.xz/plugins/win-capture/window-capture.c
Changed
@@ -121,17 +121,19 @@ "Windows.UI.Core.CoreWindow", "WinUIDesktopWin32WindowClass", "GAMINGSERVICESUI_HOSTING_WINDOW_CLASS", - "XLMAIN", /* Microsoft Excel */ - "PPTFrameClass", /* Microsoft PowerPoint */ - "screenClass", /* Microsoft PowerPoint (Slide Show) */ - "PodiumParent", /* Microsoft PowerPoint (Presenter View) */ - "OpusApp", /* Microsoft Word */ - "OMain", /* Microsoft Access */ - "Framework::CFrame", /* Microsoft OneNote */ - "rctrl_renwnd32", /* Microsoft Outlook */ - "MSWinPub", /* Microsoft Publisher */ - "OfficeApp-Frame", /* Microsoft 365 Software */ + "XLMAIN", /* Microsoft Excel */ + "PPTFrameClass", /* Microsoft PowerPoint */ + "screenClass", /* Microsoft PowerPoint (Slide Show) */ + "PodiumParent", /* Microsoft PowerPoint (Presenter View) */ + "OpusApp", /* Microsoft Word */ + "OMain", /* Microsoft Access */ + "Framework::CFrame", /* Microsoft OneNote */ + "rctrl_renwnd32", /* Microsoft Outlook */ + "MSWinPub", /* Microsoft Publisher */ + "OfficeApp-Frame", /* Microsoft 365 Software */ + "WindowsWebview2Wrapper", /* Construct 3 Games */ "SDL_app", + "WINDOWSCLIENT", /* Roblox */ NULL, }; @@ -535,9 +537,9 @@ p = obs_properties_add_list(ppts, "method", TEXT_METHOD, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_list_add_int(p, TEXT_METHOD_AUTO, METHOD_AUTO); - obs_property_list_add_int(p, TEXT_METHOD_BITBLT, METHOD_BITBLT); obs_property_list_add_int(p, TEXT_METHOD_WGC, METHOD_WGC); - obs_property_list_item_disable(p, 2, !wgc_supported); + obs_property_list_add_int(p, TEXT_METHOD_BITBLT, METHOD_BITBLT); + obs_property_list_item_disable(p, 1, !wgc_supported); obs_property_set_modified_callback(p, wc_capture_method_changed); p = obs_properties_add_list(ppts, "priority", TEXT_MATCH_PRIORITY, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
View file
obs-studio-32.2.2.tar.xz/plugins/win-dshow/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/win-dshow/CMakeLists.txt
Changed
@@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.28...3.30) -find_package(FFmpeg REQUIRED avcodec avutil) +find_package(FFmpeg 8.0 REQUIRED avcodec avutil) add_library(win-dshow MODULE) add_library(OBS::dshow ALIAS win-dshow)
View file
obs-studio-32.2.2.tar.xz/plugins/win-dshow/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/win-dshow/data/locale/kaa.ini
Changed
@@ -1,28 +1,24 @@ -Device="Qurılma" -ColorSpace="Reń maydanı" -ColorSpace.Default="Aldınnan ornatılǵan" -ColorRange="Reń aralıǵı" -ColorRange.Default="Aldınnan ornatılǵan" -ColorRange.Partial="Sheklengen" -ColorRange.Full="Tolıq" -ConfigureVideo="Videonı sazlaw" -ResFPSType="Ólshem / kadrlar tezliginiń túri" -ResFPSType.Custom="Arnawlı" -Resolution="Kólem" -VideoFormat="Video format" -VideoFormat.Any="Qálegen" -VideoFormat.Unknown="Belgisiz (%1)" -AudioOutputMode="Dawıstı shıǵarıw rejimi" -AudioOutputMode.Capture="Tek dawıstı qamtıw" -AudioOutputMode.DirectSound="Sistema dawısın shıǵarıw (DirectSound)" -AudioOutputMode.WaveOut="Sistema dawısın shıǵarıw (WaveOut)" -UseCustomAudioDevice="Arnawlı audio qurılmanı qollanıw" -AudioDevice="Audio qurılma" -Buffering.AutoDetect="Avtomat tárizde anıqlaw" -Buffering.Enable="Qosıw" -Buffering.Disable="Óshiriw" -Activate="Aktivlestiriw" -Deactivate="Óshiriw" -Bitrate="Bit tezligi" -Encoder.C985="AVerMedia H.264 (c985) kodlawshısı" -Encoder.C353="AVerMedia H.264 kodlawshısı" +Device="Қурылма" +ColorSpace="Рең майданы" +ColorSpace.Default="Әдепки" +ColorRange="Рең аралығы" +ColorRange.Default="Әдепки" +ColorRange.Partial="Шекленген" +ColorRange.Full="Толық" +ConfigureVideo="Видеоны сазлаў" +ConfigureCrossbar="Кроссбар сазлаўы" +ResFPSType.Custom="Арнаўлы" +FPS.Highest="Ең жоқары FPS" +VideoFormat="Видео форматы" +VideoFormat.Any="Қәлеген" +VideoFormat.Unknown="Белгисиз (%1)" +AudioDevice="Аудио қурылма" +Buffering="Буферизация" +Buffering.AutoDetect="Авто-анықлаў" +Buffering.Enable="Қосыў" +Buffering.Disable="Өшириў" +Activate="Иске түсириў" +Deactivate="Өшириў" +Bitrate="Битрейт" +Encoder.C985="AVerMedia H.264 (c985) кодлаўшысы" +Encoder.C353="AVerMedia H.264 кодлаўшысы"
View file
obs-studio-32.2.2.tar.xz/plugins/win-dshow/data/locale/tr-TR.ini -> obs-studio-33.0.0.tar.xz/plugins/win-dshow/data/locale/tr-TR.ini
Changed
@@ -11,14 +11,14 @@ ResFPSType="Çözünürlük/FPS Türü" ResFPSType.Custom="Özel" ResFPSType.DevPreferred="Aygıt Varsayılanı" -FPS.Matching="Çıkış FPS'ini Eşleştir" +FPS.Matching="Çıktı FPS'sini Eşleştir" FPS.Highest="En Yüksek FPS" Resolution="Çözünürlük" VideoFormat="Video Formatı" VideoFormat.Any="Herhangi" VideoFormat.Unknown="Bilinmiyor (%1)" -AudioOutputMode="Ses Çıkış Modu" -AudioOutputMode.Capture="Sadece ses yakalama" +AudioOutputMode="Ses Çıkış Kipi" +AudioOutputMode.Capture="Yalnızca ses yakalama" AudioOutputMode.DirectSound="Masaüstü ses çıkışı (DirectSound)" AudioOutputMode.WaveOut="Masaüstü ses çıkışı (WaveOut)" UseCustomAudioDevice="Özel ses aygıtını kullan"
View file
obs-studio-32.2.2.tar.xz/plugins/win-dshow/virtualcam-module/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/plugins/win-dshow/virtualcam-module/CMakeLists.txt
Changed
@@ -138,12 +138,12 @@ configure_file(virtualcam-install.bat.in virtualcam-install.bat) target_add_resource(obs-virtualcam-module "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-install.bat" - "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow" + "${OBS_PLUGIN_DESTINATION}/win-dshow/data" ) configure_file(virtualcam-uninstall.bat.in virtualcam-uninstall.bat) target_add_resource(obs-virtualcam-module "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-uninstall.bat" - "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow" + "${OBS_PLUGIN_DESTINATION}/win-dshow/data" ) set_target_properties_obs(
View file
obs-studio-32.2.2.tar.xz/plugins/win-dshow/virtualcam-module/virtualcam-install.bat.in -> obs-studio-33.0.0.tar.xz/plugins/win-dshow/virtualcam-module/virtualcam-install.bat.in
Changed
@@ -11,33 +11,10 @@ goto end ) -:checkDLL - echo Checking for 32-bit Virtual Cam registration... - reg query "HKLM\SOFTWARE\Classes\WOW6432Node\CLSID\{@VIRTUALCAM_GUID@}" >nul 2>&1 - if %errorLevel% == 0 ( - echo 32-bit Virtual Cam found, skipping install... - echo. - ) else ( - echo 32-bit Virtual Cam not found, installing... - goto install32DLL - ) - -:CheckDLLContinue - echo Checking for 64-bit Virtual Cam registration... - reg query "HKLM\SOFTWARE\Classes\CLSID\{@VIRTUALCAM_GUID@}" >nul 2>&1 - if %errorLevel% == 0 ( - echo 64-bit Virtual Cam found, skipping install... - echo. - ) else ( - echo 64-bit Virtual Cam not found, installing... - goto install64DLL - ) - goto endSuccess - :install32DLL echo Installing 32-bit Virtual Cam... - if exist "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll" ( - regsvr32.exe /i /s "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll" + if exist "%~dp0\core\win-dshow\data\obs-virtualcam-module32.dll" ( + regsvr32.exe /i /s "%~dp0\core\win-dshow\data\obs-virtualcam-module32.dll" ) else ( regsvr32.exe /i /s obs-virtualcam-module32.dll ) @@ -50,12 +27,11 @@ echo. goto end ) - goto checkDLLContinue :install64DLL echo Installing 64-bit Virtual Cam... - if exist "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll" ( - regsvr32.exe /i /s "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll" + if exist "%~dp0\core\win-dshow\data\obs-virtualcam-module64.dll" ( + regsvr32.exe /i /s "%~dp0\core\win-dshow\data\obs-virtualcam-module64.dll" ) else ( regsvr32.exe /i /s obs-virtualcam-module64.dll )
View file
obs-studio-32.2.2.tar.xz/plugins/win-dshow/virtualcam-module/virtualcam-uninstall.bat.in -> obs-studio-33.0.0.tar.xz/plugins/win-dshow/virtualcam-module/virtualcam-uninstall.bat.in
Changed
@@ -12,13 +12,13 @@ ) :uninstallDLLs - if exist "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll" ( - regsvr32.exe /u /s "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll" + if exist "%~dp0\core\win-dshow\data\obs-virtualcam-module32.dll" ( + regsvr32.exe /u /s "%~dp0\core\win-dshow\data\obs-virtualcam-module32.dll" ) else ( regsvr32.exe /u /s obs-virtualcam-module32.dll ) - if exist "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll" ( - regsvr32.exe /u /s "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll" + if exist "%~dp0\core\win-dshow\data\obs-virtualcam-module64.dll" ( + regsvr32.exe /u /s "%~dp0\core\win-dshow\data\obs-virtualcam-module64.dll" ) else ( regsvr32.exe /u /s obs-virtualcam-module64.dll )
View file
obs-studio-32.2.2.tar.xz/plugins/win-wasapi/data/locale/kaa.ini -> obs-studio-33.0.0.tar.xz/plugins/win-wasapi/data/locale/kaa.ini
Changed
@@ -1,3 +1,3 @@ -Device="Qurılma" -Default="Aldınnan ornatılǵan" -Window="Ayna" +Device="Қурылма" +Default="Әдепки" +Window="Айна"
View file
obs-studio-33.0.0.tar.xz/plugins/win-wasapi/data/locale/uz-UZ.ini
Added
@@ -0,0 +1,1 @@ +Device="Qurilma"
View file
obs-studio-32.2.2.tar.xz/shared/media-playback/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/shared/media-playback/CMakeLists.txt
Changed
@@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.28...3.30) -find_package(FFmpeg REQUIRED avcodec avdevice avutil avformat) +find_package(FFmpeg 8.0 REQUIRED avcodec avdevice avutil avformat) add_library(media-playback INTERFACE) add_library(OBS::media-playback ALIAS media-playback)
View file
obs-studio-32.2.2.tar.xz/shared/properties-view/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/shared/properties-view/CMakeLists.txt
Changed
@@ -28,6 +28,10 @@ add_subdirectory("${CMAKE_SOURCE_DIR}/shared/qt/icon-label" "${CMAKE_BINARY_DIR}/shared/qt/icon-label") endif() +if(NOT TARGET OBS::qt-obs-spinbox) + add_subdirectory("${CMAKE_SOURCE_DIR}/shared/qt/obs-spinbox" "${CMAKE_BINARY_DIR}/shared/qt/obs-spinbox") +endif() + add_library(properties-view INTERFACE) add_library(OBS::properties-view ALIAS properties-view) @@ -51,6 +55,7 @@ OBS::libobs OBS::qt-wrappers OBS::qt-plain-text-edit + OBS::qt-obs-spinbox OBS::qt-vertical-scroll-area OBS::qt-slider-ignorewheel OBS::qt-icon-label
View file
obs-studio-32.2.2.tar.xz/shared/properties-view/properties-view.cpp -> obs-studio-33.0.0.tar.xz/shared/properties-view/properties-view.cpp
Changed
@@ -25,6 +25,9 @@ #include <QObject> #include <QDesktopServices> #include <QUuid> + +#include "DoubleSpinBox.hpp" +#include "SpinBox.hpp" #include "double-slider.hpp" #include "spinbox-ignorewheel.hpp" #include "moc_properties-view.cpp" @@ -206,7 +209,7 @@ minSize(minSize_) { setFrameShape(QFrame::NoFrame); - QMetaObject::invokeMethod(this, "ReloadProperties", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSPropertiesView::ReloadProperties, Qt::QueuedConnection); } OBSPropertiesView::OBSPropertiesView(OBSData settings_, void *obj, PropertiesReloadCallback reloadCallback, @@ -221,7 +224,7 @@ minSize(minSize_) { setFrameShape(QFrame::NoFrame); - QMetaObject::invokeMethod(this, "ReloadProperties", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSPropertiesView::ReloadProperties, Qt::QueuedConnection); } OBSPropertiesView::OBSPropertiesView(OBSData settings_, const char *type_, PropertiesReloadCallback reloadCallback_, @@ -233,7 +236,7 @@ minSize(minSize_) { setFrameShape(QFrame::NoFrame); - QMetaObject::invokeMethod(this, "ReloadProperties", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &OBSPropertiesView::ReloadProperties, Qt::QueuedConnection); } void OBSPropertiesView::SetDisabled(bool disabled) @@ -272,11 +275,7 @@ QCheckBox *checkbox = new QCheckBox(QT_UTF8(desc)); checkbox->setCheckState(val ? Qt::Checked : Qt::Unchecked); -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) QWidget *widget = NewWidget(prop, checkbox, &QCheckBox::checkStateChanged); -#else - QWidget *widget = NewWidget(prop, checkbox, &QCheckBox::stateChanged); -#endif if (!long_desc) { return widget; @@ -434,7 +433,7 @@ const char *name = obs_property_name(prop); int val = (int)obs_data_get_int(settings, name); - QSpinBox *spin = new SpinBoxIgnoreScroll(); + OBS::SpinBox *spin = new OBS::SpinBox(); spin->setEnabled(obs_property_enabled(prop)); @@ -482,7 +481,7 @@ const char *name = obs_property_name(prop); double val = obs_data_get_double(settings, name); - QDoubleSpinBox *spin = new QDoubleSpinBox(); + OBS::DoubleSpinBox *spin = new OBS::DoubleSpinBox(); if (!obs_property_enabled(prop)) { spin->setEnabled(false); @@ -517,8 +516,8 @@ slider->setOrientation(Qt::Horizontal); subLayout->addWidget(slider); - connect(slider, &DoubleSlider::doubleValChanged, spin, &QDoubleSpinBox::setValue); - connect(spin, &QDoubleSpinBox::valueChanged, slider, &DoubleSlider::setDoubleVal); + connect(slider, &DoubleSlider::doubleValChanged, spin, &OBS::DoubleSpinBox::setValue); + connect(spin, &OBS::DoubleSpinBox::valueChanged, slider, &DoubleSlider::setDoubleVal); } connect(spin, &QDoubleSpinBox::valueChanged, info, &WidgetInfo::ControlChanged); @@ -1438,8 +1437,7 @@ stack->setToolTip(QT_UTF8(obs_property_long_description(prop))); combo->setToolTip(QT_UTF8(obs_property_long_description(prop))); - auto comboIndexChanged = static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged); - connect(combo, comboIndexChanged, stack, =(int index) { + connect(combo, &QComboBox::currentIndexChanged, stack, =(int index) { bool out_of_bounds = index >= stack->count(); auto idx = out_of_bounds ? stack->count() - 1 : index; stack->setCurrentIndex(idx); @@ -1452,7 +1450,7 @@ emit info->ControlChanged(); }); - connect(widget->simpleFPS, comboIndexChanged, info, =(int) { + connect(widget->simpleFPS, &QComboBox::currentIndexChanged, info, =(int) { if (widget->updating) { return; } @@ -1460,7 +1458,7 @@ emit info->ControlChanged(); }); - connect(widget->fpsRange, comboIndexChanged, info, =(int) { + connect(widget->fpsRange, &QComboBox::currentIndexChanged, info, =(int) { if (widget->updating) { return; } @@ -1468,8 +1466,7 @@ UpdateFPSLabels(widget); }); - auto sbValueChanged = static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged); - connect(widget->numEdit, sbValueChanged, info, =(int) { + connect(widget->numEdit, &QSpinBox::valueChanged, info, =(int) { if (widget->updating) { return; } @@ -1477,7 +1474,7 @@ emit info->ControlChanged(); }); - connect(widget->denEdit, sbValueChanged, info, =(int) { + connect(widget->denEdit, &QSpinBox::valueChanged, info, =(int) { if (widget->updating) { return; } @@ -2028,7 +2025,7 @@ OBSObject strongObj = view->GetObject(); void *obj = strongObj ? strongObj.Get() : view->rawObj; if (obs_property_button_clicked(property, obj)) { - QMetaObject::invokeMethod(view, "RefreshProperties", Qt::QueuedConnection); + QMetaObject::invokeMethod(view, &OBSPropertiesView::RefreshProperties, Qt::QueuedConnection); } } @@ -2136,7 +2133,7 @@ if (obs_property_modified(property, view->settings)) { view->lastFocused = setting; - QMetaObject::invokeMethod(view, "RefreshProperties", Qt::QueuedConnection); + QMetaObject::invokeMethod(view, &OBSPropertiesView::RefreshProperties, Qt::QueuedConnection); } }
View file
obs-studio-32.2.2.tar.xz/shared/properties-view/properties-view.hpp -> obs-studio-33.0.0.tar.xz/shared/properties-view/properties-view.hpp
Changed
@@ -59,7 +59,7 @@ { if (update_timer) { update_timer->stop(); - QMetaObject::invokeMethod(update_timer, "timeout"); + QMetaObject::invokeMethod(update_timer, &QTimer::stop); update_timer->deleteLater(); } }
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/CMakeLists.txt -> obs-studio-33.0.0.tar.xz/shared/qt/idian/CMakeLists.txt
Changed
@@ -10,25 +10,33 @@ PRIVATE components/CheckBox.cpp components/ComboBox.cpp - components/DoubleSpinBox.cpp - components/SpinBox.cpp + components/ExpandButton.cpp + components/InlineButton.cpp + components/RowDoubleSpinBox.cpp + components/RowInfo.cpp + components/RowSpinBox.cpp components/ToggleSwitch.cpp include/Idian/CheckBox.hpp + include/Idian/CollapsibleGroup.hpp include/Idian/ComboBox.hpp - include/Idian/DoubleSpinBox.hpp - include/Idian/Group.hpp + include/Idian/ExpandButton.hpp include/Idian/Idian.hpp - include/Idian/PropertiesList.hpp + include/Idian/InlineButton.hpp + include/Idian/ListHeader.hpp include/Idian/Row.hpp - include/Idian/SpinBox.hpp + include/Idian/RowDoubleSpinBox.hpp + include/Idian/RowInfo.hpp + include/Idian/RowList.hpp + include/Idian/RowSpinBox.hpp include/Idian/StateEventFilter.cpp include/Idian/StateEventFilter.hpp include/Idian/ToggleSwitch.hpp include/Idian/Utils.cpp include/Idian/Utils.hpp - widgets/Group.cpp - widgets/PropertiesList.cpp + widgets/CollapsibleGroup.cpp + widgets/ListHeader.cpp widgets/Row.cpp + widgets/RowList.cpp ) target_sources(idian PUBLIC include/Idian/Idian.hpp)
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/components/CheckBox.cpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/components/CheckBox.cpp
Changed
@@ -21,7 +21,7 @@ using idian::CheckBox; -CheckBox::CheckBox(QWidget *parent) : QCheckBox(parent), Utils(this) +CheckBox::CheckBox(QWidget *parent) : QCheckBox(parent) { Utils::applyStateStylingEventFilter(this); }
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/components/ComboBox.cpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/components/ComboBox.cpp
Changed
@@ -25,7 +25,7 @@ using idian::ComboBox; -ComboBox::ComboBox(QWidget *parent) : QComboBox(parent), Utils(this) +ComboBox::ComboBox(QWidget *parent) : QComboBox(parent) { Utils::applyStateStylingEventFilter(this); }
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/components/ExpandButton.cpp
Added
@@ -0,0 +1,30 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <Idian/ExpandButton.hpp> + +#include <QPainter> +#include <QStyleOptionButton> + +namespace idian { +ExpandButton::ExpandButton(QWidget *parent) : InlineButton(parent) +{ + Utils::applyStateStylingEventFilter(this); + + setCheckable(true); +} +} // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/components/InlineButton.cpp
Added
@@ -0,0 +1,25 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <Idian/InlineButton.hpp> + +namespace idian { +InlineButton::InlineButton(QWidget *parent) : QPushButton(parent) +{ + Utils::applyStateStylingEventFilter(this); +} +} // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/components/RowDoubleSpinBox.cpp
Added
@@ -0,0 +1,49 @@ +/****************************************************************************** + Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <Idian/RowDoubleSpinBox.hpp> + +#include <Idian/moc_RowDoubleSpinBox.cpp> + +using idian::RowDoubleSpinBox; + +RowDoubleSpinBox::RowDoubleSpinBox(QWidget *parent) : QFrame(parent) +{ + layout = new QHBoxLayout(); + setLayout(layout); + + layout->setContentsMargins(0, 0, 0, 0); + + decr = new QPushButton("-"); + decr->setObjectName("obsSpinBoxButton"); + layout->addWidget(decr); + + setFocusProxy(decr); + + sbox = new QDoubleSpinBox(); + sbox->setObjectName("obsSpinBox"); + sbox->setButtonSymbols(QAbstractSpinBox::NoButtons); + sbox->setAlignment(Qt::AlignCenter); + layout->addWidget(sbox); + + incr = new QPushButton("+"); + incr->setObjectName("obsSpinBoxButton"); + layout->addWidget(incr); + + connect(decr, &QPushButton::pressed, sbox, &QDoubleSpinBox::stepDown); + connect(incr, &QPushButton::pressed, sbox, &QDoubleSpinBox::stepUp); +}
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/components/RowInfo.cpp
Added
@@ -0,0 +1,91 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <Idian/RowInfo.hpp> +#include <Idian/Utils.hpp> + +#include <QLabel> +#include <QVBoxLayout> + +namespace idian { +RowInfo::RowInfo(QWidget *parent) : QWidget(parent) +{ + layout_ = new QVBoxLayout(); + layout_->setSpacing(0); + layout_->setContentsMargins(0, 0, 0, 0); + + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + + setLayout(layout_); + + nameLabel = new QLabel(); + nameLabel->setVisible(false); + Utils::addClass(nameLabel, "title"); + + descriptionLabel = new QLabel(); + descriptionLabel->setVisible(false); + Utils::addClass(descriptionLabel, "description"); + + layout_->addWidget(nameLabel); + layout_->addWidget(descriptionLabel); +} + +RowInfo::RowInfo(QWidget *parent, QString title) : RowInfo(parent) +{ + setTitle(title); +} + +RowInfo::RowInfo(QWidget *parent, QString title, QString description) : RowInfo(parent) +{ + setTitle(title); + setDescription(description); +} + +void RowInfo::setTitle(const QString &name) +{ + if (name.isEmpty()) { + showTitle(false); + return; + } + + nameLabel->setText(name); + setAccessibleName(name); + showTitle(true); +} + +void RowInfo::setDescription(const QString &description) +{ + if (description.isEmpty()) { + showDescription(false); + return; + } + + descriptionLabel->setText(description); + setAccessibleDescription(description); + showDescription(true); +} + +void RowInfo::showTitle(bool visible) +{ + nameLabel->setVisible(visible); +} + +void RowInfo::showDescription(bool visible) +{ + descriptionLabel->setVisible(visible); +} +} // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/components/RowSpinBox.cpp
Added
@@ -0,0 +1,46 @@ +/****************************************************************************** + Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <Idian/RowSpinBox.hpp> + +#include <Idian/moc_RowSpinBox.cpp> + +using idian::RowSpinBox; + +RowSpinBox::RowSpinBox(QWidget *parent) : QFrame(parent) +{ + layout = new QHBoxLayout(); + setLayout(layout); + + layout->setContentsMargins(0, 0, 0, 0); + + decr = new QPushButton("-"); + decr->setObjectName("obsSpinBoxButton"); + layout->addWidget(decr); + + sbox = new QSpinBox(); + sbox->setObjectName("obsSpinBox"); + sbox->setButtonSymbols(QAbstractSpinBox::NoButtons); + layout->addWidget(sbox); + + incr = new QPushButton("+"); + incr->setObjectName("obsSpinBoxButton"); + layout->addWidget(incr); + + connect(decr, &QPushButton::pressed, sbox, &QSpinBox::stepDown); + connect(incr, &QPushButton::pressed, sbox, &QSpinBox::stepUp); +}
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/components/ToggleSwitch.cpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/components/ToggleSwitch.cpp
Changed
@@ -35,8 +35,7 @@ ToggleSwitch::ToggleSwitch(QWidget *parent) : QAbstractButton(parent), animHandle(new QPropertyAnimation(this, "xpos", this)), - animBgColor(new QPropertyAnimation(this, "blend", this)), - Utils(this) + animBgColor(new QPropertyAnimation(this, "blend", this)) { Utils::applyStateStylingEventFilter(this); @@ -50,6 +49,8 @@ installEventFilter(this); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + connect(this, &ToggleSwitch::clicked, this, &ToggleSwitch::onClicked); connect(animHandle, &QVariantAnimation::valueChanged, this, &ToggleSwitch::updateBackgroundColor); @@ -102,7 +103,7 @@ void ToggleSwitch::changeEvent(QEvent *event) { if (event->type() == QEvent::EnabledChange) { - Utils::toggleClass("disabled", !isEnabled()); + Utils::toggleClass(this, "disabled", !isEnabled()); updateBackgroundColor(); } }
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/CheckBox.hpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/CheckBox.hpp
Changed
@@ -23,7 +23,7 @@ namespace idian { -class CheckBox : public QCheckBox, public Utils { +class CheckBox : public QCheckBox { Q_OBJECT; public:
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/CollapsibleGroup.hpp
Added
@@ -0,0 +1,65 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <QFrame> + +class QPixmap; +class QVBoxLayout; + +namespace idian { +class Row; +class RowInfo; +class ExpandButton; +class RowList; +class ToggleSwitch; + +class CollapsibleGroup : public QFrame { + Q_OBJECT + +public: + CollapsibleGroup(QWidget *parent = nullptr); + + void setCheckable(bool check); + bool isCheckable() { return checkable; } + + void setChecked(bool checked); + bool isChecked(); + + void setExpanded(bool expand = true); + + Row *row() { return rowWidget; } + RowList *list() { return propertyList; } + +protected: + void toggleVisibility(); + + QVBoxLayout *mainLayout; + + Row *rowWidget; + ExpandButton *expandButton; + + RowList *propertyList; + + ToggleSwitch *toggleSwitch = nullptr; + bool checkable = false; + +signals: + void toggled(bool checked); +}; +} // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/ComboBox.hpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/ComboBox.hpp
Changed
@@ -24,7 +24,7 @@ namespace idian { -class ComboBox : public QComboBox, public Utils { +class ComboBox : public QComboBox { Q_OBJECT public:
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/ExpandButton.hpp
Added
@@ -0,0 +1,34 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <Idian/InlineButton.hpp> + +#include <QAbstractButton> + +class QPixmap; + +namespace idian { + +class ExpandButton : public InlineButton { + Q_OBJECT + +public: + explicit ExpandButton(QWidget *parent = nullptr); +}; +} // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/Idian.hpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/Idian.hpp
Changed
@@ -23,9 +23,8 @@ #include <Idian/CheckBox.hpp> #include <Idian/ComboBox.hpp> -#include <Idian/DoubleSpinBox.hpp> -#include <Idian/Group.hpp> -#include <Idian/PropertiesList.hpp> #include <Idian/Row.hpp> -#include <Idian/SpinBox.hpp> +#include <Idian/RowDoubleSpinBox.hpp> +#include <Idian/RowList.hpp> +#include <Idian/RowSpinBox.hpp> #include <Idian/ToggleSwitch.hpp>
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/InlineButton.hpp
Added
@@ -0,0 +1,35 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <Idian/Utils.hpp> + +#include <QPushButton> + +class QPixmap; + +namespace idian { +class Utils; + +class InlineButton : public QPushButton { + Q_OBJECT + +public: + explicit InlineButton(QWidget *parent = nullptr); +}; +} // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/ListHeader.hpp
Added
@@ -0,0 +1,59 @@ +/****************************************************************************** + Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <Idian/RowList.hpp> +#include <Idian/ToggleSwitch.hpp> + +#include <QLabel> +#include <QLayout> +#include <QMouseEvent> +#include <QWidget> + +namespace idian { + +class ListHeader : public QFrame { + Q_OBJECT + +public: + ListHeader(QWidget *parent = nullptr); + ListHeader(QWidget *parent, QString title); + ListHeader(QWidget *parent, QString title, QString description); + + void setTitle(QString name); + void setDescription(QString desc); + + void showTitle(bool visible); + void showDescription(bool visible); + + void setCheckable(bool check); + bool isCheckable() { return checkable; } + +private: + QHBoxLayout *layout_ = nullptr; + + QLabel *nameLabel = nullptr; + QLabel *descriptionLabel = nullptr; + + ToggleSwitch *toggleSwitch = nullptr; + bool checkable = false; + +signals: + void toggled(bool enable); +}; +} // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/Row.hpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/Row.hpp
Changed
@@ -17,10 +17,7 @@ #pragma once -#include <Idian/ComboBox.hpp> -#include <Idian/DoubleSpinBox.hpp> -#include <Idian/PropertiesList.hpp> -#include <Idian/SpinBox.hpp> +#include <Idian/RowInfo.hpp> #include <Idian/ToggleSwitch.hpp> #include <Idian/Utils.hpp> @@ -33,53 +30,38 @@ #include <QWidget> namespace idian { - -// Base class mostly so adding stuff to a list is easier -class GenericRow : public QFrame, public Utils { - Q_OBJECT - -public: - GenericRow(QWidget *parent = nullptr) : QFrame(parent), Utils(this) - { - setAttribute(Qt::WA_Hover, true); - - applyStateStylingEventFilter(this); - setAccessibleName(""); - }; - - virtual void setTitle(const QString &title) = 0; - virtual void setDescription(const QString &description) = 0; -}; +class ExpandButton; +class RowList; +class RowInfo; // Row widget containing one or more controls -class Row : public GenericRow { +class Row : public QFrame { Q_OBJECT public: Row(QWidget *parent = nullptr); - void setPrefix(QWidget *w, bool autoConnect = true); - void setSuffix(QWidget *w, bool autoConnect = true); - - bool hasPrefix() { return prefix_; } - bool hasSuffix() { return suffix_; } - - QWidget *prefix() const { return prefix_; } - QWidget *suffix() const { return suffix_; } - - void setPrefixEnabled(bool enabled); - void setSuffixEnabled(bool enabled); + void setChangeCursor(bool change); - virtual void setTitle(const QString &title) override; - virtual void setDescription(const QString &description) override; + QHBoxLayout *layout() { return rowLayout; } - void showTitle(bool visible); - void showDescription(bool visible); + // Convenience function to add a widget to the row's layout. + void addWidget(QWidget *widget) { layout()->addWidget(widget); } + // Convenience function to add a widget to the row's layout and then set it as the buddy. + void addBuddy(QWidget *widget) + { + layout()->addWidget(widget); + setBuddy(widget); + } + + // Sets this widget as the buddy of the Row. + // The idian StateEventFilter on Row means certain style-able classes are applied to it based on interaction + // events. The buddy widget will be repolished when these events happen. This allows the buddy widget to be + // styled differently based on the state of the row. For certain widgets, a slot will also be triggered + // on the buddy widget. void setBuddy(QWidget *w); - void setChangeCursor(bool change); - signals: void clicked(); @@ -88,96 +70,13 @@ void leaveEvent(QEvent *) override; void mouseReleaseEvent(QMouseEvent *) override; void keyReleaseEvent(QKeyEvent *) override; - bool hasDescription() const { return descriptionLabel != nullptr; } private: - QGridLayout *layout; - - QVBoxLayout *labelLayout = nullptr; - - QLabel *nameLabel = nullptr; - QLabel *descriptionLabel = nullptr; - - QWidget *prefix_ = nullptr; - QWidget *suffix_ = nullptr; + QHBoxLayout *rowLayout; QWidget *buddyWidget = nullptr; void connectBuddyWidget(QWidget *widget); bool changeCursor = false; }; - -// Collapsible row expand button -class ExpandButton : public QAbstractButton, public Utils { - Q_OBJECT - -private: - QPixmap extendDown; - QPixmap extendUp; - - friend class CollapsibleRow; - -protected: - explicit ExpandButton(QWidget *parent = nullptr); - - void paintEvent(QPaintEvent *) override; -}; - -class RowFrame : protected QFrame, protected Utils { - Q_OBJECT - -signals: - void clicked(); - -protected: - explicit RowFrame(QWidget *parent = nullptr); - - void enterEvent(QEnterEvent *) override; - void leaveEvent(QEvent *) override; - -private: - friend class CollapsibleRow; -}; - -// Collapsible Generic OBS property container -class CollapsibleRow : public GenericRow { - Q_OBJECT - -public: - CollapsibleRow(QWidget *parent = nullptr); - - void setCheckable(bool check); - bool isCheckable() { return checkable; } - - void setChecked(bool checked); - bool isChecked() { return toggleSwitch->isChecked(); }; - - virtual void setTitle(const QString &title) override; - virtual void setDescription(const QString &description) override; - - void addRow(GenericRow *actionRow); - -signals: - void toggled(bool checked); - -private: - void toggleVisibility(); - - QPixmap extendDown; - QPixmap extendUp; - - QVBoxLayout *layout; - RowFrame *rowWidget; - QHBoxLayout *rowLayout; - - Row *actionRow; - QFrame *expandFrame; - QHBoxLayout *btnLayout; - ExpandButton *expandButton; - PropertiesList *propertyList; - - ToggleSwitch *toggleSwitch = nullptr; - bool checkable = false; -}; - } // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/RowDoubleSpinBox.hpp
Added
@@ -0,0 +1,42 @@ +/****************************************************************************** + Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <QFrame> +#include <QLayout> +#include <QPushButton> +#include <QSpinBox> + +namespace idian { + +class RowDoubleSpinBox : public QFrame { + Q_OBJECT; + +public: + RowDoubleSpinBox(QWidget *parent = nullptr); + + QDoubleSpinBox *spinBox() const { return sbox; } + +private: + QHBoxLayout *layout; + QPushButton *decr; + QPushButton *incr; + QDoubleSpinBox *sbox; +}; + +} // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/RowInfo.hpp
Added
@@ -0,0 +1,51 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <QWidget> + +class QLabel; +class QVBoxLayout; + +namespace idian { + +class RowInfo : public QWidget { + Q_OBJECT + +public: + RowInfo(QWidget *parent); + RowInfo(QWidget *parent, QString title); + RowInfo(QWidget *parent, QString title, QString description); + ~RowInfo() = default; + + void setTitle(const QString &title); + void setDescription(const QString &description); + + void showTitle(bool visible); + void showDescription(bool visible); + + QLabel *title() { return nameLabel; } + QLabel *description() { return descriptionLabel; } + +private: + QVBoxLayout *layout_ = nullptr; + + QLabel *nameLabel = nullptr; + QLabel *descriptionLabel = nullptr; +}; +} // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/RowList.hpp
Added
@@ -0,0 +1,57 @@ +/****************************************************************************** + Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <Idian/Row.hpp> +#include <Idian/Utils.hpp> + +#include <QFrame> +#include <QLayout> +#include <QWidget> + +namespace idian { +class RowList : public QFrame { + Q_OBJECT + +public: + RowList(QWidget *parent = nullptr); + + void addHeader(QWidget *widget); + void addRow(QWidget *row); + void clear(); + + int count() const; + +private: + QWidget *first = nullptr; + QWidget *last = nullptr; + + QVBoxLayout *layout; + QVBoxLayout *rowLayout; +}; + +// Spacer with only cosmetic functionality +class RowListSpacer : public QFrame { + Q_OBJECT +public: + RowListSpacer(QWidget *parent = nullptr) : QFrame(parent) + { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + } +}; +} // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/RowSpinBox.hpp
Added
@@ -0,0 +1,42 @@ +/****************************************************************************** + Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <QFrame> +#include <QLayout> +#include <QPushButton> +#include <QSpinBox> + +namespace idian { + +class RowSpinBox : public QFrame { + Q_OBJECT; + +public: + RowSpinBox(QWidget *parent = nullptr); + + QSpinBox *spinBox() const { return sbox; } + +private: + QHBoxLayout *layout; + QPushButton *decr; + QPushButton *incr; + QSpinBox *sbox; +}; + +} // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/StateEventFilter.cpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/StateEventFilter.cpp
Changed
@@ -17,13 +17,13 @@ #include <Idian/StateEventFilter.hpp> #include <Idian/Utils.hpp> + #include <QAbstractButton> #include <QFocusEvent> -#include <QStyleOptionButton> -#include <QTimer> +#include <QLabel> namespace idian { -StateEventFilter::StateEventFilter(idian::Utils *utils, QWidget *target) : QObject(target), target(target), utils(utils) +StateEventFilter::StateEventFilter(QWidget *target) : QObject(target), target(target) { QAbstractButton *button = qobject_cast<QAbstractButton *>(target); if (button) { @@ -45,54 +45,54 @@ switch (event->type()) { case QEvent::StyleChange: case QEvent::ThemeChange: - utils->repolish(widget); + Utils::repolish(widget); - utils->polishChildren(widget); + Utils::polishChildren(widget); break; case QEvent::FocusIn: - utils->toggleClass(widget, "focus", true); + Utils::toggleClass(widget, "focus", true); focusEvent = static_cast<QFocusEvent *>(event); if (focusEvent->reason() != Qt::MouseFocusReason && focusEvent->reason() != Qt::PopupFocusReason) { - utils->toggleClass(widget, "keyFocus", true); + Utils::toggleClass(widget, "keyFocus", true); } else { - utils->toggleClass(widget, "keyFocus", false); + Utils::toggleClass(widget, "keyFocus", false); } - utils->polishChildren(widget); + Utils::polishChildren(widget); break; case QEvent::FocusOut: - utils->toggleClass(widget, "focus", false); + Utils::toggleClass(widget, "focus", false); focusEvent = static_cast<QFocusEvent *>(event); if (focusEvent->reason() != Qt::PopupFocusReason) { - utils->toggleClass(widget, "keyFocus", false); - utils->polishChildren(widget); + Utils::toggleClass(widget, "keyFocus", false); + Utils::polishChildren(widget); } - utils->polishChildren(widget); + Utils::polishChildren(widget); break; case QEvent::HoverEnter: if (widget->isEnabled()) { - utils->toggleClass(widget, "hover", true); + Utils::toggleClass(widget, "hover", true); } - utils->polishChildren(widget); + Utils::polishChildren(widget); break; case QEvent::HoverLeave: - utils->toggleClass(widget, "hover", false); + Utils::toggleClass(widget, "hover", false); - utils->polishChildren(widget); + Utils::polishChildren(widget); break; case QEvent::EnabledChange: - utils->toggleClass(widget, "disabled", !widget->isEnabled()); + Utils::toggleClass(widget, "disabled", !widget->isEnabled()); - utils->polishChildren(widget); + Utils::polishChildren(widget); break; default: @@ -102,7 +102,13 @@ if (updateIconColors) { // Delay icon update - QTimer::singleShot(0, this, this, widget() { utils->applyColorToIcon(widget); }); + if (QLabel *label = qobject_cast<QLabel *>(widget)) { + QMetaObject::invokeMethod( + this, this, label() { Utils::applyColorToIcon(label); }, Qt::QueuedConnection); + } else if (QAbstractButton *button = qobject_cast<QAbstractButton *>(widget)) { + QMetaObject::invokeMethod( + this, this, button() { Utils::applyColorToIcon(button); }, Qt::QueuedConnection); + } } return QObject::eventFilter(obj, event); @@ -110,7 +116,7 @@ void StateEventFilter::updateCheckedState(bool checked) { - utils->toggleClass(target, "checked", checked); + Utils::toggleClass(target, "checked", checked); } } // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/StateEventFilter.hpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/StateEventFilter.hpp
Changed
@@ -27,7 +27,7 @@ Q_OBJECT public: - explicit StateEventFilter(idian::Utils *utils, QWidget *parent); + explicit StateEventFilter(QWidget *parent); bool eventFilter(QObject *obj, QEvent *event); @@ -35,7 +35,6 @@ void updateCheckedState(bool checked); private: - Utils *utils; QWidget *target; }; } // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/ToggleSwitch.hpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/ToggleSwitch.hpp
Changed
@@ -31,7 +31,7 @@ namespace idian { -class ToggleSwitch : public QAbstractButton, public Utils { +class ToggleSwitch : public QAbstractButton { Q_OBJECT Q_PROPERTY(int xpos MEMBER xPos WRITE setPos) Q_PROPERTY(QColor background MEMBER backgroundInactive DESIGNABLE true)
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/Utils.cpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/Utils.cpp
Changed
@@ -20,13 +20,116 @@ #include <Idian/StateEventFilter.hpp> #include <QAbstractButton> +#include <QLabel> #include <QPainter> #include <QStyleOptionButton> +#include <QStyleOptionFrame> namespace idian { -void Utils::applyColorToIcon(QWidget *widget) +Q_GLOBAL_STATIC(Utils, utils); + +Utils::Utils() : QObject(nullptr) {} + +void Utils::addToPolishQueue(QWidget *widget) +{ + widgetPolishQueue.push_back(widget); + + if (isPolishPending) { + return; + } + + isPolishPending = true; + + QMetaObject::invokeMethod(this, &Utils::processPolishQueue, Qt::QueuedConnection); +} + +void Utils::processPolishQueue() +{ + widgetPolishQueue.sort(); + widgetPolishQueue.unique(); + + for (QPointer<QWidget> widget : widgetPolishQueue) { + if (widget) { + widget->style()->polish(widget); + } + } + + isPolishPending = false; + widgetPolishQueue.clear(); +} + +void Utils::polishChildren(QWidget *widget) +{ + for (QWidget *child : widget->findChildren<QWidget *>()) { + repolish(child); + } +} + +void Utils::repolish(QWidget *widget) +{ + utils->addToPolishQueue(widget); +} + +void Utils::addClass(QWidget *widget, const QString &classname) +{ + if (!classNameIsValid(classname)) { + return; + } + + QVariant current = widget->property("class"); + + QStringList classList = current.toString().split(" "); + if (classList.contains(classname)) { + return; + } + + classList.removeDuplicates(); + classList.removeAll(""); + classList.append(classname); + + QString newClasses = classList.isEmpty() ? "" : classList.join(" "); + widget->setProperty("class", newClasses); + + repolish(widget); +} + +void Utils::removeClass(QWidget *widget, const QString &classname) +{ + if (!classNameIsValid(classname)) { + return; + } + + QVariant current = widget->property("class"); + if (current.isNull()) { + return; + } + + QStringList classList = current.toString().split(" "); + if (!classList.contains(classname, Qt::CaseSensitive)) { + return; + } + + classList.removeDuplicates(); + classList.removeAll(""); + classList.removeAll(classname); + + QString newClasses = classList.isEmpty() ? "" : classList.join(" "); + widget->setProperty("class", newClasses); + + repolish(widget); +} + +void Utils::toggleClass(QWidget *widget, const QString &classname, bool toggle) +{ + if (toggle) { + addClass(widget, classname); + } else { + removeClass(widget, classname); + } +} + +void Utils::applyColorToIcon(QAbstractButton *button) { - QAbstractButton *button = qobject_cast<QAbstractButton *>(widget); if (button && !button->icon().isNull()) { // Filter is on a widget with an icon set, update its colors QStyleOptionButton opt; @@ -42,6 +145,19 @@ } } +void Utils::applyColorToIcon(QLabel *label) +{ + if (label && !label->pixmap().isNull()) { + QStyleOptionFrame opt; + opt.initFrom(label); + + QColor color = opt.palette.color(QPalette::Text); + QPixmap tinted = recolorPixmap(label->pixmap(), color); + + label->setPixmap(tinted); + } +} + QPixmap Utils::recolorPixmap(const QPixmap &src, const QColor &color) { QImage img = src.toImage(); @@ -52,8 +168,11 @@ return QPixmap::fromImage(img); } +// Updates the dynamic property 'class' on a widget with values in response to certain interaction events. +// Ex. `hover` when the widget is hovered. +// Widgets can then be styled via CSS class-style rules like .hover. void Utils::applyStateStylingEventFilter(QWidget *widget) { - widget->installEventFilter(new StateEventFilter(this, widget)); + widget->installEventFilter(new StateEventFilter(widget)); } } // namespace idian
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/include/Idian/Utils.hpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/include/Idian/Utils.hpp
Changed
@@ -17,14 +17,19 @@ #pragma once +#include <QPointer> #include <QRegularExpression> #include <QStyle> #include <QWidget> +class QAbstractButton; +class QLabel; + namespace idian { // Helpers for OBS Idian widgets -class Utils { +class Utils : public QObject { + Q_OBJECT static bool classNameIsValid(const QString &name) { @@ -34,91 +39,33 @@ } public: - QWidget *parent = nullptr; + Utils(); - Utils(QWidget *w) { parent = w; } + bool isPolishPending{false}; + std::list<QPointer<QWidget>> widgetPolishQueue; + void addToPolishQueue(QWidget *widget); + void processPolishQueue(); // Force all children widgets to repaint - void polishChildren() { polishChildren(parent); } - static void polishChildren(QWidget *widget) - { - for (QWidget *child : widget->findChildren<QWidget *>()) { - repolish(child); - } - } + static void polishChildren(QWidget *widget); - void repolish() { repolish(parent); } - static void repolish(QWidget *widget) { widget->style()->polish(widget); } + static void repolish(QWidget *widget); // Adds a style class to the widget - void addClass(const QString &classname) { addClass(parent, classname); } - static void addClass(QWidget *widget, const QString &classname) - { - if (!classNameIsValid(classname)) { - return; - } - - QVariant current = widget->property("class"); - - QStringList classList = current.toString().split(" "); - if (classList.contains(classname)) { - return; - } - - classList.removeDuplicates(); - classList.removeAll(""); - classList.append(classname); - - QString newClasses = classList.isEmpty() ? "" : classList.join(" "); - widget->setProperty("class", newClasses); - - repolish(widget); - } + static void addClass(QWidget *widget, const QString &classname); // Removes a style class from a widget - void removeClass(const QString &classname) { removeClass(parent, classname); } - static void removeClass(QWidget *widget, const QString &classname) - { - if (!classNameIsValid(classname)) { - return; - } - - QVariant current = widget->property("class"); - if (current.isNull()) { - return; - } - - QStringList classList = current.toString().split(" "); - if (!classList.contains(classname, Qt::CaseSensitive)) { - return; - } - - classList.removeDuplicates(); - classList.removeAll(""); - classList.removeAll(classname); - - QString newClasses = classList.isEmpty() ? "" : classList.join(" "); - widget->setProperty("class", newClasses); - - repolish(widget); - } + static void removeClass(QWidget *widget, const QString &classname); // Forces the addition or removal of a style class from a widget - void toggleClass(const QString &classname, bool toggle) { toggleClass(parent, classname, toggle); } - static void toggleClass(QWidget *widget, const QString &classname, bool toggle) - { - if (toggle) { - addClass(widget, classname); - } else { - removeClass(widget, classname); - } - } + static void toggleClass(QWidget *widget, const QString &classname, bool toggle); - static void applyColorToIcon(QWidget *widget); + static void applyColorToIcon(QAbstractButton *button); + static void applyColorToIcon(QLabel *label); static QPixmap recolorPixmap(const QPixmap &src, const QColor &color); - void applyStateStylingEventFilter(QWidget *widget); + static void applyStateStylingEventFilter(QWidget *widget); }; } // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/widgets/CollapsibleGroup.cpp
Added
@@ -0,0 +1,107 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <Idian/CollapsibleGroup.hpp> +#include <Idian/ExpandButton.hpp> +#include <Idian/Row.hpp> +#include <Idian/RowInfo.hpp> +#include <Idian/RowList.hpp> +#include <Idian/ToggleSwitch.hpp> +#include <Idian/Utils.hpp> + +#include <QPixmap> +#include <QVBoxLayout> + +namespace idian { +CollapsibleGroup::CollapsibleGroup(QWidget *parent) : QFrame(parent) +{ + mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + setLayout(mainLayout); + + rowWidget = new Row(this); + + mainLayout->addWidget(rowWidget); + + auto *headerInfo = new RowInfo(rowWidget); + rowWidget->layout()->addWidget(headerInfo); + + expandButton = new ExpandButton(this); + rowWidget->layout()->addWidget(expandButton); + rowWidget->setBuddy(expandButton); + + propertyList = new RowList(this); + propertyList->setVisible(false); + mainLayout->addWidget(propertyList); + + connect(expandButton, &QAbstractButton::clicked, this, &CollapsibleGroup::toggleVisibility); +} + +void CollapsibleGroup::setCheckable(bool check) +{ + checkable = check; + + if (checkable && !toggleSwitch) { + propertyList->setEnabled(false); + Utils::polishChildren(propertyList); + + toggleSwitch = new ToggleSwitch(false); + + rowWidget->layout()->insertWidget(rowWidget->layout()->count() - 1, toggleSwitch); + connect(toggleSwitch, &ToggleSwitch::toggled, propertyList, &RowList::setEnabled); + connect(toggleSwitch, &ToggleSwitch::toggled, this, &CollapsibleGroup::toggled); + } + + if (!checkable && toggleSwitch) { + propertyList->setEnabled(true); + Utils::polishChildren(propertyList); + + toggleSwitch->deleteLater(); + } +} + +void CollapsibleGroup::setChecked(bool checked) +{ + if (!isCheckable()) { + throw std::logic_error("Called setChecked on a non-checkable collapse row."); + } + + toggleSwitch->setChecked(checked); +} + +bool CollapsibleGroup::isChecked() +{ + return toggleSwitch->isChecked(); +} + +void CollapsibleGroup::toggleVisibility() +{ + bool visible = !propertyList->isVisible(); + + setExpanded(visible); +} + +void CollapsibleGroup::setExpanded(bool expand) +{ + Utils::toggleClass(this, "expanded", expand); + Utils::repolish(rowWidget); + + propertyList->setVisible(expand); + expandButton->setChecked(expand); +} +} // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/widgets/ListHeader.cpp
Added
@@ -0,0 +1,102 @@ +/****************************************************************************** + Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <Idian/ListHeader.hpp> +#include <Idian/Utils.hpp> + +#include <Idian/moc_ListHeader.cpp> + +using idian::ListHeader; + +ListHeader::ListHeader(QWidget *parent) : QFrame(parent) +{ + layout_ = new QHBoxLayout(); + layout_->setSpacing(0); + layout_->setContentsMargins(0, 0, 0, 0); + + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + + setLayout(layout_); + + auto *textLayout = new QVBoxLayout(); + nameLabel = new QLabel(); + nameLabel->setVisible(false); + nameLabel->setIndent(0); + Utils::addClass(nameLabel, "title"); + + descriptionLabel = new QLabel(); + descriptionLabel->setVisible(false); + descriptionLabel->setIndent(0); + descriptionLabel->setWordWrap(true); + Utils::addClass(descriptionLabel, "description"); + + textLayout->addWidget(nameLabel); + textLayout->addWidget(descriptionLabel); + + layout_->addLayout(textLayout); +} + +ListHeader::ListHeader(QWidget *parent, QString title) : ListHeader(parent) +{ + setTitle(title); +} + +ListHeader::ListHeader(QWidget *parent, QString title, QString description) : ListHeader(parent) +{ + setTitle(title); + setDescription(description); +} + +void ListHeader::setTitle(QString name) +{ + nameLabel->setText(name); + setAccessibleName(name); + showTitle(true); +} + +void ListHeader::setDescription(QString desc) +{ + descriptionLabel->setText(desc); + setAccessibleDescription(desc); + showDescription(true); +} + +void ListHeader::showTitle(bool visible) +{ + nameLabel->setVisible(visible); +} + +void ListHeader::showDescription(bool visible) +{ + descriptionLabel->setVisible(visible); +} + +void ListHeader::setCheckable(bool check) +{ + checkable = check; + + if (checkable && !toggleSwitch) { + toggleSwitch = new ToggleSwitch(true); + layout_->addWidget(toggleSwitch); + connect(toggleSwitch, &ToggleSwitch::toggled, this, this(bool checked) { emit toggled(checked); }); + } + + if (!checkable && toggleSwitch) { + layout_->removeWidget(toggleSwitch); + toggleSwitch->deleteLater(); + } +}
View file
obs-studio-32.2.2.tar.xz/shared/qt/idian/widgets/Row.cpp -> obs-studio-33.0.0.tar.xz/shared/qt/idian/widgets/Row.cpp
Changed
@@ -15,7 +15,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ +#include <Idian/ComboBox.hpp> #include <Idian/Row.hpp> +#include <Idian/ToggleSwitch.hpp> #include <QApplication> #include <QComboBox> @@ -25,135 +27,29 @@ #include <Idian/moc_Row.cpp> namespace idian { - -Row::Row(QWidget *parent) : GenericRow(parent) +Row::Row(QWidget *parent) : QFrame(parent) { - layout = new QGridLayout(this); - layout->setVerticalSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - - labelLayout = new QVBoxLayout(); - labelLayout->setSpacing(0); - labelLayout->setContentsMargins(0, 0, 0, 0); - - setFocusPolicy(Qt::StrongFocus); - setLayout(layout); - - layout->setColumnMinimumWidth(0, 0); - layout->setColumnStretch(0, 0); - layout->setColumnStretch(1, 40); - layout->setColumnStretch(2, 55); - - nameLabel = new QLabel(); - nameLabel->setVisible(false); - Utils::addClass(nameLabel, "title"); - - descriptionLabel = new QLabel(); - descriptionLabel->setVisible(false); - Utils::addClass(descriptionLabel, "description"); - - labelLayout->addWidget(nameLabel); - labelLayout->addWidget(descriptionLabel); - - layout->addLayout(labelLayout, 0, 1, Qt::AlignLeft); -} - -void Row::setPrefix(QWidget *w, bool auto_connect) -{ - setSuffixEnabled(false); - - prefix_ = w; - - if (auto_connect) { - this->connectBuddyWidget(w); - } - - prefix_->setParent(this); - layout->addWidget(prefix_, 0, 0, Qt::AlignLeft); - layout->setColumnStretch(0, 3); -} - -void Row::setSuffix(QWidget *w, bool auto_connect) -{ - setPrefixEnabled(false); - - suffix_ = w; - - if (auto_connect) { - this->connectBuddyWidget(w); - } - - suffix_->setParent(this); - layout->addWidget(suffix_, 0, 2, Qt::AlignRight | Qt::AlignVCenter); -} - -void Row::setPrefixEnabled(bool enabled) -{ - if (!prefix_) { - return; - } - if (enabled) { - setSuffixEnabled(false); - } - if (enabled == prefix_->isEnabled() && enabled == prefix_->isVisible()) { - return; - } + rowLayout = new QHBoxLayout(this); + rowLayout->setContentsMargins(0, 0, 0, 0); - layout->setColumnStretch(0, enabled ? 3 : 0); - prefix_->setEnabled(enabled); - prefix_->setVisible(enabled); + setLayout(rowLayout); } -void Row::setSuffixEnabled(bool enabled) +void Row::setBuddy(QWidget *widget) { - if (!suffix_) { - return; - } - if (enabled) { - setPrefixEnabled(false); - } - if (enabled == suffix_->isEnabled() && enabled == suffix_->isVisible()) { + if (buddyWidget) { return; } - suffix_->setEnabled(enabled); - suffix_->setVisible(enabled); -} - -void Row::setTitle(const QString &name) -{ - nameLabel->setText(name); - setAccessibleName(name); - showTitle(true); -} - -void Row::setDescription(const QString &description) -{ - descriptionLabel->setText(description); - setAccessibleDescription(description); - showDescription(true); -} - -void Row::showTitle(bool visible) -{ - nameLabel->setVisible(visible); -} - -void Row::showDescription(bool visible) -{ - descriptionLabel->setVisible(visible); -} - -void Row::setBuddy(QWidget *widget) -{ buddyWidget = widget; Utils::addClass(widget, "row-buddy"); + connectBuddyWidget(widget); } void Row::setChangeCursor(bool change) { changeCursor = change; - Utils::toggleClass("cursor-pointer", change); + Utils::toggleClass(this, "cursor-pointer", change); } void Row::enterEvent(QEnterEvent *event) @@ -170,11 +66,7 @@ Utils::repolish(buddyWidget); } - if (hasPrefix() || hasSuffix()) { - Utils::polishChildren(); - } - - GenericRow::enterEvent(event); + QFrame::enterEvent(event); } void Row::leaveEvent(QEvent *event) @@ -183,11 +75,7 @@ Utils::repolish(buddyWidget); } - if (hasPrefix() || hasSuffix()) { - Utils::polishChildren(); - } - - GenericRow::leaveEvent(event); + QFrame::leaveEvent(event); } void Row::mouseReleaseEvent(QMouseEvent *event) @@ -208,184 +96,38 @@ void Row::connectBuddyWidget(QWidget *widget) { - setAccessibleName(nameLabel->text()); - setFocusProxy(widget); - setBuddy(widget); + setAttribute(Qt::WA_Hover, true); + setFocusPolicy(Qt::StrongFocus); + Utils::applyStateStylingEventFilter(this); // If element is a ToggleSwitch and checkable, forward clicks to the widget - ToggleSwitch *obsToggle = dynamic_cast<ToggleSwitch *>(widget); + ToggleSwitch *obsToggle = qobject_cast<ToggleSwitch *>(widget); if (obsToggle && obsToggle->isCheckable()) { setChangeCursor(true); + widget->setFocusProxy(this); connect(this, &Row::clicked, obsToggle, &ToggleSwitch::click); return; } // If element is any other QAbstractButton subclass, and checkable, forward clicks to the widget. - QAbstractButton *button = dynamic_cast<QAbstractButton *>(widget); - if (button && button->isCheckable()) { + QAbstractButton *button = qobject_cast<QAbstractButton *>(widget); + if (button) { setChangeCursor(true); + widget->setFocusProxy(this); connect(this, &Row::clicked, button, &QAbstractButton::click); return; } // If element is an ComboBox, clicks toggle the dropdown. - ComboBox *obsCombo = dynamic_cast<ComboBox *>(widget); + ComboBox *obsCombo = qobject_cast<ComboBox *>(widget); if (obsCombo) { setChangeCursor(true); + widget->setFocusProxy(this); connect(this, &Row::clicked, obsCombo, &ComboBox::togglePopup); return; } } - -// Button for expanding a collapsible ActionRow -ExpandButton::ExpandButton(QWidget *parent) : QAbstractButton(parent), Utils(this) -{ - Utils::applyStateStylingEventFilter(this); - setCheckable(true); -} - -void ExpandButton::paintEvent(QPaintEvent *) -{ - QStyleOptionButton opt; - opt.initFrom(this); - QPainter p(this); - - bool checked = isChecked(); - - opt.state.setFlag(QStyle::State_On, checked); - opt.state.setFlag(QStyle::State_Off, !checked); - - opt.state.setFlag(QStyle::State_Sunken, checked); - - p.setRenderHint(QPainter::Antialiasing, true); - p.setRenderHint(QPainter::SmoothPixmapTransform, true); - - style()->drawPrimitive(QStyle::PE_PanelButtonCommand, &opt, &p, this); - style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &p, this); -} - -// Row variant that can be expanded to show another properties list -CollapsibleRow::CollapsibleRow(QWidget *parent) : GenericRow(parent) -{ - layout = new QVBoxLayout; - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - setLayout(layout); - - rowWidget = new RowFrame(); - rowLayout = new QHBoxLayout(); - rowLayout->setContentsMargins(0, 0, 0, 0); - rowLayout->setSpacing(0); - rowWidget->setLayout(rowLayout); - - actionRow = new Row(); - actionRow->setChangeCursor(false); - - rowLayout->addWidget(actionRow); - - propertyList = new PropertiesList(this); - propertyList->setVisible(false); - - expandFrame = new QFrame(); - btnLayout = new QHBoxLayout(); - btnLayout->setContentsMargins(0, 0, 0, 0); - btnLayout->setSpacing(0); - expandFrame->setLayout(btnLayout); - Utils::addClass(expandFrame, "btn-frame"); - actionRow->setBuddy(expandFrame); - - expandButton = new ExpandButton(this); - btnLayout->addWidget(expandButton); - - rowLayout->addWidget(expandFrame); - - layout->addWidget(rowWidget); - layout->addWidget(propertyList); - - actionRow->setFocusProxy(expandButton); - - connect(expandButton, &QAbstractButton::clicked, this, &CollapsibleRow::toggleVisibility); - connect(actionRow, &Row::clicked, expandButton, &QAbstractButton::click); -} - -void CollapsibleRow::setCheckable(bool check) -{ - checkable = check; - - if (checkable && !toggleSwitch) { - propertyList->setEnabled(false); - Utils::polishChildren(propertyList); - - toggleSwitch = new ToggleSwitch(false); - - actionRow->setSuffix(toggleSwitch, false); - connect(toggleSwitch, &ToggleSwitch::toggled, propertyList, &PropertiesList::setEnabled); - connect(toggleSwitch, &ToggleSwitch::toggled, this, &CollapsibleRow::toggled); - } - - if (!checkable && toggleSwitch) { - propertyList->setEnabled(true); - Utils::polishChildren(propertyList); - - actionRow->suffix()->deleteLater(); - } -} - -void CollapsibleRow::setChecked(bool checked) -{ - if (!isCheckable()) { - throw std::logic_error("Called setChecked on a non-checkable row."); - } - - toggleSwitch->setChecked(checked); -} - -void CollapsibleRow::setTitle(const QString &name) -{ - actionRow->setTitle(name); -} - -void CollapsibleRow::setDescription(const QString &description) -{ - actionRow->setDescription(description); -} - -void CollapsibleRow::toggleVisibility() -{ - bool visible = !propertyList->isVisible(); - - propertyList->setVisible(visible); - expandButton->setChecked(visible); -} - -void CollapsibleRow::addRow(GenericRow *actionRow) -{ - propertyList->addRow(actionRow); -} - -RowFrame::RowFrame(QWidget *parent) : QFrame(parent), Utils(this) -{ - setAttribute(Qt::WA_Hover, true); - - Utils::applyStateStylingEventFilter(this); -} - -void RowFrame::enterEvent(QEnterEvent *event) -{ - setCursor(Qt::PointingHandCursor); - - Utils::polishChildren(); - - QWidget::enterEvent(event); -} - -void RowFrame::leaveEvent(QEvent *event) -{ - Utils::polishChildren(); - - QWidget::leaveEvent(event); -} } // namespace idian
View file
obs-studio-33.0.0.tar.xz/shared/qt/idian/widgets/RowList.cpp
Added
@@ -0,0 +1,95 @@ +/****************************************************************************** + Copyright (C) 2023 by Dennis Sädtler <dennis@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include <Idian/RowList.hpp> + +#include <QStyle> + +#include <Idian/moc_RowList.cpp> + +using idian::RowList; + +RowList::RowList(QWidget *parent) : QFrame(parent) +{ + layout = new QVBoxLayout(); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); + + setLayout(layout); + + rowLayout = new QVBoxLayout(); + + layout->addLayout(rowLayout); +} + +void idian::RowList::addHeader(QWidget *widget) +{ + layout->insertWidget(layout->indexOf(rowLayout), widget); +} + +// Note: This function takes ownership of the added widget +// and it may be deleted when the properties list is destroyed +// or the clear() method is called! +void RowList::addRow(QWidget *widget) +{ + // Add custom spacer when more than one row exists + if (count() > 0) { + rowLayout->addWidget(new RowListSpacer(this)); + } + + // Custom properties to work around :first and :last not existing. + if (!first) { + Utils::addClass(widget, "first"); + first = widget; + } + + // Remove last property from existing last item + if (last) { + Utils::removeClass(last, "last"); + } + + // Most recently added item is also always last + Utils::addClass(widget, "last"); + last = widget; + + rowLayout->addWidget(widget); + adjustSize(); +} + +void RowList::clear() +{ + first = nullptr; + last = nullptr; + QLayoutItem *item = rowLayout->takeAt(0); + + while (item) { + if (item->widget()) { + item->widget()->deleteLater(); + } + delete item; + + item = rowLayout->takeAt(0); + } + + adjustSize(); +} + +int idian::RowList::count() const +{ + return rowLayout->count(); +}
View file
obs-studio-33.0.0.tar.xz/shared/qt/obs-spinbox
Added
+(directory)
View file
obs-studio-33.0.0.tar.xz/shared/qt/obs-spinbox/AutoSelectLineEdit.cpp
Added
@@ -0,0 +1,28 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "AutoSelectLineEdit.hpp" + +#include <QMouseEvent> + +namespace OBS { +void AutoSelectLineEdit::mouseDoubleClickEvent(QMouseEvent *event) +{ + selectAll(); + event->accept(); +} +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/shared/qt/obs-spinbox/AutoSelectLineEdit.hpp
Added
@@ -0,0 +1,38 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <QLineEdit> + +namespace OBS { +class DoubleSpinBox; +class SpinBox; + +class AutoSelectLineEdit : private QLineEdit { + Q_OBJECT + + friend class DoubleSpinBox; + friend class SpinBox; + +private: + explicit AutoSelectLineEdit(QWidget *parent) : QLineEdit(parent) {}; + +protected: + virtual void mouseDoubleClickEvent(QMouseEvent *event) override; +}; +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/shared/qt/obs-spinbox/CMakeLists.txt
Added
@@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.28...3.30) + +find_package(Qt6 REQUIRED Core Widgets) + +add_library(qt-obs-spinbox INTERFACE) +add_library(OBS::qt-obs-spinbox ALIAS qt-obs-spinbox) + +target_sources( + qt-obs-spinbox + INTERFACE AutoSelectLineEdit.cpp AutoSelectLineEdit.hpp DoubleSpinBox.cpp DoubleSpinBox.hpp SpinBox.cpp SpinBox.hpp +) +target_include_directories(qt-obs-spinbox INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") + +target_link_libraries(qt-obs-spinbox INTERFACE Qt::Core Qt::Widgets)
View file
obs-studio-33.0.0.tar.xz/shared/qt/obs-spinbox/DoubleSpinBox.cpp
Added
@@ -0,0 +1,245 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "DoubleSpinBox.hpp" + +#include "AutoSelectLineEdit.hpp" + +#include <QApplication> +#include <QKeyEvent> +#include <QLocale> +#include <QMouseEvent> +#include <QStyle> +#include <QStyleOptionSpinBox> +#include <QTimer> + +namespace { +QString trimAffixes(const QString &fullText, const QString &prefix, const QString &suffix) +{ + if (fullText.isEmpty()) { + return QString(); + } + + QString text = fullText; + + if (!prefix.isEmpty() && text.startsWith(prefix)) { + text.remove(0, prefix.length()); + } + + if (!suffix.isEmpty() && text.endsWith(suffix)) { + text.chop(suffix.length()); + } + + return text.trimmed(); +} +} // namespace + +namespace OBS { +DoubleSpinBox::DoubleSpinBox(QWidget *parent) : QDoubleSpinBox(parent) +{ + setKeyboardTracking(false); + setFocusPolicy(Qt::StrongFocus); + auto lineEdit = new AutoSelectLineEdit(this); + setLineEdit(lineEdit); + + connect(lineEdit, &QLineEdit::cursorPositionChanged, this, &DoubleSpinBox::clampCursorPosition); +} + +DoubleSpinBox::~DoubleSpinBox() {} + +QValidator::State DoubleSpinBox::validate(QString &text, int &) const +{ + QString stripped = trimAffixes(text, prefix(), suffix()); + + QString decPoint = locale().decimalPoint(); + if (stripped.isEmpty() || stripped == "-" || stripped == decPoint || stripped == "-" + decPoint) { + return QValidator::Intermediate; + } + + bool ok; + double val = locale().toDouble(stripped, &ok); + + if (!ok) { + return QValidator::Invalid; + } + + QString resultText = prefix() + textFromValue(val) + suffix(); + if (text != resultText) { + return QValidator::Intermediate; + } + + if (val < minimum() || val > maximum()) { + return QValidator::Intermediate; + } + + return QValidator::Acceptable; +} + +void DoubleSpinBox::fixup(QString &input) const +{ + QString stripped = trimAffixes(input, prefix(), suffix()); + + bool ok; + double val = locale().toDouble(stripped, &ok); + + if (ok) { + val = qBound(minimum(), val, maximum()); + input = prefix() + textFromValue(val) + suffix(); + } else { + // Fallback to base class behavior if parsing fails + QDoubleSpinBox::fixup(input); + } +} + +void DoubleSpinBox::mousePressEvent(QMouseEvent *event) +{ + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + if (style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp, this).contains(event->pos())) { + QDoubleSpinBox::mousePressEvent(event); + return; + } + + if (style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown, this).contains(event->pos())) { + QDoubleSpinBox::mousePressEvent(event); + return; + } + + // Mouse button was pressed and is not over the spinbox buttons, forward event to the lineEdit. + QRect lineEditRect = lineEdit()->geometry(); + mouseDragYOffset = (static_cast<double>(height()) / 2) - event->position().y(); + + if (!lineEditRect.contains(event->pos())) { + QPointF localPos = event->pos() - lineEditRect.topLeft(); + QMouseEvent forwardEvent(event->type(), localPos, event->globalPosition(), event->button(), + event->buttons(), event->modifiers()); + + QCoreApplication::sendEvent(lineEdit(), &forwardEvent); + event->accept(); + return; + } + + QDoubleSpinBox::mousePressEvent(event); +} + +void DoubleSpinBox::mouseMoveEvent(QMouseEvent *event) +{ + if (!(event->buttons() & Qt::LeftButton)) { + QDoubleSpinBox::mouseMoveEvent(event); + return; + } + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + if (style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp, this).contains(event->pos())) { + QDoubleSpinBox::mouseMoveEvent(event); + return; + } + + if (style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown, this).contains(event->pos())) { + QDoubleSpinBox::mouseMoveEvent(event); + return; + } + + // Mouse button is down and not over the spinbox buttons, forward move event to the lineEdit. + // This allows events within the spinbox but outside the actual lineEdit widget to work. + QPointF relativePos = lineEdit()->mapFromGlobal(event->globalPosition()); + relativePos.ry() -= mouseDragYOffset; + + QMouseEvent forwardEvent(event->type(), relativePos, event->globalPosition(), event->button(), event->buttons(), + event->modifiers()); + QCoreApplication::sendEvent(lineEdit(), &forwardEvent); +} + +void DoubleSpinBox::keyPressEvent(QKeyEvent *event) +{ + bool isShiftHeld = QGuiApplication::keyboardModifiers() & Qt::ShiftModifier; + + switch (event->key()) { + case Qt::Key_Up: + event->accept(); + if (stepEnabled() & QAbstractSpinBox::StepUpEnabled) { + stepBy(isShiftHeld ? 10 : 1); + } + return; + case Qt::Key_Down: + event->accept(); + if (stepEnabled() & QAbstractSpinBox::StepDownEnabled) { + stepBy(isShiftHeld ? -10 : -1); + } + return; + case Qt::Key_Return: + case Qt::Key_Enter: + event->accept(); + interpretText(); + return; + } + + QDoubleSpinBox::keyPressEvent(event); +} + +void DoubleSpinBox::wheelEvent(QWheelEvent *event) +{ + if (!hasFocus()) { + event->ignore(); + } else { + QDoubleSpinBox::wheelEvent(event); + } +} + +void DoubleSpinBox::clampCursorPosition() +{ + QSignalBlocker block{lineEdit()}; + + if (suffix().isEmpty() && prefix().isEmpty()) { + return; + } + + int cursorPosition = lineEdit()->cursorPosition(); + bool hasSelectedText = !lineEdit()->selectedText().isEmpty(); + + if (!suffix().isEmpty()) { + int suffixIndex = lineEdit()->text().length() - suffix().length(); + if (cursorPosition > suffixIndex) { + int cursorOvershoot = lineEdit()->selectionEnd() - suffixIndex; + if (hasSelectedText && cursorOvershoot > 0) { + lineEdit()->setSelection(lineEdit()->selectionStart(), + lineEdit()->selectionLength() - cursorOvershoot); + } else { + lineEdit()->setCursorPosition(suffixIndex); + } + return; + } + } + + if (!prefix().isEmpty()) { + int prefixIndex = prefix().length(); + if (cursorPosition < prefixIndex) { + int cursorUndershoot = prefixIndex - lineEdit()->selectionStart(); + if (hasSelectedText && cursorUndershoot > 0) { + lineEdit()->setSelection(lineEdit()->selectionEnd(), + -lineEdit()->selectionLength() + cursorUndershoot); + } else { + lineEdit()->setCursorPosition(prefixIndex); + } + return; + } + } +} +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/shared/qt/obs-spinbox/DoubleSpinBox.hpp
Added
@@ -0,0 +1,45 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <QDoubleSpinBox> + +namespace OBS { +class DoubleSpinBox : public QDoubleSpinBox { + Q_OBJECT + +public: + explicit DoubleSpinBox(QWidget *parent = nullptr); + ~DoubleSpinBox(); + + virtual QValidator::State validate(QString &text, int &pos) const override; + virtual void fixup(QString &input) const override; + +protected: + virtual void mousePressEvent(QMouseEvent *event) override; + virtual void mouseMoveEvent(QMouseEvent *event) override; + virtual void keyPressEvent(QKeyEvent *event) override; + virtual void wheelEvent(QWheelEvent *event) override; + +private: + double mouseDragYOffset = 0.0; + +private slots: + void clampCursorPosition(); +}; +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/shared/qt/obs-spinbox/SpinBox.cpp
Added
@@ -0,0 +1,244 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#include "SpinBox.hpp" + +#include "AutoSelectLineEdit.hpp" + +#include <QApplication> +#include <QKeyEvent> +#include <QLocale> +#include <QMouseEvent> +#include <QStyle> +#include <QStyleOptionSpinBox> +#include <QTimer> + +namespace { +QString trimAffixes(const QString &fullText, const QString &prefix, const QString &suffix) +{ + if (fullText.isEmpty()) { + return QString(); + } + + QString text = fullText; + + if (!prefix.isEmpty() && text.startsWith(prefix)) { + text.remove(0, prefix.length()); + } + + if (!suffix.isEmpty() && text.endsWith(suffix)) { + text.chop(suffix.length()); + } + + return text.trimmed(); +} +} // namespace + +namespace OBS { +SpinBox::SpinBox(QWidget *parent) : QSpinBox(parent) +{ + setKeyboardTracking(false); + setFocusPolicy(Qt::StrongFocus); + auto lineEdit = new AutoSelectLineEdit(this); + setLineEdit(lineEdit); + + connect(lineEdit, &QLineEdit::cursorPositionChanged, this, &SpinBox::clampCursorPosition); +} + +SpinBox::~SpinBox() {} + +QValidator::State SpinBox::validate(QString &text, int &) const +{ + QString stripped = trimAffixes(text, prefix(), suffix()); + + if (stripped.isEmpty() || stripped == "-") { + return QValidator::Intermediate; + } + + bool ok; + int val = locale().toInt(stripped, &ok); + + if (!ok) { + return QValidator::Invalid; + } + + QString resultText = prefix() + textFromValue(val) + suffix(); + if (text != resultText) { + return QValidator::Intermediate; + } + + if (val < minimum() || val > maximum()) { + return QValidator::Intermediate; + } + + return QValidator::Acceptable; +} + +void SpinBox::fixup(QString &input) const +{ + QString stripped = trimAffixes(input, prefix(), suffix()); + + bool ok; + int val = locale().toInt(stripped, &ok); + + if (ok) { + val = qBound(minimum(), val, maximum()); + input = prefix() + textFromValue(val) + suffix(); + } else { + // Fallback to base class behavior if parsing fails + QSpinBox::fixup(input); + } +} + +void SpinBox::mousePressEvent(QMouseEvent *event) +{ + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + if (style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp, this).contains(event->pos())) { + QSpinBox::mousePressEvent(event); + return; + } + + if (style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown, this).contains(event->pos())) { + QSpinBox::mousePressEvent(event); + return; + } + + // Mouse button was pressed and is not over the spinbox buttons, forward event to the lineEdit. + QRect lineEditRect = lineEdit()->geometry(); + mouseDragYOffset = (static_cast<double>(height()) / 2) - event->position().y(); + + if (!lineEditRect.contains(event->pos())) { + QPointF localPos = event->pos() - lineEditRect.topLeft(); + QMouseEvent forwardEvent(event->type(), localPos, event->globalPosition(), event->button(), + event->buttons(), event->modifiers()); + + QCoreApplication::sendEvent(lineEdit(), &forwardEvent); + event->accept(); + return; + } + + QSpinBox::mousePressEvent(event); +} + +void SpinBox::mouseMoveEvent(QMouseEvent *event) +{ + if (!(event->buttons() & Qt::LeftButton)) { + QSpinBox::mouseMoveEvent(event); + return; + } + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + if (style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp, this).contains(event->pos())) { + QSpinBox::mouseMoveEvent(event); + return; + } + + if (style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown, this).contains(event->pos())) { + QSpinBox::mouseMoveEvent(event); + return; + } + + // Mouse button is down and not over the spinbox buttons, forward move event to the lineEdit. + // This allows events within the spinbox but outside the actual lineEdit widget to work. + QPointF relativePos = lineEdit()->mapFromGlobal(event->globalPosition()); + relativePos.ry() -= mouseDragYOffset; + + QMouseEvent forwardEvent(event->type(), relativePos, event->globalPosition(), event->button(), event->buttons(), + event->modifiers()); + QCoreApplication::sendEvent(lineEdit(), &forwardEvent); +} + +void SpinBox::keyPressEvent(QKeyEvent *event) +{ + bool isShiftHeld = QGuiApplication::keyboardModifiers() & Qt::ShiftModifier; + + switch (event->key()) { + case Qt::Key_Up: + event->accept(); + if (stepEnabled() & QAbstractSpinBox::StepUpEnabled) { + stepBy(isShiftHeld ? 10 : 1); + } + return; + case Qt::Key_Down: + event->accept(); + if (stepEnabled() & QAbstractSpinBox::StepDownEnabled) { + stepBy(isShiftHeld ? -10 : -1); + } + return; + case Qt::Key_Return: + case Qt::Key_Enter: + event->accept(); + interpretText(); + return; + } + + QSpinBox::keyPressEvent(event); +} + +void SpinBox::wheelEvent(QWheelEvent *event) +{ + if (!hasFocus()) { + event->ignore(); + } else { + QSpinBox::wheelEvent(event); + } +} + +void SpinBox::clampCursorPosition() +{ + QSignalBlocker block{lineEdit()}; + + if (suffix().isEmpty() && prefix().isEmpty()) { + return; + } + + int cursorPosition = lineEdit()->cursorPosition(); + bool hasSelectedText = !lineEdit()->selectedText().isEmpty(); + + if (!suffix().isEmpty()) { + int suffixIndex = lineEdit()->text().length() - suffix().length(); + if (cursorPosition > suffixIndex) { + int cursorOvershoot = lineEdit()->selectionEnd() - suffixIndex; + if (hasSelectedText && cursorOvershoot > 0) { + lineEdit()->setSelection(lineEdit()->selectionStart(), + lineEdit()->selectionLength() - cursorOvershoot); + } else { + lineEdit()->setCursorPosition(suffixIndex); + } + return; + } + } + + if (!prefix().isEmpty()) { + int prefixIndex = prefix().length(); + if (cursorPosition < prefixIndex) { + int cursorUndershoot = prefixIndex - lineEdit()->selectionStart(); + if (hasSelectedText && cursorUndershoot > 0) { + lineEdit()->setSelection(lineEdit()->selectionEnd(), + -lineEdit()->selectionLength() + cursorUndershoot); + } else { + lineEdit()->setCursorPosition(prefixIndex); + } + return; + } + } +} +} // namespace OBS
View file
obs-studio-33.0.0.tar.xz/shared/qt/obs-spinbox/SpinBox.hpp
Added
@@ -0,0 +1,45 @@ +/****************************************************************************** + Copyright (C) 2026 by Taylor Giampaolo <warchamp7@obsproject.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +******************************************************************************/ + +#pragma once + +#include <QSpinBox> + +namespace OBS { +class SpinBox : public QSpinBox { + Q_OBJECT + +public: + explicit SpinBox(QWidget *parent = nullptr); + ~SpinBox(); + + virtual QValidator::State validate(QString &text, int &pos) const override; + virtual void fixup(QString &input) const override; + +protected: + virtual void mousePressEvent(QMouseEvent *event) override; + virtual void mouseMoveEvent(QMouseEvent *event) override; + virtual void keyPressEvent(QKeyEvent *event) override; + virtual void wheelEvent(QWheelEvent *event) override; + +private: + double mouseDragYOffset = 0.0; + +private slots: + void clampCursorPosition(); +}; +} // namespace OBS
View file
obs-studio-32.2.2.tar.xz/shared/qt/wrappers/qt-wrappers.cpp -> obs-studio-33.0.0.tar.xz/shared/qt/wrappers/qt-wrappers.cpp
Changed
@@ -90,6 +90,7 @@ QMessageBox mb(QMessageBox::Warning, title, text, QMessageBox::NoButton, parent); if (enableRichText) { mb.setTextFormat(Qt::RichText); + mb.setOption(QMessageBox::Option::DontUseNativeDialog, true); } mb.addButton(tr("OK"), QMessageBox::AcceptRole); mb.exec(); @@ -225,7 +226,7 @@ auto wait = &() { func(); - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); + QMetaObject::invokeMethod(&eventLoop, &QEventLoop::quit, Qt::QueuedConnection); }; os_atomic_inc_long(&insideEventLoop); @@ -246,7 +247,7 @@ auto wait = &() { func(); - QMetaObject::invokeMethod(&dlg, "accept", Qt::QueuedConnection); + QMetaObject::invokeMethod(&dlg, &QMessageBox::accept, Qt::QueuedConnection); }; os_atomic_inc_long(&insideEventLoop);
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.