パソコンとWebカメラを使ったちょっとしたツールのアイディアが思い浮かびました。しかし普段Androidアプリを作っていて、WindowsネイティブやJavaScript + CSSを思い出すのが大変だと思ったので、Flutter WebでWebカメラを使うことにしました。

前準備
公式のこちらの記事を参考に環境構築とプロジェクト作成を行いました。
Flutterの世界の中にWebの世界を作る
今回はブラウザで動くJavaScriptのプログラミングをDartで行い、Webカメラへの接続(getUserMedia)とプレビュー表示(videoタグ)を行います。そのためにFlutterの世界の中にWebの世界を作ります。
まず、Webの世界を作りたい箇所にHtmlElementView
を貼ります。viewType
パラメータで名前を設定します。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: HtmlElementView(viewType: 'videoView'),
);
}
}
Webプログラミングを行う
こちらの2つのライブラリをインポートします。
import 'dart:ui' as ui;
import 'dart:html';
下記のように HtmlElementView
の内容をWebプログラミングします。 ui.platformViewRegistry.registerViewFactory
メソッドの第1引数は HtmlElementView
を貼ったときに設定した名前と同じにします。そして第2引数で渡すブロックがWebの世界になります。ブラウザで動くJavaScriptをDartで書けます。
ui.platformViewRegistry.registerViewFactory('videoView', (int viewId) {
// このブロックはWebの世界
// videoタグを作る
final video = VideoElement();
// ソースが設定されたら自動再生
video.autoplay = true;
// Webカメラへの接続を要求する
window.navigator.getUserMedia(video: true).then((stream) {
// Webカメラへの接続が成功
video.srcObject = stream;
});
// HtmlElementViewの内容を返却する
return video;
});
全体ソースコード
GitHubリポジトリに全体ソースコードがあります。
Webカメラが無かったり許可されていなかったりしたときのエラー処理も実装しています。
注意点
Android Studioのエラー表示
dart:ui
ライブラリの platformViewRegistry
変数へのアクセスはAndroid Studioではエラーを表す赤い下線が表示されました。しかし、コマンドラインではビルドできます。
公式のgetUserMediaメソッドの解説について
公式のgetUserMediaメソッドの解説では取得したMediaStreamクラスのオブジェクトに対してこのような使い方を案内しています。
video.src = Url.createObjectUrlFromStream(stream);
しかしこのやりかたは実行時エラーになりました。
html_dart2js.dart:30757 Uncaught (in promise) TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided.