Files
tkAiPage/src/views/VideoStream.vue
2025-08-04 13:07:36 +08:00

1505 lines
59 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 class="main">
<el-scrollbar class="left">
<div class=" center-line">
<!-- <el-button class="open" @click="wsActions.open(device.udid, index)"></el-button>
<el-button class="Back" @click="Back(device.udid, index)"></el-button>
<el-button class="Home" @click="Home(device.udid, index)"></el-button>
<el-button class="Overview" @click="Overview(device.udid, index)"></el-button> -->
<!-- <el-button @click="play(device.udid, index)">play</el-button> -->
<!-- <el-button class="open" @click="slideDown(device.udid, index)"></el-button>
<el-button class="open" @click="slideUp(device.udid, index)"></el-button>
<el-button class="open" @click="clickLike(device.udid, index)"></el-button> -->
<div></div>
<!-- <el-button @click="clickLikes(device.udid, index)">点赞</el-button> -->
<!-- <el-button @click="stopLike(index)">停止点赞</el-button> -->
<!-- <div></div>
<el-button @click="clickComment(device.udid, index)">评论</el-button>
<el-button @click="clickComtext(device.udid, index)">评论框</el-button>
<el-button @click="clickComPush(device.udid, index)">发布评论</el-button>
<div></div>
<el-button @click="clicktomy(device.udid, index)">主页</el-button> -->
<!-- <el-button @click="wsActions.clickAttention(device.udid, index)">关注/私信</el-button> -->
<!-- <div></div>
<el-button @click="clickPrivatetext(device.udid, index)">私信输入</el-button>
<el-button @click="clickPrivatePush(device.udid, index)">私信发送</el-button> -->
<el-button type="warning" @click="reload()">刷新</el-button>
<!-- <el-button type="warning" @click="opentanchuan()">123</el-button> -->
<div></div>
<!-- <el-button @click="wsActions.clickCopy(device.udid, index)">找私信</el-button> -->
<!-- <el-button @click="wsActions.clickCopyList(device.udid, index)">私信列表</el-button> -->
<div></div>
<!-- <el-button @click="wsActions.getmesNum(device.udid, index)">获取收件箱</el-button> -->
<!-- <el-button @click="wsActions.getSize(device.udid, index)">获取屏幕尺寸</el-button> -->
<!-- <el-button @click="wsActions.slideRight(device.udid, index)">右滑</el-button> -->
<!-- <el-button @click="wsActions.isHost(device.udid, index)">一键养号</el-button> -->
<el-button type="success" @click="openTk()">打开tiktok</el-button>
<el-button type="success" @click="resetTk()">重置tiktok</el-button>
<el-button type="success" @click="brushLive()">打开直播</el-button>
<el-button :type="runType[0] == 'like' ? 'danger' : 'success'" @click="parentNum()">{{ runType[0] == 'like' ?
'养号中' : '一键养号' }}</el-button>
<el-button type="success"
@click="showDialog = true; dialogTitle = '主播ID'; selectedDevice = 999">一键关注并打招呼</el-button>
<el-button type="success" v-if="!isShowMes" @click="openMonitor()">开启监测消息</el-button>
<el-button type="danger" v-else @click="cloesMonitor()">关闭监测消息</el-button>
<el-button type="danger" @click="stop()">全部停止</el-button>
<el-button type="danger" @click="router.push('/')">登出</el-button>
<div></div>
<!-- <div style="display: flex;">
<div style="width: 150px;">主播id</div>
<el-input style="border: 1px solid #000;" v-model="hostIdContent[index]" type="text"></el-input>
<el-button @click="setHostId(index)">发送</el-button>
</div>
<div style="display: flex;">
<div style="width: 150px;">评论内容</div>
<el-input style="border: 1px solid #000;" v-model="textContent[index]" type="text"></el-input>
<el-button @click="setComText(index)">发送</el-button>
</div> -->
<!-- <div style="display: flex;">
<div style="width: 150px;">私信内容</div>
<el-input style="border: 1px solid #000;" v-model="textContentpri[index]" type="text"></el-input>
<el-button @click="setPrivateText(index)">发送</el-button>
</div> -->
<div></div>
<!-- <el-button @click="getText(index)">获取粘贴板内容</el-button> -->
<div></div>
<!-- <el-button @click="wsActions.isVideoAndLive(device.udid, index)">判断视频还是直播</el-button> -->
</div>
</el-scrollbar>
<div class="content" @click.self="selectedDevice = 999">
<div class="video-container" @click.self="selectedDevice = 999" v-for="(device, index) in deviceInformation"
:key="device.udid" @mouseup="(e) => handleCanvasup(device.udid, e, index)">
<div class="video-canvas">
<video :ref="(el) => (videoElement[device.udid] = el)" autoplay muted playsinline
:style="getVideoStyle(index)" @click.stop="selectedDevice = index"></video>
<canvas class="canvas" v-show="selectedDevice == index" :ref="(el) => (canvasRef[device.udid] = el)"
@mousemove.stop="(e) => handleMouseMove(device.udid, e, index)"
@mousedown.stop="(e) => handleCanvasdown(device.udid, e, index)">
</canvas>
</div>
<div class="input-info" v-show="selectedDevice == index" :style="{ left: phone.width * 1.4 + 4 + '0px' }">
<!-- <div class="input-info" v-show="false"> -->
<!-- <el-button @click="showDialog = true; dialogTitle = '主播ID';">批量关注</el-button> -->
<div></div>
<!-- <el-button @click="showDialog = true; dialogTitle = '评论';">导入评论</el-button> -->
<div></div>
<el-button @click="getComArr(index, '评论')">查看评论</el-button>
<div></div>
<!-- <el-button @click="showDialog = true; dialogTitle = '私信';">导入私信</el-button> -->
<div></div>
<el-button @click="getComArr(index, '私信')">查看私信</el-button>
<!-- <el-button @click="wsActions.search(device.udid, index)">搜索</el-button> -->
<!-- <el-button @click="wsActions.getmesNum(device.udid, index)">检测消息</el-button> -->
<!-- <el-button @click="wsActions.clickMesage(device.udid, index)">进入消息</el-button> -->
<el-button @click="wsActions.clickSysMesage(device.udid, index)">进入消息</el-button>
<el-button @click="resetApp(device.udid, index)">重置应用</el-button>
<el-button
@click="wsActions.clickCopyList(device.udid, index); openShowChat = true; istranslate = true">翻译本页对话</el-button>
<!-- <el-button @click="wsActions.getSize(device.udid, index)">获取屏幕尺寸</el-button> -->
<div style="display: flex;">
<el-input style="border: 1px solid #000;" v-model="textContent[index]" type="text"></el-input>
<el-button @click="setComText(index)">发送</el-button>
</div>
<el-button @click="wsActions.test(device.udid, index)">打印ui节点树</el-button>
<el-button @click="wsActions.isOneLive(device.udid, index)">判断单人还是双人</el-button>
<el-button @click="wsActions.slideDown(device.udid, index)">下滑</el-button>
<el-button @click="wsActions.killNow(device.udid, index)">关闭当前应用</el-button>
<el-button @click="chooseFile(device.udid, index, 1, wsActions)">安装 APK 文件</el-button>
<el-button @click="chooseFile(device.udid, index, 2, wsActions)">传送文件</el-button>
<!-- <el-button @click="wsActions.isHost(device.udid, index)">一键养号</el-button> -->
</div>
</div>
<!--
<div class="video-container" @click.self="selectedDevice = 999" v-for="item in 4" :style="getVideoStyle()"
:class="{ 'bottom-row': item >= 2 }">
<div style="position: relative;box-sizing: border-box; ">
</div>
</div> -->
</div>
<div class="right">
<!-- <el-button @click="openShowChat = !openShowChat">聊天</el-button> -->
<ChatDialog :visible="openShowChat" :messages="chatList" />
</div>
<MultiLineInputDialog v-model:visible="showDialog" :initialText='""' :title="dialogTitle" :index="selectedDevice"
@confirm="onDialogConfirm" />
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, onBeforeUnmount, watch, inject } from "vue";
import VideoConverter from "h264-converter";
import { useRouter } from 'vue-router';
import { setphoneXYinfo, getphoneXYinfo, getUser, getHostList, setHostList, getContentpriList, setContentpriList, getContentList, setContentList } from '@/utils/storage'
import { toBufferBtn, stringToUtf8ByteArray, getClipboard, setClipboard, bufferToString, startsWithHeader, trimLongArray, base64ToBinary, toBuffer } from '@/utils/bufferUtils';
import { createWsActions } from '@/utils/wsActions';
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
import { chat, translationToChinese, translation } from "@/api/chat";
import { update } from '@/api/account';
import MultiLineInputDialog from '@/components/MultiLineInputDialog.vue'; // 根据实际路径修改
import ChatDialog from '@/components/ChatDialog.vue'
import { splitArray } from '@/utils/arrUtil'
import { chooseFile } from '@/utils/fileUtil'
import { connectSSE } from '@/utils/sseUtils'
import { set } from "lodash";
import { prologue, comment } from '@/api/account';
const router = useRouter();
let wsActions = null;
let userdata = getUser();
// 引入刷新方法
const reload = inject("reload")
let phone = ref({ width: 207, height: 470 });
const openStr = base64ToBinary("ZQBwAAAAAAA8CgLQAtAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA"); //开启视频流的启动命令
const eitwo = base64ToBinary("BAIAAABHVFJD"); //开启设备信息的命令
let isshow = ref(true); //页面是否隐藏
let playTimer = ref([{}, {}, {}, {}, {}, {}, {}, {}]); // 播放定时器
let isdown = ref(false); //是否是按下鼠标状态
const videoElement = ref({}); //视频流元素DOM
let deviceInformation = ref([]); //设备信息列表
//当前弹窗类型
let dialogTitle = ref('');
//评论文本内容
let textContent = ref(['', '', '', '', '', '', '', '']);
let textContentArr = ref([[], [], [], [], [], [], [], [], []]);
//主播id内容
let hostIdArr = ref([{}, {}, {}, {}, {}, {}, {}, {}]);
// let hostIdContentArr = ref([[], [], [], [], [], [], [], [], []]);
//私信文本内容
let textContentpri = ref(['', '', '', '', '', '', '', '']);
let textContentpriArr = ref([[], [], [], [], [], [], [], [], []]);
//保存聊天内容
let chatList = ref([]);
//保存爬虫发送的主播信息 待存缓存
let stroageHost = ref([]);
//选中设备
let selectedDevice = ref(999);
//ws列表
let wslist = [];
// 是否停止
let isStop = ref(false);
//sse弹窗是否存在
let isMsgPop = ref(false);
//播放器列表
let instanceList = ref([{}, {}, {}, {}, {}, {}, {}, {}]);
//是否是在关注主播
let runType = ref(['', '', '', '', '', '', '', '']);
//屏幕尺寸系数
let iponeCoefficient = ref([{ width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }]);
//是否是发送的内容
let isSend = ref(false)
//adb任务队列
const taskQueues = new Map(); // 每个设备一个队列
//弹窗是否显示
let showDialog = ref(false);
//监听消息定时器
let isShowMes = ref();
//给ws-scrcpy发送的数据格式
const mouseData = {
type: 2,
action: 0,
pointerId: 0,
position: {
point: { x: 0, y: 0 },
screenSize: { width: 320, height: 720 },
},
pressure: 1,
buttons: 1,
};
//打开聊天窗口的状态
let openShowChat = ref(false);
let istranslate = ref(false); //是否是翻译本页
let phoneXYinfo = ref(getphoneXYinfo() == null ? [{}, {}, {}, {}, {}, {}, {}, {}] : getphoneXYinfo());
console.log('phoneXYinfo.value', phoneXYinfo.value)
const wsCache = new Map();
//``````````````````````````````````````````````````````````````````````````````````
// 初始化 手机显示WebSocket 和视频流
const initVideoStream = (udid, index) => {
//``````````````````````````````````````````````````````````````````````````````````
// 1. 检查缓存中是否已有实例
if (wsCache.has(udid)) {
const cachedWs = wsCache.get(udid);
if (cachedWs.readyState === WebSocket.OPEN) {
return cachedWs;
}
// 如果连接已关闭,清除缓存并重新创建
wsCache.delete(udid);
}
// 2. 创建专用实例容器
instanceList.value[index] = {
wsVideo: null,
converter: null,
timer: null
};
//``````````````````````````````````````````````````````````````````````````````````
if (!videoElement.value) return;
// 1. 创建 h264-converter 实例
instanceList.value[index].converter = new VideoConverter(videoElement.value[udid], 60, 1);
// instanceList.value[index].converter.play();
// 2. 连接 WebSocket
wslist[index] = new WebSocket(
`ws://127.0.0.1:8000/?action=proxy-adb&remote=tcp%3A8886&udid=${udid}`
);
wslist[index].binaryType = "arraybuffer";
wslist[index].onopen = () => {
console.log("手机显示ws已开启");
wsActions = createWsActions(wslist);
// 发送 开启 视频流数据
setTimeout(() => {
wslist[index].send(openStr);
}, 300);
wsCache.set(udid, instanceList.value[index]);
};
const magicSize = stringToUtf8ByteArray('scrcpy_message');
// 3. 处理接收到的二进制数据
wslist[index].onmessage = (event) => {
const data = new Uint8Array(event.data);
//判断返回的如果是字符串为自定义返回
if (typeof event.data == 'string') {
if (isStop.value) {
createTaskQueue(index).clear();//清除队伍中的任务
return;
}
const resData = JSON.parse(event.data)
//成功处理
console.log('自定义返回', resData)
if (resData.status === 'success') {
//触发长按该位置
if (resData.type == 'clickCopy') {
console.log('长按', resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index)
clickxy(resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index, 9) //index为9的时候长按
setTimeout(() => {
wsActions.clickCopyText(resData.udid, index)
}, 1500);
} else if (resData.type == 'getmesNum') {
if (resData.message == 0) {
console.log('没有消息')
if (runType.value[index] == 'follow') {
LikesToLikesToLikes(deviceInformation.value[index].udid, index)
}
//如果检测到有新消息会收到两条ws回复一条message==1 一条message==成功
} else if (resData.message == 1) {
console.log('有消息')
} else if (resData.message == '点击成功') {
console.log('双击', iponeCoefficient.value[index].width, iponeCoefficient.value[index].height)
setTimeout(() => {
clickxy(resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index)
setTimeout(() => {
clickxy(resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index) //index为9的时候长按
}, 100)
wsActions.clickSysMesage(deviceInformation.value[index].udid, index) //点击消息进入对话框
}, 1500)
}
} else if (resData.type == 'clickMesage') {
//点击进入新消息页面以后,获取页面信息
wsActions.clickCopyList(deviceInformation.value[index].udid, index)
} else if (resData.type == 'clickSysMesage') {
setTimeout(() => {
Back('', index)
}, 3000)
} else if (resData.type == 'isVideoAndLive') {
console.log(resData.message)
} else if (resData.type == 'clickCopyList') { //获取到的消息列表
//打印所有信息
console.log('消息列表', resData.message)
chatList.value = resData.message
getTranslation(chatList.value)
const mesBox = resData.message[resData.message.length - 1]
//打印最新一条信息
console.log('最新消息', mesBox)
console.log("翻译", istranslate.value)
if (istranslate.value == false) {
if (mesBox.position == 'right') return
openShowChat.value = true
console.log("执行ai")
chat({ msg: mesBox.text }).then(res => {
console.log("ai返回", res)
textContentpri.value[index] = res.result
PrivatetexToPrivatePush(deviceInformation.value[index].udid, index)
})
} else {
console.log("翻译本页")
istranslate.value = false
}
} else if (resData.action == 'getSize') {
console.log(iponeCoefficient.value, '手机尺寸宽度:', resData.width, '高度:', resData.height);
iponeCoefficient.value[index].width = 320 / resData.width
iponeCoefficient.value[index].height = 720 / resData.height
console.log('尺寸系数', iponeCoefficient.value[index])
} else {
console.log(resData.type, '坐标返回x:', resData.x, 'y:', resData.y);
}
phoneXYinfo.value[index].id = resData.udid
if (resData.type == 'Likes') {//判断是否是 点赞
phoneXYinfo.value[index].Likes = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
if (runType.value[index] == 'follow') {
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
}
} else if (resData.type == 'Comment') {//打开评论
phoneXYinfo.value[index].Comment = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'CommentText') {//复制评论
phoneXYinfo.value[index].CommentText = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
textContent.value[index] = resData.message
} else if (resData.type == 'Comtext') {//评论输入
phoneXYinfo.value[index].Comtext = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'ComPush') {//评论发送
phoneXYinfo.value[index].ComPush = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
setTimeout(() => {
Back('', index)
if (runType.value[index] == 'follow') {
setTimeout(() => {
Back('', index)
}, 1000)
} else {
setTimeout(() => {
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
setTimeout(() => {
console.log('观看视频中')
randomSeeVideo(deviceInformation.value[index].udid, index) //50秒后继续循环任务
}, 1000);
}, 1000)
}
}, 800)
} else if (resData.type == 'tomy') {//打开主页
phoneXYinfo.value[index].tomy = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'Attention') {//关注、打开私信
phoneXYinfo.value[index].Attention = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
// LikesToCommentToComPush(deviceInformation.value[index].udid, index) //是否继续循环任务
} else if (resData.type == 'return') {//私信评论
phoneXYinfo.value[index].return = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'addHost') {//添加关注
phoneXYinfo.value[index].addHost = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
setTimeout(() => {
wsActions.isHost(deviceInformation.value[index].udid, index)//检测
}, 1000);
} else if (resData.type == 'Privatetex') {//私信评论
phoneXYinfo.value[index].Privatetex = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'PrivatePush' || resData.type == 'PrivatePushFollow') {//私信发送
phoneXYinfo.value[index].PrivatePush = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
setTimeout(() => {
Back('', index);
setTimeout(() => {
Back('', index);
setTimeout(() => {
Back('', index);
setTimeout(() => {
if (resData.type == 'PrivatePush') {
Back('', index);
setTimeout(() => {
Back('', index);
setTimeout(() => {
Back('', index);
//正常没有消息,发送完私信以后,返回六次,然后继续下一个任务
wsActions.getmesNum(deviceInformation.value[index].udid, index)
// LikesToLikesToLikes(deviceInformation.value[index].udid, index)
}, 1000);
}, 1000);
} else if (resData.type == 'PrivatePushFollow') {
//如果有新消息,回复完私信以后,返回三次,然后继续下一个任务
wsActions.getmesNum(deviceInformation.value[index].udid, index)
// LikesToLikesToLikes(deviceInformation.value[index].udid, index)
}
}, 1000);
}, 1000);
}, 1000);
}, 1000);
} else if (resData.type == 'clickCopy') {//点击复制
phoneXYinfo.value[index].clickCopy = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'hostVideo') {//观看主播视频
phoneXYinfo.value[index].hostVideo = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'isHost') {//视频关注主播
phoneXYinfo.value[index].isHost = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
if (resData.message == 0) {
console.log('无关注', index)
Back(deviceInformation.value[index].udid, index)
setTimeout(() => {
console.log('观看视频中', index)
randomSeeVideo(deviceInformation.value[index].udid, index) //30-50秒后继续循环任务
}, 1000);
} else if (resData.message == 1) {
console.log('有关注', index)
const randomNum = Math.random(); // 生成一个0到1之间的随机数
//是否点赞评论的概率
if (randomNum < 0.07) {
console.log('进行点赞评论', index)
LikesToCommentToComPush(deviceInformation.value[index].udid, index)
} else {
console.log('下一个', index)
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
randomSeeVideo(deviceInformation.value[index].udid, index) //30-50秒后继续循环任务
}
}
} else if (resData.type == 'openDY') {//视频关注主播
createTaskQueue(index).clear();//清除队伍中的任务
} else if (resData.type == 'toLive') {//打开直播
wsActions.isHead(deviceInformation.value[index].udid, index)//判断直播
} else if (resData.type == 'isHead') {//判断有没有头像
if (resData.message == 1) {
wsActions.isOneLive(deviceInformation.value[index].udid, index)//判断直播
} else {
return
}
} else if (resData.type == 'isOneLive') {//判断单人还是双人
if (resData.message == 0) {
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
wsActions.isHead(deviceInformation.value[index].udid, index)//判断直播
return
}
// 用法:
(async () => {
const result = await randomDelayAndExecute();
//30%概率
if (result) {
let count = 0;
const num = Math.floor(Math.random() * 31) + 5;
const interval = setInterval(() => {
if (count >= num) {
clearInterval(interval);
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
wsActions.isHead(deviceInformation.value[index].udid, index)//判断直播
return;
}
clickxy(
resData.x * iponeCoefficient.value[index].width,
resData.y * iponeCoefficient.value[index].height,
index
)
count++;
}, 300);
return;
} else {
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
wsActions.isHead(deviceInformation.value[index].udid, index)//判断直播
return
}
})();
}
setphoneXYinfo(phoneXYinfo.value)
if (resData.type != 'isHost') {
if (resData.type == 'hostVideo' || resData.type == 'Likes') {
setTimeout(() => {
createTaskQueue(index).next(); // 继续队列中下一个任务
}, 5000)
} else if (resData.type == 'getmesNum') {
} else {
createTaskQueue(index).next(); // 继续队列中下一个任务
}
}
} else {
// ----------------------------------------------------------------------------------------------------报错处理
//如果该视频无法被评论,返回刷下一条视频
if (resData.type == 'Comtext' || resData.type == 'CommentText') {
if (runType.value[index] == 'follow') {
Back('', index)
setTimeout(() => {
Back('', index)
createTaskQueue(index).next(); // 继续队列中下一个任务
createTaskQueue(index).next(); // 继续队列中下一个任务
}, 1000)
} else {
resetApp(udid, index)
setTimeout(() => {
wsActions.isHost(deviceInformation.value[index].udid, index)
}, 1000)
}
//如果该视频无法被搜索到,返回刷下一条视频
} else if (resData.type == 'toHost') {
Back('', index)
setTimeout(() => {
Back('', index)
createTaskQueue(index).clear();//清除队伍中的任务
setTimeout(() => {
Back('', index)
LikesToLikesToLikes(deviceInformation.value[index].udid, index)
}, 1000)
}, 1000)
} else if (resData.type == 'Privatetex' || resData.type == 'hostVideo' || resData.type == 'search') {
if (runType.value[index] == 'follow') {
//关注的时候出现无法私信和没有视频的情况 错误重置
resetApp(udid, index)
setTimeout(() => {
wsActions.getmesNum(deviceInformation.value[index].udid, index)
// LikesToLikesToLikes(deviceInformation.value[index].udid, index)
}, 1000)
}
} else if (resData.type == 'getmesNum') {
if (runType.value[index] == 'follow') {
LikesToLikesToLikes(deviceInformation.value[index].udid, index)
}
//getmesNum出现没有消息的情况
} else if (resData.type == 'clickMesage' || resData.type == 'ComPush') {
//ComPush关注主播的时候出现无法评论的视频 会跳过评论发送,不处理评论发送的返回错误
} else if (resData.type == 'clickCopyList') {
//如果无法获取到聊天记录,返回继续检测
console.error('未找到聊天,返回')
Back('', index)
} else if (resData.type == 'clickSysMesage') {
//如果没有系统消息,则点击新消息
wsActions.clickMesage(deviceInformation.value[index].udid, index) //点击消息进入对话框
} else {
console.error(resData.message, resData.type); // 错误处理
ElMessage.error(resData.message);
createTaskQueue(index).clear();//清除队伍中的任务
}
// createTaskQueue(index).next(); // 继续队列中下一个任务
}
}
//返回粘贴板内容
if (startsWithHeader(magicSize, data)) {
if (!isSend.value) {
const buffer = trimLongArray(data, magicSize);
const paste = bufferToString(buffer);
console.log('获取粘贴板内容', paste)
}
}
//视频流处理
if (instanceList.value[index].converter) {
if (isshow.value) {
instanceList.value[index].converter.appendRawData(data);
}
}
};
// 4. 错误处理
wslist[index].onerror = (error) => {
wsCache.delete(udid); // 错误时清理缓存
};
//``````````````````````````````````````````````````````````````````````````````````
wslist[index].onclose = (event) => {
wsCache.delete(udid)// 自动清理缓存
clearInterval(instanceList.value[index].timer); // 清理定时器// 移除缓存
};
//``````````````````````````````````````````````````````````````````````````````````
};
// 配置参数
let canvasRef = ref({});
// 初始化画布
const initCanvas = (udid) => {
const canvas = canvasRef.value[udid];
const dpr = window.devicePixelRatio || 1;
canvas.style.width = `${phone.value.width * 1.4}px`;
canvas.style.height = `${phone.value.height * 1.4}px`;
canvas.width = phone.value.width * 1.4 * dpr;
canvas.height = phone.value.height * 1.4 * dpr;
const ctx = canvas.getContext("2d");
ctx.scale(dpr, dpr);
// 绘制参考网格(可选)
ctx.strokeStyle = "#ffffff00";
for (let x = 0; x <= phone.value.width; x += 100) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, phone.value.height);
ctx.stroke();
}
};
// 鼠标按下事件处理
const handleCanvasdown = (udid, event, index) => {
const { x, y } = getCanvasCoordinate(event, udid);
console.log("鼠标按下", x, y);
isdown.value = true;
mouseData.action = 0;
mouseData.pressure = 1;
mouseData.buttons = 1;
mouseData.position.point.x = x;
mouseData.position.point.y = y;
// console.log(mouseData);
console.log(index)
setTimeout(() => {
selectedDevice.value = index;
}, 300);
console.log(wslist)
wslist[index].send(toBuffer(mouseData));
};
// 鼠标抬起事件处理
const handleCanvasup = (udid, event, index) => {
const { x, y } = getCanvasCoordinate(event, udid);
// position.endX = floorNum(x)
// position.endY = floorNum(y)
isdown.value = false;
mouseData.action = 1;
mouseData.pressure = 0;
mouseData.buttons = 0;
mouseData.position.point.x = x;
mouseData.position.point.y = y;
// console.log(mouseData);
wslist[index].send(toBuffer(mouseData));
};
// 鼠标移动事件处理
const handleMouseMove = (udid, event, index) => {
if (isdown.value) {
const { x, y } = getCanvasCoordinate(event, udid);
// position.startX = floorNum(x)
// position.startY = floorNum(y)
mouseData.action = 2;
mouseData.pressure = 1;
mouseData.buttons = 1;
mouseData.position.point.x = x;
mouseData.position.point.y = y;
// console.log(mouseData);
wslist[index].send(toBuffer(mouseData));
}
};
// 坐标计算
const getCanvasCoordinate = (event, udid) => {
const canvas = canvasRef.value[udid];
const rect = canvas.getBoundingClientRect();
const dpr = window.devicePixelRatio || 1;
return {
x: (event.clientX - rect.left) / 0.9138 * dpr,
y: (event.clientY - rect.top) / 0.9138 * dpr,
};
};
//返回上一层
const Back = (udid, index) => {
wslist[index].send(toBufferBtn({ "type": 0, "action": 0, "keycode": 4, "metaState": 0, "repeat": 0 }));
wslist[index].send(toBufferBtn({ "type": 0, "action": 1, "keycode": 4, "metaState": 0, "repeat": 0 }));
}
//返回首页
const Home = (udid, index) => {
wslist[index].send(toBufferBtn({ "type": 0, "action": 0, "keycode": 3, "metaState": 0, "repeat": 0 }));
wslist[index].send(toBufferBtn({ "type": 0, "action": 1, "keycode": 3, "metaState": 0, "repeat": 0 }));
}
//任务视图
const Overview = (udid, index) => {
wslist[index].send(toBufferBtn({ "type": 0, "action": 0, "keycode": 187, "metaState": 0, "repeat": 0 }));
wslist[index].send(toBufferBtn({ "type": 0, "action": 1, "keycode": 187, "metaState": 0, "repeat": 0 }));
}
//回车 index手机下标 state up按下 down抬起 keycode 键
const key = (index, state, keycode) => {
// console.log("退格", index)
if (index === 999) {
return
} else {
if (state == 'up') {
wslist[index].send(toBufferBtn({ "type": 0, "action": 1, "keycode": keycode, "metaState": 0, "repeat": 0 }));
} else if (state == 'down') {
wslist[index].send(toBufferBtn({ "type": 0, "action": 0, "keycode": keycode, "metaState": 0, "repeat": 0 }));
}
}
}
const handleVisibilityChange = () => {
if (document.visibilityState === "hidden") {
console.log("页面被隐藏");
isshow.value = false;
// 页面被隐藏时执行的逻辑
} else if (document.visibilityState === "visible") {
console.log("页面变为可见");
setTimeout(() => {
isshow.value = true;
// ObtainDeviceInformation();
}, 500);
}
};
onMounted(() => {
document.addEventListener("visibilitychange", handleVisibilityChange);
ObtainDeviceInformation();
window.addEventListener('keydown', (e) => {
console.log('触发按键了 键盘事件有效', e)
if (e.key == 'Backspace') {
key(selectedDevice.value, 'down', 67)
}
})
window.addEventListener('keyup', (e) => {
// console.log('触发按键了 键盘事件有效抬起', e.keyCode, e.key)
if (e.key == 'Backspace') {
key(selectedDevice.value, 'up', 67)
}
})
const loading = ElLoading.service({
lock: true,
text: '初始化中...',
background: 'rgba(0, 0, 0, 0.7)',
})
setTimeout(() => {
loading.close()
}, 2000)
//sse接收爬虫发送的消息
connectSSE(`https://datasave.api.yolozs.com/api/sse/connect/${userdata.tenantId}/${userdata.id}`, (data) => {
// connectSSE(`http://192.168.1.155:19665/api/sse/connect/${userdata.tenantId}/${userdata.id}`, (data) => {
// 处理服务端推送的数据
console.log('来自服务端:', data)
//接收到start
if (data === 'start') {
if (!isMsgPop.value) {
isMsgPop.value = true;
ElMessageBox.confirm(
'检测到YOLO助手正在爬取主播是否进行操作',
'消息提醒',
{
confirmButtonText: '开始',
cancelButtonText: '取消',
type: 'success',
}
)
.then(() => {
//开启sse版follow任务
ElMessage({
type: 'success',
message: '任务开启成功',
})
setHostList(stroageHost.value)
//重启tk
resetTk()
//获取评论
comment().then((resA) => {
console.log('resA:', resA);
setContentList(resA)
//评论
textContentArr.value.forEach((item, indexA) => {
textContent.value[indexA] = resA[getRandomNumber(resA.length - 1)];
})
prologue().then((resB) => {
console.log('resB:', resB);
setContentpriList(resB)
//私信
textContentpriArr.value.forEach((item, indexA) => {
textContentpri.value[indexA] = resB[getRandomNumber(resB.length - 1)];
runType.value[indexA] = 'follow'
console.log('runType', runType.value[indexA])
})
deviceInformation.value.forEach((device, indexB) => {
if (getHostList().length <= 0) return;
// LikesToLikesToLikes(device.udid, indexB)
wsActions.getmesNum(device.udid, indexB)
})
})
})
})
.catch(() => {
stroageHost.value = []
isMsgPop.value = false;
})
}
} else {
stroageHost.value = getHostList()
stroageHost.value.push(({ country: data.country, text: data.hostsId, state: false }))
if (isMsgPop.value) {
setHostList(stroageHost.value)
}
}
//更新状态
// update(
// {
// id: data.id,
// operationStatus: 1,
// }
// ).then(() => {
// })
})
});
function opentanchuan() {
ElMessageBox.confirm(
'接收到YOLO爬虫爬取到的主播开始进行操作',
'消息提醒',
{
confirmButtonText: '开始',
cancelButtonText: '取消',
type: 'success',
}
)
.then(() => {
ElMessage({
type: 'success',
message: '任务开启成功',
})
resetTk()
comment().then((resA) => {
console.log('resA:', resA);
setContentList(resA)
//评论
textContentArr.value.forEach((item, indexA) => {
textContent.value[indexA] = resA[getRandomNumber(resA.length - 1)];
})
prologue().then((resB) => {
console.log('resB:', resB);
setContentpriList(resB)
//私信
textContentpriArr.value.forEach((item, indexA) => {
textContentpri.value[indexA] = resB[getRandomNumber(resB.length - 1)];
runType.value[indexA] = 'follow'
console.log('runType', runType.value[indexA])
})
deviceInformation.value.forEach((device, indexB) => {
if (getHostList().length <= 0) return;
// LikesToLikesToLikes(device.udid, indexB)
wsActions.getmesNum(device.udid, indexB)
})
})
})
})
.catch(() => {
})
}
onBeforeUnmount(() => {
document.removeEventListener("visibilitychange", handleVisibilityChange);
});
// 组件卸载时清理
onUnmounted(() => {
console.log("卸载组件");
cloesMonitor(); //关闭检测消息
});
//获取设备信息
const ObtainDeviceInformation = () => {
// 2. 连接 WebSocket
const ws = new WebSocket("ws://127.0.0.1:8000/?action=multiplex");
ws.binaryType = "arraybuffer";
ws.onopen = () => {
ws.send(eitwo);
};
// 3. 处理接收到的二进制数据
ws.onmessage = (event) => {
const data = JSON.parse(new TextDecoder('utf-8').decode(event.data).replace(/[^\x20-\x7F]/g, ''));
try {
console.log('数组', data)
if (data.type == "devicelist") {
deviceInformation.value = [];
const filteredList = data.data.list.filter(item => item.state === 'device');
//检测到设备列表时,渲染所有设备
filteredList.forEach((item, index) => {
console.log(item);
if (item.state === "device") {
deviceInformation.value.push(item);
console.log("deviceInformation", deviceInformation.value);
setTimeout(() => {
initVideoStream(item.udid, index);
initCanvas(item.udid);
setTimeout(() => {
wsActions.getSize(item.udid, index)
}, 2000)
}, 300);
}
})
} else if (data.type == "device") {
if (data.data.device.state === "offline") {
//监听设备信息,出现离线设备,则删除设备信息
deviceInformation.value.forEach((item, index) => {
if (item.udid === data.data.device.udid) {
deviceInformation.value.splice(index, 1);
if (index < wslist.length - 1) {
deviceInformation.value.forEach((item, index1) => {
//关闭websocket连接
wslist.forEach((item, index) => {
item.close();
})
//重新连接websocket
new Promise((resolve, reject) => {
setTimeout(() => {
try {
initVideoStream(item.udid, index1);
initCanvas(item.udid);
} catch (error) {
reject(error);
}
}, 300);
});
})
}
console.log("deviceInformation", deviceInformation.value);
}
})
} else if (data.data.device.state === "device") {
let isrepeat = false;
//监听设备信息,出现新设备,则添加设备信息
deviceInformation.value.forEach((item, index) => {
if (item.udid == data.data.device.udid) {
isrepeat = true;
}
})
if (!isrepeat) {
deviceInformation.value.push(data.data.device);
new Promise((resolve, reject) => {
setTimeout(() => {
try {
initVideoStream(data.data.device.udid, deviceInformation.value.length - 1);
initCanvas(data.data.device.udid);
} catch (error) {
// reject(error);
}
}, 1000);
});
}
};
}
} catch (e) {
console.error(e);
}
};
}
//喜欢-输入评论
async function LikesToCommentToComPush(udid, index) {
await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
await sendWsTask(index, { udid, action: 'click', type: 'Comment', index, resourceId: 'com.zhiliaoapp.musically:id/cvd' });
await sendWsTask(index, { udid, action: 'dump', type: 'CommentText', index, resourceId: 'com.zhiliaoapp.musically:id/d5q' });
await sendWsTask(index, { udid, action: 'click', type: 'Comtext', index, resourceId: 'com.zhiliaoapp.musically:id/cs0' });
await sendWsTask(index, { udid, action: 'click', type: 'ComPush', index, resourceId: 'com.zhiliaoapp.musically:id/bqg' });
}
//点赞主页4个作品+评论最后一个作品并返回
async function LikesToLikesToLikes(udid, index) {
isStop.value = false;
runType.value[index] = 'follow';
// await sendWsTask(index, { udid, action: 'click', type: 'getmesNum', index, resourceId: 'com.zhiliaoapp.musically:id/jyv' });
await sendWsTask(index, { udid, action: 'click', type: 'search', index, resourceId: 'com.zhiliaoapp.musically:id/gtz' });
await sendWsTask(index, { udid, action: 'click', type: 'searchHost', index, resourceId: 'com.zhiliaoapp.musically:id/t6f' });
await sendWsTask(index, { udid, action: 'click', type: 'toHost', index, resourceId: 'com.zhiliaoapp.musically:id/iso' });
await sendWsTask(index, { udid, action: 'click', type: 'hostVideo', index, resourceId: 'com.zhiliaoapp.musically:id/u3o', num: 0 });
await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
await sendWsTask(index, { udid, action: 'click', type: 'Comment', index, resourceId: 'com.zhiliaoapp.musically:id/cvd' });
await sendWsTask(index, { udid, action: 'click', type: 'Comtext', index, resourceId: 'com.zhiliaoapp.musically:id/cs0' });
await sendWsTask(index, { udid, action: 'click', type: 'ComPush', index, resourceId: 'com.zhiliaoapp.musically:id/bqg' });
await sendWsTask(index, { udid, action: 'click', type: 'Attention', index, resourceId: 'com.zhiliaoapp.musically:id/dhx' });
await sendWsTask(index, { udid, action: 'click', type: 'Attention', index, resourceId: 'com.zhiliaoapp.musically:id/dhx' });
await sendWsTask(index, { udid, action: 'click', type: 'Privatetex', index, resourceId: 'com.zhiliaoapp.musically:id/hob' });
await sendWsTask(index, { udid, action: 'click', type: 'PrivatePush', index, resourceId: 'com.zhiliaoapp.musically:id/hog' });
// await sendWsTask(index, { udid, action: 'click', type: 'fanhui', index, resourceId: 'com.zhiliaoapp.musically:id/awi' });
}
//私信
async function PrivatetexToPrivatePush(udid, index) {
await sendWsTask(index, { udid, action: 'click', type: 'Privatetex', index, resourceId: 'com.zhiliaoapp.musically:id/hob' });
await sendWsTask(index, { udid, action: 'click', type: 'PrivatePushFollow', index, resourceId: 'com.zhiliaoapp.musically:id/hog' });
}
//重置当前应用
async function resetApp(udid, index) {
createTaskQueue(index).clear();//清除队伍中的任务
await sendWsTask(index, { udid, action: 'killNow' });
await sendWsTask(index, { udid, action: 'openDY' });
}
//发送评论字符到手机方法
function setComText(index) {
isSend.value = true;
setTimeout(() => {
isSend.value = false;
}, 300);
console.log('发送评论内容', index, textContent.value[index])
wslist[index].send(setClipboard(textContent.value[index]));
if (runType.value[index] === 'follow') {
textContent.value[index] = getContentList()[index][getRandomNumber(getContentList()[index].length - 1)];
}
}
//发送主播ID字符到手机方法
function setHostId(index) {
isSend.value = true;
setTimeout(() => {
isSend.value = false;
}, 300);
const host = markFirstFalseAsTrue(getHostList())
if (host == null) {
createTaskQueue(index).clear();//清除队伍中的任务
ElMessage.success('主播ID已全部发送完毕');
return;
}
hostIdArr.value[index] = host;
wslist[index].send(setClipboard(host.text)); //发送内容
}
//发送私信字符到手机方法
function setPrivateText(index, datatype) {
isSend.value = true;
setTimeout(() => {
isSend.value = false;
}, 300);
console.log('发送私信内容', index, textContentpri.value[index])
//如果是在关注主播中,发送的开场白进行对应国家翻译
if (runType.value[index] === 'follow' && datatype == 'PrivatePush') {
translation({ msg: getContentpriList()[index][getRandomNumber(getContentpriList()[index].length - 1)], country: hostIdArr.value[index].country }).then(res => {
console.log(res)
textContentpri.value[index] = res;
wslist[index].send(setClipboard(textContentpri.value[index]));
})
} else {
wslist[index].send(setClipboard(textContentpri.value[index]));
textContentpri.value[index] = getContentpriList()[index][getRandomNumber(getContentpriList()[index].length - 1)];
}
}
//获取手机粘贴板方法
function getText(index) {
wslist[index].send(getClipboard());
}
function getComArr(index, type) {
if (type == '评论') {
ElMessageBox.alert(getContentList()[index], `当前${type}内容`, {
confirmButtonText: 'OK',
})
} else {
ElMessageBox.alert(getContentpriList()[index], `当前${type}内容`, {
confirmButtonText: 'OK',
})
}
}
//传入xy坐标 进行点击
function clickxy(x, y, index, type) {
console.log('clickxy方法', x, y)
if (type == 3) { //关注/私信 后的返回和下滑
mouseData.action = 0;
mouseData.pressure = 1;
mouseData.buttons = 1;
mouseData.position.point.x = x;
mouseData.position.point.y = y;
wslist[index].send(toBuffer(mouseData));
setTimeout(() => {
mouseData.action = 1;
wslist[index].send(toBuffer(mouseData));
}, 100)
//返回和下滑
setTimeout(() => {
Back('', index)
setTimeout(() => {
wsActions.slideDown(phoneXYinfo.value[index].id, index)
setTimeout(() => {
start(phoneXYinfo.value[index].id, index)
}, 300)
}, 300)
}, 300)
} else if (type == 2) { //评论过后的返回和右滑
mouseData.action = 0;
mouseData.pressure = 1;
mouseData.buttons = 1;
mouseData.position.point.x = x;
mouseData.position.point.y = y;
wslist[index].send(toBuffer(mouseData));
setTimeout(() => {
mouseData.action = 1;
wslist[index].send(toBuffer(mouseData));
}, 100)
//返回和右滑
setTimeout(() => {
Back('', index)
setTimeout(() => {
wsActions.slideRight(phoneXYinfo.value[index].id, index)
}, 300)
}, 300)
} else if (type == 1) {//评论框点击后的发送内容
mouseData.action = 0;
mouseData.pressure = 1;
mouseData.buttons = 1;
mouseData.position.point.x = x;
mouseData.position.point.y = y;
wslist[index].send(toBuffer(mouseData));
setTimeout(() => {
mouseData.action = 1;
wslist[index].send(toBuffer(mouseData));
}, 100)
//发送内容
setTimeout(() => {
console.log('点击了')
setComText(index)
}, 300)
} else if (type == 9) { //长按
mouseData.action = 0;
mouseData.pressure = 1;
mouseData.buttons = 1;
mouseData.position.point.x = x;
mouseData.position.point.y = y;
wslist[index].send(toBuffer(mouseData));
console.log('鼠标按下')
setTimeout(() => {
mouseData.action = 1;
wslist[index].send(toBuffer(mouseData));
console.log('抬起按下')
}, 1500)
} else {
mouseData.action = 0;
mouseData.pressure = 1;
mouseData.buttons = 1;
mouseData.position.point.x = x;
mouseData.position.point.y = y;
wslist[index].send(toBuffer(mouseData));
setTimeout(() => {
mouseData.action = 1;
wslist[index].send(toBuffer(mouseData));
}, 100)
}
}
//创建任务实例
function createTaskQueue(index) {
if (!taskQueues.has(index)) {
taskQueues.set(index, []);
}
return {
enqueue(task) {
taskQueues.get(index).push(task);
if (taskQueues.get(index).length === 1) {
console.log("执行任务第一个任务");
task(); // 执行第一个任务
}
},
next() {
console.log('执行等待中任务')
const queue = taskQueues.get(index);
queue.shift(); // 移除已完成任务
if (queue.length > 0) {
queue[0](); // 执行下一个任务
}
},
clear() {
taskQueues.set(index, []); // 清除所有任务
},
getNum() {
return taskQueues.get(index)
}
};
}
//发送检查该手机的xy坐标任务
function sendWsTask(index, data) {
console.log('任务等待中', data.type);
return new Promise((resolve) => {
try {
const queue = createTaskQueue(index);
// console.log("创建队列", queue.getNum());
const task = () => {
//发送评论的文本粘贴事件
if (data.type == 'Likes') {
clickxy(160, 360, index)
}
if (data.type == 'isHost') {
}
if (data.type == 'Comment') {
if (runType.value[index] == 'follow') {
clickxy(160, 360, index)
}
}
if (data.type == 'ComPush') {
setTimeout(() => {
setComText(index)//粘贴内容
}, 500)
}
if (data.type == 'searchHost') {
setTimeout(() => {
setHostId(index)//粘贴内容
}, 500)
}
//发送私信的文本粘贴事件
if (data.type == 'PrivatePush' || data.type == 'PrivatePushFollow') {
setPrivateText(index, data.type)
}
//关注前的返回和右滑
if (data.type == 'Attention') {
}
//发送关注之前的返回
if (data.type == 'addHost') {
}
//发送任务
if (data.type == 'Attention') {
setTimeout(() => {
wslist[index].send(JSON.stringify(data));
resolve();
}, 1000)
} else {
wslist[index].send(JSON.stringify(data));
resolve();
}
// 表示当前任务“已发出”,但不是“已完成”
// 实际完成由 onmessage 中的 success 决定并继续执行队列
};
queue.enqueue(task);
} catch (e) {
console.error('发送任务错误:', e);
}
});
}
// 生成start秒到end秒的随机延迟
function randomDelay(start, end) {
return Math.floor(Math.random() * end * 1000) + start * 1000;
}
//一个0到n之间的随机整数
function getRandomNumber(n) {
return Math.floor(Math.random() * (n + 1));
}
//延迟30-50秒后检测关注
function randomSeeVideo(udid, index) {
const delay = Math.floor(Math.random() * (50 - 30) + 10) * 1000;
playTimer.value[index] = setTimeout(() => {
console.log('观看结束', index);
wsActions.isHost(udid, index)//检测
}, delay);
}
//延迟3-4分钟后秒后检测关注
async function randomDelayAndExecute() {
const minDelay = 1 * 60 * 1000;
const maxDelay = 4 * 60 * 1000;
const randomDelay = Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
console.log(`将延迟 ${Math.round(randomDelay / 1000)} 秒后执行...`);
return new Promise((resolve) => {
setTimeout(() => {
const randomNum = Math.floor(Math.random() * 100);
if (randomNum < 30) {
console.log("30%概率触发");
resolve(true);
} else {
console.log("70%概率触发");
resolve(false);
}
}, randomDelay);
});
}
//选中样式
function getVideoStyle(index) {
const isSelected = selectedDevice.value === index;
const baseWidth = phone.value.width;
const baseHeight = phone.value.height;
// console.log(isSelected, '是否相等')
return {
width: isSelected ? baseWidth * 1.4 + 'px' : baseWidth + 'px',
height: isSelected ? baseHeight * 1.4 + 'px' : baseHeight + 'px',
border: isSelected ? '2px solid blue' : '1px solid blue',
position: isSelected ? 'absolute' : 'relative',
top: isSelected ? '0' : 'unset',
left: isSelected ? '0' : 'unset',
zIndex: isSelected ? 1000 : 1,
pointerEvents: isSelected ? 'none' : 'auto',
};
}
function stop() {
// actions[index] = [];
cloesMonitor();
isStop.value = true; //停止所有任务
isMsgPop.value = false;//关闭爬虫sse任务
deviceInformation.value.forEach((item, i) => {
console.log('停止', i);
createTaskQueue(i).clear();//清除队伍中的任务
console.log(createTaskQueue(i).getNum())
//停止当前任务
//重置当前状态
runType.value[i] = ''
//清除观看视频定时器
clearInterval(playTimer.value[i])
playTimer.value[i] = null;//清除定时器
})
console.log('停止', isStop.value);
}
function openTk() {
deviceInformation.value.forEach((device, index) => {
wsActions.open(device.udid, index)
})
}
function resetTk() {
isStop.value = false;
deviceInformation.value.forEach((device, index) => {
resetApp(device.udid, index)
})
}
//监听所有手机是否有消息
function openMonitor(type) {
isStop.value = false;
deviceInformation.value.forEach((device, index) => {
wsActions.getmesNum(device.udid, index)
runType.value[index] = 'listen'
})
isShowMes.value = setInterval(() => {
deviceInformation.value.forEach((device, index) => {
wsActions.getmesNum(device.udid, index)
})
}, 10000)
}
//关闭监听
function cloesMonitor() {
deviceInformation.value.forEach((device, index) => {
runType.value[index] = ''
})
clearInterval(isShowMes.value)
isShowMes.value = ''
}
//一键养号
function parentNum() {
isStop.value = false;
deviceInformation.value.forEach((device, index) => {
runType.value[index] = 'like'
wsActions.isHost(device.udid, index)
})
}
function brushLive() {
isStop.value = false;
deviceInformation.value.forEach((device, index) => {
// runType.value[index] = 'brushLive'
wsActions.toLive(device.udid, index)
})
}
//确认多行文本框内容
function onDialogConfirm(result, type, index) {
console.log(result, type, index);
if (type == '评论') {
//index ==999 表示批量养号,输入完评论后 即可直接执行脚本
// if (index == 999) {
// getContentList().forEach((item, indexA) => {
// // textContentArr.value[indexA] = result;
// textContent.value[indexA] = result[getRandomNumber(result.length - 1)];
// })
// setContentList(result)
// console.log(getContentList())
// parentNum()
// //index==998是批量关注主播 输入完评论后 还需要输入私信内容
// } else
if (index == 998) {
textContentArr.value.forEach((item, indexA) => {
textContent.value[indexA] = result[getRandomNumber(result.length - 1)];
})
setContentList(result)
//打开私信弹窗
selectedDevice.value = 999;
dialogTitle.value = '私信';
setTimeout(() => {
showDialog.value = true;
}, 600)
} else {
setContentList(result)
textContent.value[index] = result[getRandomNumber(result.length - 1)];
}
} else if (type == '私信') {
//index ==999 表示全部
if (index == 999) {
textContentpriArr.value.forEach((item, indexA) => {
textContentpri.value[indexA] = result[getRandomNumber(result.length - 1)];
runType.value[indexA] = 'follow'
})
setContentpriList(result)
deviceInformation.value.forEach((device, indexB) => {
if (getHostList().length <= 0) return;
// LikesToLikesToLikes(device.udid, indexB)
wsActions.getmesNum(device.udid, indexB)
})
} else {
textContentpriArr.value[index] = result;
textContentpri.value[index] = result[getRandomNumber(result.length - 1)];
}
} else if (type == '主播ID') {
//index ==999 表示全部
if (index == 999) {
//分割数组 几台设备 分为几个数组
let hostListResult = [];
result.forEach((item, indexA) => {
hostListResult.push({ country: '', text: item, state: false })
})
setHostList(hostListResult)
//打开评论弹窗
selectedDevice.value = 998;
dialogTitle.value = '评论';
setTimeout(() => {
showDialog.value = true;
}, 600)
}
// else {
// hostIdContentArr.value[index] = result;
// hostIdContent.value[index] = result[0];
// deviceInformation.value.forEach((device, indexA) => {
// if (index == indexA) {
// LikesToLikesToLikes(device.udid, index)
// }
// })
// }
}
}
function getTranslation(list) {
list.forEach((item, index) => {
translationToChinese({ msg: item.text }).then(res => {
console.log(res);
chatList.value[index].text = res
})
})
}
function markFirstFalseAsTrue(hostList) {
const index = hostList.findIndex(item => item.state === false);
if (index !== -1) {
hostList[index].state = true;
setHostList(hostList)
return hostList[index]; // 可选:返回被修改的对象
}
return null; // 没有找到 false 的项
}
</script>
<style scoped lang="less">
@import '../static/css/video.less';
</style>