erro java:Exceção no thread “principal” java.lang.NullPointerException
Pergunta
Aqui está o código:
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.");
}
}
Erro:
correr:
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)
por favor me ajude com este erro. Estou usando o sistema operacional Windows Vista.
alguém pode me sugerir como armazenar arquivos no formato .3gp?
Solução
Exception in thread "main" java.lang.NullPointerException at jmfcam05v.startCapture(jmfcam05v.java:202)
Alguma referência de objeto na linha 202 de jmfcam05v.java
, dentro de startCapture()
método, é null
Enquanto o código está tentando acessar/invocar usando o ponto .
operador.
Por exemplo
SomeObject someObject = null;
someObject.doSomething(); // NullPointerException.
A solução é realmente fácil. Apenas certifique -se de que não seja nulo, instantando -o:
if (someObject == null) {
someObject = new SomeObject();
}
someObject.doSomething(); // No NPE more!
... ou simplesmente fazendo um NullCheck antes de acessar/invocar:
if (someObject != null) {
someObject.doSomething(); // No NPE more!
}
Outras dicas
O NPE é fácil. Uma das linhas
MediaLocator ml = new MediaLocator("file:capture.mpg");
datasink = Manager.createDataSink(outputDS, ml);
no método startcapture lança um CannotRealizeException
. Então datasink
não é inicializado e se você tentar fechá -lo mais tarde stopCapture
, ainda é null
E isso causa o NPE.
Para evitar o NPE: teste, se datasink
não é nulo antes de chamar um método nele.
EDITAR
E você poderia POR FAVOR Remova a lógica do aplicativo do construtor e mova -a para o método principal. Um construtor é para construir um objeto, principalmente para inicializar os membros da classe e nada mais. E as aulas de Java devem começar com uma letra maiúscula, que ajuda as pessoas (e nós) a entender o código.
O mau tratamento de exceções é o culpado aqui.
Muito provavelmente, o processor
membro não está sendo inicializado.Se não houver um processador, parece que você não poderá fazer nada de útil.Então deixe a exceção voar, encerrando seu programa condenado naquele ponto, em vez de "engoli-lo" e continuar alegremente.
Além disso, se você for comer exceções e seguir em frente, pelo menos imprima-as corretamente: ex.printStackTrace()
, em vez de System.out.println(ex)
.
Mas seria muito melhor adicionar throws
cláusulas aos seus métodos e não capturar nenhuma exceção, já que você não pode se recuperar delas.
Talvez o codec Indeo estivesse presente na sua caixa do Windows XP, mas não esteja disponível na sua máquina Vista.(Atualizar: Na verdade, o Indeo não é suportado e não é compatível com o Vista.) Isso impede o processor
seja criado com sucesso e seu programa estará condenado a partir desse ponto.Existe uma maneira de testar se um determinado FileTypeDescriptor
ou VideoFormat
é válido em tempo de execução?
Parece que esta linha:
processor = Manager.createRealizedProcessor(pm);
Joga a CannotRealizeException
, causando processor
ser nulo e levar ao NPE mais tarde. Quanto ao que essa exceção é lançada, isso parece ter a ver com seus dados e uso do JMF.
Geralmente, é ruim usar System.out.println()
Sobre exceções, porque você perde o rastreamento da pilha, que geralmente é a informação mais importante para a depuração. Em vez de. usar exception.printStackTrace();
O DataSink nunca está sendo inicializado.
Quando você tenta ligar
datasink.close();
Está dizendo que o DataSink é nulo.
Certifique -se de que seu código está realmente chegando e processando a linha #176
datasink = Manager.createDataSink(outputDS, ml);
Olhando para o private void startCapture()
Método eu acho que o processor
variável é NULL
Como esta é a única coisa que não está em um try-catch
quadra.
Tire isto :
Processor processor = null;
DataSink datasink = null;
e substitua por isso:
Processor processor;
DataSink datasink;
Isso ocorre devido ao processador creeRealized não é capaz de trabalhar no dispositivo Vediocapture. O problema é com o dispositivo de imagem Microsoft WDM.