Best way to handle multiple instances of ofVideoPlayer (OSX) (and ofxAVFVideoPlayer)

Hi, I am struggling with an app for an upcoming exhibition.

Code is here: http://pastebin.com/3TxyCD90

Everything I have tried so far turns out to be a new problem so I’m hoping someone more experienced might throw some light on it.

I have about 50 videos that the user will flick between using a remote control. It is like a simulation of a TV where you jump up and down through channels. Seems easy I thought.

When the app loads it looks in an XML file for the videos, then loads each one into a vector of ofVideoPlayers called “videoPlayers”. The big problem I am facing is that I am loading about 55 video files and they are mostly huge (about 300GB in total), so no surprise that after a while the app crashes as it can’t allocate any more RAM.

I have tried using a single instance of ofVideoPlayer and closing/opening the video files as they are requested. This deals with the RAM problem but as you can imagine this is really laggy because it can take a long time for loadMovie() to complete (and ofVideoPlayer doesn’t behave nicely when I repeatedly open and close movies).

I then tried the ofxAVFVideoPlayer plugin as I’m developing and running on 10.9. I think this might be a good route to take as it has the advantage of being much faster when calling loadMovie() so I could potentially remove the need for pre-loading all the videos. But when I use this I can’t figure out how to “wait” until isLoaded() is true before playing the video or using getDuration() etc.

Would really welcome any comments or suggestions. I feel I have looked at this too long and have gone blind!

Best wishes
Chris

Oh, I should add. One thing i can’t really figure out is why the memory used just keeps growing each time a new video is played… i wondered if there is some way to free up resources after a user changes channel?

Nobody can help? I have pretty much had to give up with this and just use fewer videos instead of fixing the problem.

I think there is some kind of memory leak when using a vector of ofVideoPlayers and calling stop and play on them individually - it is like when you call stop() it doesn’t actually deallocate any resources. Is this the expected behaviour, or some kind of leak? And can anyone think of a way around it? I tried to turn texture off on videos that aren’t playing (and then call update on them) but that makes no difference.

In short: memory allocation increases once you play() a movie, but doesn’t decrease if you call stop() on it. With 50 videos this means I soon run out of RAM.

i may be wrong but from what I understand calling the stop() method stops the player from iterating through new frames. I think you want to call video.stop() then a video.close() to free up resources before you then call video.load() to swap out new content and finally video.play() to get things moving again.

I have used something similar to the following method for an installation that swapped new movies in and out continiously for 3 months and had no memory issues.

void VidPlayer::loadVideo(string _path){
vid.stop();
vid.close();
vid.setPixelFormat(OF_PIXELS_RGBA);
vid.loadMovie(_path);
vid.play();
vid.setVolume(0.0);

}

hi @joshuabatty thanks that would make sense for stop() to do that.

like in your example i did try just using a single instance of ofVideoPlayer and calling close() then loadMovie() but I found it took too long and made the app feel very unresponsive. also I seemed to hit a new problem with that method where it would randomly crash on close()

back on of v007, I had to do something similar for 45 HD videos. I also needed the switch between videos to be instantaneous, and while loading new videos each time wasn’t a huge delay, it was noticeable. The biggest issue with loading them on the fly was that there was a memory leak in the QT video player code, and I believe it was actually in QuickTime itself, not the oF code. This was before the QTKit player, and way before the AVF player. At the time QTKit was faster than the regular player but wasn’t stable enough for me to deploy it.

TL;DR: I ended up pre-loading all of the videos into an array of ofVideoPlayers. I didn’t experience any memory leaks doing this, and just loading the videos into the ofVideoPlayer objects didn’t seem to use that much memory. It sounds like the leak you are experiencing is different, or that the current video players take up more memory than the old one did.

You could try Hap codec:

I did something like that on windows using gstreamer, basically it was a videoplayer with arround 40 videos, each video was an scene and i need to toggle with no delay between them.

I ended using a vector of videplayers and having a index to move between them. It was used in a musical during various months without issues. Videos were encoded in photo/jpeg

I am using ofxThreadedVideo to switch between videos.

Another option would be to create one big video file containing all 50 videos, and use setPosition() to jump to correct locations for individual video segments. You would also probably want to loop segments which would have to be done manually in this case.

Thanks for the ideas and suggestions. In the end I figure I have simply reached the limits of the available RAM and any workaround I have found like closing and then loading the videos “on demand” or trying different video players all have other implications or performance/stability issues.

I re-encoded all the videos from a total of 250GB down to about 30GB. Surprisingly this had very little impact on memory usage when the videos are loaded. I have now split the videos over two machines and performance and stability are both fine. Using Instruments I can see there is no leak as such just that the allocated memory never decreases when a video is stopped, and it increases each time a video is played that hasn’t played before. The only odd thing I see is that when a video loops back to the start for the first time it really takes a big chunk of RAM.

I think if I doubled the machine RAM I’d have no problems. The curator seems happy with splitting over 2 machines so hopefully this will be stable… I simulated it for 24 hours and it seemed good so fingers crossed.

Thanks for the help everyone.

hey BlueC you need to close the player to close the movie file and
de-allocate the file.

http://www.openframeworks.cc/documentation/video/ofVideoPlayer.html#show_closeMovie
http://www.openframeworks.cc/documentation/video/ofVideoPlayer.html#show_close

I am dealing with lots of HD videos (100+) and attempting to use ofxAVFVideoPlayer but I just end up with a lot crashes – both when loading them into a map as well as loading them on the fly. I need an extensible solution as this video archive will expand even larger as time goes by. Help? Code samples welcome.

Hi @atran. I did a fullHD 25+ video shuffler project with ofxThreadedVideoPlayer and ofxAVFVideoPlayer few weeks ago. Though I noticed some crash around audio things, set setShouldLoadAudio(false); will stop crashing. And the way to load & unload is basically same as the example of ofxThreadedVideoPlayer. So far I did not get any problem!

@Akira_At_Asia Thanks for the response. I was using ofxThreadedVideoPlayer for a bit but went back to ofxAVFVideoPlayer. Not sure why. I will try re-coding my application with that plugin again.

Also I’m curious if I should be loading the all the videos at once in ::setup or on the fly as they are called upon? Right now I am doing it on the fly.

I load/unload videos on the fly. And the codecs are ProRes & photoJPG.
Are you still getting crash?

Not anymore! I switched back to the base player, and everything works. Thanks.

1 Like

HI @atran, would you mind sharing code of how you implemented this multi-video player successfully?
cc @Akira_At_Asia
Which addons did you end up using?

Thanks