From 03434d2f245587b4f8e2df36ce4c30c15afd3bdd Mon Sep 17 00:00:00 2001 From: Oliver Lazoroski Date: Mon, 20 Oct 2025 13:39:14 +0200 Subject: [PATCH 01/22] feat(react-native): RTMP publishing --- .../package.json | 2 +- .../react-native-broadcast/.watchmanconfig | 1 + packages/react-native-broadcast/README.md | 33 + .../StreamReactNativeBroadcast.podspec | 26 + .../android/build.gradle | 77 +++ .../android/gradle.properties | 5 + .../android/src/main/AndroidManifest.xml | 2 + .../java/com/broadcast/BroadcastModule.kt | 23 + .../java/com/broadcast/BroadcastPackage.kt | 33 + .../react-native-broadcast/babel.config.js | 12 + .../react-native-broadcast/ios/Broadcast.h | 5 + .../react-native-broadcast/ios/Broadcast.mm | 22 + .../ios/Broadcast.swift | 10 + packages/react-native-broadcast/package.json | 92 +++ .../src/NativeBroadcast.ts | 7 + .../src/__tests__/index.test.tsx | 1 + packages/react-native-broadcast/src/index.tsx | 5 + packages/react-native-broadcast/tsconfig.json | 30 + .../video-filters-react-native/package.json | 2 +- sample-apps/react-native/dogfood/App.tsx | 5 + .../react-native/dogfood/ios/Podfile.lock | 48 +- .../project.pbxproj | 4 +- .../xcshareddata/swiftpm/Package.resolved | 24 + .../react-native/dogfood/metro.config.js | 1 + sample-apps/react-native/dogfood/package.json | 1 + yarn.lock | 565 ++++-------------- 26 files changed, 583 insertions(+), 453 deletions(-) create mode 100644 packages/react-native-broadcast/.watchmanconfig create mode 100644 packages/react-native-broadcast/README.md create mode 100644 packages/react-native-broadcast/StreamReactNativeBroadcast.podspec create mode 100644 packages/react-native-broadcast/android/build.gradle create mode 100644 packages/react-native-broadcast/android/gradle.properties create mode 100644 packages/react-native-broadcast/android/src/main/AndroidManifest.xml create mode 100644 packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastModule.kt create mode 100644 packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastPackage.kt create mode 100644 packages/react-native-broadcast/babel.config.js create mode 100644 packages/react-native-broadcast/ios/Broadcast.h create mode 100644 packages/react-native-broadcast/ios/Broadcast.mm create mode 100644 packages/react-native-broadcast/ios/Broadcast.swift create mode 100644 packages/react-native-broadcast/package.json create mode 100644 packages/react-native-broadcast/src/NativeBroadcast.ts create mode 100644 packages/react-native-broadcast/src/__tests__/index.test.tsx create mode 100644 packages/react-native-broadcast/src/index.tsx create mode 100644 packages/react-native-broadcast/tsconfig.json create mode 100644 sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/packages/noise-cancellation-react-native/package.json b/packages/noise-cancellation-react-native/package.json index aaf8706bc1..6a32382765 100644 --- a/packages/noise-cancellation-react-native/package.json +++ b/packages/noise-cancellation-react-native/package.json @@ -50,7 +50,7 @@ "@stream-io/react-native-webrtc": "125.4.4", "react": "19.1.0", "react-native": "^0.81.4", - "react-native-builder-bob": "^0.37.0", + "react-native-builder-bob": "^0.40.13", "rimraf": "^6.0.1", "typescript": "^5.9.3" }, diff --git a/packages/react-native-broadcast/.watchmanconfig b/packages/react-native-broadcast/.watchmanconfig new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/react-native-broadcast/.watchmanconfig @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/react-native-broadcast/README.md b/packages/react-native-broadcast/README.md new file mode 100644 index 0000000000..12239b2baa --- /dev/null +++ b/packages/react-native-broadcast/README.md @@ -0,0 +1,33 @@ +# react-native-broadcast + +a + +## Installation + +```sh +npm install react-native-broadcast +``` + +## Usage + +```js +import { multiply } from 'react-native-broadcast'; + +// ... + +const result = multiply(3, 7); +``` + +## Contributing + +- [Development workflow](CONTRIBUTING.md#development-workflow) +- [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request) +- [Code of conduct](CODE_OF_CONDUCT.md) + +## License + +MIT + +--- + +Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob) diff --git a/packages/react-native-broadcast/StreamReactNativeBroadcast.podspec b/packages/react-native-broadcast/StreamReactNativeBroadcast.podspec new file mode 100644 index 0000000000..14a7d0a470 --- /dev/null +++ b/packages/react-native-broadcast/StreamReactNativeBroadcast.podspec @@ -0,0 +1,26 @@ +require "json" + +package = JSON.parse(File.read(File.join(__dir__, "package.json"))) + +Pod::Spec.new do |s| + s.name = "StreamReactNativeBroadcast" + s.version = package["version"] + s.summary = package["description"] + s.homepage = package["homepage"] + s.license = package["license"] + s.authors = package["author"] + + s.platforms = { :ios => min_ios_version_supported } + s.source = { :git => "https://github.com/GetStream/stream-video-js.git", :tag => "#{s.version}" } + + s.source_files = "ios/**/*.{h,m,mm,cpp,swift}" + s.private_header_files = "ios/**/*.h" + + install_modules_dependencies(s) + + spm_dependency(s, + url: 'https://github.com/HaishinKit/HaishinKit.swift', + requirement: { kind: 'upToNextMajorVersion', minimumVersion: '2.2.0' }, + products: ['RTMPHaishinKit'] + ) +end diff --git a/packages/react-native-broadcast/android/build.gradle b/packages/react-native-broadcast/android/build.gradle new file mode 100644 index 0000000000..0884bc0252 --- /dev/null +++ b/packages/react-native-broadcast/android/build.gradle @@ -0,0 +1,77 @@ +buildscript { + ext.getExtOrDefault = {name -> + return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['Broadcast_' + name] + } + + repositories { + google() + mavenCentral() + } + + dependencies { + classpath "com.android.tools.build:gradle:8.7.2" + // noinspection DifferentKotlinGradleVersion + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}" + } +} + + +apply plugin: "com.android.library" +apply plugin: "kotlin-android" + +apply plugin: "com.facebook.react" + +def getExtOrIntegerDefault(name) { + return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["Broadcast_" + name]).toInteger() +} + +android { + namespace "com.broadcast" + + compileSdkVersion getExtOrIntegerDefault("compileSdkVersion") + + defaultConfig { + minSdkVersion getExtOrIntegerDefault("minSdkVersion") + targetSdkVersion getExtOrIntegerDefault("targetSdkVersion") + } + + buildFeatures { + buildConfig true + } + + buildTypes { + release { + minifyEnabled false + } + } + + lintOptions { + disable "GradleCompatible" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + sourceSets { + main { + java.srcDirs += [ + "generated/java", + "generated/jni" + ] + } + } +} + +repositories { + mavenCentral() + google() +} + +def kotlin_version = getExtOrDefault("kotlinVersion") + +dependencies { + implementation "com.facebook.react:react-android" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" +} diff --git a/packages/react-native-broadcast/android/gradle.properties b/packages/react-native-broadcast/android/gradle.properties new file mode 100644 index 0000000000..0e3d333563 --- /dev/null +++ b/packages/react-native-broadcast/android/gradle.properties @@ -0,0 +1,5 @@ +Broadcast_kotlinVersion=2.0.21 +Broadcast_minSdkVersion=24 +Broadcast_targetSdkVersion=34 +Broadcast_compileSdkVersion=35 +Broadcast_ndkVersion=27.1.12297006 diff --git a/packages/react-native-broadcast/android/src/main/AndroidManifest.xml b/packages/react-native-broadcast/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..bdae66c8f5 --- /dev/null +++ b/packages/react-native-broadcast/android/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastModule.kt b/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastModule.kt new file mode 100644 index 0000000000..610af7742c --- /dev/null +++ b/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastModule.kt @@ -0,0 +1,23 @@ +package com.broadcast + +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.module.annotations.ReactModule + +@ReactModule(name = BroadcastModule.NAME) +class BroadcastModule(reactContext: ReactApplicationContext) : + NativeBroadcastSpec(reactContext) { + + override fun getName(): String { + return NAME + } + + // Example method + // See https://reactnative.dev/docs/native-modules-android + override fun multiply(a: Double, b: Double): Double { + return a * b + } + + companion object { + const val NAME = "Broadcast" + } +} diff --git a/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastPackage.kt b/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastPackage.kt new file mode 100644 index 0000000000..c8ef319ce4 --- /dev/null +++ b/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastPackage.kt @@ -0,0 +1,33 @@ +package com.broadcast + +import com.facebook.react.BaseReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.module.model.ReactModuleInfo +import com.facebook.react.module.model.ReactModuleInfoProvider +import java.util.HashMap + +class BroadcastPackage : BaseReactPackage() { + override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { + return if (name == BroadcastModule.NAME) { + BroadcastModule(reactContext) + } else { + null + } + } + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { + return ReactModuleInfoProvider { + val moduleInfos: MutableMap = HashMap() + moduleInfos[BroadcastModule.NAME] = ReactModuleInfo( + BroadcastModule.NAME, + BroadcastModule.NAME, + false, // canOverrideExistingModule + false, // needsEagerInit + false, // isCxxModule + true // isTurboModule + ) + moduleInfos + } + } +} diff --git a/packages/react-native-broadcast/babel.config.js b/packages/react-native-broadcast/babel.config.js new file mode 100644 index 0000000000..0c05fd6963 --- /dev/null +++ b/packages/react-native-broadcast/babel.config.js @@ -0,0 +1,12 @@ +module.exports = { + overrides: [ + { + exclude: /\/node_modules\//, + presets: ['module:react-native-builder-bob/babel-preset'], + }, + { + include: /\/node_modules\//, + presets: ['module:@react-native/babel-preset'], + }, + ], +}; diff --git a/packages/react-native-broadcast/ios/Broadcast.h b/packages/react-native-broadcast/ios/Broadcast.h new file mode 100644 index 0000000000..ab7295b2ab --- /dev/null +++ b/packages/react-native-broadcast/ios/Broadcast.h @@ -0,0 +1,5 @@ +#import + +@interface Broadcast : NSObject + +@end diff --git a/packages/react-native-broadcast/ios/Broadcast.mm b/packages/react-native-broadcast/ios/Broadcast.mm new file mode 100644 index 0000000000..46a277051f --- /dev/null +++ b/packages/react-native-broadcast/ios/Broadcast.mm @@ -0,0 +1,22 @@ +#import "Broadcast.h" +#import + +@implementation Broadcast + +- (NSNumber *)multiply:(double)a b:(double)b +{ + return [BroadcastSwift multiply:a b:b]; +} + +- (std::shared_ptr)getTurboModule: + (const facebook::react::ObjCTurboModule::InitParams &)params +{ + return std::make_shared(params); +} + ++ (NSString *)moduleName +{ + return @"Broadcast"; +} + +@end diff --git a/packages/react-native-broadcast/ios/Broadcast.swift b/packages/react-native-broadcast/ios/Broadcast.swift new file mode 100644 index 0000000000..8c4499c926 --- /dev/null +++ b/packages/react-native-broadcast/ios/Broadcast.swift @@ -0,0 +1,10 @@ +import Foundation + +@objc +public class BroadcastSwift: NSObject { + + @objc + public static func multiply(_ a: Double, b: Double) -> NSNumber { + return NSNumber(value: a * b) + } +} diff --git a/packages/react-native-broadcast/package.json b/packages/react-native-broadcast/package.json new file mode 100644 index 0000000000..d21e24944e --- /dev/null +++ b/packages/react-native-broadcast/package.json @@ -0,0 +1,92 @@ +{ + "name": "@stream-io/video-react-native-broadcast", + "version": "0.1.0", + "description": "a", + "main": "./dist/module/index.js", + "types": "./dist/typescript/src/index.d.ts", + "exports": { + ".": { + "source": "./src/index.tsx", + "types": "./dist/typescript/src/index.d.ts", + "default": "./dist/module/index.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "src", + "lib", + "android", + "ios", + "cpp", + "*.podspec", + "react-native.config.js", + "!ios/build", + "!android/build", + "!android/gradle", + "!android/gradlew", + "!android/gradlew.bat", + "!android/local.properties", + "!**/__tests__", + "!**/__fixtures__", + "!**/__mocks__", + "!**/.*" + ], + "scripts": { + "prepare": "bob build", + "build": "bob build" + }, + "keywords": [ + "react-native", + "ios", + "android" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/GetStream/stream-video-js.git" + }, + "author": "GetStream (https://github.com/GetStream)", + "license": "MIT", + "bugs": { + "url": "https://github.com/GetStream/stream-video-js/issues" + }, + "homepage": "https://github.com/GetStream/stream-video-js", + "devDependencies": { + "@react-native-community/cli": "20.0.0", + "@react-native/babel-preset": "^0.81.4", + "@types/react": "~19.1.17", + "react": "19.1.0", + "react-native": "^0.81.4", + "react-native-builder-bob": "^0.40.13", + "typescript": "^5.9.3" + }, + "peerDependencies": { + "react": "*", + "react-native": ">=0.79.0" + }, + "react-native-builder-bob": { + "source": "src", + "output": "dist", + "targets": [ + [ + "module", + { + "esm": true + } + ], + [ + "typescript", + { + "project": "tsconfig.json" + } + ] + ] + }, + "codegenConfig": { + "name": "BroadcastSpec", + "type": "modules", + "jsSrcsDir": "src", + "android": { + "javaPackageName": "io.getstream.rn.broadcast" + } + } +} diff --git a/packages/react-native-broadcast/src/NativeBroadcast.ts b/packages/react-native-broadcast/src/NativeBroadcast.ts new file mode 100644 index 0000000000..5ec7119c48 --- /dev/null +++ b/packages/react-native-broadcast/src/NativeBroadcast.ts @@ -0,0 +1,7 @@ +import { type TurboModule, TurboModuleRegistry } from 'react-native'; + +export interface Spec extends TurboModule { + multiply(a: number, b: number): number; +} + +export default TurboModuleRegistry.getEnforcing('Broadcast'); diff --git a/packages/react-native-broadcast/src/__tests__/index.test.tsx b/packages/react-native-broadcast/src/__tests__/index.test.tsx new file mode 100644 index 0000000000..bf84291a5e --- /dev/null +++ b/packages/react-native-broadcast/src/__tests__/index.test.tsx @@ -0,0 +1 @@ +it.todo('write a test'); diff --git a/packages/react-native-broadcast/src/index.tsx b/packages/react-native-broadcast/src/index.tsx new file mode 100644 index 0000000000..ff575c05a0 --- /dev/null +++ b/packages/react-native-broadcast/src/index.tsx @@ -0,0 +1,5 @@ +import Broadcast from './NativeBroadcast'; + +export function multiply(a: number, b: number): number { + return Broadcast.multiply(a, b); +} diff --git a/packages/react-native-broadcast/tsconfig.json b/packages/react-native-broadcast/tsconfig.json new file mode 100644 index 0000000000..4618786b46 --- /dev/null +++ b/packages/react-native-broadcast/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "rootDir": ".", + "paths": { + "react-native-broadcast": ["./src/index"] + }, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "customConditions": ["react-native-strict-api"], + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noImplicitUseStrict": false, + "noStrictGenericChecks": false, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "ESNext", + "verbatimModuleSyntax": true + } +} diff --git a/packages/video-filters-react-native/package.json b/packages/video-filters-react-native/package.json index b1011ecbaa..ef711375fb 100644 --- a/packages/video-filters-react-native/package.json +++ b/packages/video-filters-react-native/package.json @@ -50,7 +50,7 @@ "@stream-io/react-native-webrtc": "125.4.4", "react": "19.1.0", "react-native": "^0.81.4", - "react-native-builder-bob": "^0.37.0", + "react-native-builder-bob": "^0.40.13", "rimraf": "^6.0.1", "typescript": "^5.9.3" }, diff --git a/sample-apps/react-native/dogfood/App.tsx b/sample-apps/react-native/dogfood/App.tsx index 3d0d46c9ab..836e249e64 100755 --- a/sample-apps/react-native/dogfood/App.tsx +++ b/sample-apps/react-native/dogfood/App.tsx @@ -44,6 +44,7 @@ import { } from '@stream-io/video-react-native-sdk'; import Toast from 'react-native-toast-message'; import { appTheme } from './src/theme'; +import { multiply } from '@stream-io/video-react-native-broadcast'; // only enable warning and error logs from webrtc library Logger.enable(`${Logger.ROOT_PREFIX}:(WARN|ERROR)`); @@ -86,6 +87,10 @@ const StackNavigator = () => { }; }, []); + useEffect(() => { + console.log('OL: multiply', multiply(3, 7)); + }, []); + let mode; switch (appMode) { case 'Meeting': diff --git a/sample-apps/react-native/dogfood/ios/Podfile.lock b/sample-apps/react-native/dogfood/ios/Podfile.lock index ccb94872ad..42b47fe0d9 100644 --- a/sample-apps/react-native/dogfood/ios/Podfile.lock +++ b/sample-apps/react-native/dogfood/ios/Podfile.lock @@ -2937,7 +2937,7 @@ PODS: - SocketRocket - Yoga - SocketRocket (0.7.1) - - stream-chat-react-native (8.5.2): + - stream-chat-react-native (8.6.0): - boost - DoubleConversion - fast_float @@ -2966,7 +2966,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - stream-io-noise-cancellation-react-native (0.3.0): + - stream-io-noise-cancellation-react-native (0.4.0): - boost - DoubleConversion - fast_float @@ -2996,7 +2996,7 @@ PODS: - stream-react-native-webrtc - StreamVideoNoiseCancellation - Yoga - - stream-io-video-filters-react-native (0.7.0): + - stream-io-video-filters-react-native (0.8.0): - boost - DoubleConversion - fast_float @@ -3028,7 +3028,7 @@ PODS: - stream-react-native-webrtc (125.4.4): - React-Core - StreamWebRTC (~> 125.6422.070) - - stream-video-react-native (1.21.2): + - stream-video-react-native (1.22.1): - boost - DoubleConversion - fast_float @@ -3057,6 +3057,34 @@ PODS: - SocketRocket - stream-react-native-webrtc - Yoga + - StreamReactNativeBroadcast (0.1.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - StreamVideoNoiseCancellation (1.0.3) - StreamWebRTC (125.6422.070) - VisionCamera (4.7.2): @@ -3164,6 +3192,7 @@ DEPENDENCIES: - "stream-io-video-filters-react-native (from `../node_modules/@stream-io/video-filters-react-native`)" - "stream-react-native-webrtc (from `../node_modules/@stream-io/react-native-webrtc`)" - "stream-video-react-native (from `../node_modules/@stream-io/video-react-native-sdk`)" + - "StreamReactNativeBroadcast (from `../node_modules/@stream-io/video-react-native-broadcast`)" - VisionCamera (from `../node_modules/react-native-vision-camera`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) @@ -3364,6 +3393,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@stream-io/react-native-webrtc" stream-video-react-native: :path: "../node_modules/@stream-io/video-react-native-sdk" + StreamReactNativeBroadcast: + :path: "../node_modules/@stream-io/video-react-native-broadcast" VisionCamera: :path: "../node_modules/react-native-vision-camera" Yoga: @@ -3461,11 +3492,12 @@ SPEC CHECKSUMS: RNVoipPushNotification: 4998fe6724d421da616dca765da7dc421ff54c4e RNWorklets: ad0606bee2a8103c14adb412149789c60b72bfb2 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - stream-chat-react-native: d30002093f5d1be72c6a7d89bc98df03f43502d0 - stream-io-noise-cancellation-react-native: c200e3f29c32bd274e3fcf5a29fd4b9e7c63f9ed - stream-io-video-filters-react-native: 3ec369fd17ee59c0628aabe5e0b2bebb28d93b3b + stream-chat-react-native: c88c3a1087393358e660885479e21be1f2c286a3 + stream-io-noise-cancellation-react-native: ed874466f2e7967ada45a9e4dfad147dabe8f9dd + stream-io-video-filters-react-native: 1336c7f604d99d452817b90828389f47771f9417 stream-react-native-webrtc: 460795039c3aa0c83c882fe2cc59f5ebae3f6a18 - stream-video-react-native: cf65d64de93d6d464c7b28672824188a00ce2a1f + stream-video-react-native: 76f36e8801910cbc5a0f909a75cef826b699ad23 + StreamReactNativeBroadcast: a86749beea3b9faee4eaeced64d343dab58311aa StreamVideoNoiseCancellation: 41f5a712aba288f9636b64b17ebfbdff52c61490 StreamWebRTC: a50ebd8beba4def8f4e378b4895824c3520f9889 VisionCamera: 891edb31806dd3a239c8a9d6090d6ec78e11ee80 diff --git a/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj b/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj index d64f1b6204..32a6a68855 100644 --- a/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj +++ b/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj @@ -8,7 +8,7 @@ /* Begin PBXBuildFile section */ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; - 4D2CFA4A1D21793DD346776C /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; + 4D2CFA4A1D21793DD346776C /* (null) in Frameworks */ = {isa = PBXBuildFile; }; 4D971DCC2E57B61BFEDC0B7D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 88BB23A1BB898D9683DCB129 /* PrivacyInfo.xcprivacy */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 971245789A3DE3BC5BE05B7A /* Pods_StreamReactNativeVideoSDKSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EE5915852699CCF75559F04 /* Pods_StreamReactNativeVideoSDKSample.framework */; }; @@ -107,7 +107,7 @@ files = ( DD6FC6042987E2E800B13B16 /* CallKit.framework in Frameworks */, DD6FC6022987E2D700B13B16 /* Intents.framework in Frameworks */, - 4D2CFA4A1D21793DD346776C /* BuildFile in Frameworks */, + 4D2CFA4A1D21793DD346776C /* (null) in Frameworks */, 971245789A3DE3BC5BE05B7A /* Pods_StreamReactNativeVideoSDKSample.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcworkspace/xcshareddata/swiftpm/Package.resolved b/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000000..4911fa612c --- /dev/null +++ b/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,24 @@ +{ + "originHash" : "8556dd82d26673d1afd3819574f15a778e2d38bd3ae4969e60f576eb2af7b16f", + "pins" : [ + { + "identity" : "haishinkit.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/HaishinKit/HaishinKit.swift", + "state" : { + "revision" : "ba1f5483b53200d8b39442c6f667b496c1efdec0", + "version" : "2.2.0" + } + }, + { + "identity" : "logboard", + "kind" : "remoteSourceControl", + "location" : "https://github.com/shogo4405/Logboard.git", + "state" : { + "revision" : "8f41c63afb903040b77049ee2efa8c257b8c0d50", + "version" : "2.6.0" + } + } + ], + "version" : 3 +} diff --git a/sample-apps/react-native/dogfood/metro.config.js b/sample-apps/react-native/dogfood/metro.config.js index a414f24daa..49e044d102 100644 --- a/sample-apps/react-native/dogfood/metro.config.js +++ b/sample-apps/react-native/dogfood/metro.config.js @@ -12,6 +12,7 @@ config.watchFolders = [ path.join(workspaceRoot, 'packages/client'), path.join(workspaceRoot, 'packages/react-bindings'), path.join(workspaceRoot, 'packages/react-native-sdk'), + path.join(workspaceRoot, 'packages/react-native-broadcast'), path.join(workspaceRoot, 'packages/video-filters-react-native'), path.join(workspaceRoot, 'packages/noise-cancellation-react-native'), ]; diff --git a/sample-apps/react-native/dogfood/package.json b/sample-apps/react-native/dogfood/package.json index 13b444d08c..ee9ba0e95a 100644 --- a/sample-apps/react-native/dogfood/package.json +++ b/sample-apps/react-native/dogfood/package.json @@ -23,6 +23,7 @@ "@stream-io/noise-cancellation-react-native": "workspace:^", "@stream-io/react-native-webrtc": "125.4.4", "@stream-io/video-filters-react-native": "workspace:^", + "@stream-io/video-react-native-broadcast": "workspace:^", "@stream-io/video-react-native-sdk": "workspace:^", "axios": "^1.12.2", "react": "19.1.0", diff --git a/yarn.lock b/yarn.lock index b8ca5e2c91..b27fa698c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -59,6 +59,31 @@ __metadata: languageName: node linkType: hard +"@ark/regex@npm:0.0.0": + version: 0.0.0 + resolution: "@ark/regex@npm:0.0.0" + dependencies: + "@ark/util": "npm:0.50.0" + checksum: 10/ba2f539b865ae9bdcc97ef1272e322e68c5d3e27327e2cd90d414df588cdbf16dca2ccd0d99ce2869efcd76063b24532b5bcea83866b8798d07f6fce35ec5c96 + languageName: node + linkType: hard + +"@ark/schema@npm:0.50.0": + version: 0.50.0 + resolution: "@ark/schema@npm:0.50.0" + dependencies: + "@ark/util": "npm:0.50.0" + checksum: 10/12608d828f38661cf320f4e45228f10fab73750c6b115ec6b600cbd60ae76944d0816b68be59c36c7442da21862ce57a687264f8c224222e238e5410292719b6 + languageName: node + linkType: hard + +"@ark/util@npm:0.50.0": + version: 0.50.0 + resolution: "@ark/util@npm:0.50.0" + checksum: 10/aa253cca47365a169e5de02f09f8aeb5ea8887475870c5a815d62139ab592ca173189e518d0c4aec1508617e29af30048da8b2601ec04f9e91782f63c338a030 + languageName: node + linkType: hard + "@babel/cli@npm:^7.23.4": version: 7.26.4 resolution: "@babel/cli@npm:7.26.4" @@ -136,7 +161,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.20.0, @babel/generator@npm:^7.20.5, @babel/generator@npm:^7.25.0, @babel/generator@npm:^7.25.7, @babel/generator@npm:^7.28.3, @babel/generator@npm:^7.7.2": +"@babel/generator@npm:^7.20.5, @babel/generator@npm:^7.25.0, @babel/generator@npm:^7.25.7, @babel/generator@npm:^7.28.3, @babel/generator@npm:^7.7.2": version: 7.28.3 resolution: "@babel/generator@npm:7.28.3" dependencies: @@ -371,7 +396,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.25.3, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.25.3, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": version: 7.28.4 resolution: "@babel/parser@npm:7.28.4" dependencies: @@ -554,14 +579,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-flow@npm:^7.12.1, @babel/plugin-syntax-flow@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-syntax-flow@npm:7.26.0" +"@babel/plugin-syntax-flow@npm:^7.12.1, @babel/plugin-syntax-flow@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-flow@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/fdc0d0a7b512e00d933e12cf93c785ea4645a193f4b539230b7601cfaa8c704410199318ce9ea14e5fca7d13e9027822f7d81a7871d3e854df26b6af04cc3c6c + checksum: 10/7baca3171ed595d04c865b0ce46fca7f21900686df9d7fcd1017036ce78bb5483e33803de810831e68d39cf478953db69f49ae3f3de2e3207bc4ba49a96b6739 languageName: node linkType: hard @@ -923,15 +948,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-flow-strip-types@npm:^7.25.2, @babel/plugin-transform-flow-strip-types@npm:^7.25.9": - version: 7.26.5 - resolution: "@babel/plugin-transform-flow-strip-types@npm:7.26.5" +"@babel/plugin-transform-flow-strip-types@npm:^7.25.2, @babel/plugin-transform-flow-strip-types@npm:^7.25.9, @babel/plugin-transform-flow-strip-types@npm:^7.26.5": + version: 7.27.1 + resolution: "@babel/plugin-transform-flow-strip-types@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.26.5" - "@babel/plugin-syntax-flow": "npm:^7.26.0" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/plugin-syntax-flow": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/01ffdf56f0cbf26d222311cd69be4e5997182dbe6fee217f241c8d67f5e5b115b70efa4acd27d850f0a242b0d36b062d255d763984416155d0237c3ee9e9b8ea + checksum: 10/22e260866b122b7d0c35f2c55b2d422b175606b4d14c9ba116b1fbe88e08cc8b024c1c41bb62527cfc5f7ccc0ed06c752e5945cb1ee22465a30aa5623e617940 languageName: node linkType: hard @@ -1526,7 +1551,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-flow@npm:^7.17.12, @babel/preset-flow@npm:^7.24.7": +"@babel/preset-flow@npm:^7.17.12": version: 7.25.9 resolution: "@babel/preset-flow@npm:7.25.9" dependencies: @@ -1590,7 +1615,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.0.0, @babel/template@npm:^7.25.0, @babel/template@npm:^7.25.7, @babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.25.0, @babel/template@npm:^7.25.7, @babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": version: 7.27.2 resolution: "@babel/template@npm:7.27.2" dependencies: @@ -1616,7 +1641,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.16.0, @babel/traverse@npm:^7.20.0, @babel/traverse@npm:^7.25.3, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4": +"@babel/traverse@npm:^7.16.0, @babel/traverse@npm:^7.25.3, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4": version: 7.28.4 resolution: "@babel/traverse@npm:7.28.4" dependencies: @@ -1631,7 +1656,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": version: 7.28.4 resolution: "@babel/types@npm:7.28.4" dependencies: @@ -7254,7 +7279,7 @@ __metadata: "@stream-io/react-native-webrtc": "npm:125.4.4" react: "npm:19.1.0" react-native: "npm:^0.81.4" - react-native-builder-bob: "npm:^0.37.0" + react-native-builder-bob: "npm:^0.40.13" rimraf: "npm:^6.0.1" typescript: "npm:^5.9.3" peerDependencies: @@ -7352,7 +7377,7 @@ __metadata: "@stream-io/react-native-webrtc": "npm:125.4.4" react: "npm:19.1.0" react-native: "npm:^0.81.4" - react-native-builder-bob: "npm:^0.37.0" + react-native-builder-bob: "npm:^0.40.13" rimraf: "npm:^6.0.1" typescript: "npm:^5.9.3" peerDependencies: @@ -7461,6 +7486,23 @@ __metadata: languageName: unknown linkType: soft +"@stream-io/video-react-native-broadcast@workspace:^, @stream-io/video-react-native-broadcast@workspace:packages/react-native-broadcast": + version: 0.0.0-use.local + resolution: "@stream-io/video-react-native-broadcast@workspace:packages/react-native-broadcast" + dependencies: + "@react-native-community/cli": "npm:20.0.0" + "@react-native/babel-preset": "npm:^0.81.4" + "@types/react": "npm:~19.1.17" + react: "npm:19.1.0" + react-native: "npm:^0.81.4" + react-native-builder-bob: "npm:^0.40.13" + typescript: "npm:^5.9.3" + peerDependencies: + react: "*" + react-native: ">=0.79.0" + languageName: unknown + linkType: soft + "@stream-io/video-react-native-dogfood@workspace:sample-apps/react-native/dogfood": version: 0.0.0-use.local resolution: "@stream-io/video-react-native-dogfood@workspace:sample-apps/react-native/dogfood" @@ -7489,6 +7531,7 @@ __metadata: "@stream-io/noise-cancellation-react-native": "workspace:^" "@stream-io/react-native-webrtc": "npm:125.4.4" "@stream-io/video-filters-react-native": "workspace:^" + "@stream-io/video-react-native-broadcast": "workspace:^" "@stream-io/video-react-native-sdk": "workspace:^" "@types/react": "npm:~19.1.17" axios: "npm:^1.12.2" @@ -9020,6 +9063,17 @@ __metadata: languageName: node linkType: hard +"arktype@npm:^2.1.15": + version: 2.1.23 + resolution: "arktype@npm:2.1.23" + dependencies: + "@ark/regex": "npm:0.0.0" + "@ark/schema": "npm:0.50.0" + "@ark/util": "npm:0.50.0" + checksum: 10/772d67c688015ae1aa4d853f4d1bf970d657054df26b83ba7d7437d8981c7bb74680f095d16aec2e4bfc7f4b2cec626bc6d562d9319d4a1f7f6bc955fe312558 + languageName: node + linkType: hard + "array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2": version: 1.0.2 resolution: "array-buffer-byte-length@npm:1.0.2" @@ -9343,19 +9397,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-module-resolver@npm:^5.0.2": - version: 5.0.2 - resolution: "babel-plugin-module-resolver@npm:5.0.2" - dependencies: - find-babel-config: "npm:^2.1.1" - glob: "npm:^9.3.3" - pkg-up: "npm:^3.1.0" - reselect: "npm:^4.1.7" - resolve: "npm:^1.22.8" - checksum: 10/8084fa8a4cd96aaa861e5fe765a6cd03accef64d21d4108e314029bcd5f3a7fd96faf0c877c575a6a24d4fe0d87458d49748ca56faa4c77b2b812e4ed6023768 - languageName: node - linkType: hard - "babel-plugin-polyfill-corejs2@npm:^0.4.10, babel-plugin-polyfill-corejs2@npm:^0.4.14": version: 0.4.14 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.14" @@ -9429,6 +9470,15 @@ __metadata: languageName: node linkType: hard +"babel-plugin-syntax-hermes-parser@npm:^0.28.0": + version: 0.28.1 + resolution: "babel-plugin-syntax-hermes-parser@npm:0.28.1" + dependencies: + hermes-parser: "npm:0.28.1" + checksum: 10/2cbc921e663463480ead9ccc8bb229a5196032367ba2b5ccb18a44faa3afa84b4dc493297749983b9a837a3d76b0b123664aecc06f9122618c3246f03e076a9d + languageName: node + linkType: hard + "babel-plugin-transform-flow-enums@npm:^0.0.2": version: 0.0.2 resolution: "babel-plugin-transform-flow-enums@npm:0.0.2" @@ -10692,13 +10742,6 @@ __metadata: languageName: node linkType: hard -"core-util-is@npm:~1.0.0": - version: 1.0.3 - resolution: "core-util-is@npm:1.0.3" - checksum: 10/9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99 - languageName: node - linkType: hard - "cosmiconfig@npm:^5.0.5": version: 5.2.1 resolution: "cosmiconfig@npm:5.2.1" @@ -10945,7 +10988,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.6.9": +"debug@npm:2.6.9, debug@npm:^2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -11143,13 +11186,6 @@ __metadata: languageName: node linkType: hard -"denodeify@npm:^1.2.1": - version: 1.2.1 - resolution: "denodeify@npm:1.2.1" - checksum: 10/f5371a93051a81b0d8f54ac2972de6ae7cd9ba272174dff58bbf28a545c5b38e1952b3e8860e6b31ead44981bb14e158720fa43501e86252315b25f3ca34a460 - languageName: node - linkType: hard - "depd@npm:2.0.0, depd@npm:^2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" @@ -12882,16 +12918,16 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": - version: 3.3.2 - resolution: "fast-glob@npm:3.3.2" +"fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2, fast-glob@npm:^3.3.3": + version: 3.3.3 + resolution: "fast-glob@npm:3.3.3" dependencies: "@nodelib/fs.stat": "npm:^2.0.2" "@nodelib/fs.walk": "npm:^1.2.3" glob-parent: "npm:^5.1.2" merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.4" - checksum: 10/222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + micromatch: "npm:^4.0.8" + checksum: 10/dcc6432b269762dd47381d8b8358bf964d8f4f60286ac6aa41c01ade70bda459ff2001b516690b96d5365f68a49242966112b5d5cc9cd82395fa8f9d017c90ad languageName: node linkType: hard @@ -13074,15 +13110,6 @@ __metadata: languageName: node linkType: hard -"find-babel-config@npm:^2.1.1": - version: 2.1.2 - resolution: "find-babel-config@npm:2.1.2" - dependencies: - json5: "npm:^2.2.3" - checksum: 10/f0fae1a9125a379cf660fc1b5ca7c1fc1edac5f47e521a89e4c2b92865c8e57101a9152ee503eef9f33e16f196182f2cff03d7768b7caf5eef81c80f1c124a2f - languageName: node - linkType: hard - "find-root@npm:^1.1.0": version: 1.1.0 resolution: "find-root@npm:1.1.0" @@ -13090,15 +13117,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^3.0.0": - version: 3.0.0 - resolution: "find-up@npm:3.0.0" - dependencies: - locate-path: "npm:^3.0.0" - checksum: 10/38eba3fe7a66e4bc7f0f5a1366dc25508b7cfc349f852640e3678d26ad9a6d7e2c43eff0a472287de4a9753ef58f066a0ea892a256fa3636ad51b3fe1e17fae9 - languageName: node - linkType: hard - "find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" @@ -13716,7 +13734,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^9.3.2, glob@npm:^9.3.3": +"glob@npm:^9.3.2": version: 9.3.5 resolution: "glob@npm:9.3.5" dependencies: @@ -13977,13 +13995,6 @@ __metadata: languageName: node linkType: hard -"hermes-estree@npm:0.23.1": - version: 0.23.1 - resolution: "hermes-estree@npm:0.23.1" - checksum: 10/b7ad78f53044d53ec1c77e93036c16e34f6f0985c895540876301e4791d4db08da828870977140f5cf1ae34532bbb9d9d013a0a1a4a5a0da05177225648d5295 - languageName: node - linkType: hard - "hermes-estree@npm:0.25.1": version: 0.25.1 resolution: "hermes-estree@npm:0.25.1" @@ -13991,6 +14002,13 @@ __metadata: languageName: node linkType: hard +"hermes-estree@npm:0.28.1": + version: 0.28.1 + resolution: "hermes-estree@npm:0.28.1" + checksum: 10/3195a1aa7035d96b77839e6bfd6832b51830518aaf8dabfca11248b84d6fb6abd27e21c8caa84229954a76b4f8a1e346b65d421a4daecd3053bd2ea08fe6abc9 + languageName: node + linkType: hard + "hermes-estree@npm:0.29.1": version: 0.29.1 resolution: "hermes-estree@npm:0.29.1" @@ -14005,12 +14023,12 @@ __metadata: languageName: node linkType: hard -"hermes-parser@npm:0.23.1": - version: 0.23.1 - resolution: "hermes-parser@npm:0.23.1" +"hermes-parser@npm:0.28.1": + version: 0.28.1 + resolution: "hermes-parser@npm:0.28.1" dependencies: - hermes-estree: "npm:0.23.1" - checksum: 10/de88df4f23bd8dc2ffa89c8a317445320af8c7705a2aeeb05c4dd171f037a747982be153a0a237b1c9c7337b79bceaeb5052934cb8a25fe2e2473294a5343334 + hermes-estree: "npm:0.28.1" + checksum: 10/cb2aa4d386929825c3bd8184eeb4e3dcf34892c1f850624d09a80aee0674bc2eb135eccaeb7ac33675552130229ee6160025c4e4f351d6a61b503bd8bfdf63f5 languageName: node linkType: hard @@ -15007,13 +15025,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: 10/f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab - languageName: node - linkType: hard - "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -15623,7 +15634,7 @@ __metadata: languageName: node linkType: hard -"jest-validate@npm:^29.6.3, jest-validate@npm:^29.7.0": +"jest-validate@npm:^29.7.0": version: 29.7.0 resolution: "jest-validate@npm:29.7.0" dependencies: @@ -15681,7 +15692,7 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^29.6.3, jest-worker@npm:^29.7.0": +"jest-worker@npm:^29.7.0": version: 29.7.0 resolution: "jest-worker@npm:29.7.0" dependencies: @@ -16277,16 +16288,6 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^3.0.0": - version: 3.0.0 - resolution: "locate-path@npm:3.0.0" - dependencies: - p-locate: "npm:^3.0.0" - path-exists: "npm:^3.0.0" - checksum: 10/53db3996672f21f8b0bf2a2c645ae2c13ffdae1eeecfcd399a583bce8516c0b88dcb4222ca6efbbbeb6949df7e46860895be2c02e8d3219abd373ace3bfb4e11 - languageName: node - linkType: hard - "locate-path@npm:^5.0.0": version: 5.0.0 resolution: "locate-path@npm:5.0.0" @@ -16963,18 +16964,6 @@ __metadata: languageName: node linkType: hard -"metro-babel-transformer@npm:0.80.12": - version: 0.80.12 - resolution: "metro-babel-transformer@npm:0.80.12" - dependencies: - "@babel/core": "npm:^7.20.0" - flow-enums-runtime: "npm:^0.0.6" - hermes-parser: "npm:0.23.1" - nullthrows: "npm:^1.1.1" - checksum: 10/3912367e269df3ac697d67541d56fed86ab6fc40ce1aa107b8f332402c7a84a3d0991e536897d4877bab2b1986dd21ec7fad0c76704a27c1c2edce0bcf9037a9 - languageName: node - linkType: hard - "metro-babel-transformer@npm:0.83.1": version: 0.83.1 resolution: "metro-babel-transformer@npm:0.83.1" @@ -16999,15 +16988,6 @@ __metadata: languageName: node linkType: hard -"metro-cache-key@npm:0.80.12": - version: 0.80.12 - resolution: "metro-cache-key@npm:0.80.12" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - checksum: 10/7a06601180604361339d19eb833d61b79cc188a4e6ebe73188cc10fbf3a33e711d74c81d1d19a14b6581bd9dfeebe1b253684360682d033ab55909c9995b6a18 - languageName: node - linkType: hard - "metro-cache-key@npm:0.83.1": version: 0.83.1 resolution: "metro-cache-key@npm:0.83.1" @@ -17026,17 +17006,6 @@ __metadata: languageName: node linkType: hard -"metro-cache@npm:0.80.12": - version: 0.80.12 - resolution: "metro-cache@npm:0.80.12" - dependencies: - exponential-backoff: "npm:^3.1.1" - flow-enums-runtime: "npm:^0.0.6" - metro-core: "npm:0.80.12" - checksum: 10/914b599ad4f8a2538e6f4788b3da722aa855688affef3002fe374a0a1cb7dd36ad9224d1ef83f7c17610ebb290cea3cb545bfd67100a216b7bbb3f26f8982c93 - languageName: node - linkType: hard - "metro-cache@npm:0.83.1": version: 0.83.1 resolution: "metro-cache@npm:0.83.1" @@ -17061,22 +17030,6 @@ __metadata: languageName: node linkType: hard -"metro-config@npm:0.80.12, metro-config@npm:^0.80.9": - version: 0.80.12 - resolution: "metro-config@npm:0.80.12" - dependencies: - connect: "npm:^3.6.5" - cosmiconfig: "npm:^5.0.5" - flow-enums-runtime: "npm:^0.0.6" - jest-validate: "npm:^29.6.3" - metro: "npm:0.80.12" - metro-cache: "npm:0.80.12" - metro-core: "npm:0.80.12" - metro-runtime: "npm:0.80.12" - checksum: 10/2d11745d32e8992b78159c275dc54b08bf258871f274634f9824540f1ec80a9b1a9d7eb5493b52078a5a68cccd4fd688cd846dd0802aea2f065b5588e98eb146 - languageName: node - linkType: hard - "metro-config@npm:0.83.1": version: 0.83.1 resolution: "metro-config@npm:0.83.1" @@ -17109,17 +17062,6 @@ __metadata: languageName: node linkType: hard -"metro-core@npm:0.80.12": - version: 0.80.12 - resolution: "metro-core@npm:0.80.12" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - lodash.throttle: "npm:^4.1.1" - metro-resolver: "npm:0.80.12" - checksum: 10/d29ab20df4d19c1d8c5178f7b182e050c659f022ab2adc669504c7ef7fd5d76cdde02936d1599e6d6137e353cbf4fef6b3cfa6aaf217bca954fc23cbf1b61f18 - languageName: node - linkType: hard - "metro-core@npm:0.83.1": version: 0.83.1 resolution: "metro-core@npm:0.83.1" @@ -17142,29 +17084,6 @@ __metadata: languageName: node linkType: hard -"metro-file-map@npm:0.80.12": - version: 0.80.12 - resolution: "metro-file-map@npm:0.80.12" - dependencies: - anymatch: "npm:^3.0.3" - debug: "npm:^2.2.0" - fb-watchman: "npm:^2.0.0" - flow-enums-runtime: "npm:^0.0.6" - fsevents: "npm:^2.3.2" - graceful-fs: "npm:^4.2.4" - invariant: "npm:^2.2.4" - jest-worker: "npm:^29.6.3" - micromatch: "npm:^4.0.4" - node-abort-controller: "npm:^3.1.1" - nullthrows: "npm:^1.1.1" - walker: "npm:^1.0.7" - dependenciesMeta: - fsevents: - optional: true - checksum: 10/a0c06da7c89bfbbe17adadb46470274e2e1ffee43126a08f665db230d7831c6195410ea7165f94182e18a27359e140fc8272d2271c04bf0286a1ea95106a3758 - languageName: node - linkType: hard - "metro-file-map@npm:0.83.1": version: 0.83.1 resolution: "metro-file-map@npm:0.83.1" @@ -17199,16 +17118,6 @@ __metadata: languageName: node linkType: hard -"metro-minify-terser@npm:0.80.12": - version: 0.80.12 - resolution: "metro-minify-terser@npm:0.80.12" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - terser: "npm:^5.15.0" - checksum: 10/ff527b3f04c5814db139e55ceb7689aaaf0af5c7fbb0eb5d4a6f22044932dfb10bd385d388fa7b352acd03a2d078edaf43a6b5cd11cbc87a7c5502a34fc12735 - languageName: node - linkType: hard - "metro-minify-terser@npm:0.83.1": version: 0.83.1 resolution: "metro-minify-terser@npm:0.83.1" @@ -17229,15 +17138,6 @@ __metadata: languageName: node linkType: hard -"metro-resolver@npm:0.80.12": - version: 0.80.12 - resolution: "metro-resolver@npm:0.80.12" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - checksum: 10/e8609f1b93f1bbe7a9f97dd3fa2a6669c0a51f8360fea9a73e528fc25615f7ef61bd8ad9feb9a52fdbf4405a4065195f053183626f3ab56f54225ebefee574ac - languageName: node - linkType: hard - "metro-resolver@npm:0.83.1": version: 0.83.1 resolution: "metro-resolver@npm:0.83.1" @@ -17256,16 +17156,6 @@ __metadata: languageName: node linkType: hard -"metro-runtime@npm:0.80.12": - version: 0.80.12 - resolution: "metro-runtime@npm:0.80.12" - dependencies: - "@babel/runtime": "npm:^7.25.0" - flow-enums-runtime: "npm:^0.0.6" - checksum: 10/8a09e7001bd54331c50145d02e6a2b67589da4dd0da3ff1cdb83e6ce161b9079e2a52a4722db8f222b46f666e3dbfe1fc59ee7c277325763a162e3d27ba81d38 - languageName: node - linkType: hard - "metro-runtime@npm:0.83.1": version: 0.83.1 resolution: "metro-runtime@npm:0.83.1" @@ -17286,23 +17176,6 @@ __metadata: languageName: node linkType: hard -"metro-source-map@npm:0.80.12": - version: 0.80.12 - resolution: "metro-source-map@npm:0.80.12" - dependencies: - "@babel/traverse": "npm:^7.20.0" - "@babel/types": "npm:^7.20.0" - flow-enums-runtime: "npm:^0.0.6" - invariant: "npm:^2.2.4" - metro-symbolicate: "npm:0.80.12" - nullthrows: "npm:^1.1.1" - ob1: "npm:0.80.12" - source-map: "npm:^0.5.6" - vlq: "npm:^1.0.0" - checksum: 10/ad6e0cf7f4d2727ecb45a082b4ab92915df8c574de0a905023a53e501a32f619aaeb0f94645aca048ae322176600867f5f21119349261427a2de27cb27ef0ef1 - languageName: node - linkType: hard - "metro-source-map@npm:0.83.1": version: 0.83.1 resolution: "metro-source-map@npm:0.83.1" @@ -17339,23 +17212,6 @@ __metadata: languageName: node linkType: hard -"metro-symbolicate@npm:0.80.12": - version: 0.80.12 - resolution: "metro-symbolicate@npm:0.80.12" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - invariant: "npm:^2.2.4" - metro-source-map: "npm:0.80.12" - nullthrows: "npm:^1.1.1" - source-map: "npm:^0.5.6" - through2: "npm:^2.0.1" - vlq: "npm:^1.0.0" - bin: - metro-symbolicate: src/index.js - checksum: 10/0c1dd055691bd670fb73a146f7e2fa3235a5afa3135996e681384676a439e10c9efe398d5b07d588907adbfbf65228829ceb57dab2c19a61eb79dde60bb7dc31 - languageName: node - linkType: hard - "metro-symbolicate@npm:0.83.1": version: 0.83.1 resolution: "metro-symbolicate@npm:0.83.1" @@ -17388,20 +17244,6 @@ __metadata: languageName: node linkType: hard -"metro-transform-plugins@npm:0.80.12": - version: 0.80.12 - resolution: "metro-transform-plugins@npm:0.80.12" - dependencies: - "@babel/core": "npm:^7.20.0" - "@babel/generator": "npm:^7.20.0" - "@babel/template": "npm:^7.0.0" - "@babel/traverse": "npm:^7.20.0" - flow-enums-runtime: "npm:^0.0.6" - nullthrows: "npm:^1.1.1" - checksum: 10/801510bde9cb70ba47572c3d5d42f98fc2ee173a48ca39893cbdeb689de54d5a1fea5383ba4fe388f334af06ecb651e5634b5e7611223e217668c98f8666c913 - languageName: node - linkType: hard - "metro-transform-plugins@npm:0.83.1": version: 0.83.1 resolution: "metro-transform-plugins@npm:0.83.1" @@ -17430,27 +17272,6 @@ __metadata: languageName: node linkType: hard -"metro-transform-worker@npm:0.80.12": - version: 0.80.12 - resolution: "metro-transform-worker@npm:0.80.12" - dependencies: - "@babel/core": "npm:^7.20.0" - "@babel/generator": "npm:^7.20.0" - "@babel/parser": "npm:^7.20.0" - "@babel/types": "npm:^7.20.0" - flow-enums-runtime: "npm:^0.0.6" - metro: "npm:0.80.12" - metro-babel-transformer: "npm:0.80.12" - metro-cache: "npm:0.80.12" - metro-cache-key: "npm:0.80.12" - metro-minify-terser: "npm:0.80.12" - metro-source-map: "npm:0.80.12" - metro-transform-plugins: "npm:0.80.12" - nullthrows: "npm:^1.1.1" - checksum: 10/a0802ebbc308a3bd6c81f9a1c640c62a8918f4d4e73da2184d24be10014ce6bc1cef53c0ef6a59568ecc0d0d44d43e38ec595d4abda043f93072613261074371 - languageName: node - linkType: hard - "metro-transform-worker@npm:0.83.1": version: 0.83.1 resolution: "metro-transform-worker@npm:0.83.1" @@ -17493,58 +17314,6 @@ __metadata: languageName: node linkType: hard -"metro@npm:0.80.12": - version: 0.80.12 - resolution: "metro@npm:0.80.12" - dependencies: - "@babel/code-frame": "npm:^7.0.0" - "@babel/core": "npm:^7.20.0" - "@babel/generator": "npm:^7.20.0" - "@babel/parser": "npm:^7.20.0" - "@babel/template": "npm:^7.0.0" - "@babel/traverse": "npm:^7.20.0" - "@babel/types": "npm:^7.20.0" - accepts: "npm:^1.3.7" - chalk: "npm:^4.0.0" - ci-info: "npm:^2.0.0" - connect: "npm:^3.6.5" - debug: "npm:^2.2.0" - denodeify: "npm:^1.2.1" - error-stack-parser: "npm:^2.0.6" - flow-enums-runtime: "npm:^0.0.6" - graceful-fs: "npm:^4.2.4" - hermes-parser: "npm:0.23.1" - image-size: "npm:^1.0.2" - invariant: "npm:^2.2.4" - jest-worker: "npm:^29.6.3" - jsc-safe-url: "npm:^0.2.2" - lodash.throttle: "npm:^4.1.1" - metro-babel-transformer: "npm:0.80.12" - metro-cache: "npm:0.80.12" - metro-cache-key: "npm:0.80.12" - metro-config: "npm:0.80.12" - metro-core: "npm:0.80.12" - metro-file-map: "npm:0.80.12" - metro-resolver: "npm:0.80.12" - metro-runtime: "npm:0.80.12" - metro-source-map: "npm:0.80.12" - metro-symbolicate: "npm:0.80.12" - metro-transform-plugins: "npm:0.80.12" - metro-transform-worker: "npm:0.80.12" - mime-types: "npm:^2.1.27" - nullthrows: "npm:^1.1.1" - serialize-error: "npm:^2.1.0" - source-map: "npm:^0.5.6" - strip-ansi: "npm:^6.0.0" - throat: "npm:^5.0.0" - ws: "npm:^7.5.10" - yargs: "npm:^17.6.2" - bin: - metro: src/cli.js - checksum: 10/b44280b16d3671be97d11327a9fe0bb2db014a6dcedaab9e88d58696a8133246ef7f8290e9fac0841534872132bbc0d7132745b02f3584339c0999d9e7a58c10 - languageName: node - linkType: hard - "metro@npm:0.83.1": version: 0.83.1 resolution: "metro@npm:0.83.1" @@ -18503,13 +18272,6 @@ __metadata: languageName: node linkType: hard -"node-abort-controller@npm:^3.1.1": - version: 3.1.1 - resolution: "node-abort-controller@npm:3.1.1" - checksum: 10/0a2cdb7ec0aeaf3cb31e1ca0e192f5add48f1c5c9c9ed822129f9dddbd9432f69b7425982f94ce803c56a2104884530aa67cd57696e5774b2e5b8ec2f58de042 - languageName: node - linkType: hard - "node-addon-api@npm:^7.0.0": version: 7.1.1 resolution: "node-addon-api@npm:7.1.1" @@ -18772,15 +18534,6 @@ __metadata: languageName: node linkType: hard -"ob1@npm:0.80.12": - version: 0.80.12 - resolution: "ob1@npm:0.80.12" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - checksum: 10/c78af51d6ecf47ba5198bc7eb27d0456a287589533f1445e6d595e2d067f6f8038da02a98e5faa4a6c3d0c04f77c570bc9b29c652fec55518884c40c73212f17 - languageName: node - linkType: hard - "ob1@npm:0.83.1": version: 0.83.1 resolution: "ob1@npm:0.83.1" @@ -19094,7 +18847,7 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": +"p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" dependencies: @@ -19121,15 +18874,6 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^3.0.0": - version: 3.0.0 - resolution: "p-locate@npm:3.0.0" - dependencies: - p-limit: "npm:^2.0.0" - checksum: 10/83991734a9854a05fe9dbb29f707ea8a0599391f52daac32b86f08e21415e857ffa60f0e120bfe7ce0cc4faf9274a50239c7895fc0d0579d08411e513b83a4ae - languageName: node - linkType: hard - "p-locate@npm:^4.1.0": version: 4.1.0 resolution: "p-locate@npm:4.1.0" @@ -19300,13 +19044,6 @@ __metadata: languageName: node linkType: hard -"path-exists@npm:^3.0.0": - version: 3.0.0 - resolution: "path-exists@npm:3.0.0" - checksum: 10/96e92643aa34b4b28d0de1cd2eba52a1c5313a90c6542d03f62750d82480e20bfa62bc865d5cfc6165f5fcd5aeb0851043c40a39be5989646f223300021bae0a - languageName: node - linkType: hard - "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" @@ -19506,15 +19243,6 @@ __metadata: languageName: node linkType: hard -"pkg-up@npm:^3.1.0": - version: 3.1.0 - resolution: "pkg-up@npm:3.1.0" - dependencies: - find-up: "npm:^3.0.0" - checksum: 10/5bac346b7c7c903613c057ae3ab722f320716199d753f4a7d053d38f2b5955460f3e6ab73b4762c62fd3e947f58e04f1343e92089e7bb6091c90877406fcd8c8 - languageName: node - linkType: hard - "playwright-core@npm:1.56.0": version: 1.56.0 resolution: "playwright-core@npm:1.56.0" @@ -19795,13 +19523,6 @@ __metadata: languageName: node linkType: hard -"process-nextick-args@npm:~2.0.0": - version: 2.0.1 - resolution: "process-nextick-args@npm:2.0.1" - checksum: 10/1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf - languageName: node - linkType: hard - "process@npm:^0.11.1": version: 0.11.10 resolution: "process@npm:0.11.10" @@ -20201,19 +19922,19 @@ __metadata: languageName: node linkType: hard -"react-native-builder-bob@npm:^0.37.0": - version: 0.37.0 - resolution: "react-native-builder-bob@npm:0.37.0" +"react-native-builder-bob@npm:^0.40.13": + version: 0.40.13 + resolution: "react-native-builder-bob@npm:0.40.13" dependencies: "@babel/core": "npm:^7.25.2" + "@babel/plugin-transform-flow-strip-types": "npm:^7.26.5" "@babel/plugin-transform-strict-mode": "npm:^7.24.7" "@babel/preset-env": "npm:^7.25.2" - "@babel/preset-flow": "npm:^7.24.7" "@babel/preset-react": "npm:^7.24.7" "@babel/preset-typescript": "npm:^7.24.7" - babel-plugin-module-resolver: "npm:^5.0.2" + arktype: "npm:^2.1.15" + babel-plugin-syntax-hermes-parser: "npm:^0.28.0" browserslist: "npm:^4.20.4" - cosmiconfig: "npm:^9.0.0" cross-spawn: "npm:^7.0.3" dedent: "npm:^0.7.0" del: "npm:^6.1.1" @@ -20223,13 +19944,13 @@ __metadata: is-git-dirty: "npm:^2.0.1" json5: "npm:^2.2.1" kleur: "npm:^4.1.4" - metro-config: "npm:^0.80.9" prompts: "npm:^2.4.2" + react-native-monorepo-config: "npm:^0.1.8" which: "npm:^2.0.2" yargs: "npm:^17.5.1" bin: bob: bin/bob - checksum: 10/194e91d1fdce14a495af23298759accd86b5c9f8eee094a45c2b77d12c1ce81f8e8ed5988c4418ab611f432fc704c9d985e688a7d91a7170824ffb9ab553105a + checksum: 10/7359398d32f237c5b3366dd6dc86862ac2059ec9878d21f4dccb10b432d154afffb68bcdfa3ce6781c1391ea08ca8d93bd2592b7d86c8d013d123736e7b5112a languageName: node linkType: hard @@ -20364,6 +20085,16 @@ __metadata: languageName: node linkType: hard +"react-native-monorepo-config@npm:^0.1.8": + version: 0.1.10 + resolution: "react-native-monorepo-config@npm:0.1.10" + dependencies: + escape-string-regexp: "npm:^5.0.0" + fast-glob: "npm:^3.3.3" + checksum: 10/36611eca9cbda6647111e659d5c466fdba002c608172b9d25880b6e3ac95c51f41d15520e06d9d3188c096b0c9182caeba7b9340c64f6b45f1fee331c08b877b + languageName: node + linkType: hard + "react-native-permissions@npm:^5.4.2": version: 5.4.2 resolution: "react-native-permissions@npm:5.4.2" @@ -20853,21 +20584,6 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:~2.3.6": - version: 2.3.8 - resolution: "readable-stream@npm:2.3.8" - dependencies: - core-util-is: "npm:~1.0.0" - inherits: "npm:~2.0.3" - isarray: "npm:~1.0.0" - process-nextick-args: "npm:~2.0.0" - safe-buffer: "npm:~5.1.1" - string_decoder: "npm:~1.1.1" - util-deprecate: "npm:~1.0.1" - checksum: 10/8500dd3a90e391d6c5d889256d50ec6026c059fadee98ae9aa9b86757d60ac46fff24fafb7a39fa41d54cb39d8be56cc77be202ebd4cd8ffcf4cb226cbaa40d4 - languageName: node - linkType: hard - "readdirp@npm:^4.0.1": version: 4.1.2 resolution: "readdirp@npm:4.1.2" @@ -21093,13 +20809,6 @@ __metadata: languageName: node linkType: hard -"reselect@npm:^4.1.7": - version: 4.1.8 - resolution: "reselect@npm:4.1.8" - checksum: 10/199984d9872f71cd207f4aa6e6fd2bd48d95154f7aa9b3aee3398335f39f5491059e732f28c12e9031d5d434adab2c458dc8af5afb6564d0ad37e1644445e09c - languageName: node - linkType: hard - "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -21506,13 +21215,6 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": - version: 5.1.2 - resolution: "safe-buffer@npm:5.1.2" - checksum: 10/7eb5b48f2ed9a594a4795677d5a150faa7eb54483b2318b568dc0c4fc94092a6cce5be02c7288a0500a156282f5276d5688bce7259299568d1053b2150ef374a - languageName: node - linkType: hard - "safe-push-apply@npm:^1.0.0": version: 1.0.0 resolution: "safe-push-apply@npm:1.0.0" @@ -22621,15 +22323,6 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:~1.1.1": - version: 1.1.1 - resolution: "string_decoder@npm:1.1.1" - dependencies: - safe-buffer: "npm:~5.1.0" - checksum: 10/7c41c17ed4dea105231f6df208002ebddd732e8e9e2d619d133cecd8e0087ddfd9587d2feb3c8caf3213cbd841ada6d057f5142cae68a4e62d3540778d9819b4 - languageName: node - linkType: hard - "stringify-entities@npm:^4.0.0": version: 4.0.4 resolution: "stringify-entities@npm:4.0.4" @@ -23084,16 +22777,6 @@ __metadata: languageName: node linkType: hard -"through2@npm:^2.0.1": - version: 2.0.5 - resolution: "through2@npm:2.0.5" - dependencies: - readable-stream: "npm:~2.3.6" - xtend: "npm:~4.0.1" - checksum: 10/cd71f7dcdc7a8204fea003a14a433ef99384b7d4e31f5497e1f9f622b3cf3be3691f908455f98723bdc80922a53af7fa10c3b7abbe51c6fd3d536dbc7850e2c4 - languageName: node - linkType: hard - "through@npm:>=2.2.7 <3, through@npm:^2.3.6": version: 2.3.8 resolution: "through@npm:2.3.8" @@ -23892,7 +23575,7 @@ __metadata: languageName: node linkType: hard -"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": +"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" checksum: 10/474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 @@ -24613,7 +24296,7 @@ __metadata: languageName: node linkType: hard -"xtend@npm:^4.0.0, xtend@npm:~4.0.1": +"xtend@npm:^4.0.0": version: 4.0.2 resolution: "xtend@npm:4.0.2" checksum: 10/ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a From ee2cdbbb957ebb7d9a0e97f05430f53d1a7e93b9 Mon Sep 17 00:00:00 2001 From: Oliver Lazoroski Date: Mon, 20 Oct 2025 17:40:40 +0200 Subject: [PATCH 02/22] wip --- .../StreamReactNativeBroadcast.podspec | 2 +- .../java/com/broadcast/BroadcastModule.kt | 12 +- .../ios/AudioSourceService.swift | 128 ++++++++++++++++++ .../react-native-broadcast/ios/Broadcast.mm | 10 +- .../ios/Broadcast.swift | 78 ++++++++++- .../src/NativeBroadcast.ts | 2 +- packages/react-native-broadcast/src/index.tsx | 2 +- sample-apps/react-native/dogfood/App.tsx | 2 +- .../react-native/dogfood/ios/Podfile.lock | 2 +- .../project.pbxproj | 4 +- 10 files changed, 227 insertions(+), 15 deletions(-) create mode 100644 packages/react-native-broadcast/ios/AudioSourceService.swift diff --git a/packages/react-native-broadcast/StreamReactNativeBroadcast.podspec b/packages/react-native-broadcast/StreamReactNativeBroadcast.podspec index 14a7d0a470..04aed4136d 100644 --- a/packages/react-native-broadcast/StreamReactNativeBroadcast.podspec +++ b/packages/react-native-broadcast/StreamReactNativeBroadcast.podspec @@ -21,6 +21,6 @@ Pod::Spec.new do |s| spm_dependency(s, url: 'https://github.com/HaishinKit/HaishinKit.swift', requirement: { kind: 'upToNextMajorVersion', minimumVersion: '2.2.0' }, - products: ['RTMPHaishinKit'] + products: ['HaishinKit', 'RTMPHaishinKit', 'SRTHaishinKit', 'MoQTHaishinKit', 'RTCHaishinKit'] ) end diff --git a/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastModule.kt b/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastModule.kt index 610af7742c..ee3965fd4e 100644 --- a/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastModule.kt +++ b/packages/react-native-broadcast/android/src/main/java/com/broadcast/BroadcastModule.kt @@ -1,5 +1,6 @@ package com.broadcast +import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.module.annotations.ReactModule @@ -11,10 +12,13 @@ class BroadcastModule(reactContext: ReactApplicationContext) : return NAME } - // Example method - // See https://reactnative.dev/docs/native-modules-android - override fun multiply(a: Double, b: Double): Double { - return a * b + // Promise-based method to match TurboModule spec + override fun multiply(a: Double, b: Double, promise: Promise) { + try { + promise.resolve(a * b) + } catch (e: Exception) { + promise.reject("multiply_error", e) + } } companion object { diff --git a/packages/react-native-broadcast/ios/AudioSourceService.swift b/packages/react-native-broadcast/ios/AudioSourceService.swift new file mode 100644 index 0000000000..be60a71dce --- /dev/null +++ b/packages/react-native-broadcast/ios/AudioSourceService.swift @@ -0,0 +1,128 @@ +@preconcurrency import AVFoundation +import Combine + +struct AudioSource: Sendable, Hashable, Equatable, CustomStringConvertible { + static let empty = AudioSource(portName: "", dataSourceName: "", isSupportedStereo: false) + + let portName: String + let dataSourceName: String + let isSupportedStereo: Bool + + var description: String { + if isSupportedStereo { + return "\(portName)(\(dataSourceName))(Stereo)" + } + return "\(portName)(\(dataSourceName))(Mono)" + } +} + +actor AudioSourceService { + enum Error: Swift.Error { + case missingDataSource(_ source: AudioSource) + } + + private(set) var sources: [AudioSource] = [] { + didSet { + guard sources != oldValue else { + return + } + continuation?.yield(sources) + } + } + private let session = AVAudioSession.sharedInstance() + private var continuation: AsyncStream<[AudioSource]>.Continuation? { + didSet { + oldValue?.finish() + } + } + + init() { + Task { await _init() } + } + + private func _init() async { + sources = makeAudioSources() + Task { + for await _ in NotificationCenter.default.notifications(named: AVAudioSession.routeChangeNotification) + .compactMap({ $0.userInfo?[AVAudioSessionRouteChangeReasonKey] as? UInt }) + .compactMap({ AVAudioSession.RouteChangeReason(rawValue: $0) }) { + sources = makeAudioSources() + } + } + } + + func setUp() { + let session = AVAudioSession.sharedInstance() + do { + // If you set the "mode" parameter, stereo capture is not possible, so it is left unspecified. + try session.setCategory(.playAndRecord, mode: .videoRecording, options: [.defaultToSpeaker, .allowBluetoothHFP]) + // It looks like this setting is required on iOS 18.5. + try session.setPreferredInputNumberOfChannels(2) + try session.setActive(true) + } catch { + print(error) + } + } + + func sourcesUpdates() -> AsyncStream<[AudioSource]> { + AsyncStream { continuation in + self.continuation = continuation + continuation.yield(sources) + } + } + + func selectAudioSource(_ audioSource: AudioSource) throws { + setPreferredInputBuiltInMic(true) + guard let preferredInput = AVAudioSession.sharedInstance().preferredInput, + let dataSources = preferredInput.dataSources, + let newDataSource = dataSources.first(where: { $0.dataSourceName == audioSource.dataSourceName }), + let supportedPolarPatterns = newDataSource.supportedPolarPatterns else { + throw Error.missingDataSource(audioSource) + } + do { + let isStereoSupported = supportedPolarPatterns.contains(.stereo) + if isStereoSupported { + try newDataSource.setPreferredPolarPattern(.stereo) + } + try preferredInput.setPreferredDataSource(newDataSource) + } catch { + print(error) + } + } + + private func makeAudioSources() -> [AudioSource] { + if session.inputDataSources?.isEmpty == true { + setPreferredInputBuiltInMic(false) + } else { + setPreferredInputBuiltInMic(true) + } + guard let preferredInput = session.preferredInput else { + return [] + } + var sources: [AudioSource] = [] + for dataSource in session.preferredInput?.dataSources ?? [] { + sources.append(.init( + portName: preferredInput.portName, + dataSourceName: dataSource.dataSourceName, + isSupportedStereo: dataSource.supportedPolarPatterns?.contains(.stereo) ?? false + )) + } + return sources + } + + private func setPreferredInputBuiltInMic(_ isEnabled: Bool) { + do { + if isEnabled { + guard let availableInputs = session.availableInputs, + let builtInMicInput = availableInputs.first(where: { $0.portType == .builtInMic }) else { + return + } + try session.setPreferredInput(builtInMicInput) + } else { + try session.setPreferredInput(nil) + } + } catch { + print(error) + } + } +} diff --git a/packages/react-native-broadcast/ios/Broadcast.mm b/packages/react-native-broadcast/ios/Broadcast.mm index 46a277051f..1e4fc13211 100644 --- a/packages/react-native-broadcast/ios/Broadcast.mm +++ b/packages/react-native-broadcast/ios/Broadcast.mm @@ -3,9 +3,15 @@ @implementation Broadcast -- (NSNumber *)multiply:(double)a b:(double)b +- (void)multiply:(double)a b:(double)b resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject { - return [BroadcastSwift multiply:a b:b]; + [BroadcastSwift multiply:a b:b completion:^(NSNumber * _Nullable result, NSError * _Nullable error) { + if (error != nil) { + reject(@"multiply_error", error.localizedDescription, error); + } else { + resolve(result); + } + }]; } - (std::shared_ptr)getTurboModule: diff --git a/packages/react-native-broadcast/ios/Broadcast.swift b/packages/react-native-broadcast/ios/Broadcast.swift index 8c4499c926..8354969a9d 100644 --- a/packages/react-native-broadcast/ios/Broadcast.swift +++ b/packages/react-native-broadcast/ios/Broadcast.swift @@ -1,10 +1,84 @@ +import AVFoundation import Foundation +import HaishinKit +import RTMPHaishinKit @objc public class BroadcastSwift: NSObject { @objc - public static func multiply(_ a: Double, b: Double) -> NSNumber { - return NSNumber(value: a * b) + public static func multiply(_ a: Double, b: Double, completion: @escaping (NSNumber?, NSError?) -> Void) { + let uri = "rtmps://ingress.stream-io-video.com:443/par8f5s3gn2j.default.RdcC9Qr4j7pzr62FZbo8N/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3Byb250by5nZXRzdHJlYW0uaW8iLCJzdWIiOiJ1c2VyL2phbmUiLCJ1c2VyX2lkIjoiamFuZSIsInZhbGlkaXR5X2luX3NlY29uZHMiOjYwNDgwMCwiZW52aXJvbm1lbnQiOiJwcm9udG8iLCJpYXQiOjE3NjA5NzM3OTcsImV4cCI6MTc2MTU3ODU5N30.SlaGVdXvSWiGFf_Bx8GcIekRj4H71hNPRQynJkR6P5c" + + print("RTMP begin publishing") + + Task { + do { + let audioSourceService = AudioSourceService() + await audioSourceService.setUp() + + let mixer = MediaMixer(captureSessionMode: .single) + await mixer.configuration { session in + session.automaticallyConfiguresApplicationAudioSession = false + session.sessionPreset = .hd1280x720 + } + try? await mixer.configuration(video: 0) { video in + try? video.setFrameRate(30) + } + + + await mixer.setMonitoringEnabled(true) + print("[RTMP] Mixer created") + + var videoMixerSettings = await mixer.videoMixerSettings + videoMixerSettings.mode = .offscreen + await mixer.setVideoMixerSettings(videoMixerSettings) + + await mixer.stopCapturing() + + let front = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) + try? await mixer.attachVideo(front, track: 0) { unit in unit.isVideoMirrored = true } + + let mic = AVCaptureDevice.default(for: .audio) + try? await mixer.attachAudio(mic); + + await mixer.startRunning() + await mixer.startCapturing() + + print("[RTMP] Mixer configured") + + await SessionBuilderFactory.shared.register(RTMPSessionFactory()) + let session = try await SessionBuilderFactory.shared.make(URL(string: uri)) + .setMode(.publish) + .build() + guard let session else { + print("[RTMP] failed to create a session") + return completion(-1, nil) + } + + print("[RTMP] session created") + + await mixer.addOutput(session.stream) + + var audioSettings = await session.stream.audioSettings + audioSettings.format = .aac + try await session.stream.setAudioSettings(audioSettings) + + var videoSettings = await session.stream.videoSettings + videoSettings.isLowLatencyRateControlEnabled = false + videoSettings.videoSize = CGSize(width: 720, height: 1280) + try await session.stream.setVideoSettings(videoSettings) + + print("[RTMP] session connecting") + try await session.connect { + print("[RTMP] session connected") + } + + completion(NSNumber(value: a * b), nil) + } catch { + print("[RTMP] error", error) + completion(nil, error as NSError) + } + } } } diff --git a/packages/react-native-broadcast/src/NativeBroadcast.ts b/packages/react-native-broadcast/src/NativeBroadcast.ts index 5ec7119c48..e5584d40f7 100644 --- a/packages/react-native-broadcast/src/NativeBroadcast.ts +++ b/packages/react-native-broadcast/src/NativeBroadcast.ts @@ -1,7 +1,7 @@ import { type TurboModule, TurboModuleRegistry } from 'react-native'; export interface Spec extends TurboModule { - multiply(a: number, b: number): number; + multiply(a: number, b: number): Promise; } export default TurboModuleRegistry.getEnforcing('Broadcast'); diff --git a/packages/react-native-broadcast/src/index.tsx b/packages/react-native-broadcast/src/index.tsx index ff575c05a0..8331676a57 100644 --- a/packages/react-native-broadcast/src/index.tsx +++ b/packages/react-native-broadcast/src/index.tsx @@ -1,5 +1,5 @@ import Broadcast from './NativeBroadcast'; -export function multiply(a: number, b: number): number { +export function multiply(a: number, b: number): Promise { return Broadcast.multiply(a, b); } diff --git a/sample-apps/react-native/dogfood/App.tsx b/sample-apps/react-native/dogfood/App.tsx index 836e249e64..d5be503d68 100755 --- a/sample-apps/react-native/dogfood/App.tsx +++ b/sample-apps/react-native/dogfood/App.tsx @@ -88,7 +88,7 @@ const StackNavigator = () => { }, []); useEffect(() => { - console.log('OL: multiply', multiply(3, 7)); + multiply(3, 7).then((r) => console.log(`OL: multiply ${r}`)); }, []); let mode; diff --git a/sample-apps/react-native/dogfood/ios/Podfile.lock b/sample-apps/react-native/dogfood/ios/Podfile.lock index 42b47fe0d9..8f90358aca 100644 --- a/sample-apps/react-native/dogfood/ios/Podfile.lock +++ b/sample-apps/react-native/dogfood/ios/Podfile.lock @@ -3497,7 +3497,7 @@ SPEC CHECKSUMS: stream-io-video-filters-react-native: 1336c7f604d99d452817b90828389f47771f9417 stream-react-native-webrtc: 460795039c3aa0c83c882fe2cc59f5ebae3f6a18 stream-video-react-native: 76f36e8801910cbc5a0f909a75cef826b699ad23 - StreamReactNativeBroadcast: a86749beea3b9faee4eaeced64d343dab58311aa + StreamReactNativeBroadcast: 9146ff698f2413836314fbfcd267e25758b90964 StreamVideoNoiseCancellation: 41f5a712aba288f9636b64b17ebfbdff52c61490 StreamWebRTC: a50ebd8beba4def8f4e378b4895824c3520f9889 VisionCamera: 891edb31806dd3a239c8a9d6090d6ec78e11ee80 diff --git a/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj b/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj index 32a6a68855..d64f1b6204 100644 --- a/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj +++ b/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj @@ -8,7 +8,7 @@ /* Begin PBXBuildFile section */ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; - 4D2CFA4A1D21793DD346776C /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + 4D2CFA4A1D21793DD346776C /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; 4D971DCC2E57B61BFEDC0B7D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 88BB23A1BB898D9683DCB129 /* PrivacyInfo.xcprivacy */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 971245789A3DE3BC5BE05B7A /* Pods_StreamReactNativeVideoSDKSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EE5915852699CCF75559F04 /* Pods_StreamReactNativeVideoSDKSample.framework */; }; @@ -107,7 +107,7 @@ files = ( DD6FC6042987E2E800B13B16 /* CallKit.framework in Frameworks */, DD6FC6022987E2D700B13B16 /* Intents.framework in Frameworks */, - 4D2CFA4A1D21793DD346776C /* (null) in Frameworks */, + 4D2CFA4A1D21793DD346776C /* BuildFile in Frameworks */, 971245789A3DE3BC5BE05B7A /* Pods_StreamReactNativeVideoSDKSample.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; From e2559f8259d9863c309b88dfc1c1a1ff11bff808 Mon Sep 17 00:00:00 2001 From: Oliver Lazoroski Date: Mon, 20 Oct 2025 17:51:24 +0200 Subject: [PATCH 03/22] wip --- packages/react-native-broadcast/ios/Broadcast.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/react-native-broadcast/ios/Broadcast.swift b/packages/react-native-broadcast/ios/Broadcast.swift index 8354969a9d..6bbb2b8fe1 100644 --- a/packages/react-native-broadcast/ios/Broadcast.swift +++ b/packages/react-native-broadcast/ios/Broadcast.swift @@ -25,8 +25,8 @@ public class BroadcastSwift: NSObject { try? await mixer.configuration(video: 0) { video in try? video.setFrameRate(30) } - - + + await mixer.setMonitoringEnabled(true) print("[RTMP] Mixer created") @@ -37,13 +37,14 @@ public class BroadcastSwift: NSObject { await mixer.stopCapturing() let front = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) - try? await mixer.attachVideo(front, track: 0) { unit in unit.isVideoMirrored = true } + try? await mixer.attachVideo(front) { unit in unit.isVideoMirrored = true } let mic = AVCaptureDevice.default(for: .audio) try? await mixer.attachAudio(mic); - await mixer.startRunning() + // Start capturing first, then running await mixer.startCapturing() + await mixer.startRunning() print("[RTMP] Mixer configured") @@ -74,6 +75,7 @@ public class BroadcastSwift: NSObject { print("[RTMP] session connected") } + print("[RTMP] connection established successfully") completion(NSNumber(value: a * b), nil) } catch { print("[RTMP] error", error) From a2499a8da9be24b814d0a3b03a9302de7a5bb866 Mon Sep 17 00:00:00 2001 From: Oliver Lazoroski Date: Tue, 21 Oct 2025 10:54:21 +0200 Subject: [PATCH 04/22] make publishing work --- .../ios/Broadcast.swift | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/packages/react-native-broadcast/ios/Broadcast.swift b/packages/react-native-broadcast/ios/Broadcast.swift index 6bbb2b8fe1..f56451d8b3 100644 --- a/packages/react-native-broadcast/ios/Broadcast.swift +++ b/packages/react-native-broadcast/ios/Broadcast.swift @@ -8,74 +8,71 @@ public class BroadcastSwift: NSObject { @objc public static func multiply(_ a: Double, b: Double, completion: @escaping (NSNumber?, NSError?) -> Void) { - let uri = "rtmps://ingress.stream-io-video.com:443/par8f5s3gn2j.default.RdcC9Qr4j7pzr62FZbo8N/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3Byb250by5nZXRzdHJlYW0uaW8iLCJzdWIiOiJ1c2VyL2phbmUiLCJ1c2VyX2lkIjoiamFuZSIsInZhbGlkaXR5X2luX3NlY29uZHMiOjYwNDgwMCwiZW52aXJvbm1lbnQiOiJwcm9udG8iLCJpYXQiOjE3NjA5NzM3OTcsImV4cCI6MTc2MTU3ODU5N30.SlaGVdXvSWiGFf_Bx8GcIekRj4H71hNPRQynJkR6P5c" - - print("RTMP begin publishing") + let uri = "rtmps://ingress.stream-io-video.com:443/par8f5s3gn2j.default.RdcC9Qr4j7pzr62FZbo8Q/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3Byb250by5nZXRzdHJlYW0uaW8iLCJzdWIiOiJ1c2VyL2phbmUiLCJ1c2VyX2lkIjoiamFuZSIsInZhbGlkaXR5X2luX3NlY29uZHMiOjYwNDgwMCwiZW52aXJvbm1lbnQiOiJwcm9udG8iLCJpYXQiOjE3NjA5Njc0MzMsImV4cCI6MTc2MTU3MjIzM30.pkBwlOMlo7wUJG4DSG7fk8QAxF912Y5UaErm4H6a59I" + print("[RTMP] Broadcast starting") + Task { do { let audioSourceService = AudioSourceService() await audioSourceService.setUp() + + print("[RTMP] Audio source created") let mixer = MediaMixer(captureSessionMode: .single) await mixer.configuration { session in session.automaticallyConfiguresApplicationAudioSession = false session.sessionPreset = .hd1280x720 } - try? await mixer.configuration(video: 0) { video in - try? video.setFrameRate(30) - } - - await mixer.setMonitoringEnabled(true) - print("[RTMP] Mixer created") - + var videoMixerSettings = await mixer.videoMixerSettings videoMixerSettings.mode = .offscreen await mixer.setVideoMixerSettings(videoMixerSettings) - - await mixer.stopCapturing() + + print("[RTMP] Mixer created") let front = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) - try? await mixer.attachVideo(front) { unit in unit.isVideoMirrored = true } - + try? await mixer.attachVideo(front, track: 0) { unit in unit.isVideoMirrored = true } + let mic = AVCaptureDevice.default(for: .audio) - try? await mixer.attachAudio(mic); + try? await mixer.attachAudio(mic) - // Start capturing first, then running await mixer.startCapturing() await mixer.startRunning() - - print("[RTMP] Mixer configured") - + + print("[RTMP] Mixer running") + await SessionBuilderFactory.shared.register(RTMPSessionFactory()) let session = try await SessionBuilderFactory.shared.make(URL(string: uri)) .setMode(.publish) .build() guard let session else { - print("[RTMP] failed to create a session") + print("[RTMP] session is null") return completion(-1, nil) } - - print("[RTMP] session created") + + print("[RTMP] Session created") await mixer.addOutput(session.stream) - + var audioSettings = await session.stream.audioSettings audioSettings.format = .aac + audioSettings.bitRate = 48000 try await session.stream.setAudioSettings(audioSettings) var videoSettings = await session.stream.videoSettings videoSettings.isLowLatencyRateControlEnabled = false + videoSettings.bitRateMode = .average +// videoSettings.bitRate = 4000000 videoSettings.videoSize = CGSize(width: 720, height: 1280) try await session.stream.setVideoSettings(videoSettings) - print("[RTMP] session connecting") + print("[RTMP] Session connecting") try await session.connect { - print("[RTMP] session connected") + print("[RTMP] Session connected") } - print("[RTMP] connection established successfully") completion(NSNumber(value: a * b), nil) } catch { print("[RTMP] error", error) From 863d67787d1164eb966c6e5c80be01b3f7646b8d Mon Sep 17 00:00:00 2001 From: Oliver Lazoroski Date: Tue, 21 Oct 2025 11:01:13 +0200 Subject: [PATCH 05/22] increase bitrate --- packages/react-native-broadcast/ios/Broadcast.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-broadcast/ios/Broadcast.swift b/packages/react-native-broadcast/ios/Broadcast.swift index f56451d8b3..efa6a9f55f 100644 --- a/packages/react-native-broadcast/ios/Broadcast.swift +++ b/packages/react-native-broadcast/ios/Broadcast.swift @@ -64,7 +64,7 @@ public class BroadcastSwift: NSObject { var videoSettings = await session.stream.videoSettings videoSettings.isLowLatencyRateControlEnabled = false videoSettings.bitRateMode = .average -// videoSettings.bitRate = 4000000 + videoSettings.bitRate = 4200000 videoSettings.videoSize = CGSize(width: 720, height: 1280) try await session.stream.setVideoSettings(videoSettings) From ebe3967346177e1d00e62409e6a5b5cbf61733e5 Mon Sep 17 00:00:00 2001 From: Oliver Lazoroski Date: Tue, 21 Oct 2025 15:00:43 +0200 Subject: [PATCH 06/22] simplify session creation, use reasonable bitrate --- .../ios/Broadcast.swift | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/packages/react-native-broadcast/ios/Broadcast.swift b/packages/react-native-broadcast/ios/Broadcast.swift index efa6a9f55f..b77970a1b9 100644 --- a/packages/react-native-broadcast/ios/Broadcast.swift +++ b/packages/react-native-broadcast/ios/Broadcast.swift @@ -11,12 +11,12 @@ public class BroadcastSwift: NSObject { let uri = "rtmps://ingress.stream-io-video.com:443/par8f5s3gn2j.default.RdcC9Qr4j7pzr62FZbo8Q/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3Byb250by5nZXRzdHJlYW0uaW8iLCJzdWIiOiJ1c2VyL2phbmUiLCJ1c2VyX2lkIjoiamFuZSIsInZhbGlkaXR5X2luX3NlY29uZHMiOjYwNDgwMCwiZW52aXJvbm1lbnQiOiJwcm9udG8iLCJpYXQiOjE3NjA5Njc0MzMsImV4cCI6MTc2MTU3MjIzM30.pkBwlOMlo7wUJG4DSG7fk8QAxF912Y5UaErm4H6a59I" print("[RTMP] Broadcast starting") - + Task { do { let audioSourceService = AudioSourceService() await audioSourceService.setUp() - + print("[RTMP] Audio source created") let mixer = MediaMixer(captureSessionMode: .single) @@ -25,37 +25,31 @@ public class BroadcastSwift: NSObject { session.sessionPreset = .hd1280x720 } await mixer.setMonitoringEnabled(true) - + var videoMixerSettings = await mixer.videoMixerSettings videoMixerSettings.mode = .offscreen await mixer.setVideoMixerSettings(videoMixerSettings) - + print("[RTMP] Mixer created") let front = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) try? await mixer.attachVideo(front, track: 0) { unit in unit.isVideoMirrored = true } - + let mic = AVCaptureDevice.default(for: .audio) try? await mixer.attachAudio(mic) await mixer.startCapturing() await mixer.startRunning() - + print("[RTMP] Mixer running") - - await SessionBuilderFactory.shared.register(RTMPSessionFactory()) - let session = try await SessionBuilderFactory.shared.make(URL(string: uri)) - .setMode(.publish) - .build() - guard let session else { - print("[RTMP] session is null") - return completion(-1, nil) - } - + + let factory = RTMPSessionFactory.init() + let session = factory.make(URL(string: uri)!, mode: .publish, configuration: nil) + print("[RTMP] Session created") await mixer.addOutput(session.stream) - + var audioSettings = await session.stream.audioSettings audioSettings.format = .aac audioSettings.bitRate = 48000 @@ -64,7 +58,7 @@ public class BroadcastSwift: NSObject { var videoSettings = await session.stream.videoSettings videoSettings.isLowLatencyRateControlEnabled = false videoSettings.bitRateMode = .average - videoSettings.bitRate = 4200000 + videoSettings.bitRate = 2500000 videoSettings.videoSize = CGSize(width: 720, height: 1280) try await session.stream.setVideoSettings(videoSettings) From d5800dc6e97fbeac0a9e034e28437d3a80eed7ab Mon Sep 17 00:00:00 2001 From: Oliver Lazoroski Date: Tue, 21 Oct 2025 17:22:34 +0200 Subject: [PATCH 07/22] add native view for local video --- packages/react-native-broadcast/README.md | 45 +++- .../ios/Broadcast.swift | 17 ++ .../ios/BroadcastVideoView.swift | 65 ++++++ .../ios/BroadcastVideoViewManager.m | 6 + .../ios/BroadcastVideoViewManager.swift | 17 ++ .../src/BroadcastVideoView.tsx | 16 ++ packages/react-native-broadcast/src/index.tsx | 3 + sample-apps/react-native/dogfood/App.tsx | 15 +- .../dogfood/src/contexts/AppContext.tsx | 8 +- .../dogfood/src/navigators/RTMP.tsx | 18 ++ .../src/screens/ChooseAppModeScreen.tsx | 9 + .../src/screens/RTMPBroadcastScreen.tsx | 203 ++++++++++++++++++ sample-apps/react-native/dogfood/types.ts | 5 + 13 files changed, 417 insertions(+), 10 deletions(-) create mode 100644 packages/react-native-broadcast/ios/BroadcastVideoView.swift create mode 100644 packages/react-native-broadcast/ios/BroadcastVideoViewManager.m create mode 100644 packages/react-native-broadcast/ios/BroadcastVideoViewManager.swift create mode 100644 packages/react-native-broadcast/src/BroadcastVideoView.tsx create mode 100644 sample-apps/react-native/dogfood/src/navigators/RTMP.tsx create mode 100644 sample-apps/react-native/dogfood/src/screens/RTMPBroadcastScreen.tsx diff --git a/packages/react-native-broadcast/README.md b/packages/react-native-broadcast/README.md index 12239b2baa..784f012f08 100644 --- a/packages/react-native-broadcast/README.md +++ b/packages/react-native-broadcast/README.md @@ -10,14 +10,51 @@ npm install react-native-broadcast ## Usage -```js -import { multiply } from 'react-native-broadcast'; +### BroadcastVideoView Component -// ... +Display the local video preview from the broadcast mixer: -const result = multiply(3, 7); +```tsx +import { BroadcastVideoView, multiply } from 'react-native-broadcast'; +import { View, StyleSheet, Button } from 'react-native'; + +function App() { + const startBroadcast = async () => { + // This will initialize the mixer and start the RTMP broadcast + await multiply(3, 7); + }; + + return ( + + +