I am trying to use a pretrained CNN model for a project and some of the included code is having issues on my machine. Windows 10, git version 2.28.0.windows.1, Python 3.9.0
This code hails from https://github.com/zhoubolei/moments_models/tree/v2
output = subprocess.Popen(['ffmpeg', '-i', video_file], stderr=subprocess.PIPE, shell=True).communicate()
# Search and parse 'Duration: 00:05:24.13,' from ffmpeg stderr.
re_duration = re.compile(r'Duration: (.*?)\.')
duration = re_duration.search(str(output[1])).groups()[0]
I get the following traceback:
Traceback (most recent call last):
File "C:\Users\gradx\PycharmProjects\final\moments_models\test_video.py", line 62, in <module>
frames = extract_frames(args.video_file, args.num_segments)
File "C:\Users\gradx\PycharmProjects\final\moments_models\utils.py", line 21, in extract_frames
duration = re_duration.search(str(output[1])).groups()[0]
AttributeError: 'NoneType' object has no attribute 'groups'
Essentially the goal is to collect the run time of the input video file from some string Popen and re.complile() produce. This is not my code so I can't say why this method is used, but also can't suggest a different one. I've tried modifying the regular expression passed to re.compile() because I realize that could return None if nothing is found, but this hasn't helped.
Any support is appreciated.
Edit: Turns out the issue was that ffmpeg was missing.
The main problem of your code
You are searching for a pattern and trying to get its groups even before checking if the search returned something.
# As the code is returning only the errors (stderr=subprocess.PIPE)
# it is better to create a variable called error instead of output:
_, error = subprocess.Popen(['ffmpeg', '-i', video_file], stderr=subprocess.PIPE, shell=True).communicate()
# Lets check if the execution returned some error
if error:
print(f"Omg some error occurred: {str(error)}")
# Get the duration returned by the error
# error are bytes, so we need to decode it
re_duration = re.search(r'Duration: (.*?)\.', error.decode())
# if the search by duration returned something
# then we are taking the group 1 (00:05:24)
if re_duration:
re_duration = re_duration.group(1)
print(re_duration)
# 00:05:24
We are assuming that Duration...
is being returned when some error happen, but if it is returned by the success output, then you must invert the variables and add a change to your subprocess:
# Changing variable to output and changing the return to stdout (successful return)
output, _ = subprocess.Popen(['ffmpeg', '-i', video_file], stdout=subprocess.PIPE, shell=True).communicate()