实时播放修改显示位置

This commit is contained in:
junleea 2024-12-26 15:35:40 +08:00
parent d6aa73cba4
commit 2083456ca5
4 changed files with 144 additions and 15 deletions

View File

@ -6,7 +6,7 @@ export const loginService = (loginData) => {
loginData = loginData._value;
for (let key in loginData) {
if (key === "username") {
//垯琛ㄨ揪寮忓垽鏂偖绠<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>
}
})
}

View File

@ -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

View File

@ -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>

104
src/views/VideoStream.vue Normal file
View File

@ -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, // axiosCancelToken.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>