实时播放修改显示位置
This commit is contained in:
parent
d6aa73cba4
commit
2083456ca5
|
|
@ -6,7 +6,7 @@ export const loginService = (loginData) => {
|
||||||
loginData = loginData._value;
|
loginData = loginData._value;
|
||||||
for (let key in loginData) {
|
for (let key in loginData) {
|
||||||
if (key === "username") {
|
if (key === "username") {
|
||||||
//姝e垯琛ㄨ揪寮忓垽鏂偖绠<EFBFBD>
|
//濮濓絽鍨悰銊ㄦ彧瀵繐鍨介弬顓㈠仏缁狅拷
|
||||||
if (RegExp(/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/).test(loginData[key])) {
|
if (RegExp(/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/).test(loginData[key])) {
|
||||||
loginData['email'] = loginData[key]
|
loginData['email'] = loginData[key]
|
||||||
loginData[key] = ''
|
loginData[key] = ''
|
||||||
|
|
@ -47,7 +47,7 @@ export const addGroupRequestService = (Data) => {
|
||||||
}
|
}
|
||||||
return request.post('/im/send_message', params,{
|
return request.post('/im/send_message', params,{
|
||||||
headers: {
|
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, {
|
return request.post('/im/get_friend_request', params, {
|
||||||
headers: {
|
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, {
|
return request.post('/user/info', params, {
|
||||||
headers: {
|
headers: {
|
||||||
'token': Data.token, // 灏<EFBFBD> token 鏇挎崲涓烘偍鐨勪护鐗屽€<EFBFBD>
|
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<EFBFBD>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//鍒犻櫎濂藉弸鎴栬€呯兢缁<EFBFBD>
|
//閸掔娀娅庢總钘夊几閹存牞鈧懐鍏㈢紒锟<EFBFBD>
|
||||||
export const DelFGService =(Data) =>{
|
export const DelFGService =(Data) =>{
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
for (let key in Data) {
|
for (let key in Data) {
|
||||||
|
|
@ -83,7 +83,7 @@ export const DelFGService =(Data) =>{
|
||||||
}
|
}
|
||||||
return request.post('/im/del_friend_or_group', params, {
|
return request.post('/im/del_friend_or_group', params, {
|
||||||
headers: {
|
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, {
|
return request.post('/user/update', params, {
|
||||||
headers: {
|
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, {
|
return request.post('/im/accept_invite', params, {
|
||||||
headers: {
|
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, {
|
return request.post('/im/reject_invite', params, {
|
||||||
headers: {
|
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,{
|
return request.post('/user/search', params,{
|
||||||
headers: {
|
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 router from "@/router/index.js";
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import Menu from "@/views/Menu.vue";
|
import Menu from "@/views/Menu.vue";
|
||||||
|
import VideoStream from "@/views/DeviceRealVP.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VideoStream,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ip: "",
|
ip: "",
|
||||||
|
|
@ -23,6 +27,8 @@ export default {
|
||||||
},
|
},
|
||||||
addDialogVisible: false,
|
addDialogVisible: false,
|
||||||
updateDialogVisible: false,
|
updateDialogVisible: false,
|
||||||
|
deviceStreamDialogVisible: false,
|
||||||
|
playing_device: "",
|
||||||
searchForm: {
|
searchForm: {
|
||||||
hour: 0,
|
hour: 0,
|
||||||
entrydate: [],
|
entrydate: [],
|
||||||
|
|
@ -108,7 +114,9 @@ export default {
|
||||||
playRealVp(index) {
|
playRealVp(index) {
|
||||||
var id = this.tableData[index].ID;
|
var id = this.tableData[index].ID;
|
||||||
localStorage.setItem("realvp_device_id", 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) {
|
async deleteDevice(index) {
|
||||||
// 删除前确认
|
// 删除前确认
|
||||||
|
|
@ -238,7 +246,7 @@ export default {
|
||||||
router.push("/login");
|
router.push("/login");
|
||||||
}
|
}
|
||||||
// console.log("mounted");
|
// console.log("mounted");
|
||||||
this.getIpClient();
|
//this.getIpClient();
|
||||||
this.getDeviceList();
|
this.getDeviceList();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -325,6 +333,20 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</el-form-item>
|
</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-form-item>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<el-button
|
<!-- <el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click.prevent="handleMenuSelect('/device')"
|
@click.prevent="handleMenuSelect('/device')"
|
||||||
>设备</el-button
|
>设备</el-button
|
||||||
>
|
> -->
|
||||||
<div>
|
<div>
|
||||||
<!-- 使用:src绑定base64图片 -->
|
<!-- 使用:src绑定base64图片 -->
|
||||||
<img :src="base64Image" alt="Base64 Image" />
|
<img :src="base64Image" alt="Base64 Image" width="100%" height ="100%"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -98,6 +98,9 @@ export default {
|
||||||
onUnmounted() {
|
onUnmounted() {
|
||||||
this.socket.close();
|
this.socket.close();
|
||||||
},
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
this.socket.close();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<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