Monaca Docs
質問…
K
Comment on page

Web APIの利用方法

このチュートリアルでは、サンプルアプリケーションを通して、デバイスカメラでの写真撮影ができる MediaDevices API の使用方法を説明します。

Electron TODOアプリの作成

まず、Monacaテンプレートを使用してアプリケーションを作成しましょう。 Monacaダッシュボードから、 新しいプロジェクトを作る → サンプルアプリケーション に移動します。 次に、テンプレートリストから Electron TODOアプリ を選択し、プロジェクト名と説明を入力して、プロジェクトを作成します。

アプリケーション機能

このサンプルアプリケーションは、ToDoリストを作成および管理できます。 ユーザーは、既存の写真をアップロードするか、写真を撮影して追加できます。リストはローカルストレージに保存されます。
このチュートリアルでは、MediaCapture APIを使用して写真を撮る方法の説明に焦点を当てます。
アプリケーションを開くと、ローカルストレージに保存されているアイテムが表示されます。
アプリケーションダッシュボード
新しいアイテムを作成するには、アプリケーションの右側にある + new ボタンをクリックします。 新しいモーダルダイアログが表示されます。 camera ボタンをクリックして、ToDoアイテムの入力、既存の写真のアップロードまたは新しい写真の撮影を行うことができます。
Add New Item
camera ボタンをクリックすると、カメラのビューを持つ別のモーダルダイアログが表示されます。 Capture ボタンを押すと、ボックス内のレンダリングがキャプチャされ、画像として保存されます。

HTMLの説明

カメラモーダル

次のコードは、カメラモーダルについてです。 camera ボタンをクリックすると、このモーダルが表示されます。モーダルには、3つのボタンrotatecapturecancel があります。 rotate ボタンは、デバイスが前面カメラと背面カメラの切り替えをサポートしている場合にのみ表示されます。 video要素(id=video-container)は、内蔵のカメラからの映像をストリーミングするために使用されています。
<div class="modal fade" id="camera-modal" tabindex="-1" data-backdrop="static" role="dialog" aria-labelledby="camera-modal-label" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="camera-header-modal"></div>
<div class="camera-modal-body modal-body text-center">
<video id="video-container" class="camera-preview" autoplay></video>
</div>
<a id="cordova-camera-cancel" class="btn enabled camera-close-btn" data-dismiss="modal"><i class="fa fa-times"></i> cancel</a>
<a id="rotate-camera" class="btn enabled camera-rotate-btn"><i class="fa fa-sync"></i> Rotate</a>
<a id="camera-capture" class="btn enabled camera-capture-btn" data-dismiss="modal"><i class="fa fa-camera"></i> Capture</a>
</div>
</div>
</div>

JavaScriptの説明

グローバル変数宣言

カメラ機能に関する重要な変数を簡単に見てみましょう。
  • isFrontCamera: フロントカメラとリアカメラを切り替えるために使用されます。
  • FRONT_CAMERA: mediaDevices APIの facingMode Enum のフロントカメラ値を保存するために使用されます。
  • REAR_CAMERA: mediaDevices APIの facingMode Enum の背面カメラ値を保存するために使用されます。
let isFrontCamera;
const FRONT_CAMERA = 'user';
const REAR_CAMERA = 'environment';
const videoContainer = document.getElementById('video-container');
const btnOpenCameraModal = document.getElementById('open-camera-modal');
const btnRotateCamera = document.getElementById('rotate-camera');
...

mediaDevices API サポートの確認

次のコードは、(1)mediaDevices APIがサポートされているかどうかを確認し、 (2)デバイスがAndroidでrearカメラをデフォルトとして使用している場合は rotate ボタンをオンにします。
function initialize() {
// Check if getUserMedia is supported on the device
if (!hasMediaDevicesApi()) {
btnOpenCameraModal.hidden = true;
}
if (isAndroidOS()) {
// use rear camera for android
btnRotateCamera.hidden = false;
isFrontCamera = false;
} else {
// use front camera for browser/electron
btnRotateCamera.hidden = true;
isFrontCamera = true;
}
...
}
function hasMediaDevicesApi() {
return !!(navigator.mediaDevices &&
navigator.mediaDevices.getUserMedia);
}

カメラのオン/オフ

MediaStream を生成するメディア入力の使用許可をユーザーに求めるために、getUserMedia()を使用します。 ストリームには、ビデオトラック(カメラ、ビデオ録画デバイス、画面共有サービスなど)、オーディオトラック、他のトラックタイプを含めることができます。詳細については、こちらの 公式ドキュメント を参照してください。
var promise = navigator.mediaDevices.getUserMedia(constraints);
この関数は Promise を返し、 MediaStreamConstraints オブジェクトをパラメーターとして受け入れます。
次のコードでは、幅と高さを 250 ピクセルに指定し、指定された引数に基づいてカメラに面するモードを設定します。 カメラデバイスが正常に接続されると、 Media Stream オブジェクトが返され、video 要素に割り当てられます。
function turnOnCamera(frontCamera) {
const facingModeOption = frontCamera ? FRONT_CAMERA : REAR_CAMERA;
const constraints = {
video: {
width: {
exact: 250
},
height: {
exact: 250
},
facingMode: facingModeOption
}
};
// Access to the camera and turn it own
navigator.mediaDevices.getUserMedia(constraints)
.then(handleSuccess)
.catch(handleError);
function handleSuccess(stream) {
videoContainer.srcObject = stream;
}
function handleError(error) {
alert('Could not get user media API' + JSON.stringify(error));
}
}
カメラをオンにするには、トラックに関連付けられているすべてのソースを停止する必要があります。
function turnOfCamera() {
if (videoContainer && videoContainer.srcObject) {
videoContainer.srcObject.getTracks().forEach(function(track) {
track.stop();
});
videoContainer.srcObject = null;
}
}
次の機能は、カメラを前面と背面に切り替えます。
function rotateCamera(e) {
isFrontCamera = !isFrontCamera;
turnOfCamera();
turnOnCamera(isFrontCamera);
}

写真を撮る

ビデオ ストリーム/トラックから写真を撮るには、まず canvas 幅と高さをvideoContainerと合わせます。 次に、すべてのトラックを停止し、最後のトラックを画像形式に変換します。
function takePicture(e) {
const canvas = document.createElement('canvas');
// Saving current image
canvas.width = videoContainer.videoWidth;
canvas.height = videoContainer.videoHeight;
canvas.getContext('2d').drawImage(videoContainer, 0, 0);
// If the video source Object is set, stop all tracks
if (videoContainer.srcObject) {
videoContainer.srcObject.getTracks().forEach(function(track) {
track.stop();
try {
// Other browsers will fall back to image/png
todoItemImage.src = canvas.toDataURL('image/webp');
} catch (error) {
alert('Could not get the picture.' + JSON.stringify(error));
}
});
}
}
See Also: