1 2 3 Previous Next 30 Replies Latest reply: Apr 28, 2011 11:25 AM by 856191 Go to original post RSS
      • 15. Re: JMF - Concurrent video feed and image capture
        captfoss
        853188 wrote:
        Only problem now is how to record and save video. Any tips?
        Pretty sure I explained that above.

        You need to program the tracks on your processor to output the format that you want to save the video in, and then hand the output DataSource of the Processor to a DataSink... and then startup the system.

        Best example of seeing all of these concepts in motion is probably the transcode example:
        http://www.cs.odu.edu/~cs778/spring04/lectures/jmfsolutions/examplesindex.html#transcode
        • 16. Re: JMF - Concurrent video feed and image capture
          856191
          captfoss wrote:
          853188 wrote:
          Only problem now is how to record and save video. Any tips?
          Pretty sure I explained that above.

          You need to program the tracks on your processor to output the format that you want to save the video in, and then hand the output DataSource of the Processor to a DataSink... and then startup the system.

          Best example of seeing all of these concepts in motion is probably the transcode example:
          http://www.cs.odu.edu/~cs778/spring04/lectures/jmfsolutions/examplesindex.html#transcode
          Problem I'm running into is the fact that it can't create a DataSink. I'm sure I'll find more problems with my code after I get past this piece, but for now I can't seem to figure out what is going wrong.

          Code:
          import java.awt.*;
          import java.util.Vector;
          import java.io.File;
          import javax.media.*;
          import javax.media.control.TrackControl;
          import javax.media.control.QualityControl;
          import javax.media.Format;
          import javax.media.format.*;
          import javax.media.datasink.*;
          import javax.media.protocol.*;
          import java.io.IOException;
          
          /**
           * A sample program to transcode an input source to an output location with
           * different data formats.
           */
          public class Transcode implements ControllerListener, DataSinkListener {
          
               /**
                * Given a source media locator, destination media locator and an array of
                * formats, this method will transcode the source to the dest into the
                * specified formats.
                */
               public boolean doIt(MediaLocator inML, MediaLocator outML, Format fmts[],
                         int start, int end) {
          
                    Processor p;
          
                    try {
                         System.err.println("- create processor for: " + inML);
                         p = Manager.createProcessor(inML);
                    } catch (Exception e) {
                         System.err.println("Yikes!  Cannot create a processor from the given url: " + e);
                         return false;
                    }
          
                    p.addControllerListener(this);
          
                    // Put the Processor into configured state.
                    p.configure();
                    if (!waitForState(p, p.Configured)) {
                         System.err.println("Failed to configure the processor.");
                         return false;
                    }
          
                    // Set the output content descriptor based on the media locator.
                    setContentDescriptor(p, outML);
          
                    // Program the tracks to the given output formats.
                    if (!setTrackFormats(p, fmts))
                         return false;
          
                    // We are done with programming the processor. Let's just
                    // realize the.
                    p.realize();
                    if (!waitForState(p, p.Realized)) {
                         System.err.println("Failed to realize the processor.");
                         return false;
                    }
          
                    // Set the JPEG quality to .5.
                    setJPEGQuality(p, 0.10f);
          
                    // Now, we'll need to create a DataSink.
                    DataSink dsink;
                    if ((dsink = createDataSink(p, outML)) == null) {
                         System.err.println("Failed to create a DataSink for the given output MediaLocator: " + outML);
                         return false;
                    }
          
                    dsink.addDataSinkListener(this);
                    fileDone = false;
          
                    // Set the start time if there's one set.
                    if (start > 0)
                         p.setMediaTime(new Time((double) start));
          
                    // Set the stop time if there's one set.
                    if (end > 0)
                         p.setStopTime(new Time((double) end));
          
                    System.err.println("start transcoding...");
          
                    // OK, we can now start the actual transcoding.
                    try {
                         p.start();
                         dsink.start();
                    } catch (IOException e) {
                         System.err.println("IO error during transcoding");
                         return false;
                    }
          
                    // Wait for EndOfStream event.
                    waitForFileDone();
          
                    // Cleanup.
                    try {
                         dsink.close();
                    } catch (Exception e) {
                    }
                    p.removeControllerListener(this);
          
                    System.err.println("...done transcoding.");
          
                    return true;
               }
          
               /**
                * Set the content descriptor based on the given output MediaLocator.
                */
               void setContentDescriptor(Processor p, MediaLocator outML) {
          
                    ContentDescriptor cd;
          
                    // If the output file maps to a content type,
                    // we'll try to set it on the processor.
          
                    if ((cd = fileExtToCD(outML.getRemainder())) != null) {
          
                         System.err.println("- set content descriptor to: " + cd);
          
                         if ((p.setContentDescriptor(cd)) == null) {
          
                              // The processor does not support the output content
                              // type. But we can set the content type to RAW and
                              // see if any DataSink supports it.
          
                              p.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW));
                         }
                    }
               }
          
               /**
                * Set the target transcode format on the processor.
                */
               boolean setTrackFormats(Processor p, Format fmts[]) {
          
                    if (fmts.length == 0)
                         return true;
          
                    TrackControl tcs[];
          
                    if ((tcs = p.getTrackControls()) == null) {
                         // The processor does not support any track control.
                         System.err
                                   .println("The Processor cannot transcode the tracks to the given formats");
                         return false;
                    }
          
                    for (int i = 0; i < fmts.length; i++) {
          
                         System.err.println("- set track format to: " + fmts);

                         if (!setEachTrackFormat(p, tcs, fmts[i])) {
                              System.err.println("Cannot transcode any track to: " + fmts[i]);
                              return false;
                         }
                    }

                    return true;
               }

               /**
               * We'll loop through the tracks and try to find a track that can be
               * converted to the given format.
               */
               boolean setEachTrackFormat(Processor p, TrackControl tcs[], Format fmt) {

                    Format supported[];
                    Format f;

                    for (int i = 0; i < tcs.length; i++) {

                         supported = tcs[i].getSupportedFormats();

                         if (supported == null)
                              continue;

                         for (int j = 0; j < supported.length; j++) {

                              if (fmt.matches(supported[j])
                                        && (f = fmt.intersects(supported[j])) != null
                                        && tcs[i].setFormat(f) != null) {

                                   // Success.
                                   return true;
                              }
                         }
                    }

                    return false;
               }

               /**
               * Setting the encoding quality to the specified value on the JPEG encoder.
               * 0.5 is a good default.
               */
               void setJPEGQuality(Player p, float val) {

                    Control cs[] = p.getControls();
                    QualityControl qc = null;
                    VideoFormat jpegFmt = new VideoFormat(VideoFormat.JPEG);

                    // Loop through the controls to find the Quality control for
                    // the JPEG encoder.
                    for (int i = 0; i < cs.length; i++) {

                         if (cs[i] instanceof QualityControl && cs[i] instanceof Owned) {
                              Object owner = ((Owned) cs[i]).getOwner();

                              // Check to see if the owner is a Codec.
                              // Then check for the output format.
                              if (owner instanceof Codec) {
                                   Format fmts[] = ((Codec) owner)
                                             .getSupportedOutputFormats(null);
                                   for (int j = 0; j < fmts.length; j++) {
                                        if (fmts[j].matches(jpegFmt)) {
                                             qc = (QualityControl) cs[i];
                                             qc.setQuality(val);
                                             System.err.println("- Set quality to " + val
                                                       + " on " + qc);
                                             break;
                                        }
                                   }
                              }
                              if (qc != null)
                                   break;
                         }
                    }
               }

               /**
               * Create the DataSink.
               */
               DataSink createDataSink(Processor p, MediaLocator outML) {

                    DataSource ds;
                    try {
                         ds = Manager.createDataSource(outML);
                    } catch (NoDataSourceException e1) {
                         // TODO Auto-generated catch block
                         e1.printStackTrace();
                    } catch (IOException e1) {
                         // TODO Auto-generated catch block
                         e1.printStackTrace();
                    }

                    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.err.println("- create DataSink for: " + outML);
                         dsink = Manager.createDataSink(ds, outML);
                         dsink.open();
                    } catch (Exception e) {
                         System.err.println("Cannot create the DataSink: " + e);
                         return null;
                    }

                    return dsink;
               }

               Object waitSync = new Object();
               boolean stateTransitionOK = true;

               /**
               * Block until the processor has transitioned to the given state. Return
               * false if the transition failed.
               */
               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().close();
                    } else if (evt instanceof MediaTimeSetEvent) {
                         System.err.println("- mediaTime set: "
                                   + ((MediaTimeSetEvent) evt).getMediaTime().getSeconds());
                    } else if (evt instanceof StopAtTimeEvent) {
                         System.err.println("- stop at time: "
                                   + ((StopAtTimeEvent) evt).getMediaTime().getSeconds());
                         evt.getSourceController().close();
                    }
               }

               Object waitFileSync = new Object();
               boolean fileDone = false;
               boolean fileSuccess = true;

               /**
               * Block until file writing is done.
               */
               boolean waitForFileDone() {
                    System.err.print(" ");
                    synchronized (waitFileSync) {
                         try {
                              while (!fileDone) {
                                   waitFileSync.wait(1000);
                                   System.err.print(".");
                              }
                         } catch (Exception e) {
                         }
                    }
                    System.err.println("");
                    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();
                         }
                    }
               }

               /**
               * Convert a file name to a content type. The extension is parsed to
               * determine the content type.
               */
               ContentDescriptor fileExtToCD(String name) {

                    String ext;
                    int p;

                    // Extract the file extension.
                    if ((p = name.lastIndexOf('.')) < 0)
                         return null;

                    ext = (name.substring(p + 1)).toLowerCase();

                    String type;

                    // Use the MimeManager to get the mime type from the file extension.
                    if (ext.equals("mp3")) {
                         type = FileTypeDescriptor.MPEG_AUDIO;
                    } else {
                         if ((type = com.sun.media.MimeManager.getMimeType(ext)) == null)
                              return null;
                         type = ContentDescriptor.mimeTypeToPackageName(type);
                    }

                    return new FileTypeDescriptor(type);
               }

               /**
               * Main program
               */
               public static void main(String[] args) {

                    int mediaStart = -1, mediaEnd = -1;
                    CameraLocator cam = new CameraLocator();
                    MediaLocator iml = cam.getLocator();
                    MediaLocator oml = new MediaLocator("C:/movePics/out.mpeg");
          //          int j = 0;
                    Format fmts[] = { new VideoFormat(VideoFormat.RGB) };

                    // Parse the video format spec. into real VideoFormat's.
          //          for (int i = 0; i < vidFmt.size(); i++) {
          //
          //               if ((fmt = parseVideoFormat((String) vidFmt.elementAt(i))) == null) {
          //                    System.err.println("Invalid video format specification: "
          //                              + (String) vidFmt.elementAt(i));
          //                    prUsage();
          //               }
          //               fmts[j++] = fmt;
          //          }

                    // Trancode with the specified parameters.
                    Transcode transcode = new Transcode();

                    if (!transcode.doIt(iml, oml, fmts, mediaStart, mediaEnd)) {
                         System.err.println("Transcoding failed");
                    }

                    System.exit(0);
               }


               /**
               * Parse the video format specifier and generate an VideoFormat. A valid
               * video format specifier is of the form: [encoding]:[widthXheight]
               */
               static Format parseVideoFormat(String fmtStr) {

                    String encodeStr = null, sizeStr = null;

                    // Parser the media locator to extract the requested format.

                    if (fmtStr != null && fmtStr.length() > 0) {
                         while (fmtStr.length() > 1 && fmtStr.charAt(0) == ':')
                              fmtStr = fmtStr.substring(1);

                         // Now see if there's a encode rate specified.
                         int off = fmtStr.indexOf(':');
                         if (off == -1) {
                              if (!fmtStr.equals(""))
                                   encodeStr = fmtStr;
                         } else {
                              encodeStr = fmtStr.substring(0, off);
                              sizeStr = fmtStr.substring(off + 1);
                         }
                    }

                    if (encodeStr == null || encodeStr.equals(""))
                         prUsage();

                    if (sizeStr == null)
                         return new VideoFormat(encodeStr);

                    int width = 320, height = 240;

                    int off = sizeStr.indexOf('X');
                    if (off == -1)
                         off = sizeStr.indexOf('x');

                    if (off == -1) {
                         System.err.println("Video dimension is not correctly specified: " + sizeStr);
                         prUsage();
                    } else {
                         String widthStr = sizeStr.substring(0, off);
                         String heightStr = sizeStr.substring(off + 1);

                         try {
                              Integer integer = Integer.valueOf(widthStr);
                              if (integer != null)
                                   width = integer.intValue();
                              integer = Integer.valueOf(heightStr);
                              if (integer != null)
                                   height = integer.intValue();
                         } catch (Throwable t) {
                              prUsage();
                         }

                         return new VideoFormat(encodeStr, new Dimension(width, height),
                                   VideoFormat.NOT_SPECIFIED, // maxDataLen
                                   null, // data class
                                   VideoFormat.NOT_SPECIFIED // FrameRate
                         );
                    }

                    return null;
               }

               static void prUsage() {
                    System.err
                              .println("Usage: java Transcode -o <output> -a <audio format> -v <video format> -s <start time> -e <end time> <input>");
                    System.err.println(" <output>: input URL or file name");
                    System.err.println(" <input>: output URL or file name");
                    System.err
                              .println(" <audio format>: [encoding]:[rate]:[sizeInBits]:[channels]:big:signed");
                    System.err.println(" <video format>: [encoding]:[widthXheight]");
                    System.err.println(" <start time>: start time in seconds");
                    System.err.println(" <end time>: end time in seconds");
                    System.exit(0);
               }
          }
          This is the output I receive:
          
          {quote}
          - create processor for: vfw://0
          - set track format to: RGB
          javax.media.NoDataSourceException: Cannot find a DataSource for: C:/movePics/out.mpeg
                  at javax.media.Manager.createDataSource(Manager.java:1037)
                  at Transcode.createDataSink(Transcode.java:269)
                  at Transcode.doIt(Transcode.java:96)
                  at Transcode.main(Transcode.java:440)
          - create DataSink for: C:/movePics/out.mpeg
          Cannot create the DataSink: javax.media.NoDataSinkException: Cannot find a DataSink for: com.sun.media.multiplexer.RawBufferMux$RawBufferDataSource@82c01f
          Failed to create a DataSink for the given output MediaLocator: C:/movePics/out.mpeg
          Transcoding failed
          {quote}
          
          
          Tips?
          
          Edited by: 853188 on Apr 23, 2011 6:57 AM
          
          Edited by: 853188 on Apr 23, 2011 6:58 AM
          
          Edited by: 853188 on Apr 23, 2011 7:13 AM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
          • 17. Re: JMF - Concurrent video feed and image capture
            captfoss
            This is the output I receive:

            >
            - create processor for: vfw://0
            - set track format to: RGB
            javax.media.NoDataSourceException: Cannot find a DataSource for: C:/movePics/out.mpeg
            at javax.media.Manager.createDataSource(Manager.java:1037)
            at Transcode.createDataSink(Transcode.java:269)
            at Transcode.doIt(Transcode.java:96)
            at Transcode.main(Transcode.java:440)
            - create DataSink for: C:/movePics/out.mpeg
            Cannot create the DataSink: javax.media.NoDataSinkException: Cannot find a DataSink for: com.sun.media.multiplexer.RawBufferMux$RawBufferDataSource@82c01f
            Failed to create a DataSink for the given output MediaLocator: C:/movePics/out.mpeg
            Transcoding failed
            >
            Well, the first thing to try would be appending "file:" to the beginning of the output media locator, which the example code I linked you to does both explicitly in the instructions as well as implicitly in the code. You've circumvented both of the places where "file:" would be appended, so that could very well be the problem...
            • 18. Re: JMF - Concurrent video feed and image capture
              856191
              captfoss wrote:
              Well, the first thing to try would be appending "file:" to the beginning of the output media locator, which the example code I linked you to does both explicitly in the instructions as well as implicitly in the code. You've circumvented both of the places where "file:" would be appended, so that could very well be the problem...
              This is because I'm trying to figure out how I can use the Transcode example as part of my larger project to record and save video only if and while motion is being detected. I don't want to run it on command line or exec() it from my larger program because it needs to cooperate with the FrameAccess motion detection functionality. So what I've been trying to do is change the example to record and save live video from a MediaLocator associated with a camera (cam.getLocator()) to a file (C:/movePics/out.mpeg) instead of using it as is.

              To test and figure this out, I'm currently hard-coding it but I would like to eventually pass into it an existing locator, or combine it with FrameAccess so I can have concurrent detection and recording (though no viewing - that will only occur when calibrating the system).

              Edited by: 853188 on Apr 26, 2011 7:53 AM
              • 19. Re: JMF - Concurrent video feed and image capture
                captfoss
                853188 wrote:
                captfoss wrote:
                Well, the first thing to try would be appending "file:" to the beginning of the output media locator, which the example code I linked you to does both explicitly in the instructions as well as implicitly in the code. You've circumvented both of the places where "file:" would be appended, so that could very well be the problem...
                This is because I'm trying to figure out how I can use the Transcode example as part of my larger project to record and save video only if and while motion is being detected. I don't want to run it on command line or exec() it from my larger program because it needs to cooperate with the FrameAccess motion detection functionality. So what I've been trying to do is change the example to record and save live video from a MediaLocator associated with a camera (cam.getLocator()) to a file (C:/movePics/out.mpeg) instead of using it as is.

                To test and figure this out, I'm currently hard-coding it but I would like to eventually pass into it an existing locator, or combine it with FrameAccess so I can have concurrent detection and recording (though no viewing - that will only occur when calibrating the system).
                And you can't hard-code the media locator to include "file:" at the beginning... why?
                • 20. Re: JMF - Concurrent video feed and image capture
                  856191
                  captfoss wrote:
                  And you can't hard-code the media locator to include "file:" at the beginning... why?
                  Well, in the code that I posted, I had removed a lot of the needed Transcode functionality. As a result, when I tried adding "file:" to the beginning of the locator, I received the same error as above. So I went back to the original Transcode version and just hard-coded the camera locator and it began recording and saving the file.

                  Problem is now that I can't seem to figure out the waitForFileDone() method to stop the video recording (after a few seconds, for example) without 'Ctrl-C' in the command prompt, which corrupts the video that is being recorded.
                  • 21. Re: JMF - Concurrent video feed and image capture
                    captfoss
                    853188 wrote:
                    waitForFileDone() method to stop the video recording (after a few seconds, for example) without 'Ctrl-C' in the command prompt, which corrupts the video that is being recorded.
                    There's no way to do that automatically for a live stream like you can for a video file.

                    You can do it in response to a timer (record for 50 seconds), you can do it in response to a button press in a Swing application or a key press in a console application... but your web cam doesn't have an "end of media" event to wait for.

                    And yes, just killing the program will corrupt the video. You need to shutdown the processor and sink in a specific order in order for your video to be usable.
                    • 22. Re: JMF - Concurrent video feed and image capture
                      856191
                      captfoss wrote:
                      There's no way to do that automatically for a live stream like you can for a video file.

                      You can do it in response to a timer (record for 50 seconds), you can do it in response to a button press in a Swing application or a key press in a console application... but your web cam doesn't have an "end of media" event to wait for.
                      What is the general idea stopping recording in response to a timer? If I modify the waitForFileDone() method to simply wait 10 seconds and return true, for example, recompile and rerun, it continues to act just as it did if I did nothing, updating with a '.' every second. Example code below:


                      if I change
                          /**
                           * Block until file writing is done. 
                           */
                          boolean waitForFileDone() {
                           System.err.print("  ");
                           synchronized (waitFileSync) {
                               try {
                                while (!fileDone) {
                                    waitFileSync.wait(1000);
                                    System.err.print(".");
                                }
                               } catch (Exception e) {}
                           }
                           System.err.println("");
                           return fileSuccess;
                          }
                      to something like:
                       boolean waitForFileDone() {
                                 //pseudo-code to show logic
                                 wait(10000);
                                 return true;
                      }
                      it continues to print the '.' and record on and on forever, and I'm not sure where it's pulling that from.

                      Edited by: 853188 on Apr 26, 2011 12:42 PM

                      Edited by: 853188 on Apr 26, 2011 12:51 PM
                      • 23. Re: JMF - Concurrent video feed and image capture
                        856191
                        853188 wrote:
                        it continues to print the '.' and record on and on forever, and I'm not sure where it's pulling that from.
                        Disregard this, I got it working. Now all I have to do is tie it all together. Thanks so much for your help.
                        • 24. Re: JMF - Concurrent video feed and image capture
                          captfoss
                          Glad you've (mostly) got it working!
                          • 25. Re: JMF - Concurrent video feed and image capture
                            856191
                            captfoss wrote:
                            Glad you've (mostly) got it working!
                            Another question:

                            When I run my motion detection, it will only detect motion if using YUV video format. Yet somehow in the video recording code (as opposed to the motion detection code), it changes the format from YUV to MJPG, which then makes the motion detection useless. I have it set up right now to save an image every time motion is detected, and if I set the sensitivity to be as sensitive as possible, it always detects motion even when there is none (when using MJPG), and that image is completely black, meaning that the frames it pulls off the buffer are always black.

                            How can I either force YUV, or get it to draw the image using MJPG?

                            Edited by: 853188 on Apr 27, 2011 5:04 PM

                            Edited by: 853188 on Apr 27, 2011 5:05 PM

                            Edited by: 853188 on Apr 27, 2011 5:06 PM
                            • 26. Re: JMF - Concurrent video feed and image capture
                              captfoss
                              When I run my motion detection, it will only detect motion if using YUV video format. Yet somehow in the video recording code (as opposed to the motion detection code), it changes the format from YUV to MJPG, which then makes the motion detection useless. I have it set up right now to save an image every time motion is detected, and if I set the sensitivity to be as sensitive as possible, it always detects motion even when there is none (when using MJPG), and that image is completely black, meaning that the frames it pulls off the buffer are always black.
                              What? You mean your method of motion dection isn't very robust... hmmm, if ONLY you'd been warned about that previously ;-)

                              Additionally, if you had done the motion detection in the codec as you were advised to do, you wouldn't be having these problems either.

                              I didn't advise you to change how you were doing stuff days ago because I wanted you to do extra work, I did so because I wanted you to do less work in the end...
                              How can I either force YUV, or get it to draw the image using MJPG?
                              You set what video encoding you want by programming the tracks of the processor... so you "force" YUV by asking for it.

                              Additionally, you can only force YUV encoding if your output video file format (AVI, MPG, MOV, etc) support it.

                              http://www.oracle.com/technetwork/java/javase/formats-138492.html

                              Note that AVI is the only file format that supports YUV encoding... but MOV files support RGB encoding, which should work just fine with your existing motion detection code.
                              • 27. Re: JMF - Concurrent video feed and image capture
                                856191
                                853188 wrote:
                                How can I either force YUV, or get it to draw the image using MJPG?
                                I keep asking questions and then solving them myself... I have this solved but now I'm on to something new. The problem is, I can't figure out how to get the recording inside of the motion detection. I can't seem to get the process correct of setting up the processor/locator/formats for the detection whilst also setting up an output locator/DataSink for a recorder that I can use later as needed.

                                The code for my two classes are as follows (and yes, I know it's a mess right now. I've been trying to figure out the process so I've been moving stuff around a lot).


                                Motion Detection (based on FrameAccess):
                                import java.awt.BorderLayout;
                                import java.awt.Color;
                                import java.awt.Component;
                                import java.awt.Font;
                                import java.awt.Frame;
                                import java.awt.Graphics2D;
                                import java.awt.Image;
                                import java.awt.geom.AffineTransform;
                                import java.awt.image.BufferedImage;
                                import java.io.File;
                                import java.io.IOException;
                                import java.util.Date;
                                import javax.imageio.ImageIO;
                                import javax.media.Buffer;
                                import javax.media.Codec;
                                import javax.media.ConfigureCompleteEvent;
                                import javax.media.ControllerEvent;
                                import javax.media.ControllerListener;
                                import javax.media.EndOfMediaEvent;
                                import javax.media.Format;
                                import javax.media.Manager;
                                import javax.media.MediaLocator;
                                import javax.media.PrefetchCompleteEvent;
                                import javax.media.Processor;
                                import javax.media.RealizeCompleteEvent;
                                import javax.media.ResourceUnavailableEvent;
                                import javax.media.UnsupportedPlugInException;
                                import javax.media.control.TrackControl;
                                import javax.media.format.VideoFormat;
                                import javax.media.util.BufferToImage;
                                import javax.swing.JFrame;
                                import javax.swing.JTextArea;
                                import java.util.ArrayList;
                                import java.util.Vector;
                                
                                public class Background extends Frame implements ControllerListener {
                                
                                     private Processor p;
                                     private Object waitSync = new Object();
                                     private boolean stateTransitionOK = true;
                                     private String path;
                                     private ComparatorEnvironment env;
                                     private int minRecTime;
                                     private PicComparator comparator;
                                     private VideoRecorder recorder;
                                     
                                     
                                     public Background(ComparatorEnvironment env){
                                          path = "/temp/";
                                          minRecTime = env.getMinRecordTime();
                                          System.out.println("Lighting: " + env.getLightConditions());
                                          System.out.println("Min time: " + env.getMinRecordTime());
                                          System.out.println(env.getPicHeight());
                                          System.out.println(env.getPicWidth());
                                          System.out.println("Sensitivity: " + env.getSensitivity());
                                          ArrayList<String> emails = env.getEmails();
                                          for (String s: emails){
                                               System.out.println(s);
                                          }
                                          comparator = new PicComparator(env);
                                     }
                                
                                     /**
                                      * Given a media locator, create a processor and use that processor as a
                                      * player to playback the media.
                                      * 
                                      * During the processor's Configured state, two "pass-thru" codecs,
                                      * PreAccessCodec and PostAccessCodec, are set on the video track. These
                                      * codecs are used to get access to individual video frames of the media.
                                      * 
                                      * Much of the code is just standard code to present media in JMF.
                                      */
                                     public boolean monitor(MediaLocator ml) {
                                          //createCalibTips();
                                          try {
                                               p = Manager.createProcessor(ml);
                                          } catch (Exception e) {
                                               System.err.println("Failed to create a processor." + e);
                                               return false;
                                          }
                                                    
                                          String inputURL = null, outputURL = "file:mov.avi";
                                          Vector audFmt = new Vector(), vidFmt = new Vector();
                                
                                          int j = 0;
                                          Format fmts[] = new Format[audFmt.size() + vidFmt.size()];
                                          Format fmt;
                                
                                          // Parse the video format spec. into real VideoFormat's.
                                          for (int i = 0; i < vidFmt.size(); i++) {
                                
                                               if ((fmt = VideoRecorder.parseVideoFormat((String) vidFmt.elementAt(i))) == null) {
                                                    System.err.println("Invalid video format specification: "
                                                              + (String) vidFmt.elementAt(i));
                                               }
                                               fmts[j++] = fmt;
                                          }
                                
                                          // Generate the input and output media locators.
                                          MediaLocator iml, oml;
                                
                                          if ((oml = VideoRecorder.createMediaLocator(outputURL)) == null) {
                                               System.err.println("Cannot build media locator from: " + outputURL);
                                               System.exit(0);
                                          }
                                          
                                          recorder = new VideoRecorder(p, oml, fmts);
                                
                                
                                          
                                          p.addControllerListener(this);
                                          
                                          // Put the Processor into configured state.
                                          p.configure();
                                          if (!waitForState(p.Configured)) {
                                               System.err.println("Failed to configure the processor.");
                                               return false;
                                          }
                                
                                          // So I can use it as a player.
                                          p.setContentDescriptor(null);
                                
                                          // Obtain the track controls.
                                          TrackControl tc[] = p.getTrackControls();
                                
                                          if (tc == null) {
                                               System.err
                                                         .println("Failed to obtain track controls from the processor.");
                                               return false;
                                          }
                                
                                          // Search for the track control for the video track.
                                          TrackControl videoTrack = null;
                                
                                          for (int i = 0; i < tc.length; i++) {
                                               if (tc.getFormat() instanceof VideoFormat) {
                                                    videoTrack = tc[i];
                                                    break;
                                               }
                                          }

                                          if (videoTrack == null) {
                                               System.err.println("The input media does not contain a video track.");
                                               return false;
                                          }

                                          System.err.println("Video format: " + videoTrack.getFormat());

                                          // Instantiate and set the frame access codec to the data flow path.
                                          try {
                                               Codec[] codecs = { new ComparatorCodec() };
                                               videoTrack.setCodecChain(codecs);
                                          } catch (UnsupportedPlugInException e) {
                                               System.err.println("The process does not support effects.");
                                          }

                                          // Realize the processor.
                                          p.prefetch();
                                          if (!waitForState(p.Prefetched)) {
                                               System.err.println("Failed to realize the processor.");
                                               return false;
                                          }
                                          
                                          recorder.createDataSink(p, oml);

                                          

                                          // Start the processor.
                                          p.start();
                                          //recorder = new VideoRecorder(p, comparator, "out.avi", minRecTime);


                                          //setVisible(true);

                                          return true;
                                     }
                                     
                                     public void addNotify() {
                                          super.addNotify();
                                          pack();
                                     }

                                     /**
                                     * Block until the processor has transitioned to the given state. Return
                                     * false if the transition failed.
                                     */
                                     boolean waitForState(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) {
                                               p.close();
                                               System.exit(0);
                                          }
                                     }



                                     /**
                                     * Codec to access frames coming from the camera
                                     * @author group4
                                     *
                                     */
                                     private class ComparatorCodec implements Codec {
                                          
                                          //private int movementCounter;
                                          private String timestamp;
                                     
                                          public ComparatorCodec(){
                                               //movementCounter = 0;
                                          }

                                          private BufferedImage prevPic;
                                          private BufferedImage newPic;
                                          private boolean movement;

                                          private void saveImage(String path, BufferedImage image, boolean stampDate) {
                                               File output = new File(path);

                                               if (stampDate) {
                                                    Graphics2D f = image.createGraphics();
                                                    f.setColor(Color.yellow);
                                                    f.setFont(new Font("Tahoma", Font.PLAIN, 12).deriveFont(AffineTransform.getRotateInstance(1.57)));
                                                    f.drawString((new Date()).toString(), 5, 5);
                                               }

                                               try {
                                                    ImageIO.write(image, "jpeg", output);
                                               } catch (IOException e) {
                                               }
                                          }

                                          /**
                                          * Callback to access individual video frames.
                                          */
                                          void accessFrame(Buffer frame) {
                                               prevPic = newPic;
                                               Image img = (new BufferToImage((VideoFormat) frame.getFormat()).createImage(frame));
                                               newPic = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB);
                                               Graphics2D f = newPic.createGraphics();
                                               f.drawImage(img, null, null);

                                               if (prevPic != null && newPic != null) {
                                                    movement = comparator.detectMovement(prevPic, newPic);
                                               }

                                               if (movement) {
                                                    //movementCounter = 0;
                                                    System.out.println("**WARNING**: Movement detected.");
                                                    //saveImage(path + "pic.jpeg", newPic, true);
                                                    recorder.record();
                                               } else {
                                                    // movementCounter++;
                                                    System.out.println("No movement detected.");
                                               }
                                          }

                                          /**
                                          * The code for a pass through codec.
                                          */

                                          // We'll advertize as supporting all video formats.
                                          protected Format supportedIns[] = new Format[] { new VideoFormat(VideoFormat.YUV) };

                                          // We'll advertize as supporting all video formats.
                                          protected Format supportedOuts[] = new Format[] { new VideoFormat(null) };

                                          Format input = null, output = null;

                                          public String getName() {
                                               return "Pre-Access Codec";
                                          }

                                          // No op.
                                          public void open() {
                                          }

                                          // No op.
                                          public void close() {
                                          }

                                          // No op.
                                          public void reset() {
                                          }

                                          public Format[] getSupportedInputFormats() {
                                               return supportedIns;
                                          }

                                          public Format[] getSupportedOutputFormats(Format in) {
                                               if (in == null)
                                                    return supportedOuts;
                                               else {
                                                    // If an input format is given, we use that input format
                                                    // as the output since we are not modifying the bit stream
                                                    // at all.
                                                    Format outs[] = new Format[1];
                                                    outs[0] = in;
                                                    return outs;
                                               }
                                          }

                                          public Format setInputFormat(Format format) {
                                               input = format;
                                               return input;
                                          }

                                          public Format setOutputFormat(Format format) {
                                               output = format;
                                               return output;
                                          }

                                          public int process(Buffer in, Buffer out) {

                                               // This is the "Callback" to access individual frames.
                                               accessFrame(in);
                                               
                                               // try {
                                                    // Thread.sleep(300);
                                               // } catch (InterruptedException e) {
                                                    // e.printStackTrace();
                                               // }

                                               // Swap the data between the input & output.
                                               Object data = in.getData();
                                               in.setData(out.getData());
                                               out.setData(data);

                                               // Copy the input attributes to the output
                                               out.setFormat(in.getFormat());
                                               out.setLength(in.getLength());
                                               out.setOffset(in.getOffset());

                                               return BUFFER_PROCESSED_OK;
                                          }

                                          public Object[] getControls() {
                                               return new Object[0];
                                          }

                                          public Object getControl(String type) {
                                               return null;
                                          }
                                     }
                                }
                                Video Recording (based on Transcode):
                                import java.awt.*;
                                import java.util.Vector;
                                import java.io.File;
                                import javax.media.*;
                                import javax.media.control.TrackControl;
                                import javax.media.control.QualityControl;
                                import javax.media.Format;
                                import javax.media.format.*;
                                import javax.media.datasink.*;
                                import javax.media.protocol.*;
                                import java.io.IOException;

                                public class VideoRecorder implements ControllerListener, DataSinkListener {

                                     Processor p;
                                     MediaLocator outML;
                                     Format fmts[];
                                     
                                     public VideoRecorder(Processor p, MediaLocator oml, Format[] fmts){
                                          
                                          this.p = p;
                                          // String inputURL = null, outputURL = "file:mov.avi";
                                          // int mediaStart = -1, mediaEnd = -1;
                                          // Vector audFmt = new Vector(), vidFmt = new Vector();


                                          // int i = 0;

                                          // if (outputURL == null) {
                                               // System.err.println("No output url is specified");
                                          // }

                                          // int j = 0;
                                          // Format fmts[] = new Format[audFmt.size() + vidFmt.size()];
                                          // Format fmt;

                                          // Parse the video format spec. into real VideoFormat's.
                                          // for (i = 0; i < vidFmt.size(); i++) {

                                               // if ((fmt = parseVideoFormat((String) vidFmt.elementAt(i))) == null) {
                                                    // System.err.println("Invalid video format specification: "
                                                              // + (String) vidFmt.elementAt(i));
                                               // }
                                               // fmts[j++] = fmt;
                                          // }

                                          // Generate the input and output media locators.
                                          // MediaLocator iml, oml;

                                          // if ((oml = createMediaLocator(outputURL)) == null) {
                                               // System.err.println("Cannot build media locator from: " + outputURL);
                                               // System.exit(0);
                                          // }
                                          
                                          outML = oml;
                                          this.fmts = fmts;
                                          // Trancode with the specified parameters.

                                          // if (!record(oml, fmts)) {
                                               // System.err.println("Recording failed");
                                          // }
                                     }
                                     
                                     public boolean record(){
                                          return record(outML, fmts);
                                     }
                                     
                                     /**
                                     * Given a source media locator, destination media locator and an array of
                                     * formats, this method will transcode the source to the dest into the
                                     * specified formats.
                                     */
                                     public boolean record(MediaLocator outML, Format fmts[]) {


                                          p.addControllerListener(this);

                                          // Put the Processor into configured state.
                                          p.configure();
                                          if (!waitForState(p, p.Configured)) {
                                               System.err.println("Failed to configure the processor.");
                                               return false;
                                          }

                                          // Set the output content descriptor based on the media locator.
                                          setContentDescriptor(p, outML);

                                          // Program the tracks to the given output formats.
                                          if (!setTrackFormats(p, fmts))
                                               return false;

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

                                          // Set the JPEG quality to .5.
                                          setJPEGQuality(p, 0.5f);

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

                                          dsink.addDataSinkListener(this);
                                          fileDone = false;

                                          System.err.println("start recording...");

                                          // OK, we can now start the actual recording.
                                          try {
                                               p.start();
                                               dsink.start();
                                          } catch (IOException e) {
                                               System.err.println("IO error during recording");
                                               return false;
                                          }

                                          // Wait for EndOfStream event.
                                          waitForFileDone();

                                          // Cleanup.
                                          try {
                                               dsink.close();
                                          } catch (Exception e) {
                                          }
                                          p.removeControllerListener(this);

                                          System.err.println("...done recording.");

                                          return true;
                                     }

                                     /**
                                     * Set the content descriptor based on the given output MediaLocator.
                                     */
                                     void setContentDescriptor(Processor p, MediaLocator outML) {

                                          ContentDescriptor cd;

                                          // If the output file maps to a content type,
                                          // we'll try to set it on the processor.

                                          if ((cd = fileExtToCD(outML.getRemainder())) != null) {

                                               System.err.println("- set content descriptor to: " + cd);

                                               if ((p.setContentDescriptor(cd)) == null) {

                                                    // The processor does not support the output content
                                                    // type. But we can set the content type to RAW and
                                                    // see if any DataSink supports it.

                                                    p.setContentDescriptor(new ContentDescriptor(
                                                              ContentDescriptor.RAW));
                                               }
                                          }
                                     }

                                     /**
                                     * Set the target transcode format on the processor.
                                     */
                                     boolean setTrackFormats(Processor p, Format fmts[]) {

                                          if (fmts.length == 0)
                                               return true;

                                          TrackControl tcs[];

                                          if ((tcs = p.getTrackControls()) == null) {
                                               // The processor does not support any track control.
                                               System.err
                                                         .println("The Processor cannot transcode the tracks to the given formats");
                                               return false;
                                          }

                                          for (int i = 0; i < fmts.length; i++) {

                                               System.err.println("- set track format to: " + fmts[i]);

                                               if (!setEachTrackFormat(p, tcs, fmts[i])) {
                                                    System.err.println("Cannot transcode any track to: " + fmts[i]);
                                                    return false;
                                               }
                                          }

                                          return true;
                                     }

                                     /**
                                     * We'll loop through the tracks and try to find a track that can be
                                     * converted to the given format.
                                     */
                                     boolean setEachTrackFormat(Processor p, TrackControl tcs[], Format fmt) {

                                          Format supported[];
                                          Format f;

                                          for (int i = 0; i < tcs.length; i++) {

                                               supported = tcs[i].getSupportedFormats();

                                               if (supported == null)
                                                    continue;

                                               for (int j = 0; j < supported.length; j++) {

                                                    if (fmt.matches(supported[j])
                                                              && (f = fmt.intersects(supported[j])) != null
                                                              && tcs[i].setFormat(f) != null) {

                                                         // Success.
                                                         return true;
                                                    }
                                               }
                                          }

                                          return false;
                                     }

                                     /**
                                     * Setting the encoding quality to the specified value on the JPEG encoder.
                                     * 0.5 is a good default.
                                     */
                                     void setJPEGQuality(Player p, float val) {

                                          Control cs[] = p.getControls();
                                          QualityControl qc = null;
                                          VideoFormat jpegFmt = new VideoFormat(VideoFormat.JPEG);

                                          // Loop through the controls to find the Quality control for
                                          // the JPEG encoder.
                                          for (int i = 0; i < cs.length; i++) {

                                               if (cs[i] instanceof QualityControl && cs[i] instanceof Owned) {
                                                    Object owner = ((Owned) cs[i]).getOwner();

                                                    // Check to see if the owner is a Codec.
                                                    // Then check for the output format.
                                                    if (owner instanceof Codec) {
                                                         Format fmts[] = ((Codec) owner)
                                                                   .getSupportedOutputFormats(null);
                                                         for (int j = 0; j < fmts.length; j++) {
                                                              if (fmts[j].matches(jpegFmt)) {
                                                                   qc = (QualityControl) cs[i];
                                                                   qc.setQuality(val);
                                                                   System.err.println("- Set quality to " + val
                                                                             + " on " + qc);
                                                                   break;
                                                              }
                                                         }
                                                    }
                                                    if (qc != null)
                                                         break;
                                               }
                                          }
                                     }

                                     /**
                                     * Create the DataSink.
                                     */
                                     DataSink createDataSink(Processor p, MediaLocator outML) {

                                          DataSource ds;

                                          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.err.println("- create DataSink for: " + outML);
                                               dsink = Manager.createDataSink(ds, outML);
                                               dsink.open();
                                          } catch (Exception e) {
                                               System.err.println("Cannot create the DataSink: " + e);
                                               return null;
                                          }

                                          return dsink;
                                     }

                                     Object waitSync = new Object();
                                     boolean stateTransitionOK = true;

                                     /**
                                     * Block until the processor has transitioned to the given state. Return
                                     * false if the transition failed.
                                     */
                                     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().close();
                                          } else if (evt instanceof MediaTimeSetEvent) {
                                               System.err.println("- mediaTime set: "
                                                         + ((MediaTimeSetEvent) evt).getMediaTime().getSeconds());
                                          } else if (evt instanceof StopAtTimeEvent) {
                                               System.err.println("- stop at time: "
                                                         + ((StopAtTimeEvent) evt).getMediaTime().getSeconds());
                                               evt.getSourceController().close();
                                          }
                                     }

                                     Object waitFileSync = new Object();
                                     boolean fileDone = false;
                                     boolean fileSuccess = true;

                                     /**
                                     * Block until file writing is done.
                                     */
                                     boolean waitForFileDone() {
                                          try {
                                          Thread.sleep(10000);
                                          } catch (InterruptedException e) {
                                               e.printStackTrace();
                                          }
                                          return true;
                                     }

                                     /**
                                     * 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();
                                               }
                                          }
                                     }

                                     /**
                                     * Convert a file name to a content type. The extension is parsed to
                                     * determine the content type.
                                     */
                                     ContentDescriptor fileExtToCD(String name) {

                                          String ext;
                                          int p;

                                          // Extract the file extension.
                                          if ((p = name.lastIndexOf('.')) < 0)
                                               return null;

                                          ext = (name.substring(p + 1)).toLowerCase();

                                          String type;

                                          // Use the MimeManager to get the mime type from the file extension.
                                          if (ext.equals("mp3")) {
                                               type = FileTypeDescriptor.MPEG_AUDIO;
                                          } else {
                                               if ((type = com.sun.media.MimeManager.getMimeType(ext)) == null)
                                                    return null;
                                               type = ContentDescriptor.mimeTypeToPackageName(type);
                                          }

                                          return new FileTypeDescriptor(type);
                                     }

                                     /**
                                     * Create a media locator from the given string.
                                     */
                                     static MediaLocator createMediaLocator(String url) {

                                          MediaLocator ml;

                                          if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null)
                                               return ml;

                                          if (url.startsWith(File.separator)) {
                                               if ((ml = new MediaLocator("file:" + url)) != null)
                                                    return ml;
                                          } else {
                                               String file = "file:" + System.getProperty("user.dir")
                                                         + File.separator + url;
                                               if ((ml = new MediaLocator(file)) != null)
                                                    return ml;
                                          }

                                          return null;
                                     }


                                     /**
                                     * Parse the video format specifier and generate an VideoFormat. A valid
                                     * video format specifier is of the form: [encoding]:[widthXheight]
                                     */
                                     static Format parseVideoFormat(String fmtStr) {

                                          String encodeStr = null, sizeStr = null;

                                          // Parser the media locator to extract the requested format.

                                          if (fmtStr != null && fmtStr.length() > 0) {
                                               while (fmtStr.length() > 1 && fmtStr.charAt(0) == ':')
                                                    fmtStr = fmtStr.substring(1);

                                               // Now see if there's a encode rate specified.
                                               int off = fmtStr.indexOf(':');
                                               if (off == -1) {
                                                    if (!fmtStr.equals(""))
                                                         encodeStr = fmtStr;
                                               } else {
                                                    encodeStr = fmtStr.substring(0, off);
                                                    sizeStr = fmtStr.substring(off + 1);
                                               }
                                          }

                                          if (encodeStr == null || encodeStr.equals(""))
                                               //prUsage();

                                          if (sizeStr == null)
                                               return new VideoFormat(encodeStr);

                                          int width = 649, height = 480;

                                          int off = sizeStr.indexOf('X');
                                          if (off == -1)
                                               off = sizeStr.indexOf('x');

                                          if (off == -1) {
                                               System.err.println("Video dimension is not correctly specified: "
                                                         + sizeStr);
                                               //prUsage();
                                          } else {
                                               String widthStr = sizeStr.substring(0, off);
                                               String heightStr = sizeStr.substring(off + 1);

                                               try {
                                                    Integer integer = Integer.valueOf(widthStr);
                                                    if (integer != null)
                                                         width = integer.intValue();
                                                    integer = Integer.valueOf(heightStr);
                                                    if (integer != null)
                                                         height = integer.intValue();
                                               } catch (Throwable t) {
                                                    //prUsage();
                                               }

                                               return new VideoFormat(encodeStr, new Dimension(width, height),
                                                         VideoFormat.NOT_SPECIFIED, // maxDataLen
                                                         null, // data class
                                                         VideoFormat.NOT_SPECIFIED // FrameRate
                                               );
                                          }

                                          return null;
                                     }

                                     
                                     
                                //     static void prUsage() {
                                //          System.err
                                //                    .println("Usage: java Transcode -o <output> -a <audio format> -v <video format> -s <start time> -e <end time> <input>");
                                //          System.err.println(" <output>: input URL or file name");
                                //          System.err.println(" <input>: output URL or file name");
                                //          System.err
                                //                    .println(" <audio format>: [encoding]:[rate]:[sizeInBits]:[channels]:big:signed");
                                //          System.err.println(" <video format>: [encoding]:[widthXheight]");
                                //          System.err.println(" <start time>: start time in seconds");
                                //          System.err.println(" <end time>: end time in seconds");
                                //          System.exit(0);
                                //     }
                                }
                                The main is:
                                import javax.media.MediaLocator;

                                public class Runner{

                                     public static void main(String[] args) {
                                          CameraLocator cam = new CameraLocator();
                                          MediaLocator locator = cam.getLocator();
                                          ComparatorEnvironment env = new ComparatorEnvironment();
                                          Background background = new Background(env);

                                          if (!background.monitor(locator)) {
                                               System.exit(0);
                                          }
                                     }
                                }
                                Right now it's set up to record for 10s every time motion is detected, but this is the output I receive:
                                - set content descriptor to: AVI
                                Something is really wrong: the processor does not have an output DataSource
                                Failed to create a DataSink for the given output MediaLocator: file:mov.avi
                                
                                What do I have to do to successfully create the DataSink?
                                
                                Edited by: 853188 on Apr 28, 2011 8:03 AM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                • 28. Re: JMF - Concurrent video feed and image capture
                                  856191
                                  captfoss wrote:
                                  What? You mean your method of motion dection isn't very robust... hmmm, if ONLY you'd been warned about that previously ;-)
                                  Actually, the motion detection is fairly decent considering the noise it has to endure, it just didn't work when the video format being used was not YUV, but I fixed that problem.
                                  • 29. Re: JMF - Concurrent video feed and image capture
                                    captfoss
                                    853188 wrote:
                                    I keep asking questions and then solving them myself...
                                    Then please do me the courtesey of immediately posting that you've solved the problem so I don't waste my time responding to the issue.

                                    Additionally, it would be far more helpful if you posted a new thread for each of your "new problems", and marked the old threads as answered, with helpful and correct indications for the people who come after you trying to learn from your mistakes.
                                    Something is really wrong: the processor does not have an output DataSource
                                    Failed to create a DataSink for the given output MediaLocator: file:mov.avi
                                    Those two things seem to suggest the processor couldn't be realized, which generally means you've tried to transcode from one format to another format that isn't supported...
                                    http://www.oracle.com/technetwork/java/javase/formats-138492.html

                                    Additionally, the problem could be that "file:mov.avi" needs to be a URL, and you've given it a bad URL... that's perfectly valid input to the original program, but take a look at the createMediaLocator method...

                                    Specifically,
                                    String file = "file:" + System.getProperty("user.dir") + File.separator + url;
                                    Note that it's giving it a full URL path to the file... so you need to do the same.