Reputation: 3059
I'm developing a video calling app using WebRTC and PeerDart in Flutter. The application is working fine for initiating and receiving calls, but I'm encountering an issue with toggling the video.
Here is the relevant part of my code:
Call Initiation and Listening for Room Join
final RTCVideoRenderer? localRenderer = RTCVideoRenderer();
final List<ProfileModel> remoteRenderers = [];
void listenRoomJoined() {
SocketIOHelper.socket?.on(Constants.socketListenJoinRoom, (data) async {
BaseClient.handleApiError(
ApiException(url: "url", message: data['data']['type']));
await createCall(
userData: ProfileModel(
id: data['data']['user']['id'],
peerId: data['data']['peerId'],
name: data['data']['user']['name'],
avatar: data['data']['user']['avatar'],
type: data['data']['type'],
));
});
}
Future<void> createCall({required ProfileModel userData}) async {
try {
final mediaStream = await getUserMedia();
final conn = peer.call(userData.peerId!, mediaStream);
conn.on("close").listen((event) {
inCall.value = false;
});
final dataConn = peer.connect(userData.peerId!);
dataConn.on("open").listen((event) {
ProfileModel? ownData = ProfileModel(
id: MySharedPref.getUserId(),
peerId: peer.id,
type: arguments[1]['joinType'],
name: MySharedPref.getUserName(),
avatar: MySharedPref.getUserImage());
String jsonString = jsonEncode(ownData.toJson());
dataConn.send(jsonString);
});
conn.on<MediaStream>("stream").listen((event) {
localRenderer?.srcObject = mediaStream;
addRemoteRenderer(stream: event, userData: userData);
inCall.value = true;
update();
for (var profile in remoteRenderers) {
if (profile.peerId == userData.peerId) {
if (userData.type != null) profile.type = userData.type;
if (userData.id != null) profile.id = userData.id;
if (userData.name != null) profile.name = userData.name;
if (userData.avatar != null) profile.avatar = userData.avatar;
update();
break;
}
}
});
update();
} catch (error) {
Logger().e(error);
}
}
Answering Calls
void joinAsRoomViewer() {
String? userId = MySharedPref.getUserId();
SocketIOHelper.socket?.emitWithAck(
'STREAM_JOIN_ROOM_VIEWER',
{
"roomId": roomId,
"userId": userId,
"peerId": peer.id,
},
ack: (data) {});
answerCall();
}
Future<void> answerCall() async {
try {
peer.on<MediaConnection>("call").listen((call) async {
final mediaStream = await getUserMedia();
call.answer(mediaStream);
call.on("close").listen((event) {
inCall.value = false;
});
call.on<MediaStream>("stream").listen((event) {
localRenderer?.srcObject = mediaStream;
addRemoteRenderer(
stream: event,
userData: ProfileModel(
peerId: call.peer,
));
inCall.value = true;
update();
});
});
} catch (error) {
Logger().e(error);
}
}
Getting User Media
Future<MediaStream> getUserMedia() async {
await _stopMediaStream();
Map<String, dynamic>? videoConstraints;
if (useFrontCamera) {
videoConstraints = {'facingMode': 'user'};
} else {
videoConstraints = {
'facingMode': {'exact': 'environment'}
};
}
final Map<String, dynamic> constraints = {
'audio': isMicEnabled,
'video': isVideoEnabled ? videoConstraints : false,
};
try {
MediaStream? localStream =
await navigator.mediaDevices.getUserMedia(constraints);
if (localStream != null) {
localRenderer?.srcObject = localStream;
localStream.getVideoTracks().forEach((track) {
track.enabled = isVideoEnabled;
});
localStream.getAudioTracks().forEach((track) {
track.enabled = true;
});
} else {
print('Failed to get user media');
}
} catch (e) {
print('Error accessing user media: $e');
}
return localRenderer!.srcObject!;
}
Future<void> _stopMediaStream() async {
if (localRenderer?.srcObject != null) {
localRenderer?.srcObject!.getTracks().forEach((track) {
track.stop();
});
localRenderer?.srcObject = null;
}
}
Toggle Video Function
void toggleVideo() async {
isVideoEnabled = !isVideoEnabled;
await getUserMedia();
update();
await SocketIOHelper.emit(
Constants.socketToggleVideo,
{
"roomId": roomId,
"userId": MySharedPref.getUserId(),
"peerId": peer.id,
"status": isVideoEnabled,
},
);
}
Problem
The video toggle works partially. When I turn off the video, the stream stops as expected. However, when I try to turn the video back on, the stream does not restart for other users in the room How can I modify my code to ensure that when the video is toggled back on, the stream starts correctly for other users?
Any suggestions or pointers would be greatly appreciated. Thank you!
Upvotes: 1
Views: 157