Files
hospital-rescue-app-v2/uni_modules/x-camrea-u/utssdk/web/index.uts
T
2026-09-24 16:25:22 +08:00

200 lines
4.8 KiB
Plaintext

export type xCamreaUOpts = {
autoOpenCamera : boolean,
/**
* 是否打开闪光灯,对于orientation为back有效.
*/
flash : boolean,
/**
* 摄像头朝向,默认是后置
* back,front
*/
orientation : string,
/**
* 相机的像素宽
*/
cameraWidth : number,
/**
* 相机的像素高
*/
cameraHeight : number,
/**
* 容器的宽和高
*/
width : number,
/**
* 容器的宽和高
*/
height : number
}
export class xCamreaU {
$element : HTMLDivElement;
targetView : HTMLVideoElement = document.createElement("video");
config : xCamreaUOpts;
opening = false;
private stream:any = null;
private takeModelType = 'photo'
private mediaRecorder: null | MediaRecorder = null
private startRecoderVideoFunc = (path:string)=>{}
constructor(element : HTMLDivElement, opts : xCamreaUOpts) {
this.config = opts;
this.$element = element;
this.createVideo();
}
private createVideo(){
this.targetView.style.width = "100%"
this.targetView.style.height = "100%"
this.targetView.style.objectFit = "cover"
this.targetView.playsInline = true;
this.targetView.muted = true;
this.targetView.autoplay = true;
this.targetView.controls = false;
// 针对微信的x5内核
this.targetView.setAttribute('playsinline',true)
this.targetView.setAttribute('webkit-playsinline',true)
this.targetView.setAttribute('x5-playsinline',true)
this.targetView.setAttribute('x5-video-player-type','h5')
this.targetView.setAttribute('x5-video-player-fullscreen','false')
this.$element.appendChild(this.targetView)
}
getIsOpeningCameraing():boolean{
return this.opening
}
setCameraDir(dir:string){
}
setFlash(flash:boolean){
}
start(call:(path:string)=>void) {
this.takeModelType = 'video'
this.startRecoderVideoFunc = call;
if(!this.opening){
this.openCamrea();
}
}
/** 关闭相机 */
close() {
let t = this;
this.targetView.pause()
if (t.stream) {
t.stream.getTracks().forEach(function (track) {
track.stop();
});
t.stream = null;
}
this.mediaRecorder = null;
this.opening = false;
}
createMediaRecorder() {
let t = this;
if (!MediaRecorder.isTypeSupported('video/mp4')) {
console.error("设备不支持录制 mp4 格式")
this.startRecoderVideoFunc('')
return;
}
const options = { mimeType: 'video/mp4' }; // 默认格式为 WebM
this.mediaRecorder = new MediaRecorder(t.stream, options);
let chunks = [];
this.mediaRecorder!.ondataavailable = (event) => {
if (event.data.size > 0) {
chunks.push(event.data);
}
};
this.mediaRecorder!.onstop = () => {
// 将录制的片段合并为 Blob 对象
const blob = new Blob(chunks, { type: 'video/mp4' });
chunks = [];
const dataURL = URL.createObjectURL(blob)
this.startRecoderVideoFunc(dataURL)
};
this.mediaRecorder!.onerror = () => {
console.error("录制出错,请重试。")
this.startRecoderVideoFunc('')
}
this.mediaRecorder!.start()
}
openCamrea(){
if(this.opening) return;
this.opening = true;
var constraints = {
audio: true,
video: {
width: 1920,
height: 1080,
facingMode:this.config.orientation=='front'?{ exact: 'user' }:{ exact: 'environment' }
}
};
let t = this;
window.navigator.mediaDevices
.getUserMedia(constraints)
.then(function (mediaStream) {
t.stream = mediaStream
t.targetView.srcObject = t.stream;
t.targetView.onloadedmetadata = function (e) {
t.targetView.play();
if (t.takeModelType == 'video') {
t.createMediaRecorder()
}
};
})
.catch(function (err) {
console.log(err.name + ": " + err.message);
t.close()
});
}
takePhoto(call:(path:string)=>void){
let t = this;
if (!t.targetView || !t.stream || !t.opening) return call('');
var canvas = document.createElement('canvas');
canvas.width = t.targetView.videoWidth; // 设置canvas的宽度为视频的宽度
canvas.height = t.targetView.videoHeight; // 设置canvas的高度为视频的高度
var ctx = canvas.getContext('2d');
ctx!.drawImage(t.targetView, 0, 0, canvas.width, canvas.height);
canvas.toBlob((data) => {
const dataURL = data ? URL.createObjectURL(data) : ""
call(dataURL)
}, 'image/png', 1)
}
pause(){
// this.mediaRecorder?.pause()
this.close();
}
stop(){
this.mediaRecorder?.stop()
}
}
// 检查权限
export function checkPermissions():Promise<boolean> {
return new Promise(async (res, rej) => {
let devices = await navigator.mediaDevices.enumerateDevices()
let videoDevices = devices.filter(
(device) => device.kind === 'videoinput'
);
if (videoDevices.length == 0) {
rej(false)
console.error('没有找到可用的摄像设备')
return;
}
if(!(window.navigator?.mediaDevices??undefined)){
rej(false)
console.error('设备不支持')
return;
}
res(true)
})
}