Home > Blockchain >  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

Time:02-12

Idea: Get duration of all videos in a directory.

Problem: I want to output the duration of all videos in a directory but i get an error and this is my code:

This is original code 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)

What should I do?

Output:

[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:[email protected]] 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:[email protected]] 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:[email protected]] 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

CodePudding user response:

There seems to be some confused code in this line:

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

You glob the contents of the directory you entered in the variable w, convert that list to a string, print that string to standard output and then assign None to b, because print writes its arguments to standard output (or some other stream) and doesn't return anything.

It has already been pointed out in the comments that calling print in this way won't do what you want here. The first step would therefore be to get rid of it:

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

However that's not enough, because b won't be a filename, it will be the result of converting a list of filenames to a string. Attempting to open a file whose name is the value of b will still fail.

glob.glob returns a list, with each item in the list being a file that matched the pattern given. You need to loop through this list and then run the rest of your code once for each item in the list:

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

Each time through the loop, b should be the name of one of the files in the directory you entered.

Finally, in case cv2 can't read the FPS for a video file for whatever reason, I would recommend not attempting to calculate the duration of the video. Replace the code at the bottom of your loop with something like the following:

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