这是代码:
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.");
}
}
错误:
运行:
Video device = vfw:Microsoft WDM Image Capture (Win32):0 Video format = YUV Video Format: 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: Unable to provide all requested tracks Exception in thread "main" java.lang.NullPointerException at jmfcam05v.startCapture(jmfcam05v.java:202) at jmfcam05v.(jmfcam05v.java:82) at jmfcam05v.main(jmfcam05v.java:64)
请帮我解决这个错误。我正在使用Windows Vista操作系统。
有人可以建议我如何以.3gp格式存储文件吗?请帮忙
答案 0 :(得分:5)
Exception in thread "main" java.lang.NullPointerException at jmfcam05v.startCapture(jmfcam05v.java:202)
jmfcam05v.java
方法内的startCapture()
第202行的某些对象引用为null
,而代码尝试使用点.
运算符访问/调用它
E.g。
SomeObject someObject = null;
someObject.doSomething(); // NullPointerException.
解决方案实际上很简单。只需通过实例化它确保它不为null:
if (someObject == null) {
someObject = new SomeObject();
}
someObject.doSomething(); // No NPE more!
...或者在访问/调用之前简单地执行nullcheck:
if (someObject != null) {
someObject.doSomething(); // No NPE more!
}
答案 1 :(得分:1)
NPE很简单。其中一行
MediaLocator ml = new MediaLocator("file:capture.mpg");
datasink = Manager.createDataSink(outputDS, ml);
方法startCapture中的会抛出CannotRealizeException
。因此datasink
未初始化,如果您稍后在stopCapture
中尝试关闭它,则它仍然是null
,这会导致NPE。
要避免NPE:test,如果datasink
在调用方法之前不为null,则
修改强>
你可以请从构造函数中删除应用程序逻辑并将其移动到main方法。构造函数用于构造对象,主要用于初始化类成员而不是其他任何东西。 Java类应该以大写字母开头,这有助于人们(和我们)理解代码。
答案 2 :(得分:1)
这里应该责备不良的异常处理。
最有可能的是,processor
成员未初始化。如果没有处理器,看起来你不能做任何有用的事情。因此,让异常飞行,在那时终止你的注定程序,而不是“吞咽”它并且继续快乐地继续。
此外,如果你打算吃异常和士兵,至少要正确打印它们:ex.printStackTrace()
,而不是System.out.println(ex)
。
但是将throws
子句添加到您的方法中会更好,而不会捕获任何异常,因为您无法从它们中恢复。
也许Indeo编解码器存在于您的Windows XP机器上,但在您的Vista机器上不可用。 (更新:实际上,不支持Indeo和not compatible with Vista.)这会阻止processor
成功创建,并且您的程序从那时起就注定失败了。有没有办法在运行时测试特定的FileTypeDescriptor
或VideoFormat
是否有效
答案 3 :(得分:0)
看起来好像这一行:
processor = Manager.createRealizedProcessor(pm);
引发CannotRealizeException
,导致processor
为空并稍后导致NPE。至于抛出什么异常,这似乎与您的数据和JMF的使用有关。
通常,在异常上使用System.out.println()
是不好的,因为这会丢失堆栈跟踪,这通常是调试的最重要信息。代替。使用exception.printStackTrace();
答案 4 :(得分:0)
数据链永远不会被初始化。
当您尝试拨打
时datasink.close();
它说数据链为空。
确保您的代码实际到达并处理第176行
datasink = Manager.createDataSink(outputDS, ml);
答案 5 :(得分:0)
通过查看private void startCapture()
方法,我猜processor
变量为NULL
,因为这是唯一不在try-catch
块中的内容。
答案 6 :(得分:0)
删除它:
Processor processor = null;
DataSink datasink = null;
并替换为:
Processor processor;
DataSink datasink;
答案 7 :(得分:0)
这是因为createRealizedProcessor无法在VedioCapture设备上运行。 问题出在Microsoft WDM Image设备上。