chore: Use RTCFactory interface to create MediaStream, VideoRenderer.
This commit is contained in:
parent
5dfb196c90
commit
12df5d8cdd
|
|
@ -6,52 +6,6 @@ import 'package:sdp_transform/sdp_transform.dart' as sdp_transform;
|
||||||
|
|
||||||
import '../matrix.dart';
|
import '../matrix.dart';
|
||||||
|
|
||||||
MediaDevices mediaDevices = Null as MediaDevices;
|
|
||||||
RTCFactory factory = Null as RTCFactory;
|
|
||||||
|
|
||||||
class RTCVideoRenderer extends VideoRenderer {
|
|
||||||
RTCVideoRenderer() : super() {
|
|
||||||
muted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
late bool muted;
|
|
||||||
|
|
||||||
@override
|
|
||||||
MediaStream? srcObject;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> audioOutput(String deviceId) {
|
|
||||||
// TODO: implement audioOutput
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> initialize() {
|
|
||||||
// TODO: implement initialize
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
// TODO: implement renderVideo
|
|
||||||
bool get renderVideo => throw UnimplementedError();
|
|
||||||
|
|
||||||
@override
|
|
||||||
// TODO: implement textureId
|
|
||||||
int? get textureId => throw UnimplementedError();
|
|
||||||
|
|
||||||
@override
|
|
||||||
// TODO: implement videoHeight
|
|
||||||
int get videoHeight => throw UnimplementedError();
|
|
||||||
|
|
||||||
@override
|
|
||||||
// TODO: implement videoWidth
|
|
||||||
int get videoWidth => throw UnimplementedError();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> dispose() => throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The default life time for call events, in millisecond.
|
/// The default life time for call events, in millisecond.
|
||||||
const lifetimeMs = 10 * 1000;
|
const lifetimeMs = 10 * 1000;
|
||||||
|
|
||||||
|
|
@ -72,13 +26,14 @@ class WrappedMediaStream {
|
||||||
|
|
||||||
/// for debug
|
/// for debug
|
||||||
String get title => '$displayName:$purpose:a[$audioMuted]:v[$videoMuted]';
|
String get title => '$displayName:$purpose:a[$audioMuted]:v[$videoMuted]';
|
||||||
RTCVideoRenderer? renderer;
|
final VideoRenderer renderer;
|
||||||
bool stopped = false;
|
bool stopped = false;
|
||||||
void Function(bool audioMuted, bool videoMuted)? onMuteStateChanged;
|
void Function(bool audioMuted, bool videoMuted)? onMuteStateChanged;
|
||||||
void Function(MediaStream stream)? onNewStream;
|
void Function(MediaStream stream)? onNewStream;
|
||||||
|
|
||||||
WrappedMediaStream(
|
WrappedMediaStream(
|
||||||
{this.stream,
|
{this.stream,
|
||||||
|
required this.renderer,
|
||||||
required this.room,
|
required this.room,
|
||||||
required this.userId,
|
required this.userId,
|
||||||
required this.purpose,
|
required this.purpose,
|
||||||
|
|
@ -88,23 +43,17 @@ class WrappedMediaStream {
|
||||||
|
|
||||||
/// Initialize the video renderer
|
/// Initialize the video renderer
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
if (renderer == null) {
|
await renderer.initialize();
|
||||||
renderer = RTCVideoRenderer();
|
renderer.srcObject = stream;
|
||||||
await renderer?.initialize();
|
renderer.onResize = () {
|
||||||
}
|
|
||||||
renderer?.srcObject = stream;
|
|
||||||
renderer?.onResize = () {
|
|
||||||
Logs().i(
|
Logs().i(
|
||||||
'onResize [${stream!.id.substring(0, 8)}] ${renderer?.videoWidth} x ${renderer?.videoHeight}');
|
'onResize [${stream!.id.substring(0, 8)}] ${renderer?.videoWidth} x ${renderer?.videoHeight}');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
if (renderer != null) {
|
renderer.srcObject = null;
|
||||||
renderer?.srcObject = null;
|
await renderer.dispose();
|
||||||
await renderer?.dispose();
|
|
||||||
renderer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLocal() && stream != null) {
|
if (isLocal() && stream != null) {
|
||||||
await stream?.dispose();
|
await stream?.dispose();
|
||||||
|
|
@ -135,7 +84,7 @@ class WrappedMediaStream {
|
||||||
|
|
||||||
void setNewStream(MediaStream newStream) {
|
void setNewStream(MediaStream newStream) {
|
||||||
stream = newStream;
|
stream = newStream;
|
||||||
renderer?.srcObject = stream;
|
renderer.srcObject = stream;
|
||||||
if (onNewStream != null) {
|
if (onNewStream != null) {
|
||||||
onNewStream?.call(stream!);
|
onNewStream?.call(stream!);
|
||||||
}
|
}
|
||||||
|
|
@ -571,6 +520,7 @@ class CallSession {
|
||||||
existingStream.setNewStream(stream);
|
existingStream.setNewStream(stream);
|
||||||
} else {
|
} else {
|
||||||
final newStream = WrappedMediaStream(
|
final newStream = WrappedMediaStream(
|
||||||
|
renderer: voip.factory.videoRenderer(),
|
||||||
userId: client.userID!,
|
userId: client.userID!,
|
||||||
room: opts.room,
|
room: opts.room,
|
||||||
stream: stream,
|
stream: stream,
|
||||||
|
|
@ -631,6 +581,7 @@ class CallSession {
|
||||||
existingStream.setNewStream(stream);
|
existingStream.setNewStream(stream);
|
||||||
} else {
|
} else {
|
||||||
final newStream = WrappedMediaStream(
|
final newStream = WrappedMediaStream(
|
||||||
|
renderer: voip.factory.videoRenderer(),
|
||||||
userId: remoteUser.id,
|
userId: remoteUser.id,
|
||||||
room: opts.room,
|
room: opts.room,
|
||||||
stream: stream,
|
stream: stream,
|
||||||
|
|
@ -1010,7 +961,8 @@ class CallSession {
|
||||||
: false,
|
: false,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
return await mediaDevices.getUserMedia(mediaConstraints);
|
return await voip.factory.navigator.mediaDevices
|
||||||
|
.getUserMedia(mediaConstraints);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_getUserMediaFailed(e);
|
_getUserMediaFailed(e);
|
||||||
}
|
}
|
||||||
|
|
@ -1023,7 +975,8 @@ class CallSession {
|
||||||
'video': true,
|
'video': true,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
return await mediaDevices.getDisplayMedia(mediaConstraints);
|
return await voip.factory.navigator.mediaDevices
|
||||||
|
.getDisplayMedia(mediaConstraints);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_getUserMediaFailed(e);
|
_getUserMediaFailed(e);
|
||||||
}
|
}
|
||||||
|
|
@ -1035,7 +988,7 @@ class CallSession {
|
||||||
'iceServers': opts.iceServers,
|
'iceServers': opts.iceServers,
|
||||||
'sdpSemantics': 'unified-plan'
|
'sdpSemantics': 'unified-plan'
|
||||||
};
|
};
|
||||||
final pc = await factory.createPeerConnection(configuration);
|
final pc = await voip.factory.createPeerConnection(configuration);
|
||||||
pc.onTrack = (RTCTrackEvent event) {
|
pc.onTrack = (RTCTrackEvent event) {
|
||||||
if (event.streams.isNotEmpty) {
|
if (event.streams.isNotEmpty) {
|
||||||
final stream = event.streams[0];
|
final stream = event.streams[0];
|
||||||
|
|
@ -1174,8 +1127,9 @@ class VoIP {
|
||||||
String? get localPartyId => client.deviceID;
|
String? get localPartyId => client.deviceID;
|
||||||
bool background = false;
|
bool background = false;
|
||||||
Client client;
|
Client client;
|
||||||
|
final RTCFactory factory;
|
||||||
|
|
||||||
VoIP(this.client) : super() {
|
VoIP(this.client, this.factory) : super() {
|
||||||
client.onCallInvite.stream.listen(onCallInvite);
|
client.onCallInvite.stream.listen(onCallInvite);
|
||||||
client.onCallAnswer.stream.listen(onCallAnswer);
|
client.onCallAnswer.stream.listen(onCallAnswer);
|
||||||
client.onCallCandidates.stream.listen(onCallCandidates);
|
client.onCallCandidates.stream.listen(onCallCandidates);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue