Python CV2不写视频

时间:2020-03-26 14:44:59

标签: python opencv cv2

嗨,我正尝试将长视频分解为较小的视频。我得到了一些互联网代码,但是当我运行它时却没有编写视频,我的代码有什么问题? 我没有任何错误。

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

2 个答案:

答案 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