ZeroDivisionError: float division by zero when i try show video durations in directory

ZeroDivisionError: float division by zero when i try show video durations in directory

思路:获取目录下所有视频的时长。

问题:我想输出目录中所有视频的持续时间,但出现错误,这是我的代码:

这是原始代码https://pastebin.com/xnpfwE55

from colorama import init
from colorama import Fore
import datetime
import glob
import cv2
init()

w = input(str(Fore.GREEN+"Type path to dir: ")) # path of directory
b = print(str(glob.glob(w+"*"))) # Adds a directory and reads files from there
print(b)
# create video capture object
data = cv2.VideoCapture(str(b))

# count the number of frames
frames = data.get(cv2.CAP_PROP_FRAME_COUNT)
fps = int(data.get(cv2.CAP_PROP_FPS))

# calculate dusration of the video
seconds = int(frames / fps)
video_time = str(datetime.timedelta(seconds=seconds))
print("duration in seconds:", seconds)
print("video time:", video_time)

我该怎么办?

输出:

[gooder@GOD ffmpeg]$ python untitled2.py 
Type path to dir: /home/gooder/Desktop/ffmpeg/videos/
['/home/gooder/Desktop/ffmpeg/videos/ou1t.mp4', '/home/gooder/Desktop/ffmpeg/videos/out.mp4', '/home/gooder/Desktop/ffmpeg/videos/Halloween.Kills.2021.DUB.HDRip.x264.mkv']
None
[ WARN:0@1.851] global /build/opencv/src/opencv-4.5.5/modules/videoio/src/cap_gstreamer.cpp (1127) open OpenCV | GStreamer warning: Error opening bin: no element "None"
[ WARN:0@1.851] global /build/opencv/src/opencv-4.5.5/modules/videoio/src/cap_gstreamer.cpp (862) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
[ERROR:0@2.770] global /build/opencv/src/opencv-4.5.5/modules/videoio/src/cap.cpp (164) open VIDEOIO(CV_IMAGES): raised OpenCV exception:

OpenCV(4.5.5) /build/opencv/src/opencv-4.5.5/modules/videoio/src/cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): None in function 'icvExtractPattern'


Traceback (most recent call last):
  File "/home/gooder/Desktop/ffmpeg/untitled2.py", line 19, in <module>
    seconds = int(frames / fps)
ZeroDivisionError: float division by zero

这一行似乎有一些混乱的代码:

b = print(str(glob.glob(w+"*"))) # Adds a directory and reads files from there

您将在变量 w 中输入的目录的内容全局化,将该列表转换为字符串,print 将该字符串输出到标准输出,然后将 None 分配给 b,因为 print 将其参数写入标准输出(或其他一些流)并且不 return 任何东西。

已经在评论中指出,以这种方式调用print不会做你想做的。因此,第一步是摆脱它:

b = str(glob.glob(w+"*")) # Adds a directory and reads files from there
print(b)

但这还不够,因为 b 不是文件名,而是将文件名列表转换为字符串的结果。尝试打开名称为 b 的文件仍然会失败。

glob.glob return 是一个列表,列表中的每一项都是与给定模式匹配的文件。您需要遍历此列表,然后 运行 对列表中的每个项目执行一次其余代码:

for b in glob.glob(w+"*"): # Adds a directory and reads files from there
    print(b)

    # create video capture object
    data = cv2.VideoCapture(b)

    # remaining lines also indented, but omitted here for brevity

每次循环,b 应该是您输入的目录中的文件之一的名称。

最后,如果 cv2 由于某种原因无法读取视频文件的 FPS,我建议不要尝试计算视频的持续时间。将循环底部的代码替换为如下内容:

    if fps == 0:
        print("Could not read an FPS value, unable to calculate duration of video")
    else:
        # calculate duration as normal...