Skip to content

Commit

Permalink
Merge pull request #7 from apivideo/feat/OnEventsLive
Browse files Browse the repository at this point in the history
Feat/on events live
  • Loading branch information
ThibaultBee authored Nov 18, 2021
2 parents dc8cac7 + b3cbd9b commit de9dd2f
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 74 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ const App = () => {
orientation: 'portrait',
}}
liveStreamKey="your-livestrem-key"
onConnectionSuccess={() => {
//do what you want
}}
onConnectionFailed={(e) => {
//do what you want
}}
onDisconnect={() => {
//do what you want
}}
/>
<View style={{ position: 'absolute', bottom: 40 }}>
<TouchableOpacity
Expand Down Expand Up @@ -147,6 +156,13 @@ type ReactNativeLivestreamProps = {
// default: 128000
bitrate?: number;
};
// will be called when the connection is successful
onConnectionSuccess?: (event: NativeSyntheticEvent<{ }>) => void;
// will be called on connection's error
onConnectionFailed?: (event: NativeSyntheticEvent<{ code: string }>) => void;
// will be called when the live-stream is stopped
onDisconnect?: (event: NativeSyntheticEvent<{ }>) => void;

};

type ReactNativeLivestreamMethods = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import com.pedro.encoder.input.video.CameraHelper
import net.ossrs.rtmp.ConnectCheckerRtmp
import video.api.livestream_module.ApiVideoLiveStream
import video.api.livestream_module.Resolution
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReactContext
import com.facebook.react.uimanager.events.RCTEventEmitter


private fun getResolutionFromResolutionString(resolutionString: String?): Resolution {
return when (resolutionString) {
Expand All @@ -32,6 +37,17 @@ private fun getFacingFromCameraString(resolutionString: String?): CameraHelper.F
}
}

enum class Events(private val mName: String) {
CONNECTION_SUCCESS("onConnectionSuccess"),
CONNECTION_FAILED("onConnectionFailed"),
DISCONNECT("onDisconnect");

override fun toString(): String {
return mName
}
}


class ReactNativeLivestreamViewManager : SimpleViewManager<View>(), ConnectCheckerRtmp {
override fun getName() = "ReactNativeLivestreamView"

Expand All @@ -48,6 +64,16 @@ class ReactNativeLivestreamViewManager : SimpleViewManager<View>(), ConnectCheck

private lateinit var apiVideo: ApiVideoLiveStream

private var code: String? = null

override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Map<String, String>>? {
val builder: MapBuilder.Builder<String, Map<String, String>> = MapBuilder.builder<String, Map<String, String>>()
for (event in Events.values()) {
builder.put(event.toString(), MapBuilder.of("registrationName", event.toString()))
}
return builder.build()
}

override fun createViewInstance(reactContext: ThemedReactContext): View {
context = reactContext
view = ReactNativeLivestreamView(reactContext)
Expand Down Expand Up @@ -78,6 +104,25 @@ class ReactNativeLivestreamViewManager : SimpleViewManager<View>(), ConnectCheck
)
}

private fun sendConnectionSuccessEvent() {
val reactContext = context as ReactContext
val payload = Arguments.createMap()
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(view.id, Events.CONNECTION_SUCCESS.toString(), payload)
}

private fun sendConnectionFailedEvent(reason: String?) {
val reactContext = context as ReactContext
val payload = Arguments.createMap()
payload.putString("reason", reason)
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(view.id, Events.CONNECTION_FAILED.toString(), payload)
}

private fun sendDisconnectEvent() {
val reactContext = context as ReactContext
val payload = Arguments.createMap()
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(view.id, Events.DISCONNECT.toString(), payload)
}

@ReactProp(name = "liveStreamKey")
fun setLiveStreamKey(view: View, newLiveStreamKey: String) {
if (newLiveStreamKey == liveStreamKey) return
Expand Down Expand Up @@ -146,10 +191,12 @@ class ReactNativeLivestreamViewManager : SimpleViewManager<View>(), ConnectCheck

override fun onConnectionSuccessRtmp() {
Log.e("connection rtmp", "success")
sendConnectionSuccessEvent()
}

override fun onConnectionFailedRtmp(reason: String) {
Log.e("connection rtmp", "error")
sendConnectionFailedEvent(reason)
}

override fun onNewBitrateRtmp(bitrate: Long) {
Expand All @@ -158,6 +205,7 @@ class ReactNativeLivestreamViewManager : SimpleViewManager<View>(), ConnectCheck

override fun onDisconnectRtmp() {
Log.e("disconnect rtmp", "success")
sendDisconnectEvent()
}

override fun onAuthErrorRtmp() {
Expand Down
4 changes: 2 additions & 2 deletions api-video-react-native-livestream.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ Pod::Spec.new do |s|
s.authors = package["author"]

s.platforms = { :ios => "10.0" }
s.source = { :git => "https://github.com/apivideo/RN-LiveStream.git", :tag => "#{s.version}" }
s.source = { :git => "https://github.com/apivideo/api.video-reactnative-live-stream.git", :tag => "#{s.version}" }

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

s.dependency "React-Core"
s.dependency "LiveStreamIos", '~> 0.0.2'
s.dependency "LiveStreamIos", '0.0.4'
end
18 changes: 9 additions & 9 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PODS:
- api-video-react-native-livestream (0.1.0):
- LiveStreamIos (~> 0.0.2)
- LiveStreamIos (= 0.0.4)
- React-Core
- boost-for-react-native (1.63.0)
- CocoaAsyncSocket (7.6.5)
Expand Down Expand Up @@ -80,11 +80,11 @@ PODS:
- DoubleConversion
- glog
- glog (0.3.5)
- HaishinKit (1.1.5):
- Logboard (~> 2.2.1)
- HaishinKit (1.2.1):
- Logboard (~> 2.2.2)
- libevent (2.1.12)
- LiveStreamIos (0.0.2):
- HaishinKit (~> 1.1.0)
- LiveStreamIos (0.0.4):
- HaishinKit (= 1.2.1)
- Logboard (2.2.2)
- OpenSSL-Universal (1.1.180)
- RCTRequired (0.63.4)
Expand Down Expand Up @@ -442,7 +442,7 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
api-video-react-native-livestream: caad2230ceac5eb371df19dbdd530334abc0c8b9
api-video-react-native-livestream: 8afd2fef9d12a42fb1b4899e46bb10bcc9a5e2f7
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: cde416483dac037923206447da6e1454df403714
Expand All @@ -457,9 +457,9 @@ SPEC CHECKSUMS:
FlipperKit: 651f50a42eb95c01b3e89a60996dd6aded529eeb
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
HaishinKit: 5cf385a823dee6b299404877edf418974422bf9f
HaishinKit: 2b924f6ce90483e373f7079de90b2496fea30241
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LiveStreamIos: dffd0e5d6f9fb712f72ac87eb018e0396bc1284e
LiveStreamIos: 6bd9055c6eebfd91f5df0fbd2eb334a9cc5bdb68
Logboard: 0ab6bbd984ed032b3f0b615cef06779a73445c80
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
Expand Down Expand Up @@ -487,4 +487,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 3203bd2aee4bd5eb29a8aedac7fe8e213a8b774d

COCOAPODS: 1.10.1
COCOAPODS: 1.11.2
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@
};
2D02E47A1E0B4A5D006451C7 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = VY3VXRC7P4;
ProvisioningStyle = Automatic;
};
2D02E48F1E0B4A5D006451C7 = {
Expand Down Expand Up @@ -398,7 +399,7 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-ReactNativeLivestreamExample/Pods-ReactNativeLivestreamExample-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
Expand Down Expand Up @@ -620,6 +621,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = VY3VXRC7P4;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "ReactNativeLivestreamExample-tvOS/Info.plist";
Expand Down Expand Up @@ -648,6 +650,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = VY3VXRC7P4;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "ReactNativeLivestreamExample-tvOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
Expand Down
40 changes: 8 additions & 32 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
View,
TouchableOpacity,
Platform,
// PermissionsAndroid,
Text,
} from 'react-native';
import {
Expand All @@ -24,34 +23,6 @@ export default function App() {
'landscape' | 'portrait'
>('landscape');

// const requestPermissions = async () => {
// try {
// PermissionsAndroid.request;
// const granted = await PermissionsAndroid.requestMultiple([
// PermissionsAndroid.PERMISSIONS.CAMERA,
// PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
// ]);
// if (
// granted['android.permission.CAMERA'] ===
// PermissionsAndroid.RESULTS.GRANTED
// ) {
// console.log('You can use the camera');
// } else {
// console.log('Camera permission denied');
// }
// if (
// granted['android.permission.RECORD_AUDIO'] ===
// PermissionsAndroid.RESULTS.GRANTED
// ) {
// console.log('You can use the microphone');
// } else {
// console.log('Microphone permission denied');
// }
// } catch (err) {
// console.warn(err);
// }
// };

return (
<View style={styles.container}>
<LivestreamView
Expand All @@ -71,8 +42,14 @@ export default function App() {
audio={{
muted: audioMuted,
}}
onStatusChange={(e) => {
console.log('Received onStatusChange', e.nativeEvent);
onConnectionSuccess={() => {
console.log('Received onConnectionSuccess');
}}
onConnectionFailed={(e) => {
console.log('Received onConnectionFailed', e);
}}
onDisconnect={() => {
console.log('Received onDisconnect');
}}
/>
<View style={{ position: 'absolute', bottom: 40 }}>
Expand All @@ -84,7 +61,6 @@ export default function App() {
height: 50,
}}
onPress={() => {
//requestPermissions()
if (streaming) {
ref.current?.stopStreaming();
setStreaming(false);
Expand Down
27 changes: 4 additions & 23 deletions ios/ReactNativeLivestream.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@
objectVersion = 46;
objects = {

/* Begin PBXBuildFile section */

5E555C0D2413F4C50049A1A2 /* ReactNativeLivestream.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* ReactNativeLivestream.m */; };
F4FF95D7245B92E800C19C63 /* ReactNativeLivestream.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* ReactNativeLivestream.swift */; };

/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
58B511D91A9E6C8500147676 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
Expand All @@ -27,11 +20,9 @@

/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libReactNativeLivestream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactNativeLivestream.a; sourceTree = BUILT_PRODUCTS_DIR; };

B3E7B5891CC2AC0600A0062D /* ReactNativeLivestream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReactNativeLivestream.m; sourceTree = "<group>"; };
C7B0344B270E645E004FB4FA /* ReactNativeLivestreamView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactNativeLivestreamView.swift; sourceTree = "<group>"; };
C7B0344C270E6480004FB4FA /* ReactNativeLivestreamViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactNativeLivestreamViewManager.swift; sourceTree = "<group>"; };
F4FF95D5245B92E700C19C63 /* ReactNativeLivestream-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ReactNativeLivestream-Bridging-Header.h"; sourceTree = "<group>"; };
F4FF95D6245B92E800C19C63 /* ReactNativeLivestream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactNativeLivestream.swift; sourceTree = "<group>"; };

/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -56,11 +47,9 @@
58B511D21A9E6C8500147676 = {
isa = PBXGroup;
children = (

F4FF95D6245B92E800C19C63 /* ReactNativeLivestream.swift */,
B3E7B5891CC2AC0600A0062D /* ReactNativeLivestream.m */,
C7B0344B270E645E004FB4FA /* ReactNativeLivestreamView.swift */,
C7B0344C270E6480004FB4FA /* ReactNativeLivestreamViewManager.swift */,
F4FF95D5245B92E700C19C63 /* ReactNativeLivestream-Bridging-Header.h */,

134814211AA4EA7D00B7C361 /* Products */,
);
sourceTree = "<group>";
Expand Down Expand Up @@ -122,10 +111,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (

F4FF95D7245B92E800C19C63 /* ReactNativeLivestream.swift in Sources */,
B3E7B58A1CC2AC0600A0062D /* ReactNativeLivestream.m in Sources */,

);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -238,11 +223,9 @@
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = ReactNativeLivestream;
SKIP_INSTALL = YES;

SWIFT_OBJC_BRIDGING_HEADER = "ReactNativeLivestream-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;

};
name = Debug;
};
Expand All @@ -259,10 +242,8 @@
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = ReactNativeLivestream;
SKIP_INSTALL = YES;

SWIFT_OBJC_BRIDGING_HEADER = "ReactNativeLivestream-Bridging-Header.h";
SWIFT_VERSION = 5.0;

};
name = Release;
};
Expand Down
Loading

0 comments on commit de9dd2f

Please sign in to comment.