diff --git a/.spelling b/.spelling index bbf75a0..71e8dcb 100644 --- a/.spelling +++ b/.spelling @@ -22,3 +22,7 @@ pre-configured TabItem AndroidManifest.xml iOS +Xcode +UI +dev +Podfile diff --git a/guide/react-native/assets/ios-new-folder.png b/guide/react-native/assets/ios-new-folder.png new file mode 100644 index 0000000..59299cf Binary files /dev/null and b/guide/react-native/assets/ios-new-folder.png differ diff --git a/guide/react-native/assets/ios-new-group.png b/guide/react-native/assets/ios-new-group.png new file mode 100644 index 0000000..8ec7c41 Binary files /dev/null and b/guide/react-native/assets/ios-new-group.png differ diff --git a/guide/react-native/assets/ios-new-target.png b/guide/react-native/assets/ios-new-target.png new file mode 100644 index 0000000..4ecff35 Binary files /dev/null and b/guide/react-native/assets/ios-new-target.png differ diff --git a/guide/react-native/background.mdx b/guide/react-native/background.mdx new file mode 100644 index 0000000..cd0272c --- /dev/null +++ b/guide/react-native/background.mdx @@ -0,0 +1,56 @@ +--- +sidebar_position: 6 +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +# Streaming from background + +On Android, it is possible to continue streaming when app is in background. Unfortunately this functionality is not available on iOS (due to Apple limitations) + +Below is configuration required to make it work: + + + + + +You need to modify `app.json` file and add our plugin: + +```json +{ + "expo": { + ... + "plugins": { + ... + [ + "@fishjam-cloud/react-native-client", + { + "android": { + "enableForegroundService": true + } + } + ], + ... + } + } +} +``` + + + + +You need to modify `AndroidManifest.xml` file and add below service: + +```xml + + ... + + ... + + + +``` + + + diff --git a/guide/react-native/connecting.mdx b/guide/react-native/connecting.mdx index 8619ce6..c0a3d24 100644 --- a/guide/react-native/connecting.mdx +++ b/guide/react-native/connecting.mdx @@ -15,7 +15,7 @@ In order to connect, you need to retrieve URL (multimedia server address) and to - + Once you get your account on [Fishjam Cloud](https://fishjam.io), you will have access to Sandbox App. This app comes with pre-configured test service called Room Manager. This is basically service that will diff --git a/guide/react-native/installation.mdx b/guide/react-native/installation.mdx index 5cf1079..4e48386 100644 --- a/guide/react-native/installation.mdx +++ b/guide/react-native/installation.mdx @@ -7,7 +7,9 @@ import TabItem from "@theme/TabItem"; # Installation -## Create new App +How to install package in your mobile app + +## Optional: Create new App
Follow these steps to create a new mobile app @@ -73,7 +75,7 @@ You need to modify `app.json` file and add all permissions: -You need to modify AndroidManifest.xml file, and these lines: +You need to modify `AndroidManifest.xml` file, and these lines: ```xml diff --git a/guide/react-native/screensharing.mdx b/guide/react-native/screensharing.mdx new file mode 100644 index 0000000..ba0cfca --- /dev/null +++ b/guide/react-native/screensharing.mdx @@ -0,0 +1,192 @@ +--- +sidebar_position: 5 +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +# Screen sharing + +Our SDK also allow to stream content of mobile device screen. + +## Installation + +### Android + +To enable screen sharing on android, you need enable foreground services. Here is [instruction on how to enable it](./background). + +### iOS + +To enable screen share feature on iOS, you need to follow below steps + + + + + +You need to modify `app.json` file and add our plugin: + +```json +{ + "expo": { + ... + "plugins": { + ... + [ + "@fishjam-cloud/react-native-client", + { + "ios": { + "enableScreensharing": true + } + } + ], + ... + } + } +} +``` + + + + +Configuring screen sharing on iOS is a little complicated. + +1. Add camera and microphone permissions to your main `Info.plist`. + + ```xml + NSCameraUsageDescription + Allow $(PRODUCT_NAME) to use the camera + NSMicrophoneUsageDescription + Allow $(PRODUCT_NAME) to use the microphone + ``` + +1. Open your `.xcworkspace` in Xcode + +1. Create new Broadcast Upload Extension. Select `File → New → Target... → Broadcast Upload Extension → Next`. Choose the name for the new target, select Swift language and deselect "Include UI Extension". + ![New Target](./assets/ios-new-target.png) + +1. Configure app group. Go to "Signing & Capabilities" tab, click "+ Capability" button in upper left corner and select "App Groups". + + ![New Group](./assets/ios-new-group.png) + Then in the "App Groups" add a new group or select existing. Usually group name has format `group.`. Verify that both app and extension targets have app group and dev team set correctly. + +1. A new folder with app extension should appear on the left with contents like this: + ![New Folder](./assets/ios-new-folder.png) + + Replace `SampleHandler.swift` with `FishjamBroadcastHandler.swift` and this code: + + ```swift + import FishjamCloudClient + import Foundation + import ReplayKit + import WebRTC + import os.log + + let appGroup = "group.{{BUNDLE_IDENTIFIER}}" + + let logger = OSLog(subsystem: "{{BUNDLE_IDENTIFIER}}.FishjamBroadcastHandler", category: "Broadcaster") + + class FishjamBroadcastSampleHandler: RPBroadcastSampleHandler { + let broadcastSource = BroadcastSampleSource(appGroup: appGroup) + var started: Bool = false + + override func broadcastStarted(withSetupInfo _: [String: NSObject]?) { + started = broadcastSource.connect() + + guard started else { + os_log("failed to connect with ipc server", log: logger, type: .debug) + + super.finishBroadcastWithError(NSError(domain: "", code: 0, userInfo: nil)) + + return + } + + broadcastSource.started() + } + + override func broadcastPaused() { + broadcastSource.paused() + } + + override func broadcastResumed() { + broadcastSource.resumed() + } + + override func broadcastFinished() { + broadcastSource.finished() + } + + override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) { + guard started else { + return + } + + broadcastSource.processFrame(sampleBuffer: sampleBuffer, ofType: sampleBufferType) + } + } + ``` + + Replace `{{BUNDLE_IDENTIFIER}}` with your bundle identifier. + +1. In project's Podfile add the following code: + + ```rb + target 'FishjamScreenBroadcastExtension' do + pod 'FishjamCloudClient/Broadcast' + end + ``` + +1. Add the following constants in your `Info.plist`: + + ```xml + AppGroupName + group.{{BUNDLE_IDENTIFIER}} + ScreencastExtensionBundleId + {{BUNDLE_IDENTIFIER}}.FishjamScreenBroadcastExtension + ``` + +1. Run `pod install`, rebuild your app and enjoy! + + + + +## Usage + +You can use `useScreenShare` hook to enable screen sharing. + +First, you have to make sure that permissions are granted. To do that, you can call `handleScreenSharePermission` method: + +```tsx +import { useScreenShare } from "@fishjam-cloud/react-native-client"; + +function Component() { + const { handleScreenSharePermission } = useScreenShare(); + + useEffect(() => { + function checkPermissions() { + const result = await handleScreenSharePermission(); + if (result === "granted") { + // permissions are granted + } + } + checkPermissions(); + }, []); + + return ; +} +``` + +Then, you can enable/disable screen sharing with `toggleScreenShare` method. And check current state with `isScreenShareOn` property. + +```tsx +import { useScreenShare } from "@fishjam-cloud/react-native-client"; + +function ScreenShareButton() { + const { toggleScreenShare, isScreenShareOn } = useScreenShare(); + + return ( + + ); +} +```