Hi, for my algorithm i want to process first frame from videoA
and first frame from videoB
at the same time and so on until the last frame.
In my implementation i have a problem,in theory it should read alternately like this frame 1 from videoA
, frame 1 from videoB
, frame 2 from video A
, frame 2 from videoB
and so on, but in reality the second videoB
it starts to read after video A
already read 6-8 frames, i don’t know why videoB it starts to read with so much delay.
Is it possible to read at the same time from 2 different videos without any delay?
link videos
import processing.video.*;
Movie videoA, videoB;
void setup() {
size(1600, 600);
videoA = new Movie(this, "videoL1.avi");
videoB = new Movie(this, "videoR1.avi");
videoA.play();
videoB.play();
}
void draw() {
image(videoA, 0, 0, 800, 600);
image(videoB, 800, 0, 800, 600);
}
int counterL=0;
int counterR=0;
boolean a=true;
void movieEvent(Movie c) {
if (c==videoA) {
println("left image: "+counterL);
counterL++;
videoA.read();
} else if (c==videoB) {
println("right image: "+counterR);
counterR++;
videoB.read();
}
}
boolean stop=false;
void keyPressed() {
if (key=='s')
{
if (stop==false)
{
videoA.pause();
videoB.pause();
stop=true;
} else
{
stop=false;
videoA.play();
videoB.play();
}
}
}
1 Like
Schred
April 19, 2020, 10:57pm
2
This is just a guess, but maybe the time it takes to play()
the videos in the beginning causes the delay. Try to create them both on seperate threads and check when those finished:
boolean videoAPlayed, videoBPlayed;
void setup() {
// ...
// Instead of directly playing them:
thread("playVideoA");
thread("playVideoB");
}
void playVideoA() {
videoA.play();
videoAPlayed = true;
}
void playVideoB() {
videoB.play();
videoBPlayed = true;
}
void draw() {
if (videoAPlayed)
image(videoA, 0, 0, 800, 600);
if (videoBPlayed)
image(videoB, 800, 0, 800, 600);
}
2 Likes
thank you for your help,
your idea solved my problem.
I’ve just come up w/ a FiFo Queue solution using 2 ArrayDeque containers to store previous video frames of each Movie :
The trick is to only remove() a PImage frame of each container as a pair when none isEmpty() :
This way the 2 videos are displayed synched to their corresponding frame number.
The sketch can be downloaded on the link below:
And its source code can be viewed on this link here:
/**
* FiFo Sync Frame Pair (v1.0.1)
* GoToLoop (2020/Apr/20)
*
* Discourse.Processing.org/t/read-from-2-videos-at-the-same-time/19937/4
* GitHub.com/GoToLoop/FiFo-Sync-Frame-Pair
*/
import processing.video.Movie;
import java.util.Queue;
import java.util.ArrayDeque;
static final String VID_1 = "videoL1.avi", VID_2 = "videoR1.avi";
static final int W = 1024, H = 768, WW = W >> 1, HH = H >> 1;
final Queue<PImage> framesA = new ArrayDeque<PImage>();
final Queue<PImage> framesB = new ArrayDeque<PImage>();
Movie videoA, videoB;
This file has been truncated. show original
And in this forum as well:
/**
* FiFo Sync Frame Pair (v1.0.1)
* GoToLoop (2020/Apr/20)
*
* Discourse.Processing.org/t/read-from-2-videos-at-the-same-time/19937/4
* GitHub.com/GoToLoop/FiFo-Sync-Frame-Pair
*/
import processing.video.Movie;
import java.util.Queue;
import java.util.ArrayDeque;
static final String VID_1 = "videoL1.avi", VID_2 = "videoR1.avi";
static final int W = 1024, H = 768, WW = W >> 1, HH = H >> 1;
final Queue<PImage> framesA = new ArrayDeque<PImage>();
final Queue<PImage> framesB = new ArrayDeque<PImage>();
Movie videoA, videoB;
void settings() {
size(W, HH);
}
void setup() {
videoA = new Movie(this, VID_1);
videoB = new Movie(this, VID_2);
videoA.play();
videoB.play();
}
void draw() {
if (framesB.isEmpty() || framesA.isEmpty()) return;
final PImage frameA = framesA.remove();
final PImage frameB = framesB.remove();
set(0, 0, frameA);
set(WW, 0, frameB);
}
void movieEvent(final Movie m) {
m.read();
final PImage frame = m.get();
frame.resize(WW, HH);
final Queue<PImage> frames = m == videoA? framesA : framesB;
frames.add(frame);
}
3 Likes
thank you,your implementation is great