diff --git a/src/App.vue b/src/App.vue index fbcbd08..d7861fa 100644 --- a/src/App.vue +++ b/src/App.vue @@ -9,31 +9,32 @@
自拍预览
+
+ {{ errorMsg }} +
+
- 打开摄像头 - 拍照 重拍 @@ -50,15 +51,22 @@
+ + -
+
调试信息
-
{{ responseText }}
+
{{ debug }}
+
+ +
+
年龄:{{ ageDisplay }}
+
性别:{{ genderDisplay }}
@@ -78,43 +86,59 @@ export default { photoData: null, photoBlob: null, loading: false, - responseText: '', + debug: '', + errorMsg: '', + saveConsent: true, + age: null, + gender: null, } }, methods: { async startCamera() { - this.stream = await navigator.mediaDevices.getUserMedia({ - video: { facingMode: 'user' }, - audio: false, - }) - this.cameraActive = true - await this.$nextTick() - const videoEl = this.$refs.video - videoEl.srcObject = this.stream - await videoEl.play().catch(() => {}) + try { + this.stream = await navigator.mediaDevices.getUserMedia({ + video: { facingMode: 'user' }, + audio: false, + }) + this.cameraActive = true + await this.$nextTick() + const videoEl = this.$refs.video + videoEl.srcObject = this.stream + await videoEl.play().catch(() => {}) + } catch (e) { + this.errorMsg = e + } }, takePhoto() { - const video = this.$refs.video - const canvas = document.createElement('canvas') - canvas.width = video.videoWidth || 320 - canvas.height = video.videoHeight || 240 - const ctx = canvas.getContext('2d') - ctx.drawImage(video, 0, 0, canvas.width, canvas.height) - canvas.toBlob( - (blob) => { - this.photoBlob = blob - this.photoData = URL.createObjectURL(blob) - }, - 'image/jpeg', - 0.9 - ) - this.stopCamera() + try { + const video = this.$refs.video + const canvas = document.createElement('canvas') + canvas.width = video.videoWidth || 320 + canvas.height = video.videoHeight || 240 + const ctx = canvas.getContext('2d') + ctx.drawImage(video, 0, 0, canvas.width, canvas.height) + canvas.toBlob( + (blob) => { + this.photoBlob = blob + this.photoData = URL.createObjectURL(blob) + }, + 'image/jpeg', + 0.9 + ) + this.stopCamera() + } catch (e) { + this.errorMsg = e + } }, retake() { - if (this.photoData) URL.revokeObjectURL(this.photoData) - this.photoData = null - this.photoBlob = null - this.startCamera() + try { + if (this.photoData) URL.revokeObjectURL(this.photoData) + this.photoData = null + this.photoBlob = null + this.startCamera() + } catch (e) { + this.errorMsg = e + } }, stopCamera() { if (this.stream) { @@ -124,40 +148,69 @@ export default { this.cameraActive = false }, onFileChange(e) { - const file = e.target.files && e.target.files[0] - if (!file) return - this.photoBlob = file - this.photoData = URL.createObjectURL(file) + try { + const file = e.target.files && e.target.files[0] + this.photoBlob = file + this.photoData = URL.createObjectURL(file) + } catch (e) { + this.errorMsg = e + } }, async uploadPhoto() { - if (!this.photoBlob) return alert('请先拍照或选择图片') + if (!this.photoBlob) { + this.errorMsg = '请先拍照或选择图片' + return + } this.loading = true - this.responseText = '' + this.debug = '' try { const form = new FormData() form.append('face', this.photoBlob, 'selfie.jpg') - const resp = await fetch('https://api.littlew.top/age', { + let url = 'https://api.littlew.top/age' + if (this.saveConsent) url += '?save=true' + const resp = await fetch(url, { method: 'POST', body: form, + }, { + credentials: 'include', }) const text = await resp.text() try { - const obj = JSON.parse(text) - this.responseText = JSON.stringify(obj, null, 2) + const data = JSON.parse(text) + this.debug = data.raw + this.age = typeof data.age === 'number' ? data.age : -1 + this.gender = typeof data.gender === 'number' ? data.gender : -1 } catch (e) { - this.responseText = text + this.debug = text + this.age = -1 + this.gender = -1 } } catch (e) { - this.responseText = e.message + this.errorMsg = e } finally { this.loading = false } }, }, + computed: { + ageDisplay() { + if (this.age === null) return '未知' + return this.age > -1 ? String(this.age) : '未知' + }, + genderDisplay() { + if (this.gender === null) return '未知' + if (this.gender === 0) return 'Female' + if (this.gender === 1) return 'Male' + return '未知' + }, + }, beforeUnmount() { this.stopCamera() }, + mounted() { + this.startCamera() + } }