Created
June 19, 2021 20:16
-
-
Save tomialagbe/b556c830c61a899f7317fa3ebac0bbb6 to your computer and use it in GitHub Desktop.
Flutter web: Access Webcam Video
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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