chore: Use RTCFactory interface to create MediaStream, VideoRenderer.

This commit is contained in:
cloudwebrtc 2021-11-22 22:41:49 +08:00
parent 5dfb196c90
commit 12df5d8cdd
1 changed files with 17 additions and 63 deletions

View File

@ -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);