Skip to content

Commit

Permalink
feat: support Uint8Array for stream message and metadata (#664)
Browse files Browse the repository at this point in the history
* feat: support Uint8Array for stream message and metadata

* ci: optimize for 3.x branch

* style: fix lint issue
  • Loading branch information
LichKing-2234 authored Jun 29, 2023
1 parent 03d9168 commit b4a122f
Show file tree
Hide file tree
Showing 21 changed files with 173 additions and 58 deletions.
1 change: 0 additions & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ runs:
${{ runner.os }}-yarn-
- name: Install dependencies
if: steps.yarn-cache.outputs.cache-hit != 'true'
run: |
yarn install --frozen-lockfile
shell: bash
27 changes: 16 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Build API Example
run-name: ${{ github.actor }} triggered this job

on:
workflow_dispatch:

jobs:
build-android:
runs-on: ubuntu-latest
Expand All @@ -13,8 +14,7 @@ jobs:

- name: SetupExample
run: |
yarn install --frozen-lockfile
working-directory: example
yarn example install --frozen-lockfile
- name: Modify APP ID
run: |
Expand All @@ -31,7 +31,7 @@ jobs:
with:
name: AgoraRtcExample
path: |
example/android/**/*.apk
example/android/app/build/outputs/apk/release/*.apk
build-ios:
runs-on: macos-latest
Expand All @@ -43,14 +43,23 @@ jobs:

- uses: actions/cache@v3
with:
path: example/ios/Pods
path: |
**/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
${{ runner.os }}-pods
- uses: hendrikmuhs/ccache-action@v1.2
with:
max-size: 1024M
key: ${{ runner.os }}-ccache
restore-keys: |
${{ runner.os }}-ccache
- name: SetupExample
run: |
yarn
yarn example install --frozen-lockfile
yarn example pods
- name: Modify APP ID
run: |
Expand Down Expand Up @@ -87,10 +96,6 @@ jobs:
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- uses: hendrikmuhs/ccache-action@v1.2
with:
max-size: 5G

- name: Fastlane build
env:
CC: clang
Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: CI

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

on:
push:
branches:
- main
- 3.x
pull_request:
branches:
- main
- 3.x
- release/*

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup

- name: Lint files
run: yarn lint

- name: Typecheck files
run: |
yarn example install --frozen-lockfile
yarn typescript
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup

- name: Build package
run: yarn prepare
21 changes: 21 additions & 0 deletions .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: gitleaks

on:
pull_request:
push:
workflow_dispatch:
schedule:
- cron: "0 4 * * *" # run once a day at 4 AM

jobs:
scan:
name: gitleaks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} # Only required for Organizations, not personal accounts.
11 changes: 7 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Publish to NPM
run-name: ${{ github.actor }} triggered this job

on:
workflow_dispatch:
inputs:
Expand All @@ -22,6 +22,7 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.GH_TOKEN }}

- name: Setup
uses: ./.github/actions/setup
Expand All @@ -30,12 +31,14 @@ jobs:
run: |
npm set "//registry.npmjs.org/:_authToken" ${{ secrets.NPM_TOKEN }}
- if: ${{ inputs.dry-run }}
- name: Dry Run Release
if: ${{ inputs.dry-run }}
run: |
yarn release ${{ inputs.increment }} -d --ci
- if: ${{ !inputs.dry-run }}
- name: NPM Publish
if: ${{ !inputs.dry-run }}
run: |
git config --global user.email "${{ secrets.GIT_EMAIL }}"
git config --global user.name "${{ secrets.GIT_USERNAME }}"
yarn release ${{ inputs.increment }} --ci
yarn release ${{ inputs.increment }} --ci --npm.allowSameVersion
13 changes: 8 additions & 5 deletions android/src/main/java/io/agora/rtc/base/MediaObserver.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package io.agora.rtc.base

import android.util.Base64
import androidx.annotation.IntRange
import io.agora.rtc.IMetadataObserver
import java.util.*
import java.util.Collections
import java.util.concurrent.atomic.AtomicInteger

class MediaObserver(
private val emit: (data: Map<String, Any?>?) -> Unit
) : IMetadataObserver {
private var maxMetadataSize = AtomicInteger(1024)
private var metadataList = Collections.synchronizedList<String>(mutableListOf())
private var metadataList = Collections.synchronizedList<ByteArray>(mutableListOf())

fun addMetadata(metadata: String) {
fun addMetadata(metadata: ByteArray) {
metadataList.add(metadata)
}

Expand All @@ -21,7 +22,7 @@ class MediaObserver(

override fun onReadyToSendMetadata(timeStampMs: Long): ByteArray? {
if (metadataList.size > 0) {
return metadataList.removeAt(0).toByteArray()
return metadataList.removeAt(0)
}
return null
}
Expand All @@ -33,7 +34,9 @@ class MediaObserver(
override fun onMetadataReceived(buffer: ByteArray, uid: Int, timeStampMs: Long) {
emit(
hashMapOf(
"data" to arrayListOf(String(buffer), uid.toUInt().toLong(), timeStampMs)
"data" to arrayListOf(
Base64.encodeToString(buffer, Base64.DEFAULT), uid.toUInt().toLong(), timeStampMs
)
)
)
}
Expand Down
5 changes: 3 additions & 2 deletions android/src/main/java/io/agora/rtc/base/RtcChannel.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.agora.rtc.base

import android.util.Base64
import io.agora.rtc.IMetadataObserver
import io.agora.rtc.RtcChannel
import io.agora.rtc.RtcEngine
Expand Down Expand Up @@ -479,7 +480,7 @@ class RtcChannelManager(

override fun sendMetadata(params: Map<String, *>, callback: Callback) {
callback.resolve(mediaObserverMap[params["channelId"] as String]) {
it.addMetadata(params["metadata"] as String)
it.addMetadata(Base64.decode(params["metadata"] as String, Base64.DEFAULT))
Unit
}
}
Expand Down Expand Up @@ -541,7 +542,7 @@ class RtcChannelManager(
callback.code(
RtcChannelManager[params["channelId"] as String]?.sendStreamMessage(
(params["streamId"] as Number).toInt(),
(params["message"] as String).toByteArray()
Base64.decode((params["message"] as String), Base64.DEFAULT)
)
)
}
Expand Down
4 changes: 3 additions & 1 deletion android/src/main/java/io/agora/rtc/base/RtcChannelEvent.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.agora.rtc.base

import android.util.Base64
import androidx.annotation.IntRange
import io.agora.rtc.IRtcChannelEventHandler
import io.agora.rtc.IRtcEngineEventHandler
Expand Down Expand Up @@ -319,7 +320,8 @@ class RtcChannelEventHandler(
rtcChannel,
uid.toUInt().toLong(),
streamId,
data?.let { String(it, Charsets.UTF_8) })
Base64.encodeToString(data, Base64.DEFAULT)
)
}

override fun onStreamMessageError(
Expand Down
5 changes: 3 additions & 2 deletions android/src/main/java/io/agora/rtc/base/RtcEngine.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.agora.rtc.base

import android.content.Context
import android.util.Base64
import io.agora.rtc.*
import io.agora.rtc.internal.EncryptionConfig
import io.agora.rtc.mediaio.AgoraDefaultSource
Expand Down Expand Up @@ -1369,7 +1370,7 @@ open class RtcEngineManager(

override fun sendMetadata(params: Map<String, *>, callback: Callback) {
callback.resolve(mediaObserver) {
it.addMetadata(params["metadata"] as String)
it.addMetadata(Base64.decode(params["metadata"] as String, Base64.DEFAULT))
}
}

Expand Down Expand Up @@ -1526,7 +1527,7 @@ open class RtcEngineManager(
callback.code(
engine?.sendStreamMessage(
(params["streamId"] as Number).toInt(),
(params["message"] as String).toByteArray()
Base64.decode((params["message"] as String), Base64.DEFAULT)
)
)
}
Expand Down
4 changes: 3 additions & 1 deletion android/src/main/java/io/agora/rtc/base/RtcEngineEvent.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.agora.rtc.base

import android.graphics.Rect
import android.util.Base64
import androidx.annotation.IntRange
import io.agora.rtc.AgoraMediaRecorder
import io.agora.rtc.Constants
Expand Down Expand Up @@ -478,7 +479,8 @@ class RtcEngineEventHandler(
RtcEngineEvents.StreamMessage,
uid.toUInt().toLong(),
streamId,
data?.let { String(it, Charsets.UTF_8) })
Base64.encodeToString(data, Base64.DEFAULT)
)
}

override fun onStreamMessageError(
Expand Down
19 changes: 12 additions & 7 deletions example/src/examples/advanced/StreamMessage/StreamMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
View,
} from 'react-native';

import { Buffer } from 'buffer';
import RtcEngine, {
ChannelProfile,
ClientRole,
Expand Down Expand Up @@ -102,12 +103,16 @@ export default class StreamMessage extends Component<{}, State, any> {
});
this._engine?.addListener('StreamMessage', (uid, streamId, data) => {
console.info('UserOffline', uid, streamId, data);
Alert.alert(`Receive from uid:${uid}`, `StreamId ${streamId}:${data}`, [
{
text: 'Ok',
onPress: () => {},
},
]);
Alert.alert(
`Receive from uid:${uid}`,
`StreamId ${streamId}:${data.toString()}`,
[
{
text: 'Ok',
onPress: () => {},
},
]
);
});
this._engine?.addListener(
'StreamMessageError',
Expand Down Expand Up @@ -210,7 +215,7 @@ export default class StreamMessage extends Component<{}, State, any> {
new DataStreamConfig(true, true)
);

await this._engine?.sendStreamMessage(streamId!, message);
await this._engine?.sendStreamMessage(streamId!, Buffer.from(message));
this.setState({ message: '' });
};
}
Expand Down
8 changes: 4 additions & 4 deletions ios/RCTAgora/Base/MediaObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import Foundation
class MediaObserver: NSObject {
private var emitter: (_ data: [String: Any?]?) -> Void
private var maxMetadataSize = 1024
private var metadataList = [String]()
private var metadataList = [Data]()

init(_ emitter: @escaping (_ data: [String: Any?]?) -> Void) {
self.emitter = emitter
}

func addMetadata(_ metadata: String) {
func addMetadata(_ metadata: Data) {
metadataList.append(metadata)
}

Expand All @@ -34,7 +34,7 @@ extension MediaObserver: AgoraMediaMetadataDataSource {

func readyToSendMetadata(atTimestamp _: TimeInterval) -> Data? {
if metadataList.count > 0 {
return metadataList.remove(at: 0).data(using: .utf8)
return metadataList.remove(at: 0)
}
return nil
}
Expand All @@ -43,7 +43,7 @@ extension MediaObserver: AgoraMediaMetadataDataSource {
extension MediaObserver: AgoraMediaMetadataDelegate {
func receiveMetadata(_ data: Data, fromUser uid: Int, atTimestamp timestamp: TimeInterval) {
emitter([
"data": [String(data: data, encoding: .utf8) ?? "", uid, timestamp],
"data": [data.base64EncodedString(options: .endLineWithLineFeed), uid, timestamp],
])
}
}
4 changes: 2 additions & 2 deletions ios/RCTAgora/Base/RtcChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ class RtcChannelManager: NSObject, RtcChannelInterface {

@objc func sendMetadata(_ params: NSDictionary, _ callback: Callback) {
callback.resolve(mediaObserverMap[params["channelId"] as! String]) {
$0.addMetadata(params["metadata"] as! String)
$0.addMetadata(Data(base64Encoded: (params["metadata"] as! String), options: .ignoreUnknownCharacters)!)
}
}

Expand Down Expand Up @@ -386,7 +386,7 @@ class RtcChannelManager: NSObject, RtcChannelInterface {
}

@objc func sendStreamMessage(_ params: NSDictionary, _ callback: Callback) {
callback.code(self[params["channelId"] as! String]?.sendStreamMessage((params["streamId"] as! NSNumber).intValue, data: (params["message"] as! String).data(using: .utf8)!))
callback.code(self[params["channelId"] as! String]?.sendStreamMessage((params["streamId"] as! NSNumber).intValue, data: Data(base64Encoded: (params["message"] as! String), options: .ignoreUnknownCharacters)!))
}

@objc func enableRemoteSuperResolution(_ params: NSDictionary, _ callback: Callback) {
Expand Down
Loading

0 comments on commit b4a122f

Please sign in to comment.