Using same but Unique UID for joinChannel and Local User's VideoCanvas renders a blank Local AgoraVideoView
Version of the agora_rtc_engine
6.3.2
Platforms affected
- [X] Android
- [X] iOS
- [ ] macOS
- [ ] Windows
- [X] Web
Steps to reproduce
- Create a new Flutter app
- Import plugin agora_rtc_engine: ^6.3.2
- Use a Unique UID for joining the channel and assign the same UID for the local video view.
- Run the app
- Join the channel.
Expected results
The local video view should render properly
Actual results
The local video view is blank and only works when the Local Video View is assigned uid 0.
Code sample
Code sample
import 'dart:async';
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:html';
import 'package:logger/logger.dart';
class VideoCallScreen extends StatefulWidget {
final String appId;
final String token;
final String channelName;
final bool isMicEnabled;
final bool isVideoEnabled;
final int videoId; // Added videoId
const VideoCallScreen({
super.key,
required this.appId,
required this.token,
required this.channelName,
required this.isMicEnabled,
required this.isVideoEnabled,
required this.videoId, // Added videoId to constructor
});
@override
VideoCallScreenState createState() => VideoCallScreenState();
}
class VideoCallScreenState extends State<VideoCallScreen> {
int? _remoteUid, _localUid;
bool _localUserJoined = false;
late RtcEngine _engine;
final Logger _logger = Logger();
@override
void initState() {
super.initState();
_logger.i('Initializing Agora SDK');
initAgora();
}
Future<void> initAgora() async {
//await window.navigator.getUserMedia(video: true, audio: true);
_engine = createAgoraRtcEngine();
await _engine.initialize(RtcEngineContext(
appId: widget.appId,
channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
));
_logger.i('Agora SDK initialized');
_engine.registerEventHandler(
RtcEngineEventHandler(
onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
_logger.i("Local user ${connection.localUid} joined channel");
setState(() {
_localUserJoined = true;
_localUid = connection.localUid;
});
},
onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
_logger.i("Remote user $remoteUid joined channel");
setState(() {
_remoteUid = remoteUid;
});
},
onUserOffline: (RtcConnection connection, int remoteUid,
UserOfflineReasonType reason) {
_logger.i("Remote user $remoteUid left channel");
setState(() {
_remoteUid = null;
});
},
onTokenPrivilegeWillExpire: (RtcConnection connection, String token) {
_logger.w(
'[onTokenPrivilegeWillExpire] connection: ${connection.toJson()}, token: $token');
},
),
);
_logger.i('Event handlers registered');
await _engine.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
await _engine.enableVideo();
await _engine.startPreview();
_logger.i('Client role set, video enabled, preview started');
await _engine.enableLocalAudio(widget.isMicEnabled);
await _engine.enableLocalVideo(widget.isVideoEnabled);
_logger.d("Token at Video Call Screen: ${widget.token}");
await _engine.joinChannel(
token: widget.token,
channelId: widget.channelName,
uid: widget.videoId, // Use videoId as the user ID
options: const ChannelMediaOptions(),
);
_logger
.i('Joined channel: ${widget.channelName} with uid: ${widget.videoId}');
}
@override
void dispose() {
_logger.i('Disposing VideoCallScreen');
super.dispose();
_dispose();
}
Future<void> _dispose() async {
await _engine.leaveChannel();
_logger.i('Left channel');
await _engine.release();
_logger.i('Agora SDK released');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Video Call'),
),
body: Stack(
children: [
Center(
child: _remoteVideo(),
),
Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 100,
height: 150,
child: Center(
child: _localUserJoined
? AgoraVideoView(
controller: VideoViewController(
rtcEngine: _engine,
canvas: VideoCanvas(uid: 0), // Should use videoId here
),
)
: const CircularProgressIndicator(),
),
),
),
],
),
);
}
Widget _remoteVideo() {
if (_remoteUid != null) {
return AgoraVideoView(
controller: VideoViewController.remote(
rtcEngine: _engine,
canvas: VideoCanvas(uid: _remoteUid),
connection: RtcConnection(channelId: widget.channelName),
),
);
} else {
return const Text(
'Please wait for the remote user to join',
textAlign: TextAlign.center,
);
}
}
}
Screenshots or Video
Screenshots / Video demonstration
[Upload media here]
Logs
Logs
[Paste your logs here]
Flutter Doctor output
Doctor output
[Paste your output here]
Please submit a ticket to Agora Support for further investigation of this issue. If you have any conclusions, you can share them here which may help other developers. Thanks!
Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now. If you find this problem please file a new issue with the same description, what happens, logs and the output. All system setups can be slightly different so it's always better to open new issues and reference the related ones. Thanks for your contribution.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please raise a new issue.