Video overlay

Can anyone recommend on how can I accomplish this:

Have a folder with 5 video clips of 5/7 secs each.

Get the program to play each video in a loop, but all at the same time overlaid trough transparency/opacity.

Thank you for taking your time to read this. :smiley:

Hmmm… are you talking about full-frame transparency (ie. the whole frame is rendered with an alpha != 255), or per-pixel transparency (ie. each pixel has its own alpha value)?

If it’s full-frame transparency, it is more straightforward… something along these lines:

  
- setup an ofVideoPlayer object for each of the videos  
- when drawing:  
  - ofSetColor(255, 255, 255, alpha); // if alpha != 255, it will draw transparently!  
  - draw the ofVideoPlayer objects  
  - ofSetColor(255, 255, 255, 255); // take off the alpha, so everything else draws correctly  

If it’s per-pixel transparency, and you are using an alpha mask for each layer/video (ie. a black and white image where black is transparent and white is opaque and shades of grey are semi-transparent), it’s a bit trickier since you have to handle the masking part…

  
- setup an ofVideoPlayer object for each of the videos  
- you will also need an ofImage for each video to store the current frame data  
- you will also need to load an ofImage for each of your alpha masks  
  
- when updating:  
  - get the ofVideoPlayer pixels (for our example, we'll name it framePixels)  
  - get the alpha mask pixels (for our example, we'll name it alphaPixels)  
  - do per-pixel processing on the framePixels:  
    - foreach framePixel as cPixel  
      - renderPixels[cPixel+0] = framePixels[cPixel+0]; // red channel  
      - renderPixels[cPixel+1] = framePixels[cPixel+1]; // green channel  
      - renderPixels[cPixel+2] = framePixels[cPixel+2]; // blue channel  
      - renderPixels[cPixel+3] = alphaPixels[cPixel]; // alpha channel  
  - after all pixels are processed, you can set the current frame's pixels:  
      currentFrame[cVideoIndex].setPixels(renderPixels, frameWidth, frameHeight, OF_IMAGE_COLOR_ALPHA);  
  
- when drawing:  
  - draw each of the currentFrame ofImages  

Hope this helps! Let us know if you have any questions…

Thank you very much for your help. What I mean is I believe the whole frame. Like every part of each single video has the same opacity.

If I have 3 videos in the folder those 3 get played at the same time full screen with each having 33% opacity.

But if the program detects there are 4 videos in the folder each will play with 25% opacity.

Im very new to this, and although I can code in PHP and AS im not by any strecth of imagination a good programmer, how hard will it be for me to program something that would:

-Check a folder for videos

-Play any video found in a continuous loop.

-Adding more videos for the screen as soon as they are found in the folder

-Correct the opacity depending on the number of videos so all can be viewed layered
on top of each other.

Am I going in the right direction trying to do this with openFrameworks?

Thank you.

Yup, openFrameworks would be an excellent choice for this type of problem.

To answer your specific questions:

-Check a folder for videos

  • use the ofxDirList add-on to scan the directory and retrieve a list of files. ofxDirList has a built-in extension filter so you can set it to only list video files. The add-on comes packaged with an example to get ya started with this.

-Play any video found in a continuous loop.

  • the ofVideoPlayer has looping built in.
  • load each video that ofxDirList returns into an ofVideoPlayer and call setLoopState(OF_LOOP_NORMAL); on it

-Adding more videos for the screen as soon as they are found in the folder

  • in your testApp::update(), use ofxDirList again to check the directory, and create a new ofVideoPlayer for any new videos that are found
  • please note that this could get processor-intensive if you do it every frame, so consider doing it at set intervals… (ex. if(ofGetFrameNum() % 25 == 0) loadVideos(); // calls loadVideos every 25 frames)

-Correct the opacity depending on the number of videos so all can be viewed layered
on top of each other.

  • whenever you load a new video, your opacity would be set to opacity = 100.0/numberOfVideos;

Some notes/tips on how you could tie everything together:

Because you are planning to do dynamic loading, you will need to track which videos have already been loaded and make sure you don’t load them again. Consider using a list of file names of videos that have already been loaded, and before loading any new ones, check the list to make sure it isn’t already in there. Another approach to this would be to programmatically move them out of the scanned directory after they have been loaded.

To make sure the opacity is updated every time a new video is loaded, consider using a loadVideo method that would recalculate opacity after the video is successfully loaded.

Here are some data and methods you will probably need to implement…

  
testApp has this data:  
  vector<ofVideoPlayer*> videos;  
  vector<string> loadedVideos;  
  float opacity;  
  
testApp has these methods:  
  int loadVideos(string fromPath); // loads videos found in fromPath  
  bool loadVideo(string fileName); // loads a single video if it hasn't already been loaded  
  bool videoIsLoaded(string fileName); // scans the loadedVideos vector for fileName  
  
  
bool testApp::loadVideo(string fileName){  
  if(!videoIsLoaded(fileName)){  
    ofVideoPlayer* newVideo = new ofVideoPlayer();  
    if(newVideo->loadMovie(fileName)){  
      newVideo->setLoopState(OF_LOOP_NORMAL);  
      newVideo->play();  
      videos.push_back(newVideo);  
      loadedVideos.push_back(fileName);  
      if(videos.size() > 0) // prevent dividing by 0  
        opacity = 100.0 / videos.size();  
      return true; // video loaded successfully!  
    }  
    else{  
      // loading failed! clean up the dynamic memory right away, since it won't be managed anywhere else  
      delete newVideo;  
      newVideo = NULL;  
    }  
  }  
  return false; // video is already loaded, or loading failed  
}  
  

Notice that the videos vector is using pointers to ofVideoPlayer objects, and that we have the line ofVideoPlayer* newVideo = new ofVideoPlayer(); … This is how we allocate dynamic memory. But since we allocated it, we also must deallocate it when we’re done, or else we’ll create a memory leak.

You will want to implement the void exit(); method in your testApp and have it clean up all the videos we’ve dynamically allocated. It would look something like this:

  
  
void testApp::exit(){  
  // loop through the vector and clean up each entry's dynamic memory  
  for(int i=0; i < videos.size(); i++){  
    if(videos[i] != NULL){  
      delete videos[i];  
      videos[i] = NULL;  
    }  
  }  
  videos.clear(); // empty the vector  
}  
  

HTH!
-plong0

Hi, thank you very much for taking the time and effort to help me.
All that information is is very useful for someone who was feeling a bit lost on how to approach all this.

Time to get my hands dirty 8)

Hey, no problem :slight_smile:

Best luck to ya!