Skip to content

Commit

Permalink
feat(example): add AudioCallRoute, call quality monitoring in JoinCha…
Browse files Browse the repository at this point in the history
…nnelAudio & JoinChannelVideo
  • Loading branch information
guoxianzhe committed Jun 7, 2024
1 parent a8a9a25 commit 6b646e8
Show file tree
Hide file tree
Showing 7 changed files with 575 additions and 32 deletions.
1 change: 1 addition & 0 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Any scene of this project can run successfully alone.

| Demo | Description |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| [AudioCallRoute](./src/examples/advanced/AudioCallRoute) | control audio call route |
| [AudioMixing](./src/examples/advanced/AudioMixing) | Starts playing the music file |
| [AudioSpectrum](./src/examples/advanced/AudioSpectrum) | Turn on audio spectrum monitoring |
| [BeautyEffect](./src/examples/advanced/BeautyEffect) | Sets the image enhancement options |
Expand Down
9 changes: 9 additions & 0 deletions example/src/components/ui/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,13 @@ export const AgoraStyle = StyleSheet.create({
width: '100%',
height: 200,
},
statusBar: {
position: 'absolute',
right: 0,
bottom: 0,
backgroundColor: 'rgba(0,0,0,0.6)',
},
statusBarText: {
color: '#ffffff',
},
});
162 changes: 162 additions & 0 deletions example/src/examples/advanced/AudioCallRoute/AudioCallRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import React, { ReactElement } from 'react';
import {
ChannelProfileType,
ClientRoleType,
IRtcEngineEventHandler,
createAgoraRtcEngine,
} from 'react-native-agora';

import {
BaseAudioComponentState,
BaseComponent,
} from '../../../components/BaseComponent';
import { AgoraDivider, AgoraSwitch } from '../../../components/ui';
import Config from '../../../config/agora.config';
import { askMediaAccess } from '../../../utils/permissions';

interface State extends BaseAudioComponentState {
defaultToSpeaker: boolean;
speakerOn: boolean;
}

export default class AudioCallRoute
extends BaseComponent<{}, State>
implements IRtcEngineEventHandler
{
protected createState(): State {
return {
appId: Config.appId,
enableVideo: false,
channelId: Config.channelId,
token: Config.token,
uid: Config.uid,
joinChannelSuccess: false,
remoteUsers: [],
defaultToSpeaker: false,
speakerOn: false,
};
}

/**
* Step 1: initRtcEngine
*/
protected async initRtcEngine() {
const { appId } = this.state;
if (!appId) {
this.error(`appId is invalid`);
}

this.engine = createAgoraRtcEngine();
this.engine.initialize({
appId,
logConfig: { filePath: Config.logFilePath },
// Should use ChannelProfileLiveBroadcasting on most of cases
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
});
this.engine.registerEventHandler(this);

// Need granted the microphone permission
await askMediaAccess(['android.permission.RECORD_AUDIO']);

// Only need to enable audio on this case
this.engine.enableAudio();
}

/**
* Step 2: joinChannel
*/
protected joinChannel() {
const { channelId, token, uid } = this.state;
if (!channelId) {
this.error('channelId is invalid');
return;
}
if (uid < 0) {
this.error('uid is invalid');
return;
}

// start joining channel
// 1. Users can only see each other after they join the
// same channel successfully using the same app id.
// 2. If app certificate is turned on at dashboard, token is needed
// when joining channel. The channel name and uid used to calculate
// the token has to match the ones used for channel join
this.engine?.joinChannel(token, channelId, uid, {
// Make myself as the broadcaster to send stream to remote
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
});
}

/**
* Step 3-1: setDefaultAudioRouteToSpeakerphone
*/
protected setDefaultAudioRouteToSpeakerphone() {
const { defaultToSpeaker } = this.state;
this.engine?.setDefaultAudioRouteToSpeakerphone(!defaultToSpeaker);
this.setState({
defaultToSpeaker: !defaultToSpeaker,
});
}

/**
* Step 3-2: setEnableSpeakerphone
*/
protected setEnableSpeakerphone() {
const { speakerOn } = this.state;
this.engine?.setEnableSpeakerphone(!speakerOn);
this.setState({
speakerOn: !speakerOn,
});
}

onAudioRoutingChanged(routing: number): void {
this.info('onAudioRoutingChanged', 'routing', routing);
}

/**
* Step 4: leaveChannel
*/
protected leaveChannel() {
this.engine?.leaveChannel();
}

/**
* Step 5: releaseRtcEngine
*/
protected releaseRtcEngine() {
this.engine?.unregisterEventHandler(this);
this.engine?.release();
}

protected renderConfiguration(): ReactElement | undefined {
const { defaultToSpeaker, speakerOn, joinChannelSuccess } = this.state;
return (
<>
<AgoraSwitch
title={'setDefaultAudioRouteToSpeakerphone'}
disabled={joinChannelSuccess}
value={defaultToSpeaker}
onValueChange={() => {
this.setDefaultAudioRouteToSpeakerphone();
}}
/>
<AgoraDivider />
<AgoraSwitch
title={'setEnableSpeakerphone'}
value={speakerOn}
disabled={!joinChannelSuccess}
onValueChange={() => {
this.setEnableSpeakerphone();
}}
/>
<AgoraDivider />
</>
);
}

protected renderAction(): ReactElement | undefined {
// const { startAudioMixing, pauseAudioMixing } = this.state;
return <></>;
}
}
5 changes: 5 additions & 0 deletions example/src/examples/advanced/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import AudioCallRoute from './AudioCallRoute/AudioCallRoute';
import AudioMixing from './AudioMixing/AudioMixing';
import AudioSpectrum from './AudioSpectrum/AudioSpectrum';
import BeautyEffect from './BeautyEffect/BeautyEffect';
Expand Down Expand Up @@ -31,6 +32,10 @@ import VoiceChanger from './VoiceChanger/VoiceChanger';
const Advanced = {
title: 'Advanced',
data: [
{
name: 'AudioCallRoute',
component: AudioCallRoute,
},
{
name: 'AudioMixing',
component: AudioMixing,
Expand Down
Loading

0 comments on commit 6b646e8

Please sign in to comment.