diff --git a/public/index.html b/public/index.html
index 228be0d..54180b4 100644
--- a/public/index.html
+++ b/public/index.html
@@ -75,7 +75,6 @@
-
精彩即将为您呈现...
diff --git a/src/page/index/HandTrack/index.vue b/src/page/index/HandTrack/index.vue
index c3da005..809a26b 100644
--- a/src/page/index/HandTrack/index.vue
+++ b/src/page/index/HandTrack/index.vue
@@ -9,6 +9,7 @@
playsinline
webkit-playsinline
x5-playsinline
+ muted
ref="myVideo"
>
@@ -39,6 +40,9 @@
+
+
+
14 safria ok || > 14.3 ios webview ok
+ // > 14.3 ios ok
checkUserDeviceSuitable() {
if (
- window.deviceInfo.system === "IOS" &&
- window.deviceInfo.app === "WX"
+ window.deviceInfo.system === "IOS"
+ // && window.deviceInfo.app === "WX"
) {
let iosV = this.getIOSVersion();
if (
- !this.versionStringCompare(iosV, "14.3") &&
- this.versionStringCompare(iosV, "14.0")
+ !this.versionStringCompare(iosV, "14.3")
+ // && this.versionStringCompare(iosV, "14.0")
) {
- this.$Utils.showTips({
- message: "请点击右上角 ...在浏览器打开",
- autoClose: false,
- });
- } else if (!this.versionStringCompare(iosV, "14.0")) {
+ // this.$Utils.showTips({
+ // message: "请点击右上角 ...在浏览器打开",
+ // autoClose: false,
+ // });
+ // } else if (!this.versionStringCompare(iosV, "14.0")) {
this.$Utils.showTips({
message:
"😭 很抱歉⚠️ 当前系统版本过低无法体验该Demo",
@@ -162,11 +170,16 @@ export default {
};
}
- return global.navigator.mediaDevices
+ return navigator.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
if (stream) {
- stopStreamTracks(stream);
+ const tracks = stream.getTracks();
+ tracks.forEach(function (track) {
+ track.stop();
+ });
+
+ // stopStreamTracks(stream);
return true;
}
return Promise.reject(new Error("EmptyStreamError"));
@@ -178,21 +191,26 @@ export default {
return Promise.reject(errMsg);
});
},
- // 开始获取权限
+ // IOS 用户获取授权
requestPermission() {
- return this.getDevicePermission({ video: true, audio: true })
- .catch(() =>
- this.getDevicePermission({ video: false, audio: true })
- )
- .catch(() =>
- this.getDevicePermission({ video: true, audio: false })
- )
- .catch(() => true);
+ return (
+ this.getDevicePermission({ video: true })
+ // .catch(() =>
+ // this.getDevicePermission({ video: false, audio: true })
+ // )
+ // .catch(() =>
+ // this.getDevicePermission({ video: true, audio: true })
+ // )
+ .catch(() => true)
+ );
},
// 获取摄像头设备id
async getBackCameraDeviceId() {
+ await this.requestPermission();
let source = new Array();
+ console.log("start get camera devices");
let devices = await navigator.mediaDevices.enumerateDevices();
+ console.log("devices array:", devices);
if (devices.length > 0) {
devices.forEach(function (device) {
if (device.kind == "videoinput") {
@@ -200,6 +218,7 @@ export default {
}
});
}
+ console.log("devices source:", source);
return source[source.length - 1].deviceId;
},
// 初始化 video
@@ -222,8 +241,6 @@ export default {
// },
};
- this.video.play();
-
try {
this.stream = await navigator.mediaDevices.getUserMedia(
constraints
@@ -243,12 +260,12 @@ export default {
const videoTracks = stream.getVideoTracks();
this.stream = stream; // make variable available to browser console
let streamSize = this.GetStreamDimensions(stream);
- let handledSize = this.ScaleResolutionToHeight(
- streamSize,
- window.innerHeight
- );
+ // let handledSize = this.ScaleResolutionToHeight(
+ // streamSize,
+ // window.innerHeight
+ // );
- this.videoRealSize = handledSize;
+ // this.videoRealSize = handledSize;
console.log("Got stream with constraints:", constraints);
console.log(`Using video device: ${videoTracks[0].label}`);
@@ -256,13 +273,15 @@ export default {
console.log("Got stream size:", streamSize);
console.log(
"Got streamHandled size:",
- window.innerHeight,
- handledSize
+ window.innerHeight
+ // handledSize
);
- this.responseVideo(handledSize);
+ // this.responseVideoAndCanvas(handledSize);
this.video.srcObject = stream;
+ // this.video.play();
+
// 开始识别
this.startDraw();
},
@@ -271,9 +290,14 @@ export default {
console.error(error);
},
// 视频设置
- responseVideo(size) {
+ responseVideoAndCanvas(size) {
this.video.width = size.width;
this.video.height = size.height;
+
+ // init canvcas
+ this.ctx = this.canvas.getContext("2d");
+ this.canvas.width = size.width;
+ this.canvas.height = size.height;
},
// 获得stream大小
GetStreamDimensions(stream) {
@@ -327,6 +351,7 @@ export default {
this.progress = Math.round(progress * 100);
this.progressText = `${this.progress}%`;
});
+ console.log("engine model loaded");
this.progressText = "引擎准备中…";
this.engine.Configure({
@@ -358,16 +383,25 @@ export default {
autoAlpha: 1,
delay: 0.5,
});
-
+ // 识别引擎启动
+ this.engineStart();
+ },
+ // 识别引擎启动
+ engineStart() {
this.engine.Start((e) => {
+ let cursorPos;
if (e.coordinates) {
- const cursorPos = this.ExponentialCoordinateAverage(
+ cursorPos = this.ExponentialCoordinateAverage(
this.ComputeCursorPositionFromCoordinates(e.coordinates)
);
console.log(cursorPos);
}
+ // console.log(e.type);
+
if (e.type === EventEnum.RESULT) {
+ this.drawPoint(cursorPos[0], cursorPos[1]);
+ this.Render();
if (e.poses.fist) {
this.handStatus = "握拳";
if (this.handStep == 1) {
@@ -376,7 +410,6 @@ export default {
// document.getElementById("status").innerText = "握拳";
} else if (e.poses.pinch) {
this.handStatus = "捏合";
- // document.getElementById("status").innerText = "捏合";
} else {
this.handStatus = "张开";
if (this.handStep == 2) {
@@ -445,6 +478,54 @@ export default {
];
}
},
+ // init THREELayer
+ initTHREELayer() {
+ this.camera_ = new THREE.OrthographicCamera(
+ 0,
+ this.videoRealSize.width,
+ 0,
+ this.videoRealSize.height,
+ 0,
+ 1000
+ );
+ this.renderer_ = new THREE.WebGLRenderer({
+ alpha: true,
+ powerPreference: "high-performance",
+ failIfMajorPerformanceCaveat: false,
+ antialias: true,
+ });
+ this.renderer_.domElement = this.canvas;
+ this.renderer_.debug.checkShaderErrors = false;
+ this.renderer_.setSize(
+ this.videoRealSize.width,
+ this.videoRealSize.height
+ );
+ this.renderer_.setPixelRatio(window.devicePixelRatio);
+ this.renderer_.setClearColor(0x000000, 0.0);
+ this.renderer_.autoClear = true;
+ this.scene_ = new THREE.Scene();
+ },
+ // draw pointer
+ drawPoint(x, y) {
+ if (!this.meshAdded) {
+ this.geo_ = new THREE.RingGeometry(0, 8, 30);
+ this.mat_ = new THREE.MeshBasicMaterial({
+ color: "red",
+ side: THREE.DoubleSide,
+ });
+ this.mesh_ = new THREE.Mesh(this.geo_, this.mat_);
+ this.scene_.add(this.mesh_);
+ this.meshAdded = true;
+ }
+
+ this.mesh_.position.x = x * this.videoRealSize.width;
+ this.mesh_.position.y = y * this.videoRealSize.height;
+ this.mesh_.position.z = 0;
+ },
+ // THREE canvas render
+ Render() {
+ this.renderer_.render(this.scene_, this.camera_);
+ },
},
};
@@ -459,8 +540,8 @@ export default {
align-content: center;
align-items: center;
.video {
- .paLayout(50%,50%,auto,100%,0);
- transform: translate(-50%, -50%);
+ // .paLayout(50%,50%,auto,100%,0);
+ // transform: translate(-50%, -50%);
// transform: scaleX(-1);
// width: 750px;
display: none;
@@ -521,6 +602,12 @@ export default {
}
}
}
+ .canvas {
+ .paLayout(50%,50%,auto,100%,100);
+ transform: translate(-50%, -50%);
+ pointer-events: none;
+ background-color: rgba(255, 255, 255, 0.1);
+ }
.btn {
.paCenterBottom(50%,280px,80px,2);
background-color: rgba(255, 255, 255, 0.85);
@@ -534,7 +621,7 @@ export default {
.paCenter(50%,80%,40px,12);
margin-top: -20px;
border: 1px solid #fff;
- border-radius: 20px;
+ border-radius: 25px;
padding: 4px;
.bar {
.prLayout(100%,100%);