name: KhuaPlayer include: - path: project.sparkle.yml enable: ${KHUA_ENABLE_SPARKLE} options: bundleIdPrefix: app.khuaplayer deploymentTarget: macOS: "14.0" createIntermediateGroups: true developmentRegion: en configs: Debug: debug Release: release AppStore: release settings: base: KHUA_REPO_ROOT: "$(SRCROOT)/../.." SWIFT_VERSION: "6.0" SWIFT_STRICT_CONCURRENCY: minimal CLANG_CXX_LANGUAGE_STANDARD: c++20 CLANG_CXX_LIBRARY: libc++ CLANG_ENABLE_OBJC_ARC: YES # Motion+ is part of every public channel; runtime capability still gates it. GCC_PREPROCESSOR_DEFINITIONS: "$(inherited) SP_ENHANCE=1" SWIFT_ACTIVE_COMPILATION_CONDITIONS: "$(inherited) SP_ENHANCE" MACOSX_DEPLOYMENT_TARGET: "14.0" ARCHS: arm64 MARKETING_VERSION: "0.6.1" CURRENT_PROJECT_VERSION: "11" KHUA_BUNDLE_ID: app.khuaplayer.KhuaPlayer KHUA_DEVELOPMENT_TEAM: "" ENABLE_USER_SCRIPT_SANDBOXING: NO HEADER_SEARCH_PATHS: - $(inherited) - $(KHUA_REPO_ROOT)/BuildGenerated - $(KHUA_REPO_ROOT)/Modules/MediaCore/Core - $(KHUA_REPO_ROOT)/Modules/MediaCore/Bridge - $(KHUA_REPO_ROOT)/Modules/VideoEnhancement - $(KHUA_REPO_ROOT)/ThirdParty/ffmpeg-min/include - $(KHUA_REPO_ROOT)/ThirdParty/dav1d-min/include - $(KHUA_REPO_ROOT)/ThirdParty/subtitles-min/include configs: Debug: CODE_SIGN_IDENTITY: "-" CODE_SIGNING_REQUIRED: NO CODE_SIGNING_ALLOWED: NO ENABLE_HARDENED_RUNTIME: NO Release: CODE_SIGN_IDENTITY: "-" CODE_SIGNING_REQUIRED: NO CODE_SIGNING_ALLOWED: NO ENABLE_HARDENED_RUNTIME: NO LLVM_LTO: YES_THIN SWIFT_COMPILATION_MODE: wholemodule DEAD_CODE_STRIPPING: YES DEPLOYMENT_POSTPROCESSING: YES STRIP_INSTALLED_PRODUCT: YES STRIP_STYLE: all DEBUG_INFORMATION_FORMAT: dwarf-with-dsym AppStore: CODE_SIGN_STYLE: Automatic CODE_SIGN_IDENTITY: "Apple Distribution" CODE_SIGNING_REQUIRED: YES CODE_SIGNING_ALLOWED: YES DEVELOPMENT_TEAM: $(KHUA_DEVELOPMENT_TEAM) ENABLE_APP_SANDBOX: YES ENABLE_HARDENED_RUNTIME: YES SWIFT_ACTIVE_COMPILATION_CONDITIONS: "$(inherited) SP_ENHANCE SP_APP_STORE" GCC_PREPROCESSOR_DEFINITIONS: "$(inherited) SP_ENHANCE=1 SP_APP_STORE=1" LLVM_LTO: YES_THIN SWIFT_COMPILATION_MODE: wholemodule DEAD_CODE_STRIPPING: YES DEPLOYMENT_POSTPROCESSING: YES STRIP_INSTALLED_PRODUCT: YES STRIP_STYLE: all DEBUG_INFORMATION_FORMAT: dwarf-with-dsym targets: KhuaPlayer: type: application platform: macOS preBuildScripts: - name: Validate Distribution Channel script: | set -eu if [ "${CONFIGURATION}" = "AppStore" ] && \ [ "${KHUA_SPARKLE_EMBEDDED:-NO}" = "YES" ]; then echo "error: this project was generated for direct distribution and embeds Sparkle" >&2 echo "error: regenerate and archive with Scripts/archive_app_store.sh" >&2 exit 1 fi basedOnDependencyAnalysis: false sources: - path: UI - path: CaptionsHost - path: ../../Modules/Captions - path: Resources/Localizable.xcstrings buildPhase: resources - path: Resources/InfoPlist.xcstrings buildPhase: resources - path: Resources/Assets.xcassets - path: Resources/PrivacyInfo.xcprivacy buildPhase: resources - path: ../../LICENSE buildPhase: resources - path: ../../THIRD_PARTY_NOTICES.md buildPhase: resources dependencies: - sdk: QuartzCore.framework - sdk: AppKit.framework - sdk: IOKit.framework - sdk: UniformTypeIdentifiers.framework - sdk: Speech.framework weak: true - sdk: Translation.framework weak: true - target: KhuaPlayerMediaCore embed: true codeSign: true - target: KhuaPlayerQuickLook embed: true codeSign: true # Load the system translation download UI only when it is requested. - target: KhuaPlayerCaptionsUI embed: true link: false codeSign: true - framework: ../../ThirdParty/subtitles-min/lib/libass.9.dylib embed: true codeSign: true link: false info: path: Info.plist properties: CFBundleName: Khua CFBundleDisplayName: Khua SPProductName: Khua Player CFBundleDevelopmentRegion: en CFBundleShortVersionString: $(MARKETING_VERSION) CFBundleVersion: $(CURRENT_PROJECT_VERSION) CFBundleIconName: AppIcon LSMinimumSystemVersion: "14.0" NSHighResolutionCapable: true LSApplicationCategoryType: public.app-category.video NSHumanReadableCopyright: "Copyright © 2026 Khua contributors" NSSpeechRecognitionUsageDescription: "Khua generates subtitles from the audio of the media you open. Processing takes place on this Mac." # Folder and volume privacy prompts appear only when Khua scans the # folder of a video you opened. Translations: Resources/InfoPlist.xcstrings. NSDesktopFolderUsageDescription: "Used to find subtitles and the next episode in the folder of the video you open." NSDocumentsFolderUsageDescription: "Used to find subtitles and the next episode in the folder of the video you open." NSDownloadsFolderUsageDescription: "Used to find subtitles and the next episode in the folder of the video you open." NSNetworkVolumesUsageDescription: "Used to find subtitles and the next episode in the folder of the video you open." NSRemovableVolumesUsageDescription: "Used to find subtitles and the next episode in the folder of the video you open." # Only system-provided encryption (HTTPS for update checks) is used. ITSAppUsesNonExemptEncryption: false CFBundleDocumentTypes: - CFBundleTypeName: "Video" CFBundleTypeRole: Viewer LSHandlerRank: Alternate LSItemContentTypes: - public.movie - public.video - public.mpeg-4 - com.apple.quicktime-movie - public.avi - public.mpeg - public.mpeg-2-video - com.apple.m4v-video - CFBundleTypeName: "Audio" CFBundleTypeRole: Viewer LSHandlerRank: Alternate LSItemContentTypes: - public.audio CFBundleTypeExtensions: - mp3 - flac - m4a - aac - wav - ogg - opus - wv - ape - tta - aiff - aif - amr - ac3 - dts - mka - CFBundleTypeName: "Video File" CFBundleTypeRole: Viewer LSHandlerRank: Alternate CFBundleTypeExtensions: - mp4 - mkv - mov - webm - avi - mpg - mpeg - ts - m2ts - mts - flv - wmv - m4v - 3gp - rmvb - rm - mxf - dv - av1 - obu - vvc - h266 - cavs - dnxhd - dnxhr UTImportedTypeDeclarations: - UTTypeIdentifier: org.matroska.mkv UTTypeDescription: "Matroska Video" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [mkv] public.mime-type: [video/x-matroska] - UTTypeIdentifier: org.webmproject.webm UTTypeDescription: "WebM Video" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [webm] public.mime-type: [video/webm] - UTTypeIdentifier: com.adobe.flash.video UTTypeDescription: "Flash Video" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [flv] public.mime-type: [video/x-flv] - UTTypeIdentifier: com.microsoft.windows-media-wmv UTTypeDescription: "Windows Media Video" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [wmv] public.mime-type: [video/x-ms-wmv] - UTTypeIdentifier: com.real.realmedia-vbr UTTypeDescription: "RealMedia Variable Bitrate" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [rmvb] public.mime-type: [application/vnd.rn-realmedia-vbr] - UTTypeIdentifier: org.smpte.mxf UTTypeDescription: "Material Exchange Format" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [mxf] public.mime-type: [application/mxf] - UTTypeIdentifier: app.khuaplayer.av1-video UTTypeDescription: "AV1 Elementary Video" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [av1, obu] - UTTypeIdentifier: app.khuaplayer.vvc-video UTTypeDescription: "VVC Elementary Video" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [vvc, h266] - UTTypeIdentifier: app.khuaplayer.cavs-video UTTypeDescription: "CAVS Elementary Video" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [cavs] - UTTypeIdentifier: app.khuaplayer.dnx-video UTTypeDescription: "DNxHD and DNxHR Elementary Video" UTTypeConformsTo: [public.movie] UTTypeTagSpecification: public.filename-extension: [dnxhd, dnxhr] entitlements: path: KhuaPlayer.entitlements properties: com.apple.security.app-sandbox: true # Files and folders the user opens or grants in an open panel. com.apple.security.files.user-selected.read-write: true # Recent items and granted folders survive relaunches as bookmarks. com.apple.security.files.bookmarks.app-scope: true # Subtitles, the next episode, generated captions, and screenshots # beside videos in Downloads and Movies without a folder prompt. com.apple.security.files.downloads.read-write: true com.apple.security.assets.movies.read-write: true settings: base: PRODUCT_BUNDLE_IDENTIFIER: $(KHUA_BUNDLE_ID) GENERATE_INFOPLIST_FILE: NO SWIFT_OBJC_BRIDGING_HEADER: Support/KhuaPlayer-Bridging-Header.h PRODUCT_NAME: Khua PRODUCT_MODULE_NAME: KhuaPlayer COMBINE_HIDPI_IMAGES: YES ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon LD_RUNPATH_SEARCH_PATHS: "@executable_path/../Frameworks" KhuaPlayerMediaCore: type: framework platform: macOS sources: - path: ../../Modules/MediaCore/Core - path: ../../Modules/MediaCore/Bridge - path: ../../Modules/VideoEnhancement excludes: - Shaders - path: Support/KhuaPlayer-Bridging-Header.h - path: ../../Platform/macOS - path: ../../Modules/MediaCore/Shaders/Video.metal - path: ../../ThirdParty/Licenses type: folder buildPhase: resources preBuildScripts: - name: Generate Shader Header script: | python3 "${KHUA_REPO_ROOT}/Scripts/gen_shader_header.py" mkdir -p "${DERIVED_FILE_DIR}" /usr/bin/touch "${DERIVED_FILE_DIR}/shader-header-fw.stamp" inputFiles: - $(KHUA_REPO_ROOT)/Modules/MediaCore/Shaders/Video.metal - $(KHUA_REPO_ROOT)/Scripts/gen_shader_header.py outputFiles: - $(DERIVED_FILE_DIR)/shader-header-fw.stamp basedOnDependencyAnalysis: true postBuildScripts: - name: Compile Lazy Frame Budget Library script: | set -euo pipefail AIR="${DERIVED_FILE_DIR}/FrameBudget.air" OUT="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FrameBudget.metallib" mkdir -p "$(dirname "${OUT}")" xcrun -sdk macosx metal -c -target "air64-apple-macos${MACOSX_DEPLOYMENT_TARGET}" \ "${KHUA_REPO_ROOT}/Modules/VideoEnhancement/Shaders/FrameBudget.metal" -o "${AIR}" xcrun -sdk macosx metallib "${AIR}" -o "${OUT}" inputFiles: - $(KHUA_REPO_ROOT)/Modules/VideoEnhancement/Shaders/FrameBudget.metal outputFiles: - $(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/FrameBudget.metallib basedOnDependencyAnalysis: true dependencies: - sdk: CoreMedia.framework - sdk: CoreVideo.framework - sdk: Metal.framework - sdk: QuartzCore.framework - sdk: AppKit.framework - sdk: VideoToolbox.framework - sdk: AudioToolbox.framework - sdk: CoreAudio.framework - sdk: CoreImage.framework - sdk: IOSurface.framework settings: base: PRODUCT_BUNDLE_IDENTIFIER: $(KHUA_BUNDLE_ID).MediaCore PRODUCT_NAME: KhuaPlayerMediaCore GENERATE_INFOPLIST_FILE: YES SKIP_INSTALL: YES APPLICATION_EXTENSION_API_ONLY: YES DYLIB_INSTALL_NAME_BASE: "@rpath" STRIP_STYLE: non-global LIBRARY_SEARCH_PATHS: - $(inherited) - $(KHUA_REPO_ROOT)/ThirdParty/ffmpeg-min/lib - $(KHUA_REPO_ROOT)/ThirdParty/dav1d-min/lib - $(KHUA_REPO_ROOT)/ThirdParty/speex-min/lib OTHER_LDFLAGS: - $(inherited) - -lavformat - -lavcodec - -lspeex - -lavutil - -lswscale - -lswresample - -ldav1d - -lz - -lbz2 KhuaPlayerCaptionsUI: type: framework platform: macOS sources: - path: CaptionsUI dependencies: - sdk: AppKit.framework - sdk: SwiftUI.framework weak: true - sdk: Translation.framework weak: true settings: base: PRODUCT_BUNDLE_IDENTIFIER: $(KHUA_BUNDLE_ID).CaptionsUI PRODUCT_NAME: KhuaPlayerCaptionsUI # The system translation callback requires Swift 5 isolation semantics. SWIFT_VERSION: "5" GENERATE_INFOPLIST_FILE: YES SKIP_INSTALL: YES DYLIB_INSTALL_NAME_BASE: "@rpath" STRIP_STYLE: non-global DEFINES_MODULE: NO KhuaPlayerQuickLook: type: app-extension platform: macOS sources: - path: QuickLook/Preview - path: UI/SPTimeText.swift - path: UI/SPPlaybackSleepController.swift - path: Resources/Localizable.xcstrings buildPhase: resources - path: Resources/PrivacyInfo.xcprivacy buildPhase: resources dependencies: - sdk: QuartzCore.framework - sdk: AppKit.framework - sdk: UniformTypeIdentifiers.framework - sdk: QuickLookUI.framework - sdk: IOKit.framework - target: KhuaPlayerMediaCore embed: false link: true info: path: QuickLook/Info.plist properties: CFBundleName: KhuaPlayerQuickLook CFBundleDisplayName: Khua Quick Look CFBundlePackageType: XPC! CFBundleShortVersionString: $(MARKETING_VERSION) CFBundleVersion: $(CURRENT_PROJECT_VERSION) CFBundleDevelopmentRegion: en LSMinimumSystemVersion: "14.0" NSExtension: NSExtensionPointIdentifier: com.apple.quicklook.preview NSExtensionPrincipalClass: $(PRODUCT_MODULE_NAME).QuickLookPreviewViewController NSExtensionAttributes: QLSupportedContentTypes: - org.matroska.mkv - org.webmproject.webm - com.adobe.flash.video - com.microsoft.windows-media-wmv - com.real.realmedia-vbr QLIsDataBasedPreview: false QLSupportsSearchableItems: false entitlements: path: QuickLook/KhuaPlayerQuickLook.entitlements properties: com.apple.security.app-sandbox: true com.apple.security.files.user-selected.read-only: true settings: base: PRODUCT_BUNDLE_IDENTIFIER: $(KHUA_BUNDLE_ID).QuickLook PRODUCT_NAME: KhuaPlayerQuickLook GENERATE_INFOPLIST_FILE: NO APPLICATION_EXTENSION_API_ONLY: YES SKIP_INSTALL: YES SWIFT_OBJC_BRIDGING_HEADER: Support/KhuaPlayer-Bridging-Header.h LD_RUNPATH_SEARCH_PATHS: "@executable_path/../../../../Frameworks"