求助:如何自动剪辑视频中出现"connection lost"的断连片段?
自动剔除含"Connection Lost"文本的游戏视频片段方案
方案1:FFmpeg + Tesseract OCR 半自动化流程
这个流程兼顾效率和操作性,比纯手动处理快很多:
- 提取关键帧:用FFmpeg每秒提取1帧,减少OCR处理量
先创建ffmpeg -i input.mp4 -vf "fps=1" frames/frame_%04d.pngframes文件夹,命令会把视频帧按序号存进去,帧序号对应视频秒数(因为fps=1)。 - 批量识别文本并标记异常时间:用批处理/Shell脚本遍历帧图片,调用Tesseract识别文本,记录出现"connection lost"的时间点。
Windows批处理示例:
运行后@echo off setlocal enabledelayedexpansion if not exist frames mkdir frames if exist bad_times.txt del bad_times.txt for %%f in (frames\*.png) do ( set "filename=%%~nf" set "frame_num=!filename:frame_=!" set /a "time=!frame_num!" tesseract "%%f" temp.txt >nul findstr /i "connection lost" temp.txt >nul if !errorlevel! equ 0 ( echo !time! >> bad_times.txt ) ) del temp.txtbad_times.txt会记录所有出现异常文本的秒数,后续可以手动整理成时间段(比如连续的秒数合并成[5-8秒])。 - 拼接正常片段:根据整理好的正常时间段,用FFmpeg的concat滤镜合并。比如正常区间是0-5秒、8-15秒、20-结束,命令如下:
ffmpeg -i input.mp4 -filter_complex ^ "[0:v][0:a]split=3[v0][v1][v2]; ^ [v0]trim=start=0:end=5,setpts=PTS-STARTPTS[v0out]; ^ [0:a]atrim=start=0:end=5,asetpts=PTS-STARTPTS[a0out]; ^ [v1]trim=start=8:end=15,setpts=PTS-STARTPTS[v1out]; ^ [0:a]atrim=start=8:end=15,asetpts=PTS-STARTPTS[a1out]; ^ [v2]trim=start=20,setpts=PTS-STARTPTS[v2out]; ^ [0:a]atrim=start=20,asetpts=PTS-STARTPTS[a2out]; ^ [v0out][a0out][v1out][a1out][v2out][a2out]concat=n=3:v=1:a=1[v][a]" ^ -map "[v]" -map "[a]" output.mp4
方案2:GUI工具+AutoHotkey脚本 零代码方案
适合完全不想碰命令行的用户,全程可视化操作:
- 安装LosslessCut(免费开源的视频剪切工具)和AutoHotkey,再装好Tesseract并添加到系统PATH。
- 用LosslessCut打开目标视频,然后运行下面的AutoHotkey脚本:
isMarking := false SetTimer, CheckForText, 1000 ; 每秒检查一次画面 CheckForText: { ; 截取LosslessCut窗口画面 WinActivate, ahk_exe LosslessCut.exe WinGetPos, X, Y, W, H, ahk_exe LosslessCut.exe Clipboard := "" Send, !{PrintScreen} ClipWait, 1 if ErrorLevel return ; 保存截图并识别文本 ImagePutFile("temp_shot.png", Clipboard) RunWait, tesseract temp_shot.png temp_output.txt,,Hide FileRead, textContent, temp_output.txt textContent := StrLower(textContent) ; 自动标记异常片段 if InStr(textContent, "connection lost") { if (!isMarking) { Send, ^+i ; 触发LosslessCut的"标记开始"快捷键 isMarking := true } } else { if (isMarking) { Send, ^+o ; 触发LosslessCut的"标记结束"快捷键 isMarking := false } } return } ImagePutFile(FileByRef, ClipboardAllByRef="") { ; 辅助函数:把剪贴板里的截图保存为文件 if (ClipboardAllByRef = "") ClipboardAllByRef := ClipboardAll FileDelete, %FileByRef% Clipboard := ClipboardAllByRef Send, ^v Sleep, 500 Send, ^s Sleep, 500 Send, %FileByRef%{Enter} Sleep, 500 Clipboard := ClipboardAllByRef } - 脚本会自动识别画面中的"connection lost"文本,在LosslessCut里标记异常片段。标记完成后,点击LosslessCut的"Cut out selected"按钮,就能导出剔除异常片段的干净视频。
方案3:简化版Python脚本(低代码)
用封装好的库减少代码复杂度,比纯OpenCV更容易调试:
- 先安装依赖:
注意要提前安装Tesseract本体,并且添加到系统环境变量PATH中。pip install moviepy pytesseract opencv-python - 运行下面的脚本,修改
video_path和output_path为你的文件路径:import moviepy.editor as mp import pytesseract import cv2 import numpy as np video_path = "input.mp4" output_path = "output.mp4" bad_intervals = [] current_bad_start = None check_interval = 2 # 每2帧检查一次,平衡速度和准确率 video = mp.VideoFileClip(video_path) fps = video.fps def process_frame(frame): nonlocal current_bad_start, bad_intervals # 预处理画面增强文本识别率:转灰度+阈值化 gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) _, threshold_frame = cv2.threshold(gray_frame, 120, 255, cv2.THRESH_BINARY_INV) # 识别文本 detected_text = pytesseract.image_to_string(threshold_frame).lower() # 记录异常时间段 current_time = video.current_frame / fps if "connection lost" in detected_text: if current_bad_start is None: current_bad_start = current_time else: if current_bad_start is not None: bad_intervals.append((current_bad_start, current_time)) current_bad_start = None # 遍历视频帧进行检查 video.iter_frames(fps=fps//check_interval, callback=process_frame) # 处理最后一个未闭合的异常区间 if current_bad_start is not None: bad_intervals.append((current_bad_start, video.duration)) # 生成正常时间段列表 good_intervals = [] prev_end = 0.0 for start, end in bad_intervals: if start > prev_end: good_intervals.append((prev_end, start)) prev_end = end if prev_end < video.duration: good_intervals.append((prev_end, video.duration)) # 拼接并导出干净视频 final_clips = [video.subclip(start, end) for start, end in good_intervals] final_video = mp.concatenate_videoclips(final_clips) final_video.write_videofile(output_path, codec="libx264", audio_codec="aac")
内容的提问来源于stack exchange,提问作者Yousif K Al Ameen 1
相关产品推荐
相关产品推荐

