从.avi抓取帧

问题描述

| 我试图从.avi文件中抓取单个帧(并最终获取音频)。最终,我想创建一个JNI绑定的库,该库允许我用Java打开.avi文件,但现在我正在使用本机win32 C ++。 我一直在用这种方法把头撞在墙上,尝试了VFW,它几乎不能用于较旧的视频,但是它断然拒绝给我任何最新视频的框架。我辞职了,以为VFW很老。 在尝试DirectShow时,我几乎找不到有关如何支持它的文档,并且收看一些文章说,由于其流式传输的特性,它在单个帧抓取中很烂。 然后我发现ffmpeg甚至不支持Visual Studio。 Java的JMF已经过时了,并且在新世纪似乎也完全不受支持,并且也没有很好的教程。 谁能指出我与编解码器无关的.avi解码器解决方案的方向?最好是本机或Java,但我想我可以尝试对.NET进行改造,如果它确实可用的话。     

解决方法

        根据我的经验,JMF可以很好地工作,它是最新的,API非常强大,等等。我编写了将剪辑拆分为单个帧的程序。不幸的是,我现在无法获得任何代码示例,但据我所记得,我曾经使用Player和某种控件(FrmeControl左右)。 如果出于某些原因您仍然不想使用JMF,建议您从命令行调用ffmpeg。由于ffmpeg是用于视频处理的非常强大(甚至最强大)的命令行实用程序,并且可用于多个平台,因此您的应用程序也可以跨平台。     ,        您可以尝试使用OpenCV。我具有读取和修改视频文件的功能,并且可以打开多种格式。它可用于C ++,但不确定是否可用于JAVA。而且它不会解析音频。 这是我在计算机视觉项目中使用的我的示例实现 .h文件
#ifndef _VPLAYER_H_
#定义_VPLAYER_H_ #包括    #包括    #包括    #include \“ cv.h \”    #include \“ highgui.h \” VPlayer类{ 上市:     VPlayer();     〜VPlayer(); 私人的:
CvCapture* pAvi;
IplImage* pFrame;
上市:     int高度;     int宽度;     int fps;     int numFrames;     双重CodecCode; 上市:
bool LoadVideo(char * fname);
void GetFrame(int FrameNo);
void GetImage (IplImage* &pOutBuffer);
void GetProperties();
}; #万一 .cpp文件 #include \“ stdafx.h \”    #include \“ VideoPlayer_PB_1.h \” bool VPlayer :: LoadVideo(char * 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(){     if(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);
}
}