Skip to content

Commit

Permalink
dev
Browse files Browse the repository at this point in the history
  • Loading branch information
balajahe committed Jul 15, 2020
1 parent 2cf840c commit 5391c7f
Show file tree
Hide file tree
Showing 6 changed files with 559 additions and 0 deletions.
165 changes: 165 additions & 0 deletions zdev/cctv_multicam_flutter/lib/VideoClient.dart
@@ -0,0 +1,165 @@
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:camera/camera.dart';

const SRV_ADDR = '192.168.43.245:4040';

class VideoClientPage extends StatelessWidget {
@override build(context) => Scaffold(
appBar: AppBar(title: Text('Camera')),
body: VideoClientWidget(),
);
}

class VideoClientWidget extends StatefulWidget {
final String srvAddr;
VideoClientWidget([this.srvAddr = SRV_ADDR]);
@override createState() => _State();
}

class _State extends State<VideoClientWidget> {
TextEditingController _srvAddr;
CameraController _camera;
WebSocket _socket;
String _adir;
Timer _timer;
Exception _err;
bool _recording = false;
int _recorded = 0;

@override initState() {
super.initState();
() async {
_adir = (await getApplicationDocumentsDirectory()).path;
_srvAddr = TextEditingController(text: widget.srvAddr);
final cams = await availableCameras();
print('-------\n $cams \n-------\n');
_camera = CameraController(cams[0], ResolutionPreset.medium);
await _camera.initialize();
setState((){});
}();
}

Future<void> _startRec() async {
try {
_recorded = _recorded == 1 ? 2 : 1;
await _camera.startVideoRecording('$_adir/0$_recorded.mp4');
setState((){});
} catch(e) { setState(() => _err = e); }
}

Future<void> _stopRec(bool again) async {
try {
await _camera.stopVideoRecording();
final prevfile = '$_adir/0$_recorded.mp4';
if (again) await _startRec();
_socket.add(await File(prevfile).readAsBytes());
await File(prevfile).delete();
} catch(e) { setState(() => _err = e); }
}

Future<void> _startStopRec() async {
_recording = !_recording;
setState(() =>_err = null);
if (_recording) {
try {
_err = null;
_socket = await WebSocket.connect('ws://' + _srvAddr.text);
_fdel('01.mp4');
_fdel('02.mp4');
await _startRec();
_timer = Timer.periodic(Duration(seconds: 3), (_) => _stopRec(true));
} catch(e) { setState(() => _err = e); }
} else {
_timer.cancel();
await _stopRec(false);
await _socket.close();
}
}

void _fdel(fname) {
try { File('$_adir/$fname').deleteSync(); } catch(_) {}
}

@override dispose() {
_timer.cancel();
_socket.close();
_camera.dispose();
super.dispose();
}

@override build(context) {
if (_err != null) return Center(child: Text(_err.toString()));
if (_camera?.value == null) return Center(child: Text('Activating camera...'));
return Scaffold(
body: Column(children: [
Row(children: [
Text(' Server: '),
Expanded(child: TextFormField(
controller: _srvAddr,
decoration: InputDecoration(hintText: 'IP:port'),
//autofocus: true,
)),
_recording ? Text('0$_recorded.mp4') : Container(),
]),
Expanded(child: AspectRatio(
aspectRatio: _camera.value.aspectRatio,
child: CameraPreview(_camera)
)),
]),
floatingActionButton: FloatingActionButton.extended(
label: Text(_recording ? 'STOP' : 'START'),
backgroundColor: _recording ? Colors.red : null,
onPressed: _startStopRec,
),
);
}
}

/*
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
TextFormField(
controller: _taskController,
key: ArchSampleKeys.taskField,
style: Theme.of(context).textTheme.headline,
decoration: InputDecoration(
hintText: ArchSampleLocalizations.of(context).newTodoHint,
),
validator: (val) {
return val.trim().isEmpty
? ArchSampleLocalizations.of(context).emptyTodoError
: null;
},
),
TextFormField(
controller: _noteController,
key: ArchSampleKeys.noteField,
decoration: InputDecoration(
hintText: ArchSampleLocalizations.of(context).notesHint,
),
maxLines: 10,
)
],
),
),
),
floatingActionButton: FloatingActionButton(
key: ArchSampleKeys.saveTodoFab,
tooltip: ArchSampleLocalizations.of(context).saveChanges,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
widget.onEdit(_taskController.text, _noteController.text);
}
},
child: const Icon(Icons.check),
),
);
}
}
*/
144 changes: 144 additions & 0 deletions zdev/cctv_multicam_flutter/lib/VideoServer.dart
@@ -0,0 +1,144 @@
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:video_player/video_player.dart';

const SRV_PORT = 4040;

class VideoServerPage extends StatelessWidget {
@override build(context) => Scaffold(
appBar: AppBar(title: Text('Recorder')),
body: VideoServerWidget(),
);
}

class VideoServerWidget extends StatefulWidget {
final int srvPort;
VideoServerWidget([this.srvPort = SRV_PORT]);
@override createState() => _State();
}

class _State extends State<VideoServerWidget> {
HttpServer _server;
WebSocket _socket;
VideoPlayerController _player;
String _adir;
Exception _err;
bool _playing = false;
int _received = 0;
int _played = 0;

@override initState() {
super.initState();
() async {
try {
_adir = (await getApplicationDocumentsDirectory()).path;
_server = await HttpServer.bind('127.0.0.1', SRV_PORT);
_server.listen((req) async {
try {
_socket = await WebSocketTransformer.upgrade(req);
_socket.listen((msg) async {
try {
await File('$_adir/${_received+1}.mp4').writeAsBytes(msg);
_received++;
if (!_playing) {
if (_played == 0) {
Timer(Duration(seconds: 3), _play);
} else if (_received > _played) {
_play();
}
}
} catch(e) { setState(() => _err = e); }
});
} catch(e) { setState(() => _err = e); }
});
} catch(e) { setState(() => _err = e); }
}();
}

Future<void> _play() async {
try {
_played++;
_player = VideoPlayerController.file(File('$_adir/$_played.mp4'));
await _player.initialize();
await _player.play();
_player.addListener(() {
if (_player.value.position == _player.value.duration) {
_playing = false;
if (_received > _played) {
_play();
} else {
setState((){});
}
}
});
_playing = true;
setState((){});
} catch(e) { setState(() => _err = e); }
}

@override dispose() {
_server.close(force: true);
_player.dispose();
super.dispose();
}

@override build(context) {
if (_err != null) return Center(child: Text(_err.toString()));
if (!_playing) return Center(child: Text('Lisening port $SRV_PORT...'));
return Column(children: [
Text('$_played.mp4'),
Expanded(child: AspectRatio(
aspectRatio: _player.value.aspectRatio,
child: VideoPlayer(_player),
))
]);
}
}

/*
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
TextFormField(
controller: _taskController,
key: ArchSampleKeys.taskField,
style: Theme.of(context).textTheme.headline,
decoration: InputDecoration(
hintText: ArchSampleLocalizations.of(context).newTodoHint,
),
validator: (val) {
return val.trim().isEmpty
? ArchSampleLocalizations.of(context).emptyTodoError
: null;
},
),
TextFormField(
controller: _noteController,
key: ArchSampleKeys.noteField,
decoration: InputDecoration(
hintText: ArchSampleLocalizations.of(context).notesHint,
),
maxLines: 10,
)
],
),
),
),
floatingActionButton: FloatingActionButton(
key: ArchSampleKeys.saveTodoFab,
tooltip: ArchSampleLocalizations.of(context).saveChanges,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
widget.onEdit(_taskController.text, _noteController.text);
}
},
child: const Icon(Icons.check),
),
);
}
}
*/
17 changes: 17 additions & 0 deletions zdev/cctv_multicam_flutter/lib/VideoTest.dart
@@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import './VideoClient.dart';
import './VideoServer.dart';

class VideoTestPage extends StatelessWidget {
@override build(context) => Scaffold(
appBar: AppBar(title: Text('Local test')),
body: Column(
mainAxisAlignment : MainAxisAlignment.spaceEvenly,
children: [
Expanded(child: VideoClientWidget('127.0.0.1:4040')),
Container(height: 2, color: Colors.blue),
Expanded(child: VideoServerWidget(4040)),
]
),
);
}
16 changes: 16 additions & 0 deletions zdev/cctv_multicam_flutter/lib/generated_plugin_registrant.dart
@@ -0,0 +1,16 @@
//
// Generated file. Do not edit.
//

// ignore: unused_import
import 'dart:ui';

import 'package:video_player_web/video_player_web.dart';

import 'package:flutter_web_plugins/flutter_web_plugins.dart';

// ignore: public_member_api_docs
void registerPlugins(PluginRegistry registry) {
VideoPlayerPlugin.registerWith(registry.registrarFor(VideoPlayerPlugin));
registry.registerMessageHandler();
}

0 comments on commit 5391c7f

Please sign in to comment.