We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello everybody.
I'm new here, so sorry if the question is something easy to solve. I'm working on a project and it doesn't work the way it should. Im selecting an area via a webcam. If something enters the selection (mensaanwezig) it should play a video.
There's playing a video at all times, myMovie 1 (should be looping). When something enters it switches to myMovie 2. When the person leaves/and when the end of myMovie2 has been reached, it should play myMovie3 at full length, regardless if something enters or leaves the area. after myMovie3 happened it should switch back to the start of myMovie 1.
I managed to get myMovie2 to play when somebody enters the area, but it switches back to myMovie 1 immediately when something leaves the area.
Can somebody tell me what i'm missing?
import processing.video.*;
Movie myMovie;
Movie myMovie2;
Movie myMovie3;
int x, y, w=20, h=20 ;
int togglemouse=1;
int H, S, B, Hold, Sold, Bold;
int verschil, threshold=50;
int modeselector=1;
color kleur;
boolean mensaanwezig;
boolean changed = false;
Capture cam;
void setup() {
size(640, 480);
//fullScreen();
myMovie = new Movie(this, "Movie01B.mp4");
myMovie2 = new Movie(this, "Movie02B.mp4");
myMovie3 = new Movie(this, "Movie03B.mp4");
myMovie.loop();
myMovie2.loop();
myMovie3.loop();
cam = new Capture(this, 640, 480, "Logitech Webcam C930e");
cam.start();
}
void movieEvent(Movie m) {
m.read();
}
..........................
void projectionmode() {
if (mensaanwezig ==true) {
if (changed==false) {
changed=true;
myMovie2.jump(0);
}
if (myMovie2.time() < /**myMovie2.duration*/ 45) {
myMovie2.play();
image(myMovie2, 0, 0);
} else {
myMovie3.play();
image(myMovie3, 0, 0);
if (myMovie3.time() <= /**myMovie3.duration*/ 45) {
changed=false;
}
}
} else {
if (changed==true) {
changed=false;
}
myMovie.play();
image(myMovie, 0, 0);
}
}
Answers
I suggest using states as it should make this business easier to follow. Untested code and it shows the concept.
Kf
@kfrajer
Thanks for the quick answer. I was up all night but i couldn't get it to work.
H=int(hue(kleur)); S=int(saturation(kleur)); B=int(brightness(kleur));
verschil=abs(Hold-H)+abs( Sold-S)+abs( Bold-B);
if (verschil>threshold) { mensaanwezig=true; } else { mensaanwezig=false; } }
What i have now is a boolean that works on if the colour in the selected area changes.
for the states i would need: A: play myMovie1 (mensaanwezig false) B: play myMovie2 (mensaanwezig true) and C: played every time at full length when mensaanwezig true switches back to false) <- but how do i devine this?
So I think your main bug in the above code is that you are not testing your times properly as in
if (myMovie3.time()<45)
. It should be larger than. Try the code below. To make it work, you need to set the color threshold to trigger the effect (don't forget to set the movies). To setup the color threshold, find an item that has a very unique color... let's say a color similar to apple green. Then execute the sketch with state set to CALIBRATION. Your video cam should play. Then bring this item to the field of view of the camera. Click on the item and record the color. Stop the sketch and update the Target colors. You might need to adjust COLTHRESH as well. Play the sketch again and verify the color is being detected. After you are happy, stop the sketch, change the state from CALIBRATION to IDLE in setup() and run it. Bring your cue color into the field of view to trigger movie2 followed by movie3 before it returns back to movie1 and ready for a new trigger.Kf
@kfrajer thank you very much for your help and direction! You can't imagine how much your help means to me.
void mouseClicked() { if (togglemouse==1) { x=mouseX; y=mouseY; } else { w=mouseX-x; h=mouseY-y; } togglemouse=togglemouse*-1; }
this is what i did to select the area in the previous code. I added that one instead of yours.
The code works and I finally got to see myMovie3. But i'm still not there yet. If mensaanwezig=true, myMovie2 starts playing, till the very end.. regardless if the threshold changed. After myMovie2 ends, myMovie3 starts playing till the very end, which is beautiful, because that's what it's supposed to do.
The idea is that movie2 switches to myMovie3 immediately if someone left the area and/or movie2 is played till it's end.
Right now it switches from 2 to 3 till the very end, but it's not because someones been in the area for that long, but because it's programmed to play if mensaanwezig=true.
Can't i make a boolean for if mensaanwezig=true switchtes to mensaanwezig=false?
I'm sorry if i bother you, and I really appreciate your help!
liiwn
Note 1: I will leave FINISH case as it is to ensure
mensaanwezig
is set to false not matter what.To start playing movie3, you will need to modified case
ACTIVEFIRST
:Keeping your code with your modified suggestion (
void lichtmeten()
definition), the above modification will stop playing movie2 as soon as the trigger is not present anymore and it will start playing the movie3 immediately.Kf
@kfrajer THANK YOU SO MUCH! IT WORKS! I want to thank you very much for you help, and I hope I didn't annoy you to much :)
@liiwn glad to hear it is working. All the best!
Kf
@kfrajer Hey there, it's me again.. , so now i'm trying to make an alternative ending:
myMovie2 has a duration of 45 secs. Let's say, if mensaanwezig turns out to be false within the first 15 secs while myVideo2 is playing, it switches to myVideo3 (PREPSEC, ACTIVESEC, FINISH). If mensaanwezig=false happens (or if myVideo2 duration has been reached) after those 15 secs, it should play myVideo4(PREPSECB, ACTIVESECB, FINISHB).
I need a way to select the timing of myMovie2. I thought i could add that in ACTIVEFIRST under it's if statement.
Eventually i would like to add another ending that happens if mensaanwezig=false happens between 15 & 30.
If this is possible, could you help me with your wisdom one more time?
Again, thank you very much! Have a nice weekend.
Keep in mind that if you are planning to extend your logic, it currently looks like this:
...which is, slightly more abstract:
...with looping as a special case handling of bgMovie -> bgMovie.
One way to approach that in general is a queue like this:
...and when an event happens you add things to the front, like this:
When a movie finishes playing, you remove it from the queue and start playing the next movie.
Now you can add really complex behaviors to your movie system easily by just adding / removing queued movies -- you don't have to program a set of special rules for each transition. If events happen to change the remaining duration of a movie, or remove it, or switch what comes next, you can express all those things concisely as operations that edit queue items. Common ones might be:
If you want to add complex behaviors like cross-fading, you don't have to create a cross-fade for every single possible transition -- you can just create one cross-fade behavior that acts on the current and next items in the queue. Et cetera.
@jeremydouglass Good concept. Maybe one day I'll do a demo. I can envision having a stack of videos and a stack of transitions.
@liiwn Here is my attempt based on initial concept. Notice I didn't have the chance to test this code. If this code keeps growing at this rate, then I suggest changing the name of the constant fields (aka. states) and the movie's field names so they are related to each other in a more clear way. Also notice I removed FINISHEDB and modified your FINISH case.
Kf
@kfrajer this doesn't work. myMovie plays fine, but when mensaanwezig=true it flickers between myMovie and Mymovie2. It's like is skips every case from PREPSEC upwards.
It is hard to tell where the problem is as I don't have a running version of your code. You can add print statements in the following cases: PREPSEC, PREPSECB, FINISH and see if those cases are being called. Another problem is that
mensaanwezig
might be turning false in your program in another part of your code? I am just guessing, although if this were true, then you will be entering movie3... or it should based on the code above.Kf
@kfrajer
I did it! I set specifik time values and a LOT of cases. I also noticed that processing needs some time to load the video files. A few time restarting and it works like it should.
Thank you for all your help and patience! have a nice day!
void projectionmode() {