Skip to content

Instantly share code, notes, and snippets.

@tomialagbe
Created June 19, 2021 20:16
Show Gist options
  • Save tomialagbe/b556c830c61a899f7317fa3ebac0bbb6 to your computer and use it in GitHub Desktop.
Save tomialagbe/b556c830c61a899f7317fa3ebac0bbb6 to your computer and use it in GitHub Desktop.
Flutter web: Access Webcam Video
// ignore: avoid_web_libraries_in_flutter
import 'dart:html';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
void main() {
runApp(WebcamApp());
}
class WebcamApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: WebcamPage());
}
}
class WebcamPage extends StatefulWidget {
@override
_WebcamPageState createState() => _WebcamPageState();
}
class _WebcamPageState extends State<WebcamPage> {
CanvasElement _canvasElement = CanvasElement();
VideoElement _videoElement = VideoElement();
@override
void initState() {
super.initState();
_videoElement.autoplay = true;
// Ignore the linter error on ui.platformViewRegistry
ui.platformViewRegistry.registerViewFactory(
'webcam-video-canvas', (int viewId) => _canvasElement);
window.navigator.getUserMedia(video: true).then((MediaStream mediaStream) {
_videoElement.srcObject = mediaStream;
window.requestAnimationFrame(renderFrame);
}, onError: (err) {
print(err);
});
}
void renderFrame(num i) {
window.requestAnimationFrame(renderFrame);
_canvasElement.width = _canvasElement.scrollWidth;
_canvasElement.height = _canvasElement.scrollHeight;
if (_videoElement.readyState == MediaElement.HAVE_ENOUGH_DATA) {
var videoSize = Size(_videoElement.videoWidth.toDouble(),
_videoElement.videoHeight.toDouble());
var canvasSize = Size(_canvasElement.width?.toDouble() ?? 50.0,
_canvasElement.height?.toDouble() ?? 50.0);
var renderSize = calculateSize(videoSize, canvasSize);
var xOffset = (canvasSize.width - renderSize.width) / 2;
_canvasElement.context2D.translate(canvasSize.width, 0);
_canvasElement.context2D.scale(-1, 1);
_canvasElement.context2D.drawImageScaled(
_videoElement, xOffset, 0, renderSize.width, renderSize.height);
}
}
ui.Size calculateSize(ui.Size srcSize, ui.Size dstSize) {
var srcRatio = srcSize.width / srcSize.height;
var dstRatio = dstSize.width / dstSize.height;
if (dstRatio > srcRatio) {
return Size(dstSize.height * srcRatio, dstSize.height);
} else {
return Size(dstSize.width, dstSize.width / srcRatio);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Webcam MediaStream:',
style: TextStyle(fontSize: 30, fontStyle: FontStyle.italic),
),
Container(
width: 750,
height: 750,
child: HtmlElementView(viewType: 'webcam-video-canvas')),
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment