【问题标题】:Grabbing frames from .avi从 .avi 抓取帧
【发布时间】:2011-09-17 15:25:50
【问题描述】:

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

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

在尝试 DirectShow 时,我发现几乎没有关于如何支持它的文档,最后阅读的文章说,由于其流式传输特性,它对于单个帧抓取很糟糕。

然后我发现 ffmpeg 甚至不支持 Visual Studio。

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

谁能告诉我独立于编解码器的 .avi 解码器解决方案的方向?最好是本机或 Java,但我想我可以尝试对 .NET 进行改造,如果它归结为网络的话。

【问题讨论】:

  • 我之前在 SO 上看到过 FMJ。不记得帖子了,但是有many posts。 (我还没用过,所以质量和易用性没啥好说的)

标签: java c++ avi


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    .h 文件

    #ifndef _VPLAYER_H_
    

    #define _VPLAYER_H_

    #包括 #包括 #包括 #包括“cv.h” #include "highgui.h"

    类VPlayer {

    公开: VPlayer(); ~VPlayer();

    私人:

    CvCapture* pAvi;
    IplImage* pFrame;
    

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

    公开:

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

    };

    #endif

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

    }

    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(){ 如果(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);
    }
    

    }

    【讨论】:

      猜你喜欢
      • 2012-05-21
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多