diff --git a/TrailerService b/TrailerService new file mode 160000 index 00000000..2cb2c6d1 --- /dev/null +++ b/TrailerService @@ -0,0 +1 @@ +Subproject commit 2cb2c6d1a3ca60416160bdb28be800fe249207fc diff --git a/babel.config.js b/babel.config.js index a5c5a10b..a31657b0 100644 --- a/babel.config.js +++ b/babel.config.js @@ -4,6 +4,7 @@ module.exports = function (api) { presets: ['babel-preset-expo'], plugins: [ 'react-native-worklets/plugin', + 'react-native-boost/plugin', ], env: { production: { diff --git a/enginefs b/enginefs new file mode 160000 index 00000000..3a70b36f --- /dev/null +++ b/enginefs @@ -0,0 +1 @@ +Subproject commit 3a70b36f873307cd83fb3178bb891f73cf73aa87 diff --git a/ios/Nuvio.xcodeproj/project.pbxproj b/ios/Nuvio.xcodeproj/project.pbxproj index 4bf304a6..1d96622b 100644 --- a/ios/Nuvio.xcodeproj/project.pbxproj +++ b/ios/Nuvio.xcodeproj/project.pbxproj @@ -460,8 +460,8 @@ "-lc++", ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; - PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.app; - PRODUCT_NAME = "Nuvio"; + PRODUCT_BUNDLE_IDENTIFIER = com.nuviohub.app; + PRODUCT_NAME = Nuvio; SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -492,8 +492,8 @@ "-lc++", ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; - PRODUCT_BUNDLE_IDENTIFIER = "com.nuvio.app"; - PRODUCT_NAME = "Nuvio"; + PRODUCT_BUNDLE_IDENTIFIER = com.nuviohub.app; + PRODUCT_NAME = Nuvio; SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/ios/Nuvio.xcodeproj/xcshareddata/xcschemes/Nuvio.xcscheme b/ios/Nuvio.xcodeproj/xcshareddata/xcschemes/Nuvio.xcscheme index d56adf85..60f9eb04 100644 --- a/ios/Nuvio.xcodeproj/xcshareddata/xcschemes/Nuvio.xcscheme +++ b/ios/Nuvio.xcodeproj/xcshareddata/xcschemes/Nuvio.xcscheme @@ -82,7 +82,7 @@ buildConfiguration = "Debug"> diff --git a/ios/Nuvio/Info.plist b/ios/Nuvio/Info.plist index d701baa9..4ab9b8d0 100644 --- a/ios/Nuvio/Info.plist +++ b/ios/Nuvio/Info.plist @@ -1,101 +1,98 @@ - - CADisableMinimumFrameDurationOnPhone - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Nuvio - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.2.5 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleURLSchemes - - nuvio - com.nuvio.app - - - - CFBundleURLSchemes - - exp+nuvio - - - - CFBundleVersion - 20 - LSMinimumSystemVersion - 12.0 - LSRequiresIPhoneOS - - LSSupportsOpeningDocumentsInPlace - - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - NSBonjourServices - - _http._tcp - - NSLocalNetworkUsageDescription - Allow $(PRODUCT_NAME) to access your local network - NSMicrophoneUsageDescription - This app does not require microphone access. - RCTNewArchEnabled - - RCTRootViewBackgroundColor - 4278322180 - UIBackgroundModes - - audio - - UIFileSharingEnabled - - UILaunchStoryboardName - SplashScreen - UIRequiredDeviceCapabilities - - arm64 - - UIRequiresFullScreen - - UIStatusBarStyle - UIStatusBarStyleDefault - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIUserInterfaceStyle - Dark - UIViewControllerBasedStatusBarAppearance - - - \ No newline at end of file + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Nuvio + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.2.5 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleURLSchemes + + nuvio + com.nuvio.app + + + + CFBundleURLSchemes + + exp+nuvio + + + + CFBundleVersion + 20 + LSMinimumSystemVersion + 12.0 + LSRequiresIPhoneOS + + LSSupportsOpeningDocumentsInPlace + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSBonjourServices + + _http._tcp + + RCTNewArchEnabled + + RCTRootViewBackgroundColor + 4278322180 + UIBackgroundModes + + audio + fetch + + UIFileSharingEnabled + + UILaunchStoryboardName + SplashScreen + UIRequiredDeviceCapabilities + + arm64 + + UIRequiresFullScreen + + UIStatusBarStyle + UIStatusBarStyleDefault + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIUserInterfaceStyle + Dark + UIViewControllerBasedStatusBarAppearance + + + diff --git a/ios/Nuvio/Nuvio.entitlements b/ios/Nuvio/Nuvio.entitlements index a0bc443f..0c67376e 100644 --- a/ios/Nuvio/Nuvio.entitlements +++ b/ios/Nuvio/Nuvio.entitlements @@ -1,10 +1,5 @@ - - aps-environment - development - com.apple.developer.associated-domains - - - \ No newline at end of file + + diff --git a/ios/Nuvio/NuvioRelease.entitlements b/ios/Nuvio/NuvioRelease.entitlements index a0bc443f..0c67376e 100644 --- a/ios/Nuvio/NuvioRelease.entitlements +++ b/ios/Nuvio/NuvioRelease.entitlements @@ -1,10 +1,5 @@ - - aps-environment - development - com.apple.developer.associated-domains - - - \ No newline at end of file + + diff --git a/package-lock.json b/package-lock.json index 0e9a36bf..79e673e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "@react-navigation/native-stack": "^7.3.10", "@react-navigation/stack": "^7.2.10", "@sentry/react-native": "~7.3.0", - "@shopify/flash-list": "2.0.2", + "@shopify/flash-list": "^2.1.0", "@supabase/supabase-js": "^2.54.0", "@types/lodash": "^4.17.16", "@types/react-native-video": "^5.0.20", @@ -2813,6 +2813,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@legendapp/list": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@legendapp/list/-/list-2.0.13.tgz", + "integrity": "sha512-OL9rvxRDDqiQ07+QhldcRqCX5+VihtXbbZaoey0TVWJqQN5XPh9b9Buefax3/HjNRzCaYTx1lCoeW5dz20j+cA==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/@lottiefiles/dotlottie-react": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/@lottiefiles/dotlottie-react/-/dotlottie-react-0.6.5.tgz", @@ -3589,13 +3602,10 @@ } }, "node_modules/@shopify/flash-list": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@shopify/flash-list/-/flash-list-2.0.2.tgz", - "integrity": "sha512-zhlrhA9eiuEzja4wxVvotgXHtqd3qsYbXkQ3rsBfOgbFA9BVeErpDE/yEwtlIviRGEqpuFj/oU5owD6ByaNX+w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@shopify/flash-list/-/flash-list-2.1.0.tgz", + "integrity": "sha512-/EIQlptG456yM5o9qNmNsmaZEFEOGvG3WGyb6GUAxSLlcKUGlPUkPI2NLW5wQSDEY4xSRa5zocUI+9xwmsM4Kg==", "license": "MIT", - "dependencies": { - "tslib": "2.8.1" - }, "peerDependencies": { "@babel/runtime": "*", "react": "*", @@ -12949,6 +12959,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, "license": "0BSD" }, "node_modules/tunnel-agent": { diff --git a/package.json b/package.json index 7f3d4927..6c96b1e0 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@expo/metro-runtime": "~6.1.2", "@expo/vector-icons": "^15.0.2", "@gorhom/bottom-sheet": "^5.2.6", + "@legendapp/list": "^2.0.13", "@lottiefiles/dotlottie-react": "^0.6.5", "@react-native-async-storage/async-storage": "2.2.0", "@react-native-community/blur": "^4.4.1", @@ -28,7 +29,7 @@ "@react-navigation/native-stack": "^7.3.10", "@react-navigation/stack": "^7.2.10", "@sentry/react-native": "~7.3.0", - "@shopify/flash-list": "2.0.2", + "@shopify/flash-list": "^2.1.0", "@supabase/supabase-js": "^2.54.0", "@types/lodash": "^4.17.16", "@types/react-native-video": "^5.0.20", @@ -67,6 +68,7 @@ "posthog-react-native": "^4.4.0", "react": "19.1.0", "react-native": "0.81.4", + "react-native-boost": "^0.6.2", "react-native-bottom-tabs": "^0.12.2", "react-native-gesture-handler": "~2.28.0", "react-native-get-random-values": "^1.11.0", @@ -80,7 +82,7 @@ "react-native-svg": "15.12.1", "react-native-url-polyfill": "^2.0.0", "react-native-vector-icons": "^10.3.0", - "react-native-video": "^6.12.0", + "react-native-video": "^6.17.0", "react-native-web": "^0.21.0", "react-native-wheel-color-picker": "^1.3.1", "react-native-worklets": "^0.6.1", diff --git a/patches/react-native-video+6.17.0.patch b/patches/react-native-video+6.17.0.patch new file mode 100644 index 00000000..ca97b5a9 --- /dev/null +++ b/patches/react-native-video+6.17.0.patch @@ -0,0 +1,1467 @@ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/.transforms/cde462de23ae0e930ed29ed683a0d845/results.bin b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/.transforms/cde462de23ae0e930ed29ed683a0d845/results.bin +new file mode 100644 +index 0000000..0d259dd +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/.transforms/cde462de23ae0e930ed29ed683a0d845/results.bin +@@ -0,0 +1 @@ ++o/classes +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/.transforms/cde462de23ae0e930ed29ed683a0d845/transformed/classes/classes_dex/classes.dex b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/.transforms/cde462de23ae0e930ed29ed683a0d845/transformed/classes/classes_dex/classes.dex +new file mode 100644 +index 0000000..f27c56f +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/.transforms/cde462de23ae0e930ed29ed683a0d845/transformed/classes/classes_dex/classes.dex differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/generated/source/buildConfig/debug/com/brentvatne/react/BuildConfig.java b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/generated/source/buildConfig/debug/com/brentvatne/react/BuildConfig.java +new file mode 100644 +index 0000000..b26a50e +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/generated/source/buildConfig/debug/com/brentvatne/react/BuildConfig.java +@@ -0,0 +1,22 @@ ++/** ++ * Automatically generated file. DO NOT MODIFY ++ */ ++package com.brentvatne.react; ++ ++public final class BuildConfig { ++ public static final boolean DEBUG = Boolean.parseBoolean("true"); ++ public static final String LIBRARY_PACKAGE_NAME = "com.brentvatne.react"; ++ public static final String BUILD_TYPE = "debug"; ++ // Field from default config. ++ public static final boolean IS_NEW_ARCHITECTURE_ENABLED = true; ++ // Field from default config. ++ public static final boolean USE_EXOPLAYER_DASH = true; ++ // Field from default config. ++ public static final boolean USE_EXOPLAYER_HLS = true; ++ // Field from default config. ++ public static final boolean USE_EXOPLAYER_IMA = false; ++ // Field from default config. ++ public static final boolean USE_EXOPLAYER_RTSP = false; ++ // Field from default config. ++ public static final boolean USE_EXOPLAYER_SMOOTH_STREAMING = true; ++} +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +new file mode 100644 +index 0000000..728c5a9 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +@@ -0,0 +1,7 @@ ++ ++ ++ ++ ++ ++ +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +new file mode 100644 +index 0000000..247891c +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +@@ -0,0 +1,18 @@ ++{ ++ "version": 3, ++ "artifactType": { ++ "type": "AAPT_FRIENDLY_MERGED_MANIFESTS", ++ "kind": "Directory" ++ }, ++ "applicationId": "com.brentvatne.react", ++ "variantName": "debug", ++ "elements": [ ++ { ++ "type": "SINGLE", ++ "filters": [], ++ "attributes": [], ++ "outputFile": "AndroidManifest.xml" ++ } ++ ], ++ "elementType": "File" ++} +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar +new file mode 100644 +index 0000000..1f4ce80 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +new file mode 100644 +index 0000000..1211b1e +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +@@ -0,0 +1,6 @@ ++aarFormatVersion=1.0 ++aarMetadataVersion=1.0 ++minCompileSdk=1 ++minCompileSdkExtension=0 ++minAndroidGradlePluginVersion=1.0.0 ++coreLibraryDesugaringEnabled=false +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +new file mode 100644 +index 0000000..9e26dfe +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +@@ -0,0 +1 @@ ++{} +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt +new file mode 100644 +index 0000000..e69de29 +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +new file mode 100644 +index 0000000..9ec2b04 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +new file mode 100644 +index 0000000..0889def +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +new file mode 100644 +index 0000000..b5a67e1 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +@@ -0,0 +1,44 @@ ++int color player_overlay_color 0x0 ++int color red 0x0 ++int color silver_gray 0x0 ++int color white 0x0 ++int dimen controller_wrapper_padding_top 0x0 ++int dimen full_screen_margin 0x0 ++int dimen full_screen_size 0x0 ++int dimen live_wrapper_margin_top 0x0 ++int dimen position_duration_horizontal_padding 0x0 ++int dimen position_duration_text_size 0x0 ++int dimen position_duration_width 0x0 ++int dimen seekBar_height 0x0 ++int dimen seekBar_wrapper_margin_top 0x0 ++int drawable circle 0x0 ++int id exo_duration 0x0 ++int id exo_ffwd 0x0 ++int id exo_fullscreen 0x0 ++int id exo_live_container 0x0 ++int id exo_live_icon 0x0 ++int id exo_live_label 0x0 ++int id exo_next 0x0 ++int id exo_pause 0x0 ++int id exo_play 0x0 ++int id exo_play_pause_container 0x0 ++int id exo_position 0x0 ++int id exo_prev 0x0 ++int id exo_progress 0x0 ++int id exo_rew 0x0 ++int id exo_settings 0x0 ++int layout exo_legacy_player_control_view 0x0 ++int string error_drm_not_supported 0x0 ++int string error_drm_unknown 0x0 ++int string error_drm_unsupported_scheme 0x0 ++int string error_instantiating_decoder 0x0 ++int string error_no_decoder 0x0 ++int string error_no_secure_decoder 0x0 ++int string error_querying_decoders 0x0 ++int string media_playback_notification_text 0x0 ++int string media_playback_notification_title 0x0 ++int string playback_speed 0x0 ++int string select_playback_speed 0x0 ++int string settings 0x0 ++int string unrecognized_media_format 0x0 ++int style ExoMediaButton_FullScreen 0x0 +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/drawable_circle.xml.flat b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/drawable_circle.xml.flat +new file mode 100644 +index 0000000..e62758d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/drawable_circle.xml.flat differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/layout_exo_legacy_player_control_view.xml.flat b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/layout_exo_legacy_player_control_view.xml.flat +new file mode 100644 +index 0000000..bb5b5f9 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/layout_exo_legacy_player_control_view.xml.flat differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug-mergeJavaRes/merge-state b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug-mergeJavaRes/merge-state +new file mode 100644 +index 0000000..441a1d2 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug-mergeJavaRes/merge-state differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +new file mode 100644 +index 0000000..842471c +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +@@ -0,0 +1,3 @@ ++#Thu Oct 16 20:19:39 IST 2025 ++com.brentvatne.react.react-native-video-main-6\:/drawable/circle.xml=/Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/drawable/circle.xml ++com.brentvatne.react.react-native-video-main-6\:/layout/exo_legacy_player_control_view.xml=/Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/layout/exo_legacy_player_control_view.xml +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/merged.dir/values/values.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/merged.dir/values/values.xml +new file mode 100644 +index 0000000..e8dd9e4 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/merged.dir/values/values.xml +@@ -0,0 +1,33 @@ ++ ++ ++ #00000000 ++ #FF0000 ++ #FFBEBEBE ++ #FFFFFF ++ 4dp ++ 4dp ++ 30dp ++ 12dp ++ 4dp ++ 14sp ++ 50dp ++ 26dp ++ 4dp ++ Protected content not supported on API levels below 18 ++ An unknown DRM error occurred ++ This device does not support the required DRM scheme ++ Unable to instantiate decoder %1$s ++ This device does not provide a decoder for %1$s ++ This device does not provide a secure decoder for %1$s ++ Unable to query device decoders ++ Preparing playback ++ Media playback ++ Playback Speed ++ Select Playback Speed ++ Settings ++ Unrecognized media format ++ ++ +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/merger.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/merger.xml +new file mode 100644 +index 0000000..55ffc6b +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/debug/packageDebugResources/merger.xml +@@ -0,0 +1,5 @@ ++ ++#FFBEBEBE#00000000#FFFFFF#FF00004dp4dp12dp4dp4dp50dp26dp30dp14spThis device does not provide a decoder for %1$sThis device does not provide a secure decoder for %1$sUnable to query device decodersUnable to instantiate decoder %1$sProtected content not supported on API levels below 18Unrecognized media formatThis device does not support the required DRM schemeAn unknown DRM error occurredSettingsPlayback SpeedSelect Playback SpeedMedia playbackPreparing playback +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugAssets/merger.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugAssets/merger.xml +new file mode 100644 +index 0000000..8769311 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugAssets/merger.xml +@@ -0,0 +1,2 @@ ++ ++ +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugJniLibFolders/merger.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +new file mode 100644 +index 0000000..af687a7 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +@@ -0,0 +1,2 @@ ++ ++ +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugShaders/merger.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugShaders/merger.xml +new file mode 100644 +index 0000000..65138a3 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/incremental/mergeDebugShaders/merger.xml +@@ -0,0 +1,2 @@ ++ ++ +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-video_debug.kotlin_module b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-video_debug.kotlin_module +new file mode 100644 +index 0000000..1698483 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-video_debug.kotlin_module differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/ima/ImaAdsLoader$Builder.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/ima/ImaAdsLoader$Builder.class +new file mode 100644 +index 0000000..b019110 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/ima/ImaAdsLoader$Builder.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/ima/ImaAdsLoader.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/ima/ImaAdsLoader.class +new file mode 100644 +index 0000000..5e16e53 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/ima/ImaAdsLoader.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/rtsp/RtspMediaSource$Factory.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/rtsp/RtspMediaSource$Factory.class +new file mode 100644 +index 0000000..b08faeb +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/rtsp/RtspMediaSource$Factory.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/rtsp/RtspMediaSource.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/rtsp/RtspMediaSource.class +new file mode 100644 +index 0000000..2f92e20 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/androidx/media3/exoplayer/rtsp/RtspMediaSource.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$1.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$1.class +new file mode 100644 +index 0000000..a1368f5 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$1.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$2.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$2.class +new file mode 100644 +index 0000000..ec7b745 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$2.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$3.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$3.class +new file mode 100644 +index 0000000..598654a +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$3.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$4.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$4.class +new file mode 100644 +index 0000000..803aefe +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$4.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$OnAudioFocusChangedListener.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$OnAudioFocusChangedListener.class +new file mode 100644 +index 0000000..6ec4ad1 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$OnAudioFocusChangedListener.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$RNVLoadControl.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$RNVLoadControl.class +new file mode 100644 +index 0000000..22d8796 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView$RNVLoadControl.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView.class +new file mode 100644 +index 0000000..53eee7f +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/exoplayer/ReactExoplayerView.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/react/BuildConfig.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/react/BuildConfig.class +new file mode 100644 +index 0000000..4c5c87e +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/brentvatne/react/BuildConfig.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdError.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdError.class +new file mode 100644 +index 0000000..0a9b7a7 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdError.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdErrorEvent$AdErrorListener.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdErrorEvent$AdErrorListener.class +new file mode 100644 +index 0000000..1380a05 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdErrorEvent$AdErrorListener.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdErrorEvent.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdErrorEvent.class +new file mode 100644 +index 0000000..07ab3fa +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdErrorEvent.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdEvent$AdEventListener.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdEvent$AdEventListener.class +new file mode 100644 +index 0000000..dbe9984 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdEvent$AdEventListener.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdEvent.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdEvent.class +new file mode 100644 +index 0000000..88ae34c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/AdEvent.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ConcreteImaSdkFactory.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ConcreteImaSdkFactory.class +new file mode 100644 +index 0000000..a3184b3 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ConcreteImaSdkFactory.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ConcreteImaSdkSettings.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ConcreteImaSdkSettings.class +new file mode 100644 +index 0000000..264cd83 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ConcreteImaSdkSettings.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ImaSdkFactory.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ImaSdkFactory.class +new file mode 100644 +index 0000000..46cea81 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ImaSdkFactory.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ImaSdkSettings.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ImaSdkSettings.class +new file mode 100644 +index 0000000..a4cef0d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/google/ads/interactivemedia/v3/api/ImaSdkSettings.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +new file mode 100644 +index 0000000..987e479 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +@@ -0,0 +1,46 @@ ++R_DEF: Internal format may change without notice ++local ++color player_overlay_color ++color red ++color silver_gray ++color white ++dimen controller_wrapper_padding_top ++dimen full_screen_margin ++dimen full_screen_size ++dimen live_wrapper_margin_top ++dimen position_duration_horizontal_padding ++dimen position_duration_text_size ++dimen position_duration_width ++dimen seekBar_height ++dimen seekBar_wrapper_margin_top ++drawable circle ++id exo_duration ++id exo_ffwd ++id exo_fullscreen ++id exo_live_container ++id exo_live_icon ++id exo_live_label ++id exo_next ++id exo_pause ++id exo_play ++id exo_play_pause_container ++id exo_position ++id exo_prev ++id exo_progress ++id exo_rew ++id exo_settings ++layout exo_legacy_player_control_view ++string error_drm_not_supported ++string error_drm_unknown ++string error_drm_unsupported_scheme ++string error_instantiating_decoder ++string error_no_decoder ++string error_no_secure_decoder ++string error_querying_decoders ++string media_playback_notification_text ++string media_playback_notification_title ++string playback_speed ++string select_playback_speed ++string settings ++string unrecognized_media_format ++style ExoMediaButton.FullScreen +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +new file mode 100644 +index 0000000..2300097 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +@@ -0,0 +1,7 @@ ++1 ++2 ++4 ++5 ++6 ++7 +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-react-native-video.jar b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-react-native-video.jar +new file mode 100644 +index 0000000..87d384d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-react-native-video.jar differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +new file mode 100644 +index 0000000..728c5a9 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +@@ -0,0 +1,7 @@ ++ ++ ++ ++ ++ ++ +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +new file mode 100644 +index 0000000..0637a08 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +@@ -0,0 +1 @@ ++[] +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +new file mode 100644 +index 0000000..08f4ebe +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +@@ -0,0 +1 @@ ++0 Warning/Error +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/drawable/circle.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/drawable/circle.xml +new file mode 100644 +index 0000000..9f06d7c +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/drawable/circle.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/layout/exo_legacy_player_control_view.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/layout/exo_legacy_player_control_view.xml +new file mode 100644 +index 0000000..e0babc4 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/layout/exo_legacy_player_control_view.xml +@@ -0,0 +1,120 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/values/values.xml b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/values/values.xml +new file mode 100644 +index 0000000..e8dd9e4 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/packaged_res/debug/packageDebugResources/values/values.xml +@@ -0,0 +1,33 @@ ++ ++ ++ #00000000 ++ #FF0000 ++ #FFBEBEBE ++ #FFFFFF ++ 4dp ++ 4dp ++ 30dp ++ 12dp ++ 4dp ++ 14sp ++ 50dp ++ 26dp ++ 4dp ++ Protected content not supported on API levels below 18 ++ An unknown DRM error occurred ++ This device does not support the required DRM scheme ++ Unable to instantiate decoder %1$s ++ This device does not provide a decoder for %1$s ++ This device does not provide a secure decoder for %1$s ++ Unable to query device decoders ++ Preparing playback ++ Media playback ++ Playback Speed ++ Select Playback Speed ++ Settings ++ Unrecognized media format ++ ++ +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +new file mode 100644 +index 0000000..e65b062 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +new file mode 100644 +index 0000000..1cb95ed +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +@@ -0,0 +1,45 @@ ++com.brentvatne.react ++color player_overlay_color ++color red ++color silver_gray ++color white ++dimen controller_wrapper_padding_top ++dimen full_screen_margin ++dimen full_screen_size ++dimen live_wrapper_margin_top ++dimen position_duration_horizontal_padding ++dimen position_duration_text_size ++dimen position_duration_width ++dimen seekBar_height ++dimen seekBar_wrapper_margin_top ++drawable circle ++id exo_duration ++id exo_ffwd ++id exo_fullscreen ++id exo_live_container ++id exo_live_icon ++id exo_live_label ++id exo_next ++id exo_pause ++id exo_play ++id exo_play_pause_container ++id exo_position ++id exo_prev ++id exo_progress ++id exo_rew ++id exo_settings ++layout exo_legacy_player_control_view ++string error_drm_not_supported ++string error_drm_unknown ++string error_drm_unsupported_scheme ++string error_instantiating_decoder ++string error_no_decoder ++string error_no_secure_decoder ++string error_querying_decoders ++string media_playback_notification_text ++string media_playback_notification_title ++string playback_speed ++string select_playback_speed ++string settings ++string unrecognized_media_format ++style ExoMediaButton_FullScreen +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +new file mode 100644 +index 0000000..7df5bcf +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +new file mode 100644 +index 0000000..1a55594 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +new file mode 100644 +index 0000000..74ddf64 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +new file mode 100644 +index 0000000..41d6c24 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +new file mode 100644 +index 0000000..d0eda54 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +new file mode 100644 +index 0000000..8a80b7d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +new file mode 100644 +index 0000000..532458c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +new file mode 100644 +index 0000000..1d1d548 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +new file mode 100644 +index 0000000..3247724 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +new file mode 100644 +index 0000000..bba171d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +new file mode 100644 +index 0000000..5d6b64a +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +new file mode 100644 +index 0000000..045022c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +new file mode 100644 +index 0000000..8178530 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +new file mode 100644 +index 0000000..1d1d548 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +new file mode 100644 +index 0000000..3247724 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +new file mode 100644 +index 0000000..bba171d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +new file mode 100644 +index 0000000..6a45a65 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +new file mode 100644 +index 0000000..045022c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +new file mode 100644 +index 0000000..496bda2 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +new file mode 100644 +index 0000000..a49789c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +new file mode 100644 +index 0000000..a3d0573 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +new file mode 100644 +index 0000000..93a595b +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +new file mode 100644 +index 0000000..9d91003 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +new file mode 100644 +index 0000000..1598ef3 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +new file mode 100644 +index 0000000..c3975e3 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +new file mode 100644 +index 0000000..9d05b9a +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +new file mode 100644 +index 0000000..d3e09af +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +new file mode 100644 +index 0000000..b7d7395 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +new file mode 100644 +index 0000000..e3911a1 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +new file mode 100644 +index 0000000..af27d9c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab +new file mode 100644 +index 0000000..bdf584a +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream +new file mode 100644 +index 0000000..a9e6823 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len +new file mode 100644 +index 0000000..de8bf97 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.len +new file mode 100644 +index 0000000..2a17e6e +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at +new file mode 100644 +index 0000000..46d6744 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i +new file mode 100644 +index 0000000..2073982 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +new file mode 100644 +index 0000000..c626f49 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +new file mode 100644 +index 0000000..7214377 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +new file mode 100644 +index 0000000..86b154b +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +new file mode 100644 +index 0000000..882f24f +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values +new file mode 100644 +index 0000000..2ff3eb7 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +new file mode 100644 +index 0000000..af661f7 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +new file mode 100644 +index 0000000..b6551b9 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +@@ -0,0 +1 @@ ++ÏÒ +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +new file mode 100644 +index 0000000..0cbafa1 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +new file mode 100644 +index 0000000..85d9216 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +new file mode 100644 +index 0000000..1a55594 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +new file mode 100644 +index 0000000..74ddf64 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +new file mode 100644 +index 0000000..41d6c24 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +new file mode 100644 +index 0000000..dfc60fb +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +new file mode 100644 +index 0000000..8a80b7d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +new file mode 100644 +index 0000000..95c2c01 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +new file mode 100644 +index 0000000..90b21c4 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +new file mode 100644 +index 0000000..4cb813c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +new file mode 100644 +index 0000000..385642d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +new file mode 100644 +index 0000000..195d865 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +new file mode 100644 +index 0000000..5e4a0c0 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +new file mode 100644 +index 0000000..d98dace +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +new file mode 100644 +index 0000000..ae4ac93 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +new file mode 100644 +index 0000000..6dc1435 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +new file mode 100644 +index 0000000..42df8b9 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +new file mode 100644 +index 0000000..bc345c6 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +new file mode 100644 +index 0000000..f0c9463 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +new file mode 100644 +index 0000000..672070d +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +@@ -0,0 +1,2 @@ ++44 ++0 +\ No newline at end of file +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +new file mode 100644 +index 0000000..1878d5a +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +new file mode 100644 +index 0000000..1a55594 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +new file mode 100644 +index 0000000..74ddf64 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +new file mode 100644 +index 0000000..41d6c24 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +new file mode 100644 +index 0000000..d3fcc7e +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +new file mode 100644 +index 0000000..8a80b7d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +new file mode 100644 +index 0000000..04aeda4 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +new file mode 100644 +index 0000000..132a271 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +new file mode 100644 +index 0000000..79ad34c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +new file mode 100644 +index 0000000..41d6c24 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +new file mode 100644 +index 0000000..c834290 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +new file mode 100644 +index 0000000..1601c02 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +new file mode 100644 +index 0000000..5fc703e +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +new file mode 100644 +index 0000000..39f4cac +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +new file mode 100644 +index 0000000..e381b23 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +new file mode 100644 +index 0000000..35ed991 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +new file mode 100644 +index 0000000..a262c4a +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +new file mode 100644 +index 0000000..1bfa622 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +new file mode 100644 +index 0000000..131e265 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/last-build.bin b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/last-build.bin +new file mode 100644 +index 0000000..1fe138d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/cacheable/last-build.bin differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +new file mode 100644 +index 0000000..fb7ec91 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/outputs/aar/react-native-video-debug.aar b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/outputs/aar/react-native-video-debug.aar +new file mode 100644 +index 0000000..a704fe4 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/outputs/aar/react-native-video-debug.aar differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/outputs/logs/manifest-merger-debug-report.txt b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/outputs/logs/manifest-merger-debug-report.txt +new file mode 100644 +index 0000000..a388215 +--- /dev/null ++++ b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/outputs/logs/manifest-merger-debug-report.txt +@@ -0,0 +1,16 @@ ++-- Merging decision tree log --- ++manifest ++ADDED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml:1:1-2:12 ++INJECTED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml:1:1-2:12 ++ package ++ INJECTED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml ++ xmlns:android ++ ADDED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml:1:11-69 ++uses-sdk ++INJECTED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml reason: use-sdk injection requested ++INJECTED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml ++INJECTED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml ++ android:targetSdkVersion ++ INJECTED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml ++ android:minSdkVersion ++ INJECTED from /Users/nayifnoushad/Documents/Projects/NuvioStreaming/node_modules/react-native-video/android/src/main/AndroidManifestNew.xml +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +new file mode 100644 +index 0000000..b63c0e3 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/META-INF/react-native-video_debug.kotlin_module b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/META-INF/react-native-video_debug.kotlin_module +new file mode 100644 +index 0000000..1698483 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/META-INF/react-native-video_debug.kotlin_module differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/AdsProps$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/AdsProps$Companion.class +new file mode 100644 +index 0000000..2e5d42b +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/AdsProps$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/AdsProps.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/AdsProps.class +new file mode 100644 +index 0000000..e2b54bd +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/AdsProps.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Companion.class +new file mode 100644 +index 0000000..0fbaa90 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Live$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Live$Companion.class +new file mode 100644 +index 0000000..ce1128e +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Live$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Live.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Live.class +new file mode 100644 +index 0000000..2054200 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig$Live.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig.class +new file mode 100644 +index 0000000..7ef226b +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferConfig.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy$BufferingStrategyEnum.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy$BufferingStrategyEnum.class +new file mode 100644 +index 0000000..162566c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy$BufferingStrategyEnum.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy$Companion.class +new file mode 100644 +index 0000000..7477be8 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy.class +new file mode 100644 +index 0000000..3516405 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/BufferingStrategy.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps$Companion$WhenMappings.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps$Companion$WhenMappings.class +new file mode 100644 +index 0000000..5145552 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps$Companion$WhenMappings.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps$Companion.class +new file mode 100644 +index 0000000..e813d1a +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps.class +new file mode 100644 +index 0000000..e6c0538 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/CMCDProps.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ControlsConfig$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ControlsConfig$Companion.class +new file mode 100644 +index 0000000..b2e5cfc +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ControlsConfig$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ControlsConfig.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ControlsConfig.class +new file mode 100644 +index 0000000..a672b48 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ControlsConfig.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/DRMProps$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/DRMProps$Companion.class +new file mode 100644 +index 0000000..949a5b9 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/DRMProps$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/DRMProps.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/DRMProps.class +new file mode 100644 +index 0000000..8e26a44 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/DRMProps.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ResizeMode$Mode.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ResizeMode$Mode.class +new file mode 100644 +index 0000000..8c2948d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ResizeMode$Mode.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ResizeMode.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ResizeMode.class +new file mode 100644 +index 0000000..ab7c203 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ResizeMode.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrack$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrack$Companion.class +new file mode 100644 +index 0000000..3262de8 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrack$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrack.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrack.class +new file mode 100644 +index 0000000..a6b7907 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrack.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrackList$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrackList$Companion.class +new file mode 100644 +index 0000000..a41fe7d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrackList$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrackList.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrackList.class +new file mode 100644 +index 0000000..ec0f170 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SideLoadedTextTrackList.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Companion.class +new file mode 100644 +index 0000000..20c7316 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Metadata$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Metadata$Companion.class +new file mode 100644 +index 0000000..3a83d08 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Metadata$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Metadata.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Metadata.class +new file mode 100644 +index 0000000..381c5ea +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source$Metadata.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source.class +new file mode 100644 +index 0000000..763511c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Source.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SubtitleStyle$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SubtitleStyle$Companion.class +new file mode 100644 +index 0000000..1ef82f1 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SubtitleStyle$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SubtitleStyle.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SubtitleStyle.class +new file mode 100644 +index 0000000..4ebb38c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/SubtitleStyle.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/TimedMetadata.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/TimedMetadata.class +new file mode 100644 +index 0000000..81dc3f7 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/TimedMetadata.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Track.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Track.class +new file mode 100644 +index 0000000..bf9687d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/Track.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/VideoTrack.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/VideoTrack.class +new file mode 100644 +index 0000000..a011166 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/VideoTrack.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ViewType$ViewType.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ViewType$ViewType.class +new file mode 100644 +index 0000000..2dfe0a5 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ViewType$ViewType.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ViewType.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ViewType.class +new file mode 100644 +index 0000000..24c319c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/api/ViewType.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/EventTypes$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/EventTypes$Companion.class +new file mode 100644 +index 0000000..7c1c2f6 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/EventTypes$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/EventTypes.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/EventTypes.class +new file mode 100644 +index 0000000..68c48f1 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/EventTypes.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter$EventBuilder.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter$EventBuilder.class +new file mode 100644 +index 0000000..0dceebe +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter$EventBuilder.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter$VideoCustomEvent.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter$VideoCustomEvent.class +new file mode 100644 +index 0000000..6116962 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter$VideoCustomEvent.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter.class +new file mode 100644 +index 0000000..1f63a29 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/react/VideoEventEmitter.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/toolbox/DebugLog.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/toolbox/DebugLog.class +new file mode 100644 +index 0000000..35fd981 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/toolbox/DebugLog.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/toolbox/ReactBridgeUtils.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/toolbox/ReactBridgeUtils.class +new file mode 100644 +index 0000000..5b3a99d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/common/toolbox/ReactBridgeUtils.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AspectRatioFrameLayout$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AspectRatioFrameLayout$Companion.class +new file mode 100644 +index 0000000..e1e118c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AspectRatioFrameLayout$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AspectRatioFrameLayout.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AspectRatioFrameLayout.class +new file mode 100644 +index 0000000..8955650 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AspectRatioFrameLayout.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AudioOutput$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AudioOutput$Companion.class +new file mode 100644 +index 0000000..fdbd8c4 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AudioOutput$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AudioOutput.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AudioOutput.class +new file mode 100644 +index 0000000..49bd1a1 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/AudioOutput.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/CMCDConfig$createCmcdConfiguration$1.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/CMCDConfig$createCmcdConfiguration$1.class +new file mode 100644 +index 0000000..1b9ff2b +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/CMCDConfig$createCmcdConfiguration$1.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/CMCDConfig.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/CMCDConfig.class +new file mode 100644 +index 0000000..24ff469 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/CMCDConfig.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ConfigurationUtils.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ConfigurationUtils.class +new file mode 100644 +index 0000000..8623659 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ConfigurationUtils.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DRMManager.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DRMManager.class +new file mode 100644 +index 0000000..c054558 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DRMManager.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DRMManagerSpec.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DRMManagerSpec.class +new file mode 100644 +index 0000000..3ba0b21 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DRMManagerSpec.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DataSourceUtil.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DataSourceUtil.class +new file mode 100644 +index 0000000..435095f +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DataSourceUtil.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DefaultReactExoplayerConfig.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DefaultReactExoplayerConfig.class +new file mode 100644 +index 0000000..7d79368 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/DefaultReactExoplayerConfig.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView$Companion.class +new file mode 100644 +index 0000000..345dd50 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView$playerListener$1.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView$playerListener$1.class +new file mode 100644 +index 0000000..4dcc80e +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView$playerListener$1.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView.class +new file mode 100644 +index 0000000..df0ace7 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ExoPlayerView.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView$KeepScreenOnUpdater$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView$KeepScreenOnUpdater$Companion.class +new file mode 100644 +index 0000000..8bcae8d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView$KeepScreenOnUpdater$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView$KeepScreenOnUpdater.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView$KeepScreenOnUpdater.class +new file mode 100644 +index 0000000..550135d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView$KeepScreenOnUpdater.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView.class +new file mode 100644 +index 0000000..257de83 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/FullScreenPlayerView.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PictureInPictureUtil.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PictureInPictureUtil.class +new file mode 100644 +index 0000000..9e8c1b9 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PictureInPictureUtil.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PictureInPictureUtilKt.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PictureInPictureUtilKt.class +new file mode 100644 +index 0000000..2c42f4a +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PictureInPictureUtilKt.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PlaybackServiceBinder.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PlaybackServiceBinder.class +new file mode 100644 +index 0000000..5ae25b4 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/PlaybackServiceBinder.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVExoplayerPlugin$DefaultImpls.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVExoplayerPlugin$DefaultImpls.class +new file mode 100644 +index 0000000..af3decf +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVExoplayerPlugin$DefaultImpls.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVExoplayerPlugin.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVExoplayerPlugin.class +new file mode 100644 +index 0000000..9bc6115 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVExoplayerPlugin.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVSimpleCache.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVSimpleCache.class +new file mode 100644 +index 0000000..659e439 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/RNVSimpleCache.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerConfig.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerConfig.class +new file mode 100644 +index 0000000..2456c95 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerConfig.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerLoadErrorHandlingPolicy.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerLoadErrorHandlingPolicy.class +new file mode 100644 +index 0000000..38ce458 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerLoadErrorHandlingPolicy.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerViewManager$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerViewManager$Companion.class +new file mode 100644 +index 0000000..bc906a9 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerViewManager$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerViewManager.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerViewManager.class +new file mode 100644 +index 0000000..07bd865 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/ReactExoplayerViewManager.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackCallback.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackCallback.class +new file mode 100644 +index 0000000..5e67aa0 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackCallback.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion$COMMAND.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion$COMMAND.class +new file mode 100644 +index 0000000..6ba65f2 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion$COMMAND.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion$WhenMappings.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion$WhenMappings.class +new file mode 100644 +index 0000000..647f782 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion$WhenMappings.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion.class +new file mode 100644 +index 0000000..0f20e85 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService.class +new file mode 100644 +index 0000000..8a576c2 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/exoplayer/VideoPlaybackService.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/RNVPlugin.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/RNVPlugin.class +new file mode 100644 +index 0000000..8a59f22 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/RNVPlugin.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactNativeVideoManager$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactNativeVideoManager$Companion.class +new file mode 100644 +index 0000000..32d6d1f +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactNativeVideoManager$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactNativeVideoManager.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactNativeVideoManager.class +new file mode 100644 +index 0000000..2679ae0 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactNativeVideoManager.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactVideoPackage.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactVideoPackage.class +new file mode 100644 +index 0000000..2af2d2c +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/ReactVideoPackage.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoDecoderInfoModule$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoDecoderInfoModule$Companion.class +new file mode 100644 +index 0000000..d8a4aa3 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoDecoderInfoModule$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoDecoderInfoModule.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoDecoderInfoModule.class +new file mode 100644 +index 0000000..8348d9d +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoDecoderInfoModule.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoManagerModule$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoManagerModule$Companion.class +new file mode 100644 +index 0000000..435293b +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoManagerModule$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoManagerModule.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoManagerModule.class +new file mode 100644 +index 0000000..c28e02b +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/react/VideoManagerModule.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/AudioBecomingNoisyReceiver.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/AudioBecomingNoisyReceiver.class +new file mode 100644 +index 0000000..990ca48 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/AudioBecomingNoisyReceiver.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener$Companion$NO_OP$1.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener$Companion$NO_OP$1.class +new file mode 100644 +index 0000000..07a503b +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener$Companion$NO_OP$1.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener$Companion.class +new file mode 100644 +index 0000000..efa3ee3 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener.class +new file mode 100644 +index 0000000..75d1cd4 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/BecomingNoisyListener.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/PictureInPictureReceiver$Companion.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/PictureInPictureReceiver$Companion.class +new file mode 100644 +index 0000000..535aad5 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/PictureInPictureReceiver$Companion.class differ +diff --git a/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/PictureInPictureReceiver.class b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/PictureInPictureReceiver.class +new file mode 100644 +index 0000000..0143f64 +Binary files /dev/null and b/node_modules/react-native-video/android/buildOutput_a15d4dee7fc4eda61b91308cbb6a2e72/tmp/kotlin-classes/debug/com/brentvatne/receiver/PictureInPictureReceiver.class differ +diff --git a/node_modules/react-native-video/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/node_modules/react-native-video/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +index f175dec..87e436a 100644 +--- a/node_modules/react-native-video/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java ++++ b/node_modules/react-native-video/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +@@ -726,7 +726,7 @@ public class ReactExoplayerView extends FrameLayout implements + + DefaultRenderersFactory renderersFactory = + new DefaultRenderersFactory(getContext()) +- .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF) ++ .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER) + .setEnableDecoderFallback(true) + .forceEnableMediaCodecAsynchronousQueueing(); + diff --git a/src/components/home/CatalogSection.tsx b/src/components/home/CatalogSection.tsx index 77fd6af2..7639a9f0 100644 --- a/src/components/home/CatalogSection.tsx +++ b/src/components/home/CatalogSection.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useMemo, useRef } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, Platform, Dimensions } from 'react-native'; -import { FlashList } from '@shopify/flash-list'; +import { LegendList } from '@legendapp/list'; import { NavigationProp, useNavigation } from '@react-navigation/native'; import { MaterialIcons } from '@expo/vector-icons'; import { LinearGradient } from 'expo-linear-gradient'; @@ -98,7 +98,7 @@ const CatalogSection = ({ catalog }: CatalogSectionProps) => { - { ItemSeparatorComponent={ItemSeparator} onEndReachedThreshold={0.7} onEndReached={() => {}} - scrollEventThrottle={64} - removeClippedSubviews={true} + recycleItems={true} + maintainVisibleContentPosition /> ); diff --git a/src/components/home/HeroCarousel.tsx b/src/components/home/HeroCarousel.tsx index fb7e20c5..58b13981 100644 --- a/src/components/home/HeroCarousel.tsx +++ b/src/components/home/HeroCarousel.tsx @@ -1,6 +1,6 @@ -import React, { useMemo, useState, useEffect, useCallback, memo } from 'react'; -import { View, Text, StyleSheet, Dimensions, TouchableOpacity, ViewStyle, TextStyle, ImageStyle, FlatList, StyleProp, Platform, Image } from 'react-native'; -import Animated, { FadeIn, FadeOut, Easing, useSharedValue, withTiming, useAnimatedStyle, useAnimatedScrollHandler, useAnimatedReaction, runOnJS } from 'react-native-reanimated'; +import React, { useMemo, useState, useEffect, useCallback, memo, useRef } from 'react'; +import { View, Text, StyleSheet, Dimensions, TouchableOpacity, ViewStyle, TextStyle, ImageStyle, ScrollView, StyleProp, Platform, Image } from 'react-native'; +import Animated, { FadeIn, FadeOut, Easing, useSharedValue, withTiming, useAnimatedStyle, useAnimatedScrollHandler, useAnimatedReaction, runOnJS, SharedValue } from 'react-native-reanimated'; import { LinearGradient } from 'expo-linear-gradient'; import { BlurView } from 'expo-blur'; import FastImage from '@d11/react-native-fast-image'; @@ -47,6 +47,7 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = const data = useMemo(() => (items && items.length ? items.slice(0, 10) : []), [items]); const [activeIndex, setActiveIndex] = useState(0); const [failedLogoIds, setFailedLogoIds] = useState>(new Set()); + const scrollViewRef = useRef(null); // Note: do not early-return before hooks. Loading UI is returned later. @@ -55,10 +56,50 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = // Optimized: update background as soon as scroll starts, without waiting for momentum end const scrollX = useSharedValue(0); const interval = CARD_WIDTH + 16; + + // Comprehensive reset when component mounts/remounts to prevent glitching + useEffect(() => { + scrollX.value = 0; + setActiveIndex(0); + + // Scroll to position 0 after a brief delay to ensure ScrollView is ready + const timer = setTimeout(() => { + scrollViewRef.current?.scrollTo({ x: 0, y: 0, animated: false }); + }, 50); + + return () => clearTimeout(timer); + }, []); + + // Reset scroll when data becomes available + useEffect(() => { + if (data.length > 0) { + scrollX.value = 0; + setActiveIndex(0); + + const timer = setTimeout(() => { + scrollViewRef.current?.scrollTo({ x: 0, y: 0, animated: false }); + }, 100); + + return () => clearTimeout(timer); + } + }, [data.length]); + const scrollHandler = useAnimatedScrollHandler({ onScroll: (event) => { scrollX.value = event.contentOffset.x; }, + onBeginDrag: () => { + // Smooth scroll start - could add haptic feedback here + }, + onEndDrag: () => { + // Smooth scroll end + }, + onMomentumBegin: () => { + // Momentum scroll start + }, + onMomentumEnd: () => { + // Momentum scroll end + }, }); // Derive the index reactively and only set state when it changes @@ -78,17 +119,6 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = const contentPadding = useMemo(() => ({ paddingHorizontal: (width - CARD_WIDTH) / 2 }), []); - const keyExtractor = useCallback((item: StreamingContent) => item.id, []); - - const getItemLayout = useCallback( - (_: unknown, index: number) => { - const length = CARD_WIDTH + 16; - const offset = length * index; - return { length, offset, index }; - }, - [] - ); - const handleNavigateToMetadata = useCallback((id: string, type: any) => { navigation.navigate('Metadata', { id, type }); }, [navigation]); @@ -97,20 +127,31 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = navigation.navigate('Streams', { id, type }); }, [navigation]); + // Container animation based on scroll - must be before early returns + const containerAnimatedStyle = useAnimatedStyle(() => { + const translateX = scrollX.value; + const progress = Math.abs(translateX) / (data.length * (CARD_WIDTH + 16)); + + // Very subtle scale animation for the entire container + const scale = 1 - progress * 0.01; + const clampedScale = Math.max(0.99, Math.min(1, scale)); + + return { + transform: [{ scale: clampedScale }], + }; + }); + if (loading) { return ( }> - String(i)} + ( - + > + {[1, 2, 3].map((_, index) => ( + = ({ items, loading = false }) = - )} - /> + ))} + ); @@ -222,7 +263,7 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = return ( - + {settings.enableHomeHeroBackground && data.length > 0 && ( {data[activeIndex + 1] && ( @@ -264,37 +305,35 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = pointerEvents="none" /> )} - ( - - setFailedLogoIds((prev) => new Set(prev).add(item.id))} - onPressInfo={() => handleNavigateToMetadata(item.id, item.type)} - onPressPlay={() => handleNavigateToStreams(item.id, item.type)} - /> - - )} - /> - + pagingEnabled={false} + bounces={false} + overScrollMode="never" + > + {data.map((item, index) => ( + setFailedLogoIds((prev) => new Set(prev).add(item.id))} + onPressInfo={() => handleNavigateToMetadata(item.id, item.type)} + onPressPlay={() => handleNavigateToStreams(item.id, item.type)} + scrollX={scrollX} + index={index} + /> + ))} + + ); }; @@ -306,61 +345,208 @@ interface CarouselCardProps { onLogoError: () => void; onPressPlay: () => void; onPressInfo: () => void; + scrollX: SharedValue; + index: number; } -const CarouselCard: React.FC = memo(({ item, colors, logoFailed, onLogoError, onPressPlay, onPressInfo }) => { +const CarouselCard: React.FC = memo(({ item, colors, logoFailed, onLogoError, onPressPlay, onPressInfo, scrollX, index }) => { + const [bannerLoaded, setBannerLoaded] = useState(false); + const [logoLoaded, setLogoLoaded] = useState(false); + + const bannerOpacity = useSharedValue(0); + const logoOpacity = useSharedValue(0); + const genresOpacity = useSharedValue(0); + const actionsOpacity = useSharedValue(0); + + // Reset animations when component mounts/remounts to prevent glitching + useEffect(() => { + bannerOpacity.value = 0; + logoOpacity.value = 0; + genresOpacity.value = 0; + actionsOpacity.value = 0; + // Force re-render states to ensure clean state + setBannerLoaded(false); + setLogoLoaded(false); + }, [item.id]); + + const inputRange = [ + (index - 1) * (CARD_WIDTH + 16), + index * (CARD_WIDTH + 16), + (index + 1) * (CARD_WIDTH + 16), + ]; + + const bannerAnimatedStyle = useAnimatedStyle(() => ({ + opacity: bannerOpacity.value, + })); + + const logoAnimatedStyle = useAnimatedStyle(() => ({ + opacity: logoOpacity.value, + })); + + const genresAnimatedStyle = useAnimatedStyle(() => { + const translateX = scrollX.value; + const cardOffset = index * (CARD_WIDTH + 16); + const distance = Math.abs(translateX - cardOffset); + const maxDistance = (CARD_WIDTH + 16) * 0.5; // Smaller threshold for smoother transition + + // Hide genres when scrolling (not centered) + const progress = Math.min(distance / maxDistance, 1); + const opacity = 1 - progress; // Linear fade out + const clampedOpacity = Math.max(0, Math.min(1, opacity)); + + return { + opacity: clampedOpacity, + }; + }); + + const actionsAnimatedStyle = useAnimatedStyle(() => { + const translateX = scrollX.value; + const cardOffset = index * (CARD_WIDTH + 16); + const distance = Math.abs(translateX - cardOffset); + const maxDistance = (CARD_WIDTH + 16) * 0.5; // Smaller threshold for smoother transition + + // Hide actions when scrolling (not centered) + const progress = Math.min(distance / maxDistance, 1); + const opacity = 1 - progress; // Linear fade out + const clampedOpacity = Math.max(0, Math.min(1, opacity)); + + return { + opacity: clampedOpacity, + }; + }); + + // Scroll-based animations + const cardAnimatedStyle = useAnimatedStyle(() => { + const translateX = scrollX.value; + const cardOffset = index * (CARD_WIDTH + 16); + const distance = Math.abs(translateX - cardOffset); + const maxDistance = CARD_WIDTH + 16; + + // Scale animation based on distance from center + const scale = 1 - (distance / maxDistance) * 0.1; + const clampedScale = Math.max(0.9, Math.min(1, scale)); + + // Opacity animation for cards that are far from center + const opacity = 1 - (distance / maxDistance) * 0.3; + const clampedOpacity = Math.max(0.7, Math.min(1, opacity)); + + return { + transform: [{ scale: clampedScale }], + opacity: clampedOpacity, + }; + }); + + const bannerParallaxStyle = useAnimatedStyle(() => { + const translateX = scrollX.value; + const cardOffset = index * (CARD_WIDTH + 16); + const distance = translateX - cardOffset; + + // Reduced parallax effect to prevent displacement + const parallaxOffset = distance * 0.05; + + return { + transform: [{ translateX: parallaxOffset }], + }; + }); + + const infoParallaxStyle = useAnimatedStyle(() => { + const translateX = scrollX.value; + const cardOffset = index * (CARD_WIDTH + 16); + const distance = Math.abs(translateX - cardOffset); + const maxDistance = CARD_WIDTH + 16; + + // Hide info section when scrolling (not centered) + const progress = distance / maxDistance; + const opacity = 1 - progress * 2; // Fade out faster when scrolling + const clampedOpacity = Math.max(0, Math.min(1, opacity)); + + // Minimal parallax for info section to prevent displacement + const parallaxOffset = -(translateX - cardOffset) * 0.02; + + return { + transform: [{ translateY: parallaxOffset }], + opacity: clampedOpacity, + }; + }); + + useEffect(() => { + if (bannerLoaded) { + bannerOpacity.value = withTiming(1, { + duration: 250, + easing: Easing.out(Easing.ease) + }); + } + }, [bannerLoaded]); + + useEffect(() => { + if (logoLoaded) { + logoOpacity.value = withTiming(1, { + duration: 300, + easing: Easing.out(Easing.ease) + }); + } + }, [logoLoaded]); + return ( - - }> - - - - - - {item.logo && !logoFailed ? ( - + }> + + {!bannerLoaded && ( + + )} + + setBannerLoaded(true)} + /> + + - ) : ( - - {item.name} - - )} - {item.genres && ( - + + + {/* Static genres positioned absolutely over the card */} + {item.genres && ( + + {item.genres.slice(0, 3).join(' • ')} - - )} - + + + )} + {/* Static action buttons positioned absolutely over the card */} + + = memo(({ item, colors, logoFail Info - + - - + {/* Static logo positioned absolutely over the card */} + {item.logo && !logoFailed && ( + + + setLogoLoaded(true)} + onError={onLogoError} + /> + + + )} + {/* Static title when no logo */} + {!item.logo || logoFailed ? ( + + + + {item.name} + + + + ) : null} + + ); }); @@ -542,6 +756,46 @@ const styles = StyleSheet.create({ marginLeft: 6, fontSize: 14, }, + logoOverlay: { + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, + alignItems: 'center', + justifyContent: 'flex-end', + paddingBottom: 80, // Position above genres and actions + }, + titleOverlay: { + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, + alignItems: 'center', + justifyContent: 'flex-end', + paddingBottom: 90, // Position above genres and actions + }, + genresOverlay: { + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, + alignItems: 'center', + justifyContent: 'flex-end', + paddingBottom: 65, // Position above actions + }, + actionsOverlay: { + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, + alignItems: 'center', + justifyContent: 'flex-end', + paddingBottom: 12, // Position at bottom + }, }); export default React.memo(HeroCarousel); diff --git a/src/components/metadata/FloatingHeader.tsx b/src/components/metadata/FloatingHeader.tsx index fd3a8ac0..ca7ffdd0 100644 --- a/src/components/metadata/FloatingHeader.tsx +++ b/src/components/metadata/FloatingHeader.tsx @@ -6,6 +6,7 @@ import { TouchableOpacity, Platform, Dimensions, + Image, } from 'react-native'; import { BlurView as ExpoBlurView } from 'expo-blur'; import { MaterialIcons, Feather } from '@expo/vector-icons'; @@ -24,7 +25,6 @@ if (Platform.OS === 'ios') { liquidGlassAvailable = false; } } -import FastImage from '@d11/react-native-fast-image'; import Animated, { useAnimatedStyle, interpolate, @@ -49,6 +49,7 @@ interface FloatingHeaderProps { headerElementsOpacity: SharedValue; safeAreaTop: number; setLogoLoadError: (error: boolean) => void; + stableLogoUri?: string | null; } const FloatingHeader: React.FC = ({ @@ -62,6 +63,7 @@ const FloatingHeader: React.FC = ({ headerElementsOpacity, safeAreaTop, setLogoLoadError, + stableLogoUri, }) => { const { currentTheme } = useTheme(); const [isHeaderInteractive, setIsHeaderInteractive] = React.useState(false); @@ -111,13 +113,13 @@ const FloatingHeader: React.FC = ({ - {metadata.logo && !logoLoadError ? ( - { - logger.warn(`[FloatingHeader] Logo failed to load: ${metadata.logo}`); + logger.warn(`[FloatingHeader] Logo failed to load: ${stableLogoUri || metadata.logo}`); setLogoLoadError(true); }} /> @@ -155,13 +157,13 @@ const FloatingHeader: React.FC = ({ - {metadata.logo && !logoLoadError ? ( - { - logger.warn(`[FloatingHeader] Logo failed to load: ${metadata.logo}`); + logger.warn(`[FloatingHeader] Logo failed to load: ${stableLogoUri || metadata.logo}`); setLogoLoadError(true); }} /> @@ -202,10 +204,10 @@ const FloatingHeader: React.FC = ({ {metadata.logo && !logoLoadError ? ( - { logger.warn(`[FloatingHeader] Logo failed to load: ${metadata.logo}`); setLogoLoadError(true); diff --git a/src/components/metadata/HeroSection.tsx b/src/components/metadata/HeroSection.tsx index 3d18114a..64fef14c 100644 --- a/src/components/metadata/HeroSection.tsx +++ b/src/components/metadata/HeroSection.tsx @@ -83,6 +83,7 @@ interface HeroSectionProps { traktSynced?: boolean; traktProgress?: number; } | null; + onStableLogoUriChange?: (logoUri: string | null) => void; type: 'movie' | 'series'; getEpisodeDetails: (episodeId: string) => { seasonNumber: string; episodeNumber: string; episodeName: string } | null; handleShowStreams: () => void; @@ -777,6 +778,7 @@ const HeroSection: React.FC = memo(({ buttonsTranslateY, watchProgressOpacity, watchProgress, + onStableLogoUriChange, type, getEpisodeDetails, handleShowStreams, @@ -832,7 +834,7 @@ const HeroSection: React.FC = memo(({ const titleCardTranslateY = useSharedValue(0); const genreOpacity = useSharedValue(1); - // Performance optimization: Cache theme colors + // Ultra-optimized theme colors with stable references const themeColors = useMemo(() => ({ black: currentTheme.colors.black, darkBackground: currentTheme.colors.darkBackground, @@ -840,6 +842,15 @@ const HeroSection: React.FC = memo(({ text: currentTheme.colors.text }), [currentTheme.colors.black, currentTheme.colors.darkBackground, currentTheme.colors.highEmphasis, currentTheme.colors.text]); + // Pre-calculated style objects for better performance + const staticStyles = useMemo(() => ({ + heroWrapper: styles.heroWrapper, + heroSection: styles.heroSection, + absoluteFill: styles.absoluteFill, + thumbnailContainer: styles.thumbnailContainer, + thumbnailImage: styles.thumbnailImage, + }), []); + // Handle trailer preload completion const handleTrailerPreloaded = useCallback(() => { setTrailerPreloaded(true); @@ -957,12 +968,14 @@ const HeroSection: React.FC = memo(({ if (metadata?.logo && metadata.logo !== stableLogoUri) { setStableLogoUri(metadata.logo); + onStableLogoUriChange?.(metadata.logo); setLogoHasLoadedSuccessfully(false); // Reset for new logo logoLoadOpacity.value = 0; // reset fade for new logo setShouldShowTextFallback(false); } else if (!metadata?.logo && stableLogoUri) { // Clear logo if metadata no longer has one setStableLogoUri(null); + onStableLogoUriChange?.(null); setLogoHasLoadedSuccessfully(false); // Start a short grace period before showing text fallback setShouldShowTextFallback(false); @@ -1153,15 +1166,31 @@ const HeroSection: React.FC = memo(({ opacity: watchProgressOpacity.value, }), []); - // Enhanced backdrop with smooth loading animation + // Ultra-optimized backdrop with cached calculations and minimal worklet overhead const backdropImageStyle = useAnimatedStyle(() => { 'worklet'; - const scale = 1 + (scrollY.value * 0.0001); // Micro scale effect + const scrollYValue = scrollY.value; + + // Pre-calculated constants for better performance + const DEFAULT_ZOOM = 1.1; + const SCROLL_UP_MULTIPLIER = 0.002; + const SCROLL_DOWN_MULTIPLIER = 0.0001; + const MAX_SCALE = 1.4; + const PARALLAX_FACTOR = 0.3; + + // Optimized scale calculation with minimal branching + const scrollUpScale = DEFAULT_ZOOM + Math.abs(scrollYValue) * SCROLL_UP_MULTIPLIER; + const scrollDownScale = DEFAULT_ZOOM + scrollYValue * SCROLL_DOWN_MULTIPLIER; + const scale = Math.min(scrollYValue < 0 ? scrollUpScale : scrollDownScale, MAX_SCALE); + + // Single parallax calculation + const parallaxOffset = scrollYValue * PARALLAX_FACTOR; return { opacity: imageOpacity.value * imageLoadOpacity.value, transform: [ - { scale: Math.min(scale, SCALE_FACTOR) } // Cap scale + { scale }, + { translateY: parallaxOffset } ], }; }, []); @@ -1189,6 +1218,34 @@ const HeroSection: React.FC = memo(({ opacity: genreOpacity.value }), []); + // Ultra-optimized trailer parallax with cached calculations + const trailerParallaxStyle = useAnimatedStyle(() => { + 'worklet'; + const scrollYValue = scrollY.value; + + // Pre-calculated constants for better performance + const DEFAULT_ZOOM = 1.0; + const SCROLL_UP_MULTIPLIER = 0.0015; + const SCROLL_DOWN_MULTIPLIER = 0.0001; + const MAX_SCALE = 1.25; + const PARALLAX_FACTOR = 0.2; + + // Optimized scale calculation with minimal branching + const scrollUpScale = DEFAULT_ZOOM + Math.abs(scrollYValue) * SCROLL_UP_MULTIPLIER; + const scrollDownScale = DEFAULT_ZOOM + scrollYValue * SCROLL_DOWN_MULTIPLIER; + const scale = Math.min(scrollYValue < 0 ? scrollUpScale : scrollDownScale, MAX_SCALE); + + // Single parallax calculation + const parallaxOffset = scrollYValue * PARALLAX_FACTOR; + + return { + transform: [ + { scale }, + { translateY: parallaxOffset } + ], + }; + }, []); + // Optimized genre rendering with lazy loading and memory management const genreElements = useMemo(() => { if (!shouldLoadSecondaryData || !metadata?.genres?.length) return null; @@ -1336,27 +1393,31 @@ const HeroSection: React.FC = memo(({ } }, [isFocused, setTrailerPlaying]); - // Pause/resume trailer based on scroll with hysteresis and guard + // Ultra-optimized scroll-based pause/resume with cached calculations useDerivedValue(() => { 'worklet'; try { if (!scrollGuardEnabledSV.value || isFocusedSV.value === 0) return; - const pauseThreshold = heroHeight.value * 0.7; // pause when beyond 70% - const resumeThreshold = heroHeight.value * 0.4; // resume when back within 40% - + + // Pre-calculate thresholds for better performance + const pauseThreshold = heroHeight.value * 0.7; + const resumeThreshold = heroHeight.value * 0.4; const y = scrollY.value; + const isPlaying = isPlayingSV.value === 1; + const isPausedByScroll = pausedByScrollSV.value === 1; - if (y > pauseThreshold && isPlayingSV.value === 1 && pausedByScrollSV.value === 0) { + // Optimized pause/resume logic with minimal branching + if (y > pauseThreshold && isPlaying && !isPausedByScroll) { pausedByScrollSV.value = 1; runOnJS(setTrailerPlaying)(false); isPlayingSV.value = 0; - } else if (y < resumeThreshold && pausedByScrollSV.value === 1) { + } else if (y < resumeThreshold && isPausedByScroll) { pausedByScrollSV.value = 0; runOnJS(setTrailerPlaying)(true); isPlayingSV.value = 1; } } catch (e) { - // no-op + // Silent error handling for performance } }); @@ -1408,20 +1469,21 @@ const HeroSection: React.FC = memo(({ return ( - - {/* Optimized Background */} - + + + {/* Optimized Background */} + {/* Shimmer loading effect removed */} - {/* Background thumbnail image - always rendered when available */} + {/* Background thumbnail image - always rendered when available with parallax */} {shouldLoadSecondaryData && imageSource && !loadingBanner && ( - = memo(({ {/* Hidden preload trailer player - loads in background */} {shouldLoadSecondaryData && settings?.showTrailers && trailerUrl && !trailerLoading && !trailerError && !trailerPreloaded && ( - + = memo(({ )} - {/* Visible trailer player - rendered on top with fade transition */} + {/* Visible trailer player - rendered on top with fade transition and parallax */} {shouldLoadSecondaryData && settings?.showTrailers && trailerUrl && !trailerLoading && !trailerError && trailerPreloaded && ( - + }, trailerParallaxStyle]}> = memo(({ /> - + + ); }); // Ultra-optimized styles const styles = StyleSheet.create({ + heroWrapper: { + width: '100%', + marginTop: -150, // Extend wrapper 150px above to accommodate thumbnail overflow + paddingTop: 150, // Add padding to maintain proper positioning + overflow: 'hidden', // This will clip the thumbnail overflow when scrolling + }, heroSection: { width: '100%', backgroundColor: '#000', - overflow: 'hidden', + overflow: 'visible', // Allow thumbnail to extend within the wrapper }, absoluteFill: { @@ -1660,6 +1729,20 @@ const styles = StyleSheet.create({ right: 0, bottom: 0, }, + thumbnailContainer: { + position: 'absolute', + top: 0, // Now positioned at the top of the wrapper (which extends 150px above) + left: 0, + right: 0, + bottom: 0, + }, + thumbnailImage: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + }, backButtonContainer: { position: 'absolute', top: Platform.OS === 'android' ? 40 : 50, diff --git a/src/components/metadata/TrailerModal.tsx b/src/components/metadata/TrailerModal.tsx new file mode 100644 index 00000000..c18e131e --- /dev/null +++ b/src/components/metadata/TrailerModal.tsx @@ -0,0 +1,467 @@ +import React, { useState, useEffect, useCallback, memo } from 'react'; +import { + View, + Text, + StyleSheet, + Modal, + TouchableOpacity, + ActivityIndicator, + Dimensions, + Platform, + Alert, +} from 'react-native'; +import { useTheme } from '../../contexts/ThemeContext'; +import { useTrailer } from '../../contexts/TrailerContext'; +import { logger } from '../../utils/logger'; +import TrailerService from '../../services/trailerService'; +import Video, { VideoRef, OnLoadData, OnProgressData } from 'react-native-video'; + +const { width, height } = Dimensions.get('window'); +const isTablet = width >= 768; + +// Helper function to format trailer type +const formatTrailerType = (type: string): string => { + switch (type) { + case 'Trailer': + return 'Official Trailer'; + case 'Teaser': + return 'Teaser'; + case 'Clip': + return 'Clip'; + case 'Featurette': + return 'Featurette'; + case 'Behind the Scenes': + return 'Behind the Scenes'; + default: + return type; + } +}; + +interface TrailerVideo { + id: string; + key: string; + name: string; + site: string; + size: number; + type: string; + official: boolean; + published_at: string; +} + +interface TrailerModalProps { + visible: boolean; + onClose: () => void; + trailer: TrailerVideo | null; + contentTitle: string; +} + +const TrailerModal: React.FC = memo(({ + visible, + onClose, + trailer, + contentTitle +}) => { + const { currentTheme } = useTheme(); + const { pauseTrailer, resumeTrailer } = useTrailer(); + const videoRef = React.useRef(null); + const [trailerUrl, setTrailerUrl] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [isPlaying, setIsPlaying] = useState(false); + const [retryCount, setRetryCount] = useState(0); + + // Load trailer when modal opens or trailer changes + useEffect(() => { + if (visible && trailer) { + loadTrailer(); + } else { + // Reset state when modal closes + setTrailerUrl(null); + setLoading(false); + setError(null); + setIsPlaying(false); + setRetryCount(0); + } + }, [visible, trailer]); + + const loadTrailer = useCallback(async () => { + if (!trailer) return; + + // Pause hero section trailer when modal opens + try { + pauseTrailer(); + logger.info('TrailerModal', 'Paused hero section trailer'); + } catch (error) { + logger.warn('TrailerModal', 'Error pausing hero trailer:', error); + } + + setLoading(true); + setError(null); + setTrailerUrl(null); + setRetryCount(0); // Reset retry count when starting fresh load + + try { + const youtubeUrl = `https://www.youtube.com/watch?v=${trailer.key}`; + + logger.info('TrailerModal', `Loading trailer: ${trailer.name} (${youtubeUrl})`); + + // Use the direct YouTube URL method - much more efficient! + const directUrl = await TrailerService.getTrailerFromYouTubeUrl( + youtubeUrl, + `${contentTitle} - ${trailer.name}`, + new Date(trailer.published_at).getFullYear().toString() + ); + + if (directUrl) { + setTrailerUrl(directUrl); + setIsPlaying(true); + logger.info('TrailerModal', `Successfully loaded direct trailer URL for: ${trailer.name}`); + } else { + throw new Error('No streaming URL available'); + } + } catch (err) { + const errorMessage = err instanceof Error ? err.message : 'Failed to load trailer'; + setError(errorMessage); + setLoading(false); + logger.error('TrailerModal', 'Error loading trailer:', err); + + Alert.alert( + 'Trailer Unavailable', + 'This trailer could not be loaded at this time. Please try again later.', + [{ text: 'OK', style: 'default' }] + ); + } + }, [trailer, contentTitle, pauseTrailer]); + + const handleClose = useCallback(() => { + setIsPlaying(false); + + // Resume hero section trailer when modal closes + try { + resumeTrailer(); + logger.info('TrailerModal', 'Resumed hero section trailer'); + } catch (error) { + logger.warn('TrailerModal', 'Error resuming hero trailer:', error); + } + + onClose(); + }, [onClose, resumeTrailer]); + + const handleTrailerError = useCallback(() => { + setError('Failed to play trailer'); + setIsPlaying(false); + }, []); + + // Handle video playback errors with retry logic + const handleVideoError = useCallback((error: any) => { + logger.error('TrailerModal', 'Video error:', error); + + // Check if this is a permission/network error that might benefit from retry + const errorCode = error?.error?.code; + const isRetryableError = errorCode === -1102 || errorCode === -1009 || errorCode === -1005; + + if (isRetryableError && retryCount < 2) { + // Silent retry - increment count and try again + logger.info('TrailerModal', `Retrying video load (attempt ${retryCount + 1}/2)`); + setRetryCount(prev => prev + 1); + + // Small delay before retry to avoid rapid-fire attempts + setTimeout(() => { + if (videoRef.current) { + // Force video to reload by changing the source briefly + setTrailerUrl(null); + setTimeout(() => { + if (trailerUrl) { + setTrailerUrl(trailerUrl); + } + }, 100); + } + }, 1000); + return; + } + + // After 2 retries or for non-retryable errors, show the error + logger.error('TrailerModal', 'Video error after retries or non-retryable:', error); + setError('Unable to play trailer. Please try again.'); + setLoading(false); + }, [retryCount, trailerUrl]); + + const handleTrailerEnd = useCallback(() => { + setIsPlaying(false); + }, []); + + if (!visible || !trailer) return null; + + const modalHeight = isTablet ? height * 0.8 : height * 0.7; + const modalWidth = isTablet ? width * 0.8 : width * 0.95; + + return ( + + + + {/* Enhanced Header */} + + + + + {trailer.name} + + + + {formatTrailerType(trailer.type)} • {new Date(trailer.published_at).getFullYear()} + + + + + + + Close + + + + + {/* Player Container */} + + {loading && ( + + + + Loading trailer... + + + )} + + {error && !loading && ( + + + {error} + + + Try Again + + + )} + + {/* Render the Video as soon as we have a URL; keep spinner overlay until onLoad */} + {trailerUrl && !error && ( + + + )} + + + {/* Enhanced Footer */} + + + + {contentTitle} + + + + + + + ); +}); + +const styles = StyleSheet.create({ + overlay: { + flex: 1, + backgroundColor: 'rgba(0,0,0,0.92)', + justifyContent: 'center', + alignItems: 'center', + }, + modal: { + borderRadius: 20, + overflow: 'hidden', + elevation: 12, + shadowColor: '#000', + shadowOffset: { width: 0, height: 6 }, + shadowOpacity: 0.4, + shadowRadius: 12, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.1)', + }, + + // Enhanced Header Styles + header: { + flexDirection: 'row', + alignItems: 'flex-start', + justifyContent: 'space-between', + paddingHorizontal: 20, + paddingVertical: 18, + borderBottomWidth: 1, + borderBottomColor: 'rgba(255,255,255,0.08)', + }, + headerLeft: { + flexDirection: 'row', + flex: 1, + }, + headerTextContainer: { + flex: 1, + gap: 4, + }, + title: { + fontSize: 16, + fontWeight: '700', + lineHeight: 20, + color: '#fff', + }, + headerMeta: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + }, + meta: { + fontSize: 12, + opacity: 0.7, + fontWeight: '500', + }, + closeButton: { + paddingHorizontal: 12, + paddingVertical: 6, + borderRadius: 16, + alignItems: 'center', + justifyContent: 'center', + }, + closeButtonText: { + fontSize: 14, + fontWeight: '600', + }, + playerContainer: { + aspectRatio: 16 / 9, + backgroundColor: '#000', + position: 'relative', + }, + loadingContainer: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#000', + gap: 16, + }, + loadingText: { + fontSize: 14, + opacity: 0.8, + }, + errorContainer: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#000', + padding: 20, + gap: 16, + }, + errorText: { + fontSize: 14, + textAlign: 'center', + opacity: 0.8, + }, + retryButton: { + paddingHorizontal: 20, + paddingVertical: 10, + borderRadius: 20, + }, + retryButtonText: { + color: '#fff', + fontSize: 14, + fontWeight: '600', + }, + playerWrapper: { + flex: 1, + }, + player: { + flex: 1, + }, + // Enhanced Footer Styles + footer: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: 20, + paddingVertical: 16, + borderTopWidth: 1, + borderTopColor: 'rgba(255,255,255,0.08)', + }, + footerContent: { + flexDirection: 'row', + alignItems: 'center', + flex: 1, + }, + footerText: { + fontSize: 13, + fontWeight: '500', + opacity: 0.8, + }, + footerMeta: { + alignItems: 'flex-end', + }, + footerMetaText: { + fontSize: 11, + opacity: 0.6, + fontWeight: '500', + }, +}); + +export default TrailerModal; diff --git a/src/components/metadata/TrailersSection.tsx b/src/components/metadata/TrailersSection.tsx new file mode 100644 index 00000000..c059a59a --- /dev/null +++ b/src/components/metadata/TrailersSection.tsx @@ -0,0 +1,860 @@ +import React, { useState, useEffect, useCallback, memo, useRef } from 'react'; +import { + View, + Text, + StyleSheet, + TouchableOpacity, + ActivityIndicator, + Dimensions, + Alert, + Platform, + ScrollView, + Modal, +} from 'react-native'; +import { MaterialIcons } from '@expo/vector-icons'; +import FastImage from '@d11/react-native-fast-image'; +import { useTheme } from '../../contexts/ThemeContext'; +import { useSettings } from '../../hooks/useSettings'; +import { useTrailer } from '../../contexts/TrailerContext'; +import { logger } from '../../utils/logger'; +import TrailerService from '../../services/trailerService'; +import TrailerModal from './TrailerModal'; +import Animated, { useSharedValue, withTiming, withDelay, useAnimatedStyle } from 'react-native-reanimated'; + +const { width } = Dimensions.get('window'); +const isTablet = width >= 768; + +interface TrailerVideo { + id: string; + key: string; + name: string; + site: string; + size: number; + type: string; + official: boolean; + published_at: string; + seasonNumber: number | null; + displayName?: string; +} + +interface TrailersSectionProps { + tmdbId: number | null; + type: 'movie' | 'tv'; + contentId: string; + contentTitle: string; +} + +interface CategorizedTrailers { + [key: string]: TrailerVideo[]; +} + +const TrailersSection: React.FC = memo(({ + tmdbId, + type, + contentId, + contentTitle +}) => { + const { currentTheme } = useTheme(); + const { settings } = useSettings(); + const { pauseTrailer } = useTrailer(); + const [trailers, setTrailers] = useState({}); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [selectedTrailer, setSelectedTrailer] = useState(null); + const [modalVisible, setModalVisible] = useState(false); + const [selectedCategory, setSelectedCategory] = useState('Trailer'); + const [dropdownVisible, setDropdownVisible] = useState(false); + const [backendAvailable, setBackendAvailable] = useState(null); + + // Smooth reveal animation after trailers are fetched + const sectionOpacitySV = useSharedValue(0); + const sectionTranslateYSV = useSharedValue(8); + const hasAnimatedRef = useRef(false); + + const sectionAnimatedStyle = useAnimatedStyle(() => ({ + opacity: sectionOpacitySV.value, + transform: [{ translateY: sectionTranslateYSV.value }], + })); + + // Reset animation state before a new fetch starts + const resetSectionAnimation = useCallback(() => { + hasAnimatedRef.current = false; + sectionOpacitySV.value = 0; + sectionTranslateYSV.value = 8; + }, [sectionOpacitySV, sectionTranslateYSV]); + + // Trigger animation once, 500ms after trailers are available + const triggerSectionAnimation = useCallback(() => { + if (hasAnimatedRef.current) return; + hasAnimatedRef.current = true; + sectionOpacitySV.value = withDelay(500, withTiming(1, { duration: 400 })); + sectionTranslateYSV.value = withDelay(500, withTiming(0, { duration: 400 })); + }, [sectionOpacitySV, sectionTranslateYSV]); + + // Check if trailer service backend is available + const checkBackendAvailability = useCallback(async (): Promise => { + try { + const serverStatus = TrailerService.getServerStatus(); + const healthUrl = `${serverStatus.localUrl.replace('/trailer', '/health')}`; + + const response = await fetch(healthUrl, { + method: 'GET', + signal: AbortSignal.timeout(3000), // 3 second timeout + }); + const isAvailable = response.ok; + logger.info('TrailersSection', `Backend availability check: ${isAvailable ? 'AVAILABLE' : 'UNAVAILABLE'}`); + return isAvailable; + } catch (error) { + logger.warn('TrailersSection', 'Backend availability check failed:', error); + return false; + } + }, []); + + // Fetch trailers from TMDB + useEffect(() => { + if (!tmdbId) return; + + const initializeTrailers = async () => { + resetSectionAnimation(); + // First check if backend is available + const available = await checkBackendAvailability(); + setBackendAvailable(available); + + if (!available) { + logger.warn('TrailersSection', 'Trailer service backend is not available - skipping trailer loading'); + setLoading(false); + return; + } + + // Backend is available, proceed with fetching trailers + await fetchTrailers(); + }; + + const fetchTrailers = async () => { + setLoading(true); + setError(null); + + try { + logger.info('TrailersSection', `Fetching trailers for TMDB ID: ${tmdbId}, type: ${type}`); + + // First check if the movie/TV show exists + const basicEndpoint = type === 'movie' + ? `https://api.themoviedb.org/3/movie/${tmdbId}?api_key=d131017ccc6e5462a81c9304d21476de` + : `https://api.themoviedb.org/3/tv/${tmdbId}?api_key=d131017ccc6e5462a81c9304d21476de`; + + const basicResponse = await fetch(basicEndpoint); + if (!basicResponse.ok) { + if (basicResponse.status === 404) { + // 404 on basic endpoint means TMDB ID doesn't exist - this is normal + logger.info('TrailersSection', `TMDB ID ${tmdbId} not found in TMDB (404) - skipping trailers`); + setTrailers({}); // Empty trailers - section won't render + return; + } + logger.error('TrailersSection', `TMDB basic endpoint failed: ${basicResponse.status} ${basicResponse.statusText}`); + setError(`Failed to verify content: ${basicResponse.status}`); + return; + } + + let allVideos: any[] = []; + + if (type === 'movie') { + // For movies, just fetch the main videos endpoint + const videosEndpoint = `https://api.themoviedb.org/3/movie/${tmdbId}/videos?api_key=d131017ccc6e5462a81c9304d21476de&language=en-US`; + + logger.info('TrailersSection', `Fetching movie videos from: ${videosEndpoint}`); + + const response = await fetch(videosEndpoint); + if (!response.ok) { + // 404 is normal - means no videos exist for this content + if (response.status === 404) { + logger.info('TrailersSection', `No videos found for movie TMDB ID ${tmdbId} (404 response)`); + setTrailers({}); // Empty trailers - section won't render + return; + } + logger.error('TrailersSection', `Videos endpoint failed: ${response.status} ${response.statusText}`); + throw new Error(`Failed to fetch trailers: ${response.status}`); + } + + const data = await response.json(); + allVideos = data.results || []; + logger.info('TrailersSection', `Received ${allVideos.length} videos for movie TMDB ID ${tmdbId}`); + } else { + // For TV shows, fetch both main TV videos and season-specific videos + logger.info('TrailersSection', `Fetching TV show videos and season trailers for TMDB ID ${tmdbId}`); + + // Get TV show details to know how many seasons there are + const tvDetailsResponse = await fetch(basicEndpoint); + const tvDetails = await tvDetailsResponse.json(); + const numberOfSeasons = tvDetails.number_of_seasons || 0; + + logger.info('TrailersSection', `TV show has ${numberOfSeasons} seasons`); + + // Fetch main TV show videos + const tvVideosEndpoint = `https://api.themoviedb.org/3/tv/${tmdbId}/videos?api_key=d131017ccc6e5462a81c9304d21476de&language=en-US`; + const tvResponse = await fetch(tvVideosEndpoint); + + if (tvResponse.ok) { + const tvData = await tvResponse.json(); + // Add season info to main TV videos + const mainVideos = (tvData.results || []).map((video: any) => ({ + ...video, + seasonNumber: null as number | null, // null indicates main TV show videos + displayName: video.name + })); + allVideos.push(...mainVideos); + logger.info('TrailersSection', `Received ${mainVideos.length} main TV videos`); + } + + // Fetch videos from each season (skip season 0 which is specials) + const seasonPromises = []; + for (let seasonNum = 1; seasonNum <= numberOfSeasons; seasonNum++) { + seasonPromises.push( + fetch(`https://api.themoviedb.org/3/tv/${tmdbId}/season/${seasonNum}/videos?api_key=d131017ccc6e5462a81c9304d21476de&language=en-US`) + .then(res => res.json()) + .then(data => ({ + seasonNumber: seasonNum, + videos: data.results || [] + })) + .catch(err => { + logger.warn('TrailersSection', `Failed to fetch season ${seasonNum} videos:`, err); + return { seasonNumber: seasonNum, videos: [] }; + }) + ); + } + + const seasonResults = await Promise.all(seasonPromises); + + // Add season videos to the collection + seasonResults.forEach(result => { + if (result.videos.length > 0) { + const seasonVideos = result.videos.map((video: any) => ({ + ...video, + seasonNumber: result.seasonNumber as number | null, + displayName: `Season ${result.seasonNumber} - ${video.name}` + })); + allVideos.push(...seasonVideos); + logger.info('TrailersSection', `Season ${result.seasonNumber}: ${result.videos.length} videos`); + } + }); + + const totalSeasonVideos = seasonResults.reduce((sum, result) => sum + result.videos.length, 0); + logger.info('TrailersSection', `Total videos collected: ${allVideos.length} (main: ${allVideos.filter(v => v.seasonNumber === null).length}, seasons: ${totalSeasonVideos})`); + } + + const categorized = categorizeTrailers(allVideos); + const totalVideos = Object.values(categorized).reduce((sum, videos) => sum + videos.length, 0); + + if (totalVideos === 0) { + logger.info('TrailersSection', `No videos found for TMDB ID ${tmdbId} - this is normal`); + setTrailers({}); // No trailers available + setSelectedCategory(''); // No category selected + } else { + logger.info('TrailersSection', `Categorized ${totalVideos} videos into ${Object.keys(categorized).length} categories`); + setTrailers(categorized); + // Trigger smooth reveal after 1.5s since we have content + triggerSectionAnimation(); + + // Auto-select the first available category, preferring "Trailer" + const availableCategories = Object.keys(categorized); + const preferredCategory = availableCategories.includes('Trailer') ? 'Trailer' : + availableCategories.includes('Teaser') ? 'Teaser' : availableCategories[0]; + setSelectedCategory(preferredCategory); + } + } catch (err) { + const errorMessage = err instanceof Error ? err.message : 'Failed to load trailers'; + setError(errorMessage); + logger.error('TrailersSection', 'Error fetching trailers:', err); + } finally { + setLoading(false); + } + }; + + initializeTrailers(); + }, [tmdbId, type, checkBackendAvailability]); + + // Categorize trailers by type + const categorizeTrailers = (videos: any[]): CategorizedTrailers => { + const categories: CategorizedTrailers = {}; + + videos.forEach(video => { + if (video.site !== 'YouTube') return; // Only YouTube videos + + const category = video.type; + if (!categories[category]) { + categories[category] = []; + } + categories[category].push(video); + }); + + // Sort within each category: season trailers first (newest seasons), then main series, official first, then by date + Object.keys(categories).forEach(category => { + categories[category].sort((a, b) => { + // Season trailers come before main series trailers + if (a.seasonNumber !== null && b.seasonNumber === null) return -1; + if (a.seasonNumber === null && b.seasonNumber !== null) return 1; + + // If both have season numbers, sort by season number (newest seasons first) + if (a.seasonNumber !== null && b.seasonNumber !== null) { + if (a.seasonNumber !== b.seasonNumber) { + return b.seasonNumber - a.seasonNumber; // Higher season numbers first + } + } + + // Official trailers come first within the same season/main series group + if (a.official && !b.official) return -1; + if (!a.official && b.official) return 1; + + // If both are official or both are not, sort by published date (newest first) + return new Date(b.published_at).getTime() - new Date(a.published_at).getTime(); + }); + }); + + // Sort categories: "Trailer" category first, then categories with official trailers, then alphabetically + const sortedCategories = Object.keys(categories).sort((a, b) => { + // "Trailer" category always comes first + if (a === 'Trailer') return -1; + if (b === 'Trailer') return 1; + + const aHasOfficial = categories[a].some(trailer => trailer.official); + const bHasOfficial = categories[b].some(trailer => trailer.official); + + // Categories with official trailers come first (after Trailer) + if (aHasOfficial && !bHasOfficial) return -1; + if (!aHasOfficial && bHasOfficial) return 1; + + // If both have or don't have official trailers, sort alphabetically + return a.localeCompare(b); + }); + + // Create new object with sorted categories + const sortedCategoriesObj: CategorizedTrailers = {}; + sortedCategories.forEach(category => { + sortedCategoriesObj[category] = categories[category]; + }); + + return sortedCategoriesObj; + }; + + // Handle trailer selection + const handleTrailerPress = (trailer: TrailerVideo) => { + // Pause hero section trailer when modal opens + try { + pauseTrailer(); + } catch (error) { + logger.warn('TrailersSection', 'Error pausing hero trailer:', error); + } + + setSelectedTrailer(trailer); + setModalVisible(true); + }; + + // Handle modal close + const handleModalClose = () => { + setModalVisible(false); + setSelectedTrailer(null); + // Note: Hero trailer will resume automatically when modal closes + // The HeroSection component handles resuming based on scroll position + }; + + // Handle category selection + const handleCategorySelect = (category: string) => { + setSelectedCategory(category); + setDropdownVisible(false); + }; + + // Toggle dropdown + const toggleDropdown = () => { + setDropdownVisible(!dropdownVisible); + }; + + // Get thumbnail URL for YouTube video + const getYouTubeThumbnail = (videoId: string, quality: 'default' | 'hq' | 'maxres' = 'hq') => { + const qualities = { + default: `https://img.youtube.com/vi/${videoId}/default.jpg`, + hq: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`, + maxres: `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg` + }; + return qualities[quality]; + }; + + // Format trailer type for display + const formatTrailerType = (type: string): string => { + switch (type) { + case 'Trailer': + return 'Official Trailers'; + case 'Teaser': + return 'Teasers'; + case 'Clip': + return 'Clips & Scenes'; + case 'Featurette': + return 'Featurettes'; + case 'Behind the Scenes': + return 'Behind the Scenes'; + default: + return type; + } + }; + + // Get icon for trailer type + const getTrailerTypeIcon = (type: string): string => { + switch (type) { + case 'Trailer': + return 'movie'; + case 'Teaser': + return 'videocam'; + case 'Clip': + return 'content-cut'; + case 'Featurette': + return 'featured-video'; + case 'Behind the Scenes': + return 'camera'; + default: + return 'play-circle-outline'; + } + }; + + if (!tmdbId) { + return null; // Don't show if no TMDB ID + } + + // Don't render if backend availability is still being checked or backend is unavailable + if (backendAvailable === null || backendAvailable === false) { + return null; + } + + // Don't render if TMDB enrichment is disabled + if (!settings?.enrichMetadataWithTMDB) { + return null; + } + + if (loading) { + return null; + } + + if (error) { + return null; + } + + const trailerCategories = Object.keys(trailers); + const totalVideos = Object.values(trailers).reduce((sum, videos) => sum + videos.length, 0); + + // Don't show section if no trailers (this is normal for many movies/TV shows) + if (trailerCategories.length === 0 || totalVideos === 0) { + // In development, show a subtle indicator that the section checked but found no trailers + if (__DEV__) { + return ( + + + + + Trailers + + + + + No trailers available + + + + ); + } + return null; + } + + return ( + + {/* Enhanced Header with Category Selector */} + + + Trailers & Videos + + + {/* Category Selector - Right Aligned */} + {trailerCategories.length > 0 && selectedCategory && ( + + + {formatTrailerType(selectedCategory)} + + + + )} + + + {/* Category Dropdown Modal */} + setDropdownVisible(false)} + > + setDropdownVisible(false)} + > + + {trailerCategories.map(category => ( + handleCategorySelect(category)} + activeOpacity={0.7} + > + + + + + + {formatTrailerType(category)} + + + {trailers[category].length} + + + + ))} + + + + + {/* Selected Category Trailers */} + {selectedCategory && trailers[selectedCategory] && ( + + {/* Trailers Horizontal Scroll */} + + {trailers[selectedCategory].map((trailer, index) => ( + handleTrailerPress(trailer)} + activeOpacity={0.9} + > + {/* Thumbnail with Gradient Overlay */} + + + {/* Subtle Gradient Overlay */} + + + + {/* Trailer Info */} + + + {trailer.displayName || trailer.name} + + + {new Date(trailer.published_at).getFullYear()} + + + + ))} + {/* Scroll Indicator - shows when there are more items to scroll */} + {trailers[selectedCategory].length > (isTablet ? 4 : 3) && ( + + + + )} + + + )} + + {/* Trailer Modal */} + + + ); +}); + +const styles = StyleSheet.create({ + container: { + paddingHorizontal: 16, + marginTop: 24, + marginBottom: 16, + }, + // Enhanced Header Styles + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-start', + marginBottom: 0, + gap: 12, + }, + headerTitle: { + fontSize: 20, + fontWeight: '700', + letterSpacing: 0.5, + }, + + // Category Selector Styles + categorySelector: { + flexDirection: 'row', + alignItems: 'center', + borderWidth: 1, + borderRadius: 16, + paddingHorizontal: 10, + paddingVertical: 5, + backgroundColor: 'rgba(255,255,255,0.03)', + gap: 6, + maxWidth: 160, // Limit maximum width to prevent overflow + }, + categorySelectorText: { + fontSize: 12, + fontWeight: '600', + maxWidth: 120, // Limit text width + }, + + // Dropdown Styles + dropdownOverlay: { + flex: 1, + backgroundColor: 'rgba(0,0,0,0.5)', + justifyContent: 'center', + alignItems: 'center', + paddingHorizontal: 20, + }, + dropdownContainer: { + width: '100%', + maxWidth: 320, + borderRadius: 16, + borderWidth: 1, + overflow: 'hidden', + elevation: 8, + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.3, + shadowRadius: 8, + }, + dropdownItem: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: 16, + paddingVertical: 14, + borderBottomWidth: 1, + borderBottomColor: 'rgba(255,255,255,0.05)', + }, + dropdownItemContent: { + flexDirection: 'row', + alignItems: 'center', + gap: 12, + flex: 1, + }, + dropdownItemText: { + fontSize: 16, + flex: 1, + }, + dropdownItemCount: { + fontSize: 12, + opacity: 0.7, + backgroundColor: 'rgba(255,255,255,0.1)', + paddingHorizontal: 8, + paddingVertical: 4, + borderRadius: 10, + minWidth: 24, + textAlign: 'center', + }, + + // Selected Category Content + selectedCategoryContent: { + marginTop: 16, + }, + + // Category Section Styles + categorySection: { + gap: 12, + position: 'relative', // For scroll indicator positioning + }, + categoryHeader: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + categoryTitleContainer: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + }, + categoryIconContainer: { + width: 28, + height: 28, + borderRadius: 8, + alignItems: 'center', + justifyContent: 'center', + }, + categoryTitle: { + fontSize: 16, + fontWeight: '600', + }, + categoryBadge: { + borderRadius: 12, + paddingHorizontal: 8, + paddingVertical: 4, + minWidth: 24, + alignItems: 'center', + }, + categoryBadgeText: { + fontSize: 12, + fontWeight: '600', + }, + + // Trailers Scroll View + trailersScrollView: { + marginHorizontal: -4, // Compensate for padding + }, + trailersScrollContent: { + paddingHorizontal: 4, // Restore padding for first/last items + gap: 12, + paddingRight: 20, // Extra padding at end for scroll indicator + }, + + // Enhanced Trailer Card Styles + trailerCard: { + width: isTablet ? 200 : 170, + backgroundColor: 'rgba(255,255,255,0.03)', + borderRadius: 16, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.08)', + overflow: 'hidden', + elevation: 2, + shadowColor: '#000', + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.1, + shadowRadius: 2, + }, + + // Thumbnail Styles + thumbnailWrapper: { + position: 'relative', + aspectRatio: 16 / 9, + }, + thumbnail: { + width: '100%', + height: '100%', + borderTopLeftRadius: 16, + borderTopRightRadius: 16, + }, + thumbnailGradient: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'rgba(0,0,0,0.2)', + borderTopLeftRadius: 16, + borderTopRightRadius: 16, + }, + + + + // Trailer Info Styles + trailerInfo: { + padding: 12, + }, + trailerTitle: { + fontSize: 12, + fontWeight: '600', + lineHeight: 16, + marginBottom: 4, + }, + trailerMeta: { + fontSize: 10, + opacity: 0.7, + fontWeight: '500', + }, + + // Loading and Error States + loadingContainer: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + paddingVertical: 32, + gap: 12, + }, + loadingText: { + fontSize: 14, + opacity: 0.7, + }, + errorContainer: { + alignItems: 'center', + paddingVertical: 32, + gap: 8, + }, + errorText: { + fontSize: 14, + textAlign: 'center', + opacity: 0.7, + }, + + // Scroll Indicator + scrollIndicator: { + position: 'absolute', + right: 4, + top: '50%', + transform: [{ translateY: -10 }], + width: 24, + height: 20, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: 'rgba(0,0,0,0.3)', + borderRadius: 12, + }, + + // No Trailers State + noTrailersContainer: { + alignItems: 'center', + paddingVertical: 24, + }, + noTrailersText: { + fontSize: 14, + opacity: 0.6, + fontStyle: 'italic', + }, +}); + +export default TrailersSection; diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index 0a89cdc7..2354da8e 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -86,7 +86,7 @@ const AndroidVideoPlayer: React.FC = () => { }, [route.params]); // TEMP: force React Native Video for testing (disable VLC) const TEMP_FORCE_RNV = false; - const TEMP_FORCE_VLC = true; + const TEMP_FORCE_VLC = false; const useVLC = Platform.OS === 'android' && !TEMP_FORCE_RNV && (TEMP_FORCE_VLC || forceVlc); // Log player selection @@ -1614,7 +1614,7 @@ const AndroidVideoPlayer: React.FC = () => { resizeModes = ['contain', 'cover']; } else { // On Android with VLC backend, only 'none' (original) and 'cover' (client-side crop) - resizeModes = useVLC ? ['none', 'cover'] : ['contain', 'cover', 'none']; + resizeModes = useVLC ? ['none', 'cover'] : ['cover', 'none']; } const currentIndex = resizeModes.indexOf(resizeMode); diff --git a/src/components/player/KSPlayerCore.tsx b/src/components/player/KSPlayerCore.tsx index 94e65628..688af143 100644 --- a/src/components/player/KSPlayerCore.tsx +++ b/src/components/player/KSPlayerCore.tsx @@ -110,7 +110,7 @@ const KSPlayerCore: React.FC = () => { const [selectedAudioTrack, setSelectedAudioTrack] = useState(null); const [textTracks, setTextTracks] = useState([]); const [selectedTextTrack, setSelectedTextTrack] = useState(-1); - const [resizeMode, setResizeMode] = useState('stretch'); + const [resizeMode, setResizeMode] = useState('contain'); const [buffered, setBuffered] = useState(0); const [seekPosition, setSeekPosition] = useState(null); const ksPlayerRef = useRef(null); diff --git a/src/components/video/TrailerPlayer.tsx b/src/components/video/TrailerPlayer.tsx index 5ce62332..6dafac8e 100644 --- a/src/components/video/TrailerPlayer.tsx +++ b/src/components/video/TrailerPlayer.tsx @@ -20,6 +20,7 @@ import Animated, { runOnJS, } from 'react-native-reanimated'; import { useTheme } from '../../contexts/ThemeContext'; +import { useTrailer } from '../../contexts/TrailerContext'; import { logger } from '../../utils/logger'; const { width, height } = Dimensions.get('window'); @@ -57,6 +58,7 @@ const TrailerPlayer = React.forwardRef(({ hideControls = false, }, ref) => { const { currentTheme } = useTheme(); + const { isTrailerPlaying: globalTrailerPlaying } = useTrailer(); const videoRef = useRef(null); const [isLoading, setIsLoading] = useState(true); @@ -146,6 +148,22 @@ const TrailerPlayer = React.forwardRef(({ } }, [autoPlay, isComponentMounted]); + // Respond to global trailer state changes (e.g., when modal opens) + useEffect(() => { + if (isComponentMounted) { + // If global trailer is paused, pause this trailer too + if (!globalTrailerPlaying && isPlaying) { + logger.info('TrailerPlayer', 'Global trailer paused - pausing this trailer'); + setIsPlaying(false); + } + // If global trailer is resumed and autoPlay is enabled, resume this trailer + else if (globalTrailerPlaying && !isPlaying && autoPlay) { + logger.info('TrailerPlayer', 'Global trailer resumed - resuming this trailer'); + setIsPlaying(true); + } + } + }, [globalTrailerPlaying, isPlaying, autoPlay, isComponentMounted]); + const showControlsWithTimeout = useCallback(() => { if (!isComponentMounted) return; diff --git a/src/hooks/useMetadata.ts b/src/hooks/useMetadata.ts index fb66db71..3c9ad638 100644 --- a/src/hooks/useMetadata.ts +++ b/src/hooks/useMetadata.ts @@ -107,28 +107,6 @@ interface UseMetadataReturn { imdbId: string | null; scraperStatuses: ScraperStatus[]; activeFetchingScrapers: string[]; - clearScraperCache: () => Promise; - invalidateScraperCache: (scraperId: string) => Promise; - invalidateContentCache: (type: string, tmdbId: string, season?: number, episode?: number) => Promise; - getScraperCacheStats: () => Promise<{ - local: { - totalEntries: number; - totalSize: number; - oldestEntry: number | null; - newestEntry: number | null; - }; - global: { - totalEntries: number; - totalSize: number; - oldestEntry: number | null; - newestEntry: number | null; - hitRate: number; - }; - combined: { - totalEntries: number; - hitRate: number; - }; - }>; } export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadataReturn => { @@ -287,9 +265,9 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat // Optimize streams before storing const optimizedStreams = optimizeStreams(streams); streamCountRef.current += optimizedStreams.length; - + if (__DEV__) logger.log(`📊 [${logPrefix}:${sourceName}] Optimized ${streams.length} → ${optimizedStreams.length} streams, total: ${streamCountRef.current}`); - + // Use debounced update to prevent rapid state changes debouncedStreamUpdate(() => { const updateState = (prevState: GroupedStreams): GroupedStreams => { @@ -302,7 +280,7 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat } }; }; - + // Track response order for addons setAddonResponseOrder(prevOrder => { if (!prevOrder.includes(addonId)) { @@ -310,7 +288,7 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat } return prevOrder; }); - + if (isEpisode) { setEpisodeStreams(updateState); setLoadingEpisodeStreams(false); @@ -320,7 +298,38 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat } }); } else { - if (__DEV__) logger.log(`🤷 [${logPrefix}:${sourceName}] No streams found for addon ${addonName} (${addonId})`); + // Even providers with no streams should be added to the streams object + // This ensures streamsEmpty becomes false and UI shows available streams progressively + if (__DEV__) logger.log(`🤷 [${logPrefix}:${sourceName}] No streams found for addon ${addonName} (${addonId})`); + + debouncedStreamUpdate(() => { + const updateState = (prevState: GroupedStreams): GroupedStreams => { + if (__DEV__) logger.log(`🔄 [${logPrefix}:${sourceName}] Adding empty provider ${addonName} (${addonId}) to state`); + return { + ...prevState, + [addonId]: { + addonName: addonName, + streams: [] // Empty array for providers with no streams + } + }; + }; + + // Track response order for addons + setAddonResponseOrder(prevOrder => { + if (!prevOrder.includes(addonId)) { + return [...prevOrder, addonId]; + } + return prevOrder; + }); + + if (isEpisode) { + setEpisodeStreams(updateState); + setLoadingEpisodeStreams(false); + } else { + setGroupedStreams(updateState); + setLoadingStreams(false); + } + }); } } else { // Handle case where callback provides null streams without error (e.g., empty results) @@ -1974,36 +1983,6 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat }; }, [cleanupStreams]); - // Cache management methods - const clearScraperCache = useCallback(async () => { - await localScraperService.clearScraperCache(); - }, []); - - const invalidateScraperCache = useCallback(async (scraperId: string) => { - await localScraperService.invalidateScraperCache(scraperId); - }, []); - - const invalidateContentCache = useCallback(async (type: string, tmdbId: string, season?: number, episode?: number) => { - await localScraperService.invalidateContentCache(type, tmdbId, season, episode); - }, []); - - const getScraperCacheStats = useCallback(async () => { - const localStats = await localScraperService.getCacheStats(); - return { - local: localStats.local, - global: { - totalEntries: 0, - totalSize: 0, - oldestEntry: null, - newestEntry: null, - hitRate: 0 - }, - combined: { - totalEntries: localStats.local.totalEntries, - hitRate: 0 - } - }; - }, []); return { metadata, @@ -2038,9 +2017,5 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat imdbId, scraperStatuses, activeFetchingScrapers, - clearScraperCache, - invalidateScraperCache, - invalidateContentCache, - getScraperCacheStats, }; }; \ No newline at end of file diff --git a/src/navigation/AppNavigator.tsx b/src/navigation/AppNavigator.tsx index 32219897..c8057995 100644 --- a/src/navigation/AppNavigator.tsx +++ b/src/navigation/AppNavigator.tsx @@ -672,7 +672,7 @@ const MainTabs = () => { bottom: 0, left: 0, right: 0, - height: 85, + height: 85 + insets.bottom, backgroundColor: 'transparent', overflow: 'hidden', }}> @@ -722,7 +722,7 @@ const MainTabs = () => { { // Dynamically require to avoid impacting Android bundle const { createNativeBottomTabNavigator } = require('@bottom-tabs/react-navigation'); const IOSTab = createNativeBottomTabNavigator(); + const downloadsEnabled = appSettings?.enableDownloads !== false; return ( @@ -828,6 +829,8 @@ const MainTabs = () => { backgroundColor="transparent" /> { tabBarIcon: () => ({ sfSymbol: 'magnifyingglass' }), }} /> - {appSettings?.enableDownloads !== false && ( + {downloadsEnabled && ( { backgroundColor="transparent" translucent /> - { ListFooterComponent={ListFooterComponent} onEndReached={handleLoadMoreCatalogs} onEndReachedThreshold={0.6} - removeClippedSubviews={true} - scrollEventThrottle={64} + recycleItems={true} + maintainVisibleContentPosition onScroll={handleScroll} /> {/* Toasts are rendered globally at root */} diff --git a/src/screens/MetadataScreen.tsx b/src/screens/MetadataScreen.tsx index d37128ac..40043dea 100644 --- a/src/screens/MetadataScreen.tsx +++ b/src/screens/MetadataScreen.tsx @@ -26,6 +26,7 @@ import { MovieContent } from '../components/metadata/MovieContent'; import { MoreLikeThisSection } from '../components/metadata/MoreLikeThisSection'; import { RatingsSection } from '../components/metadata/RatingsSection'; import { CommentsSection, CommentBottomSheet } from '../components/metadata/CommentsSection'; +import TrailersSection from '../components/metadata/TrailersSection'; import { RouteParams, Episode } from '../types/metadata'; import Animated, { useAnimatedStyle, @@ -210,6 +211,9 @@ const MetadataScreen: React.FC = () => { const watchProgressData = useWatchProgress(id, Object.keys(groupedEpisodes).length > 0 ? 'series' : type as 'movie' | 'series', episodeId, episodes); const assetData = useMetadataAssets(metadata, id, type, imdbId, settings, setMetadata); const animations = useMetadataAnimations(safeAreaTop, watchProgressData.watchProgress); + + // Stable logo URI from HeroSection + const [stableLogoUri, setStableLogoUri] = React.useState(null); // Extract dominant color from hero image for dynamic background const heroImageUri = useMemo(() => { @@ -869,7 +873,7 @@ const MetadataScreen: React.FC = () => { {metadata && ( <> {/* Floating Header - Optimized */} - { headerElementsOpacity={animations.headerElementsOpacity} safeAreaTop={safeAreaTop} setLogoLoadError={assetData.setLogoLoadError} + stableLogoUri={stableLogoUri} /> { watchProgressOpacity={animations.watchProgressOpacity} watchProgressWidth={animations.watchProgressWidth} watchProgress={watchProgressData.watchProgress} + onStableLogoUriChange={setStableLogoUri} type={Object.keys(groupedEpisodes).length > 0 ? 'series' : type as 'movie' | 'series'} getEpisodeDetails={watchProgressData.getEpisodeDetails} handleShowStreams={handleShowStreams} @@ -992,6 +998,16 @@ const MetadataScreen: React.FC = () => { )} + {/* Trailers Section - Lazy loaded */} + {shouldLoadSecondaryData && tmdbId && settings.enrichMetadataWithTMDB && ( + 0 ? 'tv' : 'movie'} + contentId={id} + contentTitle={metadata?.name || (metadata as any)?.title || 'Unknown'} + /> + )} + {/* Comments Section - Lazy loaded */} {shouldLoadSecondaryData && imdbId && ( - onPress()} - activeOpacity={0.7} - > - - + {settings?.enableDownloads !== false && ( ; - expiredScrapers: string[]; - allExpired: boolean; - source: 'local'; -} - -export interface HybridCacheStats { - local: { - totalEntries: number; - totalSize: number; - oldestEntry: number | null; - newestEntry: number | null; - }; -} - -class HybridCacheService { - private static instance: HybridCacheService; - // Global caching removed; local-only - - private constructor() {} - - public static getInstance(): HybridCacheService { - if (!HybridCacheService.instance) { - HybridCacheService.instance = new HybridCacheService(); - } - return HybridCacheService.instance; - } - - /** - * Get cached results (local-only) - */ - async getCachedResults( - type: string, - tmdbId: string, - season?: number, - episode?: number, - userSettings?: { enableLocalScrapers?: boolean; enabledScrapers?: Set } - ): Promise { - try { - // Filter function to check if scraper is enabled for current user - const isScraperEnabled = (scraperId: string): boolean => { - if (!userSettings?.enableLocalScrapers) return false; - if (userSettings?.enabledScrapers) { - return userSettings.enabledScrapers.has(scraperId); - } - // If no specific scraper settings, assume all are enabled if local scrapers are enabled - return true; - }; - - // Local cache only - const localResults = await localScraperCacheService.getCachedResults(type, tmdbId, season, episode); - - // Filter results based on user settings - const filteredLocalResults = { - ...localResults, - validResults: localResults.validResults.filter(result => isScraperEnabled(result.scraperId)), - expiredScrapers: localResults.expiredScrapers.filter(scraperId => isScraperEnabled(scraperId)) - }; - - logger.log(`[HybridCache] Using local cache: ${filteredLocalResults.validResults.length} results (filtered from ${localResults.validResults.length})`); - return { - ...filteredLocalResults, - source: 'local' - }; - - } catch (error) { - logger.error('[HybridCache] Error getting cached results:', error); - return { - validResults: [], - expiredScrapers: [], - allExpired: true, - source: 'local' - }; - } - } - - /** - * Cache results (local-only) - */ - async cacheResults( - type: string, - tmdbId: string, - results: Array<{ - scraperId: string; - scraperName: string; - streams: Stream[] | null; - error: Error | null; - }>, - season?: number, - episode?: number - ): Promise { - try { - // Cache in local storage - const localPromises = results.map(result => - localScraperCacheService.cacheScraperResult( - type, tmdbId, result.scraperId, result.scraperName, - result.streams, result.error, season, episode - ) - ); - await Promise.all(localPromises); - logger.log(`[HybridCache] Cached ${results.length} results in local cache`); - - } catch (error) { - logger.error('[HybridCache] Error caching results:', error); - } - } - - /** - * Cache a single scraper result - */ - async cacheScraperResult( - type: string, - tmdbId: string, - scraperId: string, - scraperName: string, - streams: Stream[] | null, - error: Error | null, - season?: number, - episode?: number - ): Promise { - await this.cacheResults(type, tmdbId, [{ - scraperId, - scraperName, - streams, - error - }], season, episode); - } - - /** - * Get list of scrapers that need to be re-run (expired, failed, or not cached) - */ - async getScrapersToRerun( - type: string, - tmdbId: string, - availableScrapers: Array<{ id: string; name: string }>, - season?: number, - episode?: number, - userSettings?: { enableLocalScrapers?: boolean; enabledScrapers?: Set } - ): Promise { - const { validResults, expiredScrapers } = await this.getCachedResults(type, tmdbId, season, episode, userSettings); - - const validScraperIds = new Set(validResults.map(r => r.scraperId)); - const expiredScraperIds = new Set(expiredScrapers); - - // Get scrapers that previously failed (returned no streams) - const failedScraperIds = new Set( - validResults - .filter(r => !r.success || r.streams.length === 0) - .map(r => r.scraperId) - ); - - // Return scrapers that are: - // 1. Not cached at all - // 2. Expired - // 3. Previously failed (regardless of cache status) - const scrapersToRerun = availableScrapers - .filter(scraper => - !validScraperIds.has(scraper.id) || - expiredScraperIds.has(scraper.id) || - failedScraperIds.has(scraper.id) - ) - .map(scraper => scraper.id); - - logger.log(`[HybridCache] Scrapers to re-run: ${scrapersToRerun.join(', ')} (not cached: ${availableScrapers.filter(s => !validScraperIds.has(s.id)).length}, expired: ${expiredScrapers.length}, failed: ${failedScraperIds.size})`); - - return scrapersToRerun; - } - - /** - * Get all valid cached streams - */ - async getCachedStreams( - type: string, - tmdbId: string, - season?: number, - episode?: number, - userSettings?: { enableLocalScrapers?: boolean; enabledScrapers?: Set } - ): Promise { - const { validResults } = await this.getCachedResults(type, tmdbId, season, episode, userSettings); - - // Flatten all valid streams - const allStreams: Stream[] = []; - for (const result of validResults) { - if (result.success && result.streams) { - allStreams.push(...result.streams); - } - } - - return allStreams; - } - - /** - * Invalidate cache for specific content (local-only) - */ - async invalidateContent( - type: string, - tmdbId: string, - season?: number, - episode?: number - ): Promise { - try { - await localScraperCacheService.invalidateContent(type, tmdbId, season, episode); - logger.log(`[HybridCache] Invalidated cache for ${type}:${tmdbId}`); - } catch (error) { - logger.error('[HybridCache] Error invalidating cache:', error); - } - } - - /** - * Invalidate cache for specific scraper (local-only) - */ - async invalidateScraper(scraperId: string): Promise { - try { - await localScraperCacheService.invalidateScraper(scraperId); - logger.log(`[HybridCache] Invalidated cache for scraper ${scraperId}`); - } catch (error) { - logger.error('[HybridCache] Error invalidating scraper cache:', error); - } - } - - /** - * Clear all cached results (local-only) - */ - async clearAllCache(): Promise { - try { - await localScraperCacheService.clearAllCache(); - logger.log('[HybridCache] Cleared all local cache'); - } catch (error) { - logger.error('[HybridCache] Error clearing cache:', error); - } - } - - /** - * Get cache statistics (local-only) - */ - async getCacheStats(): Promise { - try { - const localStats = await localScraperCacheService.getCacheStats(); - return { local: localStats }; - } catch (error) { - logger.error('[HybridCache] Error getting cache stats:', error); - return { local: { totalEntries: 0, totalSize: 0, oldestEntry: null, newestEntry: null } }; - } - } - - /** - * Clean up old entries (local-only) - */ - async cleanupOldEntries(): Promise { - try { - await localScraperCacheService.clearAllCache(); - logger.log('[HybridCache] Cleaned up old entries'); - } catch (error) { - logger.error('[HybridCache] Error cleaning up old entries:', error); - } - } - - // Configuration APIs removed; local-only -} - -export const hybridCacheService = HybridCacheService.getInstance(); -export default hybridCacheService; diff --git a/src/services/localScraperCacheService.ts b/src/services/localScraperCacheService.ts deleted file mode 100644 index e00eb6e9..00000000 --- a/src/services/localScraperCacheService.ts +++ /dev/null @@ -1,437 +0,0 @@ -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { logger } from '../utils/logger'; -import { Stream } from '../types/streams'; - -export interface CachedScraperResult { - streams: Stream[]; - timestamp: number; - success: boolean; - error?: string; - scraperId: string; - scraperName: string; -} - -export interface CachedContentResult { - contentKey: string; // e.g., "movie:123" or "tv:123:1:2" - results: CachedScraperResult[]; - timestamp: number; - ttl: number; -} - -class LocalScraperCacheService { - private static instance: LocalScraperCacheService; - private readonly CACHE_KEY_PREFIX = 'local-scraper-cache'; - private readonly DEFAULT_TTL_MS = 30 * 60 * 1000; // 30 minutes default TTL - private readonly MAX_CACHE_SIZE = 200; // Maximum number of cached content items - private readonly FAILED_RETRY_TTL_MS = 5 * 60 * 1000; // 5 minutes for failed scrapers - private readonly SUCCESS_TTL_MS = 60 * 60 * 1000; // 1 hour for successful scrapers - - private constructor() {} - - public static getInstance(): LocalScraperCacheService { - if (!LocalScraperCacheService.instance) { - LocalScraperCacheService.instance = new LocalScraperCacheService(); - } - return LocalScraperCacheService.instance; - } - - /** - * Generate cache key for content - */ - private getContentKey(type: string, tmdbId: string, season?: number, episode?: number): string { - if (season !== undefined && episode !== undefined) { - return `${type}:${tmdbId}:${season}:${episode}`; - } - return `${type}:${tmdbId}`; - } - - /** - * Generate AsyncStorage key for cached content - */ - private getStorageKey(contentKey: string): string { - return `${this.CACHE_KEY_PREFIX}:${contentKey}`; - } - - /** - * Check if cached result is still valid based on TTL - */ - private isCacheValid(timestamp: number, ttl: number): boolean { - return Date.now() - timestamp < ttl; - } - - /** - * Get cached results for content, filtering out expired results - */ - async getCachedResults( - type: string, - tmdbId: string, - season?: number, - episode?: number - ): Promise<{ - validResults: CachedScraperResult[]; - expiredScrapers: string[]; - allExpired: boolean; - }> { - try { - const contentKey = this.getContentKey(type, tmdbId, season, episode); - const storageKey = this.getStorageKey(contentKey); - - const cachedData = await AsyncStorage.getItem(storageKey); - if (!cachedData) { - return { - validResults: [], - expiredScrapers: [], - allExpired: true - }; - } - - const parsed: CachedContentResult = JSON.parse(cachedData); - - // Check if the entire cache entry is expired - if (!this.isCacheValid(parsed.timestamp, parsed.ttl)) { - // Remove expired entry - await AsyncStorage.removeItem(storageKey); - return { - validResults: [], - expiredScrapers: parsed.results.map(r => r.scraperId), - allExpired: true - }; - } - - // Filter valid results and identify expired scrapers - const validResults: CachedScraperResult[] = []; - const expiredScrapers: string[] = []; - - for (const result of parsed.results) { - // Use different TTL based on success/failure - const ttl = result.success ? this.SUCCESS_TTL_MS : this.FAILED_RETRY_TTL_MS; - - if (this.isCacheValid(result.timestamp, ttl)) { - validResults.push(result); - } else { - expiredScrapers.push(result.scraperId); - } - } - - logger.log(`[LocalScraperCache] Retrieved ${validResults.length} valid results, ${expiredScrapers.length} expired scrapers for ${contentKey}`); - - return { - validResults, - expiredScrapers, - allExpired: validResults.length === 0 - }; - - } catch (error) { - logger.error('[LocalScraperCache] Error getting cached results:', error); - return { - validResults: [], - expiredScrapers: [], - allExpired: true - }; - } - } - - /** - * Cache results for specific scrapers - */ - async cacheResults( - type: string, - tmdbId: string, - results: CachedScraperResult[], - season?: number, - episode?: number - ): Promise { - try { - const contentKey = this.getContentKey(type, tmdbId, season, episode); - const storageKey = this.getStorageKey(contentKey); - - // Get existing cached data - const existingData = await AsyncStorage.getItem(storageKey); - let cachedContent: CachedContentResult; - - if (existingData) { - cachedContent = JSON.parse(existingData); - - // Update existing results or add new ones - for (const newResult of results) { - const existingIndex = cachedContent.results.findIndex(r => r.scraperId === newResult.scraperId); - if (existingIndex >= 0) { - // Update existing result - cachedContent.results[existingIndex] = newResult; - } else { - // Add new result - cachedContent.results.push(newResult); - } - } - } else { - // Create new cache entry - cachedContent = { - contentKey, - results, - timestamp: Date.now(), - ttl: this.DEFAULT_TTL_MS - }; - } - - // Update timestamp - cachedContent.timestamp = Date.now(); - - // Store updated cache - await AsyncStorage.setItem(storageKey, JSON.stringify(cachedContent)); - - // Clean up old cache entries if we exceed the limit - await this.cleanupOldEntries(); - - logger.log(`[LocalScraperCache] Cached ${results.length} results for ${contentKey}`); - - } catch (error) { - logger.error('[LocalScraperCache] Error caching results:', error); - } - } - - /** - * Cache a single scraper result - */ - async cacheScraperResult( - type: string, - tmdbId: string, - scraperId: string, - scraperName: string, - streams: Stream[] | null, - error: Error | null, - season?: number, - episode?: number - ): Promise { - const result: CachedScraperResult = { - streams: streams || [], - timestamp: Date.now(), - success: !error && streams !== null, - error: error?.message, - scraperId, - scraperName - }; - - await this.cacheResults(type, tmdbId, [result], season, episode); - } - - /** - * Get list of scrapers that need to be re-run (expired, failed, or not cached) - */ - async getScrapersToRerun( - type: string, - tmdbId: string, - availableScrapers: Array<{ id: string; name: string }>, - season?: number, - episode?: number - ): Promise { - const { validResults, expiredScrapers } = await this.getCachedResults(type, tmdbId, season, episode); - - const validScraperIds = new Set(validResults.map(r => r.scraperId)); - const expiredScraperIds = new Set(expiredScrapers); - - // Get scrapers that previously failed (returned no streams) - const failedScraperIds = new Set( - validResults - .filter(r => !r.success || r.streams.length === 0) - .map(r => r.scraperId) - ); - - // Return scrapers that are: - // 1. Not cached at all - // 2. Expired - // 3. Previously failed (regardless of cache status) - const scrapersToRerun = availableScrapers - .filter(scraper => - !validScraperIds.has(scraper.id) || - expiredScraperIds.has(scraper.id) || - failedScraperIds.has(scraper.id) - ) - .map(scraper => scraper.id); - - logger.log(`[LocalScraperCache] Scrapers to re-run: ${scrapersToRerun.join(', ')} (not cached: ${availableScrapers.filter(s => !validScraperIds.has(s.id)).length}, expired: ${expiredScrapers.length}, failed: ${failedScraperIds.size})`); - - return scrapersToRerun; - } - - /** - * Get all valid cached streams for content - */ - async getCachedStreams( - type: string, - tmdbId: string, - season?: number, - episode?: number - ): Promise { - const { validResults } = await this.getCachedResults(type, tmdbId, season, episode); - - // Flatten all valid streams - const allStreams: Stream[] = []; - for (const result of validResults) { - if (result.success && result.streams) { - allStreams.push(...result.streams); - } - } - - return allStreams; - } - - /** - * Invalidate cache for specific content - */ - async invalidateContent( - type: string, - tmdbId: string, - season?: number, - episode?: number - ): Promise { - try { - const contentKey = this.getContentKey(type, tmdbId, season, episode); - const storageKey = this.getStorageKey(contentKey); - - await AsyncStorage.removeItem(storageKey); - logger.log(`[LocalScraperCache] Invalidated cache for ${contentKey}`); - } catch (error) { - logger.error('[LocalScraperCache] Error invalidating cache:', error); - } - } - - /** - * Invalidate cache for specific scraper across all content - */ - async invalidateScraper(scraperId: string): Promise { - try { - const keys = await AsyncStorage.getAllKeys(); - const cacheKeys = keys.filter(key => key.startsWith(this.CACHE_KEY_PREFIX)); - - for (const key of cacheKeys) { - const cachedData = await AsyncStorage.getItem(key); - if (cachedData) { - const parsed: CachedContentResult = JSON.parse(cachedData); - - // Remove results from this scraper - parsed.results = parsed.results.filter(r => r.scraperId !== scraperId); - - if (parsed.results.length === 0) { - // Remove entire cache entry if no results left - await AsyncStorage.removeItem(key); - } else { - // Update cache with remaining results - await AsyncStorage.setItem(key, JSON.stringify(parsed)); - } - } - } - - logger.log(`[LocalScraperCache] Invalidated cache for scraper ${scraperId}`); - } catch (error) { - logger.error('[LocalScraperCache] Error invalidating scraper cache:', error); - } - } - - /** - * Clear all cached results - */ - async clearAllCache(): Promise { - try { - const keys = await AsyncStorage.getAllKeys(); - const cacheKeys = keys.filter(key => key.startsWith(this.CACHE_KEY_PREFIX)); - - await AsyncStorage.multiRemove(cacheKeys); - logger.log(`[LocalScraperCache] Cleared ${cacheKeys.length} cache entries`); - } catch (error) { - logger.error('[LocalScraperCache] Error clearing cache:', error); - } - } - - /** - * Clean up old cache entries to stay within size limit - */ - private async cleanupOldEntries(): Promise { - try { - const keys = await AsyncStorage.getAllKeys(); - const cacheKeys = keys.filter(key => key.startsWith(this.CACHE_KEY_PREFIX)); - - if (cacheKeys.length <= this.MAX_CACHE_SIZE) { - return; // No cleanup needed - } - - // Get all cache entries with their timestamps - const entriesWithTimestamps = await Promise.all( - cacheKeys.map(async (key) => { - const data = await AsyncStorage.getItem(key); - if (data) { - const parsed: CachedContentResult = JSON.parse(data); - return { key, timestamp: parsed.timestamp }; - } - return { key, timestamp: 0 }; - }) - ); - - // Sort by timestamp (oldest first) - entriesWithTimestamps.sort((a, b) => a.timestamp - b.timestamp); - - // Remove oldest entries - const entriesToRemove = entriesWithTimestamps.slice(0, cacheKeys.length - this.MAX_CACHE_SIZE); - const keysToRemove = entriesToRemove.map(entry => entry.key); - - if (keysToRemove.length > 0) { - await AsyncStorage.multiRemove(keysToRemove); - logger.log(`[LocalScraperCache] Cleaned up ${keysToRemove.length} old cache entries`); - } - - } catch (error) { - logger.error('[LocalScraperCache] Error cleaning up cache:', error); - } - } - - /** - * Get cache statistics - */ - async getCacheStats(): Promise<{ - totalEntries: number; - totalSize: number; - oldestEntry: number | null; - newestEntry: number | null; - }> { - try { - const keys = await AsyncStorage.getAllKeys(); - const cacheKeys = keys.filter(key => key.startsWith(this.CACHE_KEY_PREFIX)); - - let totalSize = 0; - let oldestTimestamp: number | null = null; - let newestTimestamp: number | null = null; - - for (const key of cacheKeys) { - const data = await AsyncStorage.getItem(key); - if (data) { - totalSize += data.length; - const parsed: CachedContentResult = JSON.parse(data); - - if (oldestTimestamp === null || parsed.timestamp < oldestTimestamp) { - oldestTimestamp = parsed.timestamp; - } - if (newestTimestamp === null || parsed.timestamp > newestTimestamp) { - newestTimestamp = parsed.timestamp; - } - } - } - - return { - totalEntries: cacheKeys.length, - totalSize, - oldestEntry: oldestTimestamp, - newestEntry: newestTimestamp - }; - } catch (error) { - logger.error('[LocalScraperCache] Error getting cache stats:', error); - return { - totalEntries: 0, - totalSize: 0, - oldestEntry: null, - newestEntry: null - }; - } - } -} - -export const localScraperCacheService = LocalScraperCacheService.getInstance(); -export default localScraperCacheService; diff --git a/src/services/localScraperService.ts b/src/services/localScraperService.ts index e8f1467a..ff7e801f 100644 --- a/src/services/localScraperService.ts +++ b/src/services/localScraperService.ts @@ -4,8 +4,6 @@ import { Platform } from 'react-native'; import { logger } from '../utils/logger'; import { Stream } from '../types/streams'; import { cacheService } from './cacheService'; -import { localScraperCacheService } from './localScraperCacheService'; -import { hybridCacheService } from './hybridCacheService'; import CryptoJS from 'crypto-js'; // Types for local scrapers @@ -862,86 +860,44 @@ class LocalScraperService { } } - // Execute scrapers for streams with caching + // Execute scrapers for streams async getStreams(type: string, tmdbId: string, season?: number, episode?: number, callback?: ScraperCallback): Promise { await this.ensureInitialized(); - + // Get available scrapers from manifest (respects manifestEnabled) const availableScrapers = await this.getAvailableScrapers(); const enabledScrapers = availableScrapers - .filter(scraper => - scraper.enabled && - scraper.manifestEnabled !== false && + .filter(scraper => + scraper.enabled && + scraper.manifestEnabled !== false && scraper.supportedTypes.includes(type as 'movie' | 'tv') ); - + if (enabledScrapers.length === 0) { logger.log('[LocalScraperService] No enabled scrapers found for type:', type); return; } - // Get current user settings for enabled scrapers - const userSettings = await this.getUserScraperSettings(); - - // Check cache for existing results (hybrid: global first, then local) - const { validResults, expiredScrapers, allExpired, source } = await hybridCacheService.getCachedResults(type, tmdbId, season, episode, userSettings); - - // Immediately return cached results for valid scrapers - if (validResults.length > 0) { - logger.log(`[LocalScraperService] Returning ${validResults.length} cached results for ${type}:${tmdbId} (source: ${source})`); - - for (const cachedResult of validResults) { - if (cachedResult.success && cachedResult.streams.length > 0) { - // Streams are already in the correct format, just pass them through - if (callback) { - callback(cachedResult.streams, cachedResult.scraperId, cachedResult.scraperName, null); - } - } else if (callback) { - // Return error for failed cached results - const error = cachedResult.error ? new Error(cachedResult.error) : new Error('Scraper failed'); - callback(null, cachedResult.scraperId, cachedResult.scraperName, error); - } - } - } - - // Determine which scrapers need to be re-run - const scrapersToRerun = enabledScrapers.filter(scraper => { - const hasValidResult = validResults.some(r => r.scraperId === scraper.id); - const isExpired = expiredScrapers.includes(scraper.id); - const hasFailedResult = validResults.some(r => r.scraperId === scraper.id && (!r.success || r.streams.length === 0)); - - return !hasValidResult || isExpired || hasFailedResult; - }); - - if (scrapersToRerun.length === 0) { - logger.log('[LocalScraperService] All scrapers have valid cached results'); - return; - } - - logger.log(`[LocalScraperService] Re-running ${scrapersToRerun.length} scrapers for ${type}:${tmdbId}`, { - totalEnabled: enabledScrapers.length, - expired: expiredScrapers.length, - failed: validResults.filter(r => !r.success || r.streams.length === 0).length, - notCached: enabledScrapers.length - validResults.length, - scrapersToRerun: scrapersToRerun.map(s => s.name) + logger.log(`[LocalScraperService] Executing ${enabledScrapers.length} scrapers for ${type}:${tmdbId}`, { + scrapers: enabledScrapers.map(s => s.name) }); // Generate a lightweight request id for tracing const requestId = `rs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`; - // Execute only scrapers that need to be re-run - for (const scraper of scrapersToRerun) { - this.executeScraperWithCaching(scraper, type, tmdbId, season, episode, callback, requestId); + // Execute all enabled scrapers + for (const scraper of enabledScrapers) { + this.executeScraper(scraper, type, tmdbId, season, episode, callback, requestId); } } - // Execute individual scraper with caching - private async executeScraperWithCaching( - scraper: ScraperInfo, - type: string, - tmdbId: string, - season?: number, - episode?: number, + // Execute individual scraper + private async executeScraper( + scraper: ScraperInfo, + type: string, + tmdbId: string, + season?: number, + episode?: number, callback?: ScraperCallback, requestId?: string ): Promise { @@ -950,10 +906,10 @@ class LocalScraperService { if (!code) { throw new Error(`No code found for scraper ${scraper.id}`); } - + // Load per-scraper settings const scraperSettings = await this.getScraperSettings(scraper.id); - + // Build single-flight key const flightKey = `${scraper.id}|${type}|${tmdbId}|${season ?? ''}|${episode ?? ''}`; @@ -980,60 +936,23 @@ class LocalScraperService { } const results = await promise; - + // Convert results to Nuvio Stream format const streams = this.convertToStreams(results, scraper); - - // Cache the successful result (hybrid: both local and global) - await hybridCacheService.cacheScraperResult( - type, - tmdbId, - scraper.id, - scraper.name, - streams, - null, - season, - episode - ); - + if (callback) { callback(streams, scraper.id, scraper.name, null); } - + } catch (error) { logger.error('[LocalScraperService] Scraper', scraper.name, 'failed:', error); - - // Cache the failed result (hybrid: both local and global) - await hybridCacheService.cacheScraperResult( - type, - tmdbId, - scraper.id, - scraper.name, - null, - error as Error, - season, - episode - ); - + if (callback) { callback(null, scraper.id, scraper.name, error as Error); } } } - // Execute individual scraper (legacy method - kept for compatibility) - private async executeScraper( - scraper: ScraperInfo, - type: string, - tmdbId: string, - season?: number, - episode?: number, - callback?: ScraperCallback, - requestId?: string - ): Promise { - // Delegate to the caching version - return this.executeScraperWithCaching(scraper, type, tmdbId, season, episode, callback, requestId); - } // Execute scraper code in sandboxed environment private async executeSandboxed(code: string, params: any): Promise { @@ -1161,7 +1080,7 @@ class LocalScraperService { ...options.headers }, data: options.body, - timeout: 60000, + timeout: 120000, // Increased to 2 minutes for complex scrapers validateStatus: () => true // Don't throw on HTTP error status codes }; @@ -1201,7 +1120,7 @@ class LocalScraperService { }, // Add axios for HTTP requests axios: axios.create({ - timeout: 30000, + timeout: 120000, // Increased to 2 minutes for complex scrapers headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } @@ -1217,27 +1136,29 @@ class LocalScraperService { SCRAPER_ID: params?.scraperId }; - // Execute the scraper code without timeout + // Execute the scraper code with 1 minute timeout + const SCRAPER_EXECUTION_TIMEOUT_MS = 60000; // 1 minute + const executionPromise = new Promise((resolve, reject) => { try { // Create function from code const func = new Function('sandbox', 'params', 'PRIMARY_KEY', 'TMDB_API_KEY', ` const { console, setTimeout, clearTimeout, Promise, JSON, Date, Math, parseInt, parseFloat, encodeURIComponent, decodeURIComponent, require, axios, fetch, module, exports, global, URL_VALIDATION_ENABLED, SCRAPER_SETTINGS, SCRAPER_ID } = sandbox; - + // Inject MovieBox constants into global scope global.PRIMARY_KEY = PRIMARY_KEY; global.TMDB_API_KEY = TMDB_API_KEY; window.PRIMARY_KEY = PRIMARY_KEY; window.TMDB_API_KEY = TMDB_API_KEY; - + // Expose per-scraper context to plugin globals global.SCRAPER_SETTINGS = SCRAPER_SETTINGS; global.SCRAPER_ID = SCRAPER_ID; window.SCRAPER_SETTINGS = SCRAPER_SETTINGS; window.SCRAPER_ID = SCRAPER_ID; - + ${code} - + // Call the main function (assuming it's exported) if (typeof getStreams === 'function') { return getStreams(params.tmdbId, params.mediaType, params.season, params.episode); @@ -1249,9 +1170,9 @@ class LocalScraperService { throw new Error('No getStreams function found in scraper'); } `); - + const result = func(sandbox, params, MOVIEBOX_PRIMARY_KEY, MOVIEBOX_TMDB_API_KEY); - + // Handle both sync and async results if (result && typeof result.then === 'function') { result.then(resolve).catch(reject); @@ -1262,8 +1183,14 @@ class LocalScraperService { reject(error); } }); - - return await executionPromise; + + // Apply 1-minute timeout to prevent hanging scrapers + return await Promise.race([ + executionPromise, + new Promise((_, reject) => + setTimeout(() => reject(new Error(`Scraper execution timed out after ${SCRAPER_EXECUTION_TIMEOUT_MS}ms`)), SCRAPER_EXECUTION_TIMEOUT_MS) + ) + ]); } catch (error) { logger.error('[LocalScraperService] Sandbox execution failed:', error); @@ -1365,6 +1292,19 @@ class LocalScraperService { // Check if local scrapers are available async hasScrapers(): Promise { await this.ensureInitialized(); + + // Get user settings to check if local scrapers are enabled + const userSettings = await this.getUserScraperSettings(); + if (!userSettings.enableLocalScrapers) { + return false; + } + + // Check if there are any enabled scrapers based on user settings + if (userSettings.enabledScrapers && userSettings.enabledScrapers.size > 0) { + return true; + } + + // Fallback: check if any scrapers are enabled in the internal state return Array.from(this.installedScrapers.values()).some(scraper => scraper.enabled); } @@ -1384,8 +1324,11 @@ class LocalScraperService { }; } - // Get user settings from AsyncStorage - const settingsData = await AsyncStorage.getItem('app_settings'); + // Get user settings from AsyncStorage (scoped with fallback) + const scope = (await AsyncStorage.getItem('@user:current')) || 'local'; + const scopedSettingsJson = await AsyncStorage.getItem(`@user:${scope}:app_settings`); + const legacySettingsJson = await AsyncStorage.getItem('app_settings'); + const settingsData = scopedSettingsJson || legacySettingsJson; const settings = settingsData ? JSON.parse(settingsData) : {}; // Get enabled scrapers based on current user settings @@ -1408,32 +1351,6 @@ class LocalScraperService { } } - // Cache management methods (hybrid: local + global) - async clearScraperCache(): Promise { - await hybridCacheService.clearAllCache(); - logger.log('[LocalScraperService] Cleared all scraper cache (local + global)'); - } - - async invalidateScraperCache(scraperId: string): Promise { - await hybridCacheService.invalidateScraper(scraperId); - logger.log('[LocalScraperService] Invalidated cache for scraper:', scraperId); - } - - async invalidateContentCache(type: string, tmdbId: string, season?: number, episode?: number): Promise { - await hybridCacheService.invalidateContent(type, tmdbId, season, episode); - logger.log('[LocalScraperService] Invalidated cache for content:', `${type}:${tmdbId}`); - } - - async getCacheStats(): Promise<{ - local: { - totalEntries: number; - totalSize: number; - oldestEntry: number | null; - newestEntry: number | null; - }; - }> { - return await hybridCacheService.getCacheStats(); - } } export const localScraperService = LocalScraperService.getInstance(); diff --git a/src/services/stremioService.ts b/src/services/stremioService.ts index 49593b08..c1a39478 100644 --- a/src/services/stremioService.ts +++ b/src/services/stremioService.ts @@ -1235,13 +1235,16 @@ class StremioService { // Execute local scrapers asynchronously with TMDB ID (when available) if (tmdbId) { localScraperService.getStreams(scraperType, tmdbId, season, episode, (streams, scraperId, scraperName, error) => { - if (error) { - if (callback) { + // Always call callback to ensure UI updates, regardless of result + if (callback) { + if (error) { callback(null, scraperId, scraperName, error); - } - } else if (streams && streams.length > 0) { - if (callback) { + } else if (streams && streams.length > 0) { callback(streams, scraperId, scraperName, null); + } else { + // Handle case where scraper completed successfully but returned no streams + // This ensures the scraper is removed from "fetching" state in UI + callback([], scraperId, scraperName, null); } } }); diff --git a/src/services/trailerService.ts b/src/services/trailerService.ts index c72aaecb..fa4c7366 100644 --- a/src/services/trailerService.ts +++ b/src/services/trailerService.ts @@ -7,10 +7,16 @@ export interface TrailerData { } export class TrailerService { - private static readonly XPRIME_URL = 'https://db.xprime.tv/trailers'; - private static readonly LOCAL_SERVER_URL = 'http://192.168.1.11:3001/trailer'; - private static readonly AUTO_SEARCH_URL = 'http://192.168.1.11:3001/search-trailer'; - private static readonly TIMEOUT = 10000; // 10 seconds + // Environment-configurable values (Expo public env) + private static readonly ENV_LOCAL_BASE = process.env.EXPO_PUBLIC_TRAILER_LOCAL_BASE || 'http://46.62.173.157:3001'; + private static readonly ENV_LOCAL_TRAILER_PATH = process.env.EXPO_PUBLIC_TRAILER_LOCAL_TRAILER_PATH || '/trailer'; + private static readonly ENV_LOCAL_SEARCH_PATH = process.env.EXPO_PUBLIC_TRAILER_LOCAL_SEARCH_PATH || '/search-trailer'; + private static readonly ENV_XPRIME_URL = process.env.EXPO_PUBLIC_XPRIME_URL || 'https://db.xprime.tv/trailers'; + + private static readonly XPRIME_URL = TrailerService.ENV_XPRIME_URL; + private static readonly LOCAL_SERVER_URL = `${TrailerService.ENV_LOCAL_BASE}${TrailerService.ENV_LOCAL_TRAILER_PATH}`; + private static readonly AUTO_SEARCH_URL = `${TrailerService.ENV_LOCAL_BASE}${TrailerService.ENV_LOCAL_SEARCH_PATH}`; + private static readonly TIMEOUT = 20000; // 20 seconds private static readonly USE_LOCAL_SERVER = true; // Toggle between local and XPrime /** @@ -22,10 +28,12 @@ export class TrailerService { * @returns Promise - The trailer URL or null if not found */ static async getTrailerUrl(title: string, year: number, tmdbId?: string, type?: 'movie' | 'tv'): Promise { + logger.info('TrailerService', `getTrailerUrl requested: title="${title}", year=${year}, tmdbId=${tmdbId || 'n/a'}, type=${type || 'n/a'}, useLocal=${this.USE_LOCAL_SERVER}`); if (this.USE_LOCAL_SERVER) { // Try local server first, fallback to XPrime if it fails const localResult = await this.getTrailerFromLocalServer(title, year, tmdbId, type); if (localResult) { + logger.info('TrailerService', 'Returning trailer URL from local server'); return localResult; } @@ -46,6 +54,7 @@ export class TrailerService { */ private static async getTrailerFromLocalServer(title: string, year: number, tmdbId?: string, type?: 'movie' | 'tv'): Promise { try { + const startTime = Date.now(); const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.TIMEOUT); @@ -65,6 +74,8 @@ export class TrailerService { } const url = `${this.AUTO_SEARCH_URL}?${params.toString()}`; + logger.info('TrailerService', `Local server request URL: ${url}`); + logger.info('TrailerService', `Local server timeout set to ${this.TIMEOUT}ms`); const response = await fetch(url, { method: 'GET', @@ -77,25 +88,55 @@ export class TrailerService { clearTimeout(timeoutId); + const elapsed = Date.now() - startTime; + const contentType = response.headers.get('content-type') || 'unknown'; + logger.info('TrailerService', `Local server response: status=${response.status} ok=${response.ok} content-type=${contentType} elapsedMs=${elapsed}`); + + // Read body as text first so we can log it even on non-200s + let rawText = ''; + try { + rawText = await response.text(); + if (rawText) { + const preview = rawText.length > 200 ? `${rawText.slice(0, 200)}...` : rawText; + logger.info('TrailerService', `Local server body preview: ${preview}`); + } else { + logger.info('TrailerService', 'Local server body is empty'); + } + } catch (e) { + const msg = e instanceof Error ? `${e.name}: ${e.message}` : String(e); + logger.warn('TrailerService', `Failed reading local server body text: ${msg}`); + } + if (!response.ok) { logger.warn('TrailerService', `Auto-search failed: ${response.status} ${response.statusText}`); return null; } - const data = await response.json(); + // Attempt to parse JSON from the raw text + let data: any = null; + try { + data = rawText ? JSON.parse(rawText) : null; + const keys = typeof data === 'object' && data !== null ? Object.keys(data).join(',') : typeof data; + logger.info('TrailerService', `Local server JSON parsed. Keys/Type: ${keys}`); + } catch (e) { + const msg = e instanceof Error ? `${e.name}: ${e.message}` : String(e); + logger.warn('TrailerService', `Failed to parse local server JSON: ${msg}`); + return null; + } if (!data.url || !this.isValidTrailerUrl(data.url)) { logger.warn('TrailerService', `Invalid trailer URL from auto-search: ${data.url}`); return null; } - logger.info('TrailerService', `Successfully found trailer: ${data.url.substring(0, 50)}...`); + logger.info('TrailerService', `Successfully found trailer: ${String(data.url).substring(0, 80)}...`); return data.url; } catch (error) { if (error instanceof Error && error.name === 'AbortError') { - logger.warn('TrailerService', 'Auto-search request timed out'); + logger.warn('TrailerService', `Auto-search request timed out after ${this.TIMEOUT}ms`); } else { - logger.error('TrailerService', 'Error in auto-search:', error); + const msg = error instanceof Error ? `${error.name}: ${error.message}` : String(error); + logger.error('TrailerService', `Error in auto-search: ${msg}`); } return null; // Return null to trigger XPrime fallback } @@ -115,6 +156,8 @@ export class TrailerService { const url = `${this.XPRIME_URL}?title=${encodeURIComponent(title)}&year=${year}`; logger.info('TrailerService', `Fetching trailer from XPrime for: ${title} (${year})`); + logger.info('TrailerService', `XPrime request URL: ${url}`); + logger.info('TrailerService', `XPrime timeout set to ${this.TIMEOUT}ms`); const response = await fetch(url, { method: 'GET', @@ -127,12 +170,14 @@ export class TrailerService { clearTimeout(timeoutId); + logger.info('TrailerService', `XPrime response: status=${response.status} ok=${response.ok}`); if (!response.ok) { logger.warn('TrailerService', `XPrime failed: ${response.status} ${response.statusText}`); return null; } const trailerUrl = await response.text(); + logger.info('TrailerService', `XPrime raw URL length: ${trailerUrl ? trailerUrl.length : 0}`); if (!trailerUrl || !this.isValidTrailerUrl(trailerUrl.trim())) { logger.warn('TrailerService', `Invalid trailer URL from XPrime: ${trailerUrl}`); @@ -145,9 +190,10 @@ export class TrailerService { return cleanUrl; } catch (error) { if (error instanceof Error && error.name === 'AbortError') { - logger.warn('TrailerService', 'XPrime request timed out'); + logger.warn('TrailerService', `XPrime request timed out after ${this.TIMEOUT}ms`); } else { - logger.error('TrailerService', 'Error fetching from XPrime:', error); + const msg = error instanceof Error ? `${error.name}: ${error.message}` : String(error); + logger.error('TrailerService', `Error fetching from XPrime: ${msg}`); } return null; } @@ -218,16 +264,21 @@ export class TrailerService { if (url.includes('M3U')) { // Try to get M3U without encryption first, then with encryption const baseUrl = url.split('?')[0]; - return `${baseUrl}?formats=M3U+none,M3U+appleHlsEncryption`; + const best = `${baseUrl}?formats=M3U+none,M3U+appleHlsEncryption`; + logger.info('TrailerService', `Optimized format URL from M3U: ${best.substring(0, 80)}...`); + return best; } // Fallback to MP4 if available if (url.includes('MPEG4')) { const baseUrl = url.split('?')[0]; - return `${baseUrl}?formats=MPEG4`; + const best = `${baseUrl}?formats=MPEG4`; + logger.info('TrailerService', `Optimized format URL from MPEG4: ${best.substring(0, 80)}...`); + return best; } } // Return the original URL if no format optimization is needed + logger.info('TrailerService', 'No format optimization applied'); return url; } @@ -238,7 +289,9 @@ export class TrailerService { * @returns Promise - True if trailer is available */ static async isTrailerAvailable(title: string, year: number): Promise { + logger.info('TrailerService', `Checking trailer availability for: ${title} (${year})`); const trailerUrl = await this.getTrailerUrl(title, year); + logger.info('TrailerService', `Trailer availability for ${title} (${year}): ${trailerUrl ? 'available' : 'not available'}`); return trailerUrl !== null; } @@ -249,9 +302,11 @@ export class TrailerService { * @returns Promise - Trailer data or null if not found */ static async getTrailerData(title: string, year: number): Promise { + logger.info('TrailerService', `getTrailerData for: ${title} (${year})`); const url = await this.getTrailerUrl(title, year); if (!url) { + logger.info('TrailerService', 'No trailer URL found for getTrailerData'); return null; } @@ -262,6 +317,65 @@ export class TrailerService { }; } + /** + * Fetches trailer directly from a known YouTube URL + * @param youtubeUrl - The YouTube URL to process + * @param title - Optional title for logging/caching + * @param year - Optional year for logging/caching + * @returns Promise - The direct streaming URL or null if failed + */ + static async getTrailerFromYouTubeUrl(youtubeUrl: string, title?: string, year?: string): Promise { + try { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), this.TIMEOUT); + + const params = new URLSearchParams(); + params.append('youtube_url', youtubeUrl); + if (title) params.append('title', title); + if (year) params.append('year', year.toString()); + + const url = `${this.ENV_LOCAL_BASE}${this.ENV_LOCAL_TRAILER_PATH}?${params.toString()}`; + logger.info('TrailerService', `Fetching trailer directly from YouTube URL: ${youtubeUrl}`); + logger.info('TrailerService', `Direct trailer request URL: ${url}`); + + const response = await fetch(url, { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'User-Agent': 'Nuvio/1.0', + }, + signal: controller.signal, + }); + + clearTimeout(timeoutId); + + logger.info('TrailerService', `Direct trailer response: status=${response.status} ok=${response.ok}`); + + if (!response.ok) { + logger.warn('TrailerService', `Direct trailer failed: ${response.status} ${response.statusText}`); + return null; + } + + const data = await response.json(); + + if (!data.url || !this.isValidTrailerUrl(data.url)) { + logger.warn('TrailerService', `Invalid trailer URL from direct fetch: ${data.url}`); + return null; + } + + logger.info('TrailerService', `Successfully got direct trailer: ${String(data.url).substring(0, 80)}...`); + return data.url; + } catch (error) { + if (error instanceof Error && error.name === 'AbortError') { + logger.warn('TrailerService', `Direct trailer request timed out after ${this.TIMEOUT}ms`); + } else { + const msg = error instanceof Error ? `${error.name}: ${error.message}` : String(error); + logger.error('TrailerService', `Error in direct trailer fetch: ${msg}`); + } + return null; + } + } + /** * Switch between local server and XPrime API * @param useLocal - true for local server, false for XPrime @@ -292,6 +406,7 @@ export class TrailerService { localServer: { status: 'online' | 'offline'; responseTime?: number }; xprimeServer: { status: 'online' | 'offline'; responseTime?: number }; }> { + logger.info('TrailerService', 'Testing servers (local and XPrime)'); const results: { localServer: { status: 'online' | 'offline'; responseTime?: number }; xprimeServer: { status: 'online' | 'offline'; responseTime?: number }; @@ -312,9 +427,11 @@ export class TrailerService { status: 'online', responseTime: Date.now() - startTime }; + logger.info('TrailerService', `Local server online. Response time: ${results.localServer.responseTime}ms`); } } catch (error) { - logger.warn('TrailerService', 'Local server test failed:', error); + const msg = error instanceof Error ? `${error.name}: ${error.message}` : String(error); + logger.warn('TrailerService', `Local server test failed: ${msg}`); } // Test XPrime server @@ -329,11 +446,14 @@ export class TrailerService { status: 'online', responseTime: Date.now() - startTime }; + logger.info('TrailerService', `XPrime server online. Response time: ${results.xprimeServer.responseTime}ms`); } } catch (error) { - logger.warn('TrailerService', 'XPrime server test failed:', error); + const msg = error instanceof Error ? `${error.name}: ${error.message}` : String(error); + logger.warn('TrailerService', `XPrime server test failed: ${msg}`); } + logger.info('TrailerService', `Server test results -> local: ${results.localServer.status}, xprime: ${results.xprimeServer.status}`); return results; } } diff --git a/src/types/metadata.ts b/src/types/metadata.ts index de2338a3..be8bc396 100644 --- a/src/types/metadata.ts +++ b/src/types/metadata.ts @@ -1,6 +1,9 @@ import { TMDBEpisode } from '../services/tmdbService'; import { StreamingContent } from '../services/catalogService'; +// Re-export StreamingContent for convenience +export { StreamingContent }; + // Types for route params export type RouteParams = { id: string;