video_ca/src/views/VideoStream.vue

105 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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