-3

这是代码:

import java.awt.*;
import java.util.*;
import javax.media.*;
import javax.media.protocol.*;
import javax.media.control.*;
import javax.media.format.*;

public class jmfcam05v
{
       DataSource dataSource;
       PushBufferStream pbs;

       Vector camImgSize = new Vector();
       Vector camCapDevice = new Vector();
       Vector camCapFormat = new Vector();

       int camFPS;
       int camImgSel;

       Processor processor = null;
       DataSink datasink = null;

       public static void main(String[] args)
       {
               jmfcam05v jmfcam = new jmfcam05v();
       }

       public jmfcam05v()
       {

               fetchDeviceFormats();
 camFPS = 30;    // framerate


               fetchDeviceDataSource();
               createPBDSource();
               createProcessor(dataSource);
               startCapture();
               try{Thread.sleep(20000);}catch(Exception e){}   // 20 seconds
               stopCapture();
       }

      boolean fetchDeviceFormats()
       {
               Vector deviceList = CaptureDeviceManager.getDeviceList(new VideoFormat(null));
               CaptureDeviceInfo CapDevice = null;
               Format CapFormat = null;
               String type = "N/A";

               CaptureDeviceInfo deviceInfo=null;boolean VideoFormatMatch=false;
               for(int i=0;i<deviceList.size();i++)
               {
                       // search for video device
                       deviceInfo = (CaptureDeviceInfo)deviceList.elementAt(i);
                       if(deviceInfo.getName().indexOf("vfw:")<0)continue;

                       Format deviceFormat[] = deviceInfo.getFormats();
                       for (int f=0;f<deviceFormat.length;f++)
                       {
                               if(deviceFormat[f] instanceof RGBFormat)type="RGB";
                               if(deviceFormat[f] instanceof YUVFormat)type="YUV";
                               if(deviceFormat[f] instanceof JPEGFormat)type="JPG";

                               Dimension size = ((VideoFormat)deviceFormat[f]).getSize();
                               camImgSize.addElement(type+" "+size.width+"x"+size.height);

                               CapDevice = deviceInfo;
                               camCapDevice.addElement(CapDevice);
                               //System.out.println("Video device = " + deviceInfo.getName());

                               CapFormat = (VideoFormat)deviceFormat[f];
                               camCapFormat.addElement(CapFormat);
                               //System.out.println("Video format = " + deviceFormat[f].toString());

                               VideoFormatMatch=true;  // at least one
                       }
               }
               if(VideoFormatMatch==false)
               {
                       if(deviceInfo!=null)System.out.println(deviceInfo);
                       System.out.println("Video Format not found");
                       return false;
               }

               return true;
       }


       void fetchDeviceDataSource()
       {
               CaptureDeviceInfo CapDevice =
(CaptureDeviceInfo)camCapDevice.elementAt(camImgSel);
               System.out.println("Video device = " + CapDevice.getName());
               Format CapFormat = (Format)camCapFormat.elementAt(camImgSel);
               System.out.println("Video format = " + CapFormat.toString());

               MediaLocator loc = CapDevice.getLocator();
               try
               {
                       dataSource = Manager.createDataSource(loc);
               }
               catch(Exception e){}

               try
               {
                       FormatControl formCont=((CaptureDevice)dataSource).getFormatControls()[0];
                       VideoFormat formatVideoNew = new
VideoFormat(null,null,-1,null,(float)camFPS);
                       formCont.setFormat(CapFormat.intersects(formatVideoNew));
               }
               catch(Exception e){}
       }

       void createPBDSource()
       {
               try
               {
                       pbs=((PushBufferDataSource)dataSource).getStreams()[0];
               }
               catch(Exception e){}
       }

       public void createProcessor(DataSource datasource)
       {
               FileTypeDescriptor ftd = new FileTypeDescriptor(FileTypeDescriptor.MSVIDEO);
               Format[] formats = new Format[] {new VideoFormat(VideoFormat.INDEO50)};
               ProcessorModel pm = new ProcessorModel(datasource, formats, ftd);
               try
               {
                       processor = Manager.createRealizedProcessor(pm);
               }
               catch(Exception me)
               {
                       System.out.println(me);
                       // Make sure the capture devices are released
                       datasource.disconnect();
                       return;
               }
       }

       private void startCapture()
       {
               // Get the processor's output, create a DataSink and connect the two.
               DataSource outputDS = processor.getDataOutput();
               try
               {
                       MediaLocator ml = new MediaLocator("file:capture.mpg");
                       datasink = Manager.createDataSink(outputDS, ml);
                       datasink.open();
                       datasink.start();
               }catch (Exception e)
               {
                       System.out.println(e);
               }
               processor.start();
               System.out.println("Started saving...");
       }

       private void pauseCapture()
       {
               processor.stop();
       }

       private void resumeCapture()
       {
               processor.start();
       }

       private void stopCapture()
       {
               // Stop the capture and the file writer (DataSink)
               processor.stop();
               processor.close();
               datasink.close();
               processor = null;
               System.out.println("Done saving.");
       }
}

错误:

跑:

视频设备 = vfw:Microsoft WDM 图像捕获 (Win32):0
视频格式 = YUV 视频格式: Size = java.awt.Dimension[width=640,height=480] MaxDataLength = 614400 DataType = class [B yuvType = 32 StrideY = 1280 StrideUV = 1280 OffsetY = 0 OffsetU = 1 OffsetV = 3

javax.media.CannotRealizeException:无法提供所有请求的曲目
线程“主”java.lang.NullPointerException 中的异常
        在 jmfcam05v.startCapture(jmfcam05v.java:202)
        在 jmfcam05v.(jmfcam05v.java:82)
        在 jmfcam05v.main(jmfcam05v.java:64)

请帮我解决这个错误。我正在使用 Windows Vista 操作系统。

谁能建议我如何以 .3gp 格式存储文件?请帮助

4

8 回答 8

5
Exception in thread "main" java.lang.NullPointerException
    at jmfcam05v.startCapture(jmfcam05v.java:202)

方法jmfcam05v.java内部的第202 行的一些对象引用是在代码尝试使用点运算符访问/调用它时。startCapture()null.

例如

SomeObject someObject = null;
someObject.doSomething(); // NullPointerException.

解决方案其实很简单。只需通过实例化它来确保它不为空:

if (someObject == null) {
    someObject = new SomeObject();
}
someObject.doSomething(); // No NPE more!

...或者在访问/调用之前简单地做一个空检查:

if (someObject != null) {
    someObject.doSomething(); // No NPE more!
}
于 2010-01-26T16:58:12.877 回答
1

NPE 很简单。其中一条线

MediaLocator ml = new MediaLocator("file:capture.mpg");
datasink = Manager.createDataSink(outputDS, ml);

在方法 startCapture 中抛出一个CannotRealizeException. 所以datasink没有初始化,如果你稍后尝试关闭它stopCapture,它仍然存在null,这会导致 NPE。

为了避免 NPE: test, if datasinkis not null 在调用它的方法之前。

编辑

您能否从构造函数中删除应用程序逻辑并将其移至 main 方法。构造函数用于构造对象,主要用于初始化类成员,仅此而已。Java 类应该以大写字母开头,这有助于人们(和我们)理解代码。

于 2010-01-26T16:58:27.777 回答
1

糟糕的异常处理是罪魁祸首。

最有可能的是,该processor成员没有被初始化。如果没有处理器,您似乎无法做任何有用的事情。所以让异常飞起来,在那个时候终止你注定要失败的程序,而不是“吞下”它并愉快地继续下去。

此外,如果您要吃异常和士兵,至少要正确打印它们:ex.printStackTrace(),而不是System.out.println(ex).

但是最好在throws你的方法中添加子句,而不是捕获任何异常,因为你无法从它们中恢复。


也许 Indeo 编解码器存在于您的 Windows XP 机器上,但在您的 Vista 机器上不可用。(更新:事实上,Indeo 不受支持并且与 Vista 不兼容。)这会阻止processor成功创建,并且您的程序从那时起注定要失败。有没有办法测试特定FileTypeDescriptor或在运行时是否VideoFormat有效

于 2010-01-26T16:58:47.720 回答
0

看起来好像这条线:

processor = Manager.createRealizedProcessor(pm);

抛出 a CannotRealizeException,导致processor为 null 并稍后导致 NPE。至于抛出什么异常,这似乎与您的数据和 JMF 的使用有关。

通常,在异常上使用是不好的,System.out.println()因为那样会丢失堆栈跟踪,这通常是调试最重要的信息。反而。采用exception.printStackTrace();

于 2010-01-26T16:58:02.870 回答
0

datasink 永远不会被初始化。

当你尝试打电话时

datasink.close();

它说datasink为空。

确保您的代码实际到达并处理第 176 行

datasink = Manager.createDataSink(outputDS, ml);
于 2010-01-26T16:58:50.160 回答
0

通过查看private void startCapture()方法,我猜processor变量是NULL因为这是唯一不在try-catch块中的东西。

于 2010-01-26T17:02:01.067 回答
0

删除这个:

Processor processor = null;
DataSink datasink = null;

并替换为:

Processor processor;
DataSink datasink;
于 2012-05-28T02:27:08.900 回答
0

This is because of createRealizedProcessor is not able to work on VedioCapture device. Issue is with Microsoft WDM Image device.

于 2013-12-30T12:08:15.333 回答