You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
6.9 KiB
Dart
241 lines
6.9 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart';
|
|
import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart';
|
|
import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/utils/device_info.dart';
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'dart:core';
|
|
import 'signaling.dart';
|
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
|
|
|
class StartVideoCall extends StatefulWidget {
|
|
static String tag = 'webrtc';
|
|
final String host;
|
|
|
|
String caller;
|
|
String receiver;
|
|
bool iAmCaller;
|
|
StartVideoCall({@required this.caller, @required this.receiver, this.iAmCaller = false, @required this.host});
|
|
|
|
@override
|
|
StartVideoCallState createState() => StartVideoCallState(receiverId: receiver, callerId: caller, iAmCaller: iAmCaller);
|
|
}
|
|
|
|
class StartVideoCallState extends State<StartVideoCall> {
|
|
Signaling _signaling;
|
|
SessionOneToOne _session;
|
|
|
|
StartVideoCallState({@required String callerId, @required String receiverId, @required bool iAmCaller}){
|
|
|
|
final self_role = iAmCaller ? "Caller" : "Receiver";
|
|
final self_id = iAmCaller ? callerId : receiverId;
|
|
final self_user = SocketUser(id: self_id, name: "$self_role-$self_id", userAgent: DeviceInfo.userAgent, moreInfo: {});
|
|
|
|
final remote_role = !iAmCaller ? "Caller" : "Receiver";
|
|
final remote_id = !iAmCaller ? callerId : receiverId;
|
|
final remote_user = SocketUser(id: remote_id, name: "$remote_role-$remote_id", userAgent: DeviceInfo.userAgent, moreInfo: {});
|
|
|
|
final session_id = "$callerId-$receiverId";
|
|
_session = SessionOneToOne(id: session_id, local_user: self_user, remote_user: remote_user);
|
|
}
|
|
|
|
bool showNoise = true;
|
|
final StreamController<bool> _audioButton = StreamController<bool>.broadcast();
|
|
final StreamController<bool> _videoButton = StreamController<bool>.broadcast();
|
|
final StreamController<bool> _onButtonBarVisibleStreamController = StreamController<bool>.broadcast();
|
|
final StreamController<double> _onButtonBarHeightStreamController = StreamController<double>.broadcast();
|
|
|
|
final RTCVideoRenderer _localRenderer = RTCVideoRenderer();
|
|
final RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
|
|
|
|
MediaStream get localMediaStream => _signaling.localStream;
|
|
MediaStream get remoteMediaStream => _signaling.remoteStreams.first;
|
|
|
|
@override
|
|
initState() {
|
|
super.initState();
|
|
initRenderers();
|
|
_connect();
|
|
}
|
|
|
|
initRenderers() async {
|
|
await _localRenderer.initialize();
|
|
await _remoteRenderer.initialize();
|
|
}
|
|
|
|
@override
|
|
deactivate() {
|
|
super.deactivate();
|
|
_signaling?.close();
|
|
_localRenderer.dispose();
|
|
_remoteRenderer.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
// appBar: AppBar(
|
|
// title: Text('P2P Call Sample' + (_session?.local_user != null ? ' [Your ID (${_session?.local_user?.id})] ' : '')),
|
|
// actions: <Widget>[
|
|
// IconButton(
|
|
// icon: const Icon(Icons.settings),
|
|
// onPressed: (){
|
|
// setState(() {
|
|
// });
|
|
// },
|
|
// tooltip: 'setup',
|
|
// ),
|
|
// ],
|
|
// ),
|
|
body: videoCanvasWidgets(),
|
|
);
|
|
}
|
|
|
|
LayoutBuilder videoCanvasWidgets() {
|
|
return LayoutBuilder(
|
|
builder: (BuildContext context, BoxConstraints constraints) {
|
|
return Stack(
|
|
children: [
|
|
CamViewWidget(
|
|
localRenderer: _localRenderer,
|
|
remoteRenderer: _remoteRenderer,
|
|
constraints: constraints,
|
|
onButtonBarVisibleStreamController: _onButtonBarVisibleStreamController,
|
|
onButtonBarHeightStreamController: _onButtonBarHeightStreamController,
|
|
),
|
|
ConferenceButtonBar(
|
|
audioEnabled: _audioButton.stream,
|
|
videoEnabled: _videoButton.stream,
|
|
onAudioEnabled: _onAudioEnable,
|
|
onVideoEnabled: _onVideoEnabled,
|
|
onSwitchCamera: _onSwitchCamera,
|
|
onHangup: _onHangup,
|
|
onPersonAdd: () {},
|
|
onPersonRemove: () {},
|
|
onHeight: _onHeightBar,
|
|
onShow: _onShowBar,
|
|
onHide: _onHideBar,
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
|
|
void _connect() async {
|
|
if(_session == null)
|
|
return;
|
|
|
|
_signaling ??= Signaling(widget.host, session: _session)..connect();
|
|
|
|
_signaling?.onSignalingStateChange = (SignalingState state) {
|
|
switch (state) {
|
|
case SignalingState.Closed:
|
|
case SignalingState.Error:
|
|
case SignalingState.Open:
|
|
break;
|
|
}
|
|
};
|
|
|
|
_signaling?.onCallStateChange = (SessionOneToOne session, CallState state) {
|
|
switch (state) {
|
|
case CallState.Calling:
|
|
setState(() {});
|
|
break;
|
|
case CallState.Bye:
|
|
setState(() {
|
|
_localRenderer.srcObject = null;
|
|
_remoteRenderer.srcObject = null;
|
|
_session = null;
|
|
});
|
|
break;
|
|
case CallState.Invite:
|
|
case CallState.Connected:
|
|
case CallState.Ringing:
|
|
}
|
|
};
|
|
|
|
_signaling?.onConnected = ((event) {
|
|
_signaling?.callAccepted(_session);
|
|
});
|
|
|
|
_signaling?.onRemoteConnected = ((event) {
|
|
|
|
});
|
|
|
|
_signaling?.onLocalStream = ((stream) {
|
|
_localRenderer.srcObject = stream;
|
|
setState(() {
|
|
});
|
|
});
|
|
|
|
_signaling?.onAddRemoteStream = ((_, stream) {
|
|
_remoteRenderer.srcObject = stream;
|
|
setState(() {});
|
|
});
|
|
|
|
_signaling?.onRemoveRemoteStream = ((_, stream) {
|
|
setState(() {
|
|
_remoteRenderer.srcObject = null;
|
|
});
|
|
});
|
|
}
|
|
|
|
_hangUp() async{
|
|
if (_session != null) {
|
|
_signaling?.bye(_session);
|
|
}
|
|
}
|
|
|
|
_switchCamera() {
|
|
_signaling?.switchCamera();
|
|
}
|
|
|
|
_muteMic() {
|
|
_signaling?.muteMic();
|
|
}
|
|
|
|
Function _onAudioEnable() {
|
|
final audioTrack = localMediaStream.getAudioTracks()[0];
|
|
final mute = audioTrack.muted;
|
|
Helper.setMicrophoneMute(!mute, audioTrack);
|
|
_audioButton.add(mute);
|
|
}
|
|
|
|
Function _onVideoEnabled() {
|
|
final videoTrack = localMediaStream.getVideoTracks()[0];
|
|
bool videoEnabled = videoTrack.enabled;
|
|
localMediaStream.getVideoTracks()[0].enabled = !videoEnabled;
|
|
_videoButton.add(!videoEnabled);
|
|
}
|
|
|
|
Function _onSwitchCamera() {
|
|
Helper.switchCamera(localMediaStream.getVideoTracks()[0]);
|
|
}
|
|
|
|
void _onShowBar() {
|
|
setState(() {
|
|
});
|
|
_onButtonBarVisibleStreamController.add(true);
|
|
}
|
|
|
|
void _onHeightBar(double height) {
|
|
_onButtonBarHeightStreamController.add(height);
|
|
}
|
|
|
|
void _onHideBar() {
|
|
setState(() {
|
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom]);
|
|
});
|
|
_onButtonBarVisibleStreamController.add(false);
|
|
}
|
|
|
|
Future<void> _onHangup() async {
|
|
_signaling?.finishSessions();
|
|
print('onHangup');
|
|
Navigator.of(context).pop();
|
|
}
|
|
} |