Media Player 播放视频,怎么截取画面,和截取出某一小段视频独立出来。

Thorwein 2009-04-06 11:29:05
Media Player 播放视频,怎么截取画面,和截取出某一小段视频独立出来。
上网搜了很多,很多朋友回答得有点泛。没有什么头绪,可能主要原因是COM我不熟悉吧。
很多朋友说用Directshow,如果Directshow具体步骤是一个怎么的流程呢?
或者还有别的方法的朋友,也支支招。 先谢过。
...全文
618 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jerry4711 2009-04-09
  • 打赏
  • 举报
回复
HRESULT CFrameGrabberDlg::GrabFrameFromMovie()
{
double dtime = 0.00;
double totaltime=1;

for (dtime =0;dtime<totaltime;dtime+=0.04)
{
HRESULT hr;
// 定义IMediaDet接口实例
CComPtr< IMediaDet > pDet;
hr = CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER,
IID_IMediaDet, (void**) &pDet );
if (FAILED(hr))
return hr;

// 将影片文件名转换成BSTR类型
CComBSTR openBSTR(m_editOpenDir);
// 设置IMediaDet接口的文件关联
hr = pDet->put_Filename(openBSTR);
if (FAILED(hr))
return hr;

// 从影片中检索视频流和音频流
long lStreams;
hr = pDet->get_OutputStreams(&lStreams);
if (FAILED(hr))
return hr;

// 取出影片的视频流,因为帧的信息是保存在视频流中的
bool bFound = false;
//------ 1 ----------------------
for (int i=0; i<lStreams; i++)
{
GUID major_type;
hr = pDet->put_CurrentStream(i);
if (SUCCEEDED(hr))
hr = pDet->get_StreamType(&major_type);
if (FAILED(hr))
break;
//---------- 2 ---------------
if (major_type == MEDIATYPE_Video)
{
bFound =true;
long width = 0, height = 0; // 存储位图的宽和高(单位:象素)
AM_MEDIA_TYPE mt;
hr = pDet->get_StreamMediaType(&mt);
//----------- 3 -----------------------
if (SUCCEEDED(hr))
{
if ((mt.formattype == FORMAT_VideoInfo) &&
(mt.cbFormat >= sizeof(VIDEOINFOHEADER)))
{
// 得到VIDEOINFOHEADER结构指针,VIDEOINFOHEADER结构包含一些与视频
// 有关的信息,其中含有BITMAPINFORHEADER结构
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)(mt.pbFormat);
width = pVih->bmiHeader.biWidth;
height = pVih->bmiHeader.biHeight;
}
else
hr = VFW_E_INVALIDMEDIATYPE;
MyFreeMediaType(mt); // 释放AM_MEDIA_TYPE结构
}
long size;
//double dtime = 0.00;
//double totaltime,dRate;

pDet->get_StreamLength(&totaltime); // 获取整个视频的时间长度
//pDet->get_FrameRate(&dRate);
CStatic * ps = (CStatic *)GetDlgItem(AFX_IDS_PICTYPE_BITMAP); //picture是CStatic类型
// 每1秒,截取视频截图
//for(dtime=0.0; dtime <totaltime; dtime+=0.4)
//{
// 获取bitmap的buffer大小

hr = pDet->GetBitmapBits(dtime, &size, 0, width, height);

if (SUCCEEDED(hr))
{
//分配缓冲区
char *pBuffer = new char[size];
if (!pBuffer)
return NULL;

//------------------ 4 ------------------------
hr = pDet->GetBitmapBits(dtime, 0, pBuffer, width, height);
if (SUCCEEDED(hr))
{
// Find the address of the start of the image data.
void *pData = pBuffer + sizeof(BITMAPINFOHEADER);
BITMAPINFOHEADER *bmih = (BITMAPINFOHEADER*)pBuffer;

BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
CopyMemory(&(bmi.bmiHeader), bmih, sizeof(BITMAPINFOHEADER));
HBITMAP hBitmap = CreateDIBitmap(::GetDC(NULL), bmih, CBM_INIT,
pData, &bmi, DIB_RGB_COLORS);

ps->SetBitmap(hBitmap);
DeleteObject(hBitmap);
//ps->ReleaseDC;

}
delete[] pBuffer;
}
//::Sleep(400);
//}
}
}
pDet ->Release;

::Sleep(40);

if (!bFound)
return VFW_E_INVALIDMEDIATYPE;

if (FAILED(hr))
return hr;
}

return S_OK;
}



这个代码是我以前用DSHOW截视频画面的主要函数,有点乱,楼主自己参考参考
warsour 2009-04-08
  • 打赏
  • 举报
回复
我看过这样做过的
就是播放时捕获视频流和音频流临时存到一个文件里,然后借助像ffmpeg之类的转换成你想要的类型
Thorwein 2009-04-06
  • 打赏
  • 举报
回复
兄弟 光顶。。。。没用啊。
朋友的毕业设计,,,快要挂了~。。。

看了看directshow开发指南,看得我晕晕的。

大家也可以说说,如果我要学短期之内学这个,学到可以解决这个毕设。要怎么来学习呢?

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧