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