# videoManager **Repository Path**: maxuxu2000/videoManager ## Basic Information - **Project Name**: videoManager - **Description**: python-通过opencv打开视频的任意帧,判断视频的类型,然后通过键盘的键位来选择是删除,保留或待定 - **Primary Language**: Python - **License**: BSD-3-Clause - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-03-12 - **Last Updated**: 2022-06-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 1. # opencv && os -- 视频和文件处理 ## 1. 目的与需求 硬盘文件过多且杂乱,需要筛选后删除,因为有很多学习资料视频,所以把老旧的删除,同时给某些文件改名等操作 ## 2. 环境 python 环境 + opencv +os opencv是第三方库的所以需要单独下载 ```python pip install opencv-python ``` ## 3. 思路 通过 os 模块 操作文件(获取文件目录并打开),遍历所有的文件,并筛选出我要的文件类型(mp4,txt……),然后用for循环一个个打开让我判断是否需要,需要就按下键盘 `q` 跳过,按下 `d` 删除或是改名,按下 `s` 存入列表以便处理犹豫的特殊文件。因为有视频判断的需求,所有用到了 opencv 模块,可以打开视频并监听按键 ## 4. 步骤 ### 4.1 获取目录地址 ```python from asyncio.windows_events import NULL import os import cv2 import shutil # 遍历路径 把路径下的所有文件存储到列表 list # list = os.listdir('E:\onecloud\tddownload') #根路径写法 # 写在操作文件夹下,推荐 list = os.listdir('./') ``` ### 4.2 编写播放视频的方法 ```python def see_video(filename): cap = cv2.VideoCapture(filename) # 设置从第几帧开始播放,比如是开头还是中间或是结尾的,跳过开头前戏 cap.set(cv2.CAP_PROP_POS_FRAMES, 8000) # ret, frame = cap.read() while (1): ret, frame = cap.read() res = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5) target_Del = NULL cv2.imshow('frame', res) key = cv2.waitKey(1) if key & 0xFF == ord('q') or ret == False: cap.release() cv2.destroyAllWindows() break elif key & 0xFF == ord('d'): print("删除视频") target_Del = filename cap.release() cv2.destroyAllWindows() break elif key & 0xFF == ord('s'): lists.append(filename) cap.release() cv2.destroyAllWindows() break cv2.imshow('frame', res) os.rename(filename,f"{filename}==========") ``` > 技巧,如果监听多个按键,可能会失灵变卡,可能是 每次都调用 cv2.waitKey(1),可以赋值给一个变量,而不是每次遍历调用,非常耗费资源。 ### 4.3 文件遍历 ```python if __name__ == '__main__': for list_sam in list: try: test = os.listdir(f'./{list_sam}') for te in test: mp4 = te.endswith('mp4') avi = te.endswith('avi') # mp4=False # avi=False wmv = te.endswith('wmv') # print(ls) if mp4: # print(f"{te}文件是mp4") see_video(f"./{list_sam}/{te}",list_sam,test) elif avi: # print(f"{te}文件是avi") see_video(f"./{list_sam}/{te}",list_sam,test) elif wmv: see_video(f"./{list_sam}/{te}",list_sam,test) except: print(f"{list_sam}不是文件夹") ``` > 调用方法,传入三个参数: 路径,目标文件夹,目标文件 ### 4.4 完整代码 ```python import os from asyncio.windows_events import NULL import shutil import cv2 list = os.listdir('./') lists = [] def see_video(filepath,filesname,filename): cap = cv2.VideoCapture(filepath) cap.set(cv2.CAP_PROP_POS_FRAMES, 10000) # ret, frame = cap.read() while (1): ret, frame = cap.read() res = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5) target_Del = NULL cv2.imshow('frame', res) key = cv2.waitKey(1) if key & 0xFF == ord('q') or ret == False: cap.release() cv2.destroyAllWindows() break elif key & 0xFF == ord('d'): print("删除或修改视频") # target_Del = filename cap.release() cv2.destroyAllWindows() # 修改文件名 # os.rename(filepath,f"{filepath}==========") # 删除文件 # os.remove(filepath) # 删除上级文件夹 shutil.rmtree(filesname) break elif key & 0xFF == ord('s'): cap.release() cv2.destroyAllWindows() lists.append(filename,filesname) break cv2.imshow('frame', res) print(filesname,filename,filepath, lists) if __name__ == '__main__': for list_sam in list: try: test = os.listdir(f'./{list_sam}') for te in test: mp4 = te.endswith('mp4') avi = te.endswith('avi') # mp4=False # avi=False wmv = te.endswith('wmv') # print(ls) if mp4: # print(f"{te}文件是mp4") see_video(f"./{list_sam}/{te}",list_sam,test) elif avi: # print(f"{te}文件是avi") see_video(f"./{list_sam}/{te}",list_sam,test) elif wmv: see_video(f"./{list_sam}/{te}",list_sam,test) except: print(f"{list_sam}不是文件夹") ``` ## 5. 补充 * 因为删除文件后是无法直接从回收站里恢复的,所有之前思路是把文件改显而易见的名字事后处理,或者添加到一个了列表了我在一个个筛选。为了方便我直接把文件名改成了文件后缀夹“========”,导致文件打不开,所以要改回原来的名字,也就是删掉======,所以写了一个小demo,同理稍加改动就可以修改任意的文件名或后缀 > ```python > from fileinput import filename > import imp > import os > list = os.listdir('./') > for list_sam in list: > try: > test =os.listdir(f'./{list_sam}') > for te in test: > ls = te.endswith('mp4==========') > le = te.endswith('flv==========') > # print(ls) > if ls: > print(f"{te}文件是mp4") > # see_video(f"./test/{list_sam}/{te}") > res = te.split("==========")[0] > os.rename(f'./{list_sam}/{te}',f'./{list_sam}/{res}') > print("修改为:[ {} ]".format(res)) > elif le: > print("{} 文件是flv".format(te)) > res = te.split("==========")[0] > os.rename(f'./{list_sam}/{te}',f'./{list_sam}/{res}') > print("修改为:[ {} ]".format(res)) > except: > print("不是文件夹") > ``` * 或者为了小心起见你改了后缀,然后觉得好像没删错也不想在改回原来的文件名,所以还是直接删除,基于此情况写了小demo,删除所有后缀为MP4========的文件 > ```python > import os > from asyncio.windows_events import NULL > import shutil > import cv2 > list = os.listdir('./') > i =0 > if __name__ == '__main__': > for list_sam in list: > try: > test = os.listdir(f'./{list_sam}') > for te in test: > mp4 = te.endswith('mp4==========') > avi = te.endswith('avi==========') > # print(ls) > if mp4: > i = i + 1 > print(f"删除第{i}个:{te}") > shutil.rmtree(f'./{list_sam}') > > elif avi: > i = i + 1 > print(f"删除第{i}个:{te}") > shutil.rmtree(f'./{list_sam}') > i = i + 1 > except: > print(f"{list_sam}不是文件夹") > print("一共删除了{}个文件".format(i)) > ``` * 还有一种思路就是直接建好一个文件夹,把觉得有争议的想删除的视频移动到新建的文件夹里,直接筛选新建文件夹,有时间再写一个。应用场景其实很广泛,不就是给文件分类嘛,但是不是直接通过后缀,而是打开后由用户确定是否删除,或是给某些视频分类为欧美,大陆 等等。