整顿JMF视频捕捉

时间:2012-10-14 18:14:00

标签: java jmf

我在stackoverflow.com中看到以下代码并将其复制到您在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);
    }
}

但是我在哪里可以获得Logging.LogRunner和VideoStarter。对于这些我的程序在编译期间显示错误。显示以下错误消息

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

请帮忙

1 个答案:

答案 0 :(得分:0)

我是那个真实写过的人。很抱歉延迟回复,因为我确定你远远超过这个,但它可能对将来有用。 LogRunner是我们用来编写日志消息的类。您可以删除它,或使用任何您喜欢的日志记录。

VideoStarter只是一个启动视频录制过程的JWindow。这个课程也不需要工作。