☰
基于YOLOv5的AI自瞄系统:目标检测、坐标换算与鼠标控制全解析
2026/10/11 14:35:03 网站建设 项目流程

简介:这是一套基于YOLOv5二次开发、面向所有FPS游戏的AI自瞄源码工程,适合人工智能、自动化、电子信息等专业的学生、教师或相关从业者用于毕业设计、课程设计或项目初期验证。项目在保留原YOLOv5目录结构与用法的同时加入GUI交互界面,采用常见的罗技鼠标驱动,环境配置完成后可直接运行主程序;压缩包共162个文件、大小38.68MB,以Python源码、YAML配置、动态库、模型权重、Markdown文档为主,另含容器化部署与脚本文件,兼顾开发、部署与二次修改。已有466人学习下载,资料包含详细文档和全部源码,项目获导师认可、答辩评分95分,代码经过运行测试,可按需调整参数或替换模型,适用性较强。无论是作为高分项目参考,还是作为深度学习目标检测与游戏交互结合的入门案例,这套资料都能提供较为完整的实现思路与调试依据。

1. 基于yolov5的ai自瞄:先看清它解决什么,适合谁

很多人看到“基于yolov5的ai自瞄,适用于所有fps游戏源码+详细文档+全部资料+高分项目.zip”这种压缩包,第一反应是解压就能一键起飞。但实际拆过几份同类项目后,我劝你先冷静:标题里的“所有fps游戏”是最容易让人翻车的宣传语,不同游戏的分辨率、HUD、角色模型、队友颜色,都会让同一个yolov5模型输出完全不同的结果。这个项目的本质是三件事:用yolov5识别游戏画面里的人物,把检测框中心换算成屏幕瞄准点,再通过程序移动鼠标。它解决的是“看到目标并锁过去”的自动化问题,适合想研究目标检测落地、游戏AI自动化和测试脚本的开发者,不适合指望下载即完美的人。下面我把链路拆开讲,并给出一套能照着复现的最小方案。

2. 拆掉自瞄黑匣子:为什么yolov5只是中间一环,还有三个硬骨头

这类源码包看起来全是魔法,其实内部是四段链路的串联,任一环节出问题,准星就会飘。很多新手把注意力全放在yolov5模型上,却发现模型跑通了还是锁不准,原因就在前后环节。

2.1 四段链路:画面采集、目标检测、坐标换算和鼠标控制

常见做法是把实时系统拆成四个独立模块:屏幕采集、目标检测、坐标换算、鼠标控制。屏幕采集负责从显卡或系统帧缓冲里拿到当前画面;yolov5只做目标检测,输出若干个矩形框;坐标换算负责把框中心变成屏幕上的偏移量;最后的鼠标控制模块把这个偏移量转成鼠标移动指令。四个模块之间用队列或共享变量通信,这样调试时可以单独替换任意一段。

先从屏幕采集说起。Windows下常见方案有三种:GDI抓屏、DXGI桌面复制、直接读取显示内存。我一般用dxcam,它基于DXGI输出复制,延迟比PIL.ImageGrab低得多。很多打包项目为了省事,用mss或ImageGrab,结果模型推理只要20毫秒,抓帧却要50毫秒,整体延迟反而下不来。dxcam还支持指定output_idx,在多显示器环境下能选对显示器,这是自瞄项目能不能通用的前提。

目标检测之后的坐标换算也有讲究。yolov5返回的x1、y1、x2、y2坐标会自动映射回输入图像的原始分辨率,所以只要dxcam抓到的帧分辨率就是屏幕分辨率,那么框中心就能直接当屏幕像素坐标用。但如果你把屏幕采集区域裁成一部分,或者用了scale缩放,就必须按比例换算,否则就会出现“模型框对了,鼠标却移到一边”的怪现象。

最后是鼠标控制。这部分是自瞄里合规风险最高的地方,也是反作弊重点盯的区域。常见的简单做法是调用系统SendInput发送相对移动;复杂一些的会用独立USB HID设备模拟物理鼠标,延迟高但更难被特征检测。我只建议在离线测试和游戏官方允许的AI练习场景下做研究,不要拿它去真人排位。下面给一个模块间传递数据的统一结构,方便后续代码对接。

# 用统一结构传递每帧检测结果,画面采集和鼠标控制都只认这个类 class FrameResult: def __init__(self, frame_id, dets=None): self.frame_id = frame_id self.dets = dets or [] # 每个元素是 (x1, y1, x2, y2, conf, cls) def center(self, idx=0): x1, y1, x2, y2 = self.dets[idx][:4] return ((x1 + x2) / 2, (y1 + y2) / 2)

这里把检测框封装成FrameResult,调试时可以把每帧dets序列化成json回放,方便排查坐标问题。frame_id用来判断是不是拿到了最新帧,避免处理堆积的旧帧。这个结构虽然简单,但能避免你在四个模块之间来回改参数。

2.2 为什么选yolov5而不是yolov8或传统视觉

首先说传统视觉。很多老项目用颜色阈值识别敌人头顶血条,或者用Haar检测角色轮廓。这类方法在干净背景下勉强能用,一旦地图里出现相似颜色的物件、光影变化,误检率会高到没法看。所以现在这类源码包几乎都换成了深度学习目标检测。

其次说yolov8。yolov8确实在COCO上的精度更高,C2f结构比原版C3更好,但自瞄场景的瓶颈往往不在模型那零点几的mAP。yolov5的生态更成熟,导出ONNX、TensorRT的教程一抓一大把,很多打包项目的源码也都是围绕yolov5写的,直接换yolov8需要改数据加载、改锚点、改导出脚本,收益不大。如果你看yolov5网络结构图,会发现它的SPPF模块扩大了感受野,CSP结构在小目标上表现很稳,这对游戏里中远距离的小人物很关键。所以不是yolov5最好,而是它在“快速落地、资料多、改造成本低”这三个维度上最平衡。

还有一个原因是模型体量可选。yolov5s只有大概1400万参数,一张中端显卡上用半精度推理能跑到几十毫秒;yolov5l更准但延迟翻倍。自瞄要的是低延迟下的“够用”,不是“极限精度”,所以yolov5s/yolov5m通常就够了。

2.3 视觉自瞄 vs 读内存自瞄:标题项目为什么走检测路线

读内存方案是另一条路:通过读取游戏进程内存里的玩家坐标矩阵,直接算出准星要转多少度。优点是延迟极低、不需要每帧做图像识别,瞄准精度很高;缺点是必须针对每个游戏逆向数据结构,游戏版本一更新就得重写,而且进程注入和内存读取本身就是反作弊重点扫描对象,风险不是一般大。

视觉自瞄走的是“硬挂在画面上”的路线,不碰游戏进程内存,所以对游戏版本的依赖相对低。同样是换游戏,视觉方案只需要换一套训练数据和模型权重,代码链路可以复用。这就是标题里“适用于所有fps游戏”的真实含义:不是同一个模型通吃所有游戏,而是“视觉自瞄这套链路可以移植到所有FPS游戏”,前提是你为每个游戏准备对应的目标检测数据。看这类“高分项目.zip”时,先看它的文档里有没有强调这一点。如果连自己的数据集都没有,那它大概率放了一个COCO预训练模型,效果不用抱太高期待。

3. 用yolov5训练自己的fps目标检测模型:从抽帧标注到实时推理

这一章是全文最核心的可复现部分。我按“准备数据 → 训练模型 → 实时推理 → 坐标换算”四步走,每一步都会给可以直接改的命令和代码。注意,不要跳过数据集准备直接拿权重去跑。

3.1 准备数据集:从游戏录像抽帧并标注人物和头部

先录制一段至少5分钟的游戏视频,覆盖出生点、交火区、远视角和近视角,要尽量包含不同角色皮肤和地图光影。不要只在训练地图录,后面换图很容易翻车。录好后用ffmpeg均匀抽帧,我常用每秒2帧,太多的话标注工作量会爆炸。

# 每秒钟抽2帧,并把尺寸缩到1280,减少标注工作量 ffmpeg -i gameplay.mp4 -vf "fps=2,scale=1280:-1" -q:v 2 \ -start_number 0 ./frames/img_%05d.jpg

参数说明:fps=2是每秒抽两帧,scale=1280:-1表示宽度缩到1280,高度按比例缩放。这样比原始1920x1080图像小,标注时眼睛不容易累。q:v 2是高质量jpeg,画质太差会影响标注准确性。

然后处理HUD遮挡。大多数FPS游戏底部有武器栏、地图、血量条,这些区域里的血条和小地图容易干扰标注。我一般先用ffmpeg裁掉顶部和底部的固定UI区域,再把剩余画面用于标注:

# 裁掉上下HUD,只保留中间交火区域,再抽帧 ffmpeg -i gameplay.mp4 -filter:v "crop=1280:720:0:180,fps=2" \ -q:v 2 ./frames/frame_%05d.jpg

标注工具用LabelImg或者X-AnyLabeling。类别我建议设两个:player和head。player框全身,head框头部。如果你能稳定标出头部,后处理可以直接用head框的中心做瞄准点,精度远高于全身框取上部。如果标不了头部,就只标player,然后在全身框上部约35%位置取瞄准点。

标注数量上,每类至少1000个实例,越多越好。通用真实目标检测用COCO做预训练,但游戏角色是合成图像,纹理、边缘和真实人差别很大,至少要训练几十轮才能收敛。

3.2 训练自己的yolov5模型:数据配置、关键超参数和训练命令

数据目录建议放在yolov5仓库同级:

datasets/game/ images/train/*.jpg images/val/*.jpg labels/train/*.txt labels/val/*.txt

label是YOLO格式的txt,每行是“class cx cy w h”,坐标都是归一化到0到1之间的比例值。LabelImg导出时选YOLO格式就行。然后建一个数据配置文件:

# game.yaml train: datasets/game/images/train val: datasets/game/images/val nc: 2 names: ['player', 'head']

train和val给的是图片目录,不是标签目录,yolov5会自己去找同名txt。nc是类别数2,names顺序必须和标注时一致。训练命令用下面的模板,我一般会先把数据缓存到内存,避免小磁盘拖慢训练:

# 用yolov5s预训练权重做迁移学习,100轮起步 python train.py --data game.yaml --weights yolov5s.pt \ --img 640 --batch 16 --epochs 100 \ --hyp data/hyps/hyp.scratch-low.yaml \ --cache --device 0 --workers 4

参数含义:--img 640是模型输入分辨率,游戏画面里远程目标比较小,如果显存够可以试1280,但训练和推理都会变慢;--hyp指定超参数文件,注意不是所有扩展都要拉满。游戏画面和真实世界的颜色分布很不同,yolov5默认超参里的mixup、hsv增强太强会让模型学到奇怪的颜色扰动,我通常会把mixup调到0,hsv_v从0.4降到0.2。训练结束后看runs/train/exp/weights/best.pt,这是验证集上最优的权重。

3.3 实时屏幕推理:dxcam抓帧 + torch.hub加载模型

推理部分直接用yolov5自带的torch.hub接口,省去自己写预处理和后处理。屏幕捕获用dxcam,它拿的是GPU表面的最新帧,比ImageGrab快很多。下面是完整循环:

import cv2 import torch import dxcam # source='local' 表示用本地yolov5仓库,不要联网下载 model = torch.hub.load('yolov5', 'custom', path='best.pt', source='local') model.conf = 0.45 # 置信度阈值,先按0.45起步 model.iou = 0.5 # NMS的IoU阈值,目标重叠大时降低到0.4 model.classes = [0, 1] # 只看player和head camera = dxcam.create() # 默认主显示器 camera.start(target_fps=120, video_mode=True) # 视频模式提高帧率 while True: frame = camera.get_latest_frame() # 只拿最新帧,不排队 if frame is None: continue results = model(frame, size=640) # size要和训练尽量一致 dets = results.xyxy[0].cpu().numpy() # x1,y1,x2,y2,conf,cls for x1, y1, x2, y2, conf, cls in dets: cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) cv2.imshow('preview', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break camera.stop() cv2.destroyAllWindows()

这段代码的关键在camera.get_latest_frame()。很多从网上抄来的脚本用camera.grab()拿帧,它会持续返回队列里的画面,一旦模型推理变慢,队列会堆积,你拿到的其实是一秒前的画面,自瞄自然就跟不上。video_mode=True会让dxcam内部维护一个高帧率帧缓存,get_latest_frame每次都返回最近的那一帧。torch.hub.load里的source参数很重要,不写local的话每次启动都可能去访问网络,离线环境会卡住。

3.4 把检测框换成瞄准点:坐标转换和鼠标移动示例

拿到检测框之后,要把框变成鼠标偏移量。如果dxcam抓的就是全屏分辨率的画面,yolov5返回的坐标就是屏幕像素坐标。下面这个函数计算瞄准点:

def get_aim_target(detections, screen_w, screen_h, head_bias=0.35): if len(detections) == 0: return None # detections已按置信度降序,取第一个作为目标 x1, y1, x2, y2, conf, cls = detections[0] cx = (x1 + x2) / 2.0 # 如果只有一个全身框,取框上部三分之一作为头部参考点 cy = y1 + (y2 - y1) * head_bias # 相对屏幕中心的偏移 dx = cx - screen_w / 2.0 dy = cy - screen_h / 2.0 return dx, dy

head_bias=0.35的经验值适用于多数站立角色,但如果敌人蹲下或趴下,这个系数会偏。所以更稳的做法是单独检测head类,一旦检测到head框就直接用head的中心。屏幕分辨率screen_w、screen_h需要和dxcam实际输出严格一致,如果你把分辨率设置错了,坐标换算会整体偏移。

鼠标移动这段我只做演示,并且再次强调:不要把这个程序跑在在线游戏排位里,合规风险极高。

import ctypes # 仅演示用途:发送相对鼠标移动 # move_x和move_y来自get_aim_target的返回值,实际使用前要做鼠标灵敏度标定 ctypes.windll.user32.mouse_event(0x0001, int(dx), int(dy), 0, 0)

很多游戏会内置鼠标加速度,同样的dx在不同游戏里转过的角度不一样。你要是直接套用,准星要么过头要么不足。常见做法是先放进测试靶场,记录dx和实际准星位移的比值,做成一个灵敏度系数,而不是直接硬编码。

4. 自瞄落地避坑指南:检测框出来了,为什么还是翻车

模型训练好、推理链路也通了,但一接上鼠标就各种问题。我把最常见的四类翻车现象放在这里,每条都是“现象 → 原因 → 解决”的排查思路。这部分是我反复调这类项目的血泪经验。

4.1 总是锁不准:画面延迟和坐标滞后

现象:屏幕上检测框已经罩住敌人,但准星总落在敌人身后半个身位;敌人移动越快,偏差越大。很多人以为是模型框不准,其实框很准。

原因:从“敌人当前位置”到“鼠标执行移动”要经过抓帧、推理、鼠标移动三步,累计延迟可能超过80毫秒。敌人每秒跑5米的话,80毫秒就是你准星落后的根源。另外,如果用了Queue一帧一帧消费,队列里积压的旧帧会让延迟更高。

解决:抓帧用get_latest_frame而不是grab;推理模型导出成TensorRT;鼠标移动不要每帧都发,可以累积两次偏移后再移动。还可以对目标位置做外推,用上一帧和当前帧的位置差估计速度。下面这个外推片段可以接在前面dets后面:

# 一阶位置外推:用两帧之间的位移补一个提前量 prev_cx, prev_cy = prev_center cur_cx, cur_cy = current_center pred_x = cur_cx + (cur_cx - prev_cx) * 0.3 pred_y = cur_cy + (cur_cy - prev_cy) * 0.3

0.3是外推系数,系数越大补得越激进,也越容易过冲。如果敌人左右横跳,建议系数不要超过0.2。

4.2 掉帧卡顿:屏幕采集和模型推理的瓶颈

现象:游戏帧数从144掉到60,自瞄程序一跑,整个机器都卡。原因有两种:一是图像转换和模型推理都放在GPU上,和游戏渲染抢资源;二是dxcam在全屏多显示器场景下没指定output,导致额外的framebuffer拷贝。

解决:把模型推理分辨率降到416或320,检测框精度会下降,但FPS能上来;只截取屏幕中央区域,减少传输数据量;推理模型用半精度fp16或ONNX Runtime,避免占用过多GPU显存。dxcam创建时指定显示器编号:

# 指定输出接口,避免在双显示器时频繁切换 camera = dxcam.create(output_idx=0) camera.start(target_fps=120, video_mode=True, region=(0, 0, 1920, 1080))

region参数只采集左半屏,可以省一半带宽。这个做法在目标总是出现在准星附近时很有效。

4.3 换张地图误检率暴涨:训练集背景过拟合

现象:模型在自己训练的那张地图上很准,一换地图,把窗户、岩石阴影、远处模型错认成人,检测框乱飞。

原因:训练集里背景太单一,模型学到的是“训练地图的纹理+人物轮廓”的组合,而不是真正的人物结构。比如雪地地图里白色背景多,模型会把高亮的窗户框当成敌人。

解决:录制至少3张不同地图的视频,按比例混入训练集;把HUD区域裁掉再训练;把增强超参里的hsv_h、hsv_s打开一点,让模型不要依赖特定颜色。下面是我在hyp.game.yaml里常用的改动:

# 游戏场景增强建议 hsv_h: 0.014 hsv_s: 0.5 hsv_v: 0.4 mosaic: 1.0 mixup: 0.0

mosaic保持1.0,因为它在小目标上帮助很大;mixup设为0,因为两个游戏角色混叠出来的训练样本会让自瞄模型输出奇怪的框。改完超参后重新训练,才能让模型的泛化性上来。

4.4 多目标横跳:缺少跟踪导致瞄准点不稳定

现象:两个敌人靠近时,准星在两颗头之间反复横跳,甚至锁到背景目标。原因很简单:每一帧都取置信度最高的框,没把“这是否是同一个敌人”关联起来。

解决:做一个最简单的IOU匹配跟踪器,记录上一帧选中的框,如果当前帧有框和它IOU大于阈值,就继续用当前匹配的框;如果匹配不上,才切换到新的高置信目标。示例代码:

class IOUTracker: def __init__(self, iou_thresh=0.3): self.prev_box = None self.iou_thresh = iou_thresh self.id = -1 def iou(self, a, b): # 计算两个框的交并比 ... def update(self, dets): if self.prev_box is None or len(dets) == 0: self.prev_box = dets[0] if len(dets) else None return self.prev_box for det in dets: if self.iou(self.prev_box, det) > self.iou_thresh: self.prev_box = det return det # 没有匹配,切换最高置信度框 self.prev_box = dets[0] return self.prev_box

如果多人交战时仍会切目标,就把iou_thresh降到0.2,或者把置信度阈值提高到0.5,减少低质量框干扰。更复杂的方案是引入BoT-SORT,但在自瞄场景里,一个简单的IOU匹配就够稳住瞄准点了。

5. 从检测到“锁定”:参数调优、平滑算法与性能优化

这一章讲怎么把“能跑”变成“稳”。重点在置信度、IoU、平滑算法和部署优化,每一步都有自己的边界。

5.1 置信度、IoU和yolov5超参数怎么搭配

推理时的conf和iou直接影响自瞄手感。如果误检太多,鼠标会乱飘,调高conf到0.6;如果漏检太多,把conf降到0.3。自瞄不是安防,不需要追求完美mAP,只需要稳定锁定一个真实目标。我常用下面这组经验值:

参数推荐值场景说明
model.conf0.3 ~ 0.45远程小目标时用0.3,近战频繁时用0.45
model.iou0.4 ~ 0.5多人贴近时降到0.4,平常0.5
训练图尺寸640目标非常小再上1280,否则推理太慢
推理图尺寸416 ~ 640416最快,640更准

训练超参数也不能照搬COCO。游戏画面颜色相对固定,hsv_v增强太大容易破坏角色皮肤和衣服的辨识度。mosaic增强要保留,因为它能把小目标拼接到不同背景里,提升模型对远处敌人的检测能力。如果显存充足,把batch提到32,bn统计会更稳定。

5.2 平滑瞄准:一阶低通滤波和PID参数的经验值

检测框本身就有抖动,直接取每帧的目标中心移动鼠标,准星会像电钻一样抖。所以要有平滑层。最简单有效的是指数移动平均,也叫一阶低通滤波:

class SmoothAim: def __init__(self, alpha=0.3, deadzone=2.0): self.alpha = alpha # 平滑系数,越小越平滑但越迟钝 self.deadzone = deadzone self.x = None self.y = None def update(self, dx, dy): if self.x is None: self.x, self.y = dx, dy else: self.x = self.alpha * dx + (1 - self.alpha) * self.x self.y = self.alpha * dy + (1 - self.alpha) * self.y # 死区处理:偏移小于2像素就不移动 if abs(self.x) < self.deadzone and abs(self.y) < self.deadzone: return 0, 0 return self.x, self.y

alpha取0.3是我常用的起点。alpha越小,鼠标越稳,但跟不上突然出现的敌人;alpha越大,反应快,但容易颤抖。如果目标移动平滑,alpha取0.2;如果敌人喜欢急停急起,取0.4。

比一阶低通更进阶的是PID。我这里倒不推荐完整PID,自瞄用比例项就够,积分项会让准星冲过头,微分项会把检测框抖动的噪声放大。最多加一点微分用于目标速度补偿,但初始调试时先关掉。

5.3 性能调优:ONNX/TensorRT导出和量化部署

实时推理要跑到fps游戏的刷新率,纯PyTorch模型在CPU上基本没戏。常见做法是把best.pt导出成ONNX,再用ONNX Runtime或者TensorRT跑。yolov5自带导出脚本:

# 导出动态尺寸ONNX,方便不同分辨率推理 python export.py --weights best.pt --include onnx --opset 12 --dynamic

导出后用ONNX Runtime加载:

import onnxruntime as ort sess = ort.InferenceSession('best.onnx', providers=['CUDAExecutionProvider']) # 之后用sess.run做推理,输入shape是动态的

动态尺寸在批量变分辨率时很有用,但TensorRT对动态shape支持不够友好。如果固定用640输入,导出时去掉--dynamic,TensorRT引擎会稳定很多。推理帧率和显卡关系很大,我测试过yolov5s在RTX 3060上用fp16精度大概能跑到10毫秒级别,在CPU上则要100毫秒以上。

低功耗设备是另一个话题。树莓派4B跑yolov5s纯CPU只有几帧,基本没法实时;如果目标平台是RK3568这类带NPU的板子,需要把模型量化成int8并转成rknn格式。这里要注意,量化后精度会掉,尤其是游戏里中远距离的小人物,最好先验证mAP再决定。很多“源码+文档”项目里根本不提边缘部署,因为他们的代码只想在PC上跑。

5.4 效果验证:离线回放测精度,实时回放测延迟

被自瞄坑过多次后,我养成了一个习惯:先离线验证,再上实时验证。离线验证就是拿带标注的测试视频跑val.py,看mAP数值:

python val.py --data game.yaml --weights best.pt --verbose

重点关注mAP50,也就是目标和框重叠50%就算对的粗定位指标。自瞄不需要mAP50-95非常高,因为只要框住目标就能瞄准。mAP50如果低于0.8,先去补数据或调超参,别急着调鼠标。

离线验证之后,实时验证要测端到端延迟。最简单的测法是在屏幕上放一个白色方块,让程序检测它并立刻打印时间戳,再对比屏幕显示变化的时间。专业一点可以用光电二极管探针,但普通开发者用摄像头对着屏幕拍,也能量出大概延迟。我之前就遇到过模型mAP很高,但整体延迟超过150毫秒的情况,原因就在屏幕采集和鼠标移动之间的队列里。所以验证不能只看模型指标,要看“画面出现目标 → 鼠标偏移执行”的完整链路。

6. 这个方案值不值得投入:边界、局限和我的最后建议

这类“高分项目.zip”最多帮你省掉收集资料的时间,源码跑通只是起点,真正值钱的是你能否把数据准备、模型训练、实时链路、平滑调参这四个环节串起来。如果你是为了学目标检测,这个方向很值得投入一次,因为你把yolov5从训练到部署完整走过一遍,之后做任何视觉检测项目都会顺手很多。

但它也有很明显的边界。第一,不存在“所有fps游戏通用”的模型,每个游戏的渲染风格和角色模型都不同,换游戏就必须重新训练数据。第二,鼠标控制的硬件和游戏灵敏度差异很大,哪怕同一个yolov5模型,在两台不同鼠标的电脑上也要重调系数。第三,在线游戏里跑自瞄大概率违反用户协议,风险收益完全不成正比,我自己的做法是只把它留在离线视频回放和官方允许的AI训练场里。

最后给你一句实在话:不要一开始就追求完美瞄准,先搭一个“能跑、能看检测框、能计算偏移”的骨架,再一步步加平滑、跟踪和外推。每一步改动都留一份日志和回放视频,这样出了问题还有后悔药。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询