实时播放修改显示位置
This commit is contained in:
parent
d6aa73cba4
commit
2083456ca5
|
|
@ -6,7 +6,7 @@ export const loginService = (loginData) => {
|
|||
loginData = loginData._value;
|
||||
for (let key in loginData) {
|
||||
if (key === "username") {
|
||||
//姝e垯琛ㄨ揪寮忓垽鏂偖绠<EFBFBD>
|
||||
//濮濓絽鍨悰銊ㄦ彧瀵繐鍨介弬顓㈠仏缁狅拷
|
||||
if (RegExp(/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/).test(loginData[key])) {
|
||||
loginData['email'] = loginData[key]
|
||||
loginData[key] = ''
|
||||
|
|
@ -47,7 +47,7 @@ export const addGroupRequestService = (Data) => {
|
|||
}
|
||||
return request.post('/im/send_message', params,{
|
||||
headers: {
|
||||
'token': Data.token, // 灏<EFBFBD> token 鏇挎崲涓烘偍鐨勪护鐗屽€<EFBFBD>
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<EFBFBD>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ export const getFriendReqService = (Data) => {
|
|||
}
|
||||
return request.post('/im/get_friend_request', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 灏<EFBFBD> token 鏇挎崲涓烘偍鐨勪护鐗屽€<EFBFBD>
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<EFBFBD>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -70,12 +70,12 @@ export const GetUserInfoService = (Data) => {
|
|||
}
|
||||
return request.post('/user/info', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 灏<EFBFBD> token 鏇挎崲涓烘偍鐨勪护鐗屽€<EFBFBD>
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<EFBFBD>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//鍒犻櫎濂藉弸鎴栬€呯兢缁<EFBFBD>
|
||||
//閸掔娀娅庢總钘夊几閹存牞鈧懐鍏㈢紒锟<EFBFBD>
|
||||
export const DelFGService =(Data) =>{
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
|
|
@ -83,7 +83,7 @@ export const DelFGService =(Data) =>{
|
|||
}
|
||||
return request.post('/im/del_friend_or_group', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 灏<EFBFBD> token 鏇挎崲涓烘偍鐨勪护鐗屽€<EFBFBD>
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<EFBFBD>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ export const updateUserInfoService = (Data) => {
|
|||
}
|
||||
return request.post('/user/update', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 灏<EFBFBD> token 锟斤拷鎹负鎮ㄧ殑浠ょ墝鍊<E5A29D>
|
||||
'token': Data.token, // 鐏忥拷 token 閿熸枻鎷烽幑顫礋閹劎娈戞禒銈囧閸婏拷
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -107,7 +107,7 @@ export const acceptInviteService =(Data)=> {
|
|||
}
|
||||
return request.post('/im/accept_invite', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 灏<EFBFBD> token 鏇挎崲涓烘偍鐨勪护鐗屽€<EFBFBD>
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<EFBFBD>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ export const rejectInviteService =(Data)=> {
|
|||
}
|
||||
return request.post('/im/reject_invite', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 灏<EFBFBD> token 鏇挎崲涓烘偍鐨勪护鐗屽€<EFBFBD>
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<EFBFBD>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ export const SearchUserService = (Data) => {
|
|||
}
|
||||
return request.post('/user/search', params,{
|
||||
headers: {
|
||||
'token': Data.token, // 灏<EFBFBD> token 鏇挎崲涓烘偍鐨勪护鐗屽€<EFBFBD>
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<EFBFBD>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,12 @@ import { updateDeviceService } from "@/api/device.js";
|
|||
import router from "@/router/index.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
import Menu from "@/views/Menu.vue";
|
||||
import VideoStream from "@/views/DeviceRealVP.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VideoStream,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
|
|
@ -23,6 +27,8 @@ export default {
|
|||
},
|
||||
addDialogVisible: false,
|
||||
updateDialogVisible: false,
|
||||
deviceStreamDialogVisible: false,
|
||||
playing_device: "",
|
||||
searchForm: {
|
||||
hour: 0,
|
||||
entrydate: [],
|
||||
|
|
@ -108,7 +114,9 @@ export default {
|
|||
playRealVp(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
localStorage.setItem("realvp_device_id", id);
|
||||
router.push("/deviceRealVP");
|
||||
// router.push("/deviceRealVP");
|
||||
this.playing_device = id + " " + this.tableData[index].DeviceName;
|
||||
this.deviceStreamDialogVisible = true;
|
||||
},
|
||||
async deleteDevice(index) {
|
||||
// 删除前确认
|
||||
|
|
@ -238,7 +246,7 @@ export default {
|
|||
router.push("/login");
|
||||
}
|
||||
// console.log("mounted");
|
||||
this.getIpClient();
|
||||
//this.getIpClient();
|
||||
this.getDeviceList();
|
||||
},
|
||||
};
|
||||
|
|
@ -325,6 +333,20 @@ export default {
|
|||
</template>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
title="实时播放"
|
||||
v-model="deviceStreamDialogVisible"
|
||||
width="60%"
|
||||
height="60%"
|
||||
center
|
||||
>
|
||||
<div>
|
||||
视频播放({{playing_device }}):
|
||||
<VideoStream v-if="deviceStreamDialogVisible"></VideoStream>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<template>
|
||||
<el-button
|
||||
<!-- <el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备</el-button
|
||||
>
|
||||
> -->
|
||||
<div>
|
||||
<!-- 使用:src绑定base64图片 -->
|
||||
<img :src="base64Image" alt="Base64 Image" />
|
||||
<img :src="base64Image" alt="Base64 Image" width="100%" height ="100%"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
|
@ -98,6 +98,9 @@ export default {
|
|||
onUnmounted() {
|
||||
this.socket.close();
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.socket.close();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
<template>
|
||||
<div>
|
||||
<video ref="videoPlayer" autoplay playsinline></video>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
videoPlayer: null,
|
||||
source: null, // 用于存储axios的CancelToken.source对象,以便后续取消请求
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.videoPlayer = this.$refs.videoPlayer;
|
||||
this.startVideoStream();
|
||||
},
|
||||
methods: {
|
||||
startVideoStream() {
|
||||
//let url = "https://gep.ljsea.top/device/video_feed?" +"&device_id=" +localStorage.getItem("realvp_device_id") +"&token=" +localStorage.getItem("token"); //视频地址
|
||||
|
||||
const deviceId = localStorage.getItem("realvp_device_id"); // 替换为实际存储设备id的方式和键名
|
||||
const token = localStorage.getItem("token"); // 替换为实际存储token的方式和键名
|
||||
const url = `https://gep.ljsea.top/device/video_feed?device_id=${deviceId}&token=${token}`;
|
||||
this.source = axios.CancelToken.source();
|
||||
axios
|
||||
.get(url, {
|
||||
responseType: "arraybuffer",
|
||||
cancelToken: this.source.token,
|
||||
})
|
||||
.then((response) => {
|
||||
console.log("获取视频流成功");
|
||||
const reader = response.data
|
||||
.pipeThrough(new window.TextDecoderStream())
|
||||
.getReader();
|
||||
const processData = () => {
|
||||
reader.read().then(({ done, value }) => {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
const dataString = new window.TextDecoder().decode(value);
|
||||
const parts = dataString.split("\r\n");
|
||||
|
||||
// 检查是否包含关键的视频流格式标识
|
||||
const hasFrameMarker = parts.some((part) =>
|
||||
part.startsWith("--frame")
|
||||
);
|
||||
const hasContentTypeMarker = parts.some(
|
||||
(part) => part === "Content-Type: image/jpeg"
|
||||
);
|
||||
if (!hasFrameMarker || !hasContentTypeMarker) {
|
||||
console.error("视频流数据格式不符合预期,无法解析");
|
||||
return;
|
||||
}
|
||||
|
||||
parts.forEach((part) => {
|
||||
if (part.startsWith("--frame")) {
|
||||
const imageData = [];
|
||||
let isImageData = false;
|
||||
parts.forEach((subPart) => {
|
||||
if (isImageData) {
|
||||
imageData.push(subPart);
|
||||
}
|
||||
if (subPart === "Content-Type: image/jpeg") {
|
||||
isImageData = true;
|
||||
}
|
||||
});
|
||||
const imageBlob = new Blob(imageData, { type: "image/jpeg" });
|
||||
const objectURL = URL.createObjectURL(imageBlob);
|
||||
this.videoPlayer.src = objectURL;
|
||||
}
|
||||
});
|
||||
processData();
|
||||
});
|
||||
};
|
||||
processData();
|
||||
})
|
||||
.catch((error) => {
|
||||
if (axios.isCancel(error)) {
|
||||
console.log("请求已取消");
|
||||
} else {
|
||||
console.error("获取视频流出错:", error);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.source) {
|
||||
this.source.cancel("组件即将销毁,取消视频流请求");
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
video {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue