barcode_reader.dart
4.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import 'dart:async';
import 'dart:js_interop';
import 'dart:ui';
import 'package:mobile_scanner/src/enums/mobile_scanner_error_code.dart';
import 'package:mobile_scanner/src/enums/torch_state.dart';
import 'package:mobile_scanner/src/mobile_scanner_exception.dart';
import 'package:mobile_scanner/src/objects/barcode_capture.dart';
import 'package:mobile_scanner/src/objects/start_options.dart';
import 'package:web/web.dart';
/// This class represents the base interface for a barcode reader implementation.
abstract class BarcodeReader {
const BarcodeReader();
/// Whether the scanner is currently scanning for barcodes.
bool get isScanning {
throw UnimplementedError('isScanning has not been implemented.');
}
/// Get the size of the output of the video stream.
Size get videoSize {
throw UnimplementedError('videoSize has not been implemented.');
}
/// The id for the script tag that loads the barcode library.
///
/// If a script tag with this id already exists,
/// the library will not be loaded again.
String get scriptId => 'mobile-scanner-barcode-reader';
/// The script url for the barcode library.
String get scriptUrl {
throw UnimplementedError('scriptUrl has not been implemented.');
}
/// Start detecting barcodes.
///
/// The returned stream will emit a [BarcodeCapture] for each detected barcode.
Stream<BarcodeCapture> detectBarcodes() {
throw UnimplementedError('detectBarcodes() has not been implemented.');
}
/// Check whether the active camera has a flashlight.
Future<bool> hasTorch() {
// The torch of a media stream is not available for video tracks.
// See https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#instance_properties_of_video_tracks
return Future<bool>.value(false);
}
/// Load the barcode reader library.
///
/// If [alternateScriptUrl] is provided,
/// the script is loaded from that url instead.
///
/// Does nothing if the library is already loaded.
Future<void> maybeLoadLibrary({String? alternateScriptUrl}) async {
// Script already exists.
if (document.querySelector('script#$scriptId') != null) {
return;
}
final Completer<void> completer = Completer();
final HTMLScriptElement script = HTMLScriptElement()
..id = scriptId
..async = true
..defer = false
..type = 'application/javascript'
..lang = 'javascript'
..crossOrigin = 'anonymous'
..src = alternateScriptUrl ?? scriptUrl
..onload = (JSAny _) {
if (!completer.isCompleted) {
completer.complete();
}
}.toJS;
script.onerror = (JSAny _) {
if (!completer.isCompleted) {
// Remove the script if it did not load.
document.head!.removeChild(script);
completer.completeError(
const MobileScannerException(
errorCode: MobileScannerErrorCode.genericError,
errorDetails: MobileScannerErrorDetails(
message:
'Could not load the BarcodeReader script due to a network error.',
),
),
);
}
}.toJS;
document.head!.appendChild(script);
await completer.future;
}
/// Set a listener for the media stream settings.
void setMediaTrackSettingsListener(
void Function(MediaTrackSettings) listener,
) {
throw UnimplementedError(
'setMediaTrackConstraintsListener() has not been implemented.',
);
}
/// Set the torch state for the active camera to the given [value].
Future<void> setTorchState(TorchState value) {
throw UnsupportedError(
'Setting the torch state is not supported for video tracks on the web.\n'
'See https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#instance_properties_of_video_tracks',
);
}
/// Start the barcode reader and initialize the [videoStream].
///
/// The [options] are used to configure the barcode reader.
/// The [videoElement] will become the video output element.
/// The [videoStream] is the input for the barcode reader and video preview element.
Future<void> start(
StartOptions options, {
required HTMLVideoElement videoElement,
required MediaStream videoStream,
}) {
throw UnimplementedError('start() has not been implemented.');
}
/// Pause the barcode reader.
Future<void> pause() {
throw UnimplementedError('pause() has not been implemented.');
}
/// Stop the barcode reader and dispose of the video stream.
Future<void> stop() {
throw UnimplementedError('stop() has not been implemented.');
}
}