Moviepy: OSError on `get_frame(__some_existing_large_index__)

Created on 7 Sep 2019  路  7Comments  路  Source: Zulko/moviepy

Expected Behavior

> clip = VideoFileClip(str(video_path))
> clip.duration * clip.fps
252723.60000000003
> clip.get_frame(10000) # Should return 10000th frame

Actual Behavior

> clip = VideoFileClip(str(video_path))
> frame = clip.get_frame(0)   # works
> clip.duration * clip.fps
63229.799999999996    # The duration is '17min 34sec'
> clip.get_frame(63220) # Throws OSError even though the given frame 
                                       # number is  before the end of the video.
> clip.get_frame(6322)   # Throws OSError
> clip.get_frame(632)     # Works.

Here's the error message:

OSError: MoviePy error: failed to read the first frame of video file /app/data/streams/unravel1/unravel1_cropped.mp4. That might mean that the file is corrupted. That may also mean that you are using a deprecated version of FFMPEG. On Ubuntu/Debian for instance the version in the repos is deprecated. Please update to a recent version from the website.

Steps to Reproduce the Problem

Run the above code with the video: https://www.dropbox.com/s/27mie3v8kvo30fz/unravel16_cropped.mp4?dl=0

Specifications

  • Python Version: '3.6.8 (default, Jan 14 2019, 11:02:34) \n[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]'
  • Moviepy Version: '1.0.0'
  • Platform Name: Ubuntu
  • Platform Version: 16.04LTS. Linux 4f9e6923e339 4.15.0-58-generic
video

All 7 comments

Related bug: get_frame(i) in loop does not read frames in order

Setup

import math
import numpy as np

clip = VideoFileClip(str(video_path))
num_frames = math.floor(clip.duration * clip.fps)

clip_array = np.zeros([num_frames, *clip.get_frame(0).shape], dtype=np.uint8)
print(f"clip_array is {np.prod(clip_array.shape)} bytes")

for i in range(math.floor(clip.duration * clip.fps)):
    clip_array[i,:,:,:] += clip.get_frame(i)

# Plot frames
j = 0

while True:
    plt.imshow(clip_array[j,:,:,:])
    print(j); j += 1
    plt.pause(0.05)

Expected Behavior

The frames should be plotted in order.

Actual Behavior

The frames are random. The array actually does not contain the same data as the frames. It lacks a lot of frames and in the latter part of the array, it contains just pitch black images.

.get_frame's input is seconds, not frame no.

I use this:

vid.get_frame((n / (vid.duration * vid.fps)) * vid.duration)
vid.get_frame(n / vid.fps)

@SuperShinyEyes Did the above info help you resolve your problem?

@keikoro Let me try tonight. Have to dig my old Ubuntu laptop.

I think that this is probably fixed in #1220, released in v2.0.0.dev2 (install with pip using --pre).

@billop was correct:

.get_frame's input is seconds, not frame no.

I use this:

vid.get_frame((n / (vid.duration * vid.fps)) * vid.duration)
vid.get_frame(n / vid.fps)

Tested on

  • macOS 10.15.6
  • Python 3.8
  • moviepy v1.0.3

@tburrows13 v2.0.0.dev2 has the same behaviour as v1.0.3.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Swiffers picture Swiffers  路  4Comments

TowelDude picture TowelDude  路  3Comments

Gicehajunior picture Gicehajunior  路  3Comments

Netherdrake picture Netherdrake  路  5Comments

tburrows13 picture tburrows13  路  3Comments