Showing
1 changed file
with
0 additions
and
192 deletions
lib/mobile_scanner_web_plugin.dart
deleted
100644 → 0
| 1 | -import 'dart:async'; | ||
| 2 | -import 'dart:html' as html; | ||
| 3 | -import 'dart:ui_web' as ui; | ||
| 4 | - | ||
| 5 | -import 'package:flutter/services.dart'; | ||
| 6 | -import 'package:flutter_web_plugins/flutter_web_plugins.dart'; | ||
| 7 | -import 'package:mobile_scanner/mobile_scanner_web.dart'; | ||
| 8 | -import 'package:mobile_scanner/src/enums/barcode_format.dart'; | ||
| 9 | -import 'package:mobile_scanner/src/enums/camera_facing.dart'; | ||
| 10 | - | ||
| 11 | -/// This plugin is the web implementation of mobile_scanner. | ||
| 12 | -/// It only supports QR codes. | ||
| 13 | -class MobileScannerWebPlugin { | ||
| 14 | - static void registerWith(Registrar registrar) { | ||
| 15 | - final PluginEventChannel event = PluginEventChannel( | ||
| 16 | - 'dev.steenbakker.mobile_scanner/scanner/event', | ||
| 17 | - const StandardMethodCodec(), | ||
| 18 | - registrar, | ||
| 19 | - ); | ||
| 20 | - final MethodChannel channel = MethodChannel( | ||
| 21 | - 'dev.steenbakker.mobile_scanner/scanner/method', | ||
| 22 | - const StandardMethodCodec(), | ||
| 23 | - registrar, | ||
| 24 | - ); | ||
| 25 | - final MobileScannerWebPlugin instance = MobileScannerWebPlugin(); | ||
| 26 | - | ||
| 27 | - channel.setMethodCallHandler(instance.handleMethodCall); | ||
| 28 | - event.setController(instance.controller); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | - // Controller to send events back to the framework | ||
| 32 | - StreamController controller = StreamController.broadcast(); | ||
| 33 | - | ||
| 34 | - // ID of the video feed | ||
| 35 | - String viewID = 'WebScanner-${DateTime.now().millisecondsSinceEpoch}'; | ||
| 36 | - | ||
| 37 | - static final html.DivElement vidDiv = html.DivElement(); | ||
| 38 | - | ||
| 39 | - /// Represents barcode reader library. | ||
| 40 | - /// Change this property if you want to use a custom implementation. | ||
| 41 | - /// | ||
| 42 | - /// Example of using the jsQR library: | ||
| 43 | - /// void main() { | ||
| 44 | - /// if (kIsWeb) { | ||
| 45 | - /// MobileScannerWebPlugin.barCodeReader = | ||
| 46 | - /// JsQrCodeReader(videoContainer: MobileScannerWebPlugin.vidDiv); | ||
| 47 | - /// } | ||
| 48 | - /// runApp(const MaterialApp(home: MyHome())); | ||
| 49 | - /// } | ||
| 50 | - static WebBarcodeReaderBase barCodeReader = | ||
| 51 | - ZXingBarcodeReader(videoContainer: vidDiv); | ||
| 52 | - StreamSubscription? _barCodeStreamSubscription; | ||
| 53 | - | ||
| 54 | - /// Handle incomming messages | ||
| 55 | - Future<dynamic> handleMethodCall(MethodCall call) async { | ||
| 56 | - switch (call.method) { | ||
| 57 | - case 'start': | ||
| 58 | - return _start(call.arguments as Map); | ||
| 59 | - case 'torch': | ||
| 60 | - return _torch(call.arguments); | ||
| 61 | - case 'stop': | ||
| 62 | - return cancel(); | ||
| 63 | - case 'updateScanWindow': | ||
| 64 | - return Future<void>.value(); | ||
| 65 | - default: | ||
| 66 | - throw PlatformException( | ||
| 67 | - code: 'Unimplemented', | ||
| 68 | - details: "The mobile_scanner plugin for web doesn't implement " | ||
| 69 | - "the method '${call.method}'", | ||
| 70 | - ); | ||
| 71 | - } | ||
| 72 | - } | ||
| 73 | - | ||
| 74 | - /// Can enable or disable the flash if available | ||
| 75 | - Future<void> _torch(arguments) async { | ||
| 76 | - barCodeReader.toggleTorch(enabled: arguments == 1); | ||
| 77 | - } | ||
| 78 | - | ||
| 79 | - /// Starts the video stream and the scanner | ||
| 80 | - Future<Map> _start(Map arguments) async { | ||
| 81 | - var cameraFacing = CameraFacing.front; | ||
| 82 | - if (arguments.containsKey('facing')) { | ||
| 83 | - cameraFacing = CameraFacing.values[arguments['facing'] as int]; | ||
| 84 | - } | ||
| 85 | - | ||
| 86 | - ui.platformViewRegistry.registerViewFactory( | ||
| 87 | - viewID, | ||
| 88 | - (int id) { | ||
| 89 | - return vidDiv | ||
| 90 | - ..style.width = '100%' | ||
| 91 | - ..style.height = '100%'; | ||
| 92 | - }, | ||
| 93 | - ); | ||
| 94 | - | ||
| 95 | - // Check if stream is running | ||
| 96 | - if (barCodeReader.isStarted) { | ||
| 97 | - final hasTorch = await barCodeReader.hasTorch(); | ||
| 98 | - return { | ||
| 99 | - 'ViewID': viewID, | ||
| 100 | - 'videoWidth': barCodeReader.videoWidth, | ||
| 101 | - 'videoHeight': barCodeReader.videoHeight, | ||
| 102 | - 'torchable': hasTorch, | ||
| 103 | - }; | ||
| 104 | - } | ||
| 105 | - try { | ||
| 106 | - List<BarcodeFormat>? formats; | ||
| 107 | - if (arguments.containsKey('formats')) { | ||
| 108 | - formats = (arguments['formats'] as List) | ||
| 109 | - .cast<int>() | ||
| 110 | - .map(BarcodeFormat.fromRawValue) | ||
| 111 | - .toList(); | ||
| 112 | - } | ||
| 113 | - | ||
| 114 | - final Duration? detectionTimeout; | ||
| 115 | - if (arguments.containsKey('timeout')) { | ||
| 116 | - detectionTimeout = Duration(milliseconds: arguments['timeout'] as int); | ||
| 117 | - } else { | ||
| 118 | - detectionTimeout = null; | ||
| 119 | - } | ||
| 120 | - | ||
| 121 | - await barCodeReader.start( | ||
| 122 | - cameraFacing: cameraFacing, | ||
| 123 | - formats: formats, | ||
| 124 | - detectionTimeout: detectionTimeout, | ||
| 125 | - ); | ||
| 126 | - | ||
| 127 | - _barCodeStreamSubscription = | ||
| 128 | - barCodeReader.detectBarcodeContinuously().listen((code) { | ||
| 129 | - if (code != null) { | ||
| 130 | - controller.add({ | ||
| 131 | - 'name': 'barcodeWeb', | ||
| 132 | - 'data': { | ||
| 133 | - 'rawValue': code.rawValue, | ||
| 134 | - 'rawBytes': code.rawBytes, | ||
| 135 | - 'format': code.format.rawValue, | ||
| 136 | - 'displayValue': code.displayValue, | ||
| 137 | - 'type': code.type.rawValue, | ||
| 138 | - if (code.corners.isNotEmpty) | ||
| 139 | - 'corners': code.corners | ||
| 140 | - .map( | ||
| 141 | - (Offset c) => <Object?, Object?>{'x': c.dx, 'y': c.dy}, | ||
| 142 | - ) | ||
| 143 | - .toList(), | ||
| 144 | - }, | ||
| 145 | - }); | ||
| 146 | - } | ||
| 147 | - }); | ||
| 148 | - | ||
| 149 | - final hasTorch = await barCodeReader.hasTorch(); | ||
| 150 | - final bool? enableTorch = arguments['torch'] as bool?; | ||
| 151 | - | ||
| 152 | - if (hasTorch && enableTorch != null) { | ||
| 153 | - await barCodeReader.toggleTorch(enabled: enableTorch); | ||
| 154 | - } | ||
| 155 | - | ||
| 156 | - return { | ||
| 157 | - 'ViewID': viewID, | ||
| 158 | - 'videoWidth': barCodeReader.videoWidth, | ||
| 159 | - 'videoHeight': barCodeReader.videoHeight, | ||
| 160 | - 'torchable': hasTorch, | ||
| 161 | - }; | ||
| 162 | - } catch (e, stackTrace) { | ||
| 163 | - throw PlatformException( | ||
| 164 | - code: 'MobileScannerWeb', | ||
| 165 | - message: '$e', | ||
| 166 | - details: stackTrace.toString(), | ||
| 167 | - ); | ||
| 168 | - } | ||
| 169 | - } | ||
| 170 | - | ||
| 171 | - /// Check if any camera's are available | ||
| 172 | - static Future<bool> cameraAvailable() async { | ||
| 173 | - final sources = | ||
| 174 | - await html.window.navigator.mediaDevices!.enumerateDevices(); | ||
| 175 | - for (final e in sources) { | ||
| 176 | - // TODO: | ||
| 177 | - // ignore: avoid_dynamic_calls | ||
| 178 | - if (e.kind == 'videoinput') { | ||
| 179 | - return true; | ||
| 180 | - } | ||
| 181 | - } | ||
| 182 | - return false; | ||
| 183 | - } | ||
| 184 | - | ||
| 185 | - /// Stops the video feed and analyzer | ||
| 186 | - Future<void> cancel() async { | ||
| 187 | - await barCodeReader.stop(); | ||
| 188 | - await barCodeReader.stopDetectBarcodeContinuously(); | ||
| 189 | - await _barCodeStreamSubscription?.cancel(); | ||
| 190 | - _barCodeStreamSubscription = null; | ||
| 191 | - } | ||
| 192 | -} |
-
Please register or login to post a comment