hldy_app/pages/smallcarmera.nvue

627 lines
17 KiB
Plaintext
Raw Permalink Normal View History

2025-10-27 17:16:52 +08:00
<template>
<div class="center-column" :style="{ height: isshow ? '675px' : '0px' }">
<!-- 视频播放组件 -->
<MonitorView ref="monitor" init="5" style="width: 675px;height: 475px;" @onTel="handleTelEvent"
@onSnapShot="handleSnapShotEvent" @onRecord="handleRecordEvent" @onTalkStatus="handleTalkEvent" />
</div>
</template>
<script>
export default {
data() {
return {
phoneNumber: "1234567890",
initnumber: 5,
isAlarming: false,
isRecording: false, // 录屏状态
isTalking: false, // 对讲状态
_pendingRequests: {
snapshot: [],
record: [],
talk: []
},
suo: true,
isshow: false,
globalEvent: ''
};
},
onLoad() {
console.log("???加载")
// 保留你的 globalEvent 监听
this.globalEvent = uni.requireNativePlugin && uni.requireNativePlugin("globalEvent");
if (this.globalEvent && this.globalEvent.addEventListener) {
this.globalEvent.addEventListener("myEvent", (e) => {
// console.log(e)
if (e.recordUrl) {
uni.showToast({
title: '录屏成功',
icon: 'success', // 'success' | 'loading' | 'none'
duration: 1500
})
}
if (e.snapShotUrl) {
uni.showToast({
title: '截屏成功',
icon: 'success', // 'success' | 'loading' | 'none'
duration: 1500
})
}
// console.log("00000",e.onVolumeChange)
if (this.suo && e.onVolumeChange) {
if (e.onVolumeChange) {
this.toggleVolume();
}
this.suo = false;
}
});
}
uni.setStorageSync('saveinit', 5);
uni.$on('smallmonitor:changeinit', (number) => {
this.$refs.monitor.initAutoPlay(number)
uni.setStorageSync('saveinit', number);
console.log("saveinit", number)
});
uni.$on('smallmonitor:isshow', (bool) => {
this.isshow = bool;
})
uni.$on('smallmonitor:killView', this.killView);
// 在页面生命周期注册 uni.$on 事件,暴露给其他页面调用
uni.$on('smallmonitor:doSnapshot', this.doSnapshot);
uni.$on('smallmonitor:startRecord', this.doStartRecord);
uni.$on('smallmonitor:stopRecord', this.doStopRecord);
uni.$on('smallmonitor:openTalk', this.doOpenTalk);
uni.$on('smallmonitor:stopTalk', this.doStopTalk);
uni.$on('smallmonitor:switchDisplay', (payload) => this.switchDisplay(payload));
uni.$on('smallmonitor:startAlarm', this.startAlarm);
uni.$on('smallmonitor:stopAlarm', this.stopAlarm);
uni.$on('smallmonitor:flipImage', (payload) => this.flipImage(payload));
uni.$on('smallmonitor:resumeOrPause', this.resumeOrPause);
uni.$on('smallmonitor:changeQuality', this.changeQuality);
uni.$on('smallmonitor:toggleVolume', this.toggleVolume);
uni.$on('smallmonitor:test', this.test);
},
onUnload() {
console.log('fullcamera 卸载,清理事件');
// 确保 globalEvent 有才清除
if (this.globalEvent && this.globalEvent.removeEventListener) {
this.globalEvent.removeEventListener("myEvent");
}
const events = [
'smallmonitor:killView',
'smallmonitor:changeinit',
'smallmonitor:isshow',
'smallmonitor:doSnapshot',
'smallmonitor:startRecord',
'smallmonitor:stopRecord',
'smallmonitor:openTalk',
'smallmonitor:stopTalk',
'smallmonitor:switchDisplay',
'smallmonitor:startAlarm',
'smallmonitor:stopAlarm',
'smallmonitor:flipImage',
'smallmonitor:resumeOrPause',
'smallmonitor:changeQuality',
'smallmonitor:toggleVolume',
'smallmonitor:test'
];
events.forEach(ev => uni.$off(ev)); // 💥这样会解绑当前页面注册的所有监听
},
methods: {
/* ------------------ 原有功能 ------------------ */
handleTelEvent(event) {
console.log("Tel event detail:", event.detail);
// 如果需要解析电话事件,在这里处理
},
killView() {
this.$refs.monitor.killView && this.$refs.monitor.killView();
},
switchDisplay(mode) {
console.log("zzzzz", mode)
this.$refs.monitor && this.$refs.monitor.switchDisplayModeFragment(mode);
},
startAlarm() {
this.isAlarming = true;
this.$refs.monitor.startOrStopManualAlarm(this.isAlarming, (res) => {
console.log("startAlarm callback:", res);
});
},
stopAlarm() {
this.isAlarming = false;
this.$refs.monitor.startOrStopManualAlarm(this.isAlarming, (res) => {
console.log("stopAlarm callback:", res);
});
},
flipImage(type) {
this.$refs.monitor.changeImageSwitch(type, (res) => {
console.log("flipImage callback:", res);
});
},
resumeOrPause() {
this.$refs.monitor.resumeOrPause && this.$refs.monitor.resumeOrPause();
},
changeQuality() {
this.$refs.monitor.changeQuality && this.$refs.monitor.changeQuality();
},
toggleVolume() {
this.$refs.monitor.toggleVolume && this.$refs.monitor.toggleVolume();
},
test() {
this.$refs.monitor && this.$refs.monitor.test && this.$refs.monitor.test();
},
/* ------------------ 新增:截图/录屏/对讲 调用方法(支持 payload.reqId ------------------ */
// 1. 截图(调用)
// payload 可选:{ reqId: number }
doSnapshot(payload = {}) {
if (!this.$refs.monitor || !this.$refs.monitor.snapShot) {
uni.showToast({
title: "组件不支持 snapShot()",
icon: "none"
});
// 直接给请求方回错
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'snapShot_not_supported'
});
}
return;
}
// 如果 caller 传了 reqId就把 reqId 放入 pending以备 native 事件回调时匹配)
if (payload.reqId) {
this._pendingRequests.snapshot.push(payload.reqId);
}
try {
this.$refs.monitor.snapShot((res) => {
// 这个 callback 优先使用,直接回传结果给请求方(如果有)
console.log("snapShot callback:", res);
this._handleSnapshotResultFromNative(res, payload.reqId);
});
uni.showToast({
title: "正在截屏...",
icon: "none",
duration: 800
});
} catch (err) {
console.error("snapShot 调用失败", err);
uni.showToast({
title: "snapShot 调用失败",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'snapShot_call_failed',
detail: String(err)
});
}
}
},
// 2. 开始录屏(调用)
// payload 可选:{ reqId: number }
doStartRecord(payload = {}) {
if (!this.$refs.monitor || !this.$refs.monitor.startRecord) {
uni.showToast({
title: "组件不支持 startRecord()",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'startRecord_not_supported'
});
}
return;
}
try {
this.$refs.monitor.startRecord((res) => {
console.log("startRecord callback:", res);
// 有些实现会在 start 的 callback 里返回启动结果;如果 caller 传了 reqId 则回传
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: true,
res
});
}
});
this.isRecording = true;
uni.showToast({
title: "录屏已开始",
icon: "none"
});
} catch (err) {
console.error("startRecord 调用失败", err);
uni.showToast({
title: "startRecord 调用失败",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'startRecord_call_failed',
detail: String(err)
});
}
}
},
// 3. 停止录屏(调用)
// payload 可选:{ reqId: number }
doStopRecord(payload = {}) {
if (!this.$refs.monitor || !this.$refs.monitor.stopRecord) {
uni.showToast({
title: "组件不支持 stopRecord()",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'stopRecord_not_supported'
});
}
return;
}
// 记录 pending以便 native 的 onRecord 事件回传可匹配)
if (payload.reqId) {
this._pendingRequests.record.push(payload.reqId);
}
try {
this.$refs.monitor.stopRecord((res) => {
console.log("stopRecord callback:", res);
this._handleRecordResultFromNative(res, payload.reqId);
});
// 状态会在回调或事件里最终设置
} catch (err) {
console.error("stopRecord 调用失败", err);
uni.showToast({
title: "stopRecord 调用失败",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'stopRecord_call_failed',
detail: String(err)
});
}
}
},
// 4. 开始对讲(调用)
// payload 可选:{ reqId: number }
doOpenTalk(payload = {}) {
if (!this.$refs.monitor || !this.$refs.monitor.openTalk) {
uni.showToast({
title: "组件不支持 openTalk()",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'openTalk_not_supported'
});
}
return;
}
// pending 用于当 native 发来 talk 状态事件时回传
if (payload.reqId) {
this._pendingRequests.talk.push(payload.reqId);
}
try {
this.$refs.monitor.openTalk((res) => {
console.log("openTalk callback:", res);
// 如果 callback 里有最终状态可以直接回传
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: true,
res
});
}
});
this.isTalking = true;
uni.showToast({
title: "尝试建立对讲连接...",
icon: "none"
});
} catch (err) {
console.error("openTalk 调用失败", err);
uni.showToast({
title: "openTalk 调用失败",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'openTalk_call_failed',
detail: String(err)
});
}
}
},
// 5. 停止对讲(调用)
// payload 可选:{ reqId: number }
doStopTalk(payload = {}) {
if (!this.$refs.monitor || !this.$refs.monitor.stopTalk) {
uni.showToast({
title: "组件不支持 stopTalk()",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'stopTalk_not_supported'
});
}
return;
}
try {
this.$refs.monitor.stopTalk((res) => {
console.log("stopTalk callback:", res);
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: true,
res
});
}
});
this.isTalking = false;
} catch (err) {
console.error("stopTalk 调用失败", err);
uni.showToast({
title: "stopTalk 调用失败",
icon: "none"
});
if (payload.reqId) {
uni.$emit(`smallmonitor:response:${payload.reqId}`, {
ok: false,
error: 'stopTalk_call_failed',
detail: String(err)
});
}
}
},
/* ------------------ 事件回调处理(来自原生推送的事件) ------------------ */
// 处理来自模板 @onSnapShot 的事件event.detail
handleSnapShotEvent(event) {
const payload = event && event.detail ? event.detail : event;
console.log("onSnapShot event:", payload);
// 统一处理并尝试把结果回给 pending 请求者
this._handleSnapshotResultFromNative(payload);
},
// 处理来自模板 @onRecord 的事件event.detail
handleRecordEvent(event) {
const payload = event && event.detail ? event.detail : event;
console.log("onRecord event:", payload);
this._handleRecordResultFromNative(payload);
},
// 处理来自模板 @onTalkStatus 的事件
handleTalkEvent(event) {
const payload = event && event.detail ? event.detail : event;
console.log("onTalkStatus event:", payload);
const status = payload && payload.talkStatus;
const tips = payload && payload.tips;
// 通知调用方(通用事件)
uni.$emit('smallmonitor:talk:status', payload);
// 如果有 pending talk 请求,回传结果
if (this._pendingRequests.talk && this._pendingRequests.talk.length) {
while (this._pendingRequests.talk.length) {
const reqId = this._pendingRequests.talk.shift();
uni.$emit(`smallmonitor:response:${reqId}`, {
ok: true,
payload
});
}
}
switch ((status || "").toLowerCase()) {
case "loading":
uni.showToast({
title: tips || "对讲连接中...",
icon: "none"
});
this.isTalking = true;
break;
case "playing":
uni.showToast({
title: tips || "对讲已连接",
icon: "none"
});
this.isTalking = true;
break;
case "stopped":
uni.showToast({
title: tips || "对讲已停止",
icon: "none"
});
this.isTalking = false;
break;
case "failed":
uni.showToast({
title: tips || "对讲失败",
icon: "none"
});
this.isTalking = false;
break;
default:
uni.showToast({
title: tips || ("对讲状态: " + (status || "unknown")),
icon: "none"
});
break;
}
},
/* ------------------ 原生结果的内部处理函数(统一处理 callback / event ------------------ */
_handleSnapshotResultFromNative(res, reqIdFromCallback = null) {
if (!res) {
uni.showToast({
title: "截图没有返回数据",
icon: "none"
});
// 回传失败
if (reqIdFromCallback) {
uni.$emit(`smallmonitor:response:${reqIdFromCallback}`, {
ok: false,
error: 'no_data'
});
}
return;
}
let payload = res;
if (res.detail) payload = res.detail;
console.log("snapshot payload normalized:", payload);
// 优先判断 callback 里直接传进来的 reqId
if (reqIdFromCallback) {
uni.$emit(`smallmonitor:response:${reqIdFromCallback}`, {
ok: !!payload.snapShotResult,
payload
});
}
// 如果没有 callback reqId但有 pending 列表,则把结果分发给所有 pending reqId典型场景调用方只发了 reqId但 native 最终通过 onSnapShot 事件推回)
if ((!reqIdFromCallback) && this._pendingRequests.snapshot && this._pendingRequests.snapshot.length) {
while (this._pendingRequests.snapshot.length) {
const rid = this._pendingRequests.snapshot.shift();
uni.$emit(`smallmonitor:response:${rid}`, {
ok: !!payload.snapShotResult,
payload
});
}
}
// 无论如何,都发一个通用完成事件,方便只监听通用事件的页面
uni.$emit('smallmonitor:snapshot:done', payload);
if (payload.snapShotResult === true || payload.snapShotResult === "true") {
const url = payload.snapShotUrl || payload.snapShotPath || payload.url;
uni.showToast({
title: "截图成功",
icon: "success",
duration: 1200
});
if (url) {
uni.previewImage({
urls: [url]
});
}
} else {
const err = payload.snapShotErrorCode || payload.error || "unknown";
uni.showToast({
title: "截图失败: " + err,
icon: "none",
duration: 2000
});
console.warn("snapshot failed reason:", err, payload);
}
},
_handleRecordResultFromNative(res, reqIdFromCallback = null) {
if (!res) {
uni.showToast({
title: "录屏没有返回数据",
icon: "none"
});
this.isRecording = false;
if (reqIdFromCallback) {
uni.$emit(`smallmonitor:response:${reqIdFromCallback}`, {
ok: false,
error: 'no_data'
});
}
return;
}
let payload = res;
if (res.detail) payload = res.detail;
console.log("record payload normalized:", payload);
// 优先用 callback 的 reqId 回传
if (reqIdFromCallback) {
uni.$emit(`smallmonitor:response:${reqIdFromCallback}`, {
ok: !!(payload.recordUrl || payload.snapShotResult),
payload
});
}
// 如果没有 callback reqId但有 pending则回传给 pending 列表
if ((!reqIdFromCallback) && this._pendingRequests.record && this._pendingRequests.record.length) {
while (this._pendingRequests.record.length) {
const rid = this._pendingRequests.record.shift();
uni.$emit(`smallmonitor:response:${rid}`, {
ok: !!(payload.recordUrl || payload.snapShotResult),
payload
});
}
}
// 通用事件
uni.$emit('smallmonitor:record:done', payload);
if (payload.recordUrl) {
uni.showToast({
title: "录屏完成",
icon: "success",
duration: 1400
});
this.isRecording = false;
console.log("录屏地址:", payload.recordUrl);
} else if (payload.recordFailedReason) {
uni.showToast({
title: "录屏失败: " + payload.recordFailedReason,
icon: "none",
duration: 2000
});
this.isRecording = false;
console.warn("record failed reason:", payload.recordFailedReason);
} else {
if (payload.snapShotResult === true) {
uni.showToast({
title: "录屏操作已完成(返回未知)",
icon: "none"
});
}
this.isRecording = false;
}
},
},
};
</script>
<style>
.center-column {
/* width: 680px;
height: 520px; */
width: 675px;
height: 475px;
border-radius: 30px;
overflow: hidden;
}
</style>