简体   繁体   中英

Rectify JMF Video Capture

I saw the following code in stackoverflow.com and copied to my system submitted by you on JMF:

import Logging.LogRunner; //Logging.LogRunner is absent s error occurs
import java.util.Vector;
import java.awt.*;
import java.awt.event.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
import javax.media.datasink.*;
import javax.swing.JButton;
import javax.swing.JOptionPane;

/**
 * Records audio and video from a usb camera and saves it to disk. Essentially what is happening
 * is we are creating two video streams and an audio stream. We use two video streams
 * so one can be sent to the file, and the other can be sent to the gui to show the
 * user what they are currently recording. This class is configured to use a certain
 * audio and video format, but this can easily be changed to fit dirrenet needs.
 * This class was created with
 * help from http://www.codeproject.com/KB/audio-video/Java_Video_Capture.aspx.
 * Please refer to that site for more information.
 * @author dvargo
 */

public class VideoRecorder
{

    /**
     * The source of the video stream
     */
    CaptureDeviceInfo device = null;

    /**
     * The location of media content
     */
    MediaLocator ml = null;

    /**
     * MediaHandler for rendering and controlling time based media data
     */
    Player player = null;

    /**
     * The screen that will display the video as it is being recorded
     */
    Component videoScreen = null;

    /**
     * The Processor processes data and creates an output in the destination 
     * format required
     */
    Processor processor = null;

    /**
     * takes a DataSource as input and renders the output to a specified destination
     */
    DataSink dataSink = null;
    /**
     * 
     */
    TheDataSinkListener dataSinkListener = null;
    /**
     * The form for the video and other gui compoenents
     */
    Frame frm = null;
    /**
     * A reference to the Starter class.
     */
    VideoStarter theForm = null;  //VideoStarter does not exist so error occurs

    /**
     * Used to determine if something went wrong
     */
    boolean error = false;

    /**
     * Basic Constructor to begin recording video to a specified file path. This
     * constructor initalizes everything needed to begin recording.
     * @param saveFileTo The path and file name of where to save the video.
     * @param inForm Reference to the Starter class that initatied this recording.
     */
    public VideoRecorder(String saveFileTo,VideoStarter inForm)
    {
        theForm = inForm;
        try
        {
            //gets a list of devices how support the given video format
            Vector deviceList = CaptureDeviceManager.getDeviceList(new YUVFormat());

            //if we couldnt find anything to record from
            if(deviceList.size() == 0)
            {
                LogRunner.dialogMessage(this.getClass(),"No video capture devices could be found.");
                error = true;
                return;
            }

            // get video device - the first one is almost always the only available camera
            device = (CaptureDeviceInfo) deviceList.firstElement();
            ml = device.getLocator();

            //create a source from the device
            DataSource ods = null;
            ods = Manager.createDataSource(ml);

            /*
             * Clone the video source so it can be displayed and used to capture
             * the video at the same time. Trying to use the same source for two
             * purposes would cause a "source is in use" error
             */
            DataSource cloneableDS = Manager.createCloneableDataSource(ods);
            DataSource PlayerVidDS = cloneableDS;

            // The video capture code will use the clone which is controlled by the player
            DataSource CaptureVidDS = ((javax.media.protocol.SourceCloneable) cloneableDS).createClone();

            /*
             * Display video by starting the player on the source clonable data source
             * the clones are fed data stopping the player will stop the video flow
             * to the clone data source
             */
            player = Manager.createRealizedPlayer(PlayerVidDS);
            player.start();

            // get an audio device and create an audio data source
            deviceList = CaptureDeviceManager.getDeviceList(new javax.media.format.AudioFormat(null));
            device = (CaptureDeviceInfo) deviceList.firstElement();
            ml = device.getLocator();
            DataSource audioDataSource = Manager.createDataSource(ml);

            // merge audio and video data sources
            DataSource mixedDataSource = null;
            DataSource dsArray[] = new DataSource[2];
            dsArray[0] = CaptureVidDS; // this is a cloned datasource and is controlled by the master clonable data source
            dsArray[1] = audioDataSource;
            try
            {
                mixedDataSource = javax.media.Manager.createMergingDataSource(dsArray);
            }
            catch (Exception e)
            {
                //exception handling here
                error = true;
                System.out.println("Error 1");
                e.printStackTrace();
            }

            // setup output file format to msvideo
            FileTypeDescriptor outputType = new FileTypeDescriptor(FileTypeDescriptor.MSVIDEO);

            // setup output video and audio data format
            Format outputFormat[] = new Format[2];
            //outputFormat[0] = new VideoFormat(VideoFormat.RGB);
            outputFormat[0] = new VideoFormat(VideoFormat.YUV);
            outputFormat[1] = new AudioFormat(AudioFormat.LINEAR);


            // create a new processor
            ProcessorModel processorModel = new ProcessorModel(mixedDataSource, outputFormat, outputType);
            try
            {
                processor = Manager.createRealizedProcessor(processorModel);
            }
            catch (Exception e) {
                // exception handling here
                error = true;
                System.out.println("Error 2");
                e.printStackTrace();
            }

            try
            {
                // get the output of the processor to be used as the datasink input
                DataSource source = processor.getDataOutput();

                // create a File protocol MediaLocator with the location of the file to which bits are to be written
                MediaLocator mediadestination = new MediaLocator("file:" + saveFileTo);

                // create a datasink to create the video file
                dataSink = Manager.createDataSink(source, mediadestination);

                // create a listener to control the datasink
                dataSinkListener = new TheDataSinkListener();
                dataSink.addDataSinkListener(dataSinkListener);
                dataSink.open();

                // now start the datasink and processor
                dataSink.start();

                processor.start();
            } 
            catch (Exception e)
            {
                // exception handling here
                error = true;
                System.out.println("Error 3");
                e.printStackTrace();
            }

            //set up the gui
            createGui();

        }
        catch (Exception e)
        {
            System.out.println("Error 4");
            LogRunner.getLogger().warning("Error recording video - " + e.getMessage());
            e.printStackTrace();
            error = true;
        }
    }

    /**
     * Flag that determines if something went wrong
     * @return True if something did go wrong, false if everything is fine.
     */
    public boolean getError()
    {
        return error;
    }

    /**
     * Creates the gui used to display what is currently being recorded.
     */
    private void createGui()
    {
            videoScreen = player.getVisualComponent();
            frm = new Frame("Recording");
            frm.setSize(300, 300);
            frm.setLayout(new BorderLayout());
            frm.add(videoScreen,BorderLayout.CENTER);
            JButton close = new JButton("Click Here when done");
            frm.add(close,BorderLayout.SOUTH);
            close.setVisible(true);
            close.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {

                    // Stop the processor doing the movie capture first
                    processor.stop();
                    processor.close();

                    // Closing the processor will end the data stream to the data sink.
                    // Wait for the end of stream to occur before closing the datasink
                    dataSinkListener.waitEndOfStream(10);
                    dataSink.close();

                    // stop and close the player which closes the video data source
                    player.stop();
                    player.close();

                    theForm.done();

                    // dispose of the frame and close the application
                    frm.setVisible(false);

            }
        });
            frm.setAlwaysOnTop(true);
            frm.setUndecorated(true);
            frm.setLocationRelativeTo(theForm.mainWindow);
            frm.setVisible(true);



    }
}

/**
 *
 * Control the ending of the program prior to closing the data sink
 */
class TheDataSinkListener implements DataSinkListener {

    boolean endOfStream = false;

    // Flag the ending of the data stream
    public void dataSinkUpdate(DataSinkEvent event)
    {
        if (event instanceof javax.media.datasink.EndOfStreamEvent)
        {
            endOfStream = true;
        }
    }

    /**
     * Cause the current thread to sleep if the data stream is still available.
     * This makes certain that JMF threads are done prior to closing the data sink
     * and finalizing the output file
     */
    public void waitEndOfStream(long checkTimeMs) {
        while (!endOfStream)
        {
            try
            {
                //Thread.currentThread().sleep(checkTimeMs);
                Thread.sleep(checkTimeMs);
            } 
            catch (InterruptedException ie)
            {
                System.out.println("Error 5");
                e.printStackTrace();
            }
        }
    }

    public static void main(String []args)
    {

        new VideoRecorder("d:/yusuf/abc.mpg",theForm);
    }
}

But where can i get the Logging.LogRunner and VideoStarter. For these my program shows error during compile. The following error messages are shown

1.
symbol:   variable LogRunner
  location: class VideoRecorder
F:\Tutorials\Java Tutorial\Programs\VideoRecorder\src\VideoRecorder.java:206: error: cannot find symbol
            LogRunner.getLogger().warning("Error recording video - " + e.getMessage());

2.
public VideoRecorder(String saveFileTo,VideoStarter inForm)
                                           ^
  symbol:   class VideoStarter
  location: class VideoRecorder

Please help

Im the one that acutally wrote that. Sorry for the delayed reply as im sure your far past this, but it may be useful to someone in the future. The LogRunner is a class we use to write our log messages out. You can just remove that, or use whatever youd like for logging.

The VideoStarter is just a JWindow that starts the video recording process. It also is not needed for this class to work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM