0

I'm quite new to pyqt. So please forgive any misconcepts I might have.

I have trouble to load video directly to QMovie using: __init__ (self, QString fileName, ...) QMovie itself seems quite picky when it comes to supporting (decoding) Video formats.

This is why I want to decode the VideoFiles using FFMPEG, store the frames into a QIODevice and feed the device to QMovie using: __init__ (self, QIODevice device, ...)

This code uses FFMPEG to decode a Video file and stores the first 20 frames into a QIODevice stream as JPGs. This QIODevice is fed to the QMovie.

Great! the QMovie plays at full speed... But.. only once ... and the QMovie.frameCount() returns just 1 frame instead of 20... (when queried before QMovie.start())

Using PyQt4, imageio, numpy

print('>> FFMPEG Loading file : '+videoFile)

# Use FFMPEG to decode Video through imageio
self.vid=imageio.get_reader(str(videoFile),  'ffmpeg')

# Init QIODevice
byte_array = QtCore.QByteArray()
self.buf = QtCore.QBuffer()
self.movie= QtGui.QMovie(parent)

# Populate 20 Frames Stream 
i=0
self.buf.open(QtCore.QIODevice.Append)

#Sample 20 Frames from videoFile
while i<20:
    # decode / read to rgb24 Frame
    npArray_RGB888 = self.vid.get_data(i).astype(np.uint8)

    # Actually 'append' the Frame data to the Stream as JPG
    npArray_RGB888.save(self.buf, 'JPG')

    #print(' == == '+str(self.buf.data().size()))
    #print(' == == '+str(buf.data()))            

    i+=1

# Close the Stream 
self.buf.close()     

# Load the QIODecvice buffer in QMovie   
# self.movie.setFileName(videoFile) # To decode with QMovie directly
self.movie = QtGui.QMovie(self.buf, 'jpg', self)

print('>>>   FrameCount : '+str(self.movie.frameCount()))

self.movie.start()

Why is the framecount 1 instead of 20? What am I doing wrong?

Is there a more direct way to store FFMPEG result data into QIODevice? Prehaps loading the videoFile at once into the QIODevice instead of each frame individually?

Many thanks in advance.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
ljilekor
  • 31
  • 2
  • Are you sure you understand what the `QMovie` class is intended for? I suggest you read the [detailed description](https://doc.qt.io/qt-4.8/qmovie.html#details) more carefully. – ekhumoro Mar 02 '17 at 23:50
  • I think so... What do you mean exactly? When the `__init__ (self, QString fileName, ...)` works (for me only with GIFs), it does EXACTLY, perfectomundo what I need. I need more than simple playback.I must be able to jump to any frame at any time, browse the frames forward/backwards, change speed etc. I could write everything myself, decoding / reading in separate threads etc... Dynamically caching frames underneath the mousepointer on a sliderbar before it gets clicked, ... It seems to me that QMovie handles all this very stuff neatly. – ljilekor Mar 03 '17 at 00:22
  • I cannot put it any more clearly than what is already written there. – ekhumoro Mar 03 '17 at 00:51
  • QMovie does exactly what I need when initialized with a filepath. But it plays only 2% of the vidéo formats. You can decode videos yourself and initialize a QMovie with a QIODevice. 99% there before hitting a wall... Motivation @ 0%. – ljilekor Mar 08 '17 at 17:46
  • So you're just going to stubbornly continue trying to use a class which is clearly not designed for displaying video content. No wonder your motivation is at zero percent ... – ekhumoro Mar 08 '17 at 17:52
  • What should I use? Its called qmovie and does what I need. http://stackoverflow.com/questions/27214178/load-gif-into-qmovie-object-from-data-no-file – ljilekor Mar 08 '17 at 17:59
  • An animated gif is not a video. Read the article I linked to in my first comment. And by "read", I mean more than just skimming the first sentence. – ekhumoro Mar 08 '17 at 18:08
  • I read it 10 times trying to understand what you mean. Is flipping QPixmap's the sollution? Using phonon? I need to make a videoplayer for animators (finetuning lipsync etc ) where you can scrub through etc. Browsing / synching audio is no problem. – ljilekor Mar 08 '17 at 18:17
  • The `QMovie` class only displays images, not videos: see [QMovie.supportedFormats](https://doc.qt.io/qt-4.8/qmovie.html#supportedFormats). Loading an image from an `QIODevice`, is like (in python terms) passing in a file-object rather than a path. Either way, you need to supply data from an *animated image format* (such as a gif), rather than from a video format. – ekhumoro Mar 08 '17 at 18:33
  • PS: if you can upgrade to PyQt5, the QtMultimedia module has all the functionality you need (see: [Working with Low Level Video Frames](https://doc.qt.io/qt-5/videooverview.html#working-with-low-level-video-frames)). – ekhumoro Mar 08 '17 at 19:09
  • Thx. QMovie is a quite misleading name though – ljilekor Mar 08 '17 at 20:29

0 Answers0