2

我正在尝试从 .avi 文件中获取单个帧(最终是音频)。最终,我想制作一个 JNI 绑定库,允许我在 Java 中打开 .avi 文件,但现在我正在使用本机 win32 C++。

我一直在用这个把头撞到墙上,尝试了 VFW,它几乎不适用于旧视频,但它断然拒绝给我任何更新视频的帧。我接受了 VFW 已经老了。

在尝试 DirectShow 后,我发现几乎没有关于如何支持它的文档,并且最终阅读了一些文章,说由于其流媒体性质,它对于单个帧抓取很糟糕。

然后我发现 ffmpeg 甚至不支持视觉工作室。

Java 的 JMF 已经过时,而且在新世纪似乎也完全不受支持,而且也没有很好的教程。

谁能指出我独立于编解码器的 .avi 解码器解决方案的方向?最好是本机或 Java,但我想我可以尝试改造一些 .NET,如果它归结为电线。

4

2 回答 2

1

根据我的经验,JMF 运行良好,它非常最新,API 非常强大等。我编写了将剪辑分割成单个帧的程序。不幸的是,我现在无法实现任何代码示例,但据我所知,我使用了 Player 和某种控件(FrmeControl 左右)。

如果由于某种原因您仍然不想使用 JMF,我建议您从命令行调用 ffmpeg。由于 ffmpeg 是一个非常强大(甚至是最强大的)用于视频处理的命令行实用程序,并且可用于多个平台,因此您的应用程序也可以是跨平台的。

于 2011-06-18T05:36:45.710 回答
0

你可以试试 OpenCV。我有读取和修改视频文件的功能,它可以打开多种格式。它适用于 C++,但不确定它是否适用于 JAVA。它也不会解析音频。

这是我在计算机视觉项目中使用的示例实现

.h 文件

#ifndef _VPLAYER_H_

#define _VPLAYER_H_

#include #include #include #include "cv.h" #include "highgui.h"

类VPlayer {

公共:VPlayer();~VPlayer();

私人的:

CvCapture* pAvi;
IplImage* pFrame;

公共:int高度;整数宽度;帧速率;整数帧数;双编解码器代码;

上市:

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);
}

}

于 2011-06-18T07:48:46.260 回答