media.cpp

来自「c++系统开发实例精粹内附的80例源代码 环境:windows2000,c++」· C++ 代码 · 共 286 行

CPP
286
字号
// Media.cpp: implementation of the CMedia class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MPlayer.h"
#include "Media.h"
//#include "IVolume.h"
//#include "volumeoutwave.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#if _DEBUG
void DispatchMciError(MCIERROR mciError)
{
	if(mciError)		//get error
	{
		char chError[100];
		mciGetErrorString(mciError,chError,lstrlen(chError));
		AfxMessageBox(chError);
	}
}
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMedia::CMedia()
{
	m_pause=FALSE;
}

CMedia::~CMedia()
{

}

void CMedia::Create(LPCTSTR strMedia,CString& szError)
{
	m_strMedia=strMedia;
	MCIERROR mciError;
	CString strCommand;
	//得到播放文件后缀
	int iIndex=m_strMedia.ReverseFind('.');
	m_mediaSuffix=m_strMedia.Mid(iIndex+1,3);//get the file's suffix
	m_mediaSuffix.MakeLower();
    //填充命令消息结构
	MCI_OPEN_PARMS mciOpen;
	if(m_mediaSuffix=="avi")
		mciOpen.lpstrDeviceType="avivideo";
	else if(m_mediaSuffix=="wav") //wave form file
		mciOpen.lpstrDeviceType="waveaudio";
	else if(m_mediaSuffix=="cda")
		mciOpen.lpstrDeviceType="cdaudio";
	else
		mciOpen.lpstrDeviceType="MPEGvideo2";
		
	mciOpen.lpstrElementName=m_strMedia;//文件名
	mciOpen.lpstrAlias="myMedia";//可选的设备别名
	mciError=mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_ELEMENT|MCI_OPEN_ALIAS|MCI_OPEN_TYPE ,(DWORD)&mciOpen);//打开设备的波形文件
//////////////////////////////////////////////
	if(mciError)		//返回打开错误
	{
		char chError[100];
		mciGetErrorString(mciError,chError,sizeof(chError));
		szError.Format("%s",chError);
	}
	else		//没有错误
		szError="OK";

	if(m_mediaSuffix=="mp3" || m_mediaSuffix=="wav" || m_mediaSuffix=="cda")
		m_bIsVideo=FALSE;
	else
		m_bIsVideo=TRUE;
}

void CMedia::Play(int iStartPos)
{	//the default parameter is CURRENTPOS
	ASSERT(iStartPos>=-1);
	m_pause=FALSE;
	if(iStartPos==CURRENTPOS) //如果开始位置和以前的位置相同,则从以前位置继续播放
		mciSendString("play myMedia",NULL,0,NULL);
	else //从指定的位置播放
	{
		CString strCommand;
		strCommand.Format("play myMedia from %d",iStartPos);
		mciSendString(strCommand,NULL,0,NULL);
	}
}

void CMedia::SetSpeed(int iSpeed)
{

}

void CMedia::Close()
{
	mciSendString("close myMedia",NULL,0,NULL);
}

void CMedia::Stop()
{
	mciSendString("stop myMedia",NULL,0,NULL);
	mciSendString("seek myMedia to start",NULL,0,NULL);
}


void CMedia::Pause()
{
	if(m_pause)	//中断后继续播放
		mciSendString("resume myMedia",NULL,0,NULL);	
	else //中断播放 
		mciSendString("pause myMedia", NULL,0,NULL);
	m_pause=!m_pause;
}

LONG CMedia::GetLength()
{
	MCIERROR mciError;	
	char chLength[50];
	if(!m_bIsVideo)	//music file ,get total length in milliseconds
	{
		mciError=mciSendString("set myMedia time format milliseconds",NULL,0,NULL);
#if _DEBUG
		DispatchMciError(mciError);
#endif
	}else //video file ,get total frames
	{
		mciError=mciSendString("set myMedia time format frames",NULL,0,NULL);
#if _DEBUG
		DispatchMciError(mciError);
#endif
	}
	
	mciError=mciSendString("status myMedia length",chLength,sizeof(chLength),NULL);
#if _DEBUG
		DispatchMciError(mciError);
#endif
	if(mciError)
		return 0;	//0 means can not get length: ASF file can not get length
	CString strLength;
	strLength.Format("%s",chLength);
	return (LONG)(StrToLong((LPCTSTR)strLength));
	// music return in milliseconds 
	// video return in frames
}
//GetHwnd(),
//Get the handle of the VIDEO play window.
//this function only for Video media who has a play window
HWND CMedia::GetHwnd()
{
	if(!IsVideo())	//music media
		return NULL;
	
	char chHandle[100];
	MCIERROR mciError=mciSendString("status myMedia window handle",chHandle,sizeof(chHandle),NULL);	
#if _DEBUG
	DispatchMciError(mciError);
#endif
	CString strHandle;
	strHandle.Format("%s",chHandle);
	return (HWND)(StrToLong((LPCTSTR)strHandle));
}
//the setVolume function have some problem in my computer
//I can not get the device handle while the media is playing
//that is, I can not get the audio divice handle while the handle is open by my media 
//I had used many ways , but failed
////////////////////////////////////
void CMedia::SetVolume(int iFactor)
{
	AfxMessageBox("The setVolume() function have some problem in my computer,\r\n\
		I can not get the device handle while the media is playing,\r\n\
	that is, I can not get the audio divice handle while the handle is opened by my media. \r\n\
	   I had used many ways , but failed.\r\n\
	   See source code and Please mail me if you can solve the problem. : )\r\n\
	   My mail: mdreamchen@solomon-systech.com \r\n\
	   Thanks for your kindness.");
////// method 1//////////////////////
/*	MMRESULT mmResult;
	HWAVEOUT hWaveOut;
//	PCMWAVEFORMAT pFormat;
	WAVEFORMATEX waveFormat;
	waveFormat.wFormatTag=WAVE_FORMAT_PCM;
	waveFormat.nChannels=2;
	waveFormat.nSamplesPerSec=44.1;
	waveFormat.wBitsPerSample=16;
	waveFormat.nBlockAlign=waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
	waveFormat.nAvgBytesPerSec=waveFormat.nBlockAlign * waveFormat.nSamplesPerSec;
	waveFormat.cbSize=0;
	UINT numDevs=waveOutGetNumDevs();
	WAVEOUTCAPS waveOutCaps;
	for(UINT openDevId=0;openDevId < numDevs;openDevId++)
	{
		mmResult=waveOutGetDevCaps(openDevId,&waveOutCaps,sizeof(WAVEOUTCAPS));
		//		mmResult=waveOutOpen(&hWaveOut,openDevId,&waveFormat,NULL,NULL,NULL);
//		if(mmResult==MMSYSERR_NOERROR)
//			break;
		//ASSERT(mmResult==MMSYSERR_NOERROR);
	}

	mmResult=waveOutOpen(&hWaveOut,WAVE_MAPPER ,&waveFormat,NULL,0,WAVE_ALLOWSYNC );
	ASSERT(mmResult!=MMSYSERR_BADDEVICEID);
	ASSERT(mmResult==MMSYSERR_NOERROR);
	DWORD dwVolume;
	mmResult=waveOutGetVolume(hWaveOut,&dwVolume);
	ASSERT(mmResult==MMSYSERR_NOERROR);
	mmResult=waveOutSetVolume(hWaveOut,0);
	waveOutClose(hWaveOut);
*/

////////method 2///////////////////use a volume class whiched downloaded from net
/*	IVolume* pWaveVolume=(IVolume*)new CVolumeOutWave();
	if(!pWaveVolume || !pWaveVolume->IsAvailable())
		return;
	DWORD dwVolume=pWaveVolume->GetCurrentVolume();
*/

//////////method 3///////////////////use a volume class whiched downloaded from net
/*	IVolume* pMasterVolume = (IVolume*)new CVolumeOutMaster();
	if ( !pMasterVolume || !pMasterVolume->IsAvailable() )
	{
 		// handle error
		return;
	}
	DWORD dwVolume=pMasterVolume->GetCurrentVolume();
*/
}
//SetFullScreen(),
//Only for media play who has a play window
bool CMedia::SetFullScreen()
{
	///////this functon can not be effected to the media window
	////// should close previous media window ,then call this function!
	if(!m_bIsVideo)			//not video file
		return FALSE;
	MCIERROR mciError=mciSendString("window myMedia state minimized",NULL,0,NULL);
	mciSendString("play myMedia fullscreen",NULL,0,NULL);

#if _DEBUG
	DispatchMciError(mciError);
#endif
	return TRUE;
}

bool CMedia::IsVideo()
{
	return m_bIsVideo;
}

// function GetFrameRate() only for video file
int CMedia::GetFrameRate()
{
	ASSERT(m_bIsVideo);
	MCIERROR mciError;	
	char chFrameRate[50];
//	mciError=mciSendString("set myMedia time format frames",NULL,0,NULL);
 	/////// frames format is default /////////////////
	mciError=mciSendString("status myMedia frame rate",chFrameRate,sizeof(chFrameRate),NULL);
#if _DEBUG
	DispatchMciError(mciError);
#endif
	CString strFrameRate;
	strFrameRate.Format("%s",chFrameRate);
	int temp=StrToInt((LPCTSTR)strFrameRate)/1000;
	return temp;
}

//GetTotalSec(),
//return media file's total length in seconds
LONG CMedia::GetTotalSec()
{
	if(m_bIsVideo) //video file
	{
		int frameRate=GetFrameRate();
		if(frameRate)	//not failure
			return GetLength()/frameRate;
		else		//asf file can not get framerate
			return 3600; //an hour
	}else     //music file
		return GetLength()/1000;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?