Skip to content

Commit

Permalink
feat(ios): add support for new architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaultBee committed Jan 4, 2024
1 parent c9837bb commit 340f3b5
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 133 deletions.
11 changes: 0 additions & 11 deletions example/ios/_xcode.env

This file was deleted.

20 changes: 20 additions & 0 deletions ios/RNLiveStreamView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This guard prevent this file to be compiled in the old architecture.
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTViewComponentView.h>
#import <React/RCTConversions.h>
#import <WebKit/WKDataDetectorTypes.h>
#import <UIKit/UIKit.h>
#import <react/renderer/components/ApiVideoLiveStreamView/Props.h>

#ifndef RNLiveStreamView_h
#define RNLiveStreamView_h

NS_ASSUME_NONNULL_BEGIN

@interface RNLiveStreamView : RCTViewComponentView
@end

NS_ASSUME_NONNULL_END

#endif /* RNLiveStreamView_h */
#endif /* RCT_NEW_ARCH_ENABLED */
141 changes: 141 additions & 0 deletions ios/RNLiveStreamView.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// This guard prevent the code from being compiled in the old architecture
#ifdef RCT_NEW_ARCH_ENABLED
#import "RNLiveStreamView.h"

#import <react/renderer/components/ApiVideoLiveStreamView/ComponentDescriptors.h>
#import <react/renderer/components/ApiVideoLiveStreamView/EventEmitters.h>
#import <react/renderer/components/ApiVideoLiveStreamView/Props.h>
#import <react/renderer/components/ApiVideoLiveStreamView/RCTComponentViewHelpers.h>

#import "RCTFabricComponentsPlugins.h"

// MARK: Swift classes in ObjC++
#if __has_include("react-native-livestream/react_native_livestream-Swift.h")
#import "react-native-livestream/react_native_livestream-Swift.h"
#else
#import "react_native_livestream-Swift.h"
#endif

using namespace facebook::react;

@class RNLiveStreamViewImpl;

@interface RNLiveStreamView () <RCTApiVideoLiveStreamViewViewProtocol>

@end

// MARK: Implementation

@implementation RNLiveStreamView {
RNLiveStreamViewImpl * _view;
}

// MARK: Initializers
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
static const auto defaultProps = std::make_shared<const ApiVideoLiveStreamViewProps>();
_props = defaultProps;

_view = [[RNLiveStreamViewImpl alloc] init];
// TODO events
/*_view.onConnectionSuccess = [self]() {
if (_eventEmitter) {
auto liveStreamEventEmitter = std::dynamic_pointer_cast<ApiVideoLiveStreamViewEventEmitter() const>(_eventEmitter);
ApiVideoLiveStreamViewEventEmitter::OnConnectionSuccess data = {};
liveStreamEventEmitter->OnConnectionSuccess(data);
}
};
_view.onConnectionFailed = [self](NSString* code) {
if (_eventEmitter) {
auto liveStreamEventEmitter = std::dynamic_pointer_cast<ApiVideoLiveStreamViewEventEmitter() const>(_eventEmitter);
ApiVideoLiveStreamViewEventEmitter::OnConnectionFailed data = {
.code = std::string([code UTF8String])
};
liveStreamEventEmitter->OnConnectionFailed(data);
}
};
_view.onDisconnect = [self]() {
if (_eventEmitter) {
auto liveStreamEventEmitter = std::dynamic_pointer_cast<ApiVideoLiveStreamViewEventEmitter() const>(_eventEmitter);
ApiVideoLiveStreamViewEventEmitter::OnDisconnect data = {};
liveStreamEventEmitter->OnDisconnect(data);
}
};*/

self.contentView = _view;
}
return self;
}

// MARK: Props
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
const auto &oldViewProps = *std::static_pointer_cast<const ApiVideoLiveStreamViewProps>(_props);
const auto &newViewProps = *std::static_pointer_cast<const ApiVideoLiveStreamViewProps>(props);

RNLiveStreamViewImpl *view = (RNLiveStreamViewImpl *)self.contentView;
if (oldViewProps.camera != newViewProps.camera) {
NSString *camera = RCTNSStringFromStringNilIfEmpty(toString(newViewProps.camera));
[view setCamera:camera];
}

if ((oldViewProps.video.bitrate != newViewProps.video.bitrate) || (oldViewProps.video.fps != newViewProps.video.fps) || (oldViewProps.video.resolution != newViewProps.video.resolution) || (oldViewProps.video.gopDuration != newViewProps.video.gopDuration)) {
NSString *resolution = RCTNSStringFromStringNilIfEmpty(toString(newViewProps.video.resolution));
NSDictionary *config = @{ @"bitrate" : @(newViewProps.video.bitrate), @"resolution" : resolution, @"fps" : @(newViewProps.video.fps), @"gopDuration" : @(newViewProps.video.gopDuration)};
[view setVideo:config];
}

if (oldViewProps.isMuted != newViewProps.isMuted) {
[view setIsMuted:newViewProps.isMuted];
}

if ((oldViewProps.audio.bitrate != newViewProps.audio.bitrate) || (oldViewProps.audio.sampleRate != newViewProps.audio.sampleRate) || (oldViewProps.audio.isStereo != newViewProps.audio.isStereo)) {
NSString *sampleRate = RCTNSStringFromStringNilIfEmpty(toString(newViewProps.audio.sampleRate));
NSDictionary *config = @{ @"bitrate" : @(newViewProps.audio.bitrate), @"sampleRate" : @([sampleRate intValue]), @"isStereo" : @(newViewProps.audio.isStereo)};
[view setAudio:config];
}

if (oldViewProps.zoomRatio != newViewProps.zoomRatio) {
[view setZoomRatio:newViewProps.zoomRatio];
}

if (oldViewProps.enablePinchedZoom != newViewProps.enablePinchedZoom) {
[view setEnablePinchedZoom:newViewProps.enablePinchedZoom];
}

[super updateProps:props oldProps:oldProps];
}

// MARK: RCTComponentViewProtocol
- (void)startStreaming:(NSString *)streamKey url:(NSString *)url
{
NSError *error = nil;
[_view startStreaming:streamKey url:url error:&error];

}

- (void)stopStreaming
{
[_view stopStreaming];
}

- (void)setZoomRatioCommand:(float)zoomRatio
{
[_view setZoomRatioWithZoomRatio:zoomRatio];
}

+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<ApiVideoLiveStreamViewComponentDescriptor>();
}

@end

Class<RCTComponentViewProtocol> ApiVideoLiveStreamViewCls(void)
{
return RNLiveStreamView.class;
}

#endif
67 changes: 0 additions & 67 deletions ios/RNLiveStreamView.swift

This file was deleted.

50 changes: 24 additions & 26 deletions ios/RNLiveStreamViewImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ extension AVCaptureDevice.Position {
}
}

class RNLiveStreamViewImpl: UIView {
@objc(RNLiveStreamViewImpl)
public class RNLiveStreamViewImpl: UIView {
private var liveStream: ApiVideoLiveStream!
private var isStreaming: Bool = false

Expand Down Expand Up @@ -103,13 +104,13 @@ class RNLiveStreamViewImpl: UIView {
}
}

@objc var audio: NSDictionary = [:] {
@objc public var audio: NSDictionary = [:] {
didSet {
audioConfig = AudioConfig(bitrate: audio["bitrate"] as! Int)
}
}

@objc var video: NSDictionary = [:] {
@objc public var video: NSDictionary = [:] {
didSet {
if isStreaming {
videoBitrate = video["bitrate"] as! Int
Expand All @@ -122,7 +123,7 @@ class RNLiveStreamViewImpl: UIView {
}
}

@objc var camera: String {
@objc public var camera: String {
get {
return liveStream.cameraPosition.toCameraPositionName()
}
Expand All @@ -135,7 +136,7 @@ class RNLiveStreamViewImpl: UIView {
}
}

@objc var isMuted: Bool {
@objc public var isMuted: Bool {
get {
return liveStream.isMuted
}
Expand All @@ -147,7 +148,7 @@ class RNLiveStreamViewImpl: UIView {
}
}

@objc var zoomRatio: Float {
@objc public var zoomRatio: Float {
get {
return Float(liveStream.zoomRatio)
}
Expand All @@ -156,7 +157,7 @@ class RNLiveStreamViewImpl: UIView {
}
}

@objc var enablePinchedZoom: Bool {
@objc public var enablePinchedZoom: Bool {
get {
return zoomGesture.isEnabled
}
Expand All @@ -165,7 +166,7 @@ class RNLiveStreamViewImpl: UIView {
}
}

@objc func startStreaming(_ streamKey: String, url: String? = nil) throws {
@objc public func startStreaming(_ streamKey: String, url: String?) throws {
if let url = url {
try liveStream.startStreaming(streamKey: streamKey, url: url)
} else {
Expand All @@ -174,15 +175,13 @@ class RNLiveStreamViewImpl: UIView {
isStreaming = true
}

@objc func stopStreaming() {
@objc public func stopStreaming() {
isStreaming = false
liveStream.stopStreaming()
}

@objc func setZoomRatio(zoomRatio: CGFloat) {
if let liveStream = liveStream {
liveStream.zoomRatio = zoomRatio
}
@objc public func setZoomRatio(zoomRatio: CGFloat) {
liveStream.zoomRatio = zoomRatio
}

@objc
Expand All @@ -193,41 +192,40 @@ class RNLiveStreamViewImpl: UIView {
}
}

@objc var onConnectionSuccess: RCTDirectEventBlock?
@objc public var onConnectionSuccess: () -> Void = { }

@objc var onConnectionFailed: RCTDirectEventBlock?
@objc public var onConnectionFailed: (String) -> Void = { _ in }

@objc var onDisconnect: RCTDirectEventBlock?
@objc public var onDisconnect: () -> Void = { }

@objc override public func removeFromSuperview() {
super.removeFromSuperview()
liveStream.stopPreview()
}
}


extension RNLiveStreamViewImpl: ApiVideoLiveStreamDelegate {
/// Called when the connection to the rtmp server is successful
func connectionSuccess() {
onConnectionSuccess?([:])
public func connectionSuccess() {
onConnectionSuccess()
}

/// Called when the connection to the rtmp server failed
func connectionFailed(_ code: String) {
public func connectionFailed(_ code: String) {
isStreaming = false
onConnectionFailed?([
"code": code,
])
onConnectionFailed(code)
}

/// Called when the connection to the rtmp server is closed
func disconnection() {
public func disconnection() {
isStreaming = false
onDisconnect?([:])
onDisconnect()
}

/// Called if an error happened during the audio configuration
func audioError(_: Error) {}
public func audioError(_: Error) {}

/// Called if an error happened during the video configuration
func videoError(_: Error) {}
public func videoError(_: Error) {}
}
Loading

0 comments on commit 340f3b5

Please sign in to comment.