简单MP4制作文档.docx
《简单MP4制作文档.docx》由会员分享,可在线阅读,更多相关《简单MP4制作文档.docx(40页珍藏版)》请在冰豆网上搜索。
![简单MP4制作文档.docx](https://file1.bdocx.com/fileroot1/2023-1/8/d5ee8774-b9ac-4315-82cd-037c291ba270/d5ee8774-b9ac-4315-82cd-037c291ba2701.gif)
简单MP4制作文档
简单MP4制作文档
1:
打开VisualStudio.Net2005,选择File->New->Project…,在NewProject下面选择VisualC++->SmartDevice工程类型,选择MFCSmartDeviceApplication文件类型。
在下列的Name和Location当中分别填写文件名MediaPlayer和D:
\vc\XSBase270工程文件路径。
图【1】NewProject建立界面
2:
在下列的步骤当中,按照如下图所示,选择好所见工程的SDK和工程类型,选择Emulator(SDK,注意这里的SDK是我们从PlatformBuilder工程镜像当中导出产生。
),工程类型为:
DialogBase对话框工程类型。
图【2】MFCSmartDeviceApplicationWinzard(向导)
图【3】选择工程SDK类型
图【4】工程类型选择向导
图【5】MFCSmartDeviceApplicationWizard
图【6】MFCSmartDeviceApplicationWizard
图【7】MFCSmartDeviceApplicationWizard
4:
工程建立完成之后,按照如下图所示添加如下组建并设置其属性如下:
控件ID
控件类型
控件说明
IDC_WND_VIDEO
TEXT_Control(static组件)
用于视频显示
IDC_PRG_VIDEO
Progress_Bar_Control
用于显示播放进度
IDC_Open
Button
用于打开播放视屏文件
IDC_Pause
Button
用于暂停播放的视频文件
IDC_Stop
Button
用于停止当前播放视频文件
IDC_Full
Button
用于全频显示当前播放的视频
IDC_Play
Button
用于播放开始播放视频
图【8】MediaPlayer播放器界面构架
5:
选择MediaPlayer工程,单击右键选择工程Property->ConfigurationProperties->Linker->Input,在AdditionalDependecies当中输入strmiids.lib,为能使用directshow库而做好准备。
图【9】静态库添加方法图
6:
建立一个Directshow的接口类,其中包括Directshow的如下接口:
IGraphicBuilder,IMediaControlm,IMediaEventEx,IVideoWindow,IBasicAudio,IBasicVideo和IMediaSeeking。
建立类的方法如下:
1:
在SolutionExplor视图下,右单击MediaPlayer工程,选择Add->Class(如下图提示);
2:
在AddClass选中C++->C++Class,按Add添加按钮添加CEricMediaControl类。
(这里两部也可以不用,我们可以直接在已有的工程当中,将EricMediaControl.h和EricMediaControl.cpp两个文件拷贝到当前工程目录下。
)
图【10_1】添加类方法
图【10_2】添加类方法
图【10_3】添加类方法
并在其中输入如下代码:
CEricMediaControl(类头文件定义如下)
EricMediaControl.h(用如下代码规换掉原来的代码)
#pragmaonce
#include
#include
//定义DSHOW事件通知消息
#defineWM_GRAPHNOTIFYWM_USER+101
classCEricMediaControl
{
public:
CEricMediaControl(void);
~CEricMediaControl(void);
private:
//DSHOW接口
IGraphBuilder*m_pGB;
IMediaControl*m_pMC;
IMediaEventEx*m_pME;
IVideoWindow*m_pVW;
IBasicAudio*m_pBA;
IBasicVideo*m_pBV;
IMediaSeeking*m_pMS;
//显示视频的窗口句柄
HWNDm_hOwnerWnd;
private:
//初始化DSHOW接口
BOOLInitDShow(LPCTSTRstrFileName/*视频文件名*/
HWNDhOwnerWnd/*显示视频的窗口句柄*/
HWNDhNotifyWnd/*接收DSHOW事件消息的串口句柄*/
);
//释放DSHOW接口
BOOLUnInitDShow();
public:
//打开视频文件
BOOLOpenFile(LPCTSTRstrFileName/*视频文件名*/
HWNDhOwnerWnd/*显示视频的窗口句柄*/
HWNDhNotifyWnd/*接收DSHOW事件消息的串口句柄*/
);
//播放视频
BOOLVideoRun();
//暂停视频
BOOLVideoPause();
//停止视频
BOOLVideoStop();
public:
BOOLFitVideoWindow(FLOATfScale);//设置视频显示比例
BOOLFullScreen();//全屏显示
BOOLGetFullScreenStatus();//得到是否是全屏显示
BOOLGetMediaEvent(long*lEventCode);//得到Dshow播放事件
//设置播放进度,单位:
秒
BOOLSetPositions(DWORDdwPos/*设置当前播放进度*/);
//得到视频播放当前的位置,单位:
秒
BOOLGetCurrentPos(DWORD&dwPos/*out当前播放进度*/);
BOOLGetDuration(DWORD&dwLength);//得到视频文件时间长度,单位:
秒
};
EricMediaControl.h文件添加好后,如下图所示:
图【11】CEricMediaControl.h头文件添加视图
CEricMediaControl类实现文件
向EricMediaControl.cpp文件当中添加如下源代码:
#include"StdAfx.h"
#include"EricMediaControl.h"
CEricMediaControl:
:
CEricMediaControl(void)//构造函数
{
//将DSHOW接口置空
m_pGB=NULL;
m_pMC=NULL;
m_pME=NULL;
m_pVW=NULL;
m_pBA=NULL;
m_pBV=NULL;
m_pMS=NULL;
//初始化COM环境
CoInitialize(NULL);//directshow使用到了COM技术,在使用Directshow变量时,我们首先要初始化COM环境。
}
//析构函数
CEricMediaControl:
:
~CEricMediaControl(void)
{
//释放DSHOW接口
UnInitDShow();
//释放COM环境
CoUninitialize();
}
Directshow接口流程图:
/*
*函数介绍:
初始化DShow接口,并渲染好视频文件
*入口参数:
strFileName:
视频文件名
hOwnerWnd:
显示视频的窗口句柄
hNotifyWnd:
接收DSHOW事件消息的串口句柄
*出口参数:
(无)
*返回值:
TRUE:
成功;FALSE:
失败
*/
BOOLCEricMediaControl:
:
InitDShow(LPCTSTRstrFileName/*视频文件名*/
HWNDhOwnerWnd/*显示视频的窗口句柄*/
HWNDhNotifyWnd/*接收DSHOW事件消息的串口句柄*/
)
{
HRESULThResult;
//第1步:
创建IGraphBuilder接口
hResult=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(void**)&m_pGB);
if(hResult!
=S_OK)
{
returnFALSE;
}
//第2步:
利用IGraphBuilder渲染视频文件
hResult=m_pGB->RenderFile(strFileName,NULL);
if(hResult!
=S_OK)
{
//
if(hResult==VFW_S_PARTIAL_RENDER)
{
TRACE(L"Someofthestreamsinthismovieareinanunsupportedformat.\n");
}
elseif(hResult==VFW_S_AUDIO_NOT_RENDERED)
{
TRACE(L"Partialsuccess;theaudiowasnotrendered.\n");
}
elseif(hResult==VFW_S_DUPLICATE_NAME)
{
TRACE(L"Success;theFilterGraphManagermodifiedthefilternametoavoidduplication..\n");
}
elseif(hResult==VFW_S_VIDEO_NOT_RENDERED)
{
TRACE(L"Partialsuccess;someofthestreamsinthismovieareinanunsupportedformat.\n");
}
else
{
//释放DSHOW接口
UnInitDShow();
returnFALSE;
}
}
//第3步:
得到媒体播放控制接口
hResult=m_pGB->QueryInterface(IID_IMediaControl,(void**)&m_pMC);
if(hResult!
=S_OK)
{
//释放DSHOW接口
UnInitDShow();
returnFALSE;
}
//第4步:
得到媒体播放位置搜索接口
hResult=m_pGB->QueryInterface(IID_IMediaSeeking,(void**)&m_pMS);
if(hResult!
=S_OK)
{
//释放DSHOW接口
UnInitDShow();
returnFALSE;
}
//设置查找定位的时间单位,这里设置:
纳秒(十亿分之一秒)
//GUIDguid_timeFormat=TIME_FORMAT_MEDIA_TIME;
//m_pMS->SetTimeFormat(&guid_timeFormat);
//第5步:
得到FilterGraph媒体事件接口
hResult=m_pGB->QueryInterface(IID_IMediaEventEx,(void**)&m_pME);
if(hResult!
=S_OK)
{
//释放DSHOW接口
UnInitDShow();
returnFALSE;
}
//设置媒体事件通知消息窗口
m_pME->SetNotifyWindow((OAHWND)hNotifyWnd,WM_GRAPHNOTIFY,0);
//第6步:
得到视频播放窗口接口
hResult=m_pGB->QueryInterface(IID_IVideoWindow,(void**)&m_pVW);
if(hResult!
=S_OK)
{
//释放DSHOW接口
UnInitDShow();
returnFALSE;
}
//设置视频播放窗口句柄
m_pVW->put_Owner((OAHWND)hOwnerWnd);
//设置视频窗口格式
m_pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
//第7步:
得到基础视频流接口
hResult=m_pGB->QueryInterface(IID_IBasicVideo,(void**)&m_pBV);
if(hResult!
=S_OK)
{
//释放DSHOW接口
UnInitDShow();
returnFALSE;
}
//第8步:
得到基础音频流接口
hResult=m_pGB->QueryInterface(IID_IBasicAudio,(void**)&m_pBA);
if(hResult!
=S_OK)
{
//释放DSHOW接口
UnInitDShow();
returnFALSE;
}
returnTRUE;
}
/*
*函数介绍:
卸载DShow系列接口
*入口参数:
(无)
*出口参数:
(无)
*返回值:
TRUE:
成功;FALSE:
失败
*/
BOOLCEricMediaControl:
:
UnInitDShow()
{
//1,释放媒体播放控制接口
if(m_pMC!
=NULL)
{
//停止视频播放
m_pMC->Stop();
m_pMC->Release();
m_pMC=NULL;
}
//2,释放媒体事件接口
if(m_pME!
=NULL)
{
//消息通知窗口置空
m_pME->SetNotifyWindow(NULL,0,0);
m_pME->Release();
m_pME=NULL;
}
//3,释放视频播放窗口接口
if(m_pVW!
=NULL)
{
//隐藏视频窗口
m_pVW->put_Visible(OAFALSE);
//设置视频播放窗口句柄为空
m_pVW->put_Owner(NULL);
m_pVW->Release();
m_pVW=NULL;
}
//4,释放基础音频流接口
if(m_pBA!
=NULL)
{
m_pBA->Release();
m_pBA=NULL;
}
//5,释放基础视频流接口
if(m_pBV!
=NULL)
{
m_pBV->Release();
m_pBV=NULL;
}
//6,释放媒体搜索接口
if(m_pMS!
=NULL)
{
m_pMS->Release();
m_pMS=NULL;
}
//7,最后释放FilterGpaph接口
if(m_pGB!
=NULL)
{
m_pGB->Release();
m_pGB=NULL;
}
returnTRUE;
}
/*
*函数介绍:
打开视频文件
*入口参数:
strFileName:
视频文件名
hOwnerWnd:
显示视频的窗口句柄
hNotifyWnd:
接收DSHOW事件消息的串口句柄
*出口参数:
(无)
*返回值:
TRUE:
成功打开视频文件;FALSE:
打开视频文件失败
*/
BOOLCEricMediaControl:
:
OpenFile(LPCTSTRstrFileName/*视频文件名*/
HWNDhOwnerWnd/*显示视频的窗口句柄*/
HWNDhNotifyWnd/*接收DSHOW事件消息的串口句柄*/
)
{
//存储显示视频窗口句柄
m_hOwnerWnd=hOwnerWnd;
//重置DSHOW接口
UnInitDShow();
//打开视频文件,并对DSHOW接口做初始化工作
returnInitDShow(strFileName,hOwnerWnd,hNotifyWnd);
}
/*
*函数介绍:
播放视频
*入口参数:
(无)
*出口参数:
(无)
*返回值:
TRUE:
成功;FALSE:
失败
*/
BOOLCEricMediaControl:
:
VideoRun()
{
//检测IMediaControl控制接口有效性
if(m_pMC==NULL)
{
returnFALSE;
}
//播放视频
HRESULThResult=m_pMC->Run();
if(hResult!
=S_OK)
{
returnFALSE;
}
returnTRUE;
}
/*
*函数介绍:
暂停视频
*入口参数:
(无)
*出口参数:
(无)
*返回值:
TRUE:
成功;FALSE:
失败
*/
BOOLCEricMediaControl:
:
VideoPause()
{
//检测IMediaControl控制接口有效性
if(m_pMC==NULL)
{
returnFALSE;
}
//暂停视频
HRESULThResult=m_pMC->Pause();
if(hResult!
=S_OK)
{
returnFALSE;
}
returnTRUE;
}
/*
*函数介绍:
停止视频
*入口参数:
(无)
*出口参数:
(无)
*返回值:
TRUE:
成功;FALSE:
失败
*/
BOOLCEricMediaControl:
:
VideoStop()
{
HRESULThResult;
//检测IMediaControl控制接口有效性
if(m_pMC==NULL)
{
returnFALSE;
}
//停止视频
hResult=m_pMC->Stop();
if(hResult!
=S_OK)
{
returnFALSE;
}
//将当前播放位置置
LONGLONGpos=0;
hResult=m_pMS->SetPositions(&pos,AM_SEEKING_AbsolutePositioning,
NULL,AM_SEEKING_NoPositioning);
returnTRUE;
}
/*
*函数介绍:
设置视频显示比例
*入口参数:
fScale:
显示比例,<=1.0
*出口参数:
(无)
*返回值:
TRUE:
成功;FALSE:
失败,此处有点问题
*/
BOOLCEricMediaControl:
:
FitVideoWindow(FLOATfScale)
{
LONGlHeight,lWidth;
intiSeek=0;
doubledblScaleX,dblScaleY;
HRESULThr=S_OK;
LONGlDeflateX=0;
LONGlDeflateY=0;
CRectclientRect;
CRectdstRect;
//
if(m_pBV==NULL)
{
returnFALSE;
}
//放缩比例必须小于等于
if(fScale>1.0)
{
returnFALSE;
}
//得到原始视频尺寸
hr=m_pBV->GetVideoSize(&lWidth,&lHeight);
if(hr!
=S_OK)
{
returnFALSE;
}
//设置拉伸后的尺寸
lWidth=lWidth*fScale;
lHeight=lHeight*fScale;
//得到视频播放窗口的尺寸
GetClientRect(m_hOwnerWnd,&clientRect);
lDeflateX=(clientRect.Width()-clientRect.Width()*fScale)/2;
lDeflateY=(clientRect.Height()-clientRect.Height()*fScale)/2;
//重新设置客户区域
clientRect.DeflateRect(lDeflateX,lDeflateY);
if((lWidth<=clientRect.Width())
&&(lHeight<=clientRect.Height()))
{
dstRect.left=(clientRect.right-clientRect.left-lWidth)/2;
dstRect.right=dstRect.left+lWidth;
dstRect.top=(clientRect.bottom-clientRect.top-lHeight)/2;
dstRect.bottom=dstRect.top+lHeight;
}
else
{
dblScaleX=double(clientRect.Width())/double(lWidth);
dblScaleY=double(clientRect.Height())/double(lHeight);
if(dblScaleX<=dblScaleY)
{
dstRect.left=clientRect.left;
dstRect.right=clientRect.right;
iSeek=(clientRect.Height()-clientRect.Width()*(double(lHeight)/double(lWidth)))/2;
dstRect.top=clientRect.top+iSeek;
dstRect.bottom=dstR