Multi Layered Video Sequencer
2 | Made with:
3 |
4 |
9 |
10 | Videos used in the demo are from Beeple
11 | This project is under developpement.
12 |
13 |
14 | First, add your videos inside /data/videos folder. It will automatically create playlist and check if thumbnails exist or need to be created. The Sequencer works in 3 steps/parts:
15 |
16 | - Clips: choose a video, modify its settings and add the created clip to a chosen Layer.
17 | - Layers: a succession of clips playing one after another, you can modify each layer settings and choose a delay before playing Layer.
18 | - Composition: all the Layers playing at the same time (after their launch delay is met) with the blendMode chosen for the current clip of each Layer.
19 |
20 |
21 |
22 |
23 | Part 1: Clip Editor
24 |
25 | The Clip Editor allows you to edit Clip settings like:
26 |
27 | - play mode: loop or play-playback
28 | - number of repetition (loop 1 = play once, you need 2 for play-playback)
29 | - how fast/slow the movie should be run
30 | - position XY
31 | - scale
32 | - opacity
33 | - blendmode
34 | - custom fade in and fade out
35 | - choice of VideoLayer to add the clip to
36 |
37 |
38 |
39 |
40 |
41 | Part 2: VideoLayers
42 |
43 | A videoLayer is defined as an array clips playing successively.
44 | The Layer Editor allows you to edit each Layer settings like:
45 |
46 | - position XY
47 | - scale
48 | - opacity
49 | - custom fade in and fade out
50 | - delay before playing first clip of the Layer
51 |
52 |
53 |
54 |
55 |
56 | Part 3: Composition
57 |
58 |
59 |
60 | Needing reviews:
61 |
62 | -GLSL BlendModes behavior regarding Opacity of the 2 Layers mixed
63 |
--------------------------------------------------------------------------------
/Composition.pde:
--------------------------------------------------------------------------------
1 | class Composition{
2 | PApplet parent;
3 | GLTexture[] tex;
4 | boolean isPlaying = false;
5 | float duration = 0.0;
6 | float timelineValue = 0.0;
7 | float timer = 0.0;
8 | int top=999, bottom=999;
9 | boolean firstBlend = true;
10 | boolean initialize=true;
11 |
12 | Composition(PApplet applet){
13 | parent = applet;
14 | tex = new GLTexture[nbLayers-1];
15 | for (int i = 0; i=0; i--){
39 | if(timelineValue>layers[i].Delay && timelineValue0 && layers[i].currentClipduration){// stop composition
90 | isPlaying=false;
91 | initialize = true;
92 | timelineValue=0.0;
93 |
94 | // stop layers
95 | for(int i=0; i. You can also
30 | * obtain it by writing to the Free Software Foundation,
31 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 | */
33 |
34 | import processing.opengl.*;
35 | import codeanticode.glgraphics.*;
36 | import codeanticode.gsvideo.*;
37 | import controlP5.*;
38 | import org.json.*;
39 |
40 | //////////////////////////////Clips
41 | String[] Playlist;
42 | Clip editClip;
43 |
44 | //////////////////////////////Layers
45 | LayerVideo[] layers;
46 | int nbLayers = 8;
47 | int editLayer = 0;
48 |
49 | //////////////////////////////Composition
50 | Composition composition;
51 | GLTextureFilter[] BlendModes;
52 |
53 | //////////////////////////////GUI
54 | ControlP5 gui;
55 | int[] updateLayerClip = {999,999};
56 | boolean updatingClip = false;
57 |
58 | void setup(){
59 | size(1500, 800, GLConstants.GLGRAPHICS);
60 | background(20);
61 | noStroke();
62 |
63 | // load videos and check if you need to load or create thumbnails
64 | println("loading videos");
65 | loadVideos();
66 | println("loading thumbnails");
67 | checkThumbnails();
68 |
69 | // create a Clip for edition
70 | println("initializing Clip Editor");
71 | editClip = new Clip(this);
72 | editClip.isEditClip = true;
73 |
74 | // create layers
75 | println("initializing Layers Editor");
76 | layers = new LayerVideo[nbLayers];
77 | for (int i = 0; i clips;
6 | int currentClip = 0;
7 |
8 | boolean isEditLayer = false;
9 | boolean isPlaying = false;
10 | float duration = 0.0;
11 | float timelineValue = 0.0;
12 | float timer = 0.0;
13 | float posX=0, posY=0;
14 | float Scale=1.0;
15 | float Opacity=0.0;
16 | float TargetOpacity=1.0;
17 | float Delay=0.0;
18 | float fadeInAlpha=1.0;
19 | float fadeInDuration=0.0;
20 | float fadeOutAlpha=1.0;
21 | float fadeOutDuration=0.0;
22 |
23 | GLTexture tex;
24 | GLTextureFilter LayerFilter;
25 |
26 | LayerVideo(PApplet applet, int _id){
27 | parent = applet;
28 | id = _id;
29 | clips = new ArrayList();
30 | tex = new GLTexture(parent);
31 | LayerFilter = new GLTextureFilter(parent, "LayerFilter.xml");
32 | }
33 |
34 | void display(){
35 | if(clips.size()>0 && currentClipduration) timelineValue=0.0;
86 | timer = millis();
87 | Layer_Timeline[id].setRange(0.0, duration);
88 | Layer_Timeline[id].setValue(timelineValue);
89 | Layer_Timeline[id].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
90 | }
91 |
92 | void updateGLSLParams(){
93 | LayerFilter.setParameterValue("posXY", new float[] {posX, posY});
94 | LayerFilter.setParameterValue("Scale", Scale);
95 | if(timelineValue=0; i--){
137 | clips.get(i).movie.stop();
138 | clips.get(i).texFiltered.delete();
139 | clips.get(i).tex.delete();
140 | clips.get(i).ClipFilter.delete();
141 | clips.remove(i);
142 | gui.remove("Layer"+id+"Clip"+i);
143 | }
144 | fill(20);
145 | rect(505,15,490,280);
146 | }
147 | }
--------------------------------------------------------------------------------
/Clip.pde:
--------------------------------------------------------------------------------
1 | class Clip{
2 | PApplet parent;
3 |
4 | boolean isEditClip = false;
5 | boolean isLoaded = false;// clip is loaded
6 | boolean ended = false;// clip ended
7 |
8 | int movieNum=999;
9 | GSMovie movie;
10 | float duration;// duration of the movie
11 | float timelineValue = 0.0;
12 | float timer = 0.0;
13 | int lectureMode=0;// 0:loop - 1:play/playback
14 | int nbRepeat=1;// number of repetition
15 | int nbLecture=1;// current number of reads
16 | boolean addLectureSwitch=false;// utility boolean to count nbLecture
17 |
18 | float movieSpeed=1.0;
19 | float TargetOpacity=1.0;
20 | float Opacity;// current Opacity
21 | float posX=0, posY=0;
22 | float Scale=1.0;
23 | float fadeInAlpha=1.0;
24 | float fadeInDuration=0.0;
25 | float fadeOutAlpha=1.0;
26 | float fadeOutDuration=0.0;
27 | int blendMode=0;
28 |
29 | GLTexture tex;
30 | GLTexture texFiltered;
31 | GLTextureFilter ClipFilter;
32 |
33 | Clip(PApplet applet){
34 | parent = applet;
35 | ClipFilter = new GLTextureFilter(parent, "ClipFilter.xml");
36 | }
37 |
38 | void setVideo(){
39 | isLoaded = false;
40 | // check if a movie was already loaded and delete it
41 | if(movie != null){
42 | movie.stop();
43 | movie.delete();
44 | tex.delete();
45 | texFiltered.delete();
46 | // println("Movie deleted");
47 | }
48 |
49 | // load movie and set Texture
50 | movie = new GSMovie(parent,"videos/"+Playlist[movieNum]);
51 | tex = new GLTexture(parent);
52 | texFiltered = new GLTexture(parent);
53 | movie.setPixelDest(tex);
54 | tex.setPixelBufferSize(10);
55 | tex.delPixelsWhenBufferFull(false);
56 |
57 | if(lectureMode == 0) movie.loop();
58 | else movie.play();
59 | while(movie.width<1){
60 | movie.volume(0.0);
61 | }
62 |
63 | movie.goToBeginning();
64 | if(isEditClip){
65 | gui.getController("Clip_PlayPause").setValue(1.0);
66 | Clip_Timeline.setValue(0);
67 | }
68 | else{
69 | movie.pause();
70 | }
71 |
72 | Opacity = fadeInAlpha;
73 | movie.speed(movieSpeed);
74 | duration = movie.duration()*nbRepeat/movieSpeed;
75 | isLoaded=true;
76 | }
77 |
78 | void display(){
79 | if(isLoaded && movie.isPlaying()){
80 | if(lectureMode == 0) movie.speed(movieSpeed);
81 | if (tex.putPixelsIntoTexture()) {
82 | updateGLSLParams();
83 | // apply GLSL Filter
84 | tex.filter(ClipFilter, texFiltered);
85 |
86 | // display editClip in editor
87 | if(isEditClip){
88 | duration = movie.duration()*nbRepeat/movieSpeed;
89 | // due to Clip alpha, we need to "erase" previous frame
90 | fill(20);
91 | rect(5,15,490,280);
92 |
93 | image(texFiltered,5,15,490,280);
94 | updateClipGui();
95 | }
96 | }
97 |
98 | // check loop/playback/stop
99 | checkLoop();
100 | }
101 | }
102 |
103 | void checkLoop() {
104 | timelineValue += (millis()-timer)/1000;
105 | timer = millis();
106 |
107 | // check at Beginning
108 | if(addLectureSwitch && movie.time()<.05*max(1,movieSpeed)){
109 | if(lectureMode==1){
110 | nbLecture++;
111 | movie.speed(movieSpeed);
112 | }
113 | addLectureSwitch=false;
114 | }
115 | // check at end
116 | else if(movie.duration()-movie.time()<.05*max(1,movieSpeed)){
117 | // lectureMode: loop
118 | if(lectureMode==0){
119 | if(!addLectureSwitch){
120 | nbLecture++;
121 | addLectureSwitch=true;
122 | movie.speed(movieSpeed+1);
123 | movie.goToBeginning();
124 | movie.speed(movieSpeed);
125 | }
126 | }
127 |
128 | // lectureMode: play/playback
129 | else if(lectureMode==1 && !addLectureSwitch) {
130 | nbLecture++;
131 | addLectureSwitch=true;
132 | movie.speed(-movieSpeed);
133 | }
134 | }
135 |
136 | if(nbLecture > nbRepeat || timelineValue>duration){
137 | // println("Clip end");
138 | nbLecture = 1;
139 | addLectureSwitch=false;
140 | Opacity = fadeInAlpha;
141 | movie.speed(movieSpeed+1);
142 | movie.goToBeginning();
143 | movie.speed(movieSpeed);
144 | timelineValue=0.0;
145 | addLectureSwitch=false;
146 | if(!isEditClip){
147 | // println("nbLecture: "+nbLecture+" nbRepeat: "+nbRepeat);
148 | ended = true;
149 | movie.pause();
150 | }
151 | }
152 | }
153 |
154 | void updateGLSLParams(){
155 | Opacity = TargetOpacity;
156 | if(timelineValueduration-fadeOutDuration){
161 | // println("fadeOut");
162 | Opacity = fadeOutAlpha+(duration-timelineValue)*((TargetOpacity-fadeOutAlpha)/fadeOutDuration);
163 | }
164 | ClipFilter.setParameterValue("Opacity", Opacity);
165 | ClipFilter.setParameterValue("posXY", new float[] {posX, posY});
166 | ClipFilter.setParameterValue("Scale", Scale);
167 | }
168 |
169 | void updateClipGui(){
170 | Clip_Timeline.setRange(0.0, duration);
171 | Clip_Timeline.setValue(timelineValue);
172 | Clip_Timeline.getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
173 | Clip_Duration.setText("DURATION: "+duration);
174 | }
175 | }
--------------------------------------------------------------------------------
/LayerGui.pde:
--------------------------------------------------------------------------------
1 | Group[] layerG;
2 | Slider[] Layer_Timeline;
3 | Textlabel[] Layer_Duration;
4 | Toggle[] Layer_PlayPause;
5 | Slider2D[] Layer_XY;
6 | Slider[] Layer_Scale;
7 | Slider[] Layer_Opacity;
8 | Slider[] Layer_Delay;
9 | Slider[] Layer_fadeInAlpha;
10 | Slider[] Layer_fadeInDuration;
11 | Slider[] Layer_fadeOutAlpha;
12 | Slider[] Layer_fadeOutDuration;
13 | Button[] Layer_Reset;
14 |
15 | void initLayerGui(){
16 | layerG = new Group[nbLayers];
17 | Layer_Timeline = new Slider[nbLayers];
18 | Layer_Duration = new Textlabel[nbLayers];
19 | Layer_PlayPause = new Toggle[nbLayers];
20 | Layer_XY = new Slider2D[nbLayers];
21 | Layer_Scale = new Slider[nbLayers];
22 | Layer_Opacity = new Slider[nbLayers];
23 | Layer_Delay = new Slider[nbLayers];
24 | Layer_fadeInAlpha = new Slider[nbLayers];
25 | Layer_fadeInDuration = new Slider[nbLayers];
26 | Layer_fadeOutAlpha = new Slider[nbLayers];
27 | Layer_fadeOutDuration = new Slider[nbLayers];
28 | Layer_Reset = new Button[nbLayers];
29 |
30 | Group layerGui = gui.addGroup("Layer")
31 | .setBackgroundColor(color(0))
32 | .setPosition(505,310)
33 | .setWidth(490)
34 | .setBackgroundHeight(490)
35 | .disableCollapse()
36 | ;
37 |
38 | Accordion LayersGui = gui.addAccordion("LayersGui")
39 | .setPosition(0,10)
40 | .setWidth(490)
41 | .setCollapseMode(Accordion.SINGLE)
42 | .moveTo(layerGui)
43 | ;
44 |
45 | // Accoordion's content
46 | for (int n = nbLayers-1; n>=0; n--){
47 | layerG[n] = gui.addGroup("Layer"+n)
48 | .setWidth(490)
49 | .setBackgroundHeight(390)
50 | .activateEvent(true)
51 | ;
52 |
53 | Layer_Timeline[n] = gui.addSlider("Layer_Timeline"+n)
54 | .setPosition(10,10)
55 | .setSize(470,10)
56 | .setRange(0,1)
57 | .setId(0)
58 | .moveTo(layerG[n])
59 | ;
60 | Layer_Timeline[n].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
61 |
62 | Layer_Duration[n] = gui.addTextlabel("Layer_Duration"+n)
63 | .setText("DURATION: 0.00")
64 | .setPosition(380,23)
65 | .moveTo(layerG[n])
66 | .setId(1)
67 | ;
68 |
69 | Layer_PlayPause[n] = gui.addToggle("Layer_PlayPause"+n)
70 | .setPosition(10,40)
71 | .setSize(80,10)
72 | .moveTo(layerG[n])
73 | .setId(2)
74 | ;
75 |
76 | Layer_XY[n] = gui.addSlider2D("Layer_XY"+n)
77 | .setPosition(10,130)
78 | .setSize(260,140)
79 | .setMinX(-100)
80 | .setMaxX(100)
81 | .setMinY(-100)
82 | .setMaxY(100)
83 | .setArrayValue(new float[] {100,100})
84 | .setId(3)
85 | .moveTo(layerG[n])
86 | ;
87 |
88 | Layer_Scale[n] = gui.addSlider("Layer_Scale"+n)
89 | .setPosition(295,130)
90 | .setSize(185,10)
91 | .setMin(0.1)
92 | .setMax(10)
93 | .setValue(1)
94 | .setId(4)
95 | .moveTo(layerG[n])
96 | ;
97 | Layer_Scale[n].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
98 |
99 | Layer_Opacity[n] = gui.addSlider("Layer_Opacity"+n)
100 | .setPosition(295,180)
101 | .setSize(185,10)
102 | .setMin(0.0)
103 | .setMax(1.0)
104 | .setValue(1.0)
105 | .setId(5)
106 | .moveTo(layerG[n])
107 | ;
108 | Layer_Opacity[n].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
109 |
110 | Layer_Delay[n] = gui.addSlider("Layer_Delay"+n)
111 | .setPosition(295,220)
112 | .setSize(185,10)
113 | .setMin(0.0)
114 | .setMax(600.0)
115 | .setValue(0.0)
116 | .setId(6)
117 | .moveTo(layerG[n])
118 | ;
119 | Layer_Delay[n].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
120 |
121 | Layer_fadeInAlpha[n] = gui.addSlider("Layer_fadeInAlpha"+n)
122 | .setPosition(10,300)
123 | .setSize(185,10)
124 | .setMin(0.0)
125 | .setMax(1.0)
126 | .setValue(1.0)
127 | .setId(7)
128 | .moveTo(layerG[n])
129 | ;
130 | Layer_fadeInAlpha[n].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
131 |
132 | Layer_fadeInDuration[n] = gui.addSlider("Layer_fadeInDuration"+n)
133 | .setPosition(10,330)
134 | .setSize(185,10)
135 | .setMin(0.0)
136 | .setMax(20.0)
137 | .setValue(0.0)
138 | .setId(8)
139 | .moveTo(layerG[n])
140 | ;
141 | Layer_fadeInDuration[n].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
142 |
143 | Layer_fadeOutAlpha[n] = gui.addSlider("Layer_fadeOutAlpha"+n)
144 | .setPosition(240,300)
145 | .setSize(185,10)
146 | .setMin(0.0)
147 | .setMax(1.0)
148 | .setValue(1.0)
149 | .setId(9)
150 | .moveTo(layerG[n])
151 | ;
152 | Layer_fadeOutAlpha[n].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
153 |
154 | Layer_fadeOutDuration[n] = gui.addSlider("Layer_fadeOutDuration"+n)
155 | .setPosition(240,330)
156 | .setSize(185,10)
157 | .setMin(0.0)
158 | .setMax(20.0)
159 | .setValue(0.0)
160 | .setId(10)
161 | .moveTo(layerG[n])
162 | ;
163 | Layer_fadeOutDuration[n].getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
164 |
165 | Layer_Reset[n] = gui.addButton("Layer_Reset"+n)
166 | .setPosition(400,40)
167 | .setSize(80,10)
168 | .setId(11)
169 | .moveTo(layerG[n])
170 | ;
171 | Layer_Reset[n].getCaptionLabel().align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
172 |
173 | // add to accordion
174 | LayersGui.addItem(layerG[n]);
175 | }
176 | LayersGui.open(7);
177 | }
--------------------------------------------------------------------------------
/GuiEvents.pde:
--------------------------------------------------------------------------------
1 | void controlEvent(ControlEvent event){
2 | if(event.isGroup()){
3 | // println(event.getGroup().getName()+" is Group");
4 |
5 | /////////////////////////////////////////////////Clip Events
6 | if(event.isFrom("clipList")){
7 | if(!event.getGroup().isOpen()){
8 | fill(20);
9 | rect(0,0,500,300);
10 | }
11 | }
12 |
13 | else if(event.isFrom("Clip_LectureMode")){
14 | editClip.lectureMode = (int)event.getGroup().getValue();
15 | if(editClip.lectureMode == 0 && editClip.movie != null) editClip.movie.loop();
16 | // println("editClip.lectureMode: "+editClip.lectureMode);
17 | }
18 |
19 | else if(event.isFrom("Clip_Effect")){
20 | editClip.blendMode = (int)event.getGroup().getValue();
21 | // println("editClip.blendMode: "+editClip.blendMode);
22 | }
23 |
24 | else if(event.isFrom("Add_to_Layer")){
25 | addTo = (int)event.getGroup().getValue();
26 | // println("editClip.blendMode: "+editClip.blendMode);
27 | }
28 |
29 | /////////////////////////////////////////////////Edit Layer choice
30 | else if((event.getGroup().getName().substring(0,5)).equals("Layer")){
31 | String s = event.getGroup().getName();
32 | // println(s);
33 | editLayer = int(Character.toString(s.charAt(s.length()-1)));
34 | // println(editLayer);
35 | for (int i = 0; i10 && (s.substring(6,10)).equals("Clip")){
80 | // get number of the Layer
81 | int n = int(s.substring(5,6));
82 | // println("Layer: "+n);
83 | layers[n].isEditLayer = true;
84 | updateLayerClip = new int[]{n, int(Character.toString(s.charAt(s.length()-1)))};
85 | println("updateLayerClip: Layer"+updateLayerClip[0]+" Clip"+updateLayerClip[1]);
86 | if(gui.getGroup("clipList").isOpen()) gui.getGroup("clipList").close();
87 | fill(20);
88 | rect(0,0,500,300);
89 | setEditClip(updateLayerClip);
90 | }
91 | else{
92 | // get number of the Layer
93 | int n = int(Character.toString(s.charAt(s.length()-1)));
94 | // println("Layer: "+n);
95 | layers[n].isEditLayer = true;
96 |
97 | switch(event.controller().id()){
98 | case(0): // Layer_Timeline
99 | // layers[n].Timeline = event.controller().value();
100 | break;
101 | case(1): // Layer_Duration
102 | // layers[n].Duration = event.controller().value();
103 | break;
104 | case(2): // Layer_PlayPause
105 | if(layers[n].clips.size()>0 && !composition.isPlaying){
106 | layers[n].isPlaying = boolean(int(event.controller().value()));
107 | if(layers[n].isPlaying){
108 | if(!layers[n].clips.get(layers[n].currentClip).movie.isPlaying()){
109 | layers[n].clips.get(layers[n].currentClip).movie.play();
110 | layers[n].clips.get(layers[n].currentClip).timer=millis();
111 | }
112 | layers[n].timer = millis();
113 | }
114 | else{
115 | if((layers[n].clips).get(layers[n].currentClip).movie.isPlaying()){// if layer.currentClip is playing -> pause
116 | (layers[n].clips).get(layers[n].currentClip).movie.pause();
117 | }
118 | }
119 | }
120 | // println("layers["+n+"].isPlaying: "+layers[n].isPlaying);
121 | break;
122 | case(3): // Layer_XY
123 | layers[n].posX = map(event.getController().arrayValue()[0],-100,100,-1,1);
124 | // println("layers["+n+"].posX: "+layers[n].posX);
125 | layers[n].posY = map(event.getController().arrayValue()[1],-100,100,-1,1);
126 | // println("layers["+n+"].posY: "+layers[n].posY);
127 | break;
128 | case(4): // Layer_Scale
129 | layers[n].Scale = event.controller().value();
130 | // println("layers["+n+"].Scale: "+layers[n].Scale);
131 | break;
132 | case(5): // Layer_Opacity
133 | layers[n].TargetOpacity = event.controller().value();
134 | // println("layers["+n+"].Opacity: "+layers[n].Opacity);
135 | break;
136 | case(6): // Layer_Delay
137 | layers[n].Delay = event.controller().value();
138 | // println("layers["+n+"].Delay: "+layers[n].Delay);
139 |
140 | float MaxLayerDuration=0.0;
141 | for(int i=0; iMaxLayerDuration){
143 | MaxLayerDuration = layers[n].Delay+layers[n].duration;
144 | }
145 | }
146 | composition.duration = MaxLayerDuration;
147 | Composition_Duration.setText("DURATION: "+composition.duration);
148 | break;
149 | case(7): // Layer_fadeInAlpha
150 | layers[n].fadeInAlpha = event.controller().value();
151 | // println("layers["+n+"].fadeInAlpha: "+layers[n].fadeInAlpha);
152 | break;
153 | case(8): // Layer_fadeInDuration
154 | layers[n].fadeInDuration = event.controller().value();
155 | // println("layers["+n+"].fadeInDuration: "+layers[n].fadeInDuration);
156 | break;
157 | case(9): // Layer_fadeOutAlpha
158 | layers[n].fadeOutAlpha = event.controller().value();
159 | // println("layers["+n+"].fadeOutAlpha: "+layers[n].fadeOutAlpha);
160 | break;
161 | case(10):// Layer_fadeOutDuration
162 | layers[n].fadeOutDuration = event.controller().value();
163 | // println("layers["+n+"].fadeOutDuration: "+layers[n].fadeOutDuration);
164 | break;
165 | case(11):
166 | layers[n].resetLayer();
167 | break;
168 | }
169 | }
170 | }
171 | }
172 | }
173 |
174 | void setEditClip(int[] n) {
175 | // stop editClip
176 | if(editClip.movieNum!=999) editClip.movie.stop();
177 | editClip.isEditClip = false;
178 |
179 | editClip.movieNum = layers[n[0]].clips.get(n[1]).movieNum;
180 | editClip.duration = layers[n[0]].clips.get(n[1]).duration;
181 | editClip.lectureMode = layers[n[0]].clips.get(n[1]).lectureMode;
182 | editClip.nbRepeat = layers[n[0]].clips.get(n[1]).nbRepeat;
183 | editClip.movieSpeed = layers[n[0]].clips.get(n[1]).movieSpeed;
184 | editClip.TargetOpacity = layers[n[0]].clips.get(n[1]).TargetOpacity;
185 | editClip.posX = layers[n[0]].clips.get(n[1]).posX;
186 | editClip.posY = layers[n[0]].clips.get(n[1]).posY;
187 | editClip.Scale = layers[n[0]].clips.get(n[1]).Scale;
188 | editClip.fadeInAlpha = layers[n[0]].clips.get(n[1]).fadeInAlpha;
189 | editClip.fadeInDuration = layers[n[0]].clips.get(n[1]).fadeInDuration;
190 | editClip.fadeOutAlpha = layers[n[0]].clips.get(n[1]).fadeOutAlpha;
191 | editClip.fadeOutDuration = layers[n[0]].clips.get(n[1]).fadeOutDuration;
192 | editClip.blendMode = layers[n[0]].clips.get(n[1]).blendMode;
193 |
194 | editClip.isEditClip = true;
195 | editClip.setVideo();
196 |
197 | Clip_Duration.setText("DURATION: "+editClip.duration*editClip.nbRepeat/editClip.movieSpeed);
198 | Clip_LectureMode.setIndex(editClip.lectureMode);
199 | Clip_nbRepeat.setValue(editClip.nbRepeat);
200 | Clip_Speed.setValue(editClip.movieSpeed);
201 | Clip_XY.setArrayValue(new float[]{map(editClip.posX,-1,1,0,200), map(editClip.posY,-1,1,0,200)});
202 | Clip_Scale.setValue(editClip.Scale);
203 | Clip_fadeInAlpha.setValue(editClip.fadeInAlpha);
204 | Clip_fadeInDuration.setValue(editClip.fadeInDuration);
205 | Clip_fadeOutAlpha.setValue(editClip.fadeOutAlpha);
206 | Clip_fadeOutDuration.setValue(editClip.fadeOutDuration);
207 | Clip_Opacity.setValue(editClip.TargetOpacity);
208 | Clip_Effect.setValue(editClip.blendMode);
209 | Update_ClipId.setText("LAYER"+n[0]+" CLIP"+n[1]);
210 | }
--------------------------------------------------------------------------------
/ClipGui.pde:
--------------------------------------------------------------------------------
1 | int currentButton=0;
2 | Slider Clip_Timeline;
3 | Textlabel Clip_Duration;
4 | DropdownList Clip_LectureMode;
5 | Slider Clip_nbRepeat;
6 | Slider Clip_Speed;
7 | Slider2D Clip_XY;
8 | Slider Clip_Scale;
9 | Slider Clip_fadeInAlpha;
10 | Slider Clip_fadeInDuration;
11 | Slider Clip_fadeOutAlpha;
12 | Slider Clip_fadeOutDuration;
13 | Slider Clip_Opacity;
14 | DropdownList Clip_Effect;
15 | DropdownList Add_to_Layer;
16 | int addTo=0;
17 | Button Update_Clip;
18 | Textlabel Update_ClipId;
19 |
20 | class ImageButton implements ControllerView {
21 | PImage img = thumbnails[currentButton];
22 | public void display(PApplet theApplet, Button theButton) {
23 | theApplet.pushMatrix();
24 | image(img,0,0);
25 | if (theButton.isInside()) {
26 | if (theButton.isPressed()) { // button is pressed
27 | theApplet.fill(0,0);
28 | } else { // mouse hovers the button
29 | theApplet.fill(0, 0);
30 | }
31 | } else { // the mouse is located outside the button area
32 | theApplet.fill(0, 120);
33 | }
34 |
35 | theApplet.rect(0, 0, 45, 45);
36 |
37 | theApplet.popMatrix();
38 | }
39 | }
40 |
41 | void initClipGui() {
42 | Group clipList = gui.addGroup("clipList")
43 | .setBackgroundColor(color(0))
44 | .setPosition(5,10)
45 | .setWidth(490)
46 | .setBackgroundHeight(280)
47 | .activateEvent(true)
48 | ;
49 | for(int i=0; icomposition.duration){
375 | composition.duration = layers[addTo].duration;
376 | Composition_Duration.setText("DURATION: "+composition.duration);
377 | }
378 | }
379 | }
380 |
381 | void Update_Clip(){
382 | if(updateLayerClip[0] != 999 && !updatingClip){
383 | updatingClip=true;
384 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).movie.stop();
385 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).movieNum = editClip.movieNum;
386 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).duration = editClip.duration;
387 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).lectureMode = editClip.lectureMode;
388 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).nbRepeat = editClip.nbRepeat;
389 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).movieSpeed = editClip.movieSpeed;
390 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).TargetOpacity = editClip.TargetOpacity;
391 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).posX = editClip.posX;
392 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).posY = editClip.posY;
393 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).Scale = editClip.Scale;
394 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).fadeInAlpha = editClip.fadeInAlpha;
395 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).fadeInDuration = editClip.fadeInDuration;
396 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).fadeOutAlpha = editClip.fadeOutAlpha;
397 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).fadeOutDuration = editClip.fadeOutDuration;
398 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).blendMode = editClip.blendMode;
399 | layers[updateLayerClip[0]].clips.get(updateLayerClip[1]).setVideo();
400 |
401 | // calcul new LayerDuration
402 | float updateLayerDuration=0.0;
403 | for(int i=0; icomposition.duration){
411 | composition.duration = updateLayerDuration;
412 | Composition_Duration.setText("DURATION: "+composition.duration);
413 | }
414 |
415 | updateLayerClip = new int[]{999,999};
416 | Update_ClipId.setText("LAYER_ CLIP_");
417 | updatingClip=false;
418 | }
419 | }
420 |
421 | void resetEditClip(){
422 | editClip.movie.stop();
423 | editClip.tex.delete();
424 | editClip.texFiltered.delete();
425 | editClip = new Clip(this);
426 | editClip.isEditClip = true;
427 | initClipGui();
428 | }
--------------------------------------------------------------------------------
/CompositionGui.pde:
--------------------------------------------------------------------------------
1 | /*
2 | Missing features:
3 | ControlP5.Ranges could be added to composition GUI to show position of layers
4 | */
5 |
6 | Slider Composition_Timeline;
7 | Textlabel Composition_Duration;
8 | Button Composition_Save;
9 | Button Composition_Load;
10 | Button Composition_Reset;
11 |
12 | void initCompositionGui(){
13 | Group compositionGui = gui.addGroup("Composition")
14 | .setBackgroundColor(color(0))
15 | .setPosition(1005,310)
16 | .setWidth(490)
17 | .setBackgroundHeight(490)
18 | .disableCollapse()
19 | ;
20 |
21 | Composition_Timeline = gui.addSlider("Composition_Timeline")
22 | .setPosition(10,10)
23 | .setSize(470,10)
24 | .setRange(0,1)
25 | .moveTo(compositionGui)
26 | ;
27 | Composition_Timeline.getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
28 |
29 | Composition_Duration = gui.addTextlabel("Composition_Duration")
30 | .setText("DURATION: 0.00")
31 | .setPosition(380,23)
32 | .moveTo(compositionGui)
33 | ;
34 |
35 | gui.addToggle("Composition_PlayPause")
36 | .setPosition(10,40)
37 | .setSize(80,10)
38 | .moveTo(compositionGui)
39 | ;
40 |
41 | Composition_Reset = gui.addButton("Composition_Reset")
42 | .setPosition(400,40)
43 | .setSize(80,10)
44 | .moveTo(compositionGui)
45 | ;
46 | Composition_Reset.getCaptionLabel().align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
47 |
48 | Composition_Save = gui.addButton("Composition_Save")
49 | .setPosition(10,100)
50 | .setSize(80,10)
51 | .moveTo(compositionGui)
52 | ;
53 | Composition_Save.getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
54 |
55 | Composition_Load = gui.addButton("Composition_Load")
56 | .setPosition(150,100)
57 | .setSize(80,10)
58 | .moveTo(compositionGui)
59 | ;
60 | Composition_Load.getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
61 | }
62 |
63 | void Composition_PlayPause(boolean b){
64 | composition.isPlaying = b;
65 | for (int i = 0; icomposition.duration) composition.duration = layers[i].duration;
232 | }
233 | Composition_Duration.setText("DURATION: "+composition.duration);
234 | Composition_Timeline.setRange(0.0, composition.duration);
235 | Composition_Timeline.setValue(0.0);
236 | Composition_Timeline.getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
237 | }
238 | }
239 |
240 | // quick access 'r' || 'R'
241 | void Composition_Reset(){
242 | composition.isPlaying=false;
243 | for (int i = 0; icomposition.duration) composition.duration = layers[i].duration;
328 | }
329 | Composition_Duration.setText("DURATION: "+composition.duration);
330 | Composition_Timeline.setRange(0.0, composition.duration);
331 | Composition_Timeline.setValue(0.0);
332 | Composition_Timeline.getCaptionLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
333 | }
--------------------------------------------------------------------------------