编辑:
从网络摄像头录制并将每帧的时间戳编码为毫秒分辨率的最佳方法是什么?应该使用什么视频格式/编解码器? 我已经非常努力地安装xuggler但是无法做到。在生产者/消费者范例中使用JCodec的SequenceEncoder,但它太慢了。
public class WebcamProducerConsumer {
//
private Producer p;
private Consumer c;
private BlockingQueue<BufferedImageAndTimeLong> sharedQueue;
public WebcamProducerConsumer() throws IOException {
sharedQueue = new LinkedBlockingQueue<BufferedImageAndTimeLong>();
p = new Producer(sharedQueue);
c = new Consumer(sharedQueue);
}
public void start(Webcam cam){
p.setUpCamera(cam);
p.startCamera();
System.out.println("Cam set up");
Thread pThread = new Thread(p);
Thread cThread = new Thread(c);
pThread.start();
cThread.start();
System.out.println("P and C running");
}
public void startSaving(File f){
try {
c.startSaving(f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void finishSaving() throws IOException{
p.sendSentinel();
System.out.println("Saving Done");
}
public void closeWebcamProducerConsumer() throws IOException{
p.kill();
c.kill();
}
}
public class Producer implements Runnable {
private BlockingQueue<BufferedImageAndTimeLong> sharedQueue;
private Webcam webcam;
private boolean capturing;
public Producer(BlockingQueue<BufferedImageAndTimeLong> sharedQueue) {
this.sharedQueue = sharedQueue;
capturing = false;
}
public void setUpCamera(Webcam wb){
webcam = wb;
}
public void startCamera(){
webcam.open();
capturing = true;
}
@Override
public synchronized void run() {
while(capturing){//eh?
try{
sharedQueue.add(new BufferedImageAndTimeLong(webcam.getImage(), System.nanoTime()));}
catch(NullPointerException e){
e.printStackTrace();
System.out.println("Camera was not opened");
}
System.out.println(sharedQueue.size());
}
if (!capturing){
sharedQueue.add(null);
}
}
public synchronized void kill() {
sharedQueue.add(null);
capturing = false;
}
public void sendSentinel(){
sharedQueue.add(new BufferedImageAndTimeLong(null, -1));
}
}
public class Consumer{
public synchronized void run() {
while(recording){
BufferedImageAndTimeLong bitl;
try {
bitl = sharedQueue.take();
if (bitl.getTimeLong()!= -1){
currentImage = bitl.getBufferedImage();
// System.out.println(bitl.getTimeLong());
if (saving){
enc.encodeImage(currentImage);
// JOptionPane.showInputDialog(null, "SequenceEncoder is null!");
}
}
else {
enc.finish();
saving = false;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void kill() throws IOException{
recording = false;
}
public void startSaving(File f) throws IOException{
enc = new SequenceEncoder(f);
saving = true;
}
/*
public void finishSaving() throws IOException{
try{
saving = false;
savingStateChanging = true;
System.out.println("Saving Complete");
}catch(NullPointerException e){
e.printStackTrace();
JOptionPane.showInputDialog(null, "SequenceEncoder is null!");
}
}
*/
public BufferedImage getCurrentImage(){
return currentImage;
}
}