Схватив кадры из .avi - PullRequest
       5

Схватив кадры из .avi

2 голосов
/ 18 июня 2011

Я пытаюсь получить отдельные кадры (и, в конечном итоге, аудио) из файлов .avi. В конечном итоге я хочу создать библиотеку, связанную с JNI, которая позволит мне открывать файлы .avi в Java, но сейчас я работаю на родном win32 C ++.

Я бился головой об стену с этим, пробовал VFW, и он едва работает для старых видео, но он категорически отказывается давать мне какой-либо кадр более свежего видео. Я смирился с тем, что VFW был стар.

Попробовав DirectShow, я практически не нашел документации о том, как его поддерживать, и заканчиваю читать статьи, в которых говорится, что это отстой для отдельных захватов кадров из-за потоковой природы.

Тогда я узнаю, что ffmpeg даже не поддерживает визуальную студию.

Java JMF устарел и, похоже, полностью не поддерживается в новом столетии, и хороших руководств для этого также не существует.

Может кто-нибудь направить меня в сторону решения, не зависящего от кодека .avi? Предпочтительно нативный или Java, но я думаю, что я могу попытаться дооснастить что-нибудь .NET, если это произойдет.

Ответы [ 2 ]

1 голос
/ 18 июня 2011

Судя по моему опыту, JMF отлично работает, он очень современный, API очень мощный и т.д. Я написал программу, которая разбивает клип на отдельные кадры.К сожалению, сейчас я не могу получить ни одного примера кода, но, насколько я помню, я использовал Player и какой-то элемент управления (FrmeControl или около того).

Если по какой-то причине вы все еще не хотите использовать JMF, я бы порекомендовал вам вызвать ffmpeg из командной строки.Поскольку ffmpeg является очень сильной (даже самой сильной) утилитой командной строки для обработки видео и доступна для нескольких платформ, ваше приложение также может быть кроссплатформенным.

0 голосов
/ 18 июня 2011

Вы можете попробовать OpenCV.У меня есть функции для чтения и изменения видео файла, и он может открывать различные форматы.Он доступен для C ++, но не уверен, что он доступен для JAVA.Также он не будет анализировать аудио.

Вот пример моей реализации, которую я использую в своих проектах машинного зрения

.h файл

#ifndef _VPLAYER_H_

# define _VPLAYER_H_

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

class VPlayer {

public: VPlayer ();~ VPlayer ();

private:

CvCapture* pAvi;
IplImage* pFrame;

public: int Height;int Width;int fps;int numFrames;double CodecCode;

public:

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

};

# endif

.cpp file

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

}

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

}

void VPlayer :: GetImage (IplImage * & pOutBuffer) {

pOutBuffer = cvCloneImage(pFrame);

}

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

}

...