Bonjour a tous,

Cela fait un petit moment que je suis sur un problème que je n'arrive pas à résoudre (et oui, forcement, sinon ce ne serait pas un probleme !!)
Je dois développer une méthode qui permet de créer un fichier vidéo qui est le résultat de deux fichiers vidéos collés.
J'ai cherché un peu partout sur le net et ai trouvé quelques solutions, notamment sur la doc de JMF, mais sans succès. J'utilise la méthode createMergingDataSource qui a pour but, si je ne me trompe pas, de "merger" plusieurs flux. Or, lorsque je lance mon application, j'ai cette erreur la :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
com.sun.media.multiplexer.BasicMux$BasicMuxDataSource@1f06dc3
com.sun.media.multiplexer.BasicMux$BasicMuxDataSource@1b64e6a
Exception in thread "main" javax.media.NoProcessorException: Cannot find a Processor for: com.ibm.media.protocol.MergingPushDataSource@f8f7db
        at javax.media.Manager.createProcessorForSource(Manager.java:1766)
        at javax.media.Manager.createProcessor(Manager.java:666)
        at model.Paste.makeMovie(Paste.java:167)
        at model.Paste.<init>(Paste.java:49)
        at controller.Interact.<init>(Interact.java:21)
        at controller.Interact.main(Interact.java:14)

Je vous transmets mon code :


le main qui se situe dans une autre classe :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
public static void main(String[] args) throws Exception {
            File fichier=new File("C:\\Users\\Joe\\Desktop\\Montage_Video_temp\\Montage_Video\\sample.avi");
            File f1 = new File("C:\\Users\\Joe\\Desktop\\Montage_Video_temp\\Montage_Video\\test1.avi");
            File f2 = new File("C:\\Users\\Joe\\Desktop\\Montage_Video_temp\\Montage_Video\\test2.avi");
            Paste p = new Paste(fichier,f1,f2);
}
ma classe qui est chargée de la création du resultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
package model;

import java.io.*;
import java.util.*;
import java.awt.Dimension;
import java.awt.Image;
import java.net.MalformedURLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.*;
import javax.media.control.*;
import javax.media.protocol.*;
import javax.media.protocol.DataSource;
import javax.media.datasink.*;
import javax.media.format.VideoFormat;
import javax.media.util.ImageToBuffer;

public class Paste implements ControllerListener, DataSinkListener{

    private Object waitSync = new Object();
    private Object waitFileSync = new Object();
    private boolean stateTransitionOK = true;
    private boolean fileDone = false;
    private boolean fileSuccess = true;
    private MediaLocator outML;
    private Processor processor;
    private MediaLocator inML;
    private MediaLocator outML2;
    private Processor processor2;
    private MediaLocator inML2;
    private File output;
    private File input1;
    private File input2;


    public Paste (File outputFile,File inputFile1,File inputFile2) throws Exception {

        output = outputFile;
        input1 = inputFile1;
        input2 = inputFile2;
        this.inML = new MediaLocator(inputFile1.toURL());
        this.inML2 = new MediaLocator(inputFile2.toURL());
        this.processor = createProcessorFile1(outputFile);

        this.processor2 = createProcessorFile2(outputFile);

        this.outML = new MediaLocator(outputFile.toURL());
        this.outML2 = new MediaLocator(outputFile.toURL());
        makeMovie();
    }

     private Processor createProcessorFile1(File outputFile) throws Exception {
        Processor p= null;
        try{
            System.out.println("- create processor for the image datasource ...");
            p = Manager.createProcessor(this.inML);
        }
        catch (Exception e){
            System.err.println("Yikes! Cannot create a processor from the data source.");
        }

        p.addControllerListener(this);

        // Put the Processor into configured state so we can set
        // some processing options on the processor.
        p.configure();
        if (!waitForState(p, Processor.Configured))
        {
            System.err.println("Failed to configure the processor.");
        }

        if (outputFile.getName().toLowerCase().endsWith(".mov")) {
            // Set the output content descriptor to QuickTime.
            p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.QUICKTIME));
        } else if (outputFile.getName().toLowerCase().endsWith(".avi")) {
            // Set the output content descriptor to AVI (MSVIDEO).
            p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.MSVIDEO));
        } else {
         throw new IllegalArgumentException("unsupported file extension: "+ outputFile.getName());
        }

        return p;
     }

     private Processor createProcessorFile2(File outputFile) throws Exception {
        Processor p =null;
        try{
            System.out.println("- create processor for the image datasource ...");
            p = Manager.createProcessor(this.inML2);
        }
        catch (Exception e){
            System.err.println("Yikes! Cannot create a processor from the data source.");
        }

        p.addControllerListener(this);

        // Put the Processor into configured state so we can set
        // some processing options on the processor.
        p.configure();
        if (!waitForState(p, Processor.Configured))
        {
            System.err.println("Failed to configure the processor.");
        }

        if (outputFile.getName().toLowerCase().endsWith(".mov")) {
            // Set the output content descriptor to QuickTime.
            p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.QUICKTIME));
        } else if (outputFile.getName().toLowerCase().endsWith(".avi")) {
            // Set the output content descriptor to AVI (MSVIDEO).
            p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.MSVIDEO));
        } else {
         throw new IllegalArgumentException("unsupported file extension: "+ outputFile.getName());
        }

        return p;
     }

     public void makeMovie() throws Exception {


        // We are done with programming the processor. Let's just
        // realize it.
        processor.realize();
        if (!waitForState(processor, Processor.Realized))
        {
            System.err.println("Failed to realize the processor.");
        }

        processor2.realize();
        if (!waitForState(processor2, Processor.Realized))
        {
            System.err.println("Failed to realize the processor.");
        }

       /* // Now, we'll need to create a DataSink.
        DataSink dsink;
        if ((dsink = createDataSink(processor, outML)) == null)
        {
            System.err.println("Failed to create a DataSink for the given output MediaLocator: "+ outML);
        }

                // Now, we'll need to create a DataSink.
        DataSink dsink2;
        if ((dsink2 = createDataSink(processor2, outML)) == null)
        {
            System.err.println("Failed to create a DataSink for the given output MediaLocator: "+ outML);
        }*/
        DataSource ds[] = new DataSource[2];
        ds[0] = processor.getDataOutput();
        ds[1] = processor2.getDataOutput();

        System.out.println(ds[0]);
        System.out.println(ds[1]);
        DataSource src = Manager.createMergingDataSource(ds);
        
        Processor proc =  Manager.createProcessor(src );
        DataSource temp = proc.getDataOutput();
        DataSink dsink = Manager.createDataSink(temp, outML);



        fileDone = false;
        System.out.println("start processing...");

        // OK, we can now start the actual transcoding.
        try{

            dsink.open();
            dsink.start();
            proc.start();

        }
        catch (IOException e){
            System.err.println("IO error during processing");
        }

        // Wait for EndOfStream event.
        waitForFileDone();

        // Cleanup.
        try{
            proc.stop();
            proc.close();
            dsink.close();
        }
        catch (Exception e){
        }


        System.out.println("...done processing.");


    }

    /**
    * Create the DataSink.
    */
    private DataSink createDataSink(Processor p, MediaLocator outML,DataSource ds) throws IncompatibleSourceException, IOException, NoDataSourceException
    {

       // DataSource ds = p.getDataOutput();

       /* if ((ds = p.getDataOutput()) == null)
        {
            System.err.println("Something is really wrong: the processor does not have an output DataSource");
            return null;
        }*/

        DataSink dsink;

        try{
            System.out.println("- create DataSink for: " + outML);
            dsink = Manager.createDataSink(ds, outML);
            dsink.open();
        }
        catch (Exception e){
            e.printStackTrace();
            System.err.println("Cannot create the DataSink: " + e);
            return null;
        }

        return dsink;
    }



    /**
    * Block until the processor has transitioned to the given state.
    * Return false if the transition failed.
    */
    private boolean waitForState(Processor p, int state)
    {
        synchronized (waitSync)
        {
            try{
                while (p.getState() < state && stateTransitionOK)
                    waitSync.wait();
            }
            catch (Exception e){
            }
        }
        return stateTransitionOK;
    }

    /**
    * Controller Listener.
    */
    public void controllerUpdate(ControllerEvent evt)
    {

        if (evt instanceof ConfigureCompleteEvent
            || evt instanceof RealizeCompleteEvent
            || evt instanceof PrefetchCompleteEvent)
        {
            synchronized (waitSync)
            {
                stateTransitionOK = true;
                waitSync.notifyAll();
            }
        }
        else if (evt instanceof ResourceUnavailableEvent)
        {
            synchronized (waitSync)
            {
                stateTransitionOK = false;
                waitSync.notifyAll();
            }
        }
        else if (evt instanceof EndOfMediaEvent)
        {
            evt.getSourceController().stop();
            evt.getSourceController().close();
        }
    }



    /**
    * Block until file writing is done.
    */
    private boolean waitForFileDone()
    {
        synchronized (waitFileSync)
        {
            try
            {
                while (!fileDone)
                    waitFileSync.wait();
            }
            catch (Exception e)
            {
            }
        }
        return fileSuccess;
    }

    /**
    * Event handler for the file writer.
    */
    public void dataSinkUpdate(DataSinkEvent evt)
    {

        if (evt instanceof EndOfStreamEvent)
        {
            synchronized (waitFileSync)
            {
                fileDone = true;
                waitFileSync.notifyAll();
            }
        }
        else if (evt instanceof DataSinkErrorEvent)
        {
            synchronized (waitFileSync)
            {
                fileDone = true;
                fileSuccess = false;
                waitFileSync.notifyAll();
            }
        }
    }
}
J'ai mis en rouge la ligne qui me crée l'erreur.
Pour information, lorsque j'utilise mon code avec une seule video en entrée, il n'y a aucun problème (ma vidéo en entrée est bien copié dans un autre fichier) si ce n'est une perte de 2 Ko.

Voila , je remercie d'avance toutes les personnes qui se pencheront sur mon cas et qui voudront bien m'aider.

Je développe sous Netbeans, avec la derniere version de java.

John