Skip to content

Commit

Permalink
[web] Implement more APIs (#1597)
Browse files Browse the repository at this point in the history
## RtcEngine
- enableLocalVideo
- muteAllRemoteVideoStreams
- createDataStream
- sendStreamMessage
- muteLocalVideoStream
- muteRemoteVideoStream
- joinChannelWithUserAccount
- getUserInfoByUserAccount
- getUserInfoByUid

## RtcEngineEx
- muteAllRemoteVideoStreamsEx
- sendStreamMessageEx
- createDataStreamEx
- muteLocalVideoStreamEx
- muteRemoteVideoStreamEx

## RtcEngineEventHandler
- onStreamMessage
- onRemoteVideoStateChanged

---------

Co-authored-by: Littlegnal <[email protected]>
Co-authored-by: guoxianzhe <[email protected]>
  • Loading branch information
3 people authored Mar 12, 2024
1 parent 5646230 commit bfd4eaa
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 11 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Download the `iris_web`(see the link below) artifact and include it as a `<scrip
</body>
</html>
```
Download: https://download.agora.io/staging/iris-web-rtc_n430_w4182_0.5.0.js
Download: https://download.agora.io/sdk/release/iris-web-rtc_n430_w4200_0.6.0.js

**For Testing Purposes**

Expand All @@ -101,7 +101,7 @@ You can directly depend on the Agora CDN for testing purposes:
...
<body>
...
<script src="https://download.agora.io/staging/iris-web-rtc_n430_w4182_0.5.0.js"></script>
<script src="https://download.agora.io/sdk/release/iris-web-rtc_n430_w4200_0.6.0.js"></script>
</body>
</html>
```
Expand Down
2 changes: 1 addition & 1 deletion example/lib/examples/advanced/index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ final advanced = [
'name': 'SetVideoEncoderConfiguration',
'widget': const SetVideoEncoderConfiguration()
},
if (!kIsWeb) {'name': 'StreamMessage', 'widget': const StreamMessage()},
{'name': 'StreamMessage', 'widget': const StreamMessage()},
if (!kIsWeb) {'name': 'VoiceChanger', 'widget': const VoiceChanger()},
if (!kIsWeb)
{
Expand Down
2 changes: 1 addition & 1 deletion example/lib/examples/basic/index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ final basic = [
{'name': 'Basic'},
{'name': 'JoinChannelAudio', 'widget': const JoinChannelAudio()},
{'name': 'JoinChannelVideo', 'widget': const JoinChannelVideo()},
if (!kIsWeb) {'name': 'StringUid', 'widget': const StringUid()}
{'name': 'StringUid', 'widget': const StringUid()}
];
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@ class JoinChannelAudio extends StatefulWidget {
class _State extends State<JoinChannelAudio> {
late final RtcEngine _engine;
String channelId = config.channelId;
final String _selectedUid = '';
bool isJoined = false,
openMicrophone = true,
muteMicrophone = false,
muteAllRemoteAudio = false,
enableSpeakerphone = true,
playEffect = false;
bool _enableInEarMonitoring = false;
double _recordingVolume = 100,
_playbackVolume = 100,
_inEarMonitoringVolume = 100;
late TextEditingController _controller;
late final TextEditingController _selectedUidController;
ChannelProfileType _channelProfileType =
ChannelProfileType.channelProfileLiveBroadcasting;
late final RtcEngineEventHandler _rtcEngineEventHandler;
Expand All @@ -35,6 +39,7 @@ class _State extends State<JoinChannelAudio> {
void initState() {
super.initState();
_controller = TextEditingController(text: channelId);
_selectedUidController = TextEditingController(text: _selectedUid);
_initEngine();
}

Expand Down Expand Up @@ -67,6 +72,11 @@ class _State extends State<JoinChannelAudio> {
isJoined = true;
});
},
onRemoteAudioStateChanged: (RtcConnection connection, int remoteUid,
RemoteAudioState state, RemoteAudioStateReason reason, int elapsed) {
logSink.log(
'[onRemoteAudioStateChanged] connection: ${connection.toJson()} remoteUid: $remoteUid state: $state reason: $reason elapsed: $elapsed');
},
onLeaveChannel: (RtcConnection connection, RtcStats stats) {
logSink.log(
'[onLeaveChannel] connection: ${connection.toJson()} stats: ${stats.toJson()}');
Expand Down Expand Up @@ -106,6 +116,8 @@ class _State extends State<JoinChannelAudio> {
setState(() {
isJoined = false;
openMicrophone = true;
muteMicrophone = false;
muteAllRemoteAudio = false;
enableSpeakerphone = true;
playEffect = false;
_enableInEarMonitoring = false;
Expand All @@ -123,6 +135,20 @@ class _State extends State<JoinChannelAudio> {
});
}

_muteLocalAudioStream() async {
await _engine.muteLocalAudioStream(!muteMicrophone);
setState(() {
muteMicrophone = !muteMicrophone;
});
}

_muteAllRemoteAudioStreams() async {
await _engine.muteAllRemoteAudioStreams(!muteAllRemoteAudio);
setState(() {
muteAllRemoteAudio = !muteAllRemoteAudio;
});
}

_switchSpeakerphone() async {
await _engine.setEnableSpeakerphone(!enableSpeakerphone);
setState(() {
Expand Down Expand Up @@ -219,6 +245,29 @@ class _State extends State<JoinChannelAudio> {
)
],
),
if (kIsWeb) ...[
TextField(
controller: _selectedUidController,
decoration: const InputDecoration(
hintText: 'input userID you want to mute/unmute'),
),
ElevatedButton(
onPressed: () async {
await _engine.muteRemoteAudioStream(
uid: int.tryParse(_selectedUidController.text) ?? -1,
mute: true);
},
child: Text('mute Remote Audio'),
),
ElevatedButton(
onPressed: () async {
await _engine.muteRemoteAudioStream(
uid: int.tryParse(_selectedUidController.text) ?? -1,
mute: false);
},
child: Text('unmute Remote Audio'),
),
],
],
),
Align(
Expand All @@ -228,6 +277,18 @@ class _State extends State<JoinChannelAudio> {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
if (kIsWeb) ...[
ElevatedButton(
onPressed: _muteLocalAudioStream,
child: Text(
'Microphone ${muteMicrophone ? 'muted' : 'unmute'}'),
),
ElevatedButton(
onPressed: _muteAllRemoteAudioStreams,
child: Text(
'All Remote Microphone ${muteAllRemoteAudio ? 'muted' : 'unmute'}'),
),
],
ElevatedButton(
onPressed: _switchMicrophone,
child: Text('Microphone ${openMicrophone ? 'on' : 'off'}'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ class JoinChannelVideo extends StatefulWidget {
class _State extends State<JoinChannelVideo> {
late final RtcEngine _engine;

bool isJoined = false, switchCamera = true, switchRender = true;
bool isJoined = false,
switchCamera = true,
switchRender = true,
openCamera = true,
muteCamera = false,
muteAllRemoteVideo = false;
Set<int> remoteUid = {};
late TextEditingController _controller;
bool _isUseFlutterTexture = false;
Expand Down Expand Up @@ -86,6 +91,15 @@ class _State extends State<JoinChannelVideo> {
remoteUid.clear();
});
},
onRemoteVideoStateChanged: (
RtcConnection connection,
int remoteUid,
RemoteVideoState state,
RemoteVideoStateReason reason,
int elapsed) {
logSink.log(
'[onRemoteVideoStateChanged] connection: ${connection.toJson()} remoteUid: $remoteUid state: $state reason: $reason elapsed: $elapsed');
},
);

_engine.registerEventHandler(_rtcEngineEventHandler);
Expand All @@ -108,6 +122,11 @@ class _State extends State<JoinChannelVideo> {

Future<void> _leaveChannel() async {
await _engine.leaveChannel();
setState(() {
openCamera = true;
muteCamera = false;
muteAllRemoteVideo = false;
});
}

Future<void> _switchCamera() async {
Expand All @@ -117,6 +136,27 @@ class _State extends State<JoinChannelVideo> {
});
}

_openCamera() async {
await _engine.enableLocalVideo(!openCamera);
setState(() {
openCamera = !openCamera;
});
}

_muteLocalVideoStream() async {
await _engine.muteLocalVideoStream(!muteCamera);
setState(() {
muteCamera = !muteCamera;
});
}

_muteAllRemoteVideoStreams() async {
await _engine.muteAllRemoteVideoStreams(!muteAllRemoteVideo);
setState(() {
muteAllRemoteVideo = !muteAllRemoteVideo;
});
}

@override
Widget build(BuildContext context) {
return ExampleActionsWidget(
Expand Down Expand Up @@ -268,6 +308,24 @@ class _State extends State<JoinChannelVideo> {
child: Text('Camera ${switchCamera ? 'front' : 'rear'}'),
),
],
if (kIsWeb) ...[
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: _muteLocalVideoStream,
child: Text('Camera ${muteCamera ? 'muted' : 'unmute'}'),
),
ElevatedButton(
onPressed: _muteAllRemoteVideoStreams,
child: Text(
'All Remote Camera ${muteAllRemoteVideo ? 'muted' : 'unmute'}'),
),
ElevatedButton(
onPressed: _openCamera,
child: Text('Camera ${openCamera ? 'on' : 'off'}'),
),
],
],
);
},
Expand Down
11 changes: 9 additions & 2 deletions example/lib/examples/basic/string_uid/string_uid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class _State extends State<StringUid> {
late final RtcEngine _engine;
bool isJoined = false;
late TextEditingController _controller0, _controller1;
late final RtcEngineEventHandler _rtcEngineEventHandler;

@override
void initState() {
Expand All @@ -36,6 +37,7 @@ class _State extends State<StringUid> {
}

Future<void> _dispose() async {
_engine.unregisterEventHandler(_rtcEngineEventHandler);
await _engine.leaveChannel();
await _engine.release();
}
Expand All @@ -47,7 +49,7 @@ class _State extends State<StringUid> {
channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
));

_engine.registerEventHandler(RtcEngineEventHandler(
_rtcEngineEventHandler = RtcEngineEventHandler(
onError: (ErrorCodeType err, String msg) {
logSink.log('[onError] err: $err, msg: $msg');
},
Expand All @@ -58,14 +60,19 @@ class _State extends State<StringUid> {
isJoined = true;
});
},
onUserInfoUpdated: (int uid, UserInfo info) {
logSink
.log('[onUserInfoUpdated] uid: ${uid} UserInfo: ${info.toJson()}');
},
onLeaveChannel: (RtcConnection connection, RtcStats stats) {
logSink.log(
'[onLeaveChannel] connection: ${connection.toJson()} stats: ${stats.toJson()}');
setState(() {
isJoined = false;
});
},
));
);
_engine.registerEventHandler(_rtcEngineEventHandler);

await _engine.enableAudio();
await _engine.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
Expand Down
2 changes: 1 addition & 1 deletion example/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@
loadMainDartJs();
}
</script>
<script src="https://download.agora.io/staging/iris-web-rtc_n430_w4182_0.5.0.js"></script>
<script src="https://download.agora.io/sdk/release/iris-web-rtc_n430_w4200_0.6.0.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies:
ffi: '>=1.1.2'
async: ^2.8.2
meta: ^1.7.0
iris_method_channel: 2.0.1
iris_method_channel: 2.1.0
js: '>=0.6.3'
dev_dependencies:
flutter_test:
Expand Down
4 changes: 2 additions & 2 deletions scripts/iris_web_version.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Share the iris web url to all the tests

// This url should be same as the url inside the `example/web/index.html`
const irisWebUrl = 'https://download.agora.io/staging/iris-web-rtc_n430_w4182_0.5.0.js';
const irisWebFakeUrl = 'https://download.agora.io/staging/iris-web-rtc-fake_n430_w4182_0.5.0.js';
const irisWebUrl = 'https://download.agora.io/sdk/release/iris-web-rtc_n430_w4200_0.6.0.js';
const irisWebFakeUrl = 'https://download.agora.io/sdk/release/iris-web-rtc-fake_n430_w4200_0.6.0.js';

(function() {
var scriptLoaded = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class EventParam {
@JS('createIrisRtcEngineFake')
external Object createIrisRtcEngineFake(Object irisApiEngine);

@JS('irisMock')
external void irisMock();

@JS('triggerEventWithFakeApiEngine')
external int triggerEventWithFakeApiEngine(
// ignore: non_constant_identifier_names
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class IrisTesterWeb implements IrisTester {

isCreatedIrisRtcEngineFake = true;
_irisRtcEngineFake = bindings.createIrisRtcEngineFake(irisApiEngine);
bindings.irisMock();

return _irisRtcEngineFake;
}
Expand Down

0 comments on commit bfd4eaa

Please sign in to comment.