Resolves #143 Camera support
This commit is contained in:
@ -21,53 +21,59 @@ class _CameraControlsWidgetState extends State<CameraControlsWidget> {
|
|||||||
http.Client client;
|
http.Client client;
|
||||||
http.StreamedResponse response;
|
http.StreamedResponse response;
|
||||||
List<int> binaryImage = [];
|
List<int> binaryImage = [];
|
||||||
|
String cameraState = "Connecting...";
|
||||||
|
bool timeToStop = false;
|
||||||
|
Completer streamCompleter;
|
||||||
|
|
||||||
void _getData() async {
|
void _getData() async {
|
||||||
client = new http.Client(); // create a client to make api calls
|
client = new http.Client(); // create a client to make api calls
|
||||||
http.Request request = new http.Request("GET", Uri.parse(widget.url)); // create get request
|
http.Request request = new http.Request("GET", Uri.parse(widget.url)); // create get request
|
||||||
Logger.d("[Sending] ==> ${widget.url}");
|
Logger.d("[Sending] ==> ${widget.url}");
|
||||||
response = await client.send(request); // sends request and waits for response stream
|
response = await client.send(request);
|
||||||
|
setState(() {
|
||||||
|
cameraState = "Starting...";
|
||||||
|
});
|
||||||
Logger.d("[Received] <== ${response.headers}");
|
Logger.d("[Received] <== ${response.headers}");
|
||||||
List<int> primaryBuffer=[];
|
List<int> primaryBuffer=[];
|
||||||
int imageSizeStart = 0;
|
final int imageSizeStart = 59;
|
||||||
int imageSizeEnd = 0;
|
int imageSizeEnd = 0;
|
||||||
int imageStart = 0;
|
int imageStart = 0;
|
||||||
|
int imageSize = 0;
|
||||||
|
String strBuffer = "";
|
||||||
|
streamCompleter = Completer();
|
||||||
response.stream.transform(
|
response.stream.transform(
|
||||||
StreamTransformer.fromHandlers(
|
StreamTransformer.fromHandlers(
|
||||||
handleData: (data, sink) {
|
handleData: (data, sink) {
|
||||||
primaryBuffer.addAll(data);
|
primaryBuffer.addAll(data);
|
||||||
if (primaryBuffer.length >= 40) {
|
if (primaryBuffer.length >= 66) {
|
||||||
for (int i = 15; i < primaryBuffer.length - 16; i++) {
|
|
||||||
String tmp1 = utf8.decode(
|
|
||||||
primaryBuffer.sublist(i, i + 16), allowMalformed: true);
|
|
||||||
if (tmp1 == "Content-Length: ") {
|
|
||||||
imageSizeStart = i + 16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = imageSizeStart; i < primaryBuffer.length - 4; i++) {
|
for (int i = imageSizeStart; i < primaryBuffer.length - 4; i++) {
|
||||||
String tmp1 = utf8.decode(
|
strBuffer = utf8.decode(
|
||||||
primaryBuffer.sublist(i, i + 4), allowMalformed: true);
|
primaryBuffer.sublist(i, i + 4), allowMalformed: true);
|
||||||
if (tmp1 == "\r\n\r\n") {
|
if (strBuffer == "\r\n\r\n") {
|
||||||
imageSizeEnd = i;
|
imageSizeEnd = i;
|
||||||
imageStart = i + 4;
|
imageStart = i + 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int imageSize = int.tryParse(utf8.decode(
|
imageSize = int.tryParse(utf8.decode(
|
||||||
primaryBuffer.sublist(imageSizeStart, imageSizeEnd),
|
primaryBuffer.sublist(imageSizeStart, imageSizeEnd),
|
||||||
allowMalformed: true));
|
allowMalformed: true));
|
||||||
//Logger.d("== imageSize=$imageSize");
|
if (imageSize != null && primaryBuffer.length >= imageStart + imageSize + 2) {
|
||||||
if (primaryBuffer.length >= imageStart + imageSize) {
|
|
||||||
sink.add(
|
sink.add(
|
||||||
primaryBuffer.sublist(imageStart, imageStart + imageSize));
|
primaryBuffer.sublist(imageStart, imageStart + imageSize));
|
||||||
primaryBuffer = primaryBuffer.sublist(imageStart + imageSize);
|
primaryBuffer.removeRange(0, imageStart + imageSize + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (timeToStop) {
|
||||||
|
sink?.close();
|
||||||
|
streamCompleter.complete();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleError: (error, stack, sink) {
|
||||||
|
Logger.e("Error parsing MJPEG stream: $error");
|
||||||
},
|
},
|
||||||
handleError: (error, stack, sink) {},
|
|
||||||
handleDone: (sink) {
|
handleDone: (sink) {
|
||||||
sink.close();
|
sink?.close();
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
).listen((d) {
|
).listen((d) {
|
||||||
@ -80,7 +86,11 @@ class _CameraControlsWidgetState extends State<CameraControlsWidget> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (binaryImage.isEmpty) {
|
if (binaryImage.isEmpty) {
|
||||||
return Text("Loading...");
|
return Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Text("$cameraState")
|
||||||
|
],
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return Column(
|
return Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@ -92,7 +102,14 @@ class _CameraControlsWidgetState extends State<CameraControlsWidget> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
client.close();
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
timeToStop = true;
|
||||||
|
if (streamCompleter != null && !streamCompleter.isCompleted) {
|
||||||
|
streamCompleter.future.then((_) {
|
||||||
|
client?.close();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
client?.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user