How to join to a video room as subscriber #86
muhammadCodeSh
started this conversation in
General
Replies: 2 comments 1 reply
-
I also follow |
Beta Was this translation helpful? Give feedback.
0 replies
-
Can you give us feedback on this? Thanks guys! |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I tried to join a room as a subscriber but I could not.
Please send me an example code.
This is the code to join as a publisher please convert it to join as a subscriber.
`import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:janus_client/janus_client.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'dart:async';
import 'Helper.dart';
import 'conf.dart';
class TypedVideoRoomV2Unified extends StatefulWidget {
@OverRide
_VideoRoomState createState() => _VideoRoomState();
}
class _VideoRoomState extends State {
late JanusClient j;
Map<int, RemoteStream> remoteStreams = {};
late RestJanusTransport rest;
late WebSocketJanusTransport ws;
late JanusSession session;
late JanusVideoRoomPlugin plugin;
JanusVideoRoomPlugin? remoteHandle;
late int myId;
bool front = true;
int myRoom = 1234;
Map<int, dynamic> feedStreams = {};
Map<int?, dynamic> subscriptions = {};
Map<int, dynamic> feeds = {};
Map<String, int> subStreams = {};
Map<int, MediaStream?> mediaStreams = {};
@OverRide
void didChangeDependencies() async {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
initialize();
}
initialize() async {
ws = WebSocketJanusTransport(url: servermap['janus_ws']);
j = JanusClient(transport: ws, isUnifiedPlan: true, iceServers: [
RTCIceServer(
urls: "stun:stun1.l.google.com:19302", username: "", credential: "")
]);
session = await j.createSession();
plugin = await session.attach();
}
subscribeTo(List<Map<String, dynamic>> sources) async {
if (sources.length == 0) return;
var streams = (sources)
.map((e) => PublisherStream(mid: e['mid'], feed: e['feed']))
.toList();
if (remoteHandle != null) {
await remoteHandle?.subscribeToStreams(streams);
return;
}
remoteHandle = await session.attach();
print(sources);
var start = await remoteHandle?.joinSubscriber(myRoom, streams: streams);
remoteHandle?.typedMessages?.listen((event) async {
Object data = event.event.plugindata?.data;
if (data is VideoRoomAttachedEvent) {
print('Attached event');
data.streams?.forEach((element) {
if (element.mid != null && element.feedId != null) {
subStreams[element.mid!] = element.feedId!;
}
// to avoid duplicate subscriptions
if (subscriptions[element.feedId] == null)
subscriptions[element.feedId] = {};
subscriptions[element.feedId][element.mid] = true;
});
print('substreams');
print(subStreams);
}
if (event.jsep != null) {
await remoteHandle?.handleRemoteJsep(event.jsep);
await start!();
}
}, onError: (error, trace) {
if (error is JanusError) {
print(error.toMap());
}
});
remoteHandle?.remoteTrack?.listen((event) async {
String mid = event.mid!;
if (subStreams[mid] != null) {
int feedId = subStreams[mid]!;
if (!remoteStreams.containsKey(feedId)) {
RemoteStream temp = RemoteStream(feedId.toString());
await temp.init();
setState(() {
remoteStreams.putIfAbsent(feedId, () => temp);
});
}
if (event.track != null && event.flowing == true) {
remoteStreams[feedId]?.video.addTrack(event.track!);
remoteStreams[feedId]?.videoRenderer.srcObject =
remoteStreams[feedId]?.video;
if (kIsWeb) {
remoteStreams[feedId]?.videoRenderer.muted = false;
}
}
}
});
return;
}
Future joinRoom() async {
await plugin.initializeMediaDevices();
RemoteStream mystr = RemoteStream('0');
await mystr.init();
mystr.videoRenderer.srcObject = plugin.webRTCHandle!.localStream;
setState(() {
remoteStreams.putIfAbsent(0, () => mystr);
});
await plugin.joinPublisher(myRoom, displayName: "Shivansh");
plugin.typedMessages?.listen((event) async {
Object data = event.event.plugindata?.data;
if (data is VideoRoomJoinedEvent) {
(await plugin.publishMedia(bitrate: 3000000));
List<Map<String, dynamic>> publisherStreams = [];
for (Publishers publisher in data.publishers ?? []) {
for (Streams stream in publisher.streams ?? []) {
feedStreams[publisher.id!] = {
"id": publisher.id,
"display": publisher.display,
"streams": publisher.streams
};
publisherStreams.add({"feed": publisher.id, ...stream.toJson()});
if (publisher.id != null && stream.mid != null) {
subStreams[stream.mid!] = publisher.id!;
print("substreams is:");
print(subStreams);
}
}
}
subscribeTo(publisherStreams);
}
if (data is VideoRoomNewPublisherEvent) {
List<Map<String, dynamic>> publisherStreams = [];
for (Publishers publisher in data.publishers ?? []) {
feedStreams[publisher.id!] = {
"id": publisher.id,
"display": publisher.display,
"streams": publisher.streams
};
for (Streams stream in publisher.streams ?? []) {
publisherStreams.add({"feed": publisher.id, ...stream.toJson()});
if (publisher.id != null && stream.mid != null) {
subStreams[stream.mid!] = publisher.id!;
print("substreams is:");
print(subStreams);
}
}
}
print('got new publishers');
print(publisherStreams);
subscribeTo(publisherStreams);
}
if (data is VideoRoomLeavingEvent) {
print('publisher is leaving');
print(data.leaving);
unSubscribeStream(data.leaving!);
}
if (data is VideoRoomConfigured) {
print('typed event with jsep' + event.jsep.toString());
await plugin.handleRemoteJsep(event.jsep);
}
}, onError: (error, trace) {
if (error is JanusError) {
print(error.toMap());
}
});
}
Future unSubscribeStream(int id) async {
// Unsubscribe from this publisher
var feed = this.feedStreams[id];
if (feed == null) return;
this.feedStreams.remove(id);
await remoteStreams[id]?.dispose();
remoteStreams.remove(id);
MediaStream? streamRemoved = this.mediaStreams.remove(id);
streamRemoved?.getTracks().forEach((element) async {
await element.stop();
});
var unsubscribe = {
"request": "unsubscribe",
"streams": [
{feed: id}
]
};
if (remoteHandle != null)
await remoteHandle?.send(data: {"message": unsubscribe});
this.subscriptions.remove(id);
}
@OverRide
void dispose() async {
super.dispose();
await remoteHandle?.dispose();
await plugin.dispose();
session.dispose();
}
callEnd() async {
await plugin.hangup();
for (int i = 0; i < feedStreams.keys.length; i++) {
await unSubscribeStream(feedStreams.keys.elementAt(i));
}
remoteStreams.forEach((key, value) async {
value.dispose();
});
setState(() {
remoteStreams = {};
});
subStreams.clear();
subscriptions.clear();
await plugin.webRTCHandle!.localStream?.dispose();
await plugin.dispose();
await remoteHandle?.dispose();
}
@OverRide
Widget build(BuildContext context) {
print('----------------------------- ${remoteStreams.entries.length}');
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(
Icons.call,
color: Colors.greenAccent,
),
onPressed: () async {
await this.joinRoom();
}),
IconButton(
icon: Icon(
Icons.call_end,
color: Colors.red,
),
onPressed: () async {
await callEnd();
}),
IconButton(
icon: Icon(
Icons.switch_camera,
color: Colors.white,
),
onPressed: () async {
setState(() {
front = !front;
});
// await plugin.switchCamera(
// deviceId: await getCameraDeviceId(front));
RemoteStream mystr = RemoteStream('0');
await mystr.init();
mystr.videoRenderer.srcObject =
plugin.webRTCHandle!.localStream;
setState(() {
remoteStreams.remove(0);
remoteStreams[0] = mystr;
});
})
],
title: const Text('janus_client'),
),
body: GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemCount:
remoteStreams.entries.map((e) => e.value).toList().length,
itemBuilder: (context, index) {
List items =
remoteStreams.entries.map((e) => e.value).toList();
RemoteStream remoteStream = items[index];
return Stack(
children: [
RTCVideoView(remoteStream.audioRenderer,
filterQuality: FilterQuality.none,
objectFit:
RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
mirror: true),
RTCVideoView(remoteStream.videoRenderer,
filterQuality: FilterQuality.none,
objectFit:
RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
mirror: true)
],
);
}));
}
}`
Beta Was this translation helpful? Give feedback.
All reactions