mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 00:32:04 +00:00
update trailer extraction
This commit is contained in:
parent
fb0805324d
commit
8f371215e9
16 changed files with 2886 additions and 692 deletions
10
app.json
10
app.json
|
|
@ -33,7 +33,15 @@
|
||||||
"audio"
|
"audio"
|
||||||
],
|
],
|
||||||
"LSSupportsOpeningDocumentsInPlace": true,
|
"LSSupportsOpeningDocumentsInPlace": true,
|
||||||
"UIFileSharingEnabled": true
|
"UIFileSharingEnabled": true,
|
||||||
|
"LSApplicationQueriesSchemes": [
|
||||||
|
"vlc",
|
||||||
|
"vlc-x-callback",
|
||||||
|
"infuse",
|
||||||
|
"outplayer",
|
||||||
|
"open-vidhub",
|
||||||
|
"livecontainer"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"bundleIdentifier": "com.nuvio.hub",
|
"bundleIdentifier": "com.nuvio.hub",
|
||||||
"associatedDomains": [],
|
"associatedDomains": [],
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,7 @@
|
||||||
<key>NSExtensionPointIdentifier</key>
|
<key>NSExtensionPointIdentifier</key>
|
||||||
<string>com.apple.widgetkit-extension</string>
|
<string>com.apple.widgetkit-extension</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>RCTNewArchEnabled</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
|
|
@ -7,147 +7,77 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
0FFC28FB1FEA74CCFA112268 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 49055D6E250FAFA21141FE49 /* PrivacyInfo.xcprivacy */; };
|
0512F937B36046F581AF6A55 /* View+applyIfPresent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65BDE00720574797863FA748 /* View+applyIfPresent.swift */; };
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
2AA769395C1242F225F875AF /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E007C0BAC8C453623E81663 /* ExpoModulesProvider.swift */; };
|
24FC08E856045AC6A95D753A /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 495FF0F91AFAF8A860B9D485 /* PrivacyInfo.xcprivacy */; };
|
||||||
|
357A8847EA6B42B792A617D4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 348452A2DFC344C2BC70A974 /* Assets.xcassets */; };
|
||||||
|
3A4B91216E8D486E9000CD6C /* Date+toTimerInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A20BAB83F6E40D880665E14 /* Date+toTimerInterval.swift */; };
|
||||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
||||||
730F1CDE2F24B27100EF7E51 /* Color+hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8034143A77A946B5A793F967 /* Color+hex.swift */; };
|
4F1568831D134295A56C0263 /* LiveActivityWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B775F1944CB4E2EB043DB23 /* LiveActivityWidgetBundle.swift */; };
|
||||||
730F1CDF2F24B27100EF7E51 /* Date+toTimerInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A48D8A298DD48928E8D0A02 /* Date+toTimerInterval.swift */; };
|
7069406A1E324608A86CC6C9 /* ViewHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D296491CC4F4406182E2A2BC /* ViewHelpers.swift */; };
|
||||||
730F1CE02F24B27100EF7E51 /* Image+dynamic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26957CDD392E4E9390811D0D /* Image+dynamic.swift */; };
|
94F843501BFD40C384CBB500 /* View+applyWidgetURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0AC8A8984F4495492E13EFD /* View+applyWidgetURL.swift */; };
|
||||||
730F1CE12F24B27100EF7E51 /* LiveActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F448294A36E433E924078C1 /* LiveActivityView.swift */; };
|
9BE191900481495083B7ECC1 /* Color+hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = B36264437D84461BBC2BB706 /* Color+hex.swift */; };
|
||||||
730F1CE22F24B27100EF7E51 /* LiveActivityWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD48662BB71E4C9C9E340289 /* LiveActivityWidget.swift */; };
|
B3BB1BBDA8C742DC9A32EACF /* Image+dynamic.swift in Sources */ = {isa = PBXBuildFile; fileRef = F03926C841844CC38C468345 /* Image+dynamic.swift */; };
|
||||||
730F1CE32F24B27100EF7E51 /* LiveActivityWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83D742B36224176A0AB3B25 /* LiveActivityWidgetBundle.swift */; };
|
|
||||||
730F1CE42F24B27100EF7E51 /* View+applyIfPresent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 324373F393774A9CA40DE22E /* View+applyIfPresent.swift */; };
|
|
||||||
730F1CE52F24B27100EF7E51 /* View+applyWidgetURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373D1473F5A74CBC9DBD108B /* View+applyWidgetURL.swift */; };
|
|
||||||
730F1CE62F24B27100EF7E51 /* ViewHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3396D68881EF486E99FD480A /* ViewHelpers.swift */; };
|
|
||||||
730F1CE72F24B27100EF7E51 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0F1D0037D1F24E60BDB57628 /* Assets.xcassets */; };
|
|
||||||
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 */; };
|
|
||||||
A0892AA96024D9EF7CA87A8A /* libPods-Nuvio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 349BFD3B214640DED8541999 /* libPods-Nuvio.a */; };
|
|
||||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
||||||
|
BD4FE0C298E078EA08432C75 /* libPods-Nuvio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7206543A5AAE2788326BFBC7 /* libPods-Nuvio.a */; };
|
||||||
|
D102CD3E3CCC4B83AC0F4DBE /* LiveActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3182DD61A7C04BD383DBB4B0 /* LiveActivityView.swift */; };
|
||||||
|
DEB0D346CF964886AD06A268 /* LiveActivityWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C77B925A48A4711B3B59C6A /* LiveActivityWidget.swift */; };
|
||||||
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
|
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
|
||||||
F285A1620F5847BA863124AF /* LiveActivity.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = EF8716173E0148BD82B233B7 /* LiveActivity.appex */; };
|
F1924CDEBB5847D8A1AFD925 /* LiveActivity.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 37E2BF6107484CD098F81560 /* LiveActivity.appex */; };
|
||||||
797799D4F9144A9E8D2AB90D /* LiveActivity.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 49DDF70A2BBD4320BBD94B1B /* LiveActivity.appex */; };
|
F4B2944DA5D06650F3B40F2A /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9B2F28305B8518622853186 /* ExpoModulesProvider.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
55A0DD628D7F4F4F88B4A001 /* PBXContainerItemProxy */ = {
|
DBC6C07FF91444EEAB5F4C66 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||||
proxyType = 1;
|
proxyType = 1;
|
||||||
remoteGlobalIDString = 0EA489F2BF6143F1BA7B8485;
|
remoteGlobalIDString = BB0FA6CBF7FD404994DB1E52;
|
||||||
remoteInfo = LiveActivity;
|
|
||||||
};
|
|
||||||
7A41A1F529994F0C8801F1A5 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = EFB756D21A05453EA489278C;
|
|
||||||
remoteInfo = LiveActivity;
|
remoteInfo = LiveActivity;
|
||||||
};
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
13CD9594FB5C4FE4A6794089 /* Embed Foundation Extensions */ = {
|
8773BA7C99F44506A4A25842 /* Embed Foundation Extensions */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 13;
|
dstSubfolderSpec = 13;
|
||||||
files = (
|
files = (
|
||||||
797799D4F9144A9E8D2AB90D /* LiveActivity.appex in Embed Foundation Extensions */,
|
F1924CDEBB5847D8A1AFD925 /* LiveActivity.appex in Embed Foundation Extensions */,
|
||||||
);
|
);
|
||||||
name = "Embed Foundation Extensions";
|
name = "Embed Foundation Extensions";
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
3447F08B99D9427E99FEE18E /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXCopyFilesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
dstPath = "";
|
|
||||||
dstSubfolderSpec = 13;
|
|
||||||
files = (
|
|
||||||
F285A1620F5847BA863124AF /* LiveActivity.appex in Embed Foundation Extensions */,
|
|
||||||
);
|
|
||||||
name = "Embed Foundation Extensions";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
571AD3FB23F14FC7BE6A1E44 /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXCopyFilesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
dstPath = "";
|
|
||||||
dstSubfolderSpec = 13;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
name = "Embed Foundation Extensions";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
BDCAC5D772944755921F3BCF /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXCopyFilesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
dstPath = "";
|
|
||||||
dstSubfolderSpec = 13;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
name = "Embed Foundation Extensions";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
F1058FE7710A45FABC0689A7 /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXCopyFilesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
dstPath = "";
|
|
||||||
dstSubfolderSpec = 13;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
name = "Embed Foundation Extensions";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
CC1B793274FE428D8531E950 /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXCopyFilesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
name = "Embed Foundation Extensions";
|
|
||||||
dstPath = "";
|
|
||||||
dstSubfolderSpec = 13;
|
|
||||||
};
|
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
0DFF64A670930CED5EA4DF3A /* 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>"; };
|
0E5AC167979645D9ADB47923 /* LiveActivity.entitlements */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = LiveActivity.entitlements; path = LiveActivity.entitlements; sourceTree = "<group>"; };
|
||||||
0E13CE4BDE2F4555806AE753 /* Info.plist */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
||||||
0F1D0037D1F24E60BDB57628 /* Assets.xcassets */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
|
||||||
13B07F961A680F5B00A75B9A /* Nuvio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Nuvio.app; 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>"; };
|
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>"; };
|
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Nuvio/Info.plist; sourceTree = "<group>"; };
|
||||||
26957CDD392E4E9390811D0D /* Image+dynamic.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = "Image+dynamic.swift"; sourceTree = "<group>"; };
|
1B775F1944CB4E2EB043DB23 /* LiveActivityWidgetBundle.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = LiveActivityWidgetBundle.swift; path = LiveActivityWidgetBundle.swift; sourceTree = "<group>"; };
|
||||||
2DE29A8A87D24662BEFFF849 /* LiveActivity.entitlements */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; path = LiveActivity.entitlements; sourceTree = "<group>"; };
|
3182DD61A7C04BD383DBB4B0 /* LiveActivityView.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = LiveActivityView.swift; path = LiveActivityView.swift; sourceTree = "<group>"; };
|
||||||
2F448294A36E433E924078C1 /* LiveActivityView.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = LiveActivityView.swift; sourceTree = "<group>"; };
|
348452A2DFC344C2BC70A974 /* Assets.xcassets */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
324373F393774A9CA40DE22E /* View+applyIfPresent.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = "View+applyIfPresent.swift"; sourceTree = "<group>"; };
|
37E2BF6107484CD098F81560 /* LiveActivity.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = undefined; name = LiveActivity.appex; path = LiveActivity.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
3396D68881EF486E99FD480A /* ViewHelpers.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = ViewHelpers.swift; sourceTree = "<group>"; };
|
3A20BAB83F6E40D880665E14 /* Date+toTimerInterval.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "Date+toTimerInterval.swift"; path = "Date+toTimerInterval.swift"; sourceTree = "<group>"; };
|
||||||
349BFD3B214640DED8541999 /* libPods-Nuvio.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Nuvio.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
44393AD0ABDBAED5B40D2E49 /* 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>"; };
|
||||||
373D1473F5A74CBC9DBD108B /* View+applyWidgetURL.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = "View+applyWidgetURL.swift"; sourceTree = "<group>"; };
|
495FF0F91AFAF8A860B9D485 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Nuvio/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||||
3A48D8A298DD48928E8D0A02 /* Date+toTimerInterval.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = "Date+toTimerInterval.swift"; sourceTree = "<group>"; };
|
65BDE00720574797863FA748 /* View+applyIfPresent.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "View+applyIfPresent.swift"; path = "View+applyIfPresent.swift"; sourceTree = "<group>"; };
|
||||||
49055D6E250FAFA21141FE49 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = Nuvio/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
7206543A5AAE2788326BFBC7 /* libPods-Nuvio.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Nuvio.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
6E007C0BAC8C453623E81663 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Nuvio/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
|
7EC866223BB0FA7280D468BF /* 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>"; };
|
||||||
730F1CE82F24B29C00EF7E51 /* LiveActivityDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LiveActivityDebug.entitlements; sourceTree = "<group>"; };
|
9C77B925A48A4711B3B59C6A /* LiveActivityWidget.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = LiveActivityWidget.swift; path = LiveActivityWidget.swift; sourceTree = "<group>"; };
|
||||||
73BB213C2E9EEAC700EC03F8 /* NuvioRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = NuvioRelease.entitlements; path = Nuvio/NuvioRelease.entitlements; sourceTree = "<group>"; };
|
A0AC8A8984F4495492E13EFD /* View+applyWidgetURL.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "View+applyWidgetURL.swift"; path = "View+applyWidgetURL.swift"; sourceTree = "<group>"; };
|
||||||
8034143A77A946B5A793F967 /* Color+hex.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = "Color+hex.swift"; sourceTree = "<group>"; };
|
|
||||||
9FBA88F02E86ECD700892850 /* KSPlayerManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ../KSPlayer/RNBridge/KSPlayerManager.m; sourceTree = "<group>"; };
|
|
||||||
9FBA88F12E86ECD700892850 /* KSPlayerModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ../KSPlayer/RNBridge/KSPlayerModule.swift; sourceTree = "<group>"; };
|
|
||||||
9FBA88F22E86ECD700892850 /* KSPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ../KSPlayer/RNBridge/KSPlayerView.swift; sourceTree = "<group>"; };
|
|
||||||
9FBA88F32E86ECD700892850 /* KSPlayerViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ../KSPlayer/RNBridge/KSPlayerViewManager.swift; sourceTree = "<group>"; };
|
|
||||||
A83D742B36224176A0AB3B25 /* LiveActivityWidgetBundle.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = LiveActivityWidgetBundle.swift; sourceTree = "<group>"; };
|
|
||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = Nuvio/SplashScreen.storyboard; sourceTree = "<group>"; };
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = Nuvio/SplashScreen.storyboard; sourceTree = "<group>"; };
|
||||||
AD48662BB71E4C9C9E340289 /* LiveActivityWidget.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; path = LiveActivityWidget.swift; sourceTree = "<group>"; };
|
B36264437D84461BBC2BB706 /* Color+hex.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "Color+hex.swift"; path = "Color+hex.swift"; sourceTree = "<group>"; };
|
||||||
|
B9B2F28305B8518622853186 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Nuvio/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
|
||||||
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
|
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
|
||||||
DAD634845937EAF8D64F20FC /* 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>"; };
|
D296491CC4F4406182E2A2BC /* ViewHelpers.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = ViewHelpers.swift; path = ViewHelpers.swift; sourceTree = "<group>"; };
|
||||||
|
E93B94AE2F7240878D655B2F /* Info.plist */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||||
EF8716173E0148BD82B233B7 /* LiveActivity.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; fileEncoding = 9; includeInIndex = 0; path = LiveActivity.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
F03926C841844CC38C468345 /* Image+dynamic.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "Image+dynamic.swift"; path = "Image+dynamic.swift"; sourceTree = "<group>"; };
|
||||||
F11748412D0307B40044C1D9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = Nuvio/AppDelegate.swift; sourceTree = "<group>"; };
|
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>"; };
|
F11748442D0722820044C1D9 /* Nuvio-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Nuvio-Bridging-Header.h"; path = "Nuvio/Nuvio-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
49DDF70A2BBD4320BBD94B1B /* LiveActivity.appex */ = {isa = PBXFileReference; name = "LiveActivity.appex"; path = "LiveActivity.appex"; sourceTree = BUILT_PRODUCTS_DIR; fileEncoding = undefined; lastKnownFileType = undefined; explicitFileType = wrapper.app-extension; includeInIndex = 0; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
|
@ -155,18 +85,11 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A0892AA96024D9EF7CA87A8A /* libPods-Nuvio.a in Frameworks */,
|
BD4FE0C298E078EA08432C75 /* libPods-Nuvio.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
C105694FF46449959CE16947 /* Frameworks */ = {
|
2341847DAC4A41A89AA0DED2 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
A2537B59C29048BFB082D5F3 /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
|
@ -179,18 +102,13 @@
|
||||||
13B07FAE1A68108700A75B9A /* Nuvio */ = {
|
13B07FAE1A68108700A75B9A /* Nuvio */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
73BB213C2E9EEAC700EC03F8 /* NuvioRelease.entitlements */,
|
|
||||||
F11748412D0307B40044C1D9 /* AppDelegate.swift */,
|
F11748412D0307B40044C1D9 /* AppDelegate.swift */,
|
||||||
F11748442D0722820044C1D9 /* Nuvio-Bridging-Header.h */,
|
F11748442D0722820044C1D9 /* Nuvio-Bridging-Header.h */,
|
||||||
9FBA88F02E86ECD700892850 /* KSPlayerManager.m */,
|
|
||||||
9FBA88F12E86ECD700892850 /* KSPlayerModule.swift */,
|
|
||||||
9FBA88F22E86ECD700892850 /* KSPlayerView.swift */,
|
|
||||||
9FBA88F32E86ECD700892850 /* KSPlayerViewManager.swift */,
|
|
||||||
BB2F792B24A3F905000567C9 /* Supporting */,
|
BB2F792B24A3F905000567C9 /* Supporting */,
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
||||||
49055D6E250FAFA21141FE49 /* PrivacyInfo.xcprivacy */,
|
495FF0F91AFAF8A860B9D485 /* PrivacyInfo.xcprivacy */,
|
||||||
);
|
);
|
||||||
name = Nuvio;
|
name = Nuvio;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -199,23 +117,28 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||||
349BFD3B214640DED8541999 /* libPods-Nuvio.a */,
|
7206543A5AAE2788326BFBC7 /* libPods-Nuvio.a */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
358C5C99C443A921C8EEDDC8 /* ExpoModulesProviders */ = {
|
6BFD9CA52F844119ABE664C4 /* LiveActivity */ = {
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
ECB31D9B6FF08C7E8E875650 /* Nuvio */,
|
|
||||||
);
|
|
||||||
name = ExpoModulesProviders;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
62B088ADB2A740DAB9E343F9 /* LiveActivity */ = {
|
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B36264437D84461BBC2BB706 /* Color+hex.swift */,
|
||||||
|
3A20BAB83F6E40D880665E14 /* Date+toTimerInterval.swift */,
|
||||||
|
F03926C841844CC38C468345 /* Image+dynamic.swift */,
|
||||||
|
3182DD61A7C04BD383DBB4B0 /* LiveActivityView.swift */,
|
||||||
|
9C77B925A48A4711B3B59C6A /* LiveActivityWidget.swift */,
|
||||||
|
1B775F1944CB4E2EB043DB23 /* LiveActivityWidgetBundle.swift */,
|
||||||
|
65BDE00720574797863FA748 /* View+applyIfPresent.swift */,
|
||||||
|
A0AC8A8984F4495492E13EFD /* View+applyWidgetURL.swift */,
|
||||||
|
D296491CC4F4406182E2A2BC /* ViewHelpers.swift */,
|
||||||
|
E93B94AE2F7240878D655B2F /* Info.plist */,
|
||||||
|
348452A2DFC344C2BC70A974 /* Assets.xcassets */,
|
||||||
|
0E5AC167979645D9ADB47923 /* LiveActivity.entitlements */,
|
||||||
);
|
);
|
||||||
|
name = LiveActivity;
|
||||||
path = LiveActivity;
|
path = LiveActivity;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
|
@ -233,14 +156,9 @@
|
||||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||||
83CBBA001A601CBA00E9B192 /* Products */,
|
83CBBA001A601CBA00E9B192 /* Products */,
|
||||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||||
D90A3959C97EE9926C513293 /* Pods */,
|
6BFD9CA52F844119ABE664C4 /* LiveActivity */,
|
||||||
358C5C99C443A921C8EEDDC8 /* ExpoModulesProviders */,
|
94DA158AE0BA28C86D2B8468 /* Pods */,
|
||||||
E8C72B3DF7DB40A8896F56C9 /* LiveActivity */,
|
FD98B8AFFD47909E52F111EF /* ExpoModulesProviders */,
|
||||||
62B088ADB2A740DAB9E343F9 /* LiveActivity */,
|
|
||||||
B9F3EB198DED443D980ADFB3 /* LiveActivity */,
|
|
||||||
C05E525650E143FB85ED7622 /* LiveActivity */,
|
|
||||||
D05210A39FF14E649D77F8A8 /* LiveActivity */,
|
|
||||||
2EAF711C6AB246A0A253E404 /* LiveActivity */,
|
|
||||||
);
|
);
|
||||||
indentWidth = 2;
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -251,17 +169,19 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
13B07F961A680F5B00A75B9A /* Nuvio.app */,
|
13B07F961A680F5B00A75B9A /* Nuvio.app */,
|
||||||
EF8716173E0148BD82B233B7 /* LiveActivity.appex */,
|
37E2BF6107484CD098F81560 /* LiveActivity.appex */,
|
||||||
49DDF70A2BBD4320BBD94B1B /* LiveActivity.appex */,
|
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
B9F3EB198DED443D980ADFB3 /* LiveActivity */ = {
|
94DA158AE0BA28C86D2B8468 /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7EC866223BB0FA7280D468BF /* Pods-Nuvio.debug.xcconfig */,
|
||||||
|
44393AD0ABDBAED5B40D2E49 /* Pods-Nuvio.release.xcconfig */,
|
||||||
);
|
);
|
||||||
path = LiveActivity;
|
name = Pods;
|
||||||
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
BB2F792B24A3F905000567C9 /* Supporting */ = {
|
BB2F792B24A3F905000567C9 /* Supporting */ = {
|
||||||
|
|
@ -273,144 +193,66 @@
|
||||||
path = Nuvio/Supporting;
|
path = Nuvio/Supporting;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C05E525650E143FB85ED7622 /* LiveActivity */ = {
|
E3DA69DC92F44258CBB5D7D2 /* Nuvio */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
);
|
B9B2F28305B8518622853186 /* ExpoModulesProvider.swift */,
|
||||||
path = LiveActivity;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
D05210A39FF14E649D77F8A8 /* LiveActivity */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
8034143A77A946B5A793F967 /* Color+hex.swift */,
|
|
||||||
3A48D8A298DD48928E8D0A02 /* Date+toTimerInterval.swift */,
|
|
||||||
26957CDD392E4E9390811D0D /* Image+dynamic.swift */,
|
|
||||||
2F448294A36E433E924078C1 /* LiveActivityView.swift */,
|
|
||||||
AD48662BB71E4C9C9E340289 /* LiveActivityWidget.swift */,
|
|
||||||
A83D742B36224176A0AB3B25 /* LiveActivityWidgetBundle.swift */,
|
|
||||||
324373F393774A9CA40DE22E /* View+applyIfPresent.swift */,
|
|
||||||
373D1473F5A74CBC9DBD108B /* View+applyWidgetURL.swift */,
|
|
||||||
3396D68881EF486E99FD480A /* ViewHelpers.swift */,
|
|
||||||
0E13CE4BDE2F4555806AE753 /* Info.plist */,
|
|
||||||
0F1D0037D1F24E60BDB57628 /* Assets.xcassets */,
|
|
||||||
2DE29A8A87D24662BEFFF849 /* LiveActivity.entitlements */,
|
|
||||||
);
|
|
||||||
path = LiveActivity;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
D90A3959C97EE9926C513293 /* Pods */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
DAD634845937EAF8D64F20FC /* Pods-Nuvio.debug.xcconfig */,
|
|
||||||
0DFF64A670930CED5EA4DF3A /* Pods-Nuvio.release.xcconfig */,
|
|
||||||
);
|
|
||||||
path = Pods;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
E8C72B3DF7DB40A8896F56C9 /* LiveActivity */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
730F1CE82F24B29C00EF7E51 /* LiveActivityDebug.entitlements */,
|
|
||||||
);
|
|
||||||
path = LiveActivity;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
ECB31D9B6FF08C7E8E875650 /* Nuvio */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
6E007C0BAC8C453623E81663 /* ExpoModulesProvider.swift */,
|
|
||||||
);
|
);
|
||||||
name = Nuvio;
|
name = Nuvio;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
2EAF711C6AB246A0A253E404 /* LiveActivity */ = {
|
FD98B8AFFD47909E52F111EF /* ExpoModulesProviders */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
8034143A77A946B5A793F967 /* Color+hex.swift */,
|
E3DA69DC92F44258CBB5D7D2 /* Nuvio */,
|
||||||
3A48D8A298DD48928E8D0A02 /* Date+toTimerInterval.swift */,
|
|
||||||
26957CDD392E4E9390811D0D /* Image+dynamic.swift */,
|
|
||||||
2F448294A36E433E924078C1 /* LiveActivityView.swift */,
|
|
||||||
AD48662BB71E4C9C9E340289 /* LiveActivityWidget.swift */,
|
|
||||||
A83D742B36224176A0AB3B25 /* LiveActivityWidgetBundle.swift */,
|
|
||||||
324373F393774A9CA40DE22E /* View+applyIfPresent.swift */,
|
|
||||||
373D1473F5A74CBC9DBD108B /* View+applyWidgetURL.swift */,
|
|
||||||
3396D68881EF486E99FD480A /* ViewHelpers.swift */,
|
|
||||||
0E13CE4BDE2F4555806AE753 /* Info.plist */,
|
|
||||||
0F1D0037D1F24E60BDB57628 /* Assets.xcassets */,
|
|
||||||
2DE29A8A87D24662BEFFF849 /* LiveActivity.entitlements */,
|
|
||||||
);
|
);
|
||||||
name = LiveActivity;
|
name = ExpoModulesProviders;
|
||||||
path = LiveActivity;
|
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
0EA489F2BF6143F1BA7B8485 /* LiveActivity */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = C95083D445BA485B82D2FFBC /* Build configuration list for PBXNativeTarget "LiveActivity" */;
|
|
||||||
buildPhases = (
|
|
||||||
6E9A0429F8E74948A82DEFF5 /* Sources */,
|
|
||||||
C105694FF46449959CE16947 /* Frameworks */,
|
|
||||||
1E668E0B92C34E73AECDBE1A /* Resources */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
name = LiveActivity;
|
|
||||||
productName = LiveActivity;
|
|
||||||
productReference = EF8716173E0148BD82B233B7 /* LiveActivity.appex */;
|
|
||||||
productType = "com.apple.product-type.app-extension";
|
|
||||||
};
|
|
||||||
13B07F861A680F5B00A75B9A /* Nuvio */ = {
|
13B07F861A680F5B00A75B9A /* Nuvio */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Nuvio" */;
|
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Nuvio" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
13C7A3175A582B3D4E9F198E /* [CP] Check Pods Manifest.lock */,
|
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */,
|
||||||
99A79B70155E84EE1FB7F466 /* [Expo] Configure project */,
|
B67FC995125067F91F480913 /* [Expo] Configure project */,
|
||||||
13B07F871A680F5B00A75B9A /* Sources */,
|
13B07F871A680F5B00A75B9A /* Sources */,
|
||||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||||
9B977D89FE30470F8C59964C /* Upload Debug Symbols to Sentry */,
|
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */,
|
||||||
E043D7E00F2210228303FC0B /* [CP] Embed Pods Frameworks */,
|
7D1788E2D4EF42D9BD43136D /* Upload Debug Symbols to Sentry */,
|
||||||
7F1DFB9D902E2DBC35F3FB84 /* [CP] Copy Pods Resources */,
|
8773BA7C99F44506A4A25842 /* Embed Foundation Extensions */,
|
||||||
3447F08B99D9427E99FEE18E /* Embed Foundation Extensions */,
|
0014ED4AAB03BFF76DF3B778 /* [CP] Embed Pods Frameworks */,
|
||||||
BDCAC5D772944755921F3BCF /* Embed Foundation Extensions */,
|
|
||||||
571AD3FB23F14FC7BE6A1E44 /* Embed Foundation Extensions */,
|
|
||||||
13CD9594FB5C4FE4A6794089 /* Embed Foundation Extensions */,
|
|
||||||
F1058FE7710A45FABC0689A7 /* Embed Foundation Extensions */,
|
|
||||||
CC1B793274FE428D8531E950 /* Embed Foundation Extensions */,
|
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
8410CAE82E604DD1A187EDA2 /* PBXTargetDependency */,
|
65AA2578A3174CBBAFE7AF11 /* PBXTargetDependency */,
|
||||||
523C5D7CB8E740A5A0BF4322 /* PBXTargetDependency */,
|
|
||||||
);
|
);
|
||||||
name = Nuvio;
|
name = Nuvio;
|
||||||
productName = Nuvio;
|
productName = Nuvio;
|
||||||
productReference = 13B07F961A680F5B00A75B9A /* Nuvio.app */;
|
productReference = 13B07F961A680F5B00A75B9A /* Nuvio.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
EFB756D21A05453EA489278C /* LiveActivity */ = {
|
BB0FA6CBF7FD404994DB1E52 /* LiveActivity */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
name = LiveActivity;
|
buildConfigurationList = 4D277DDAFD8E470E87E3A678 /* Build configuration list for PBXNativeTarget "LiveActivity" */;
|
||||||
productName = LiveActivity;
|
|
||||||
productReference = 49DDF70A2BBD4320BBD94B1B;
|
|
||||||
productType = "com.apple.product-type.app-extension";
|
|
||||||
buildConfigurationList = F11E3E24512A427FB847D2F6;
|
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
784E2472974841CD88391F31 /* Embed Foundation Extensions */,
|
547FCD1068DD43D2B6E1582A /* Sources */,
|
||||||
A2537B59C29048BFB082D5F3 /* Embed Foundation Extensions */,
|
2341847DAC4A41A89AA0DED2 /* Frameworks */,
|
||||||
B06A5B524C284D9FAFC33F3C /* Embed Foundation Extensions */,
|
466E6B41B3D44B44941DC4FF /* Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
|
name = LiveActivity;
|
||||||
|
productName = LiveActivity;
|
||||||
|
productReference = 37E2BF6107484CD098F81560 /* LiveActivity.appex */;
|
||||||
|
productType = "com.apple.product-type.app-extension";
|
||||||
};
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
|
@ -420,18 +262,15 @@
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1130;
|
LastUpgradeCheck = 1130;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
0EA489F2BF6143F1BA7B8485 = {
|
|
||||||
DevelopmentTeam = 8QBDZ766S3;
|
|
||||||
LastSwiftMigration = 1250;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
13B07F861A680F5B00A75B9A = {
|
13B07F861A680F5B00A75B9A = {
|
||||||
DevelopmentTeam = 8QBDZ766S3;
|
|
||||||
LastSwiftMigration = 1250;
|
LastSwiftMigration = 1250;
|
||||||
|
DevelopmentTeam = "8QBDZ766S3";
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
EFB756D21A05453EA489278C = {
|
BB0FA6CBF7FD404994DB1E52 = {
|
||||||
LastSwiftMigration = 1250;
|
LastSwiftMigration = 1250;
|
||||||
|
DevelopmentTeam = "8QBDZ766S3";
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -449,8 +288,7 @@
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
13B07F861A680F5B00A75B9A /* Nuvio */,
|
13B07F861A680F5B00A75B9A /* Nuvio */,
|
||||||
0EA489F2BF6143F1BA7B8485 /* LiveActivity */,
|
BB0FA6CBF7FD404994DB1E52 /* LiveActivity */,
|
||||||
EFB756D21A05453EA489278C /* LiveActivity */,
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
@ -463,29 +301,43 @@
|
||||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */,
|
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */,
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
|
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
|
||||||
0FFC28FB1FEA74CCFA112268 /* PrivacyInfo.xcprivacy in Resources */,
|
24FC08E856045AC6A95D753A /* PrivacyInfo.xcprivacy in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
1E668E0B92C34E73AECDBE1A /* Resources */ = {
|
466E6B41B3D44B44941DC4FF /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
730F1CE72F24B27100EF7E51 /* Assets.xcassets in Resources */,
|
357A8847EA6B42B792A617D4 /* Assets.xcassets in Resources */,
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
B06A5B524C284D9FAFC33F3C /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXResourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
730F1CE72F24B27100EF7E51 /* Assets.xcassets in Resources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
0014ED4AAB03BFF76DF3B778 /* [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;
|
||||||
|
};
|
||||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
|
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
|
|
@ -503,7 +355,7 @@
|
||||||
shellPath = /bin/sh;
|
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";
|
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";
|
||||||
};
|
};
|
||||||
13C7A3175A582B3D4E9F198E /* [CP] Check Pods Manifest.lock */ = {
|
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
|
@ -525,7 +377,21 @@
|
||||||
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";
|
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;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
7F1DFB9D902E2DBC35F3FB84 /* [CP] Copy Pods Resources */ = {
|
7D1788E2D4EF42D9BD43136D /* 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'\"`";
|
||||||
|
};
|
||||||
|
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
|
@ -637,7 +503,7 @@
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Nuvio/Pods-Nuvio-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Nuvio/Pods-Nuvio-resources.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
99A79B70155E84EE1FB7F466 /* [Expo] Configure project */ = {
|
B67FC995125067F91F480913 /* [Expo] Configure project */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
|
@ -661,42 +527,6 @@
|
||||||
shellPath = /bin/sh;
|
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";
|
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'\"`";
|
|
||||||
};
|
|
||||||
E043D7E00F2210228303FC0B /* [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 */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
|
@ -705,73 +535,46 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */,
|
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */,
|
||||||
9FBA88F42E86ECD700892850 /* KSPlayerViewManager.swift in Sources */,
|
F4B2944DA5D06650F3B40F2A /* ExpoModulesProvider.swift in Sources */,
|
||||||
9FBA88F52E86ECD700892850 /* KSPlayerModule.swift in Sources */,
|
|
||||||
9FBA88F62E86ECD700892850 /* KSPlayerManager.m in Sources */,
|
|
||||||
9FBA88F72E86ECD700892850 /* KSPlayerView.swift in Sources */,
|
|
||||||
2AA769395C1242F225F875AF /* ExpoModulesProvider.swift in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
6E9A0429F8E74948A82DEFF5 /* Sources */ = {
|
547FCD1068DD43D2B6E1582A /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
730F1CDE2F24B27100EF7E51 /* Color+hex.swift in Sources */,
|
9BE191900481495083B7ECC1 /* Color+hex.swift in Sources */,
|
||||||
730F1CDF2F24B27100EF7E51 /* Date+toTimerInterval.swift in Sources */,
|
3A4B91216E8D486E9000CD6C /* Date+toTimerInterval.swift in Sources */,
|
||||||
730F1CE02F24B27100EF7E51 /* Image+dynamic.swift in Sources */,
|
B3BB1BBDA8C742DC9A32EACF /* Image+dynamic.swift in Sources */,
|
||||||
730F1CE12F24B27100EF7E51 /* LiveActivityView.swift in Sources */,
|
D102CD3E3CCC4B83AC0F4DBE /* LiveActivityView.swift in Sources */,
|
||||||
730F1CE22F24B27100EF7E51 /* LiveActivityWidget.swift in Sources */,
|
DEB0D346CF964886AD06A268 /* LiveActivityWidget.swift in Sources */,
|
||||||
730F1CE32F24B27100EF7E51 /* LiveActivityWidgetBundle.swift in Sources */,
|
4F1568831D134295A56C0263 /* LiveActivityWidgetBundle.swift in Sources */,
|
||||||
730F1CE42F24B27100EF7E51 /* View+applyIfPresent.swift in Sources */,
|
0512F937B36046F581AF6A55 /* View+applyIfPresent.swift in Sources */,
|
||||||
730F1CE52F24B27100EF7E51 /* View+applyWidgetURL.swift in Sources */,
|
94F843501BFD40C384CBB500 /* View+applyWidgetURL.swift in Sources */,
|
||||||
730F1CE62F24B27100EF7E51 /* ViewHelpers.swift in Sources */,
|
7069406A1E324608A86CC6C9 /* ViewHelpers.swift in Sources */,
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
784E2472974841CD88391F31 /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
730F1CDE2F24B27100EF7E51 /* "Color+hex.swift" in Sources */,
|
|
||||||
730F1CDF2F24B27100EF7E51 /* "Date+toTimerInterval.swift" in Sources */,
|
|
||||||
730F1CE02F24B27100EF7E51 /* "Image+dynamic.swift" in Sources */,
|
|
||||||
730F1CE12F24B27100EF7E51 /* LiveActivityView.swift in Sources */,
|
|
||||||
730F1CE22F24B27100EF7E51 /* LiveActivityWidget.swift in Sources */,
|
|
||||||
730F1CE32F24B27100EF7E51 /* LiveActivityWidgetBundle.swift in Sources */,
|
|
||||||
730F1CE42F24B27100EF7E51 /* "View+applyIfPresent.swift" in Sources */,
|
|
||||||
730F1CE52F24B27100EF7E51 /* "View+applyWidgetURL.swift" in Sources */,
|
|
||||||
730F1CE62F24B27100EF7E51 /* ViewHelpers.swift in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
8410CAE82E604DD1A187EDA2 /* PBXTargetDependency */ = {
|
65AA2578A3174CBBAFE7AF11 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = 0EA489F2BF6143F1BA7B8485 /* LiveActivity */;
|
target = BB0FA6CBF7FD404994DB1E52 /* LiveActivity */;
|
||||||
targetProxy = 55A0DD628D7F4F4F88B4A001 /* PBXContainerItemProxy */;
|
targetProxy = DBC6C07FF91444EEAB5F4C66 /* PBXContainerItemProxy */;
|
||||||
};
|
|
||||||
523C5D7CB8E740A5A0BF4322 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = EFB756D21A05453EA489278C /* LiveActivity */;
|
|
||||||
targetProxy = 7A41A1F529994F0C8801F1A5 /* PBXContainerItemProxy */;
|
|
||||||
};
|
};
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = DAD634845937EAF8D64F20FC /* Pods-Nuvio.debug.xcconfig */;
|
baseConfigurationReference = 7EC866223BB0FA7280D468BF /* Pods-Nuvio.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Nuvio/Nuvio.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Nuvio/Nuvio.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = 8QBDZ766S3;
|
DEVELOPMENT_TEAM = "8QBDZ766S3";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
|
@ -791,27 +594,26 @@
|
||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub;
|
||||||
PRODUCT_NAME = "Nuvio";
|
PRODUCT_NAME = Nuvio;
|
||||||
SUPPORTS_MACCATALYST = YES;
|
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 0DFF64A670930CED5EA4DF3A /* Pods-Nuvio.release.xcconfig */;
|
baseConfigurationReference = 44393AD0ABDBAED5B40D2E49 /* Pods-Nuvio.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Nuvio/NuvioRelease.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Nuvio/Nuvio.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = 8QBDZ766S3;
|
DEVELOPMENT_TEAM = "8QBDZ766S3";
|
||||||
INFOPLIST_FILE = Nuvio/Info.plist;
|
INFOPLIST_FILE = Nuvio/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
|
@ -826,38 +628,15 @@
|
||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub;
|
||||||
PRODUCT_NAME = "Nuvio";
|
PRODUCT_NAME = Nuvio;
|
||||||
SUPPORTS_MACCATALYST = YES;
|
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
3DCEA1FBF99E46F58A7150CC /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = LiveActivity/LiveActivity.entitlements;
|
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 34;
|
|
||||||
DEVELOPMENT_TEAM = 8QBDZ766S3;
|
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
|
||||||
INFOPLIST_FILE = LiveActivity/Info.plist;
|
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = LiveActivity;
|
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
|
||||||
MARKETING_VERSION = 1.3.6;
|
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub.LiveActivity;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Release;
|
||||||
};
|
};
|
||||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
|
@ -977,70 +756,54 @@
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
E4108F64486C48E192EAA45D /* Release */ = {
|
935F73C6BA4D42D1A1F36953 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = LiveActivity/LiveActivity.entitlements;
|
CODE_SIGN_ENTITLEMENTS = LiveActivity/LiveActivity.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CURRENT_PROJECT_VERSION = 37;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 34;
|
|
||||||
DEVELOPMENT_TEAM = 8QBDZ766S3;
|
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = LiveActivity/Info.plist;
|
INFOPLIST_FILE = LiveActivity/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = LiveActivity;
|
INFOPLIST_KEY_CFBundleDisplayName = LiveActivity;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||||
MARKETING_VERSION = 1.3.6;
|
MARKETING_VERSION = 1.4.1;
|
||||||
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub.LiveActivity;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
DEVELOPMENT_TEAM = "8QBDZ766S3";
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
DE24FDCA00464F85805C3A58 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = LiveActivity/LiveActivity.entitlements;
|
||||||
|
CURRENT_PROJECT_VERSION = 37;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = LiveActivity/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = LiveActivity;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||||
|
MARKETING_VERSION = 1.4.1;
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub.LiveActivity;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub.LiveActivity;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
DEVELOPMENT_TEAM = "8QBDZ766S3";
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
B062D46778AF40DE92953986 /* Debug */ = {
|
|
||||||
name = Debug;
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
INFOPLIST_FILE = LiveActivity/Info.plist;
|
|
||||||
CURRENT_PROJECT_VERSION = "37";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = "16.2";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.nuvio.hub.LiveActivity";
|
|
||||||
GENERATE_INFOPLIST_FILE = "YES";
|
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = LiveActivity;
|
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
|
||||||
MARKETING_VERSION = "1.4.1";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
CODE_SIGN_ENTITLEMENTS = "LiveActivity/LiveActivity.entitlements";
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = "YES";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
67617475B4F443CBBCE1A6FD /* Release */ = {
|
|
||||||
name = Release;
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
INFOPLIST_FILE = LiveActivity/Info.plist;
|
|
||||||
CURRENT_PROJECT_VERSION = "37";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = "16.2";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.nuvio.hub.LiveActivity";
|
|
||||||
GENERATE_INFOPLIST_FILE = "YES";
|
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = LiveActivity;
|
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
|
||||||
MARKETING_VERSION = "1.4.1";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
CODE_SIGN_ENTITLEMENTS = "LiveActivity/LiveActivity.entitlements";
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = "YES";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
|
@ -1053,6 +816,15 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
4D277DDAFD8E470E87E3A678 /* Build configuration list for PBXNativeTarget "LiveActivity" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
935F73C6BA4D42D1A1F36953 /* Debug */,
|
||||||
|
DE24FDCA00464F85805C3A58 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Nuvio" */ = {
|
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Nuvio" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|
@ -1062,24 +834,6 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
C95083D445BA485B82D2FFBC /* Build configuration list for PBXNativeTarget "LiveActivity" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
3DCEA1FBF99E46F58A7150CC /* Debug */,
|
|
||||||
E4108F64486C48E192EAA45D /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
F11E3E24512A427FB847D2F6 /* Build configuration list for PBXNativeTarget "LiveActivity" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
B062D46778AF40DE92953986 /* Debug */,
|
|
||||||
67617475B4F443CBBCE1A6FD /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,15 @@
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>37</string>
|
<string>37</string>
|
||||||
|
<key>LSApplicationQueriesSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>vlc</string>
|
||||||
|
<string>vlc-x-callback</string>
|
||||||
|
<string>infuse</string>
|
||||||
|
<string>outplayer</string>
|
||||||
|
<string>open-vidhub</string>
|
||||||
|
<string>livecontainer</string>
|
||||||
|
</array>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>12.0</string>
|
<string>12.0</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
|
|
||||||
234
ios/Podfile.lock
234
ios/Podfile.lock
|
|
@ -4,14 +4,14 @@ PODS:
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXApplication (7.0.8):
|
- EXApplication (7.0.8):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXConstants (18.0.12):
|
- EXConstants (18.0.13):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXJSONUtils (0.15.0)
|
- EXJSONUtils (0.15.0)
|
||||||
- EXManifests (1.0.10):
|
- EXManifests (1.0.10):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXNotifications (0.32.15):
|
- EXNotifications (0.32.16):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- Expo (54.0.29):
|
- Expo (54.0.33):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
|
|
@ -207,7 +207,7 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- ExpoAsset (12.0.11):
|
- ExpoAsset (12.0.12):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoBlur (15.0.8):
|
- ExpoBlur (15.0.8):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
|
|
@ -223,9 +223,9 @@ PODS:
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoFileSystem (19.0.21):
|
- ExpoFileSystem (19.0.21):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoFont (14.0.10):
|
- ExpoFont (14.0.11):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoGlassEffect (0.1.8):
|
- ExpoGlassEffect (0.1.9):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoHaptics (15.0.8):
|
- ExpoHaptics (15.0.8):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
|
|
@ -233,7 +233,7 @@ PODS:
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoLinearGradient (15.0.8):
|
- ExpoLinearGradient (15.0.8):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoLinking (8.0.10):
|
- ExpoLinking (8.0.11):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoLiveActivity (0.4.2):
|
- ExpoLiveActivity (0.4.2):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
|
|
@ -294,7 +294,7 @@ PODS:
|
||||||
- ExpoWebBrowser (15.0.10):
|
- ExpoWebBrowser (15.0.10):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXStructuredHeaders (5.0.0)
|
- EXStructuredHeaders (5.0.0)
|
||||||
- EXUpdates (29.0.15):
|
- EXUpdates (29.0.16):
|
||||||
- EASClient
|
- EASClient
|
||||||
- EXManifests
|
- EXManifests
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
|
|
@ -333,8 +333,9 @@ PODS:
|
||||||
- hermes-engine (0.81.4):
|
- hermes-engine (0.81.4):
|
||||||
- hermes-engine/Pre-built (= 0.81.4)
|
- hermes-engine/Pre-built (= 0.81.4)
|
||||||
- hermes-engine/Pre-built (0.81.4)
|
- hermes-engine/Pre-built (0.81.4)
|
||||||
- ImageColors (2.5.1):
|
- ImageColors (2.6.0):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
|
- SwiftDraw (~> 0.27)
|
||||||
- KSPlayer (1.1.0):
|
- KSPlayer (1.1.0):
|
||||||
- KSPlayer/Audio (= 1.1.0)
|
- KSPlayer/Audio (= 1.1.0)
|
||||||
- KSPlayer/AVPlayer (= 1.1.0)
|
- KSPlayer/AVPlayer (= 1.1.0)
|
||||||
|
|
@ -382,10 +383,10 @@ PODS:
|
||||||
- libwebp/sharpyuv (1.5.0)
|
- libwebp/sharpyuv (1.5.0)
|
||||||
- libwebp/webp (1.5.0):
|
- libwebp/webp (1.5.0):
|
||||||
- libwebp/sharpyuv
|
- libwebp/sharpyuv
|
||||||
- lottie-ios (4.5.0)
|
- lottie-ios (4.6.0)
|
||||||
- lottie-react-native (7.3.4):
|
- lottie-react-native (7.3.6):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- lottie-ios (= 4.5.0)
|
- lottie-ios (= 4.6.0)
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
- React-Core
|
- React-Core
|
||||||
|
|
@ -406,12 +407,12 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- MMKV (2.2.4):
|
- MMKV (2.3.0):
|
||||||
- MMKVCore (~> 2.2.4)
|
- MMKVCore (~> 2.3.0)
|
||||||
- MMKVCore (2.2.4)
|
- MMKVCore (2.3.0)
|
||||||
- NitroMmkv (4.1.0):
|
- NitroMmkv (4.2.0):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- MMKVCore (= 2.2.4)
|
- MMKVCore (= 2.3.0)
|
||||||
- NitroModules
|
- NitroModules
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -434,7 +435,7 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- NitroModules (0.31.10):
|
- NitroModules (0.35.0):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -1738,7 +1739,7 @@ PODS:
|
||||||
- React-RCTFBReactNativeSpec
|
- React-RCTFBReactNativeSpec
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- react-native-background-downloader (4.4.5):
|
- react-native-background-downloader (4.5.3):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- MMKV
|
- MMKV
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
|
|
@ -1858,33 +1859,7 @@ PODS:
|
||||||
- google-cast-sdk
|
- google-cast-sdk
|
||||||
- PromisesObjC
|
- PromisesObjC
|
||||||
- React
|
- React
|
||||||
- react-native-netinfo (11.4.1):
|
- react-native-netinfo (12.0.1):
|
||||||
- React-Core
|
|
||||||
- react-native-safe-area-context (5.6.2):
|
|
||||||
- hermes-engine
|
|
||||||
- RCTRequired
|
|
||||||
- RCTTypeSafety
|
|
||||||
- React-Core
|
|
||||||
- React-Core-prebuilt
|
|
||||||
- React-debug
|
|
||||||
- React-Fabric
|
|
||||||
- React-featureflags
|
|
||||||
- React-graphics
|
|
||||||
- React-ImageManager
|
|
||||||
- React-jsi
|
|
||||||
- react-native-safe-area-context/common (= 5.6.2)
|
|
||||||
- react-native-safe-area-context/fabric (= 5.6.2)
|
|
||||||
- React-NativeModulesApple
|
|
||||||
- React-RCTFabric
|
|
||||||
- React-renderercss
|
|
||||||
- React-rendererdebug
|
|
||||||
- React-utils
|
|
||||||
- ReactCodegen
|
|
||||||
- ReactCommon/turbomodule/bridging
|
|
||||||
- ReactCommon/turbomodule/core
|
|
||||||
- ReactNativeDependencies
|
|
||||||
- Yoga
|
|
||||||
- react-native-safe-area-context/common (5.6.2):
|
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -1906,7 +1881,53 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- react-native-safe-area-context/fabric (5.6.2):
|
- react-native-safe-area-context (5.7.0):
|
||||||
|
- hermes-engine
|
||||||
|
- RCTRequired
|
||||||
|
- RCTTypeSafety
|
||||||
|
- React-Core
|
||||||
|
- React-Core-prebuilt
|
||||||
|
- React-debug
|
||||||
|
- React-Fabric
|
||||||
|
- React-featureflags
|
||||||
|
- React-graphics
|
||||||
|
- React-ImageManager
|
||||||
|
- React-jsi
|
||||||
|
- react-native-safe-area-context/common (= 5.7.0)
|
||||||
|
- react-native-safe-area-context/fabric (= 5.7.0)
|
||||||
|
- React-NativeModulesApple
|
||||||
|
- React-RCTFabric
|
||||||
|
- React-renderercss
|
||||||
|
- React-rendererdebug
|
||||||
|
- React-utils
|
||||||
|
- ReactCodegen
|
||||||
|
- ReactCommon/turbomodule/bridging
|
||||||
|
- ReactCommon/turbomodule/core
|
||||||
|
- ReactNativeDependencies
|
||||||
|
- Yoga
|
||||||
|
- react-native-safe-area-context/common (5.7.0):
|
||||||
|
- hermes-engine
|
||||||
|
- RCTRequired
|
||||||
|
- RCTTypeSafety
|
||||||
|
- React-Core
|
||||||
|
- React-Core-prebuilt
|
||||||
|
- React-debug
|
||||||
|
- React-Fabric
|
||||||
|
- React-featureflags
|
||||||
|
- React-graphics
|
||||||
|
- React-ImageManager
|
||||||
|
- React-jsi
|
||||||
|
- React-NativeModulesApple
|
||||||
|
- React-RCTFabric
|
||||||
|
- React-renderercss
|
||||||
|
- React-rendererdebug
|
||||||
|
- React-utils
|
||||||
|
- ReactCodegen
|
||||||
|
- ReactCommon/turbomodule/bridging
|
||||||
|
- ReactCommon/turbomodule/core
|
||||||
|
- ReactNativeDependencies
|
||||||
|
- Yoga
|
||||||
|
- react-native-safe-area-context/fabric (5.7.0):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -1929,7 +1950,7 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- react-native-skia (2.4.14):
|
- react-native-skia (2.5.1):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -1953,7 +1974,7 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- react-native-slider (5.1.1):
|
- react-native-slider (5.1.2):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -1965,7 +1986,7 @@ PODS:
|
||||||
- React-graphics
|
- React-graphics
|
||||||
- React-ImageManager
|
- React-ImageManager
|
||||||
- React-jsi
|
- React-jsi
|
||||||
- react-native-slider/common (= 5.1.1)
|
- react-native-slider/common (= 5.1.2)
|
||||||
- React-NativeModulesApple
|
- React-NativeModulesApple
|
||||||
- React-RCTFabric
|
- React-RCTFabric
|
||||||
- React-renderercss
|
- React-renderercss
|
||||||
|
|
@ -1976,7 +1997,7 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- react-native-slider/common (5.1.1):
|
- react-native-slider/common (5.1.2):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2466,7 +2487,7 @@ PODS:
|
||||||
- SDWebImageSVGCoder (~> 1.7.0)
|
- SDWebImageSVGCoder (~> 1.7.0)
|
||||||
- SDWebImageWebPCoder (~> 0.14)
|
- SDWebImageWebPCoder (~> 0.14)
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNGestureHandler (2.29.1):
|
- RNGestureHandler (2.30.0):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2488,7 +2509,7 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNReanimated (4.2.0):
|
- RNReanimated (4.2.2):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2510,10 +2531,10 @@ PODS:
|
||||||
- ReactCommon/turbomodule/bridging
|
- ReactCommon/turbomodule/bridging
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- RNReanimated/reanimated (= 4.2.0)
|
- RNReanimated/reanimated (= 4.2.2)
|
||||||
- RNWorklets
|
- RNWorklets
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNReanimated/reanimated (4.2.0):
|
- RNReanimated/reanimated (4.2.2):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2535,10 +2556,10 @@ PODS:
|
||||||
- ReactCommon/turbomodule/bridging
|
- ReactCommon/turbomodule/bridging
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- RNReanimated/reanimated/apple (= 4.2.0)
|
- RNReanimated/reanimated/apple (= 4.2.2)
|
||||||
- RNWorklets
|
- RNWorklets
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNReanimated/reanimated/apple (4.2.0):
|
- RNReanimated/reanimated/apple (4.2.2):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2562,7 +2583,7 @@ PODS:
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- RNWorklets
|
- RNWorklets
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNScreens (4.18.0):
|
- RNScreens (4.24.0):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2584,9 +2605,9 @@ PODS:
|
||||||
- ReactCommon/turbomodule/bridging
|
- ReactCommon/turbomodule/bridging
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- RNScreens/common (= 4.18.0)
|
- RNScreens/common (= 4.24.0)
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNScreens/common (4.18.0):
|
- RNScreens/common (4.24.0):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2609,7 +2630,7 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNSentry (7.7.0):
|
- RNSentry (8.4.0):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2631,9 +2652,9 @@ PODS:
|
||||||
- ReactCommon/turbomodule/bridging
|
- ReactCommon/turbomodule/bridging
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Sentry/HybridSDK (= 8.57.3)
|
- Sentry (= 9.7.0)
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNSVG (15.15.1):
|
- RNSVG (15.15.3):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2654,9 +2675,9 @@ PODS:
|
||||||
- ReactCommon/turbomodule/bridging
|
- ReactCommon/turbomodule/bridging
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- RNSVG/common (= 15.15.1)
|
- RNSVG/common (= 15.15.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNSVG/common (15.15.1):
|
- RNSVG/common (15.15.3):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2700,7 +2721,7 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNWorklets (0.7.1):
|
- RNWorklets (0.7.4):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2722,9 +2743,9 @@ PODS:
|
||||||
- ReactCommon/turbomodule/bridging
|
- ReactCommon/turbomodule/bridging
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- RNWorklets/worklets (= 0.7.1)
|
- RNWorklets/worklets (= 0.7.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNWorklets/worklets (0.7.1):
|
- RNWorklets/worklets (0.7.4):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2746,9 +2767,9 @@ PODS:
|
||||||
- ReactCommon/turbomodule/bridging
|
- ReactCommon/turbomodule/bridging
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- RNWorklets/worklets/apple (= 0.7.1)
|
- RNWorklets/worklets/apple (= 0.7.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNWorklets/worklets/apple (0.7.1):
|
- RNWorklets/worklets/apple (0.7.4):
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCTRequired
|
- RCTRequired
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
|
|
@ -2771,9 +2792,9 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- SDWebImage (5.21.5):
|
- SDWebImage (5.21.7):
|
||||||
- SDWebImage/Core (= 5.21.5)
|
- SDWebImage/Core (= 5.21.7)
|
||||||
- SDWebImage/Core (5.21.5)
|
- SDWebImage/Core (5.21.7)
|
||||||
- SDWebImageAVIFCoder (0.11.1):
|
- SDWebImageAVIFCoder (0.11.1):
|
||||||
- libavif/core (>= 0.11.0)
|
- libavif/core (>= 0.11.0)
|
||||||
- SDWebImage (~> 5.10)
|
- SDWebImage (~> 5.10)
|
||||||
|
|
@ -2782,7 +2803,12 @@ PODS:
|
||||||
- SDWebImageWebPCoder (0.15.0):
|
- SDWebImageWebPCoder (0.15.0):
|
||||||
- libwebp (~> 1.0)
|
- libwebp (~> 1.0)
|
||||||
- SDWebImage/Core (~> 5.17)
|
- SDWebImage/Core (~> 5.17)
|
||||||
- Sentry/HybridSDK (8.57.3)
|
- Sentry (9.7.0):
|
||||||
|
- Sentry/Core (= 9.7.0)
|
||||||
|
- Sentry/Core (9.7.0)
|
||||||
|
- SwiftDraw (0.27.0):
|
||||||
|
- SwiftDrawDOM (~> 0.27.0)
|
||||||
|
- SwiftDrawDOM (0.27.0)
|
||||||
- SwiftUIIntrospect (1.3.0)
|
- SwiftUIIntrospect (1.3.0)
|
||||||
- Yoga (0.0.0)
|
- Yoga (0.0.0)
|
||||||
|
|
||||||
|
|
@ -2936,6 +2962,8 @@ SPEC REPOS:
|
||||||
- SDWebImageSVGCoder
|
- SDWebImageSVGCoder
|
||||||
- SDWebImageWebPCoder
|
- SDWebImageWebPCoder
|
||||||
- Sentry
|
- Sentry
|
||||||
|
- SwiftDraw
|
||||||
|
- SwiftDrawDOM
|
||||||
- SwiftUIIntrospect
|
- SwiftUIIntrospect
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
|
|
@ -3217,16 +3245,16 @@ SPEC CHECKSUMS:
|
||||||
DisplayCriteria: bb0a90faf14b30848bc50ac0516340ce50164187
|
DisplayCriteria: bb0a90faf14b30848bc50ac0516340ce50164187
|
||||||
EASClient: 40dd9e740684782610c49becab2643782ea1a20c
|
EASClient: 40dd9e740684782610c49becab2643782ea1a20c
|
||||||
EXApplication: 1e98d4b1dccdf30627f92917f4b2c5a53c330e5f
|
EXApplication: 1e98d4b1dccdf30627f92917f4b2c5a53c330e5f
|
||||||
EXConstants: 805f35b1b295c542ca6acce836f21a1f9ee104d5
|
EXConstants: fce59a631a06c4151602843667f7cfe35f81e271
|
||||||
EXJSONUtils: 1d3e4590438c3ee593684186007028a14b3686cd
|
EXJSONUtils: 1d3e4590438c3ee593684186007028a14b3686cd
|
||||||
EXManifests: a8d97683e5c7a3b026ffbd58559c64dc655b747b
|
EXManifests: a8d97683e5c7a3b026ffbd58559c64dc655b747b
|
||||||
EXNotifications: 983f04ad4ad879b181179e326bf220541e478386
|
EXNotifications: 9eec98712cc814ceff916d876cb53859003b0597
|
||||||
Expo: 8fa2204bf8483fe546b4ec87c90d3ca189afc8db
|
Expo: aadbcc8c6c14ff3105a9154f1683cb1424ff0d2a
|
||||||
expo-dev-client: 425ee077d6754a98cfe3a2e2410d29b440b24c9d
|
expo-dev-client: 425ee077d6754a98cfe3a2e2410d29b440b24c9d
|
||||||
expo-dev-launcher: a4f4cdef064ab1fb8621e5b8c7c457cd6e9568c3
|
expo-dev-launcher: a4f4cdef064ab1fb8621e5b8c7c457cd6e9568c3
|
||||||
expo-dev-menu: 05b18812110c175814c6af0d09dd658abcc5e00d
|
expo-dev-menu: 05b18812110c175814c6af0d09dd658abcc5e00d
|
||||||
expo-dev-menu-interface: 600df12ea01efecdd822daaf13cc0ac091775533
|
expo-dev-menu-interface: 600df12ea01efecdd822daaf13cc0ac091775533
|
||||||
ExpoAsset: 23a958e97d3d340919fe6774db35d563241e6c03
|
ExpoAsset: f867e55ceb428aab99e1e8c082b5aee7c159ea18
|
||||||
ExpoBlur: b90747a3f22a8b6ceffd9cb0dc41a4184efdc656
|
ExpoBlur: b90747a3f22a8b6ceffd9cb0dc41a4184efdc656
|
||||||
ExpoBrightness: 46c980463e8a54b9ce77f923c4bff0bb0c9526e0
|
ExpoBrightness: 46c980463e8a54b9ce77f923c4bff0bb0c9526e0
|
||||||
ExpoClipboard: b36b287d8356887844bb08ed5c84b5979bb4dd1e
|
ExpoClipboard: b36b287d8356887844bb08ed5c84b5979bb4dd1e
|
||||||
|
|
@ -3234,12 +3262,12 @@ SPEC CHECKSUMS:
|
||||||
ExpoDevice: 6327c3c200816795708885adf540d26ecab83d1a
|
ExpoDevice: 6327c3c200816795708885adf540d26ecab83d1a
|
||||||
ExpoDocumentPicker: 7cd9e71a0f66fb19eb0a586d6f26eee1284692e0
|
ExpoDocumentPicker: 7cd9e71a0f66fb19eb0a586d6f26eee1284692e0
|
||||||
ExpoFileSystem: 858a44267a3e6e9057e0888ad7c7cfbf55d52063
|
ExpoFileSystem: 858a44267a3e6e9057e0888ad7c7cfbf55d52063
|
||||||
ExpoFont: 35ac6191ed86bbf56b3ebd2d9154eda9fad5b509
|
ExpoFont: f543ce20a228dd702813668b1a07b46f51878d47
|
||||||
ExpoGlassEffect: 8ce45eca31f12e949e23a4ee13e2bfb59e9b0785
|
ExpoGlassEffect: 93f0665d19063cb3b46bbd0a2ebea4a36b6a4e37
|
||||||
ExpoHaptics: d3a6375d8dcc3a1083d003bc2298ff654fafb536
|
ExpoHaptics: d3a6375d8dcc3a1083d003bc2298ff654fafb536
|
||||||
ExpoKeepAwake: 55f75eca6499bb9e4231ebad6f3e9cb8f99c0296
|
ExpoKeepAwake: 55f75eca6499bb9e4231ebad6f3e9cb8f99c0296
|
||||||
ExpoLinearGradient: 809102bdb979f590083af49f7fa4805cd931bd58
|
ExpoLinearGradient: 809102bdb979f590083af49f7fa4805cd931bd58
|
||||||
ExpoLinking: f4c4a351523da72a6bfa7e1f4ca92aee1043a3ca
|
ExpoLinking: 8f0aaf69aa56f832913030503b6263dc6f647f37
|
||||||
ExpoLiveActivity: d0dd0e8e1460b6b26555b611c4826cdb1036eea2
|
ExpoLiveActivity: d0dd0e8e1460b6b26555b611c4826cdb1036eea2
|
||||||
ExpoLocalization: d9168d5300a5b03e5e78b986124d11fb6ec3ebbd
|
ExpoLocalization: d9168d5300a5b03e5e78b986124d11fb6ec3ebbd
|
||||||
ExpoModulesCore: f3da4f1ab5a8375d0beafab763739dbee8446583
|
ExpoModulesCore: f3da4f1ab5a8375d0beafab763739dbee8446583
|
||||||
|
|
@ -3249,24 +3277,24 @@ SPEC CHECKSUMS:
|
||||||
ExpoSystemUI: 2ad325f361a2fcd96a464e8574e19935c461c9cc
|
ExpoSystemUI: 2ad325f361a2fcd96a464e8574e19935c461c9cc
|
||||||
ExpoWebBrowser: 17b064c621789e41d4816c95c93f429b84971f52
|
ExpoWebBrowser: 17b064c621789e41d4816c95c93f429b84971f52
|
||||||
EXStructuredHeaders: c951e77f2d936f88637421e9588c976da5827368
|
EXStructuredHeaders: c951e77f2d936f88637421e9588c976da5827368
|
||||||
EXUpdates: f20abbc8a9f4e150656fe88126d52f52d4e7793f
|
EXUpdates: f86d4af4362c2c83a7bf8531d777e9fba680e2d9
|
||||||
EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734
|
EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734
|
||||||
FBLazyVector: 9e0cd874afd81d9a4d36679daca991b58b260d42
|
FBLazyVector: 9e0cd874afd81d9a4d36679daca991b58b260d42
|
||||||
FFmpegKit: 3885085fbbc320745838ee4c8a1f9c5e5953dab2
|
FFmpegKit: 3885085fbbc320745838ee4c8a1f9c5e5953dab2
|
||||||
google-cast-sdk: 32f65af50d164e3c475e79ad123db3cc26fbcd37
|
google-cast-sdk: 32f65af50d164e3c475e79ad123db3cc26fbcd37
|
||||||
hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394
|
hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394
|
||||||
ImageColors: e12eb73e29bc1feaa3c228db8c174a1b25acb59d
|
ImageColors: 3019b37809023d67795162135628e367d70e1766
|
||||||
KSPlayer: f163ac6195f240b6fa5b8225aeb39ec811a70c62
|
KSPlayer: f163ac6195f240b6fa5b8225aeb39ec811a70c62
|
||||||
Libass: e88af2324e1217e3a4c8bdc675f6f23a9dfc7677
|
Libass: e88af2324e1217e3a4c8bdc675f6f23a9dfc7677
|
||||||
libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
|
libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
|
||||||
libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
|
libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
|
||||||
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
|
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
|
||||||
lottie-ios: a881093fab623c467d3bce374367755c272bdd59
|
lottie-ios: 8f959969761e9c45d70353667d00af0e5b9cadb3
|
||||||
lottie-react-native: cbe3d931a7c24f7891a8e8032c2bb9b2373c4b9c
|
lottie-react-native: 6a080b2f109ef611c75c503a33ebb8ea75db0c91
|
||||||
MMKV: 1a8e7dbce7f9cad02c52e1b1091d07bd843aefaf
|
MMKV: c953dbaac0da392c24b005e763c03ce2638b4ed7
|
||||||
MMKVCore: f2dd4c9befea04277a55e84e7812f930537993df
|
MMKVCore: d078dce7d6586a888b2c2ef5343b6242678e3ee8
|
||||||
NitroMmkv: 4af10c70043b4c3cded3f16547627c7d9d8e3b8b
|
NitroMmkv: 38dfb2983c83e9bbbb64423ff48fbeaaa097cc38
|
||||||
NitroModules: a71a5ab2911caf79e45170e6e12475b5260a12d0
|
NitroModules: ff0d24be334de628166b9ac63661c998c732de7d
|
||||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||||
RCTDeprecation: 7487d6dda857ccd4cb3dd6ecfccdc3170e85dcbc
|
RCTDeprecation: 7487d6dda857ccd4cb3dd6ecfccdc3170e85dcbc
|
||||||
RCTRequired: 54128b7df8be566881d48c7234724a78cb9b6157
|
RCTRequired: 54128b7df8be566881d48c7234724a78cb9b6157
|
||||||
|
|
@ -3302,16 +3330,16 @@ SPEC CHECKSUMS:
|
||||||
React-logger: 7b234de35acb469ce76d6bbb0457f664d6f32f62
|
React-logger: 7b234de35acb469ce76d6bbb0457f664d6f32f62
|
||||||
React-Mapbuffer: fbe1da882a187e5898bdf125e1cc6e603d27ecae
|
React-Mapbuffer: fbe1da882a187e5898bdf125e1cc6e603d27ecae
|
||||||
React-microtasksnativemodule: 76905804171d8ccbe69329fc84c57eb7934add7f
|
React-microtasksnativemodule: 76905804171d8ccbe69329fc84c57eb7934add7f
|
||||||
react-native-background-downloader: 384c954ba4510de725697f7df4fd75f7c25579a2
|
react-native-background-downloader: 19eb7c5a834bac72f1273ab25325c71c44953c49
|
||||||
react-native-blur: 1b00ef07fe0efdc0c40b37139a5268ccad73c72d
|
react-native-blur: 1b00ef07fe0efdc0c40b37139a5268ccad73c72d
|
||||||
react-native-bottom-tabs: bcb70e4fae95fc9da0da875f7414acda26dfc551
|
react-native-bottom-tabs: bcb70e4fae95fc9da0da875f7414acda26dfc551
|
||||||
react-native-device-brightness: 1a997350d060c3df9f303b1df84a4f7c5cbeb924
|
react-native-device-brightness: 1a997350d060c3df9f303b1df84a4f7c5cbeb924
|
||||||
react-native-get-random-values: a603782b2b222a34533c66371614790282dba3f1
|
react-native-get-random-values: a603782b2b222a34533c66371614790282dba3f1
|
||||||
react-native-google-cast: 7be68a5d0b7eeb95a5924c3ecef8d319ef6c0a44
|
react-native-google-cast: 7be68a5d0b7eeb95a5924c3ecef8d319ef6c0a44
|
||||||
react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187
|
react-native-netinfo: 7e0b1936e928fa8ddb60da9e572a33767db7805f
|
||||||
react-native-safe-area-context: 37e680fc4cace3c0030ee46e8987d24f5d3bdab2
|
react-native-safe-area-context: ae7587b95fb580d1800c5b0b2a7bd48c2868e67a
|
||||||
react-native-skia: 268f183f849742e9da216743ee234bd7ad81c69b
|
react-native-skia: 6a51463f8391c82f675f490c8078135925285a8f
|
||||||
react-native-slider: f954578344106f0a732a4358ce3a3e11015eb6e1
|
react-native-slider: 8b9a218d1a3e526146a170cb6133be9cda23e70e
|
||||||
react-native-video: bca076cfff2a3e749fc63b3ac88118e1d8ee2689
|
react-native-video: bca076cfff2a3e749fc63b3ac88118e1d8ee2689
|
||||||
React-NativeModulesApple: a9464983ccc0f66f45e93558671f60fc7536e438
|
React-NativeModulesApple: a9464983ccc0f66f45e93558671f60fc7536e438
|
||||||
React-oscompat: 73db7dbc80edef36a9d6ed3c6c4e1724ead4236d
|
React-oscompat: 73db7dbc80edef36a9d6ed3c6c4e1724ead4236d
|
||||||
|
|
@ -3346,18 +3374,20 @@ SPEC CHECKSUMS:
|
||||||
ReactNativeDependencies: ed6d1e64802b150399f04f1d5728ec16b437251e
|
ReactNativeDependencies: ed6d1e64802b150399f04f1d5728ec16b437251e
|
||||||
RNCPicker: c8a3584b74133464ee926224463fcc54dfdaebca
|
RNCPicker: c8a3584b74133464ee926224463fcc54dfdaebca
|
||||||
RNFastImage: 2d36f4cfed9b2342f94f8591c8be69dd047ac67c
|
RNFastImage: 2d36f4cfed9b2342f94f8591c8be69dd047ac67c
|
||||||
RNGestureHandler: 723f29dac55e25f109d263ed65cecc4b9c4bd46a
|
RNGestureHandler: e0d0bce5599f6120b7adf90c38d2805e2935795f
|
||||||
RNReanimated: e1c71e6e693a66b203ae98773347b625d3cc85ee
|
RNReanimated: f4644326ad2bc0f5c0e52f15db316d4f5ee77a60
|
||||||
RNScreens: 61c18865ab074f4d995ac8d7cf5060522a649d05
|
RNScreens: 6cb648bdad8fe9bee9259fe144df95b6d1d5b707
|
||||||
RNSentry: 1d7b9fdae7a01ad8f9053335b5d44e75c39a955e
|
RNSentry: 4e9fc32104771fbb20c5f567eb9299fd92ea48b8
|
||||||
RNSVG: cf9ae78f2edf2988242c71a6392d15ff7dd62522
|
RNSVG: 7612f5bc575eab5da3364d44abe9f0d5db2cde03
|
||||||
RNVectorIcons: 4351544f100d4f12cac156a7c13399e60bab3e26
|
RNVectorIcons: 4351544f100d4f12cac156a7c13399e60bab3e26
|
||||||
RNWorklets: 9eb6d567fa43984e96b6924a6df504b8a15980cd
|
RNWorklets: eb8d899de8701d58c6a634b8468ce2a6db3113b2
|
||||||
SDWebImage: e9c98383c7572d713c1a0d7dd2783b10599b9838
|
SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
|
||||||
SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57
|
SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57
|
||||||
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
|
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
|
||||||
SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377
|
SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377
|
||||||
Sentry: c643eb180df401dd8c734c5036ddd9dd9218daa6
|
Sentry: 0fe17abdc98f83a3799c02564382d8b2afabadef
|
||||||
|
SwiftDraw: c3fb77c08081f1255f33bcc0fd3c2e00fbc9bd46
|
||||||
|
SwiftDrawDOM: 8e7d9812af1ef6e06230e72769e97838e6c7c765
|
||||||
SwiftUIIntrospect: fee9aa07293ee280373a591e1824e8ddc869ba5d
|
SwiftUIIntrospect: fee9aa07293ee280373a591e1824e8ddc869ba5d
|
||||||
Yoga: 051f086b5ccf465ff2ed38a2cf5a558ae01aaaa1
|
Yoga: 051f086b5ccf465ff2ed38a2cf5a558ae01aaaa1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -864,8 +864,19 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||||
drmSessionManager,
|
drmSessionManager,
|
||||||
runningSource.getCropStartMs(),
|
runningSource.getCropStartMs(),
|
||||||
runningSource.getCropEndMs());
|
runningSource.getCropEndMs());
|
||||||
MediaSource mediaSourceWithAds = initializeAds(videoSource, runningSource);
|
MediaSource mergedSource = videoSource;
|
||||||
MediaSource mediaSource = Objects.requireNonNullElse(mediaSourceWithAds, videoSource);
|
if (runningSource.getAudioUri() != null) {
|
||||||
|
MediaSource audioSource = buildMediaSource(
|
||||||
|
runningSource.getAudioUri(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
mergedSource = new MergingMediaSource(true, videoSource, audioSource);
|
||||||
|
}
|
||||||
|
MediaSource mediaSourceWithAds = initializeAds(mergedSource, runningSource);
|
||||||
|
MediaSource mediaSource = Objects.requireNonNullElse(mediaSourceWithAds, mergedSource);
|
||||||
|
|
||||||
// wait for player to be set
|
// wait for player to be set
|
||||||
while (player == null) {
|
while (player == null) {
|
||||||
|
|
@ -1100,8 +1111,17 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||||
}
|
}
|
||||||
} else if ("file".equals(uri.getScheme()) ||
|
} else if ("file".equals(uri.getScheme()) ||
|
||||||
!useCache) {
|
!useCache) {
|
||||||
|
DataSource.Factory progressiveDataSourceFactory = mediaDataSourceFactory;
|
||||||
|
String host = uri.getHost();
|
||||||
|
if (host != null && host.contains("googlevideo.com")) {
|
||||||
|
progressiveDataSourceFactory = DataSourceUtil.buildYoutubeChunkedDataSourceFactory(
|
||||||
|
themedReactContext,
|
||||||
|
bandwidthMeter,
|
||||||
|
source.getHeaders()
|
||||||
|
);
|
||||||
|
}
|
||||||
mediaSourceFactory = new ProgressiveMediaSource.Factory(
|
mediaSourceFactory = new ProgressiveMediaSource.Factory(
|
||||||
mediaDataSourceFactory
|
progressiveDataSourceFactory
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
mediaSourceFactory = new ProgressiveMediaSource.Factory(
|
mediaSourceFactory = new ProgressiveMediaSource.Factory(
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
269
scripts/inspect-youtube-formats.mjs
Normal file
269
scripts/inspect-youtube-formats.mjs
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
const DEFAULT_USER_AGENT =
|
||||||
|
'Mozilla/5.0 (Linux; Android 12; Android TV) AppleWebKit/537.36 ' +
|
||||||
|
'(KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36';
|
||||||
|
|
||||||
|
const DEFAULT_HEADERS = {
|
||||||
|
'accept-language': 'en-US,en;q=0.9',
|
||||||
|
'user-agent': DEFAULT_USER_AGENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const CLIENTS = [
|
||||||
|
{
|
||||||
|
key: 'android_vr',
|
||||||
|
id: '28',
|
||||||
|
version: '1.62.27',
|
||||||
|
userAgent:
|
||||||
|
'com.google.android.apps.youtube.vr.oculus/1.62.27 ' +
|
||||||
|
'(Linux; U; Android 12; en_US; Quest 3; Build/SQ3A.220605.009.A1) gzip',
|
||||||
|
context: {
|
||||||
|
clientName: 'ANDROID_VR',
|
||||||
|
clientVersion: '1.62.27',
|
||||||
|
deviceMake: 'Oculus',
|
||||||
|
deviceModel: 'Quest 3',
|
||||||
|
osName: 'Android',
|
||||||
|
osVersion: '12',
|
||||||
|
platform: 'MOBILE',
|
||||||
|
androidSdkVersion: 32,
|
||||||
|
hl: 'en',
|
||||||
|
gl: 'US',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'android',
|
||||||
|
id: '3',
|
||||||
|
version: '20.10.38',
|
||||||
|
userAgent:
|
||||||
|
'com.google.android.youtube/20.10.38 (Linux; U; Android 14; en_US) gzip',
|
||||||
|
context: {
|
||||||
|
clientName: 'ANDROID',
|
||||||
|
clientVersion: '20.10.38',
|
||||||
|
osName: 'Android',
|
||||||
|
osVersion: '14',
|
||||||
|
platform: 'MOBILE',
|
||||||
|
androidSdkVersion: 34,
|
||||||
|
hl: 'en',
|
||||||
|
gl: 'US',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ios',
|
||||||
|
id: '5',
|
||||||
|
version: '20.10.1',
|
||||||
|
userAgent:
|
||||||
|
'com.google.ios.youtube/20.10.1 (iPhone16,2; U; CPU iOS 17_4 like Mac OS X)',
|
||||||
|
context: {
|
||||||
|
clientName: 'IOS',
|
||||||
|
clientVersion: '20.10.1',
|
||||||
|
deviceModel: 'iPhone16,2',
|
||||||
|
osName: 'iPhone',
|
||||||
|
osVersion: '17.4.0.21E219',
|
||||||
|
platform: 'MOBILE',
|
||||||
|
hl: 'en',
|
||||||
|
gl: 'US',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function parseVideoId(input) {
|
||||||
|
if (!input) return null;
|
||||||
|
const trimmed = input.trim();
|
||||||
|
if (/^[A-Za-z0-9_-]{11}$/.test(trimmed)) return trimmed;
|
||||||
|
try {
|
||||||
|
const url = new URL(trimmed.startsWith('http') ? trimmed : `https://${trimmed}`);
|
||||||
|
if (url.hostname.endsWith('youtu.be')) {
|
||||||
|
const id = url.pathname.slice(1).split('/')[0];
|
||||||
|
if (/^[A-Za-z0-9_-]{11}$/.test(id)) return id;
|
||||||
|
}
|
||||||
|
const v = url.searchParams.get('v');
|
||||||
|
if (v && /^[A-Za-z0-9_-]{11}$/.test(v)) return v;
|
||||||
|
} catch {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMimeBase(mimeType = '') {
|
||||||
|
return mimeType.split(';')[0].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExt(mimeType = '') {
|
||||||
|
const base = getMimeBase(mimeType);
|
||||||
|
if (base === 'video/mp4' || base === 'audio/mp4') return 'mp4';
|
||||||
|
if (base.includes('webm')) return 'webm';
|
||||||
|
if (base.includes('m4a')) return 'm4a';
|
||||||
|
return 'other';
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseQualityLabel(label = '') {
|
||||||
|
const match = label.match(/(\d{2,4})p/);
|
||||||
|
return match ? Number.parseInt(match[1], 10) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function videoScore(height, fps, bitrate) {
|
||||||
|
return height * 1_000_000_000 + fps * 1_000_000 + bitrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
function audioScore(bitrate, sampleRate) {
|
||||||
|
return bitrate * 1_000_000 + sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortCandidates(items) {
|
||||||
|
return [...items].sort((a, b) => b.score - a.score);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIosSafeVideo(candidate) {
|
||||||
|
const mimeBase = getMimeBase(candidate.mimeType);
|
||||||
|
return mimeBase === 'video/mp4';
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIosSafeAudio(candidate) {
|
||||||
|
const mimeBase = getMimeBase(candidate.mimeType);
|
||||||
|
return mimeBase === 'audio/mp4' || candidate.ext === 'm4a';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchWatchConfig(videoId) {
|
||||||
|
const response = await fetch(`https://www.youtube.com/watch?v=${videoId}&hl=en`, {
|
||||||
|
headers: DEFAULT_HEADERS,
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`watch page failed: ${response.status}`);
|
||||||
|
}
|
||||||
|
const html = await response.text();
|
||||||
|
return {
|
||||||
|
apiKey: html.match(/"INNERTUBE_API_KEY":"([^"]+)"/)?.[1] ?? null,
|
||||||
|
visitorData: html.match(/"VISITOR_DATA":"([^"]+)"/)?.[1] ?? null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchPlayerResponse(videoId, apiKey, visitorData, client) {
|
||||||
|
const endpoint = apiKey
|
||||||
|
? `https://www.youtube.com/youtubei/v1/player?key=${encodeURIComponent(apiKey)}&prettyPrint=false`
|
||||||
|
: `https://www.youtube.com/youtubei/v1/player?prettyPrint=false`;
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
...DEFAULT_HEADERS,
|
||||||
|
'content-type': 'application/json',
|
||||||
|
origin: 'https://www.youtube.com',
|
||||||
|
'x-youtube-client-name': client.id,
|
||||||
|
'x-youtube-client-version': client.version,
|
||||||
|
'user-agent': client.userAgent,
|
||||||
|
...(visitorData ? { 'x-goog-visitor-id': visitorData } : {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
videoId,
|
||||||
|
contentCheckOk: true,
|
||||||
|
racyCheckOk: true,
|
||||||
|
context: { client: client.context },
|
||||||
|
playbackContext: {
|
||||||
|
contentPlaybackContext: { html5Preference: 'HTML5_PREF_WANTS' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch(endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`player API ${client.key} failed: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const input = process.argv[2];
|
||||||
|
const videoId = parseVideoId(input);
|
||||||
|
if (!videoId) {
|
||||||
|
console.error('Usage: node scripts/inspect-youtube-formats.mjs <youtube-id-or-url>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { apiKey, visitorData } = await fetchWatchConfig(videoId);
|
||||||
|
if (!apiKey) {
|
||||||
|
throw new Error('Could not extract INNERTUBE_API_KEY');
|
||||||
|
}
|
||||||
|
|
||||||
|
const adaptiveVideo = [];
|
||||||
|
const adaptiveAudio = [];
|
||||||
|
|
||||||
|
for (const client of CLIENTS) {
|
||||||
|
const data = await fetchPlayerResponse(videoId, apiKey, visitorData, client);
|
||||||
|
const formats = data?.streamingData?.adaptiveFormats ?? [];
|
||||||
|
|
||||||
|
for (const f of formats) {
|
||||||
|
if (!f.url) continue;
|
||||||
|
const mimeBase = getMimeBase(f.mimeType);
|
||||||
|
if (mimeBase.startsWith('video/')) {
|
||||||
|
const height = f.height ?? parseQualityLabel(f.qualityLabel);
|
||||||
|
const fps = f.fps ?? 0;
|
||||||
|
const bitrate = f.bitrate ?? f.averageBitrate ?? 0;
|
||||||
|
adaptiveVideo.push({
|
||||||
|
client: client.key,
|
||||||
|
mimeType: f.mimeType ?? '',
|
||||||
|
ext: getExt(f.mimeType),
|
||||||
|
height,
|
||||||
|
fps,
|
||||||
|
bitrate,
|
||||||
|
score: videoScore(height, fps, bitrate),
|
||||||
|
url: f.url,
|
||||||
|
});
|
||||||
|
} else if (mimeBase.startsWith('audio/')) {
|
||||||
|
const bitrate = f.bitrate ?? f.averageBitrate ?? 0;
|
||||||
|
const sampleRate = Number.parseFloat(f.audioSampleRate ?? '0') || 0;
|
||||||
|
adaptiveAudio.push({
|
||||||
|
client: client.key,
|
||||||
|
mimeType: f.mimeType ?? '',
|
||||||
|
ext: getExt(f.mimeType),
|
||||||
|
bitrate,
|
||||||
|
audioSampleRate: f.audioSampleRate ?? '',
|
||||||
|
score: audioScore(bitrate, sampleRate),
|
||||||
|
url: f.url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortedVideo = sortCandidates(adaptiveVideo);
|
||||||
|
const sortedAudio = sortCandidates(adaptiveAudio);
|
||||||
|
const iosSafeVideo = sortedVideo.filter(isIosSafeVideo);
|
||||||
|
const iosSafeAudio = sortedAudio.filter(isIosSafeAudio);
|
||||||
|
|
||||||
|
console.log(`Video ID: ${videoId}`);
|
||||||
|
console.log('');
|
||||||
|
console.log('Top adaptive video candidates:');
|
||||||
|
for (const item of sortedVideo.slice(0, 8)) {
|
||||||
|
console.log(
|
||||||
|
`- client=${item.client} height=${item.height} fps=${item.fps} bitrate=${item.bitrate} ext=${item.ext} mime=${item.mimeType}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
console.log('Top adaptive audio candidates:');
|
||||||
|
for (const item of sortedAudio.slice(0, 12)) {
|
||||||
|
console.log(
|
||||||
|
`- client=${item.client} bitrate=${item.bitrate} sampleRate=${item.audioSampleRate} ext=${item.ext} mime=${item.mimeType}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
console.log('Top iOS-safe video candidates:');
|
||||||
|
for (const item of iosSafeVideo.slice(0, 8)) {
|
||||||
|
console.log(
|
||||||
|
`- client=${item.client} height=${item.height} fps=${item.fps} bitrate=${item.bitrate} ext=${item.ext} mime=${item.mimeType}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
console.log('Top iOS-safe audio candidates:');
|
||||||
|
for (const item of iosSafeAudio.slice(0, 8)) {
|
||||||
|
console.log(
|
||||||
|
`- client=${item.client} bitrate=${item.bitrate} sampleRate=${item.audioSampleRate} ext=${item.ext} mime=${item.mimeType}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error(error instanceof Error ? error.stack ?? error.message : String(error));
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
@ -40,7 +40,7 @@ import { logger } from '../../utils/logger';
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import { useSettings } from '../../hooks/useSettings';
|
import { useSettings } from '../../hooks/useSettings';
|
||||||
import { useTrailer } from '../../contexts/TrailerContext';
|
import { useTrailer } from '../../contexts/TrailerContext';
|
||||||
import TrailerService from '../../services/trailerService';
|
import TrailerService, { TrailerPlaybackSource } from '../../services/trailerService';
|
||||||
import TrailerPlayer from '../video/TrailerPlayer';
|
import TrailerPlayer from '../video/TrailerPlayer';
|
||||||
import { useLibrary } from '../../hooks/useLibrary';
|
import { useLibrary } from '../../hooks/useLibrary';
|
||||||
import { useToast } from '../../contexts/ToastContext';
|
import { useToast } from '../../contexts/ToastContext';
|
||||||
|
|
@ -202,7 +202,7 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
const [initialLoadComplete, setInitialLoadComplete] = useState(false);
|
const [initialLoadComplete, setInitialLoadComplete] = useState(false);
|
||||||
|
|
||||||
// Trailer state
|
// Trailer state
|
||||||
const [trailerUrl, setTrailerUrl] = useState<string | null>(null);
|
const [trailerSource, setTrailerSource] = useState<TrailerPlaybackSource | null>(null);
|
||||||
const [trailerLoading, setTrailerLoading] = useState(false);
|
const [trailerLoading, setTrailerLoading] = useState(false);
|
||||||
const [trailerError, setTrailerError] = useState(false);
|
const [trailerError, setTrailerError] = useState(false);
|
||||||
const [trailerReady, setTrailerReady] = useState(false);
|
const [trailerReady, setTrailerReady] = useState(false);
|
||||||
|
|
@ -392,14 +392,14 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
setTrailerShouldBePaused(false);
|
setTrailerShouldBePaused(false);
|
||||||
|
|
||||||
// If trailer was ready and loaded, restore the video opacity
|
// If trailer was ready and loaded, restore the video opacity
|
||||||
if (trailerReady && trailerUrl) {
|
if (trailerReady && trailerSource?.videoUrl) {
|
||||||
logger.info('[AppleTVHero] Screen in focus and in view - restoring trailer');
|
logger.info('[AppleTVHero] Screen in focus and in view - restoring trailer');
|
||||||
thumbnailOpacity.value = withTiming(0, { duration: 800 });
|
thumbnailOpacity.value = withTiming(0, { duration: 800 });
|
||||||
trailerOpacity.value = withTiming(1, { duration: 800 });
|
trailerOpacity.value = withTiming(1, { duration: 800 });
|
||||||
setTrailerPlaying(true);
|
setTrailerPlaying(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [isFocused, isOutOfView, setTrailerPlaying, trailerOpacity, thumbnailOpacity, trailerReady, trailerUrl]);
|
}, [isFocused, isOutOfView, setTrailerPlaying, trailerOpacity, thumbnailOpacity, trailerReady, trailerSource]);
|
||||||
|
|
||||||
// Listen to navigation events to stop trailer when navigating to other screens
|
// Listen to navigation events to stop trailer when navigating to other screens
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -425,7 +425,7 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
|
|
||||||
const fetchTrailer = async () => {
|
const fetchTrailer = async () => {
|
||||||
if (!currentItem || !showTrailersEnabled.current) {
|
if (!currentItem || !showTrailersEnabled.current) {
|
||||||
setTrailerUrl(null);
|
setTrailerSource(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -448,7 +448,7 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
|
|
||||||
if (!tmdbId) {
|
if (!tmdbId) {
|
||||||
logger.info('[AppleTVHero] No TMDB ID for:', currentItem.name, '- skipping trailer');
|
logger.info('[AppleTVHero] No TMDB ID for:', currentItem.name, '- skipping trailer');
|
||||||
setTrailerUrl(null);
|
setTrailerSource(null);
|
||||||
setTrailerLoading(false);
|
setTrailerLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -467,7 +467,7 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
|
|
||||||
if (!videosRes.ok) {
|
if (!videosRes.ok) {
|
||||||
logger.warn('[AppleTVHero] TMDB videos fetch failed:', videosRes.status);
|
logger.warn('[AppleTVHero] TMDB videos fetch failed:', videosRes.status);
|
||||||
setTrailerUrl(null);
|
setTrailerSource(null);
|
||||||
setTrailerLoading(false);
|
setTrailerLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -485,31 +485,31 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
|
|
||||||
if (!pick) {
|
if (!pick) {
|
||||||
logger.info('[AppleTVHero] No YouTube video found for:', currentItem.name);
|
logger.info('[AppleTVHero] No YouTube video found for:', currentItem.name);
|
||||||
setTrailerUrl(null);
|
setTrailerSource(null);
|
||||||
setTrailerLoading(false);
|
setTrailerLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info('[AppleTVHero] Extracting stream for videoId:', pick.key, currentItem.name);
|
logger.info('[AppleTVHero] Extracting stream for videoId:', pick.key, currentItem.name);
|
||||||
|
|
||||||
const url = await TrailerService.getTrailerFromVideoId(
|
const source = await TrailerService.getTrailerPlaybackSourceFromVideoId(
|
||||||
pick.key,
|
pick.key,
|
||||||
currentItem.name
|
currentItem.name
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!alive) return;
|
if (!alive) return;
|
||||||
|
|
||||||
if (url) {
|
if (source) {
|
||||||
setTrailerUrl(url);
|
setTrailerSource(source);
|
||||||
} else {
|
} else {
|
||||||
logger.info('[AppleTVHero] No stream extracted for:', currentItem.name);
|
logger.info('[AppleTVHero] No stream extracted for:', currentItem.name);
|
||||||
setTrailerUrl(null);
|
setTrailerSource(null);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!alive) return;
|
if (!alive) return;
|
||||||
logger.error('[AppleTVHero] Error fetching trailer:', error);
|
logger.error('[AppleTVHero] Error fetching trailer:', error);
|
||||||
setTrailerError(true);
|
setTrailerError(true);
|
||||||
setTrailerUrl(null);
|
setTrailerSource(null);
|
||||||
} finally {
|
} finally {
|
||||||
if (alive) {
|
if (alive) {
|
||||||
setTrailerLoading(false);
|
setTrailerLoading(false);
|
||||||
|
|
@ -1094,11 +1094,12 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Hidden preload trailer player */}
|
{/* Hidden preload trailer player */}
|
||||||
{settings?.showTrailers && trailerUrl && !trailerLoading && !trailerError && !trailerPreloaded && (
|
{settings?.showTrailers && trailerSource?.videoUrl && !trailerLoading && !trailerError && !trailerPreloaded && (
|
||||||
<View style={[StyleSheet.absoluteFillObject, { opacity: 0, pointerEvents: 'none' }]}>
|
<View style={[StyleSheet.absoluteFillObject, { opacity: 0, pointerEvents: 'none' }]}>
|
||||||
<TrailerPlayer
|
<TrailerPlayer
|
||||||
key={`preload-${trailerUrl}`}
|
key={`preload-${trailerSource.videoUrl}-${trailerSource.audioUrl ?? 'no-audio'}`}
|
||||||
trailerUrl={trailerUrl}
|
trailerUrl={trailerSource.videoUrl}
|
||||||
|
audioUrl={trailerSource.audioUrl}
|
||||||
autoPlay={false}
|
autoPlay={false}
|
||||||
muted={true}
|
muted={true}
|
||||||
style={StyleSheet.absoluteFillObject}
|
style={StyleSheet.absoluteFillObject}
|
||||||
|
|
@ -1112,13 +1113,14 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Visible trailer player - 60% height with 5% zoom and smooth fade */}
|
{/* Visible trailer player - 60% height with 5% zoom and smooth fade */}
|
||||||
{settings?.showTrailers && trailerUrl && !trailerLoading && !trailerError && trailerPreloaded && (
|
{settings?.showTrailers && trailerSource?.videoUrl && !trailerLoading && !trailerError && trailerPreloaded && (
|
||||||
<Animated.View style={[trailerContainerStyle, trailerParallaxStyle]}>
|
<Animated.View style={[trailerContainerStyle, trailerParallaxStyle]}>
|
||||||
<Animated.View style={trailerVideoStyle}>
|
<Animated.View style={trailerVideoStyle}>
|
||||||
<TrailerPlayer
|
<TrailerPlayer
|
||||||
key={`visible-${trailerUrl}`}
|
key={`visible-${trailerSource.videoUrl}-${trailerSource.audioUrl ?? 'no-audio'}`}
|
||||||
ref={trailerVideoRef}
|
ref={trailerVideoRef}
|
||||||
trailerUrl={trailerUrl}
|
trailerUrl={trailerSource.videoUrl}
|
||||||
|
audioUrl={trailerSource.audioUrl}
|
||||||
autoPlay={!trailerShouldBePaused}
|
autoPlay={!trailerShouldBePaused}
|
||||||
muted={trailerMuted}
|
muted={trailerMuted}
|
||||||
style={StyleSheet.absoluteFillObject}
|
style={StyleSheet.absoluteFillObject}
|
||||||
|
|
@ -1168,7 +1170,7 @@ const AppleTVHero: React.FC<AppleTVHeroProps> = ({
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Trailer control buttons (unmute and fullscreen) */}
|
{/* Trailer control buttons (unmute and fullscreen) */}
|
||||||
{settings?.showTrailers && trailerReady && trailerUrl && (
|
{settings?.showTrailers && trailerReady && trailerSource?.videoUrl && (
|
||||||
<Animated.View style={{
|
<Animated.View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: (Platform.OS === 'android' ? 60 : 70) + insets.top,
|
top: (Platform.OS === 'android' ? 60 : 70) + insets.top,
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ import { useTrailer } from '../../contexts/TrailerContext';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
import { TMDBService } from '../../services/tmdbService';
|
import { TMDBService } from '../../services/tmdbService';
|
||||||
import TrailerService from '../../services/trailerService';
|
import TrailerService, { TrailerPlaybackSource } from '../../services/trailerService';
|
||||||
import TrailerPlayer from '../video/TrailerPlayer';
|
import TrailerPlayer from '../video/TrailerPlayer';
|
||||||
import { HERO_HEIGHT, SCREEN_WIDTH as width, IS_TABLET as isTablet } from '../../constants/dimensions';
|
import { HERO_HEIGHT, SCREEN_WIDTH as width, IS_TABLET as isTablet } from '../../constants/dimensions';
|
||||||
|
|
||||||
|
|
@ -878,7 +878,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
// Image loading state with optimized management
|
// Image loading state with optimized management
|
||||||
const [imageError, setImageError] = useState(false);
|
const [imageError, setImageError] = useState(false);
|
||||||
const [imageLoaded, setImageLoaded] = useState(false);
|
const [imageLoaded, setImageLoaded] = useState(false);
|
||||||
const [trailerUrl, setTrailerUrl] = useState<string | null>(null);
|
const [trailerSource, setTrailerSource] = useState<TrailerPlaybackSource | null>(null);
|
||||||
const [trailerLoading, setTrailerLoading] = useState(false);
|
const [trailerLoading, setTrailerLoading] = useState(false);
|
||||||
const [trailerError, setTrailerError] = useState(false);
|
const [trailerError, setTrailerError] = useState(false);
|
||||||
// Use persistent setting instead of local state
|
// Use persistent setting instead of local state
|
||||||
|
|
@ -1188,12 +1188,12 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
|
|
||||||
logger.info('HeroSection', `Extracting stream for videoId: ${pick.key} (${metadata.name})`);
|
logger.info('HeroSection', `Extracting stream for videoId: ${pick.key} (${metadata.name})`);
|
||||||
|
|
||||||
const url = await TrailerService.getTrailerFromVideoId(pick.key, metadata.name);
|
const source = await TrailerService.getTrailerPlaybackSourceFromVideoId(pick.key, metadata.name);
|
||||||
|
|
||||||
if (!alive) return;
|
if (!alive) return;
|
||||||
|
|
||||||
if (url) {
|
if (source) {
|
||||||
setTrailerUrl(url);
|
setTrailerSource(source);
|
||||||
logger.info('HeroSection', `Trailer loaded for ${metadata.name}`);
|
logger.info('HeroSection', `Trailer loaded for ${metadata.name}`);
|
||||||
} else {
|
} else {
|
||||||
logger.info('HeroSection', `No stream extracted for ${metadata.name}`);
|
logger.info('HeroSection', `No stream extracted for ${metadata.name}`);
|
||||||
|
|
@ -1508,7 +1508,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
try {
|
try {
|
||||||
setTrailerReady(false);
|
setTrailerReady(false);
|
||||||
setTrailerPreloaded(false);
|
setTrailerPreloaded(false);
|
||||||
setTrailerUrl(null);
|
setTrailerSource(null);
|
||||||
trailerOpacity.value = 0;
|
trailerOpacity.value = 0;
|
||||||
thumbnailOpacity.value = 1;
|
thumbnailOpacity.value = 1;
|
||||||
} catch (_e) { }
|
} catch (_e) { }
|
||||||
|
|
@ -1614,14 +1614,15 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Single trailer player - starts hidden (opacity 0), fades in when ready */}
|
{/* Single trailer player - starts hidden (opacity 0), fades in when ready */}
|
||||||
{shouldLoadSecondaryData && settings?.showTrailers && trailerUrl && !trailerLoading && !trailerError && (
|
{shouldLoadSecondaryData && settings?.showTrailers && trailerSource?.videoUrl && !trailerLoading && !trailerError && (
|
||||||
<Animated.View style={[staticStyles.absoluteFill, {
|
<Animated.View style={[staticStyles.absoluteFill, {
|
||||||
opacity: trailerOpacity
|
opacity: trailerOpacity
|
||||||
}, trailerParallaxStyle]}>
|
}, trailerParallaxStyle]}>
|
||||||
<TrailerPlayer
|
<TrailerPlayer
|
||||||
key={`trailer-${trailerUrl}`}
|
key={`trailer-${trailerSource.videoUrl}-${trailerSource.audioUrl ?? 'no-audio'}`}
|
||||||
ref={trailerVideoRef}
|
ref={trailerVideoRef}
|
||||||
trailerUrl={trailerUrl}
|
trailerUrl={trailerSource.videoUrl}
|
||||||
|
audioUrl={trailerSource.audioUrl}
|
||||||
autoPlay={globalTrailerPlaying}
|
autoPlay={globalTrailerPlaying}
|
||||||
muted={trailerMuted}
|
muted={trailerMuted}
|
||||||
style={staticStyles.absoluteFill}
|
style={staticStyles.absoluteFill}
|
||||||
|
|
@ -1641,7 +1642,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Trailer control buttons (unmute and fullscreen) */}
|
{/* Trailer control buttons (unmute and fullscreen) */}
|
||||||
{settings?.showTrailers && trailerReady && trailerUrl && (
|
{settings?.showTrailers && trailerReady && trailerSource?.videoUrl && (
|
||||||
<Animated.View style={{
|
<Animated.View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: Platform.OS === 'android' ? 40 : 50,
|
top: Platform.OS === 'android' ? 40 : 50,
|
||||||
|
|
@ -1750,7 +1751,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* AI Chat button (when trailers are disabled) */}
|
{/* AI Chat button (when trailers are disabled) */}
|
||||||
{settings?.aiChatEnabled && !(settings?.showTrailers && trailerReady && trailerUrl) && (
|
{settings?.aiChatEnabled && !(settings?.showTrailers && trailerReady && trailerSource?.videoUrl) && (
|
||||||
<Animated.View style={{
|
<Animated.View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: Platform.OS === 'android' ? 40 : 50,
|
top: Platform.OS === 'android' ? 40 : 50,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { useTranslation } from 'react-i18next';
|
||||||
import { useTheme } from '../../contexts/ThemeContext';
|
import { useTheme } from '../../contexts/ThemeContext';
|
||||||
import { useTrailer } from '../../contexts/TrailerContext';
|
import { useTrailer } from '../../contexts/TrailerContext';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
import TrailerService from '../../services/trailerService';
|
import TrailerService, { TrailerPlaybackSource } from '../../services/trailerService';
|
||||||
import Video, { VideoRef, OnLoadData, OnProgressData } from 'react-native-video';
|
import Video, { VideoRef, OnLoadData, OnProgressData } from 'react-native-video';
|
||||||
|
|
||||||
const { width, height } = Dimensions.get('window');
|
const { width, height } = Dimensions.get('window');
|
||||||
|
|
@ -38,6 +38,14 @@ interface TrailerModalProps {
|
||||||
contentTitle: string;
|
contentTitle: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isUnsupportedIosMediaFormat(error: any): boolean {
|
||||||
|
if (Platform.OS !== 'ios') return false;
|
||||||
|
|
||||||
|
const errorCode = error?.error?.code;
|
||||||
|
const errorDomain = error?.error?.domain;
|
||||||
|
return errorDomain === 'AVFoundationErrorDomain' && errorCode === -11828;
|
||||||
|
}
|
||||||
|
|
||||||
const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
visible,
|
visible,
|
||||||
onClose,
|
onClose,
|
||||||
|
|
@ -67,7 +75,7 @@ const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
}, [t]);
|
}, [t]);
|
||||||
|
|
||||||
const videoRef = React.useRef<VideoRef>(null);
|
const videoRef = React.useRef<VideoRef>(null);
|
||||||
const [trailerUrl, setTrailerUrl] = useState<string | null>(null);
|
const [playbackSource, setPlaybackSource] = useState<TrailerPlaybackSource | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [isPlaying, setIsPlaying] = useState(false);
|
const [isPlaying, setIsPlaying] = useState(false);
|
||||||
|
|
@ -79,7 +87,7 @@ const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
loadTrailer();
|
loadTrailer();
|
||||||
} else {
|
} else {
|
||||||
// Reset state when modal closes
|
// Reset state when modal closes
|
||||||
setTrailerUrl(null);
|
setPlaybackSource(null);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setError(null);
|
setError(null);
|
||||||
setIsPlaying(false);
|
setIsPlaying(false);
|
||||||
|
|
@ -87,7 +95,7 @@ const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
}
|
}
|
||||||
}, [visible, trailer]);
|
}, [visible, trailer]);
|
||||||
|
|
||||||
const loadTrailer = useCallback(async () => {
|
const loadTrailer = useCallback(async (resetRetryCount = true) => {
|
||||||
if (!trailer) return;
|
if (!trailer) return;
|
||||||
|
|
||||||
// Pause hero section trailer when modal opens
|
// Pause hero section trailer when modal opens
|
||||||
|
|
@ -100,8 +108,10 @@ const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
setTrailerUrl(null);
|
setPlaybackSource(null);
|
||||||
setRetryCount(0); // Reset retry count when starting fresh load
|
if (resetRetryCount) {
|
||||||
|
setRetryCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const youtubeUrl = `https://www.youtube.com/watch?v=${trailer.key}`;
|
const youtubeUrl = `https://www.youtube.com/watch?v=${trailer.key}`;
|
||||||
|
|
@ -109,14 +119,14 @@ const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
logger.info('TrailerModal', `Loading trailer: ${trailer.name} (${youtubeUrl})`);
|
logger.info('TrailerModal', `Loading trailer: ${trailer.name} (${youtubeUrl})`);
|
||||||
|
|
||||||
// Use the direct YouTube URL method - much more efficient!
|
// Use the direct YouTube URL method - much more efficient!
|
||||||
const directUrl = await TrailerService.getTrailerFromYouTubeUrl(
|
const source = await TrailerService.getTrailerPlaybackSourceFromYouTubeUrl(
|
||||||
youtubeUrl,
|
youtubeUrl,
|
||||||
`${contentTitle} - ${trailer.name}`,
|
`${contentTitle} - ${trailer.name}`,
|
||||||
new Date(trailer.published_at).getFullYear().toString()
|
new Date(trailer.published_at).getFullYear().toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (directUrl) {
|
if (source) {
|
||||||
setTrailerUrl(directUrl);
|
setPlaybackSource(source);
|
||||||
setIsPlaying(true);
|
setIsPlaying(true);
|
||||||
logger.info('TrailerModal', `Successfully loaded direct trailer URL for: ${trailer.name}`);
|
logger.info('TrailerModal', `Successfully loaded direct trailer URL for: ${trailer.name}`);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -159,12 +169,20 @@ const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
const handleVideoError = useCallback((error: any) => {
|
const handleVideoError = useCallback((error: any) => {
|
||||||
logger.error('TrailerModal', 'Video error:', error);
|
logger.error('TrailerModal', 'Video error:', error);
|
||||||
|
|
||||||
|
if (isUnsupportedIosMediaFormat(error)) {
|
||||||
|
logger.error('TrailerModal', 'Unsupported iOS trailer format:', error);
|
||||||
|
setError('This trailer format is not supported on iOS.');
|
||||||
|
setLoading(false);
|
||||||
|
setIsPlaying(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (retryCount < 2) {
|
if (retryCount < 2) {
|
||||||
logger.info('TrailerModal', `Re-extracting trailer (attempt ${retryCount + 1}/2)`);
|
logger.info('TrailerModal', `Re-extracting trailer (attempt ${retryCount + 1}/2)`);
|
||||||
setRetryCount(prev => prev + 1);
|
setRetryCount(prev => prev + 1);
|
||||||
// Invalidate cache so loadTrailer gets a fresh URL, not the same bad one
|
// Invalidate cache so loadTrailer gets a fresh URL, not the same bad one
|
||||||
if (trailer?.key) TrailerService.invalidateCache(trailer.key);
|
if (trailer?.key) TrailerService.invalidateCache(trailer.key);
|
||||||
loadTrailer();
|
loadTrailer(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,7 +260,9 @@ const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
</Text>
|
</Text>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[styles.retryButton, { backgroundColor: currentTheme.colors.primary }]}
|
style={[styles.retryButton, { backgroundColor: currentTheme.colors.primary }]}
|
||||||
onPress={loadTrailer}
|
onPress={() => {
|
||||||
|
void loadTrailer(true);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Text style={styles.retryButtonText}>{t('common.try_again')}</Text>
|
<Text style={styles.retryButtonText}>{t('common.try_again')}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
@ -250,21 +270,28 @@ const TrailerModal: React.FC<TrailerModalProps> = memo(({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Render the Video as soon as we have a URL; keep spinner overlay until onLoad */}
|
{/* Render the Video as soon as we have a URL; keep spinner overlay until onLoad */}
|
||||||
{trailerUrl && !error && (
|
{playbackSource?.videoUrl && !error && (
|
||||||
<View style={styles.playerWrapper}>
|
<View style={styles.playerWrapper}>
|
||||||
<Video
|
<Video
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
source={(() => {
|
source={(() => {
|
||||||
const lower = (trailerUrl || '').toLowerCase();
|
const lower = playbackSource.videoUrl.toLowerCase();
|
||||||
const looksLikeHls = /\.m3u8(\b|$)/.test(lower) || /hls|playlist|m3u/.test(lower);
|
const looksLikeHls = /\.m3u8(\b|$)/.test(lower) || /hls|playlist|m3u/.test(lower);
|
||||||
if (Platform.OS === 'android') {
|
if (Platform.OS === 'android') {
|
||||||
const headers = { 'User-Agent': 'Nuvio/1.0 (Android)' };
|
const headers = { 'User-Agent': 'Nuvio/1.0 (Android)' };
|
||||||
if (looksLikeHls) {
|
if (looksLikeHls) {
|
||||||
return { uri: trailerUrl, type: 'm3u8', headers } as any;
|
return { uri: playbackSource.videoUrl, type: 'm3u8', headers } as any;
|
||||||
}
|
}
|
||||||
return { uri: trailerUrl, headers } as any;
|
return {
|
||||||
|
uri: playbackSource.videoUrl,
|
||||||
|
headers,
|
||||||
|
...(playbackSource.audioUrl ? { audioUri: playbackSource.audioUrl } : null),
|
||||||
|
} as any;
|
||||||
}
|
}
|
||||||
return { uri: trailerUrl } as any;
|
return {
|
||||||
|
uri: playbackSource.videoUrl,
|
||||||
|
...(playbackSource.audioUrl ? { audioUri: playbackSource.audioUrl } : null),
|
||||||
|
} as any;
|
||||||
})()}
|
})()}
|
||||||
style={styles.player}
|
style={styles.player}
|
||||||
controls={true}
|
controls={true}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ const isTablet = width >= 768;
|
||||||
|
|
||||||
interface TrailerPlayerProps {
|
interface TrailerPlayerProps {
|
||||||
trailerUrl: string;
|
trailerUrl: string;
|
||||||
|
audioUrl?: string | null;
|
||||||
autoPlay?: boolean;
|
autoPlay?: boolean;
|
||||||
muted?: boolean;
|
muted?: boolean;
|
||||||
onLoadStart?: () => void;
|
onLoadStart?: () => void;
|
||||||
|
|
@ -46,6 +47,7 @@ interface TrailerPlayerProps {
|
||||||
|
|
||||||
const TrailerPlayer = React.forwardRef<any, TrailerPlayerProps>(({
|
const TrailerPlayer = React.forwardRef<any, TrailerPlayerProps>(({
|
||||||
trailerUrl,
|
trailerUrl,
|
||||||
|
audioUrl,
|
||||||
autoPlay = true,
|
autoPlay = true,
|
||||||
muted = true,
|
muted = true,
|
||||||
onLoadStart,
|
onLoadStart,
|
||||||
|
|
@ -381,9 +383,16 @@ const TrailerPlayer = React.forwardRef<any, TrailerPlayerProps>(({
|
||||||
if (looksLikeHls) {
|
if (looksLikeHls) {
|
||||||
return { uri: trailerUrl, type: 'm3u8', headers: androidHeaders } as any;
|
return { uri: trailerUrl, type: 'm3u8', headers: androidHeaders } as any;
|
||||||
}
|
}
|
||||||
return { uri: trailerUrl, headers: androidHeaders } as any;
|
return {
|
||||||
|
uri: trailerUrl,
|
||||||
|
headers: androidHeaders,
|
||||||
|
...(audioUrl ? { audioUri: audioUrl } : null),
|
||||||
|
} as any;
|
||||||
}
|
}
|
||||||
return { uri: trailerUrl } as any;
|
return {
|
||||||
|
uri: trailerUrl,
|
||||||
|
...(audioUrl ? { audioUri: audioUrl } : null),
|
||||||
|
} as any;
|
||||||
})()}
|
})()}
|
||||||
style={styles.video}
|
style={styles.video}
|
||||||
resizeMode="cover"
|
resizeMode="cover"
|
||||||
|
|
|
||||||
|
|
@ -472,15 +472,12 @@ const DownloadsScreen: React.FC = () => {
|
||||||
case 'infuse':
|
case 'infuse':
|
||||||
externalPlayerUrls = [
|
externalPlayerUrls = [
|
||||||
`infuse://x-callback-url/play?url=${streamUrl}`,
|
`infuse://x-callback-url/play?url=${streamUrl}`,
|
||||||
`infuse://play?url=${streamUrl}`,
|
|
||||||
`infuse://${streamUrl}`
|
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'vidhub':
|
case 'vidhub':
|
||||||
externalPlayerUrls = [
|
externalPlayerUrls = [
|
||||||
`vidhub://play?url=${streamUrl}`,
|
`open-vidhub://x-callback-url/open?url=${streamUrl}`,
|
||||||
`vidhub://${streamUrl}`
|
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -493,12 +493,12 @@ export const useStreamsScreen = () => {
|
||||||
case 'infuse':
|
case 'infuse':
|
||||||
externalPlayerUrls = [
|
externalPlayerUrls = [
|
||||||
`infuse://x-callback-url/play?url=${streamUrl}`,
|
`infuse://x-callback-url/play?url=${streamUrl}`,
|
||||||
`infuse://play?url=${streamUrl}`,
|
|
||||||
`infuse://${streamUrl}`,
|
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
case 'vidhub':
|
case 'vidhub':
|
||||||
externalPlayerUrls = [`vidhub://play?url=${streamUrl}`, `vidhub://${streamUrl}`];
|
externalPlayerUrls = [
|
||||||
|
`open-vidhub://x-callback-url/open?url=${streamUrl}`,
|
||||||
|
];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
navigateToPlayer(stream);
|
navigateToPlayer(stream);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { logger } from '../utils/logger';
|
import { logger } from '../utils/logger';
|
||||||
import { Platform } from 'react-native';
|
import { Platform } from 'react-native';
|
||||||
import { YouTubeExtractor } from './youtubeExtractor';
|
import { YouTubeExtractionResult, YouTubeExtractor } from './youtubeExtractor';
|
||||||
|
|
||||||
export interface TrailerData {
|
export interface TrailerData {
|
||||||
url: string;
|
url: string;
|
||||||
|
|
@ -8,8 +8,14 @@ export interface TrailerData {
|
||||||
year: number;
|
year: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TrailerPlaybackSource {
|
||||||
|
videoUrl: string;
|
||||||
|
audioUrl: string | null;
|
||||||
|
quality?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface CacheEntry {
|
interface CacheEntry {
|
||||||
url: string;
|
source: TrailerPlaybackSource;
|
||||||
expiresAt: number;
|
expiresAt: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,6 +37,15 @@ export class TrailerService {
|
||||||
title?: string,
|
title?: string,
|
||||||
year?: number
|
year?: number
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
|
const source = await this.getTrailerPlaybackSourceFromVideoId(youtubeVideoId, title, year);
|
||||||
|
return source?.videoUrl ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getTrailerPlaybackSourceFromVideoId(
|
||||||
|
youtubeVideoId: string,
|
||||||
|
title?: string,
|
||||||
|
year?: number
|
||||||
|
): Promise<TrailerPlaybackSource | null> {
|
||||||
if (!youtubeVideoId) return null;
|
if (!youtubeVideoId) return null;
|
||||||
|
|
||||||
logger.info('TrailerService', `getTrailerFromVideoId: ${youtubeVideoId} (${title ?? '?'} ${year ?? ''})`);
|
logger.info('TrailerService', `getTrailerFromVideoId: ${youtubeVideoId} (${title ?? '?'} ${year ?? ''})`);
|
||||||
|
|
@ -43,11 +58,12 @@ export class TrailerService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const platform = Platform.OS === 'android' ? 'android' : 'ios';
|
const platform = Platform.OS === 'android' ? 'android' : 'ios';
|
||||||
const url = await YouTubeExtractor.getBestStreamUrl(youtubeVideoId, platform);
|
const extracted = await YouTubeExtractor.extract(youtubeVideoId, platform);
|
||||||
if (url) {
|
if (extracted) {
|
||||||
|
const source = this.toPlaybackSource(extracted);
|
||||||
logger.info('TrailerService', `Extraction succeeded for ${youtubeVideoId}`);
|
logger.info('TrailerService', `Extraction succeeded for ${youtubeVideoId}`);
|
||||||
this.setCache(youtubeVideoId, url);
|
this.setCache(youtubeVideoId, source);
|
||||||
return url;
|
return source;
|
||||||
}
|
}
|
||||||
logger.warn('TrailerService', `Extraction returned null for ${youtubeVideoId}`);
|
logger.warn('TrailerService', `Extraction returned null for ${youtubeVideoId}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -66,6 +82,15 @@ export class TrailerService {
|
||||||
title?: string,
|
title?: string,
|
||||||
year?: string
|
year?: string
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
|
const source = await this.getTrailerPlaybackSourceFromYouTubeUrl(youtubeUrl, title, year);
|
||||||
|
return source?.videoUrl ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getTrailerPlaybackSourceFromYouTubeUrl(
|
||||||
|
youtubeUrl: string,
|
||||||
|
title?: string,
|
||||||
|
year?: string
|
||||||
|
): Promise<TrailerPlaybackSource | null> {
|
||||||
logger.info('TrailerService', `getTrailerFromYouTubeUrl: ${youtubeUrl}`);
|
logger.info('TrailerService', `getTrailerFromYouTubeUrl: ${youtubeUrl}`);
|
||||||
|
|
||||||
const videoId = YouTubeExtractor.parseVideoId(youtubeUrl);
|
const videoId = YouTubeExtractor.parseVideoId(youtubeUrl);
|
||||||
|
|
@ -74,7 +99,7 @@ export class TrailerService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getTrailerFromVideoId(
|
return this.getTrailerPlaybackSourceFromVideoId(
|
||||||
videoId,
|
videoId,
|
||||||
title,
|
title,
|
||||||
year ? parseInt(year, 10) : undefined
|
year ? parseInt(year, 10) : undefined
|
||||||
|
|
@ -135,7 +160,7 @@ export class TrailerService {
|
||||||
// Private — cache
|
// Private — cache
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
private static getCached(key: string): string | null {
|
private static getCached(key: string): TrailerPlaybackSource | null {
|
||||||
const entry = this.urlCache.get(key);
|
const entry = this.urlCache.get(key);
|
||||||
if (!entry) return null;
|
if (!entry) return null;
|
||||||
if (Date.now() > entry.expiresAt) {
|
if (Date.now() > entry.expiresAt) {
|
||||||
|
|
@ -144,9 +169,9 @@ export class TrailerService {
|
||||||
}
|
}
|
||||||
// Check the URL's own CDN expiry — googlevideo.com URLs carry an `expire`
|
// Check the URL's own CDN expiry — googlevideo.com URLs carry an `expire`
|
||||||
// param (Unix timestamp). Treat as stale if it expires within 2 minutes.
|
// param (Unix timestamp). Treat as stale if it expires within 2 minutes.
|
||||||
if (entry.url.includes('googlevideo.com')) {
|
if (entry.source.videoUrl.includes('googlevideo.com')) {
|
||||||
try {
|
try {
|
||||||
const u = new URL(entry.url);
|
const u = new URL(entry.source.videoUrl);
|
||||||
const expire = u.searchParams.get('expire');
|
const expire = u.searchParams.get('expire');
|
||||||
if (expire) {
|
if (expire) {
|
||||||
const expiresAt = parseInt(expire, 10) * 1000;
|
const expiresAt = parseInt(expire, 10) * 1000;
|
||||||
|
|
@ -158,16 +183,24 @@ export class TrailerService {
|
||||||
}
|
}
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
return entry.url;
|
return entry.source;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static setCache(key: string, url: string): void {
|
private static setCache(key: string, source: TrailerPlaybackSource): void {
|
||||||
this.urlCache.set(key, { url, expiresAt: Date.now() + this.CACHE_TTL_MS });
|
this.urlCache.set(key, { source, expiresAt: Date.now() + this.CACHE_TTL_MS });
|
||||||
if (this.urlCache.size > 100) {
|
if (this.urlCache.size > 100) {
|
||||||
const oldest = this.urlCache.keys().next().value;
|
const oldest = this.urlCache.keys().next().value;
|
||||||
if (oldest) this.urlCache.delete(oldest);
|
if (oldest) this.urlCache.delete(oldest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static toPlaybackSource(extracted: YouTubeExtractionResult): TrailerPlaybackSource {
|
||||||
|
return {
|
||||||
|
videoUrl: extracted.videoUrl,
|
||||||
|
audioUrl: extracted.audioUrl,
|
||||||
|
quality: extracted.quality,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TrailerService;
|
export default TrailerService;
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ const DEFAULT_HEADERS: Record<string, string> = {
|
||||||
'user-agent': DEFAULT_USER_AGENT,
|
'user-agent': DEFAULT_USER_AGENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PREFERRED_ADAPTIVE_CLIENT = 'android_vr';
|
|
||||||
const REQUEST_TIMEOUT_MS = 6000; // player API + HLS manifest requests
|
const REQUEST_TIMEOUT_MS = 6000; // player API + HLS manifest requests
|
||||||
const WATCH_PAGE_TIMEOUT_MS = 3000; // watch page scrape — best-effort only
|
const WATCH_PAGE_TIMEOUT_MS = 3000; // watch page scrape — best-effort only
|
||||||
const MAX_RETRIES = 2; // retry extraction up to 2 times on total failure
|
const MAX_RETRIES = 2; // retry extraction up to 2 times on total failure
|
||||||
|
|
@ -182,6 +181,12 @@ function getMimeBase(mimeType?: string): string {
|
||||||
return (mimeType ?? '').split(';')[0].trim();
|
return (mimeType ?? '').split(';')[0].trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCodecs(mimeType?: string): string[] {
|
||||||
|
const match = (mimeType ?? '').match(/codecs="([^"]+)"/i);
|
||||||
|
if (!match) return [];
|
||||||
|
return match[1].split(',').map(codec => codec.trim().toLowerCase()).filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
function getExt(mimeType?: string): 'mp4' | 'webm' | 'm4a' | 'other' {
|
function getExt(mimeType?: string): 'mp4' | 'webm' | 'm4a' | 'other' {
|
||||||
const base = getMimeBase(mimeType);
|
const base = getMimeBase(mimeType);
|
||||||
if (base === 'video/mp4' || base === 'audio/mp4') return 'mp4';
|
if (base === 'video/mp4' || base === 'audio/mp4') return 'mp4';
|
||||||
|
|
@ -260,16 +265,6 @@ async function validateUrl(url: string, userAgent: string): Promise<boolean> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// android_vr preferred selection — only fall back to other clients if
|
|
||||||
// android_vr returned zero formats (likely PO token required for others)
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
function filterPreferAndroidVr(items: StreamCandidate[]): StreamCandidate[] {
|
|
||||||
const fromVr = items.filter(c => c.client === 'android_vr');
|
|
||||||
return fromVr.length > 0 ? fromVr : items;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortCandidates(items: StreamCandidate[]): StreamCandidate[] {
|
function sortCandidates(items: StreamCandidate[]): StreamCandidate[] {
|
||||||
return [...items].sort((a, b) => {
|
return [...items].sort((a, b) => {
|
||||||
if (b.score !== a.score) return b.score - a.score;
|
if (b.score !== a.score) return b.score - a.score;
|
||||||
|
|
@ -279,13 +274,39 @@ function sortCandidates(items: StreamCandidate[]): StreamCandidate[] {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function pickBestForClient(
|
async function findBestValidatedCandidate(
|
||||||
items: StreamCandidate[],
|
items: StreamCandidate[],
|
||||||
preferredClient: string,
|
userAgent: string,
|
||||||
): StreamCandidate | null {
|
label: string,
|
||||||
const fromPreferred = items.filter(c => c.client === preferredClient);
|
): Promise<StreamCandidate | null> {
|
||||||
const pool = fromPreferred.length > 0 ? fromPreferred : items;
|
for (const candidate of sortCandidates(items)) {
|
||||||
return sortCandidates(pool)[0] ?? null;
|
const valid = await validateUrl(candidate.url, userAgent);
|
||||||
|
if (valid) return candidate;
|
||||||
|
logger.warn('YouTubeExtractor', `${label} URL invalid, trying next candidate`);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHlsQualityScore(variant: HlsVariant): number {
|
||||||
|
return variant.height * 1_000_000_000 + variant.bandwidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIosCompatibleSeparateVideo(candidate: StreamCandidate): boolean {
|
||||||
|
if (getMimeBase(candidate.mimeType) !== 'video/mp4') return false;
|
||||||
|
const codecs = getCodecs(candidate.mimeType);
|
||||||
|
if (codecs.length === 0) return true;
|
||||||
|
return codecs.some(codec =>
|
||||||
|
codec.startsWith('avc1') ||
|
||||||
|
codec.startsWith('hvc1') ||
|
||||||
|
codec.startsWith('hev1'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIosCompatibleSeparateAudio(candidate: StreamCandidate): boolean {
|
||||||
|
if (getMimeBase(candidate.mimeType) !== 'audio/mp4') return false;
|
||||||
|
const codecs = getCodecs(candidate.mimeType);
|
||||||
|
if (codecs.length === 0) return true;
|
||||||
|
return codecs.some(codec => codec.startsWith('mp4a'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
@ -580,12 +601,8 @@ export class YouTubeExtractor {
|
||||||
* Matches the Kotlin InAppYouTubeExtractor approach:
|
* Matches the Kotlin InAppYouTubeExtractor approach:
|
||||||
* 1. Fetch watch page for dynamic API key + visitor data
|
* 1. Fetch watch page for dynamic API key + visitor data
|
||||||
* 2. Try ALL clients, collect formats from all that succeed
|
* 2. Try ALL clients, collect formats from all that succeed
|
||||||
* 3. Pick best HLS variant (by resolution/bandwidth) as primary
|
* 3. Prefer separate adaptive video+audio when available
|
||||||
* 4. Fall back to best progressive (muxed) if no HLS
|
* 4. Fall back to HLS/progressive muxed sources
|
||||||
*
|
|
||||||
* Note: Unlike the Kotlin version, we do not return separate videoUrl/audioUrl
|
|
||||||
* for adaptive streams — react-native-video cannot merge two sources. HLS
|
|
||||||
* provides the best quality without needing a separate audio track.
|
|
||||||
*/
|
*/
|
||||||
static async extract(
|
static async extract(
|
||||||
videoIdOrUrl: string,
|
videoIdOrUrl: string,
|
||||||
|
|
@ -650,63 +667,140 @@ export class YouTubeExtractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefer android_vr formats exclusively — other clients may require PO tokens
|
const progressiveCandidates = sortCandidates(progressive);
|
||||||
// and return URLs that 403 at the CDN level during playback
|
const adaptiveVideoCandidates = sortCandidates(adaptiveVideo);
|
||||||
const preferredProgressive = sortCandidates(filterPreferAndroidVr(progressive));
|
const adaptiveAudioCandidates = sortCandidates(adaptiveAudio);
|
||||||
const bestAdaptiveVideo = pickBestForClient(adaptiveVideo, PREFERRED_ADAPTIVE_CLIENT);
|
const compatibleAdaptiveVideoCandidates =
|
||||||
const bestAdaptiveAudio = pickBestForClient(adaptiveAudio, PREFERRED_ADAPTIVE_CLIENT);
|
effectivePlatform === 'ios'
|
||||||
|
? adaptiveVideoCandidates.filter(isIosCompatibleSeparateVideo)
|
||||||
|
: adaptiveVideoCandidates;
|
||||||
|
const compatibleAdaptiveAudioCandidates =
|
||||||
|
effectivePlatform === 'ios'
|
||||||
|
? adaptiveAudioCandidates.filter(isIosCompatibleSeparateAudio)
|
||||||
|
: adaptiveAudioCandidates;
|
||||||
|
|
||||||
if (bestHls) logger.info('YouTubeExtractor', `Best HLS: ${bestHls.height}p ${bestHls.bandwidth}bps`);
|
if (bestHls) logger.info('YouTubeExtractor', `Best HLS: ${bestHls.height}p ${bestHls.bandwidth}bps`);
|
||||||
if (preferredProgressive[0]) logger.info('YouTubeExtractor', `Best progressive: ${preferredProgressive[0].height}p client=${preferredProgressive[0].client}`);
|
if (progressiveCandidates[0]) logger.info('YouTubeExtractor', `Best progressive: ${progressiveCandidates[0].height}p client=${progressiveCandidates[0].client}`);
|
||||||
if (bestAdaptiveVideo) logger.info('YouTubeExtractor', `Best adaptive video: ${bestAdaptiveVideo.height}p client=${bestAdaptiveVideo.client}`);
|
if (adaptiveVideoCandidates[0]) logger.info('YouTubeExtractor', `Best adaptive video: ${adaptiveVideoCandidates[0].height}p client=${adaptiveVideoCandidates[0].client}`);
|
||||||
if (bestAdaptiveAudio) logger.info('YouTubeExtractor', `Best adaptive audio: ${bestAdaptiveAudio.bitrate}bps client=${bestAdaptiveAudio.client}`);
|
if (adaptiveAudioCandidates[0]) logger.info('YouTubeExtractor', `Best adaptive audio: ${adaptiveAudioCandidates[0].bitrate}bps client=${adaptiveAudioCandidates[0].client}`);
|
||||||
|
if (effectivePlatform === 'ios') {
|
||||||
|
if (compatibleAdaptiveVideoCandidates[0]) {
|
||||||
|
logger.info(
|
||||||
|
'YouTubeExtractor',
|
||||||
|
`Best iOS-compatible adaptive video: ${compatibleAdaptiveVideoCandidates[0].height}p client=${compatibleAdaptiveVideoCandidates[0].client} mime=${compatibleAdaptiveVideoCandidates[0].mimeType}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (compatibleAdaptiveAudioCandidates[0]) {
|
||||||
|
logger.info(
|
||||||
|
'YouTubeExtractor',
|
||||||
|
`Best iOS-compatible adaptive audio: ${compatibleAdaptiveAudioCandidates[0].bitrate}bps client=${compatibleAdaptiveAudioCandidates[0].client} mime=${compatibleAdaptiveAudioCandidates[0].mimeType}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VR client user agent used for CDN URL validation
|
// VR client user agent used for CDN URL validation
|
||||||
const vrUserAgent = CLIENTS.find(c => c.key === 'android_vr')!.userAgent;
|
const vrUserAgent = CLIENTS.find(c => c.key === 'android_vr')!.userAgent;
|
||||||
|
|
||||||
// Step 4: select final source with URL validation
|
// Step 4: validate the best candidates per source type, then pick the
|
||||||
// Priority: HLS > progressive muxed
|
// highest-quality playable result.
|
||||||
// HLS manifests don't need validation — they're not CDN segment URLs
|
const validatedAdaptiveVideo = await findBestValidatedCandidate(
|
||||||
if (bestHls) {
|
compatibleAdaptiveVideoCandidates,
|
||||||
// Return the specific best variant URL, not the master playlist.
|
vrUserAgent,
|
||||||
// Master playlist lets the player pick quality adaptively (often starts low).
|
'Adaptive video',
|
||||||
// Pinning to the best variant ensures consistent high quality playback.
|
);
|
||||||
logger.info('YouTubeExtractor', `Using HLS variant: ${summarizeUrl(bestHls.url)} ${bestHls.height}p`);
|
const validatedAdaptiveAudio = await findBestValidatedCandidate(
|
||||||
|
compatibleAdaptiveAudioCandidates,
|
||||||
|
vrUserAgent,
|
||||||
|
'Adaptive audio',
|
||||||
|
);
|
||||||
|
const validatedProgressive = await findBestValidatedCandidate(
|
||||||
|
progressiveCandidates,
|
||||||
|
vrUserAgent,
|
||||||
|
'Progressive',
|
||||||
|
);
|
||||||
|
|
||||||
|
const adaptivePlayback =
|
||||||
|
validatedAdaptiveVideo && validatedAdaptiveAudio
|
||||||
|
? {
|
||||||
|
type: 'adaptive' as const,
|
||||||
|
videoUrl: validatedAdaptiveVideo.url,
|
||||||
|
audioUrl: validatedAdaptiveAudio.url,
|
||||||
|
quality: `${validatedAdaptiveVideo.height}p`,
|
||||||
|
score: validatedAdaptiveVideo.score,
|
||||||
|
height: validatedAdaptiveVideo.height,
|
||||||
|
audioBitrate: validatedAdaptiveAudio.bitrate,
|
||||||
|
videoClient: validatedAdaptiveVideo.client,
|
||||||
|
videoMimeType: validatedAdaptiveVideo.mimeType,
|
||||||
|
videoExt: validatedAdaptiveVideo.ext,
|
||||||
|
audioClient: validatedAdaptiveAudio.client,
|
||||||
|
audioMimeType: validatedAdaptiveAudio.mimeType,
|
||||||
|
audioExt: validatedAdaptiveAudio.ext,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const progressivePlayback = validatedProgressive
|
||||||
|
? {
|
||||||
|
type: 'progressive' as const,
|
||||||
|
videoUrl: validatedProgressive.url,
|
||||||
|
audioUrl: null,
|
||||||
|
quality: `${validatedProgressive.height}p`,
|
||||||
|
score: validatedProgressive.score,
|
||||||
|
height: validatedProgressive.height,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const hlsPlayback = bestHls
|
||||||
|
? {
|
||||||
|
type: 'hls' as const,
|
||||||
|
videoUrl: bestHls.manifestUrl,
|
||||||
|
audioUrl: null,
|
||||||
|
quality: `${bestHls.height}p`,
|
||||||
|
score: getHlsQualityScore(bestHls),
|
||||||
|
height: bestHls.height,
|
||||||
|
bandwidth: bestHls.bandwidth,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const bestPlayable = [adaptivePlayback, progressivePlayback, hlsPlayback]
|
||||||
|
.filter((candidate): candidate is NonNullable<typeof candidate> => candidate !== null)
|
||||||
|
.sort((a, b) => b.score - a.score)[0] ?? null;
|
||||||
|
|
||||||
|
if (bestPlayable) {
|
||||||
|
if (bestPlayable.type === 'adaptive') {
|
||||||
|
logger.info(
|
||||||
|
'YouTubeExtractor',
|
||||||
|
`Using separate adaptive streams: video=${bestPlayable.height}p ` +
|
||||||
|
`videoClient=${bestPlayable.videoClient} videoMime=${bestPlayable.videoMimeType} videoExt=${bestPlayable.videoExt} ` +
|
||||||
|
`audio=${bestPlayable.audioBitrate}bps audioClient=${bestPlayable.audioClient} ` +
|
||||||
|
`audioMime=${bestPlayable.audioMimeType} audioExt=${bestPlayable.audioExt}`
|
||||||
|
);
|
||||||
|
} else if (bestPlayable.type === 'progressive') {
|
||||||
|
logger.info(
|
||||||
|
'YouTubeExtractor',
|
||||||
|
`Using progressive: ${summarizeUrl(bestPlayable.videoUrl)} ${bestPlayable.height}p`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
logger.info(
|
||||||
|
'YouTubeExtractor',
|
||||||
|
`Using HLS manifest: ${summarizeUrl(bestPlayable.videoUrl)} ${bestPlayable.height}p`
|
||||||
|
);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
videoUrl: bestHls.url,
|
videoUrl: bestPlayable.videoUrl,
|
||||||
audioUrl: null,
|
audioUrl: bestPlayable.audioUrl,
|
||||||
quality: `${bestHls.height}p`,
|
quality: bestPlayable.quality,
|
||||||
videoId,
|
videoId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate progressive candidates in order, return first valid one
|
if (validatedAdaptiveVideo) {
|
||||||
for (const candidate of preferredProgressive) {
|
logger.warn('YouTubeExtractor', `Using video-only adaptive fallback (no audio): ${validatedAdaptiveVideo.height}p`);
|
||||||
const valid = await validateUrl(candidate.url, vrUserAgent);
|
return {
|
||||||
if (valid) {
|
videoUrl: validatedAdaptiveVideo.url,
|
||||||
logger.info('YouTubeExtractor', `Using progressive: ${summarizeUrl(candidate.url)} ${candidate.height}p`);
|
audioUrl: null,
|
||||||
return {
|
quality: `${validatedAdaptiveVideo.height}p`,
|
||||||
videoUrl: candidate.url,
|
videoId,
|
||||||
audioUrl: null,
|
};
|
||||||
quality: `${candidate.height}p`,
|
|
||||||
videoId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
logger.warn('YouTubeExtractor', `Progressive URL invalid, trying next candidate`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last resort: video-only adaptive (no audio, but beats nothing)
|
|
||||||
if (bestAdaptiveVideo) {
|
|
||||||
const valid = await validateUrl(bestAdaptiveVideo.url, vrUserAgent);
|
|
||||||
if (valid) {
|
|
||||||
logger.warn('YouTubeExtractor', `Using video-only adaptive (no audio): ${bestAdaptiveVideo.height}p`);
|
|
||||||
return {
|
|
||||||
videoUrl: bestAdaptiveVideo.url,
|
|
||||||
audioUrl: null,
|
|
||||||
quality: `${bestAdaptiveVideo.height}p`,
|
|
||||||
videoId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn('YouTubeExtractor', `No playable source for videoId=${videoId}`);
|
logger.warn('YouTubeExtractor', `No playable source for videoId=${videoId}`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue