1
0
forked from dyf/APP

移植6155、650、670

This commit is contained in:
liub
2025-08-27 11:06:49 +08:00
parent 057858a132
commit c2aa8bfa2f
47 changed files with 20333 additions and 1355 deletions

View File

@ -0,0 +1,517 @@
<template>
<view class="content">
<canvas canvas-id="flashCanvas"
style="width: 160px; height: 80px; z-index: 9999;position: fixed; top:-9999px;left:-9999px;"></canvas>
<f-video ref="compARef" :src="videoPath" :direction="-90" :autoplay="true" @shotVideoClick="shotVideoClick"
:videoWidth="videoWidth" :videoHeight="videoHeight"></f-video>
<view>
<text>并发包数量</text>
<input type="text" v-model="packgeCnt" />
</view>
<view>
<text>发送间隔</text>
<input type="text" v-model="inteval" />
</view>
<view>
<button @click="checkVideo">选择视频</button>
<!-- <button @click="CutImg">发送</button> -->
<button @click="uploadVideo">发送</button>
</view>
<view class="sending-progress" v-if="isSending">
<view class="progress-bar">
<view class="progress-fill" :style="{ width: progress + '%' }"></view>
</view>
<text>正在发送: {{ progress }}% ({{ currentPacket }}/{{ totalPackets }})</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
videoPath: '',
packgeCnt: 20,
inteval: 0,
progress: 0,
currentPacket: 0,
totalPackets: 100,
connectedDeviceId: '',
serviceId: '0xFFE1',
writeCharacteristicId: '0xFFE1',
notifyCharacteristicId: '0xFFE2',
isSending: "",
textProgress: "",
imgs: [],
videoWidth: 320,
videoHeight: 160,
videoDuration: 2,
hexArray: []
}
},
onLoad() {
const eventChannel = this.getOpenerEventChannel();
eventChannel.on('receiveDevice', (data) => {
this.connectedDeviceId = data.connectedDeviceId;
this.serviceId = data.serviceId;
this.writeCharacteristicId = data.writeCharacteristicId;
this.notifyCharacteristicId = data.notifyCharacteristicId;
})
},
methods: {
checkVideo: function() {
uni.chooseVideo({
sourceType: ['album', 'camera'],
compressed: false,
maxDuration: 2,
camera: 'back',
success: (res) => {
this.videoPath = res.tempFilePath;
this.imgs = [];
this.hexArray = [];
this.$refs.compARef.base64 = [];
this.videoWidth = res.width;
this.videoHeight = res.height;
this.videoDuration = res.duration;
console.log("视频宽:" + res.width + ",视频高:" + res.height + ",视频时长:" + res.duration);
}
})
},
uploadVideo: function() {
if (this.hexArray.length > 0) {
console.log("开始处理,无需上传");
this.shotVideoClick(this.hexArray, 'rgb565');
return;
}
if(!this.videoPath){
uni.showToast({
title: "请选择视频",
icon: 'fail'
})
return;
}
console.log("正在上传视频");
uni.showLoading({
title: "上传中"
});
let p2=new Promise((resolve,reject)=>{
console.log("Common.baseURL="+Common.baseURL);
let start = new Date();
uni.uploadFile({
url: Common.baseURL+'video/upload',
// url: 'http://192.168.110.169:5000/video/upload',
filePath: this.videoPath,
name: 'file',
header: {
"Method": "POST",
"Content-Type": "multipart/form-data"
},
timeout: 600000,
fail: (ex) => {
//console.log("上传视频失败" + JSON.stringify(ex));
uni.showToast({
title: "视频文件上传失败了,请检查网络连接",
icon: 'fail'
})
uni.hideLoading();
reject(ex);
},
success: (res) => {
let end = new Date();
var diff = (end.getTime() - start.getTime()) / 1000;
let s = diff % 60;
let m = (diff - s) / 60;
console.log("上传完成,耗时:" + m + "分" + s + "秒");
uni.hideLoading();
resolve(res);
}
});
});
let p1=this.HoldYouHand();
Promise.all([p2,p1]).then((arr)=>{
if(arr[1]===true){
let res=arr[0];
res = JSON.parse(res.data);
if (res.data) {
this.hexArray = res.data;
uni.showLoading({
title: "正在发送"
});
setTimeout(() => {
this.shotVideoClick(res.data, 'rgb565');
}, 0)
} else {
console.log("res")
uni.showModal({
content: "服务器未返回RGB565数据",
title: '错误'
})
}
}else{
uni.showModal({
content:"与设备握手失败了",
title:"错误"
})
}
});
},
pause(e) {
////console.log('pause--------------------------', e);
},
shotVideoClick: function(array, type) {
//console.log("处理视频完成", array);
//console.log("type=" + type)
//console.log("array=", array);
this.imgs = array;
var sendImagePackets = (imageData) => {
return new Promise((resolve, reject) => {
this.isSending = true;
this.progress = 0;
this.currentPacket = 0;
// 总数据包数
const totalPackets = 1536;
this.totalPackets = totalPackets;
let currentPacket = 1;
let promises = [];
// 发送单个数据包
const sendNextPacket = () => {
////console.log("currentPacket="+currentPacket+",imageData.length="+imageData.length);
if (currentPacket > totalPackets) {
this.isSending = false;
resolve();
return;
}
// 计算当前包的数据
let packetSize = 250;
if (type == 'rgb565') {
packetSize = 500;
}
// 创建数据包
const startIndex = (currentPacket - 1) * packetSize;
const endIndex = Math.min(startIndex + packetSize, imageData.length);
if (startIndex > endIndex) {
resolve();
return;
}
////console.log("111111");
const packetData = imageData.slice(startIndex, endIndex);
// 构建数据包
////console.log("packetData.length"+packetData.length);
const bufferSize = 506; // 头部5字节 + 数据部分
const buffer = new ArrayBuffer(bufferSize);
const dataView = new DataView(buffer);
let sortNo = currentPacket.toString(16).padStart(4, '0');
// 填充头部
dataView.setUint8(0, 0x55); // 帧头
dataView.setUint8(1, 0x04); // 帧类型:开机画面
dataView.setUint8(2, '0x' + sortNo.substring(0, 2)); // 包序号
dataView.setUint8(3, '0x' + sortNo.substring(2, 4)); // 包序号
dataView.setUint8(4, 0x01);
dataView.setUint8(5, 0xF4);
if (type == 'rgb565') {
for (let i = 0; i < packetData.length; i++) {
dataView.setUint8(6 + i, '0x' + packetData[i]);
}
} else {
for (let i = 0; i < packetData.length; i++) {
dataView.setUint16(6 + i * 2, packetData[i], false);
}
}
let inteval = parseInt(this.inteval ? this.inteval : 0);
let promise = this.sendData(buffer);
promises.push(promise);
let packgeCnt = parseInt(this.packgeCnt || 20);
if (currentPacket % packgeCnt == 0 || (currentPacket >= totalPackets &&
promises.length > 0)) {
Promise.all(promises).then(() => {
if (currentPacket >= totalPackets) {
this.isSending = false;
resolve();
return;
}
this.currentPacket = currentPacket;
this.progress = Math.round((currentPacket / totalPackets) *
100);
currentPacket++;
setTimeout(sendNextPacket, inteval);
})
} else {
currentPacket++;
sendNextPacket();
}
// .then(() => {
// // 更新进度
// this.currentPacket = currentPacket;
// this.progress = Math.round((currentPacket / totalPackets) *
// 100);
// currentPacket++;
// setTimeout(sendNextPacket, inteval);
// }).catch(err => {
// console.log(err.errMsg+",发送失败了,正在补偿:" + currentPacket);
// setTimeout(sendNextPacket, inteval);
// });
};
//
sendNextPacket();
});
}
if (type == 'rgb565') {
let start = new Date();
console.log("开始发送");
sendImagePackets(array).then(() => {
let end = new Date();
var diff = (end.getTime() - start.getTime()) / 1000;
let s = diff % 60;
let m = (diff - s) / 60;
console.log("发送完成,耗时:" + m + "分" + s + "秒");
uni.showToast({
title: "发送完成,耗时:" + m + "分" + s + "秒",
icon: 'success',
})
}).catch((ex1) => {
//console.log("出现了异常", ex1)
}).finally(() => {
uni.hideLoading();
});
return;
}
},
HoldYouHand() {
var promise=new Promise((resolve,reject)=>{
try{
let start=new Date();
var str = "video transmit start"; //握手的协议字符串
console.log("开始握手:"+str)
// 1. 创建 ArrayBuffer 和 DataView
const buffer = new ArrayBuffer(str.length);
const dataView = new DataView(buffer);
// 2. 将字符串转换为 ASCII 码并写入 DataView
for (let i = 0; i < str.length; i++) {
dataView.setUint8(i, str.charCodeAt(i));
}
//console.log("111111");
this.sendData(buffer).then(() => {
// 开始发送第一个包
setTimeout(()=>{
let end = new Date();
var diff = (end.getTime() - start.getTime()) / 1000;
let s = diff % 60;
let m = (diff - s) / 60;
console.log("握手成功并完成2200ms等待,耗时"+m+"分"+s+"秒");
resolve(true);
}, 2200);
}).catch(err => {
//console.log("握手没有成功");
reject(err);
});
}catch(ex){
reject(ex);
}
});
return promise;
},
sendData(buffer) {
let sendBuffer = () => {
return new Promise((resolve, reject) => {
var promise = new Promise((succ, err) => {
uni.writeBLECharacteristicValue({
deviceId: this.connectedDeviceId,
serviceId: this.serviceId,
characteristicId: this.writeCharacteristicId,
value: buffer,
writeType: plus.os.name == 'iOS' ? 'write' : 'writeNoResponse',
success: () => {
// console.log("发送数据成功");
succ();
},
fail: (ex) => {
if (ex.code == '10007') {
// console.log("失败重试");
setTimeout(() => {
sendBuffer().then(succ).catch(err);
}, this.inteval || 0)
// succ()
} else
{
// console.log("发送数据失败",ex);
err(ex);
}
},
complete: function() {
//console.log("123456");
}
});
});
if (plus.os.name == 'iOS') {
function timeout(ms) {
return new Promise((_, err) => {
setTimeout(() => {
err({
code: -1,
errMsg: '超时了'
})
}, ms);
});
}
Promise.race([promise, timeout(this.inteval ? this.inteval : 0)]).then(() => {
// console.log("成功了");
resolve();
})
.catch((ex) => {
if (ex.code == -1) {
// console.log("超时了")
resolve();
} else {
reject(ex);
// console.log("异常了", ex);
//sendBuffer().then(resolve).catch(reject);
}
});
} else {
promise.then(() => {
//console.log("then........")
resolve();
}).catch(() => {
//console.log("catch.........")
reject()
});
}
});
}
return sendBuffer();
},
CutImg: function() {
if (this.imgs.length == 30) {
this.shotVideoClick(this.imgs, 'img');
return;
}
//console.log("开始处理视频")
uni.showLoading({
title: '开始处理'
});
this.$refs.compARef.shotVideoClick(0);
}
}
}
</script>
<style>
.sending-progress {
margin-top: 30rpx;
width: 100%;
}
.progress-bar {
height: 12rpx;
background-color: #e0e0e0;
border-radius: 6rpx;
overflow: hidden;
}
.progress-fill {
height: 100%;
background-color: #409eff;
transition: width 0.3s;
}
input {
border: 2rpx solid #000000;
}
button {
height: 100rpx;
line-height: 100rpx;
font-size: 28rpx;
float: left;
}
.content {
width: 100vw;
height: 300px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
</style>