react-native-rtmp-publisher icon indicating copy to clipboard operation
react-native-rtmp-publisher copied to clipboard

Added support for setting video settings, moved to pnpm, fixed 2nd stream reconnection

Open Andriiklymiuk opened this issue 1 year ago • 2 comments

In the MR I added:

  • setVideoSettings method, with which you can setup your needed video quality
  • videoSettings prop - does the same as setVideoSettings, but useful, when you need just default video setting
  • added fix for 2nd stream reconnection based on this one https://github.com/ezranbayantemur/react-native-rtmp-publisher/pull/35
  • added listener for CLOSED status (useful, when the stream closed and you need to listen to that and act accordingly)
  • added fix for green dot, when screen is unmounted, based on this one https://github.com/ezranbayantemur/react-native-rtmp-publisher/pull/36
  • changed yarn to pnpm, because it is faster and has autocomplete in it
  • added some useful scripts in the package.json to easy local testing of the library
  • fix styling for tsconfig

p.s. will publish separate library till these fixes are implemented (don't know if this library still supported)

Andriiklymiuk avatar Apr 14 '23 15:04 Andriiklymiuk

created react-native-publisher, till we are waiting for approval.

You can also use patch-package react-native-rtmp-publisher+0.4.7.patch with this library, if you don't want to use just another fork. Here it is

diff --git a/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift b/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
index 7538bf3..a897ef9 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
@@ -6,6 +6,14 @@
 //
 import HaishinKit
 import AVFoundation
+import VideoToolbox
+
+struct VideoSettingsType {
+    var width: Int
+    var height: Int
+    var bitrate: Int
+    var audioBitrate: Int
+}
 
 class RTMPCreator {
     public static let connection: RTMPConnection = RTMPConnection()
@@ -14,6 +22,12 @@ class RTMPCreator {
     private static var _streamUrl: String = ""
     private static var _streamName: String = ""
     public static var isStreaming: Bool = false
+    public static var videoSettings: VideoSettingsType = VideoSettingsType(
+        width: 720,
+        height: 1280,
+        bitrate: 3000 * 1024,
+        audioBitrate: 128 * 1000
+    )
 
     public static func setStreamUrl(url: String){
         _streamUrl = url
@@ -38,10 +52,24 @@ class RTMPCreator {
     public static func startPublish(){
         connection.requireNetworkFramework = true
         connection.connect(_streamUrl)
-        stream.publish(_streamName)
         isStreaming = true
     }
     
+    public static func setVideoSettings(_ newVideoSettings: VideoSettingsType) {
+        videoSettings = newVideoSettings
+        stream.videoSettings = [
+            .width: videoSettings.width,
+            .height: videoSettings.height,
+            .bitrate: videoSettings.bitrate,
+            .scalingMode: ScalingMode.cropSourceToCleanAperture,
+            .profileLevel: kVTProfileLevel_H264_High_AutoLevel
+        ]
+
+        RTMPCreator.stream.audioSettings = [
+            .bitrate: videoSettings.audioBitrate
+        ]
+    }
+  
     public static func stopPublish(){
         stream.close()
         connection.close()
diff --git a/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPView.swift b/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPView.swift
index 06276dd..f5c4592 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPView.swift
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPView.swift
@@ -8,6 +8,7 @@
 import UIKit
 import HaishinKit
 import AVFoundation
+import VideoToolbox
 
 class RTMPView: UIView {
   private var hkView: MTHKView!
@@ -30,6 +31,28 @@ class RTMPView: UIView {
     }
   }
   
+  @objc var videoSettings: NSDictionary = NSDictionary(
+      dictionary: [
+        "width": 720,
+        "height": 1280,
+        "bitrate": 3000 * 1000,
+        "audioBitrate": 192 * 1000
+      ]
+  ){
+    didSet {
+        let width = videoSettings["width"] as? Int ?? 720
+        let height = videoSettings["height"] as? Int ?? 1280
+        let bitrate = videoSettings["bitrate"] as? Int ?? (3000 * 1000)
+        let audioBitrate = videoSettings["audioBitrate"] as? Int ?? (192 * 1000)
+        
+        RTMPCreator.setVideoSettings(VideoSettingsType(width: width, height: height, bitrate: bitrate, audioBitrate: audioBitrate)
+        )
+    }
+  }
+    
+    private var retryCount: Int = 0
+    private static let maxRetryCount: Int = 10
+  
   override init(frame: CGRect) {
     super.init(frame: frame)
     UIApplication.shared.isIdleTimerDisabled = true
@@ -37,25 +60,30 @@ class RTMPView: UIView {
     hkView = MTHKView(frame: UIScreen.main.bounds)
     hkView.videoGravity = .resizeAspectFill
     
+    RTMPCreator.stream.audioSettings = [
+        .bitrate: RTMPCreator.videoSettings.audioBitrate
+    ]
+      
     RTMPCreator.stream.captureSettings = [
-        .fps: 30,
-        .sessionPreset: AVCaptureSession.Preset.hd1920x1080,
-        .continuousAutofocus: true,
-        .continuousExposure: true
+      .fps: 30,
+      .sessionPreset: AVCaptureSession.Preset.hd1920x1080,
+      .continuousAutofocus: true,
+      .continuousExposure: true,
     ]
 
     RTMPCreator.stream.videoSettings = [
-        .width: 720,
-        .height: 1280,
-        .bitrate: 3000 * 1024,
-        .scalingMode: ScalingMode.cropSourceToCleanAperture
-        
+      .width: RTMPCreator.videoSettings.width,
+      .height: RTMPCreator.videoSettings.height,
+      .bitrate: RTMPCreator.videoSettings.bitrate,
+      .scalingMode: ScalingMode.cropSourceToCleanAperture,
+      .profileLevel: kVTProfileLevel_H264_High_AutoLevel
     ]
 
     RTMPCreator.stream.attachAudio(AVCaptureDevice.default(for: .audio))
-    RTMPCreator.stream.attachCamera(DeviceUtil.device(withPosition: AVCaptureDevice.Position.back))
+    RTMPCreator.stream.attachCamera(AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back))
 
     RTMPCreator.connection.addEventListener(.rtmpStatus, selector: #selector(statusHandler), observer: self)
+    RTMPCreator.connection.addEventListener(.ioError, selector: #selector(rtmpErrorHandler), observer: self)
 
     hkView.attachStream(RTMPCreator.stream)
 
@@ -63,13 +91,22 @@ class RTMPView: UIView {
       
 }
     
+    @objc
+    private func rtmpErrorHandler(_ notification: Notification) {
+        print("rtmpErrorHandler", notification)
+
+        changeStreamState(status: "I/O ERROR")
+        RTMPCreator.connection.connect(streamURL as String)
+    }
+    
     required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
      }
     
     override func removeFromSuperview() {
-        print("ON REMOVE")
-    }
+        RTMPCreator.stream.attachAudio(nil)
+        RTMPCreator.stream.attachCamera(nil)
+     }
   
     @objc
     private func statusHandler(_ notification: Notification){
@@ -83,7 +120,9 @@ class RTMPView: UIView {
          if onConnectionSuccess != nil {
               onConnectionSuccess!(nil)
             }
+           retryCount = 0
            changeStreamState(status: "CONNECTING")
+           RTMPCreator.stream.publish(streamName as String)
            break
        
        case RTMPConnection.Code.connectFailed.rawValue:
@@ -91,12 +130,15 @@ class RTMPView: UIView {
               onConnectionFailed!(nil)
             }
            changeStreamState(status: "FAILED")
+           reconnect()
            break
          
        case RTMPConnection.Code.connectClosed.rawValue:
          if onDisconnect != nil {
               onDisconnect!(nil)
             }
+           changeStreamState(status: "CLOSED")
+           reconnect()
            break
          
        case RTMPStream.Code.publishStart.rawValue:
@@ -107,10 +149,20 @@ class RTMPView: UIView {
            break
          
        default:
+           changeStreamState(status: code)
            break
        }
     }
     
+    public func reconnect(){
+        guard retryCount <= RTMPView.maxRetryCount else {
+         return
+        }
+        Thread.sleep(forTimeInterval: pow(2.0, Double(retryCount)))
+        RTMPCreator.connection.connect(streamURL as String)
+        retryCount += 1
+    }
+
     public func changeStreamState(status: String){
       if onStreamStateChanged != nil {
         onStreamStateChanged!(["data": status])
diff --git a/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPViewManager.m b/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPViewManager.m
index de3f5bc..1351444 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPViewManager.m
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPViewManager.m
@@ -18,6 +18,8 @@ RCT_EXPORT_VIEW_PROPERTY(streamURL, NSString)
 
 RCT_EXPORT_VIEW_PROPERTY(streamName, NSString)
 
+RCT_EXPORT_VIEW_PROPERTY(videoSettings, NSDictionary)
+
 RCT_EXPORT_VIEW_PROPERTY(onDisconnect, RCTDirectEventBlock)
 
 RCT_EXPORT_VIEW_PROPERTY(onConnectionFailed, RCTDirectEventBlock)
diff --git a/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.m b/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.m
index b29a6f7..da37b37 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.m
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.m
@@ -81,4 +81,10 @@ RCT_EXTERN_METHOD(
                     reject: (RCTPromiseRejectBlock)reject
                   )
 
+RCT_EXTERN_METHOD(
+                    setVideoSettings: (NSDictionary *)videoSettings
+                    resolve: (RCTPromiseResolveBlock)resolve
+                    reject: (RCTPromiseRejectBlock)reject
+                  )
+
 @end
diff --git a/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.swift b/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.swift
index d346b74..04e0da0 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.swift
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.swift
@@ -20,6 +20,21 @@ class RTMPModule: NSObject {
         RTMPCreator.startPublish()
     }
 
+    @objc
+    func setVideoSettings(_ videoSettingsDict: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
+        guard let width = videoSettingsDict["width"] as? Int,
+              let height = videoSettingsDict["height"] as? Int,
+              let bitrate = videoSettingsDict["bitrate"] as? Int else {
+            reject("INVALID_ARGUMENTS", "Invalid video settings", nil)
+            return
+        }
+        let audioBitrate = videoSettingsDict["audioBitrate"] as? Int ?? 128000
+        let videoSettings = VideoSettingsType(width: width, height: height, bitrate: bitrate, audioBitrate: audioBitrate)
+        
+        resolve(RTMPCreator.setVideoSettings(videoSettings))
+    }
+
+
     @objc
     func stopStream(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
         RTMPCreator.stopPublish()
@@ -38,7 +53,13 @@ class RTMPModule: NSObject {
     @objc
     func switchCamera(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
         cameraPosition = cameraPosition == .back ? .front : .back
-        RTMPCreator.stream.attachCamera(DeviceUtil.device(withPosition: cameraPosition))
+        
+        RTMPCreator.stream.captureSettings = [
+            .isVideoMirrored: cameraPosition == .back ? false : true
+        ]
+        RTMPCreator.stream.attachCamera(
+            AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: cameraPosition)
+        )
     }
 
     @objc
diff --git a/node_modules/react-native-rtmp-publisher/lib/commonjs/Component.js.map b/node_modules/react-native-rtmp-publisher/lib/commonjs/Component.js.map
index 550b862..a2c27af 100644
--- a/node_modules/react-native-rtmp-publisher/lib/commonjs/Component.js.map
+++ b/node_modules/react-native-rtmp-publisher/lib/commonjs/Component.js.map
@@ -1 +1 @@
-{"version":3,"sources":["Component.tsx"],"names":[],"mappings":";;;;;;;AAAA;;eAkCe,yCACb,eADa,C","sourcesContent":["import {\n  NativeSyntheticEvent,\n  requireNativeComponent,\n  ViewStyle,\n} from 'react-native';\nimport type { StreamState, BluetoothDeviceStatuses } from './types';\n\ntype RTMPData<T> = { data: T };\n\nexport type ConnectionFailedType = NativeSyntheticEvent<RTMPData<string>>;\nexport type ConnectionStartedType = NativeSyntheticEvent<RTMPData<string>>;\nexport type ConnectionSuccessType = NativeSyntheticEvent<RTMPData<null>>;\nexport type DisconnectType = NativeSyntheticEvent<RTMPData<null>>;\nexport type NewBitrateReceivedType = NativeSyntheticEvent<RTMPData<number>>;\nexport type StreamStateChangedType = NativeSyntheticEvent<\n  RTMPData<StreamState>\n>;\nexport type BluetoothDeviceStatusChangedType = NativeSyntheticEvent<\n  RTMPData<BluetoothDeviceStatuses>\n>;\nexport interface NativeRTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  onConnectionFailed?: (e: ConnectionFailedType) => void;\n  onConnectionStarted?: (e: ConnectionStartedType) => void;\n  onConnectionSuccess?: (e: ConnectionSuccessType) => void;\n  onDisconnect?: (e: DisconnectType) => void;\n  onNewBitrateReceived?: (e: NewBitrateReceivedType) => void;\n  onStreamStateChanged?: (e: StreamStateChangedType) => void;\n  onBluetoothDeviceStatusChanged?: (\n    e: BluetoothDeviceStatusChangedType\n  ) => void;\n}\nexport default requireNativeComponent<NativeRTMPPublisherProps>(\n  'RTMPPublisher'\n);\n"]}
\ No newline at end of file
+{"version":3,"sources":["Component.tsx"],"names":[],"mappings":";;;;;;;AAAA;;eAuCe,yCACb,eADa,C","sourcesContent":["import {\n  NativeSyntheticEvent,\n  requireNativeComponent,\n  ViewStyle,\n} from 'react-native';\nimport type {\n  StreamState,\n  BluetoothDeviceStatuses,\n  VideoSettingsType,\n} from './types';\n\ntype RTMPData<T> = { data: T };\n\nexport type ConnectionFailedType = NativeSyntheticEvent<RTMPData<string>>;\nexport type ConnectionStartedType = NativeSyntheticEvent<RTMPData<string>>;\nexport type ConnectionSuccessType = NativeSyntheticEvent<RTMPData<null>>;\nexport type DisconnectType = NativeSyntheticEvent<RTMPData<null>>;\nexport type NewBitrateReceivedType = NativeSyntheticEvent<RTMPData<number>>;\nexport type StreamStateChangedType = NativeSyntheticEvent<\n  RTMPData<StreamState>\n>;\nexport type BluetoothDeviceStatusChangedType = NativeSyntheticEvent<\n  RTMPData<BluetoothDeviceStatuses>\n>;\nexport interface NativeRTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  videoSettings?: VideoSettingsType;\n  onConnectionFailed?: (e: ConnectionFailedType) => void;\n  onConnectionStarted?: (e: ConnectionStartedType) => void;\n  onConnectionSuccess?: (e: ConnectionSuccessType) => void;\n  onDisconnect?: (e: DisconnectType) => void;\n  onNewBitrateReceived?: (e: NewBitrateReceivedType) => void;\n  onStreamStateChanged?: (e: StreamStateChangedType) => void;\n  onBluetoothDeviceStatusChanged?: (\n    e: BluetoothDeviceStatusChangedType\n  ) => void;\n}\nexport default requireNativeComponent<NativeRTMPPublisherProps>(\n  'RTMPPublisher'\n);\n"]}
\ No newline at end of file
diff --git a/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js b/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js
index e456074..c016d55 100644
--- a/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js
+++ b/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js
@@ -60,6 +60,8 @@ const RTMPPublisher = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
 
   const setAudioInput = audioInput => RTMPModule.setAudioInput(audioInput);
 
+  const setVideoSettings = async videoSettings => RTMPModule.setVideoSettings(videoSettings);
+
   const handleOnConnectionFailed = e => {
     onConnectionFailed && onConnectionFailed(e.nativeEvent.data);
   };
@@ -102,7 +104,8 @@ const RTMPPublisher = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
     unmute,
     switchCamera,
     toggleFlash,
-    setAudioInput
+    setAudioInput,
+    setVideoSettings
   }));
   return /*#__PURE__*/_react.default.createElement(_Component.default, _extends({}, props, {
     onDisconnect: handleOnDisconnect,
diff --git a/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js.map b/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js.map
index b9e167c..482eee9 100644
--- a/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js.map
+++ b/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js.map
@@ -1 +1 @@
-{"version":3,"sources":["RTMPPublisher.tsx"],"names":["RTMPModule","NativeModules","RTMPPublisher","ref","onConnectionFailed","onConnectionStarted","onConnectionSuccess","onDisconnect","onNewBitrateReceived","onStreamStateChanged","onBluetoothDeviceStatusChanged","props","startStream","stopStream","isStreaming","isCameraOnPreview","getPublishURL","hasCongestion","isAudioPrepared","isVideoPrepared","isMuted","mute","unmute","switchCamera","toggleFlash","setAudioInput","audioInput","handleOnConnectionFailed","e","nativeEvent","data","handleOnConnectionStarted","handleOnConnectionSuccess","handleOnDisconnect","handleOnNewBitrateReceived","handleOnStreamStateChanged","handleBluetoothDeviceStatusChanged"],"mappings":"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","sourcesContent":["import React, { forwardRef, useImperativeHandle } from 'react';\nimport { NativeModules, ViewStyle } from 'react-native';\nimport PublisherComponent, {\n  DisconnectType,\n  ConnectionFailedType,\n  ConnectionStartedType,\n  ConnectionSuccessType,\n  NewBitrateReceivedType,\n  StreamStateChangedType,\n  BluetoothDeviceStatusChangedType,\n} from './Component';\nimport type {\n  RTMPPublisherRefProps,\n  StreamState,\n  BluetoothDeviceStatuses,\n  AudioInputType,\n} from './types';\n\nconst RTMPModule = NativeModules.RTMPPublisher;\nexport interface RTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  /**\n   * Callback for connection fails on RTMP server\n   */\n  onConnectionFailed?: (data: string) => void;\n  /**\n   * Callback for starting connection to RTMP server\n   */\n  onConnectionStarted?: (data: string) => void;\n  /**\n   * Callback for connection successfully to RTMP server\n   */\n  onConnectionSuccess?: (data: null) => void;\n  /**\n   * Callback for disconnect successfully to RTMP server\n   */\n  onDisconnect?: (data: null) => void;\n  /**\n   * Callback for receiving new bitrate value about stream\n   */\n  onNewBitrateReceived?: (data: number) => void;\n  /**\n   * Alternatively callback for changing stream state\n   * Returns parameter StreamState type\n   */\n  onStreamStateChanged?: (data: StreamState) => void;\n  /**\n   * Callback for bluetooth device connection changes\n   */\n  onBluetoothDeviceStatusChanged?: (data: BluetoothDeviceStatuses) => void;\n}\n\nconst RTMPPublisher = forwardRef<RTMPPublisherRefProps, RTMPPublisherProps>(\n  (\n    {\n      onConnectionFailed,\n      onConnectionStarted,\n      onConnectionSuccess,\n      onDisconnect,\n      onNewBitrateReceived,\n      onStreamStateChanged,\n      onBluetoothDeviceStatusChanged,\n      ...props\n    },\n    ref\n  ) => {\n    const startStream = async () => await RTMPModule.startStream();\n\n    const stopStream = async () => await RTMPModule.stopStream();\n\n    const isStreaming = async () => RTMPModule.isStreaming();\n\n    const isCameraOnPreview = async () => RTMPModule.isCameraOnPreview();\n\n    const getPublishURL = async () => RTMPModule.getPublishURL();\n\n    const hasCongestion = async () => RTMPModule.hasCongestion();\n\n    const isAudioPrepared = async () => RTMPModule.isAudioPrepared();\n\n    const isVideoPrepared = async () => RTMPModule.isVideoPrepared();\n\n    const isMuted = async () => RTMPModule.isMuted();\n\n    const mute = () => RTMPModule.mute();\n\n    const unmute = () => RTMPModule.unmute();\n\n    const switchCamera = () => RTMPModule.switchCamera();\n\n    const toggleFlash = () => RTMPModule.toggleFlash();\n\n    const setAudioInput = (audioInput: AudioInputType) =>\n      RTMPModule.setAudioInput(audioInput);\n\n    const handleOnConnectionFailed = (e: ConnectionFailedType) => {\n      onConnectionFailed && onConnectionFailed(e.nativeEvent.data);\n    };\n\n    const handleOnConnectionStarted = (e: ConnectionStartedType) => {\n      onConnectionStarted && onConnectionStarted(e.nativeEvent.data);\n    };\n\n    const handleOnConnectionSuccess = (e: ConnectionSuccessType) => {\n      onConnectionSuccess && onConnectionSuccess(e.nativeEvent.data);\n    };\n\n    const handleOnDisconnect = (e: DisconnectType) => {\n      onDisconnect && onDisconnect(e.nativeEvent.data);\n    };\n\n    const handleOnNewBitrateReceived = (e: NewBitrateReceivedType) => {\n      onNewBitrateReceived && onNewBitrateReceived(e.nativeEvent.data);\n    };\n\n    const handleOnStreamStateChanged = (e: StreamStateChangedType) => {\n      onStreamStateChanged && onStreamStateChanged(e.nativeEvent.data);\n    };\n\n    const handleBluetoothDeviceStatusChanged = (\n      e: BluetoothDeviceStatusChangedType\n    ) => {\n      onBluetoothDeviceStatusChanged &&\n        onBluetoothDeviceStatusChanged(e.nativeEvent.data);\n    };\n\n    useImperativeHandle(ref, () => ({\n      startStream,\n      stopStream,\n      isStreaming,\n      isCameraOnPreview,\n      getPublishURL,\n      hasCongestion,\n      isAudioPrepared,\n      isVideoPrepared,\n      isMuted,\n      mute,\n      unmute,\n      switchCamera,\n      toggleFlash,\n      setAudioInput,\n    }));\n\n    return (\n      <PublisherComponent\n        {...props}\n        onDisconnect={handleOnDisconnect}\n        onConnectionFailed={handleOnConnectionFailed}\n        onConnectionStarted={handleOnConnectionStarted}\n        onConnectionSuccess={handleOnConnectionSuccess}\n        onNewBitrateReceived={handleOnNewBitrateReceived}\n        onStreamStateChanged={handleOnStreamStateChanged}\n        onBluetoothDeviceStatusChanged={handleBluetoothDeviceStatusChanged}\n      />\n    );\n  }\n);\n\nexport default RTMPPublisher;\n"]}
\ No newline at end of file
+{"version":3,"sources":["RTMPPublisher.tsx"],"names":["RTMPModule","NativeModules","RTMPPublisher","ref","onConnectionFailed","onConnectionStarted","onConnectionSuccess","onDisconnect","onNewBitrateReceived","onStreamStateChanged","onBluetoothDeviceStatusChanged","props","startStream","stopStream","isStreaming","isCameraOnPreview","getPublishURL","hasCongestion","isAudioPrepared","isVideoPrepared","isMuted","mute","unmute","switchCamera","toggleFlash","setAudioInput","audioInput","setVideoSettings","videoSettings","handleOnConnectionFailed","e","nativeEvent","data","handleOnConnectionStarted","handleOnConnectionSuccess","handleOnDisconnect","handleOnNewBitrateReceived","handleOnStreamStateChanged","handleBluetoothDeviceStatusChanged"],"mappings":"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","sourcesContent":["import React, { forwardRef, useImperativeHandle } from 'react';\nimport { NativeModules, type ViewStyle } from 'react-native';\nimport PublisherComponent, {\n  type DisconnectType,\n  type ConnectionFailedType,\n  type ConnectionStartedType,\n  type ConnectionSuccessType,\n  type NewBitrateReceivedType,\n  type StreamStateChangedType,\n  type BluetoothDeviceStatusChangedType,\n} from './Component';\nimport type {\n  RTMPPublisherRefProps,\n  StreamState,\n  BluetoothDeviceStatuses,\n  AudioInputType,\n  VideoSettingsType,\n} from './types';\n\nconst RTMPModule = NativeModules.RTMPPublisher;\nexport interface RTMPPublisherProps {\n  testID?: string;\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  /**\n   * Video settings for video\n   */\n  videoSettings?: VideoSettingsType;\n  /**\n   * Callback for connection fails on RTMP server\n   */\n  onConnectionFailed?: (data: string) => void;\n  /**\n   * Callback for starting connection to RTMP server\n   */\n  onConnectionStarted?: (data: string) => void;\n  /**\n   * Callback for connection successfully to RTMP server\n   */\n  onConnectionSuccess?: (data: null) => void;\n  /**\n   * Callback for disconnect successfully to RTMP server\n   */\n  onDisconnect?: (data: null) => void;\n  /**\n   * Callback for receiving new bitrate value about stream\n   */\n  onNewBitrateReceived?: (data: number) => void;\n  /**\n   * Alternatively callback for changing stream state\n   * Returns parameter StreamState type\n   */\n  onStreamStateChanged?: (data: StreamState) => void;\n  /**\n   * Callback for bluetooth device connection changes\n   */\n  onBluetoothDeviceStatusChanged?: (data: BluetoothDeviceStatuses) => void;\n}\n\nconst RTMPPublisher = forwardRef<RTMPPublisherRefProps, RTMPPublisherProps>(\n  (\n    {\n      onConnectionFailed,\n      onConnectionStarted,\n      onConnectionSuccess,\n      onDisconnect,\n      onNewBitrateReceived,\n      onStreamStateChanged,\n      onBluetoothDeviceStatusChanged,\n      ...props\n    },\n    ref\n  ) => {\n    const startStream = async () => await RTMPModule.startStream();\n\n    const stopStream = async () => await RTMPModule.stopStream();\n\n    const isStreaming = async () => RTMPModule.isStreaming();\n\n    const isCameraOnPreview = async () => RTMPModule.isCameraOnPreview();\n\n    const getPublishURL = async () => RTMPModule.getPublishURL();\n\n    const hasCongestion = async () => RTMPModule.hasCongestion();\n\n    const isAudioPrepared = async () => RTMPModule.isAudioPrepared();\n\n    const isVideoPrepared = async () => RTMPModule.isVideoPrepared();\n\n    const isMuted = async () => RTMPModule.isMuted();\n\n    const mute = () => RTMPModule.mute();\n\n    const unmute = () => RTMPModule.unmute();\n\n    const switchCamera = () => RTMPModule.switchCamera();\n\n    const toggleFlash = () => RTMPModule.toggleFlash();\n\n    const setAudioInput = (audioInput: AudioInputType) =>\n      RTMPModule.setAudioInput(audioInput);\n\n    const setVideoSettings = async (videoSettings: VideoSettingsType) =>\n      RTMPModule.setVideoSettings(videoSettings);\n\n    const handleOnConnectionFailed = (e: ConnectionFailedType) => {\n      onConnectionFailed && onConnectionFailed(e.nativeEvent.data);\n    };\n\n    const handleOnConnectionStarted = (e: ConnectionStartedType) => {\n      onConnectionStarted && onConnectionStarted(e.nativeEvent.data);\n    };\n\n    const handleOnConnectionSuccess = (e: ConnectionSuccessType) => {\n      onConnectionSuccess && onConnectionSuccess(e.nativeEvent.data);\n    };\n\n    const handleOnDisconnect = (e: DisconnectType) => {\n      onDisconnect && onDisconnect(e.nativeEvent.data);\n    };\n\n    const handleOnNewBitrateReceived = (e: NewBitrateReceivedType) => {\n      onNewBitrateReceived && onNewBitrateReceived(e.nativeEvent.data);\n    };\n\n    const handleOnStreamStateChanged = (e: StreamStateChangedType) => {\n      onStreamStateChanged && onStreamStateChanged(e.nativeEvent.data);\n    };\n\n    const handleBluetoothDeviceStatusChanged = (\n      e: BluetoothDeviceStatusChangedType\n    ) => {\n      onBluetoothDeviceStatusChanged &&\n        onBluetoothDeviceStatusChanged(e.nativeEvent.data);\n    };\n\n    useImperativeHandle(ref, () => ({\n      startStream,\n      stopStream,\n      isStreaming,\n      isCameraOnPreview,\n      getPublishURL,\n      hasCongestion,\n      isAudioPrepared,\n      isVideoPrepared,\n      isMuted,\n      mute,\n      unmute,\n      switchCamera,\n      toggleFlash,\n      setAudioInput,\n      setVideoSettings,\n    }));\n\n    return (\n      <PublisherComponent\n        {...props}\n        onDisconnect={handleOnDisconnect}\n        onConnectionFailed={handleOnConnectionFailed}\n        onConnectionStarted={handleOnConnectionStarted}\n        onConnectionSuccess={handleOnConnectionSuccess}\n        onNewBitrateReceived={handleOnNewBitrateReceived}\n        onStreamStateChanged={handleOnStreamStateChanged}\n        onBluetoothDeviceStatusChanged={handleBluetoothDeviceStatusChanged}\n      />\n    );\n  }\n);\n\nexport default RTMPPublisher;\n"]}
\ No newline at end of file
diff --git a/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js b/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js
index 3e4c3ba..cac7253 100644
--- a/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js
+++ b/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js
@@ -11,6 +11,7 @@ exports.StreamState = StreamState;
   StreamState["CONNECTING"] = "CONNECTING";
   StreamState["CONNECTED"] = "CONNECTED";
   StreamState["DISCONNECTED"] = "DISCONNECTED";
+  StreamState["CLOSED"] = "CLOSED";
   StreamState["FAILED"] = "FAILED";
 })(StreamState || (exports.StreamState = StreamState = {}));
 
diff --git a/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js.map b/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js.map
index 5c5fd9e..d70feba 100644
--- a/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js.map
+++ b/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js.map
@@ -1 +1 @@
-{"version":3,"sources":["types.ts"],"names":["StreamState","BluetoothDeviceStatuses","AudioInputType"],"mappings":";;;;;;IA8EYA,W;;;WAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;GAAAA,W,2BAAAA,W;;IAMAC,uB;;;WAAAA,uB;AAAAA,EAAAA,uB;AAAAA,EAAAA,uB;AAAAA,EAAAA,uB;GAAAA,uB,uCAAAA,uB;;IAMAC,c;;;WAAAA,c;AAAAA,EAAAA,c,CAAAA,c;AAAAA,EAAAA,c,CAAAA,c;AAAAA,EAAAA,c,CAAAA,c;GAAAA,c,8BAAAA,c","sourcesContent":["import type { ViewStyle } from 'react-native';\n\nexport interface RTMPPublisherRefProps {\n  /**\n   * Starts stream operation\n   */\n  startStream: () => Promise<void>;\n  /**\n   * Stops stream operation\n   */\n  stopStream: () => Promise<void>;\n  /**\n   * Checks stream status\n   */\n  isStreaming: () => Promise<boolean>;\n  /**\n   * Checks if camera on mount\n   */\n  isCameraOnPreview: () => Promise<boolean>;\n  /**\n   * Gets settled publish url\n   */\n  getPublishURL: () => Promise<string>;\n  /**\n   * Checks congestion status\n   */\n  hasCongestion: () => Promise<boolean>;\n  /**\n   * Checks audio status\n   */\n  isAudioPrepared: () => Promise<boolean>;\n  /**\n   * Checks video status\n   */\n  isVideoPrepared: () => Promise<boolean>;\n  /**\n   * Checks if mic closed\n   */\n  isMuted: () => Promise<boolean>;\n  /**\n   * Mutes the mic\n   */\n  mute: () => Promise<void>;\n  /**\n   * Unmutes the mic\n   */\n  unmute: () => Promise<void>;\n  /**\n   * Switches the camera\n   */\n  switchCamera: () => Promise<void>;\n  /**\n   * Toggles the flash\n   */\n  toggleFlash: () => Promise<void>;\n  /**\n   * Sets the audio input (microphone type)\n   */\n  setAudioInput: (audioInput: AudioInputType) => Promise<void>;\n}\n\nexport interface RTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  onConnectionFailed?: (e: null) => void;\n  onConnectionStarted?: (e: null) => void;\n  onConnectionSuccess?: (e: null) => void;\n  onDisconnect?: (e: null) => void;\n  onNewBitrateReceived?: (e: number) => void;\n  onStreamStateChanged?: (e: StreamState) => void;\n}\nexport type StreamStatus =\n  | 'CONNECTING'\n  | 'CONNECTED'\n  | 'DISCONNECTED'\n  | 'FAILED';\n\nexport enum StreamState {\n  CONNECTING = 'CONNECTING',\n  CONNECTED = 'CONNECTED',\n  DISCONNECTED = 'DISCONNECTED',\n  FAILED = 'FAILED',\n}\nexport enum BluetoothDeviceStatuses {\n  CONNECTING = 'CONNECTING',\n  CONNECTED = 'CONNECTED',\n  DISCONNECTED = 'DISCONNECTED',\n}\n\nexport enum AudioInputType {\n  BLUETOOTH_HEADSET = 0,\n  SPEAKER = 1,\n  WIRED_HEADSET = 2,\n}\n"]}
\ No newline at end of file
+{"version":3,"sources":["types.ts"],"names":["StreamState","BluetoothDeviceStatuses","AudioInputType"],"mappings":";;;;;;IAoFYA,W;;;WAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;GAAAA,W,2BAAAA,W;;IAOAC,uB;;;WAAAA,uB;AAAAA,EAAAA,uB;AAAAA,EAAAA,uB;AAAAA,EAAAA,uB;GAAAA,uB,uCAAAA,uB;;IAMAC,c;;;WAAAA,c;AAAAA,EAAAA,c,CAAAA,c;AAAAA,EAAAA,c,CAAAA,c;AAAAA,EAAAA,c,CAAAA,c;GAAAA,c,8BAAAA,c","sourcesContent":["import type { ViewStyle } from 'react-native';\n\nexport interface RTMPPublisherRefProps {\n  /**\n   * Starts stream operation\n   */\n  startStream: () => Promise<void>;\n  /**\n   * Stops stream operation\n   */\n  stopStream: () => Promise<void>;\n  /**\n   * Checks stream status\n   */\n  isStreaming: () => Promise<boolean>;\n  /**\n   * Checks if camera on mount\n   */\n  isCameraOnPreview: () => Promise<boolean>;\n  /**\n   * Gets settled publish url\n   */\n  getPublishURL: () => Promise<string>;\n  /**\n   * Checks congestion status\n   */\n  hasCongestion: () => Promise<boolean>;\n  /**\n   * Checks audio status\n   */\n  isAudioPrepared: () => Promise<boolean>;\n  /**\n   * Checks video status\n   */\n  isVideoPrepared: () => Promise<boolean>;\n  /**\n   * Checks if mic closed\n   */\n  isMuted: () => Promise<boolean>;\n  /**\n   * Mutes the mic\n   */\n  mute: () => Promise<void>;\n  /**\n   * Unmutes the mic\n   */\n  unmute: () => Promise<void>;\n  /**\n   * Switches the camera\n   */\n  switchCamera: () => Promise<void>;\n  /**\n   * Toggles the flash\n   */\n  toggleFlash: () => Promise<void>;\n  /**\n   * Sets the audio input (microphone type)\n   */\n  setAudioInput: (audioInput: AudioInputType) => Promise<void>;\n  /**\n   * Sets video settings quality\n   */\n  setVideoSettings: (audioInput: VideoSettingsType) => Promise<void>;\n}\n\nexport interface RTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  videoSettings?: VideoSettingsType;\n  onConnectionFailed?: (e: null) => void;\n  onConnectionStarted?: (e: null) => void;\n  onConnectionSuccess?: (e: null) => void;\n  onDisconnect?: (e: null) => void;\n  onNewBitrateReceived?: (e: number) => void;\n  onStreamStateChanged?: (e: StreamState) => void;\n}\nexport type StreamStatus =\n  | 'CONNECTING'\n  | 'CONNECTED'\n  | 'DISCONNECTED'\n  | 'CLOSED'\n  | 'FAILED';\n\nexport enum StreamState {\n  CONNECTING = 'CONNECTING',\n  CONNECTED = 'CONNECTED',\n  DISCONNECTED = 'DISCONNECTED',\n  CLOSED = 'CLOSED',\n  FAILED = 'FAILED',\n}\nexport enum BluetoothDeviceStatuses {\n  CONNECTING = 'CONNECTING',\n  CONNECTED = 'CONNECTED',\n  DISCONNECTED = 'DISCONNECTED',\n}\n\nexport enum AudioInputType {\n  BLUETOOTH_HEADSET = 0,\n  SPEAKER = 1,\n  WIRED_HEADSET = 2,\n}\n\nexport interface VideoSettingsType {\n  width: number;\n  height: number;\n  bitrate: number;\n}\n"]}
\ No newline at end of file
diff --git a/node_modules/react-native-rtmp-publisher/lib/module/Component.js.map b/node_modules/react-native-rtmp-publisher/lib/module/Component.js.map
index 2a24090..a6dcac6 100644
--- a/node_modules/react-native-rtmp-publisher/lib/module/Component.js.map
+++ b/node_modules/react-native-rtmp-publisher/lib/module/Component.js.map
@@ -1 +1 @@
-{"version":3,"sources":["Component.tsx"],"names":["requireNativeComponent"],"mappings":"AAAA,SAEEA,sBAFF,QAIO,cAJP;AAkCA,eAAeA,sBAAsB,CACnC,eADmC,CAArC","sourcesContent":["import {\n  NativeSyntheticEvent,\n  requireNativeComponent,\n  ViewStyle,\n} from 'react-native';\nimport type { StreamState, BluetoothDeviceStatuses } from './types';\n\ntype RTMPData<T> = { data: T };\n\nexport type ConnectionFailedType = NativeSyntheticEvent<RTMPData<string>>;\nexport type ConnectionStartedType = NativeSyntheticEvent<RTMPData<string>>;\nexport type ConnectionSuccessType = NativeSyntheticEvent<RTMPData<null>>;\nexport type DisconnectType = NativeSyntheticEvent<RTMPData<null>>;\nexport type NewBitrateReceivedType = NativeSyntheticEvent<RTMPData<number>>;\nexport type StreamStateChangedType = NativeSyntheticEvent<\n  RTMPData<StreamState>\n>;\nexport type BluetoothDeviceStatusChangedType = NativeSyntheticEvent<\n  RTMPData<BluetoothDeviceStatuses>\n>;\nexport interface NativeRTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  onConnectionFailed?: (e: ConnectionFailedType) => void;\n  onConnectionStarted?: (e: ConnectionStartedType) => void;\n  onConnectionSuccess?: (e: ConnectionSuccessType) => void;\n  onDisconnect?: (e: DisconnectType) => void;\n  onNewBitrateReceived?: (e: NewBitrateReceivedType) => void;\n  onStreamStateChanged?: (e: StreamStateChangedType) => void;\n  onBluetoothDeviceStatusChanged?: (\n    e: BluetoothDeviceStatusChangedType\n  ) => void;\n}\nexport default requireNativeComponent<NativeRTMPPublisherProps>(\n  'RTMPPublisher'\n);\n"]}
\ No newline at end of file
+{"version":3,"sources":["Component.tsx"],"names":["requireNativeComponent"],"mappings":"AAAA,SAEEA,sBAFF,QAIO,cAJP;AAuCA,eAAeA,sBAAsB,CACnC,eADmC,CAArC","sourcesContent":["import {\n  NativeSyntheticEvent,\n  requireNativeComponent,\n  ViewStyle,\n} from 'react-native';\nimport type {\n  StreamState,\n  BluetoothDeviceStatuses,\n  VideoSettingsType,\n} from './types';\n\ntype RTMPData<T> = { data: T };\n\nexport type ConnectionFailedType = NativeSyntheticEvent<RTMPData<string>>;\nexport type ConnectionStartedType = NativeSyntheticEvent<RTMPData<string>>;\nexport type ConnectionSuccessType = NativeSyntheticEvent<RTMPData<null>>;\nexport type DisconnectType = NativeSyntheticEvent<RTMPData<null>>;\nexport type NewBitrateReceivedType = NativeSyntheticEvent<RTMPData<number>>;\nexport type StreamStateChangedType = NativeSyntheticEvent<\n  RTMPData<StreamState>\n>;\nexport type BluetoothDeviceStatusChangedType = NativeSyntheticEvent<\n  RTMPData<BluetoothDeviceStatuses>\n>;\nexport interface NativeRTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  videoSettings?: VideoSettingsType;\n  onConnectionFailed?: (e: ConnectionFailedType) => void;\n  onConnectionStarted?: (e: ConnectionStartedType) => void;\n  onConnectionSuccess?: (e: ConnectionSuccessType) => void;\n  onDisconnect?: (e: DisconnectType) => void;\n  onNewBitrateReceived?: (e: NewBitrateReceivedType) => void;\n  onStreamStateChanged?: (e: StreamStateChangedType) => void;\n  onBluetoothDeviceStatusChanged?: (\n    e: BluetoothDeviceStatusChangedType\n  ) => void;\n}\nexport default requireNativeComponent<NativeRTMPPublisherProps>(\n  'RTMPPublisher'\n);\n"]}
\ No newline at end of file
diff --git a/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js b/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js
index d834c39..30a9c00 100644
--- a/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js
+++ b/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js
@@ -44,6 +44,8 @@ const RTMPPublisher = /*#__PURE__*/forwardRef((_ref, ref) => {
 
   const setAudioInput = audioInput => RTMPModule.setAudioInput(audioInput);
 
+  const setVideoSettings = async videoSettings => RTMPModule.setVideoSettings(videoSettings);
+
   const handleOnConnectionFailed = e => {
     onConnectionFailed && onConnectionFailed(e.nativeEvent.data);
   };
@@ -86,7 +88,8 @@ const RTMPPublisher = /*#__PURE__*/forwardRef((_ref, ref) => {
     unmute,
     switchCamera,
     toggleFlash,
-    setAudioInput
+    setAudioInput,
+    setVideoSettings
   }));
   return /*#__PURE__*/React.createElement(PublisherComponent, _extends({}, props, {
     onDisconnect: handleOnDisconnect,
diff --git a/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js.map b/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js.map
index 2233e3b..78c5685 100644
--- a/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js.map
+++ b/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js.map
@@ -1 +1 @@
-{"version":3,"sources":["RTMPPublisher.tsx"],"names":["React","forwardRef","useImperativeHandle","NativeModules","PublisherComponent","RTMPModule","RTMPPublisher","ref","onConnectionFailed","onConnectionStarted","onConnectionSuccess","onDisconnect","onNewBitrateReceived","onStreamStateChanged","onBluetoothDeviceStatusChanged","props","startStream","stopStream","isStreaming","isCameraOnPreview","getPublishURL","hasCongestion","isAudioPrepared","isVideoPrepared","isMuted","mute","unmute","switchCamera","toggleFlash","setAudioInput","audioInput","handleOnConnectionFailed","e","nativeEvent","data","handleOnConnectionStarted","handleOnConnectionSuccess","handleOnDisconnect","handleOnNewBitrateReceived","handleOnStreamStateChanged","handleBluetoothDeviceStatusChanged"],"mappings":"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","sourcesContent":["import React, { forwardRef, useImperativeHandle } from 'react';\nimport { NativeModules, ViewStyle } from 'react-native';\nimport PublisherComponent, {\n  DisconnectType,\n  ConnectionFailedType,\n  ConnectionStartedType,\n  ConnectionSuccessType,\n  NewBitrateReceivedType,\n  StreamStateChangedType,\n  BluetoothDeviceStatusChangedType,\n} from './Component';\nimport type {\n  RTMPPublisherRefProps,\n  StreamState,\n  BluetoothDeviceStatuses,\n  AudioInputType,\n} from './types';\n\nconst RTMPModule = NativeModules.RTMPPublisher;\nexport interface RTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  /**\n   * Callback for connection fails on RTMP server\n   */\n  onConnectionFailed?: (data: string) => void;\n  /**\n   * Callback for starting connection to RTMP server\n   */\n  onConnectionStarted?: (data: string) => void;\n  /**\n   * Callback for connection successfully to RTMP server\n   */\n  onConnectionSuccess?: (data: null) => void;\n  /**\n   * Callback for disconnect successfully to RTMP server\n   */\n  onDisconnect?: (data: null) => void;\n  /**\n   * Callback for receiving new bitrate value about stream\n   */\n  onNewBitrateReceived?: (data: number) => void;\n  /**\n   * Alternatively callback for changing stream state\n   * Returns parameter StreamState type\n   */\n  onStreamStateChanged?: (data: StreamState) => void;\n  /**\n   * Callback for bluetooth device connection changes\n   */\n  onBluetoothDeviceStatusChanged?: (data: BluetoothDeviceStatuses) => void;\n}\n\nconst RTMPPublisher = forwardRef<RTMPPublisherRefProps, RTMPPublisherProps>(\n  (\n    {\n      onConnectionFailed,\n      onConnectionStarted,\n      onConnectionSuccess,\n      onDisconnect,\n      onNewBitrateReceived,\n      onStreamStateChanged,\n      onBluetoothDeviceStatusChanged,\n      ...props\n    },\n    ref\n  ) => {\n    const startStream = async () => await RTMPModule.startStream();\n\n    const stopStream = async () => await RTMPModule.stopStream();\n\n    const isStreaming = async () => RTMPModule.isStreaming();\n\n    const isCameraOnPreview = async () => RTMPModule.isCameraOnPreview();\n\n    const getPublishURL = async () => RTMPModule.getPublishURL();\n\n    const hasCongestion = async () => RTMPModule.hasCongestion();\n\n    const isAudioPrepared = async () => RTMPModule.isAudioPrepared();\n\n    const isVideoPrepared = async () => RTMPModule.isVideoPrepared();\n\n    const isMuted = async () => RTMPModule.isMuted();\n\n    const mute = () => RTMPModule.mute();\n\n    const unmute = () => RTMPModule.unmute();\n\n    const switchCamera = () => RTMPModule.switchCamera();\n\n    const toggleFlash = () => RTMPModule.toggleFlash();\n\n    const setAudioInput = (audioInput: AudioInputType) =>\n      RTMPModule.setAudioInput(audioInput);\n\n    const handleOnConnectionFailed = (e: ConnectionFailedType) => {\n      onConnectionFailed && onConnectionFailed(e.nativeEvent.data);\n    };\n\n    const handleOnConnectionStarted = (e: ConnectionStartedType) => {\n      onConnectionStarted && onConnectionStarted(e.nativeEvent.data);\n    };\n\n    const handleOnConnectionSuccess = (e: ConnectionSuccessType) => {\n      onConnectionSuccess && onConnectionSuccess(e.nativeEvent.data);\n    };\n\n    const handleOnDisconnect = (e: DisconnectType) => {\n      onDisconnect && onDisconnect(e.nativeEvent.data);\n    };\n\n    const handleOnNewBitrateReceived = (e: NewBitrateReceivedType) => {\n      onNewBitrateReceived && onNewBitrateReceived(e.nativeEvent.data);\n    };\n\n    const handleOnStreamStateChanged = (e: StreamStateChangedType) => {\n      onStreamStateChanged && onStreamStateChanged(e.nativeEvent.data);\n    };\n\n    const handleBluetoothDeviceStatusChanged = (\n      e: BluetoothDeviceStatusChangedType\n    ) => {\n      onBluetoothDeviceStatusChanged &&\n        onBluetoothDeviceStatusChanged(e.nativeEvent.data);\n    };\n\n    useImperativeHandle(ref, () => ({\n      startStream,\n      stopStream,\n      isStreaming,\n      isCameraOnPreview,\n      getPublishURL,\n      hasCongestion,\n      isAudioPrepared,\n      isVideoPrepared,\n      isMuted,\n      mute,\n      unmute,\n      switchCamera,\n      toggleFlash,\n      setAudioInput,\n    }));\n\n    return (\n      <PublisherComponent\n        {...props}\n        onDisconnect={handleOnDisconnect}\n        onConnectionFailed={handleOnConnectionFailed}\n        onConnectionStarted={handleOnConnectionStarted}\n        onConnectionSuccess={handleOnConnectionSuccess}\n        onNewBitrateReceived={handleOnNewBitrateReceived}\n        onStreamStateChanged={handleOnStreamStateChanged}\n        onBluetoothDeviceStatusChanged={handleBluetoothDeviceStatusChanged}\n      />\n    );\n  }\n);\n\nexport default RTMPPublisher;\n"]}
\ No newline at end of file
+{"version":3,"sources":["RTMPPublisher.tsx"],"names":["React","forwardRef","useImperativeHandle","NativeModules","PublisherComponent","RTMPModule","RTMPPublisher","ref","onConnectionFailed","onConnectionStarted","onConnectionSuccess","onDisconnect","onNewBitrateReceived","onStreamStateChanged","onBluetoothDeviceStatusChanged","props","startStream","stopStream","isStreaming","isCameraOnPreview","getPublishURL","hasCongestion","isAudioPrepared","isVideoPrepared","isMuted","mute","unmute","switchCamera","toggleFlash","setAudioInput","audioInput","setVideoSettings","videoSettings","handleOnConnectionFailed","e","nativeEvent","data","handleOnConnectionStarted","handleOnConnectionSuccess","handleOnDisconnect","handleOnNewBitrateReceived","handleOnStreamStateChanged","handleBluetoothDeviceStatusChanged"],"mappings":"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","sourcesContent":["import React, { forwardRef, useImperativeHandle } from 'react';\nimport { NativeModules, type ViewStyle } from 'react-native';\nimport PublisherComponent, {\n  type DisconnectType,\n  type ConnectionFailedType,\n  type ConnectionStartedType,\n  type ConnectionSuccessType,\n  type NewBitrateReceivedType,\n  type StreamStateChangedType,\n  type BluetoothDeviceStatusChangedType,\n} from './Component';\nimport type {\n  RTMPPublisherRefProps,\n  StreamState,\n  BluetoothDeviceStatuses,\n  AudioInputType,\n  VideoSettingsType,\n} from './types';\n\nconst RTMPModule = NativeModules.RTMPPublisher;\nexport interface RTMPPublisherProps {\n  testID?: string;\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  /**\n   * Video settings for video\n   */\n  videoSettings?: VideoSettingsType;\n  /**\n   * Callback for connection fails on RTMP server\n   */\n  onConnectionFailed?: (data: string) => void;\n  /**\n   * Callback for starting connection to RTMP server\n   */\n  onConnectionStarted?: (data: string) => void;\n  /**\n   * Callback for connection successfully to RTMP server\n   */\n  onConnectionSuccess?: (data: null) => void;\n  /**\n   * Callback for disconnect successfully to RTMP server\n   */\n  onDisconnect?: (data: null) => void;\n  /**\n   * Callback for receiving new bitrate value about stream\n   */\n  onNewBitrateReceived?: (data: number) => void;\n  /**\n   * Alternatively callback for changing stream state\n   * Returns parameter StreamState type\n   */\n  onStreamStateChanged?: (data: StreamState) => void;\n  /**\n   * Callback for bluetooth device connection changes\n   */\n  onBluetoothDeviceStatusChanged?: (data: BluetoothDeviceStatuses) => void;\n}\n\nconst RTMPPublisher = forwardRef<RTMPPublisherRefProps, RTMPPublisherProps>(\n  (\n    {\n      onConnectionFailed,\n      onConnectionStarted,\n      onConnectionSuccess,\n      onDisconnect,\n      onNewBitrateReceived,\n      onStreamStateChanged,\n      onBluetoothDeviceStatusChanged,\n      ...props\n    },\n    ref\n  ) => {\n    const startStream = async () => await RTMPModule.startStream();\n\n    const stopStream = async () => await RTMPModule.stopStream();\n\n    const isStreaming = async () => RTMPModule.isStreaming();\n\n    const isCameraOnPreview = async () => RTMPModule.isCameraOnPreview();\n\n    const getPublishURL = async () => RTMPModule.getPublishURL();\n\n    const hasCongestion = async () => RTMPModule.hasCongestion();\n\n    const isAudioPrepared = async () => RTMPModule.isAudioPrepared();\n\n    const isVideoPrepared = async () => RTMPModule.isVideoPrepared();\n\n    const isMuted = async () => RTMPModule.isMuted();\n\n    const mute = () => RTMPModule.mute();\n\n    const unmute = () => RTMPModule.unmute();\n\n    const switchCamera = () => RTMPModule.switchCamera();\n\n    const toggleFlash = () => RTMPModule.toggleFlash();\n\n    const setAudioInput = (audioInput: AudioInputType) =>\n      RTMPModule.setAudioInput(audioInput);\n\n    const setVideoSettings = async (videoSettings: VideoSettingsType) =>\n      RTMPModule.setVideoSettings(videoSettings);\n\n    const handleOnConnectionFailed = (e: ConnectionFailedType) => {\n      onConnectionFailed && onConnectionFailed(e.nativeEvent.data);\n    };\n\n    const handleOnConnectionStarted = (e: ConnectionStartedType) => {\n      onConnectionStarted && onConnectionStarted(e.nativeEvent.data);\n    };\n\n    const handleOnConnectionSuccess = (e: ConnectionSuccessType) => {\n      onConnectionSuccess && onConnectionSuccess(e.nativeEvent.data);\n    };\n\n    const handleOnDisconnect = (e: DisconnectType) => {\n      onDisconnect && onDisconnect(e.nativeEvent.data);\n    };\n\n    const handleOnNewBitrateReceived = (e: NewBitrateReceivedType) => {\n      onNewBitrateReceived && onNewBitrateReceived(e.nativeEvent.data);\n    };\n\n    const handleOnStreamStateChanged = (e: StreamStateChangedType) => {\n      onStreamStateChanged && onStreamStateChanged(e.nativeEvent.data);\n    };\n\n    const handleBluetoothDeviceStatusChanged = (\n      e: BluetoothDeviceStatusChangedType\n    ) => {\n      onBluetoothDeviceStatusChanged &&\n        onBluetoothDeviceStatusChanged(e.nativeEvent.data);\n    };\n\n    useImperativeHandle(ref, () => ({\n      startStream,\n      stopStream,\n      isStreaming,\n      isCameraOnPreview,\n      getPublishURL,\n      hasCongestion,\n      isAudioPrepared,\n      isVideoPrepared,\n      isMuted,\n      mute,\n      unmute,\n      switchCamera,\n      toggleFlash,\n      setAudioInput,\n      setVideoSettings,\n    }));\n\n    return (\n      <PublisherComponent\n        {...props}\n        onDisconnect={handleOnDisconnect}\n        onConnectionFailed={handleOnConnectionFailed}\n        onConnectionStarted={handleOnConnectionStarted}\n        onConnectionSuccess={handleOnConnectionSuccess}\n        onNewBitrateReceived={handleOnNewBitrateReceived}\n        onStreamStateChanged={handleOnStreamStateChanged}\n        onBluetoothDeviceStatusChanged={handleBluetoothDeviceStatusChanged}\n      />\n    );\n  }\n);\n\nexport default RTMPPublisher;\n"]}
\ No newline at end of file
diff --git a/node_modules/react-native-rtmp-publisher/lib/module/types.js b/node_modules/react-native-rtmp-publisher/lib/module/types.js
index 33ab0d6..f4f39f2 100644
--- a/node_modules/react-native-rtmp-publisher/lib/module/types.js
+++ b/node_modules/react-native-rtmp-publisher/lib/module/types.js
@@ -4,6 +4,7 @@ export let StreamState;
   StreamState["CONNECTING"] = "CONNECTING";
   StreamState["CONNECTED"] = "CONNECTED";
   StreamState["DISCONNECTED"] = "DISCONNECTED";
+  StreamState["CLOSED"] = "CLOSED";
   StreamState["FAILED"] = "FAILED";
 })(StreamState || (StreamState = {}));
 
diff --git a/node_modules/react-native-rtmp-publisher/lib/module/types.js.map b/node_modules/react-native-rtmp-publisher/lib/module/types.js.map
index a00b7f2..6dfb0b0 100644
--- a/node_modules/react-native-rtmp-publisher/lib/module/types.js.map
+++ b/node_modules/react-native-rtmp-publisher/lib/module/types.js.map
@@ -1 +1 @@
-{"version":3,"sources":["types.ts"],"names":["StreamState","BluetoothDeviceStatuses","AudioInputType"],"mappings":"AA8EA,WAAYA,WAAZ;;WAAYA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;GAAAA,W,KAAAA,W;;AAMZ,WAAYC,uBAAZ;;WAAYA,uB;AAAAA,EAAAA,uB;AAAAA,EAAAA,uB;AAAAA,EAAAA,uB;GAAAA,uB,KAAAA,uB;;AAMZ,WAAYC,cAAZ;;WAAYA,c;AAAAA,EAAAA,c,CAAAA,c;AAAAA,EAAAA,c,CAAAA,c;AAAAA,EAAAA,c,CAAAA,c;GAAAA,c,KAAAA,c","sourcesContent":["import type { ViewStyle } from 'react-native';\n\nexport interface RTMPPublisherRefProps {\n  /**\n   * Starts stream operation\n   */\n  startStream: () => Promise<void>;\n  /**\n   * Stops stream operation\n   */\n  stopStream: () => Promise<void>;\n  /**\n   * Checks stream status\n   */\n  isStreaming: () => Promise<boolean>;\n  /**\n   * Checks if camera on mount\n   */\n  isCameraOnPreview: () => Promise<boolean>;\n  /**\n   * Gets settled publish url\n   */\n  getPublishURL: () => Promise<string>;\n  /**\n   * Checks congestion status\n   */\n  hasCongestion: () => Promise<boolean>;\n  /**\n   * Checks audio status\n   */\n  isAudioPrepared: () => Promise<boolean>;\n  /**\n   * Checks video status\n   */\n  isVideoPrepared: () => Promise<boolean>;\n  /**\n   * Checks if mic closed\n   */\n  isMuted: () => Promise<boolean>;\n  /**\n   * Mutes the mic\n   */\n  mute: () => Promise<void>;\n  /**\n   * Unmutes the mic\n   */\n  unmute: () => Promise<void>;\n  /**\n   * Switches the camera\n   */\n  switchCamera: () => Promise<void>;\n  /**\n   * Toggles the flash\n   */\n  toggleFlash: () => Promise<void>;\n  /**\n   * Sets the audio input (microphone type)\n   */\n  setAudioInput: (audioInput: AudioInputType) => Promise<void>;\n}\n\nexport interface RTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  onConnectionFailed?: (e: null) => void;\n  onConnectionStarted?: (e: null) => void;\n  onConnectionSuccess?: (e: null) => void;\n  onDisconnect?: (e: null) => void;\n  onNewBitrateReceived?: (e: number) => void;\n  onStreamStateChanged?: (e: StreamState) => void;\n}\nexport type StreamStatus =\n  | 'CONNECTING'\n  | 'CONNECTED'\n  | 'DISCONNECTED'\n  | 'FAILED';\n\nexport enum StreamState {\n  CONNECTING = 'CONNECTING',\n  CONNECTED = 'CONNECTED',\n  DISCONNECTED = 'DISCONNECTED',\n  FAILED = 'FAILED',\n}\nexport enum BluetoothDeviceStatuses {\n  CONNECTING = 'CONNECTING',\n  CONNECTED = 'CONNECTED',\n  DISCONNECTED = 'DISCONNECTED',\n}\n\nexport enum AudioInputType {\n  BLUETOOTH_HEADSET = 0,\n  SPEAKER = 1,\n  WIRED_HEADSET = 2,\n}\n"]}
\ No newline at end of file
+{"version":3,"sources":["types.ts"],"names":["StreamState","BluetoothDeviceStatuses","AudioInputType"],"mappings":"AAoFA,WAAYA,WAAZ;;WAAYA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;AAAAA,EAAAA,W;GAAAA,W,KAAAA,W;;AAOZ,WAAYC,uBAAZ;;WAAYA,uB;AAAAA,EAAAA,uB;AAAAA,EAAAA,uB;AAAAA,EAAAA,uB;GAAAA,uB,KAAAA,uB;;AAMZ,WAAYC,cAAZ;;WAAYA,c;AAAAA,EAAAA,c,CAAAA,c;AAAAA,EAAAA,c,CAAAA,c;AAAAA,EAAAA,c,CAAAA,c;GAAAA,c,KAAAA,c","sourcesContent":["import type { ViewStyle } from 'react-native';\n\nexport interface RTMPPublisherRefProps {\n  /**\n   * Starts stream operation\n   */\n  startStream: () => Promise<void>;\n  /**\n   * Stops stream operation\n   */\n  stopStream: () => Promise<void>;\n  /**\n   * Checks stream status\n   */\n  isStreaming: () => Promise<boolean>;\n  /**\n   * Checks if camera on mount\n   */\n  isCameraOnPreview: () => Promise<boolean>;\n  /**\n   * Gets settled publish url\n   */\n  getPublishURL: () => Promise<string>;\n  /**\n   * Checks congestion status\n   */\n  hasCongestion: () => Promise<boolean>;\n  /**\n   * Checks audio status\n   */\n  isAudioPrepared: () => Promise<boolean>;\n  /**\n   * Checks video status\n   */\n  isVideoPrepared: () => Promise<boolean>;\n  /**\n   * Checks if mic closed\n   */\n  isMuted: () => Promise<boolean>;\n  /**\n   * Mutes the mic\n   */\n  mute: () => Promise<void>;\n  /**\n   * Unmutes the mic\n   */\n  unmute: () => Promise<void>;\n  /**\n   * Switches the camera\n   */\n  switchCamera: () => Promise<void>;\n  /**\n   * Toggles the flash\n   */\n  toggleFlash: () => Promise<void>;\n  /**\n   * Sets the audio input (microphone type)\n   */\n  setAudioInput: (audioInput: AudioInputType) => Promise<void>;\n  /**\n   * Sets video settings quality\n   */\n  setVideoSettings: (audioInput: VideoSettingsType) => Promise<void>;\n}\n\nexport interface RTMPPublisherProps {\n  style?: ViewStyle;\n  streamURL: string;\n  streamName: string;\n  videoSettings?: VideoSettingsType;\n  onConnectionFailed?: (e: null) => void;\n  onConnectionStarted?: (e: null) => void;\n  onConnectionSuccess?: (e: null) => void;\n  onDisconnect?: (e: null) => void;\n  onNewBitrateReceived?: (e: number) => void;\n  onStreamStateChanged?: (e: StreamState) => void;\n}\nexport type StreamStatus =\n  | 'CONNECTING'\n  | 'CONNECTED'\n  | 'DISCONNECTED'\n  | 'CLOSED'\n  | 'FAILED';\n\nexport enum StreamState {\n  CONNECTING = 'CONNECTING',\n  CONNECTED = 'CONNECTED',\n  DISCONNECTED = 'DISCONNECTED',\n  CLOSED = 'CLOSED',\n  FAILED = 'FAILED',\n}\nexport enum BluetoothDeviceStatuses {\n  CONNECTING = 'CONNECTING',\n  CONNECTED = 'CONNECTED',\n  DISCONNECTED = 'DISCONNECTED',\n}\n\nexport enum AudioInputType {\n  BLUETOOTH_HEADSET = 0,\n  SPEAKER = 1,\n  WIRED_HEADSET = 2,\n}\n\nexport interface VideoSettingsType {\n  width: number;\n  height: number;\n  bitrate: number;\n}\n"]}
\ No newline at end of file
diff --git a/node_modules/react-native-rtmp-publisher/lib/typescript/Component.d.ts b/node_modules/react-native-rtmp-publisher/lib/typescript/Component.d.ts
index d192f60..284149f 100644
--- a/node_modules/react-native-rtmp-publisher/lib/typescript/Component.d.ts
+++ b/node_modules/react-native-rtmp-publisher/lib/typescript/Component.d.ts
@@ -1,5 +1,5 @@
 import { NativeSyntheticEvent, ViewStyle } from 'react-native';
-import type { StreamState, BluetoothDeviceStatuses } from './types';
+import type { StreamState, BluetoothDeviceStatuses, VideoSettingsType } from './types';
 declare type RTMPData<T> = {
     data: T;
 };
@@ -14,6 +14,7 @@ export interface NativeRTMPPublisherProps {
     style?: ViewStyle;
     streamURL: string;
     streamName: string;
+    videoSettings?: VideoSettingsType;
     onConnectionFailed?: (e: ConnectionFailedType) => void;
     onConnectionStarted?: (e: ConnectionStartedType) => void;
     onConnectionSuccess?: (e: ConnectionSuccessType) => void;
diff --git a/node_modules/react-native-rtmp-publisher/lib/typescript/RTMPPublisher.d.ts b/node_modules/react-native-rtmp-publisher/lib/typescript/RTMPPublisher.d.ts
index dc79cdd..6189ec4 100644
--- a/node_modules/react-native-rtmp-publisher/lib/typescript/RTMPPublisher.d.ts
+++ b/node_modules/react-native-rtmp-publisher/lib/typescript/RTMPPublisher.d.ts
@@ -1,10 +1,15 @@
 import React from 'react';
-import { ViewStyle } from 'react-native';
-import type { RTMPPublisherRefProps, StreamState, BluetoothDeviceStatuses } from './types';
+import { type ViewStyle } from 'react-native';
+import type { RTMPPublisherRefProps, StreamState, BluetoothDeviceStatuses, VideoSettingsType } from './types';
 export interface RTMPPublisherProps {
+    testID?: string;
     style?: ViewStyle;
     streamURL: string;
     streamName: string;
+    /**
+     * Video settings for video
+     */
+    videoSettings?: VideoSettingsType;
     /**
      * Callback for connection fails on RTMP server
      */
diff --git a/node_modules/react-native-rtmp-publisher/lib/typescript/types.d.ts b/node_modules/react-native-rtmp-publisher/lib/typescript/types.d.ts
index f2ce585..226319c 100644
--- a/node_modules/react-native-rtmp-publisher/lib/typescript/types.d.ts
+++ b/node_modules/react-native-rtmp-publisher/lib/typescript/types.d.ts
@@ -56,11 +56,16 @@ export interface RTMPPublisherRefProps {
      * Sets the audio input (microphone type)
      */
     setAudioInput: (audioInput: AudioInputType) => Promise<void>;
+    /**
+     * Sets video settings quality
+     */
+    setVideoSettings: (audioInput: VideoSettingsType) => Promise<void>;
 }
 export interface RTMPPublisherProps {
     style?: ViewStyle;
     streamURL: string;
     streamName: string;
+    videoSettings?: VideoSettingsType;
     onConnectionFailed?: (e: null) => void;
     onConnectionStarted?: (e: null) => void;
     onConnectionSuccess?: (e: null) => void;
@@ -68,11 +73,12 @@ export interface RTMPPublisherProps {
     onNewBitrateReceived?: (e: number) => void;
     onStreamStateChanged?: (e: StreamState) => void;
 }
-export declare type StreamStatus = 'CONNECTING' | 'CONNECTED' | 'DISCONNECTED' | 'FAILED';
+export declare type StreamStatus = 'CONNECTING' | 'CONNECTED' | 'DISCONNECTED' | 'CLOSED' | 'FAILED';
 export declare enum StreamState {
     CONNECTING = "CONNECTING",
     CONNECTED = "CONNECTED",
     DISCONNECTED = "DISCONNECTED",
+    CLOSED = "CLOSED",
     FAILED = "FAILED"
 }
 export declare enum BluetoothDeviceStatuses {
@@ -85,3 +91,8 @@ export declare enum AudioInputType {
     SPEAKER = 1,
     WIRED_HEADSET = 2
 }
+export interface VideoSettingsType {
+    width: number;
+    height: number;
+    bitrate: number;
+}
diff --git a/node_modules/react-native-rtmp-publisher/src/Component.tsx b/node_modules/react-native-rtmp-publisher/src/Component.tsx
index 7d273ee..04dd800 100644
--- a/node_modules/react-native-rtmp-publisher/src/Component.tsx
+++ b/node_modules/react-native-rtmp-publisher/src/Component.tsx
@@ -3,7 +3,11 @@ import {
   requireNativeComponent,
   ViewStyle,
 } from 'react-native';
-import type { StreamState, BluetoothDeviceStatuses } from './types';
+import type {
+  StreamState,
+  BluetoothDeviceStatuses,
+  VideoSettingsType,
+} from './types';
 
 type RTMPData<T> = { data: T };
 
@@ -22,6 +26,7 @@ export interface NativeRTMPPublisherProps {
   style?: ViewStyle;
   streamURL: string;
   streamName: string;
+  videoSettings?: VideoSettingsType;
   onConnectionFailed?: (e: ConnectionFailedType) => void;
   onConnectionStarted?: (e: ConnectionStartedType) => void;
   onConnectionSuccess?: (e: ConnectionSuccessType) => void;
diff --git a/node_modules/react-native-rtmp-publisher/src/RTMPPublisher.tsx b/node_modules/react-native-rtmp-publisher/src/RTMPPublisher.tsx
index 7f11946..f0e64ee 100644
--- a/node_modules/react-native-rtmp-publisher/src/RTMPPublisher.tsx
+++ b/node_modules/react-native-rtmp-publisher/src/RTMPPublisher.tsx
@@ -14,13 +14,19 @@ import type {
   StreamState,
   BluetoothDeviceStatuses,
   AudioInputType,
+  VideoSettingsType,
 } from './types';
 
 const RTMPModule = NativeModules.RTMPPublisher;
 export interface RTMPPublisherProps {
+  testID?: string;
   style?: ViewStyle;
   streamURL: string;
   streamName: string;
+  /**
+   * Video settings for video
+   */
+  videoSettings?: VideoSettingsType;
   /**
    * Callback for connection fails on RTMP server
    */
@@ -95,6 +101,9 @@ const RTMPPublisher = forwardRef<RTMPPublisherRefProps, RTMPPublisherProps>(
     const setAudioInput = (audioInput: AudioInputType) =>
       RTMPModule.setAudioInput(audioInput);
 
+    const setVideoSettings = async (videoSettings: VideoSettingsType) =>
+      RTMPModule.setVideoSettings(videoSettings);
+
     const handleOnConnectionFailed = (e: ConnectionFailedType) => {
       onConnectionFailed && onConnectionFailed(e.nativeEvent.data);
     };
@@ -141,6 +150,7 @@ const RTMPPublisher = forwardRef<RTMPPublisherRefProps, RTMPPublisherProps>(
       switchCamera,
       toggleFlash,
       setAudioInput,
+      setVideoSettings,
     }));
 
     return (
diff --git a/node_modules/react-native-rtmp-publisher/src/types.ts b/node_modules/react-native-rtmp-publisher/src/types.ts
index 3fc9fda..4b93be4 100644
--- a/node_modules/react-native-rtmp-publisher/src/types.ts
+++ b/node_modules/react-native-rtmp-publisher/src/types.ts
@@ -57,12 +57,17 @@ export interface RTMPPublisherRefProps {
    * Sets the audio input (microphone type)
    */
   setAudioInput: (audioInput: AudioInputType) => Promise<void>;
+  /**
+   * Sets video settings quality
+   */
+  setVideoSettings: (audioInput: VideoSettingsType) => Promise<void>;
 }
 
 export interface RTMPPublisherProps {
   style?: ViewStyle;
   streamURL: string;
   streamName: string;
+  videoSettings?: VideoSettingsType;
   onConnectionFailed?: (e: null) => void;
   onConnectionStarted?: (e: null) => void;
   onConnectionSuccess?: (e: null) => void;
@@ -74,12 +79,14 @@ export type StreamStatus =
   | 'CONNECTING'
   | 'CONNECTED'
   | 'DISCONNECTED'
+  | 'CLOSED'
   | 'FAILED';
 
 export enum StreamState {
   CONNECTING = 'CONNECTING',
   CONNECTED = 'CONNECTED',
   DISCONNECTED = 'DISCONNECTED',
+  CLOSED = 'CLOSED',
   FAILED = 'FAILED',
 }
 export enum BluetoothDeviceStatuses {
@@ -93,3 +100,9 @@ export enum AudioInputType {
   SPEAKER = 1,
   WIRED_HEADSET = 2,
 }
+
+export interface VideoSettingsType {
+  width: number;
+  height: number;
+  bitrate: number;
+}

Andriiklymiuk avatar Apr 14 '23 20:04 Andriiklymiuk

Hello @Andriiklymiuk thanks for the PR and contribution. Looks like Makefile file is crashing the pipeline process. Can you remove it and change the PR to the develop branch?

ezranbayantemur avatar Apr 19 '23 00:04 ezranbayantemur