This commit is contained in:
yoruix 2026-01-10 01:02:19 +05:30
parent d31cd2fcdc
commit 4cc77b96cd
12 changed files with 261 additions and 1546 deletions

View file

@ -1,69 +1,6 @@
//
// KSPlayerManager.m
// Nuvio
//
// Created by KSPlayer integration
//
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#import <React/RCTViewManager.h>
@interface RCT_EXTERN_MODULE (KSPlayerViewManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(source, NSDictionary)
RCT_EXPORT_VIEW_PROPERTY(paused, BOOL)
RCT_EXPORT_VIEW_PROPERTY(volume, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(rate, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(audioTrack, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(textTrack, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(allowsExternalPlayback, BOOL)
RCT_EXPORT_VIEW_PROPERTY(usesExternalPlaybackWhileExternalScreenIsActive, BOOL)
RCT_EXPORT_VIEW_PROPERTY(subtitleBottomOffset, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(subtitleFontSize, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(subtitleTextColor, NSString)
RCT_EXPORT_VIEW_PROPERTY(subtitleBackgroundColor, NSString)
RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString)
// Event properties
RCT_EXPORT_VIEW_PROPERTY(onLoad, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onProgress, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onBuffering, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onEnd, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onError, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onBufferingProgress, RCTDirectEventBlock)
RCT_EXTERN_METHOD(seek : (nonnull NSNumber *)node toTime : (nonnull NSNumber *)
time)
RCT_EXTERN_METHOD(setSource : (nonnull NSNumber *)
node source : (nonnull NSDictionary *)source)
RCT_EXTERN_METHOD(setPaused : (nonnull NSNumber *)node paused : (BOOL)paused)
RCT_EXTERN_METHOD(setVolume : (nonnull NSNumber *)
node volume : (nonnull NSNumber *)volume)
RCT_EXTERN_METHOD(setPlaybackRate : (nonnull NSNumber *)
node rate : (nonnull NSNumber *)rate)
RCT_EXTERN_METHOD(setAudioTrack : (nonnull NSNumber *)
node trackId : (nonnull NSNumber *)trackId)
RCT_EXTERN_METHOD(setTextTrack : (nonnull NSNumber *)
node trackId : (nonnull NSNumber *)trackId)
RCT_EXTERN_METHOD(getTracks : (nonnull NSNumber *)node resolve : (
RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(setAllowsExternalPlayback : (nonnull NSNumber *)
node allows : (BOOL)allows)
RCT_EXTERN_METHOD(setUsesExternalPlaybackWhileExternalScreenIsActive : (
nonnull NSNumber *)node uses : (BOOL)uses)
RCT_EXTERN_METHOD(getAirPlayState : (nonnull NSNumber *)node resolve : (
RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(showAirPlayPicker : (nonnull NSNumber *)node)
// Dummy
@interface KSPlayerManager : NSObject
@end
@interface RCT_EXTERN_MODULE (KSPlayerModule, RCTEventEmitter)
RCT_EXTERN_METHOD(getTracks : (NSNumber *)nodeTag resolve : (
RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(getAirPlayState : (NSNumber *)nodeTag resolve : (
RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(showAirPlayPicker : (NSNumber *)nodeTag)
@implementation KSPlayerManager
@end

View file

@ -1,71 +1,7 @@
//
// KSPlayerModule.swift
// Nuvio
//
// Created by KSPlayer integration
//
import Foundation
import KSPlayer
import React
@objc(KSPlayerModule)
class KSPlayerModule: RCTEventEmitter {
override static func requiresMainQueueSetup() -> Bool {
return true
}
override func supportedEvents() -> [String]! {
return [
"KSPlayer-onLoad",
"KSPlayer-onProgress",
"KSPlayer-onBuffering",
"KSPlayer-onEnd",
"KSPlayer-onError"
]
}
@objc func getTracks(_ nodeTag: NSNumber?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
guard let nodeTag = nodeTag else {
reject("INVALID_ARGUMENT", "nodeTag must not be nil", nil)
return
}
DispatchQueue.main.async {
if let viewManager = self.bridge.module(for: KSPlayerViewManager.self) as? KSPlayerViewManager {
viewManager.getTracks(nodeTag, resolve: resolve, reject: reject)
} else {
reject("NO_VIEW_MANAGER", "KSPlayerViewManager not found", nil)
}
}
}
@objc func getAirPlayState(_ nodeTag: NSNumber?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
guard let nodeTag = nodeTag else {
reject("INVALID_ARGUMENT", "nodeTag must not be nil", nil)
return
}
DispatchQueue.main.async {
if let viewManager = self.bridge.module(for: KSPlayerViewManager.self) as? KSPlayerViewManager {
viewManager.getAirPlayState(nodeTag, resolve: resolve, reject: reject)
} else {
reject("NO_VIEW_MANAGER", "KSPlayerViewManager not found", nil)
}
}
}
@objc func showAirPlayPicker(_ nodeTag: NSNumber?) {
guard let nodeTag = nodeTag else {
print("[KSPlayerModule] showAirPlayPicker called with nil nodeTag")
return
}
print("[KSPlayerModule] showAirPlayPicker called for nodeTag: \(nodeTag)")
DispatchQueue.main.async {
if let viewManager = self.bridge.module(for: KSPlayerViewManager.self) as? KSPlayerViewManager {
print("[KSPlayerModule] Found KSPlayerViewManager, calling showAirPlayPicker")
viewManager.showAirPlayPicker(nodeTag)
} else {
print("[KSPlayerModule] Could not find KSPlayerViewManager")
}
}
}
class KSPlayerModule: NSObject {
// Dummy class
}

File diff suppressed because it is too large Load diff

View file

@ -1,152 +1,9 @@
//
// KSPlayerViewManager.swift
// Nuvio
//
// Created by KSPlayer integration
//
import Foundation
import KSPlayer
import React
@objc(KSPlayerViewManager)
class KSPlayerViewManager: RCTViewManager {
// Not needed for RCTViewManager-based views; events are exported via Objective-C externs in KSPlayerManager.m
override func view() -> UIView! {
let view = KSPlayerView()
view.viewManager = self
return view
}
override static func requiresMainQueueSetup() -> Bool {
return true
}
override func constantsToExport() -> [AnyHashable : Any]! {
return [
"EventTypes": [
"onLoad": "onLoad",
"onProgress": "onProgress",
"onBuffering": "onBuffering",
"onEnd": "onEnd",
"onError": "onError",
"onBufferingProgress": "onBufferingProgress"
]
]
}
// No-op: events are sent via direct event blocks on the view
@objc func seek(_ node: NSNumber, toTime time: NSNumber) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
view.seek(to: TimeInterval(truncating: time))
}
}
}
@objc func setSource(_ node: NSNumber, source: NSDictionary) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
view.setSource(source)
}
}
}
@objc func setPaused(_ node: NSNumber, paused: Bool) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
view.setPaused(paused)
}
}
}
@objc func setVolume(_ node: NSNumber, volume: NSNumber) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
view.setVolume(Float(truncating: volume))
}
}
}
@objc func setPlaybackRate(_ node: NSNumber, rate: NSNumber) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
view.setPlaybackRate(Float(truncating: rate))
}
}
}
@objc func setAudioTrack(_ node: NSNumber, trackId: NSNumber) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
view.setAudioTrack(Int(truncating: trackId))
}
}
}
@objc func setTextTrack(_ node: NSNumber, trackId: NSNumber) {
NSLog("[KSPlayerViewManager] setTextTrack called - node: %@, trackId: %@", node, trackId)
DispatchQueue.main.async {
NSLog("[KSPlayerViewManager] setTextTrack on main queue - looking for view with tag: %@", node)
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
NSLog("[KSPlayerViewManager] Found view, calling setTextTrack(%d)", Int(truncating: trackId))
view.setTextTrack(Int(truncating: trackId))
} else {
NSLog("[KSPlayerViewManager] ERROR - Could not find KSPlayerView for tag: %@", node)
}
}
}
@objc func getTracks(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
let tracks = view.getAvailableTracks()
resolve(tracks)
} else {
reject("NO_VIEW", "KSPlayerView not found", nil)
}
}
}
// AirPlay methods
@objc func setAllowsExternalPlayback(_ node: NSNumber, allows: Bool) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
view.setAllowsExternalPlayback(allows)
}
}
}
@objc func setUsesExternalPlaybackWhileExternalScreenIsActive(_ node: NSNumber, uses: Bool) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
view.setUsesExternalPlaybackWhileExternalScreenIsActive(uses)
}
}
}
@objc func getAirPlayState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
let airPlayState = view.getAirPlayState()
resolve(airPlayState)
} else {
reject("NO_VIEW", "KSPlayerView not found", nil)
}
}
}
@objc func showAirPlayPicker(_ node: NSNumber) {
print("[KSPlayerViewManager] showAirPlayPicker called for node: \(node)")
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: node) as? KSPlayerView {
print("[KSPlayerViewManager] Found KSPlayerView, calling showAirPlayPicker")
view.showAirPlayPicker()
} else {
print("[KSPlayerViewManager] Could not find KSPlayerView for node: \(node)")
}
}
return UIView()
}
}

View file

@ -11,25 +11,24 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2AA769395C1242F225F875AF /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E007C0BAC8C453623E81663 /* ExpoModulesProvider.swift */; };
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
72D4090694139E0DAD9B066E /* libPods-Nuvio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 406CD0CEF46F8EAEEAD92BF7 /* libPods-Nuvio.a */; };
9FBA88F42E86ECD700892850 /* KSPlayerViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBA88F32E86ECD700892850 /* KSPlayerViewManager.swift */; };
9FBA88F52E86ECD700892850 /* KSPlayerModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBA88F12E86ECD700892850 /* KSPlayerModule.swift */; };
9FBA88F62E86ECD700892850 /* KSPlayerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FBA88F02E86ECD700892850 /* KSPlayerManager.m */; };
9FBA88F72E86ECD700892850 /* KSPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBA88F22E86ECD700892850 /* KSPlayerView.swift */; };
AAF134563EB3D8215E6C78A4 /* libPods-Nuvio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F068B5484E93EC5339E5A99 /* libPods-Nuvio.a */; };
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0F068B5484E93EC5339E5A99 /* libPods-Nuvio.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Nuvio.a"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07F961A680F5B00A75B9A /* Nuvio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Nuvio.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Nuvio/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Nuvio/Info.plist; sourceTree = "<group>"; };
15864A7148A4384BAA9F0B37 /* Pods-Nuvio.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Nuvio.release.xcconfig"; path = "Target Support Files/Pods-Nuvio/Pods-Nuvio.release.xcconfig"; sourceTree = "<group>"; };
406CD0CEF46F8EAEEAD92BF7 /* libPods-Nuvio.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Nuvio.a"; sourceTree = BUILT_PRODUCTS_DIR; };
49055D6E250FAFA21141FE49 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = Nuvio/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
6E007C0BAC8C453623E81663 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Nuvio/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
73BB213C2E9EEAC700EC03F8 /* NuvioRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = NuvioRelease.entitlements; path = Nuvio/NuvioRelease.entitlements; sourceTree = "<group>"; };
819F6DCD44DFE0C72440FDCF /* Pods-Nuvio.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Nuvio.debug.xcconfig"; path = "Target Support Files/Pods-Nuvio/Pods-Nuvio.debug.xcconfig"; sourceTree = "<group>"; };
9B3F2D0A4890046491D5DDD1 /* Pods-Nuvio.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Nuvio.debug.xcconfig"; path = "Target Support Files/Pods-Nuvio/Pods-Nuvio.debug.xcconfig"; sourceTree = "<group>"; };
9FBA88F02E86ECD700892850 /* KSPlayerManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSPlayerManager.m; sourceTree = "<group>"; };
9FBA88F12E86ECD700892850 /* KSPlayerModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KSPlayerModule.swift; sourceTree = "<group>"; };
9FBA88F22E86ECD700892850 /* KSPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KSPlayerView.swift; sourceTree = "<group>"; };
@ -39,6 +38,7 @@
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
F11748412D0307B40044C1D9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = Nuvio/AppDelegate.swift; sourceTree = "<group>"; };
F11748442D0722820044C1D9 /* Nuvio-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Nuvio-Bridging-Header.h"; path = "Nuvio/Nuvio-Bridging-Header.h"; sourceTree = "<group>"; };
F1238953C01E94C56DF67247 /* Pods-Nuvio.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Nuvio.release.xcconfig"; path = "Target Support Files/Pods-Nuvio/Pods-Nuvio.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -46,7 +46,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
72D4090694139E0DAD9B066E /* libPods-Nuvio.a in Frameworks */,
AAF134563EB3D8215E6C78A4 /* libPods-Nuvio.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -76,7 +76,7 @@
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
406CD0CEF46F8EAEEAD92BF7 /* libPods-Nuvio.a */,
0F068B5484E93EC5339E5A99 /* libPods-Nuvio.a */,
);
name = Frameworks;
sourceTree = "<group>";
@ -131,8 +131,8 @@
D90A3959C97EE9926C513293 /* Pods */ = {
isa = PBXGroup;
children = (
819F6DCD44DFE0C72440FDCF /* Pods-Nuvio.debug.xcconfig */,
15864A7148A4384BAA9F0B37 /* Pods-Nuvio.release.xcconfig */,
9B3F2D0A4890046491D5DDD1 /* Pods-Nuvio.debug.xcconfig */,
F1238953C01E94C56DF67247 /* Pods-Nuvio.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@ -152,15 +152,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Nuvio" */;
buildPhases = (
E060D0359630A7C0F4793812 /* [CP] Check Pods Manifest.lock */,
C708A7EA0807939BB52AB4D0 /* [CP] Check Pods Manifest.lock */,
99A79B70155E84EE1FB7F466 /* [Expo] Configure project */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
9B977D89FE30470F8C59964C /* Upload Debug Symbols to Sentry */,
B84E40F81DF927F34032D68B /* [CP] Embed Pods Frameworks */,
AA47AE6072D35F0490B53926 /* [CP] Copy Pods Resources */,
EED4DF498BAFB9612718127A /* [CP] Embed Pods Frameworks */,
449E4836342F88FF06D87CA6 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -234,45 +234,7 @@
shellPath = /bin/sh;
shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n/bin/sh `\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"` `\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n\n";
};
99A79B70155E84EE1FB7F466 /* [Expo] Configure project */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"$(SRCROOT)/.xcode.env",
"$(SRCROOT)/.xcode.env.local",
"$(SRCROOT)/Nuvio/Nuvio.entitlements",
"$(SRCROOT)/Pods/Target Support Files/Pods-Nuvio/expo-configure-project.sh",
);
name = "[Expo] Configure project";
outputFileListPaths = (
);
outputPaths = (
"$(SRCROOT)/Pods/Target Support Files/Pods-Nuvio/ExpoModulesProvider.swift",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-Nuvio/expo-configure-project.sh\"\n";
};
9B977D89FE30470F8C59964C /* Upload Debug Symbols to Sentry */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Upload Debug Symbols to Sentry";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh `${NODE_BINARY:-node} --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode-debug-files.sh'\"`";
};
AA47AE6072D35F0490B53926 /* [CP] Copy Pods Resources */ = {
449E4836342F88FF06D87CA6 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -288,7 +250,6 @@
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoLocalization/ExpoLocalization_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/KSPlayer/KSPlayer_KSPlayer.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
@ -339,7 +300,6 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoLocalization_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/KSPlayer_KSPlayer.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
@ -384,29 +344,45 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Nuvio/Pods-Nuvio-resources.sh\"\n";
showEnvVarsInLog = 0;
};
B84E40F81DF927F34032D68B /* [CP] Embed Pods Frameworks */ = {
99A79B70155E84EE1FB7F466 /* [Expo] Configure project */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"$(SRCROOT)/.xcode.env",
"$(SRCROOT)/.xcode.env.local",
"$(SRCROOT)/Nuvio/Nuvio.entitlements",
"$(SRCROOT)/Pods/Target Support Files/Pods-Nuvio/expo-configure-project.sh",
);
name = "[Expo] Configure project";
outputFileListPaths = (
);
outputPaths = (
"$(SRCROOT)/Pods/Target Support Files/Pods-Nuvio/ExpoModulesProvider.swift",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-Nuvio/expo-configure-project.sh\"\n";
};
9B977D89FE30470F8C59964C /* Upload Debug Symbols to Sentry */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Nuvio/Pods-Nuvio-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/React-Core-prebuilt/React.framework/React",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ReactNativeDependencies/ReactNativeDependencies.framework/ReactNativeDependencies",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
name = "Upload Debug Symbols to Sentry";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactNativeDependencies.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Nuvio/Pods-Nuvio-frameworks.sh\"\n";
showEnvVarsInLog = 0;
shellScript = "/bin/sh `${NODE_BINARY:-node} --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode-debug-files.sh'\"`";
};
E060D0359630A7C0F4793812 /* [CP] Check Pods Manifest.lock */ = {
C708A7EA0807939BB52AB4D0 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -428,6 +404,28 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
EED4DF498BAFB9612718127A /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Nuvio/Pods-Nuvio-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/React-Core-prebuilt/React.framework/React",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ReactNativeDependencies/ReactNativeDependencies.framework/ReactNativeDependencies",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactNativeDependencies.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Nuvio/Pods-Nuvio-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@ -449,7 +447,7 @@
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 819F6DCD44DFE0C72440FDCF /* Pods-Nuvio.debug.xcconfig */;
baseConfigurationReference = 9B3F2D0A4890046491D5DDD1 /* Pods-Nuvio.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@ -487,7 +485,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 15864A7148A4384BAA9F0B37 /* Pods-Nuvio.release.xcconfig */;
baseConfigurationReference = F1238953C01E94C56DF67247 /* Pods-Nuvio.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@ -507,7 +505,7 @@
"-lc++",
);
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub;
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.app;
PRODUCT_NAME = Nuvio;
SUPPORTS_MACCATALYST = YES;
SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h";

View file

@ -1,110 +1,110 @@
<?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>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Nuvio</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.2.10</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>nuvio</string>
<string>com.nuvio.app</string>
</array>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>exp+nuvio</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>29</string>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSBonjourServices</key>
<array>
<string>_http._tcp</string>
<string>_googlecast._tcp</string>
<string>_CC1AD845._googlecast._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>Allow $(PRODUCT_NAME) to access your local network</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app does not require microphone access.</string>
<key>RCTNewArchEnabled</key>
<true/>
<key>RCTRootViewBackgroundColor</key>
<integer>4278322180</integer>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>SplashScreen</string>
<key>UILaunchScreen</key>
<dict>
<key>UIColorName</key>
<string>SplashScreenBackground</string>
<key>UIImageName</key>
<string>SplashScreenLegacy</string>
</dict>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UIRequiresFullScreen</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIUserInterfaceStyle</key>
<string>Dark</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Nuvio</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.3.4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>nuvio</string>
<string>com.nuvio.app</string>
</array>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>exp+nuvio</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>32</string>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSBonjourServices</key>
<array>
<string>_http._tcp</string>
<string>_googlecast._tcp</string>
<string>_CC1AD845._googlecast._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>Nuvio uses the local network to discover Cast-enabled devices on your WiFi network and to connect to local media servers.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app does not require microphone access.</string>
<key>RCTNewArchEnabled</key>
<true/>
<key>RCTRootViewBackgroundColor</key>
<integer>4278322180</integer>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchScreen</key>
<dict>
<key>UIColorName</key>
<string>SplashScreenBackground</string>
<key>UIImageName</key>
<string>SplashScreenLegacy</string>
</dict>
<key>UILaunchStoryboardName</key>
<string>SplashScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UIRequiresFullScreen</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIUserInterfaceStyle</key>
<string>Dark</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View file

@ -9,7 +9,7 @@
<key>EXUpdatesLaunchWaitMs</key>
<integer>30000</integer>
<key>EXUpdatesRuntimeVersion</key>
<string>1.2.11</string>
<string>1.3.4</string>
<key>EXUpdatesURL</key>
<string>https://ota.nuvioapp.space/api/manifest</string>
</dict>

View file

@ -50,10 +50,13 @@ target 'Nuvio' do
)
# KSPlayer dependencies
pod 'KSPlayer', :git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'main'
pod 'DisplayCriteria', :git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'main', :modular_headers => true
pod 'FFmpegKit', :git => 'https://github.com/kingslay/FFmpegKit.git', :branch => 'main', :modular_headers => true
pod 'Libass', :git => 'https://github.com/kingslay/FFmpegKit.git', :branch => 'main'
# pod 'KSPlayer', :git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'main'
# pod 'DisplayCriteria', :git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'main', :modular_headers => true
# pod 'FFmpegKit', :git => 'https://github.com/kingslay/FFmpegKit.git', :branch => 'main', :modular_headers => true
# pod 'Libass', :git => 'https://github.com/kingslay/FFmpegKit.git', :branch => 'main'
# MPVKit (Local)
pod 'MPVKit', :path => '../MPVKit'
post_install do |installer|
react_native_post_install(

View file

@ -1,5 +1,4 @@
PODS:
- DisplayCriteria (1.1.0)
- EASClient (1.0.8):
- ExpoModulesCore
- EXApplication (7.0.8):
@ -323,46 +322,12 @@ PODS:
- EXUpdatesInterface (2.0.0):
- ExpoModulesCore
- FBLazyVector (0.81.4)
- FFmpegKit (6.1.0):
- FFmpegKit/FFmpegKit (= 6.1.0)
- FFmpegKit/FFmpegKit (6.1.0):
- Libass
- google-cast-sdk (4.8.4)
- hermes-engine (0.81.4):
- hermes-engine/Pre-built (= 0.81.4)
- hermes-engine/Pre-built (0.81.4)
- ImageColors (2.5.1):
- ExpoModulesCore
- KSPlayer (1.1.0):
- KSPlayer/Audio (= 1.1.0)
- KSPlayer/AVPlayer (= 1.1.0)
- KSPlayer/Core (= 1.1.0)
- KSPlayer/MEPlayer (= 1.1.0)
- KSPlayer/Metal (= 1.1.0)
- KSPlayer/Subtitle (= 1.1.0)
- KSPlayer/SwiftUI (= 1.1.0)
- KSPlayer/Video (= 1.1.0)
- KSPlayer/Audio (1.1.0):
- KSPlayer/Core
- KSPlayer/AVPlayer (1.1.0):
- DisplayCriteria
- KSPlayer/Core (1.1.0):
- KSPlayer/AVPlayer
- KSPlayer/MEPlayer (1.1.0):
- FFmpegKit
- KSPlayer/AVPlayer
- KSPlayer/Metal
- KSPlayer/Subtitle
- KSPlayer/Metal (1.1.0)
- KSPlayer/Subtitle (1.1.0)
- KSPlayer/SwiftUI (1.1.0):
- KSPlayer/AVPlayer
- KSPlayer/Video (1.1.0):
- KSPlayer/Core
- KSPlayer/Subtitle
- Libass (0.17.1):
- Libass/Libass (= 0.17.1)
- Libass/Libass (0.17.1)
- libavif/core (0.11.1)
- libavif/libdav1d (0.11.1):
- libavif/core
@ -405,6 +370,8 @@ PODS:
- ReactNativeDependencies
- Yoga
- MMKVCore (2.2.4)
- MPVKit (0.0.1):
- React-Core
- NitroMmkv (4.1.0):
- hermes-engine
- MMKVCore (= 2.2.4)
@ -2760,7 +2727,6 @@ PODS:
- Yoga (0.0.0)
DEPENDENCIES:
- DisplayCriteria (from `https://github.com/kingslay/KSPlayer.git`, branch `main`)
- EASClient (from `../node_modules/expo-eas-client/ios`)
- EXApplication (from `../node_modules/expo-application/ios`)
- EXConstants (from `../node_modules/expo-constants/ios`)
@ -2797,12 +2763,10 @@ DEPENDENCIES:
- EXUpdates (from `../node_modules/expo-updates/ios`)
- EXUpdatesInterface (from `../node_modules/expo-updates-interface/ios`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FFmpegKit (from `https://github.com/kingslay/FFmpegKit.git`, branch `main`)
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
- ImageColors (from `../node_modules/react-native-image-colors/ios`)
- KSPlayer (from `https://github.com/kingslay/KSPlayer.git`, branch `main`)
- Libass (from `https://github.com/kingslay/FFmpegKit.git`, branch `main`)
- lottie-react-native (from `../node_modules/lottie-react-native`)
- MPVKit (from `../MPVKit`)
- NitroMmkv (from `../node_modules/react-native-mmkv`)
- NitroModules (from `../node_modules/react-native-nitro-modules`)
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
@ -2909,9 +2873,6 @@ SPEC REPOS:
- SwiftUIIntrospect
EXTERNAL SOURCES:
DisplayCriteria:
:branch: main
:git: https://github.com/kingslay/KSPlayer.git
EASClient:
:path: "../node_modules/expo-eas-client/ios"
EXApplication:
@ -2984,22 +2945,15 @@ EXTERNAL SOURCES:
:path: "../node_modules/expo-updates-interface/ios"
FBLazyVector:
:path: "../node_modules/react-native/Libraries/FBLazyVector"
FFmpegKit:
:branch: main
:git: https://github.com/kingslay/FFmpegKit.git
hermes-engine:
:podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
:tag: hermes-2025-07-07-RNv0.81.0-e0fc67142ec0763c6b6153ca2bf96df815539782
ImageColors:
:path: "../node_modules/react-native-image-colors/ios"
KSPlayer:
:branch: main
:git: https://github.com/kingslay/KSPlayer.git
Libass:
:branch: main
:git: https://github.com/kingslay/FFmpegKit.git
lottie-react-native:
:path: "../node_modules/lottie-react-native"
MPVKit:
:path: "../MPVKit"
NitroMmkv:
:path: "../node_modules/react-native-mmkv"
NitroModules:
@ -3173,22 +3127,7 @@ EXTERNAL SOURCES:
Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga"
CHECKOUT OPTIONS:
DisplayCriteria:
:commit: a7cddd878f557afa6a1f2faad9d756949406adde
:git: https://github.com/kingslay/KSPlayer.git
FFmpegKit:
:commit: d7048037a2eb94a3b08113fbf43aa92bdcb332d9
:git: https://github.com/kingslay/FFmpegKit.git
KSPlayer:
:commit: a7cddd878f557afa6a1f2faad9d756949406adde
:git: https://github.com/kingslay/KSPlayer.git
Libass:
:commit: d7048037a2eb94a3b08113fbf43aa92bdcb332d9
:git: https://github.com/kingslay/FFmpegKit.git
SPEC CHECKSUMS:
DisplayCriteria: bb0a90faf14b30848bc50ac0516340ce50164187
EASClient: 40dd9e740684782610c49becab2643782ea1a20c
EXApplication: 1e98d4b1dccdf30627f92917f4b2c5a53c330e5f
EXConstants: 805f35b1b295c542ca6acce836f21a1f9ee104d5
@ -3225,18 +3164,16 @@ SPEC CHECKSUMS:
EXUpdates: f20abbc8a9f4e150656fe88126d52f52d4e7793f
EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734
FBLazyVector: 9e0cd874afd81d9a4d36679daca991b58b260d42
FFmpegKit: 3885085fbbc320745838ee4c8a1f9c5e5953dab2
google-cast-sdk: 32f65af50d164e3c475e79ad123db3cc26fbcd37
hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394
ImageColors: e12eb73e29bc1feaa3c228db8c174a1b25acb59d
KSPlayer: f163ac6195f240b6fa5b8225aeb39ec811a70c62
Libass: e88af2324e1217e3a4c8bdc675f6f23a9dfc7677
libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
lottie-ios: a881093fab623c467d3bce374367755c272bdd59
lottie-react-native: cbe3d931a7c24f7891a8e8032c2bb9b2373c4b9c
MMKVCore: f2dd4c9befea04277a55e84e7812f930537993df
MPVKit: 25ac17c12586bbd3aab014c6a281f6981c3fb6cf
NitroMmkv: 4af10c70043b4c3cded3f16547627c7d9d8e3b8b
NitroModules: a71a5ab2911caf79e45170e6e12475b5260a12d0
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
@ -3332,6 +3269,6 @@ SPEC CHECKSUMS:
SwiftUIIntrospect: fee9aa07293ee280373a591e1824e8ddc869ba5d
Yoga: 051f086b5ccf465ff2ed38a2cf5a558ae01aaaa1
PODFILE CHECKSUM: 7c74c9cd2c7f3df7ab68b4284d9f324282e54542
PODFILE CHECKSUM: c5d7e008c41725ad58da009620905f13109dc39a
COCOAPODS: 1.16.2

View file

@ -3,4 +3,4 @@
"EX_DEV_CLIENT_NETWORK_INSPECTOR": "true",
"newArchEnabled": "true",
"ios.deploymentTarget": "16.0"
}
}

View file

@ -0,0 +1,55 @@
import React, { useRef, useImperativeHandle, forwardRef, useEffect } from 'react';
import { requireNativeComponent, UIManager, findNodeHandle, ViewStyle } from 'react-native';
interface MPVPlayerProps {
source?: {
uri: string;
headers?: Record<string, string>;
};
paused?: boolean;
volume?: number;
rate?: number;
style?: ViewStyle;
onLoad?: (event: any) => void;
onProgress?: (event: any) => void;
onEnd?: (event: any) => void;
onError?: (event: any) => void;
}
export interface MPVPlayerRef {
seek: (time: number) => void;
}
const ComponentName = 'MPVPlayerView';
const MPVPlayerView = requireNativeComponent<MPVPlayerProps>(ComponentName);
const MPVPlayerComponent = forwardRef<MPVPlayerRef, MPVPlayerProps>((props, ref) => {
const nativeRef = useRef<any>(null);
useImperativeHandle(ref, () => ({
seek: (time: number) => {
if (nativeRef.current) {
const node = findNodeHandle(nativeRef.current);
UIManager.dispatchViewManagerCommand(
node,
// @ts-ignore
UIManager.getViewManagerConfig(ComponentName).Commands.seek,
[time]
);
}
},
}));
return (
<MPVPlayerView
ref={nativeRef}
{...props}
onLoad={(e: any) => props.onLoad?.(e.nativeEvent)}
onProgress={(e: any) => props.onProgress?.(e.nativeEvent)}
onEnd={(e: any) => props.onEnd?.(e.nativeEvent)}
onError={(e: any) => props.onError?.(e.nativeEvent)}
/>
);
});
export default MPVPlayerComponent;

View file

@ -1,10 +1,12 @@
import React, { useRef } from 'react';
import { Animated } from 'react-native';
import { PinchGestureHandler, State, PinchGestureHandlerGestureEvent } from 'react-native-gesture-handler';
import KSPlayerComponent, { KSPlayerRef, KSPlayerSource } from '../../KSPlayerComponent';
import MPVPlayerComponent from '../../MPVPlayerComponent';
import { MPVPlayerRef } from '../../MPVPlayerComponent';
interface KSPlayerSurfaceProps {
ksPlayerRef: React.RefObject<KSPlayerRef>;
ksPlayerRef: React.RefObject<any>;
uri: string;
headers?: Record<string, string>;
paused: boolean;
@ -91,12 +93,6 @@ export const KSPlayerSurface: React.FC<KSPlayerSurfaceProps> = ({
}
};
// Create source object for KSPlayerComponent
const source: KSPlayerSource = {
uri,
headers
};
// Debug: log textTrack prop changes
React.useEffect(() => {
console.log('[KSPlayerSurface] textTrack prop changed to:', textTrack);
@ -133,26 +129,20 @@ export const KSPlayerSurface: React.FC<KSPlayerSurfaceProps> = ({
justifyContent: 'center',
transform: [{ scale: zoomScale }]
}}>
<KSPlayerComponent
ref={ksPlayerRef}
source={source}
<MPVPlayerComponent
ref={ksPlayerRef as any}
source={{ uri, headers }}
paused={paused}
volume={volume}
rate={playbackSpeed}
resizeMode={resizeMode}
audioTrack={audioTrack}
textTrack={textTrack}
subtitleTextColor={subtitleTextColor}
subtitleBackgroundColor={subtitleBackgroundColor}
subtitleFontSize={subtitleFontSize}
subtitleBottomOffset={subtitleBottomOffset}
style={customVideoStyles.width ? customVideoStyles : { width: screenWidth, height: screenHeight }}
onLoad={handleLoad}
onProgress={onProgress}
onBuffering={handleBuffering}
onEnd={onEnd}
onError={onError}
style={customVideoStyles.width ? customVideoStyles : { width: screenWidth, height: screenHeight }}
/>
</Animated.View>
</PinchGestureHandler>
);