ezranbayantemur / react-native-rtmp-publisher

📹 Live stream RTMP Publisher for React Native
MIT License
98 stars 14 forks source link

Bump HaishinKit.swift to 1.4.3. Fix iOS 2nd stream #38

Closed Andriiklymiuk closed 1 year ago

Andriiklymiuk commented 1 year ago

Increased version of HaishinKit.swift in order to support rtmps links. Changed DeviceUtil to AVCaptureDevice to migrate to new HaishinKit.swift version. Fixed switching camera and muting/unmuting on new version of HaishinKit.swift. Increased minimum supported version of iOS to 11. Added suggestion from this MR https://github.com/ezranbayantemur/react-native-rtmp-publisher/pull/35 to fix 2nd stream on ios

Andriiklymiuk commented 1 year ago

Can you check it @ezranbayantemur @charlyBerthet ?

Andriiklymiuk commented 1 year ago

Here is nice patch-package file just in case you want to use it before changes merged to master and there is new release or don't want to fork it yourself.

react-native-rtmp-publisher+0.4.7.patch

diff --git a/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift b/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
index 7538bf3..c57956c 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
@@ -38,7 +38,6 @@ class RTMPCreator {
     public static func startPublish(){
         connection.requireNetworkFramework = true
         connection.connect(_streamUrl)
-        stream.publish(_streamName)
         isStreaming = true
     }

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..9ca8075 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPView.swift
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPView.swift
@@ -37,12 +37,8 @@ class RTMPView: UIView {
     hkView = MTHKView(frame: UIScreen.main.bounds)
     hkView.videoGravity = .resizeAspectFill

-    RTMPCreator.stream.captureSettings = [
-        .fps: 30,
-        .sessionPreset: AVCaptureSession.Preset.hd1920x1080,
-        .continuousAutofocus: true,
-        .continuousExposure: true
-    ]
+    RTMPCreator.stream.frameRate = 30
+    RTMPCreator.stream.sessionPreset = AVCaptureSession.Preset.hd1920x1080

     RTMPCreator.stream.videoSettings = [
         .width: 720,
@@ -53,7 +49,7 @@ class RTMPView: UIView {
     ]

     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)

@@ -67,10 +63,6 @@ class RTMPView: UIView {
        fatalError("init(coder:) has not been implemented")
      }

-    override func removeFromSuperview() {
-        print("ON REMOVE")
-    }
-  
     @objc
     private func statusHandler(_ notification: Notification){
       let e = Event.from(notification)
@@ -84,6 +76,7 @@ class RTMPView: UIView {
               onConnectionSuccess!(nil)
             }
            changeStreamState(status: "CONNECTING")
+           RTMPCreator.stream.publish(streamName as String)
            break

        case RTMPConnection.Code.connectFailed.rawValue:
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..338b8ef 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.swift
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPModule/RTMPModule.swift
@@ -27,18 +27,20 @@ class RTMPModule: NSObject {

     @objc
     func mute(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
-        RTMPCreator.stream.audioSettings[.muted] = true
+        RTMPCreator.stream.hasAudio = false
     }

     @objc
     func unmute(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
-        RTMPCreator.stream.audioSettings[.muted] = false
+        RTMPCreator.stream.hasAudio = true
     }

     @objc
     func switchCamera(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
         cameraPosition = cameraPosition == .back ? .front : .back
-        RTMPCreator.stream.attachCamera(DeviceUtil.device(withPosition: cameraPosition))
+        RTMPCreator.stream.attachCamera(
+            AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: cameraPosition)
+        )
     }

     @objc
@@ -48,7 +50,7 @@ class RTMPModule: NSObject {

     @objc
     func isMuted(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
-        resolve(RTMPCreator.stream.audioSettings[.muted])
+        resolve(RTMPCreator.stream.hasAudio)
     }

     @objc
diff --git a/node_modules/react-native-rtmp-publisher/react-native-rtmp-publisher.podspec b/node_modules/react-native-rtmp-publisher/react-native-rtmp-publisher.podspec
index 584732b..6e6dd17 100644
--- a/node_modules/react-native-rtmp-publisher/react-native-rtmp-publisher.podspec
+++ b/node_modules/react-native-rtmp-publisher/react-native-rtmp-publisher.podspec
@@ -10,12 +10,12 @@ Pod::Spec.new do |s|
   s.license      = package["license"]
   s.authors      = package["author"]

-  s.platforms    = { :ios => "10.0" }
+  s.platforms    = { :ios => "11.0" }
   s.source       = { :git => "https://github.com/ezranbayantemur/react-native-rtmp-publisher.git", :tag => "#{s.version}" }

   s.source_files = "ios/**/*.{h,m,mm,swift}"

   s.dependency "React-Core"
-  s.dependency "HaishinKit", "~> 1.2.7"
+  s.dependency "HaishinKit", "~> 1.4.3"

 end
Andriiklymiuk commented 1 year ago

oks, till we are waiting for approval, you can use this patch-package file to:

diff --git a/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift b/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
index 7538bf3..38bf451 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPCreator.swift
@@ -7,6 +7,12 @@
 import HaishinKit
 import AVFoundation

+struct VideoSettingsType {
+    var width: Int
+    var height: Int
+    var bitrate: Int
+}
+
 class RTMPCreator {
     public static let connection: RTMPConnection = RTMPConnection()
     public static let stream: RTMPStream = RTMPStream(connection: connection)
@@ -14,6 +20,11 @@ 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
+    )

     public static func setStreamUrl(url: String){
         _streamUrl = url
@@ -38,10 +49,19 @@ 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 * 1024,
+            .scalingMode: ScalingMode.cropSourceToCleanAperture
+        ]
+    }
+  
     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..e534e2c 100644
--- a/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPView.swift
+++ b/node_modules/react-native-rtmp-publisher/ios/RTMPManager/RTMPView.swift
@@ -37,23 +37,18 @@ class RTMPView: UIView {
     hkView = MTHKView(frame: UIScreen.main.bounds)
     hkView.videoGravity = .resizeAspectFill

-    RTMPCreator.stream.captureSettings = [
-        .fps: 30,
-        .sessionPreset: AVCaptureSession.Preset.hd1920x1080,
-        .continuousAutofocus: true,
-        .continuousExposure: true
-    ]
+    RTMPCreator.stream.frameRate = 30
+    RTMPCreator.stream.sessionPreset = AVCaptureSession.Preset.hd1920x1080

     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 * 1024,
+      .scalingMode: ScalingMode.cropSourceToCleanAperture
     ]

     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)

@@ -68,8 +63,12 @@ class RTMPView: UIView {
      }

     override func removeFromSuperview() {
-        print("ON REMOVE")
-    }
+        RTMPCreator.stream.attachAudio(nil)
+        RTMPCreator.stream.attachCamera(nil)
+        if #available(iOS 13.0, *) {
+            RTMPCreator.stream.attachMultiCamera(nil)
+        }
+     }

     @objc
     private func statusHandler(_ notification: Notification){
@@ -84,6 +83,7 @@ class RTMPView: UIView {
               onConnectionSuccess!(nil)
             }
            changeStreamState(status: "CONNECTING")
+           RTMPCreator.stream.publish(streamName as String)
            break

        case RTMPConnection.Code.connectFailed.rawValue:
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..e0d2760 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,19 @@ 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 videoSettings = VideoSettingsType(width: width, height: height, bitrate: bitrate)
+        resolve(RTMPCreator.setVideoSettings(videoSettings))
+    }
+
+
     @objc
     func stopStream(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
         RTMPCreator.stopPublish()
@@ -27,18 +40,20 @@ class RTMPModule: NSObject {

     @objc
     func mute(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
-        RTMPCreator.stream.audioSettings[.muted] = true
+        RTMPCreator.stream.hasAudio = false
     }

     @objc
     func unmute(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
-        RTMPCreator.stream.audioSettings[.muted] = false
+        RTMPCreator.stream.hasAudio = true
     }

     @objc
     func switchCamera(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
         cameraPosition = cameraPosition == .back ? .front : .back
-        RTMPCreator.stream.attachCamera(DeviceUtil.device(withPosition: cameraPosition))
+        RTMPCreator.stream.attachCamera(
+            AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: cameraPosition)
+        )
     }

     @objc
@@ -48,7 +63,7 @@ class RTMPModule: NSObject {

     @objc
     func isMuted(_ resolve: (RCTPromiseResolveBlock), reject: (RCTPromiseRejectBlock)){
-        resolve(RTMPCreator.stream.audioSettings[.muted])
+        resolve(RTMPCreator.stream.hasAudio)
     }

     @objc
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..888f545 100644
--- a/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js
+++ b/node_modules/react-native-rtmp-publisher/lib/commonjs/RTMPPublisher.js
@@ -34,6 +34,10 @@ const RTMPPublisher = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {

   const startStream = async () => await RTMPModule.startStream();

+  const setVideoSettings = async videoSettings => {
+    await RTMPModule.setVideoSettings(videoSettings);
+  };
+
   const stopStream = async () => await RTMPModule.stopStream();

   const isStreaming = async () => RTMPModule.isStreaming();
@@ -102,7 +106,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..05396e3 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","setVideoSettings","videoSettings","console","log","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  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   * 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    const setVideoSettings = async (videoSettings: VideoSettingsType) => {\n      await RTMPModule.setVideoSettings(videoSettings);\n    };\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      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.map b/node_modules/react-native-rtmp-publisher/lib/commonjs/types.js.map
index 5c5fd9e..d4d977f 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":";;;;;;IAkFYA,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   * 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  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\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/RTMPPublisher.js b/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js
index d834c39..ef57155 100644
--- a/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js
+++ b/node_modules/react-native-rtmp-publisher/lib/module/RTMPPublisher.js
@@ -18,6 +18,10 @@ const RTMPPublisher = /*#__PURE__*/forwardRef((_ref, ref) => {

   const startStream = async () => await RTMPModule.startStream();

+  const setVideoSettings = async videoSettings => {
+    await RTMPModule.setVideoSettings(videoSettings);
+  };
+
   const stopStream = async () => await RTMPModule.stopStream();

   const isStreaming = async () => RTMPModule.isStreaming();
@@ -86,7 +90,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..c1c3c49 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","setVideoSettings","videoSettings","console","log","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  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   * 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    const setVideoSettings = async (videoSettings: VideoSettingsType) => {\n      await RTMPModule.setVideoSettings(videoSettings);\n    };\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      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.map b/node_modules/react-native-rtmp-publisher/lib/module/types.js.map
index a00b7f2..4e40e61 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":"AAkFA,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   * 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  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\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/RTMPPublisher.d.ts b/node_modules/react-native-rtmp-publisher/lib/typescript/RTMPPublisher.d.ts
index dc79cdd..c4d50e5 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
@@ -2,6 +2,7 @@ import React from 'react';
 import { ViewStyle } from 'react-native';
 import type { RTMPPublisherRefProps, StreamState, BluetoothDeviceStatuses } from './types';
 export interface RTMPPublisherProps {
+    testID?: string;
     style?: ViewStyle;
     streamURL: string;
     streamName: string;
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..106b5d7 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,6 +56,10 @@ 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;
@@ -85,3 +89,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/react-native-rtmp-publisher.podspec b/node_modules/react-native-rtmp-publisher/react-native-rtmp-publisher.podspec
index 584732b..6e6dd17 100644
--- a/node_modules/react-native-rtmp-publisher/react-native-rtmp-publisher.podspec
+++ b/node_modules/react-native-rtmp-publisher/react-native-rtmp-publisher.podspec
@@ -10,12 +10,12 @@ Pod::Spec.new do |s|
   s.license      = package["license"]
   s.authors      = package["author"]

-  s.platforms    = { :ios => "10.0" }
+  s.platforms    = { :ios => "11.0" }
   s.source       = { :git => "https://github.com/ezranbayantemur/react-native-rtmp-publisher.git", :tag => "#{s.version}" }

   s.source_files = "ios/**/*.{h,m,mm,swift}"

   s.dependency "React-Core"
-  s.dependency "HaishinKit", "~> 1.2.7"
+  s.dependency "HaishinKit", "~> 1.4.3"

 end
diff --git a/node_modules/react-native-rtmp-publisher/src/RTMPPublisher.tsx b/node_modules/react-native-rtmp-publisher/src/RTMPPublisher.tsx
index 7f11946..66fbaad 100644
--- a/node_modules/react-native-rtmp-publisher/src/RTMPPublisher.tsx
+++ b/node_modules/react-native-rtmp-publisher/src/RTMPPublisher.tsx
@@ -14,10 +14,12 @@ import type {
   StreamState,
   BluetoothDeviceStatuses,
   AudioInputType,
+  VideoSettingsType,
 } from './types';

 const RTMPModule = NativeModules.RTMPPublisher;
 export interface RTMPPublisherProps {
+  testID?: string;
   style?: ViewStyle;
   streamURL: string;
   streamName: string;
@@ -95,6 +97,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 +146,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..24a667d 100644
--- a/node_modules/react-native-rtmp-publisher/src/types.ts
+++ b/node_modules/react-native-rtmp-publisher/src/types.ts
@@ -57,6 +57,10 @@ 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 {
@@ -93,3 +97,9 @@ export enum AudioInputType {
   SPEAKER = 1,
   WIRED_HEADSET = 2,
 }
+
+export interface VideoSettingsType {
+  width: number;
+  height: number;
+  bitrate: number;
+}