2011-06-18 60 views
2

我想從.avi文件抓取單個幀(最終是音頻)。最終我想創建一個JNI綁定的庫,它允許我在Java中打開.avi文件,但現在我正在使用原生的win32 C++。從.avi抓取幀

我一直在用這個嘗試過的VFW將我的頭撞在牆上,它幾乎不適用於較老的視頻,但它堅決拒絕給我任何更新的視頻幀。我向自己致敬,VFW很舊。

在嘗試DirectShow時,我發現幾乎沒有關於如何支持它的文檔,並且結束閱讀文章說它由於其流媒體性質而吸引單個幀抓取。

然後我發現ffmpeg甚至不支持visual studio。

Java的JMF已經過時,在新世紀似乎也完全沒有支持,也沒有好的教程。

任何人都可以指向獨立於編解碼器的.avi解碼器解決方案嗎?最好是native或Java,但我想我可以嘗試改裝.NET的東西,如果它涉及到電線。

+0

較早[FMJ(http://fmj-sf.net/)SO提到的。不記得帖子,但有[許多帖子](http://stackoverflow.com/search?q=fmj)。 (我還沒有使用它,所以沒有關於質量或易用性的任何說明) – Atreys

回答

1

根據我的經驗,JMF工作正常,它是最新的,API功能非常強大等。我編寫了將剪輯分割成單獨框架的程序。不幸的是,我現在無法實現任何代碼示例,但據我記憶,我使用了Player和某種控件(FrmeControl等)。

如果由於某種原因,您仍然不想使用JMF,我建議您從命令行調用ffmpeg。由於ffmpeg是一個非常強大的(即使是最強大的)用於視頻處理的命令行實用程序,可用於多種平臺,因此您的應用程序也可以是跨平臺的。

0

你可以試試OpenCV。我有讀取和修改視頻文件的功能,它可以打開各種格式。它適用於C++,但不確定它是否可用於JAVA。它也不會解析音頻。

這裏是我的一個樣本實現,我在我的計算機視覺利用項目

.h文件中

#ifndef _VPLAYER_H_ 

的#define _VPLAYER_H_

的#include 的#include 的#include #包括「cv.h」# #include「highgui。H」

類VPLAYER {

公共: VPLAYER(); 〜VPLAYER();

私人:

CvCapture* pAvi; 
IplImage* pFrame; 

公共: INT身高; INT寬度; int fps; int numFrames; double CodecCode;

市民:

bool LoadVideo(char * fname); 
void GetFrame(int FrameNo); 
void GetImage (IplImage* &pOutBuffer); 
void GetProperties(); 

};

#ENDIF

.cpp文件

的#include 「stdafx.h中」 的#include 「VideoPlayer_PB_1.h」

布爾VPLAYER :: LoadVideo(字符* FNAME){

if(pAvi)cvReleaseCapture(&pAvi); 
if(!(pAvi = cvCaptureFromAVI(fname)))return false; 
GetProperties(); 
return true; 

}

VPlayer :: VPlayer(){ pAvi = 0; pFrame = 0; }

VPLAYER ::〜VPLAYER(){

cvReleaseCapture(&pAvi); 

}

空隙VPLAYER ::的getFrame(INT FrameNo){

cvSetCaptureProperty(pAvi,CV_CAP_PROP_POS_FRAMES,FrameNo); 

if(!cvGrabFrame(pAvi)){    // capture a frame 
    printf("Could not grab a frame\n\7"); 
    exit(0); 
} 
pFrame = cvRetrieveFrame(pAvi); 

}

空隙VPLAYER :: GetImage(IplImage * & pOutBuffer){

pOutBuffer = cvCloneImage(pFrame); 

}

空隙VPLAYER ::的GetProperties(){ 如果(PAVI){ cvQueryFrame(PAVI); //這個調用是必要得到我看到正確的捕獲性能

Height = (int) cvGetCaptureProperty(pAvi, CV_CAP_PROP_FRAME_HEIGHT); 

    Width = (int) cvGetCaptureProperty(pAvi, CV_CAP_PROP_FRAME_WIDTH); 

    fps  = (int) cvGetCaptureProperty(pAvi, CV_CAP_PROP_FPS); 

    numFrames = (int) cvGetCaptureProperty(pAvi, CV_CAP_PROP_FRAME_COUNT); 

    CodecCode = cvGetCaptureProperty(pAvi, CV_CAP_PROP_FOURCC); 
} 

}