Zulko / moviepy

Video editing with Python
https://zulko.github.io/moviepy/
MIT License
12.49k stars 1.56k forks source link

Is there one potential bug in FFMPEG_READER? #546

Closed duguyue100 closed 7 years ago

duguyue100 commented 7 years ago

Hi,

I'm using moviepy to read my video, using FFMPEG_VideoReader. As I'm reading a large volume of videos, I start to get this warning message:

Warning: in file /to/path/dataset/UCF-101-split/train/UnevenBars/v_UnevenBars_g20_c03.avi, 230400 bytes wanted but 0 bytes read,at frame 91/101, at time 3.64/4.00 sec. Using the last valid frame instead.

And then I tested my load frame function, it appears fine if I load the same video. I'm reading UCF-101 where there are about 13,000 videos for training a neural network. This really bug me because I don't see the reason why this is happening.

Here I attached my entire video loading function:

def load_video(path, grayscale=False, target_size=None,
               n_frames=None, data_format=None):
    """Load Video."""
    if data_format is None:
        data_format = K.image_data_format()
    if data_format not in {'channels_first', 'channels_last'}:
        raise ValueError('Unknown data_format: ', data_format)

    vid_container = FFMPEG_VideoReader(path)
    # calculate how many frames skipped
    skip_frames = vid_container.nframes // n_frames
    frames = []
    for i in xrange(n_frames):
        frame_t = vid_container.read_frame()
        frame_t = util.img_as_float(frame_t)

        # gray scale
        if grayscale:
            if frame_t.ndim == 3:
                frame_t = color.rgb2gray(frame_t)

        # resize
        if target_size:
            frame_t = transform.resize(frame_t, target_size)
        # skip frames
        vid_container.skip_frames(skip_frames)
        frames.append(frame_t)

    vid_container.close()

    # make sure it's n_frames
    assert len(frames) == n_frames

    frames = np.asarray(frames, dtype=np.float32)
    # match data format
    if len(frames.shape) == 4:
        if data_format == 'channels_first':
            frames = frames.transpose(0, 3, 1, 2)
    elif len(frames.shape) == 3:
        if data_format == 'channels_first':
            frames = frames.reshape(
                (frames.shape[0], 1, frames.shape[1], frames.shape[2]))
        else:
            frames = frames.reshape(
                (frames.shape[0], frames.shape[1], frames.shape[2], 1))
    else:
        raise ValueError('Unsupported image shape: ', frames.shape)

    return frames

Regards, Yuhuang.

tburrows13 commented 7 years ago

Is this with the latest version? Run pip3 install moviepy --upgrade to get the latest (or just pip install... for python 2).

duguyue100 commented 7 years ago

Thanks for the fast reply, I'm using python 2, as the latest release is just one day ago.. my current version is 0.2.3.1 By the way, here is my FFMPEG info:

ffmpeg version 2.8.11-0ubuntu0.16.04.1 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
  configuration: --prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
tburrows13 commented 7 years ago

Can you try with 0.2.3.2? I doubt it'll have changed, but you might as well?

duguyue100 commented 7 years ago

@Gloin1313 False alarm, I think the reason is simply because I overshot.

But there is one thing that is missing from the ffmpeg_reader, in read_frame() function, self.pos is not updated: https://github.com/Zulko/moviepy/blob/master/moviepy/video/io/ffmpeg_reader.py#L118

Shouldn't it be updated after reading a frame successfully?

tburrows13 commented 7 years ago

@duguyue100 Do you want to open a new issue for that?

duguyue100 commented 7 years ago

@Gloin1313 Emm... I'm handling it externally by manually adding 1 after calling read_frame(). So I'm good for now. But you or I can reopen this one if you feel this missing pos update is actually a bug.