We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm fairly new to processing and it's my first time involving videos. I am currently using Arduino and Processing to create touch sensitive video player. I have managed to get Arduino to send the readings to Processing and it is reading them. But I can't get the videos to play properly when a sensor is activated (going from 0>1). I think there might be a few things wrong/missing with the code or certain things in the wrong place. A blank screen currently loads when I run the sketch and doesn't change even when activating the sensors. I have the video files in a 'data' folder within the sketch folder so I think they are in the right place. Any help at all is greatly appreciated. Code below;
import processing.serial.*;
import processing.video.*;
Movie movie1;
Movie movie2;
Movie movie3;
//etc.
Serial myPort;
int linefeed = 10; // Linefeed in ASCII
int numSensors = 3; // we will be expecting for reading data from four sensors (CHANGE)
int sensors[]; // array to read the values
int pSensors[]; // array to store the previuos reading, useful for comparing
// actual reading with the last one
String currentMovie;
void setup() {
size(1440, 1080);
println(Serial.list());
// files inside processing folder for this programme
movie1 = new Movie(this, "Sun.mp4");
movie2 = new Movie(this, "Mercury.mp4");
movie3 = new Movie(this, "Venus.mp4");
//etc.
myPort = new Serial(this, Serial.list()[3], 115200);
// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil(linefeed);
}
void draw() {
// check the sensors and sets the movie to play
if (currentMovie == "") //if nothing is playing
{
if (sensors[0] == 1)
{
//print("Play Movie 1");
currentMovie = "movie1";
movie1.play();
} else if (sensors[1] == 1)
{
print("Play Movie 2");
currentMovie = "movie2";
movie2.play();
} else if (sensors[2] == 1)
{
print("Play Movie 3");
currentMovie = "movie3";
movie3.play();
}
} else
{
// do nothing (if a movie is playing do nothing)
}
// show the movie frames
if (currentMovie == "movie1")
{
if (movie1.available())
{
image(movie1, 0, 0);
} else
{
currentMovie = ""; // if a frame is available, show the next frame. This means once the video ends it will play nothing.
}
} else if (currentMovie == "movie2")
{
if (movie2.available())
{
image(movie2, 0, 0);
} else
{
currentMovie = "";
}
} else if (currentMovie == "movie3")
{
if (movie3.available())
{
image(movie3, 0, 0);
} else
{
currentMovie = "";
}
}
}
void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil(linefeed);
// if you got any bytes other than the linefeed:
if (myString != null) {
myString = trim(myString);
// split the string at the commas
// and convert the sections into integers:
pSensors = sensors;
sensors = int(split(myString, ','));
// print out the values you got:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
}
}
void movieEvent(Movie m) {
m.read();
}
Answers
try to change this line with available()
I've placed line 63&64 with this;
Is that what you meant as that comes up with the error "Cannot make a static reference to the non-static method available() from the type Movie"
Here is some untested code for you to review. There is another way to do it a bit better. However, I didn't implemented it because you didn't describe what your input should do. Should the movie keep playing after the one is set to zero? Or should it play when there is a one in the line? How to handle the case that you have multiple ones or in case there are no ones in your input stream?
Kf
It's working more than my previous code, sorry I didn't describe the input.
Basically what the sensors will be inside the planets and I want it so when one is touched it plays the video all the way through, but allows the user to take their hand away without the video stopping.
So... I need it so when a sensor turns to 1, it plays it's assigned video all the way through even if the value returns to 0 OR another sensor changes to 1 whilst the video is playing if that makes sense?
Thankyou
Ok, so as it is right now, if you don't get any signal, it will stop playing the movies. You can remove the stop calls in lines 114-116. However if another sensors is driven (or even the same current sensor) it will play the new movie again.
You need to do two things:
I will suggest doing this in a separate sketch using only one movie and no arduino. Then you can integrate it to your sketch. I can try putting something together if I get some play time later today or tomorrow.
Kf
https://www.Reddit.com/r/processing/comments/6bpwp2/is_anyone_able_to_tell_me_whats_wrong_with_my/
Okay, I took the stop calls out and added a delay on the Arduino to slow down when it picks up a reading from the sensors which made the audio work but didn't actually play the video properly.
I'm aware of the duration() function which returns the length of the video. So I would imagine it involves play(), then I don't know if it would be possible to either lock the video for the duration or stop receiving results from the arduino (not reacting to the sensors) until the video is finished. I'm not sure if that would be the best way to go about it or how exactly the code would look for it.
That is the way to do it. You will have a boolean field on a global scope. The boolean field will lock any arduino processing until the movie finishes playing. How to control the boolean flag based on the movie's playing time? This is what I am thinking. When you start playing a movie, you lock your boolean value and you collect a time stamp using millis() after you have determined the duration of the movie. Then you keep checking millis() against your startStamp+movie_duration. When millis is more than timeStamp+movie_duration, you can assume the movie has stopped playing. You unlock the boolean field and your arduino will be able to process data.
In the arduino side:
Kf
Is the code above all that would be required to be placed in to code? I'm unsure on how to add the boolean field + startStamp+movie_duration section to the code I have.
I was thinking would it be easier if I manually found out the duration of the videos as they wouldn't change, would that allow for me to do something such as... play video1>lock for 45millis>end video>start receiving data again So that it doesn't have to find out the duration as it is playing the video and then keep comparing it against the start time. I don't know if this is possible/an easier method.
Here is the working example as you described it in one of your previous posts.
Kf
Hi, thanks a lot for the reply.
This works exactly how I want it to when using the Keys. But when commenting them out and trying to use the Serial Ports I get a few problems.
So when using the serial from arduino, it reads the sensors, and when a sensor is activated I get 1 of 2 errors, Firstly I get this;
--
Sensor 0: 1 Sensor 1: 0 Sensor 2: 0 Stopping 0: movie1
(Processing core video:4812): GStreamer-WARNING **: cannot replace existing sync handler
Native Object has been disposed
It is also worth noting that it is highlighting m.stop(); in the section of code from below after this error is occuring.
--
No video appears and it stops reading any sensors.
It also comes up with the error below ( especially when commenting out the 2 lines of code below underneath void serialEvent(Serial myPort) { ) //if (current!=NOMOVIE) //return;
Error: Error, disabling serialEvent() for /dev/tty.usbmodem1411 null
I have tried this with it commented in and it seems to happen less often but is still not showing any video.
Can you post your arduino code?
Kf
This will eventually be for 9 sensors (8 planets + Sun). Currently 6 in use
Two changes:
In code function playOne(), remove the call to stopAll() as it is not needed.
The second change is to remove those lines in serialEvent. I have them there initially but now that I think about it, one needs it to clear the buffer. I guess one could flush the buffer but there are more technicalities that needs to be taken into account before flushing the buffer. For now, let the serial event process any incoming data and make sure that
are the first lines in the function
void processInputData(int[] sensors)
. I don't think this will solve all the problems.Kf
I tried what you said to do and received these results without it playing any videos
Sensor 0: 0 Sensor 1: 0 Sensor 2: 0 Sensor 3: 0 Sensor 4: 0 Sensor 5: 0
Received data: Nothing to do ( No movie selected)
Sensor 0: 0 Sensor 1: 1 Sensor 2: 0 Sensor 3: 0 Sensor 4: 0 Sensor 5: 0
Stopping 1: movie2
Time schedule: 28498 -> 62139 msec
Now playing No movie selected
Sensor 0: 0 Sensor 1: 1 Sensor 2: 0 Sensor 3: 0 Sensor 4: 0 Sensor 5: 0
Stopping 1: movie2
I played around with it a bit and actually got it to work apart from a few small problems. I commented out a few of the stopAll functions and it started to work with the code below;
This started to play the video when a sensor was activated and also made it so no other video would play once a movie had started which is what I wanted. The only problem is that at the end of some of the videos it wouldn't fully end (seemed like it froze on the last frame and didn't go back to a black background) Then when trying to play the same video again it would just be the same screen (last frame of video) without any audio either. I couldn't play another video within this time as it says it is blocking the action as apparently a movie is being played.
I actually timed the duration it takes for this frozen image to stop and allow me to play another video and it is near the same duration of the video that it froze on. So I think it is playing the video again but it's just a frozen image instead of the video. I've only tested it with 3 sensors and 3 videos and it's only freezing on the second one currently. I'm going to wire all the sensors and videos up and then see if it's only one that's affected.
Other than this problem I think it's working properly, apart from every other time I run the sketch it says
Error, disabling serialEvent() for /dev/tty.usbmodem1411 null But this isn't a big issue as it usually works when I run it again. Just not sure why the video messes up for that one video. I'll wire the rest up and post if I get any additional problems with it.
My first kick at the can would be to replace the second video with another video to rule out the integrity of the video to be the problem. So you don't experience frame freezing for video 1 or 3 at all?
Related to disabling the event... not sure what could be the problem. It could be the structure of the data that you are streaming from your arduino. Are you sending data continuously from your arduino within the loop() function?
Kf
You can also enable the keyReleased testing block and see how your movies play. If they play ok, then one can infer the problem resides in the serial data processing part.
Kf