嗨,我正尝试将长视频分解为较小的视频。我得到了一些互联网代码,但是当我运行它时却没有编写视频,我的代码有什么问题? 我没有任何错误。
import cv2
count = 0
if __name__ == '__main__':
vidPath = 'VideoNietBewerkt.mp4'
shotsPath = '/videos/%d.avi' % count
segRange = [(0,1000),(1000,2000),(2000,3000)] # a list of starting/ending frame indices pairs
cap = cv2.VideoCapture(vidPath)
fps = int(cap.get(cv2.CAP_PROP_FPS))
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = int(cv2.VideoWriter_fourcc('X','V','I','D')) # XVID codecs
for idx,(begFidx,endFidx) in enumerate(segRange):
writer = cv2.VideoWriter(shotsPath,fourcc,fps,size)
cap.set(cv2.CAP_PROP_POS_FRAMES,begFidx)
ret = True # has frame returned
while(cap.isOpened() and ret and writer.isOpened()):
ret, frame = cap.read()
frame_number = cap.get(cv2.CAP_PROP_POS_FRAMES) - 1
if frame_number < endFidx:
writer.write(frame)
else:
break
writer.release()
count += 1
答案 0 :(得分:0)
似乎编解码器(至少对我来说)和输出文件名存在问题,该文件名不会在循环外更新。
我为在计算机上工作进行了一些更改,请尝试看一小段电影,代码本身几乎没有注释。
这对我有用:
import cv2
vidPath = 'movie.mp4'
segRange = [(0,30),(30,60),(60,90)] # <-- to fit my sample movie
cap = cv2.VideoCapture(vidPath)
fps = int(cap.get(cv2.CAP_PROP_FPS))
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = int(cv2.VideoWriter_fourcc(*'jpeg')) # <-- I had to change the codec
for idx,(begFidx,endFidx) in enumerate(segRange):
shotsPath = f'movie_{str(idx)}.avi' # <-- update filename here, use idx for naming the output file
print(f'saving file: {shotsPath}')
writer = cv2.VideoWriter() # <-- instantiate the writer this way
writer.open(shotsPath, fourcc, fps, size) # <-- open the writer
cap.set(cv2.CAP_PROP_POS_FRAMES, begFidx)
while(cap.isOpened() and writer.isOpened()): # removed and ret
ret, frame = cap.read()
frame_number = cap.get(cv2.CAP_PROP_POS_FRAMES) - 1
if frame_number < endFidx:
writer.write(frame)
else:
break
writer.release()
cap.release()
答案 1 :(得分:0)
问题是我没有关闭cap变量,而是通过将所有内容放入for循环中来解决此问题
import cv2
vidPath = 'VideoNietBewerkt.mp4'
segRange = [(0,5000),(5000,50000),(50000,100400)] # <-- to fit my sample movie
for idx,(begFidx,endFidx) in enumerate(segRange):
cap = cv2.VideoCapture(vidPath) # <---- Open Cap
fps = int(cap.get(cv2.CAP_PROP_FPS))
size = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = int(cv2.VideoWriter_fourcc(*'jpeg'))
shotsPath = f'movie_{str(idx)}.avi' # <-- use idx for naming the output file
print(f'saving file: {shotsPath}')
writer = cv2.VideoWriter() # <-- instantiate the writer this way
writer.open(shotsPath, fourcc, fps, size) # <-- open the writer
cap.set(cv2.CAP_PROP_POS_FRAMES, begFidx)
while(cap.isOpened() and writer.isOpened()): # removed and ret
ret, frame = cap.read()
frame_number = cap.get(cv2.CAP_PROP_POS_FRAMES) - 1
if frame_number < endFidx:
writer.write(frame)
else:
break
writer.release()
cap.release() #<--- Closed Cap