优化国标录像下载,添加进度条以及自动合并文件下载,需要结合新版assist服务使用。

This commit is contained in:
648540858
2022-03-25 16:05:14 +08:00
parent e9586687f7
commit 7d9cc96ef5
27 changed files with 761 additions and 591 deletions

View File

@@ -175,6 +175,7 @@
</el-tabs>
</div>
</el-dialog>
<recordDownload ref="recordDownload"></recordDownload>
</div>
</template>
@@ -183,15 +184,15 @@
// import LivePlayer from '@liveqing/liveplayer'
// import player from '../dialog/easyPlayer.vue'
import player from '../dialog/jessibuca.vue'
import recordDownload from '../dialog/recordDownload.vue'
export default {
name: 'devicePlayer',
props: {},
components: {
player,
player,recordDownload,
},
computed: {
getPlayerShared: function () {
return {
sharedUrl: window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl),
sharedIframe: '<iframe src="' + window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl) + '"></iframe>',
@@ -250,7 +251,7 @@ export default {
that.tracks = [];
that.tracksLoading = true;
that.tracksNotLoaded = false;
if (tab.name == "codec") {
if (tab.name === "codec") {
this.$axios({
method: 'get',
url: '/zlm/' +this.mediaServerId+ '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtmp&app='+ this.app +'&stream='+ this.streamId
@@ -340,7 +341,7 @@ export default {
this.$refs.videoPlayer.pause()
that.$axios({
method: 'post',
url: '/api/play/convert/' + that.streamId
url: '/api/gb_record/convert/' + that.streamId
}).then(function (res) {
if (res.data.code == 0) {
that.convertKey = res.data.key;
@@ -474,8 +475,8 @@ export default {
console.log(this.seekTime)
if (that.streamId != "") {
that.stopPlayRecord(function () {
that.streamId = "",
that.playRecord(row);
that.streamId = "";
that.playRecord(row);
})
} else {
this.$axios({
@@ -506,22 +507,36 @@ export default {
downloadRecord: function (row) {
let that = this;
if (that.streamId != "") {
that.stopDownloadRecord(function () {
that.streamId = "",
that.downloadRecord(row);
that.stopDownloadRecord(function (res) {
if (res.code == 0) {
that.streamId = "";
that.downloadRecord(row);
}else {
this.$message({
showClose: true,
message: res.data.msg,
type: "error",
});
}
})
} else {
this.$axios({
method: 'get',
url: '/api/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
row.endTime + '&downloadSpeed=4'
}).then(function (res) {
var streamInfo = res.data;
that.app = streamInfo.app;
that.streamId = streamInfo.stream;
that.mediaServerId = streamInfo.mediaServerId;
that.videoUrl = that.getUrlByStreamInfo(streamInfo);
that.recordPlay = true;
if (res.data.code == 0) {
let streamInfo = res.data.data;
that.recordPlay = false;
that.$refs.recordDownload.openDialog(that.deviceId, that.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);
}else {
that.$message({
showClose: true,
message: res.data.msg,
type: "error",
});
}
});
}
},
@@ -530,9 +545,9 @@ export default {
this.videoUrl = '';
this.$axios({
method: 'get',
url: '/api/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
}).then(function (res) {
if (callback) callback()
url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
}).then((res)=> {
if (callback) callback(res)
});
},
ptzCamera: function (command) {

View File

@@ -0,0 +1,195 @@
<template>
<div id="recordDownload" >
<el-dialog :title="title" v-if="showDialog" width="45rem" :append-to-body="true" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()" center>
<el-row>
<el-col :span="18" style="padding-top: 7px;">
<el-progress :percentage="percentage"></el-progress>
</el-col>
<el-col :span="6" >
<!-- <el-dropdown size="mini" title="播放倍速" style="margin-left: 1px;" @command="gbScale">-->
<!-- <el-button-group>-->
<!-- <el-button size="mini" style="width: 100%">-->
<!-- {{scale}}倍速 <i class="el-icon-arrow-down el-icon&#45;&#45;right"></i>-->
<!-- </el-button>-->
<!-- </el-button-group>-->
<!-- <el-dropdown-menu slot="dropdown">-->
<!-- <el-dropdown-item command="1">1倍速</el-dropdown-item>-->
<!-- <el-dropdown-item command="2">2倍速</el-dropdown-item>-->
<!-- <el-dropdown-item command="4">4倍速</el-dropdown-item>-->
<!-- </el-dropdown-menu>-->
<!-- </el-dropdown>-->
<el-button icon="el-icon-download" v-if="percentage < 100" size="mini" title="点击下载可将以缓存部分下载到本地" @click="download()">停止缓存并下载</el-button>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
import moment from "moment";
export default {
name: 'recordDownload',
created() {
},
data() {
return {
title: "四倍速下载中...",
deviceId: "",
channelId: "",
app: "",
stream: "",
mediaServerId: "",
showDialog: false,
scale: 1,
percentage: 0.00,
streamInfo: null,
taskId: null,
getProgressRun: false,
getProgressForFileRun: false,
};
},
methods: {
openDialog: function (deviceId, channelId, app, stream, mediaServerId) {
this.deviceId = deviceId;
this.channelId = channelId;
this.app = app;
this.stream = stream;
this.mediaServerId = mediaServerId;
this.showDialog = true;
this.getProgressRun = true;
this.percentage = 0.0;
this.getProgressTimer()
},
getProgressTimer(){
if (!this.getProgressRun) {
return;
}
if (this.percentage == 100 ) {
this.getFileDownload();
return;
}
setTimeout( ()=>{
if (!this.showDialog) return;
this.getProgress(this.getProgressTimer())
}, 5000)
},
getProgress: function (callback){
this.$axios({
method: 'get',
url: `/api/gb_record/download/progress/${this.deviceId}/${this.channelId}/${this.stream}`
}).then((res)=> {
console.log(res)
console.log(res.data.progress)
this.streamInfo = res.data;
if (parseFloat(res.data.progress) == 1) {
this.percentage = 100;
}else {
this.percentage = (res.data.progress*100).toFixed(1);
}
if (callback)callback();
}).catch((e) =>{
});
},
close: function (){
if (this.streamInfo.progress < 100) {
this.stopDownloadRecord();
}
this.showDialog=false;
this.getProgressRun = false;
this.getProgressForFileRun = false;
},
gbScale: function (scale){
this.scale = scale;
},
download: function (){
this.getProgressRun = false;
if (this.streamInfo != null ) {
if (this.streamInfo.progress < 1) {
// 发送停止缓存
this.stopDownloadRecord((res)=>{
this.getFileDownload()
})
}else {
this.getFileDownload()
}
}
},
stopDownloadRecord: function (callback) {
this.$axios({
method: 'get',
url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.stream
}).then((res)=> {
if (callback) callback(res)
});
},
getFileDownload: function (){
this.$axios({
method: 'get',
url:`/record_proxy/${this.mediaServerId}/api/record/file/download/task/add`,
params: {
app: this.app,
stream: this.stream,
startTime: null,
endTime: null,
}
}).then((res) =>{
if (res.data.code === 0 && res.data.msg === "success") {
// 查询进度
this.title = "录像文件处理中..."
this.taskId = res.data.data;
this.percentage = 0.0;
this.getProgressForFileRun = true;
this.getProgressForFileTimer();
}
}).catch(function (error) {
console.log(error);
});
},
getProgressForFileTimer: function (){
if (!this.getProgressForFileRun || this.percentage == 100) {
return;
}
setTimeout( ()=>{
if (!this.showDialog) return;
this.getProgressForFile(this.getProgressForFileTimer())
}, 1000)
},
getProgressForFile: function (callback){
this.$axios({
method: 'get',
url:`/record_proxy/${this.mediaServerId}/api/record/file/download/task/list`,
params: {
app: this.app,
stream: this.stream,
taskId: this.taskId,
isEnd: true,
}
}).then((res) => {
if (res.data.code == 0) {
this.percentage = parseFloat(res.data.data.percentage)*100
if (res.data.data[0].percentage === '1') {
this.getProgressForFileRun = false;
window.open(res.data.data[0].downloadFile)
this.close();
}else {
if (callback)callback()
}
}
}).catch(function (error) {
console.log(error);
});
}
}
};
</script>
<style>
</style>

View File

@@ -1,198 +0,0 @@
<template>
<div id="test">
<div class="timeQuery" id="timeQuery">
<div class="timeQuery-background" ></div>
<div class="timeQuery-pointer">
<div class="timeQuery-pointer-content" id="timeQueryPointer">
<div class="timeQuery-pointer-handle" @mousedown.left="mousedownHandler" ></div>
</div>
</div>
<div class="timeQuery-data" >
<div class="timeQuery-data-cell" v-for="item of recordData" :style="'width:' + getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'" ></div>
<!-- <div class="timeQuery-data-cell" style="width: 30%; left: 20%" @click="timeChoose"></div>-->
<!-- <div class="timeQuery-data-cell" style="width: 60%; left: 20%" @click="timeChoose"></div>-->
</div>
<div class="timeQuery-label" >
<div class="timeQuery-label-cell" style="left: 0%">
<div class="timeQuery-label-cell-label">0</div>
</div>
<div v-for="index of timeNode" class="timeQuery-label-cell" :style="'left:' + (100.0/timeNode*index).toFixed(4) + '%'">
<div class="timeQuery-label-cell-label">{{24/timeNode * index}}</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "test",
data() {
return {
mouseDown: false,
timeNode: 24,
recordData:[
{
startTime: "2021-04-18 00:00:00",
endTime: "2021-04-18 00:00:09",
},
{
startTime: "2021-04-18 00:00:09",
endTime: "2021-04-18 01:00:05",
},
{
startTime: "2021-04-18 02:00:01",
endTime: "2021-04-18 04:25:05",
},
{
startTime: "2021-04-18 05:00:01",
endTime: "2021-04-18 20:00:05",
},
]
};
},
mounted() {
document.body.addEventListener("mouseup", this.mouseupHandler, false)
document.body.addEventListener("mousemove", this.mousemoveHandler, false)
},
methods:{
getTimeNode(){
let mine = 20
let width = document.getElementById("timeQuery").offsetWidth
if (width/20 > 24){
return 24
}else if (width/20 > 12) {
return 12
}else if (width/20 > 6) {
return 6
}
},
timeChoose(event){
console.log(event)
},
getDataWidth(item){
let startTime = new Date(item.startTime);
let endTime = new Date(item.endTime);
let result = parseFloat((endTime.getTime() - startTime.getTime())/(24*60*60*10))
// console.log(result)
return parseFloat((endTime.getTime() - startTime.getTime())/(24*60*60*10))
},
getDataLeft(item){
let startTime = new Date(item.startTime);
let differenceTime = startTime.getTime() - new Date(item.startTime.substr(0,10) + " 00:00:00").getTime()
let result = differenceTime/(24*60*60*10)
console.log(differenceTime)
console.log(result)
return parseFloat(differenceTime/(24*60*60*10));
},
mousedownHandler(event){
this.mouseDown = true
},
mousemoveHandler(event){
if (this.mouseDown){
document.getElementById("timeQueryPointer").style.left = (event.clientX - 20)+ "px"
}
},
mouseupHandler(event){
this.mouseDown = false
}
}
}
</script>
<style scoped>
.timeQuery{
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 20%;
position: absolute;
}
.timeQuery-background{
height: 16px;
width: 100%;
background-color: #ececec;
position: absolute;
left: 0;
top: 0;
z-index: 10;
box-shadow: #9d9d9d 0px 0px 10px inset;
}
.timeQuery-data{
height: 16px;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 11;
}
.timeQuery-data-cell{
height: 10px;
background-color: #888787;
position: absolute;
z-index: 11;
-webkit-box-shadow: #9d9d9d 0px 0px 10px inset;
margin-top: 3px;
top: 100%;
}
.timeQuery-label{
height: 16px;
width: 100%;
position: absolute;
pointer-events: none;
left: 0;
top: 0;
z-index: 11;
}
.timeQuery-label-cell{
height: 16px;
position: absolute;
z-index: 12;
width: 0px;
border-right: 1px solid #b7b7b7;
}
.timeQuery-label-cell-label {
width: 23px;
text-align: center;
height: 18px;
margin-left: -10px;
margin-top: -30px;
color: #444;
}
.timeQuery-pointer{
width: 0px;
height: 18px;
position: absolute;
left: 0;
}
.timeQuery-pointer-content{
width: 0px;
height: 70px;
position: absolute;
border-right: 2px solid #f60303;
z-index: 14;
top: -30px;
}
.timeQuery-pointer-handle {
width: 0;
height: 0;
border-top: 12px solid transparent;
border-right: 12px solid transparent;
border-bottom: 20px solid #ff0909;
border-left: 12px solid transparent;
cursor: no-drop;
position: absolute;
left: -11px;
top: 50px;
}
/*.timeQuery-cell:after{*/
/* content: "";*/
/* height: 14px;*/
/* border: 1px solid #e70303;*/
/* position: absolute;*/
/*}*/
</style>

View File

@@ -1,190 +0,0 @@
<template>
<div id="test2">
<div class="timeQuery" style="width: 100%; height: 300px" id="timeQuery">
</div>
</div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: "test2",
data() {
return {
};
},
mounted() {
var base = +new Date("2021-02-02 00:00:00");
var oneDay = 24 * 3600 * 1000;
var data = [[base, 10]];
for (var i = 1; i < 24; i++) {
var now = new Date(base += oneDay);
data.push([
new Date("2021-02-02 " + i+":00:00"), 10
]);
}
// 基于准备好的dom初始化echarts实例
var myChart = echarts.init(document.getElementById('timeQuery'));
let option = {
toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none'
},
restore: {},
saveAsImage: {}
}
},
xAxis: {
type: 'time',
boundaryGap: false
},
yAxis: {
type: 'value',
show: false,
splitLine:{show: false}, //去除网格线
boundaryGap: [0, '100%']
},
dataZoom: [{
type: 'inside',
start: 0,
end: 20
}, {
start: 0,
end: 20
}],
series: [
{
name: '模拟数据',
type: 'line',
smooth: false,
symbol: 'none',
areaStyle: {},
data: data
}
]
};
// 绘制图表
myChart.setOption(option);
},
methods:{
getTimeNode(){
let mine = 20
let width = document.getElementById("timeQuery").offsetWidth
if (width/20 > 24){
return 24
}else if (width/20 > 12) {
return 12
}else if (width/20 > 6) {
return 6
}
},
hoveEvent(event){
console.log(2222222)
console.log(event)
},
timeChoose(event){
console.log(event)
},
getDataWidth(item){
let startTime = new Date(item.startTime);
let endTime = new Date(item.endTime);
let result = parseFloat((endTime.getTime() - startTime.getTime())/(24*60*60*10))
// console.log(result)
return parseFloat((endTime.getTime() - startTime.getTime())/(24*60*60*10))
},
getDataLeft(item){
let startTime = new Date(item.startTime);
let differenceTime = startTime.getTime() - new Date(item.startTime.substr(0,10) + " 00:00:00").getTime()
let result = differenceTime/(24*60*60*10)
console.log(differenceTime)
console.log(result)
return parseFloat(differenceTime/(24*60*60*10));
}
}
}
</script>
<style scoped>
.timeQuery{
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 20%;
position: absolute;
}
.timeQuery-background{
height: 16px;
width: 100%;
background-color: #ececec;
position: absolute;
left: 0;
top: 0;
z-index: 10;
box-shadow: #9d9d9d 0px 0px 10px inset;
}
.timeQuery-data{
height: 16px;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 11;
}
.timeQuery-data-cell{
height: 10px;
background-color: #888787;
position: absolute;
z-index: 11;
-webkit-box-shadow: #9d9d9d 0px 0px 10px inset;
margin-top: 3px;
}
.timeQuery-label{
height: 16px;
width: 100%;
position: absolute;
pointer-events: none;
left: 0;
top: 0;
z-index: 11;
}
.timeQuery-label-cell{
height: 16px;
position: absolute;
z-index: 12;
width: 0px;
border-right: 1px solid #b7b7b7;
}
.timeQuery-label-cell-label {
width: 23px;
text-align: center;
height: 18px;
margin-left: -10px;
margin-top: -30px;
color: #444;
}
.timeQuery-pointer{
width: 0px;
height: 18px;
position: absolute;
left: 0;
}
.timeQuery-pointer-content{
width: 0px;
height: 16px;
position: absolute;
border-right: 3px solid #f60303;
z-index: 14;
}
/*.timeQuery-cell:after{*/
/* content: "";*/
/* height: 14px;*/
/* border: 1px solid #e70303;*/
/* position: absolute;*/
/*}*/
</style>