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.
217 lines
6.4 KiB
Dart
217 lines
6.4 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart';
|
|
import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart';
|
|
import 'package:diplomaticquarterapp/pages/webRTC/call_page.dart';
|
|
import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart';
|
|
import 'package:diplomaticquarterapp/uitl/SignalRUtil.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
|
|
|
import '../conference_button_bar.dart';
|
|
|
|
class CallHomePage extends StatefulWidget {
|
|
final String receiverId;
|
|
final String callerId;
|
|
|
|
const CallHomePage({Key key, this.receiverId, this.callerId}) : super(key: key);
|
|
|
|
@override
|
|
_CallHomePageState createState() => _CallHomePageState();
|
|
}
|
|
|
|
class _CallHomePageState extends State<CallHomePage> {
|
|
bool showNoise = false;
|
|
RTCVideoRenderer _localRenderer = RTCVideoRenderer();
|
|
RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
|
|
|
|
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();
|
|
|
|
//Stream to enable video
|
|
MediaStream localMediaStream;
|
|
MediaStream remoteMediaStream;
|
|
Signaling signaling = Signaling()..init();
|
|
|
|
@override
|
|
void initState() {
|
|
// TODO: implement initState
|
|
super.initState();
|
|
startCall();
|
|
}
|
|
|
|
startCall() async{
|
|
await _localRenderer.initialize();
|
|
await _remoteRenderer.initialize();
|
|
final connected = await receivedCall();
|
|
}
|
|
|
|
|
|
Future<bool> receivedCall() async {
|
|
//Stream local media
|
|
localMediaStream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': true});
|
|
_localRenderer.srcObject = localMediaStream;
|
|
|
|
final connected = await signaling.acceptCall(widget.callerId, widget.receiverId, localMediaStream: localMediaStream, onRemoteMediaStream: (remoteMediaStream){
|
|
this.remoteMediaStream = remoteMediaStream;
|
|
_remoteRenderer.srcObject = remoteMediaStream;
|
|
});
|
|
|
|
if(connected){
|
|
signaling.signalR.listen(
|
|
onAcceptCall: (arg0){
|
|
print(arg0.toString());
|
|
},
|
|
onCandidate: (candidateJson){
|
|
signaling.addCandidate(candidateJson);
|
|
},
|
|
onDeclineCall: (arg0,arg1){
|
|
_onHangup();
|
|
},
|
|
onHangupCall: (arg0){
|
|
_onHangup();
|
|
},
|
|
|
|
onOffer: (offerSdp, callerUser) async{
|
|
print('${offerSdp.toString()} | ${callerUser.toString()}');
|
|
await signaling.answerOffer(offerSdp);
|
|
}
|
|
);
|
|
}
|
|
return connected;
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
// TODO: implement dispose
|
|
super.dispose();
|
|
_localRenderer?.dispose();
|
|
_remoteRenderer?.dispose();
|
|
_audioButton?.close();
|
|
_videoButton?.close();
|
|
localMediaStream?.dispose();
|
|
remoteMediaStream?.dispose();
|
|
_disposeStreamsAndSubscriptions();
|
|
}
|
|
|
|
Future<void> _disposeStreamsAndSubscriptions() async {
|
|
if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close();
|
|
if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// return WillPopScope(
|
|
// onWillPop: () async => false,
|
|
// child: Scaffold(
|
|
// backgroundColor: Colors.black,
|
|
// // body: ,
|
|
// ),
|
|
// );
|
|
|
|
return Scaffold(
|
|
backgroundColor: Colors.white,
|
|
body: showNoise ? _buildNoiseBox() : buildLayout(),
|
|
);
|
|
}
|
|
|
|
LayoutBuilder buildLayout() {
|
|
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,
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
NoiseBox _buildNoiseBox() {
|
|
return NoiseBox(
|
|
density: NoiseBoxDensity.xLow,
|
|
backgroundColor: Colors.grey.shade900,
|
|
child: Center(
|
|
child: Container(
|
|
color: Colors.black54,
|
|
width: double.infinity,
|
|
height: 40,
|
|
child: Center(
|
|
child: Text(
|
|
'Waiting for another participant to connect to the call...',
|
|
key: Key('text-wait'),
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(color: Colors.white),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
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.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
|
|
});
|
|
_onButtonBarVisibleStreamController.add(false);
|
|
}
|
|
|
|
Future<void> _onHangup() async {
|
|
signaling.hangupCall(widget.callerId, widget.receiverId);
|
|
print('onHangup');
|
|
Navigator.of(context).pop();
|
|
}
|
|
|
|
|
|
}
|