摘要
在 Cocos Creator 中,我們如何打開本地照相機進行拍照或者視訊
環境
cocos Creator 引擎2.4.3
編輯工具HBuild X
實作方法
1、開一個webview,加載webar.html
2、webar.html内容
<!DOCTYPE html>
<head>
<title>抓妖</title>
<meta charset="utf-8">
<script src="jquery-1.11.1.min.js"></script>
<script src="vconsole.min.js"></script>
<script src="webcamera.js"></script>
<script src="base64.js"></script>
<script src="md5.min.js"></script>
<script src="bootstrap.min.js"></script>
<script src="api_common.js"></script>
<style>
*{
margin: 0;
padding: 0;
}
.allscreen,.allscreenVideo{
position:fixed;
left:0;
right:0;
top:0;
bottom:0;
background:url("bg.jpg") no-repeat center center;
background-size:cover;
z-index:2;
}
#box{
background:url("4.gif") no-repeat center center;
background-size:cover;
width:435px;
height:435px;
position:absolute;
top:100px;
left:200px;
display:none;
}
#box2 {
width: 100%;
height: 100%;
position: relative;
}
#box2 img{
width: 150px;
height: 150px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -200px; /* 高度的一半 */
margin-left: -75px; /* 寬度的一半 */
}
.rotate{
-ms-transform:rotate(90deg); /* IE 9 */
-moz-transform:rotate(90deg); /* Firefox */
-webkit-transform:rotate(90deg); /* Safari and Chrome */
-o-transform:rotate(90deg); /* Opera */
}
body{
width:100%;
height:100%;
}
</style>
</head>
<body class="bodystyle">
<div >
<div id="cur" style="display:none;text-align: center;">ABCDEFG</div>
<select class="none" style="display:none;" id="videoDevice"></select>
<div class="allscreen">
<div class="allscreenVideo" style="display: none;">
<video id="cameraer" style="width:100%; height:100%; object-fit: fill;" playsinline="playsinline" autoplay></video>
</div>
<div id="box">
<!-- <img src="4.gif" /> -->
</div>
</div>
</div>
</body>
3.api_common.js 的内容
const webAR = new WebAR();
function initWebCamera(){
console.log("初始化攝像頭!")
const videoSelect = document.querySelector('#videoDevice');
webAR.listCamera(videoSelect)
.then(msg => {
videoSelect.onchange = () => {
webAR.openCamera(JSON.parse(videoSelect.value));
};
if(videoSelect.options.length>1){
videoSelect.value = videoSelect.options[1].value
}
if(videoSelect.options.length>5){
videoSelect.value = videoSelect.options[videoSelect.options.length-1].value
}
// 打開攝像頭
// 打開後置攝像頭參數: {audio: false, video: {facingMode: {exact: 'environment'}}}
openWebCamera(videoSelect.value);
})
.catch(err => {
// 沒有找到攝像頭
window.addEventListener("deviceorientation", orientationHandler, false);
});
}
function openWebCamera(aValue){
console.log("攝像頭打開函數!")
webAR.openCamera(JSON.parse(aValue)).then(msg => {
window.addEventListener("deviceorientation", orientationHandler, false);
}).catch(err => {
window.addEventListener("deviceorientation", orientationHandler, false);
});
}
function init(){
try{
window.addEventListener("deviceorientation", orientationHandler, false);
}catch(e){
toast('此裝置不支援AR');
}
initWebCamera();
}
function orientationHandler(event) {
console.log("這裡可以在打開照片機後做一些展示,比如設定一個怪物");
}
4.webAR.js
class WebAR {
constructor() {
// 前/後置攝像頭
this.cameras = ["user", "environment"];
}
/**
* 清單裝置上的所有攝像頭
* @param videoDevice
* @returns {Promise<T>}
*/
listCamera(videoDevice) {
return new Promise((resolve, reject) => {
navigator.mediaDevices.enumerateDevices()
.then((devices) => {
let index = 0;
devices.find((device) => {
if (device.kind === 'videoinput') {
const option = document.createElement('option');
// 在iOS12.2上deviceId為空
if (device.deviceId == '') {
option.text = device.label || 'camera ' + this.cameras[index];
option.value = JSON.stringify({ audio: false, video: { facingMode: { exact: this.cameras[index] } } });
index++;
} else {
option.text = device.label || 'camera ' + (videoDevice.length + 1).toString();
option.value = JSON.stringify({ audio: false, video: { deviceId: { exact: device.deviceId } } });
}
// 将攝像頭資訊存儲在select元素中,友善切換前、後置攝像頭
videoDevice.appendChild(option);
}
return false;
});
if (videoDevice.length === 0) {
reject('沒有可使用的視訊裝置');
} else {
this.initVideo();
resolve(true);
}
}).catch(err => {
reject(err);
});
});
}
/**
* 打開攝像頭
* 攝像頭設定參數請檢視: https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
* @param videoDeviceIndex
* @returns {Promise<T>}
*/
openCamera(constraints) {
// 如果是切換攝像頭,則需要先關閉。
if (this.videoElement && this.videoElement.srcObject) {
this.videoElement.srcObject.getTracks().forEach(track => {
track.stop();
});
}
return new Promise((resolve, reject) => {
navigator.mediaDevices.getUserMedia(constraints).then(stream => {
this.videoElement.srcObject = stream;
$('.allscreenVideo').show();
this.videoElement.play();
this.videoElement.onloadedmetadata = () => {
const cameraSize = {
width: this.videoElement.offsetWidth,
height: this.videoElement.offsetHeight
};
console.log(window.screen.width,window.screen.height);
resolve(true);
};
}).catch(err => {
reject(err);
});
});
}
/**
* 建立視訊詳情元素,播放攝像頭視訊流
*/
initVideo() {
this.videoElement=document.getElementById('cameraer');
}
}
結語:
歡迎加入微信群一起學習讨論!