|
################################## MMF概述 ######################################### MMF提供了如下几根客户端API: a. 音频接口(Audio Interface):用于音频播放,录制以及转换 b. 铃音播放接口(Tone player interface): 用于播放铃音以及DTMF(双音多频) c. 音频流接口(Audio stream Interface): 连续的音频数据播放和录制 d. 视频接口(video Interface): 视频播放与录制
音频接口和视频接口使用Controller plug-in来支持不同格式的文件的播放,录制以及转换。由于铃音播放和音频流接口的输入和输出文件格式是固定的,所以它们不必使用控制器插件来进行不同格式文件之间的转换和播放等问题。
################################ MMF音频接口 #######################################
1. 音频接口(Audio Interface) 提供的工具类有: CMdaAudioPlayerUtility; CMdaAudioRecorderUtility; CMdaAudioConvertUtility;支持的文件格式有mp3, wav, amr. ====================================音频播放======================================== a. 音频播放工具类: CMdaAudioPlayerUtility <1>. 可以通过指定一个文件(NewFilePlayerL()),描述符(NewDesPlayer())或者URL(NewL(),后加OpenFileL()/OpenDesL()/OpenUrlL())创建一个CMdaAudioPlayerUtility对象 <2> 配置设置:音量(GetVolume()/SetVolume()),平衡度(GetBalance()/SetBalance()),优先级 <3> 播放音频片段: Play(); Pause()/Stop();SetPosition() NB: 音频播放工具回调接口类(MMdaAudioPlayerCallback): 用于在音频播放工具类初始化成功或者播放结束以后被调用,它提供了两个接口函数MapcInitComplete()和MapcPlayComplete()。
// 定义一个音频播放类 class CMyPlayer : public CBase, public MMdaAudioPlayerCallback /* 回调接口 */ { public: void CreatePlayerL(const TDesC& aFileName); // 创建一个音频播放器 void PlaySound(); // 播放音频 // 回调函数 void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aTrailingSilence); void MapcPlayComplete(TInt aError); ...其他功能函数...... private: CMdaAudioPlayerUtility* iPlayer; //CMdaAudioPlayerUtility是抽象类,用户必须自己继承该类 TMyState iState; } enum TMyState { EInitializing, EPlaying, EPrepared }; void CMyPlayer::CreatePlayerL(const TDesC& aFileName) { iPlayer = CMdaAudioPlayerUtility::NewFilePlayerL(aFileName, *this); iState = EInitializing; } void CMyPlayer::PlaySound() { iPlayer->Play(); iState = EPlaying; } void CMyPlayer::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration) { // 检查aError是否为KErrNone ... iState = EPrepared; } void CMyPlayer::MapcPlayComplete(TInt aError) { // 检查aError是否为KErrNone ... iState = EPrepared; } ====================================音频录制======================================== b. 音频录制工具类: CMdaAudioRecorderUtility <1>. 创建一个CMdaAudioRecorderUtility对象,使用OpenFileL()/OpenDesL()/OpenUrlL()指定录制后的文件保存路径 <2> 配置设置:音量和增益(volume and gain),平衡度(balance), 大小(size), 格式(format),bit and sample rates,优先级(priority) <3> 开始录制音频片段: 在录制之前调用SetGain();调用RecordL()开始录制
// 定义一个音频录制类 class CMyPlayer : public CBase, public MMdaObjectStateChangeObserver /* 观察器 */ { public: void CreateRecorderL(); // 创建一个音频录制器 void OpenFileL(); // 指定录制路径 void Record(); // 进行录制 // 观察函数 void MoscoStateChangeEvent(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aError); ...其他功能函数...... private: CMdaAudioRecorderUtility* iPlayer; //CMdaAudioRecorderUtility是抽象类,用户必须自己继承该类 }
void CMyRecorder::CreatePlayerL() { iPlayer = CMdaAudioRecorderUtility::NewL(*this); } void CMyRecorder::OpenFileL(const TDesC& aFileName) { iRecorder->OpenFileL(aFileName); } void CMyRecorder::SetGain() { // Set gain to max level iRecorder->SetGain(iRecorder->MaxGain()); } void CMyRecorder::MoscoStateChangeEvent(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aError); { if(aError != KErrNone) { // 错误处理 } else if(aCurrentState==EOpen) // Handle state change { iRecorder->SetGain(); } else if(aPreviousState==ERecording) { // Recording complete } } void CMyRecorder::Record() { iRecorder->Record(); }
====================================音频转换======================================== b. 音频转换工具类: CMdaAudioConvertUtility <1>. 创建一个CMdaAudioConvertUtility对象,使用OpenFileL()要转换的文件,要转换成的格式等。 <2> 配置设置: <3> 开始转换音频片段: 调用ConvertL()开始录制
// 定义一个音频录制类 class CMyConverter : public CBase, public MMdaObjectStateChangeObserver /* 观察器 */ { public: void CreateConverterL(); // 创建一个音频转换器 void OpenL(TDesC& aSourceFile, TDesC& aDesFile); // 打开要转换的文件,以及指定转换后保存的路径 void SetDesSampleRate(TUint aRate); void ConvertL(); // 进行录制 void Stop(); // 观察函数 void MoscoStateChangeEvent(); ...其他功能函数...... private: CMdaAudioConvertUtility* iPlayer; //CMdaAudioConvertUtility是抽象类,用户必须自己继承该类 }
void CMyConverter::CreatePlayerL() { iPlayer = CMdaAudioConvertUtility::NewL(*this); } void CMyConverter::OpenL(TDesC& aSourceFile, TDesC& aDestFile) { iConverter->OpenL(aSourceFile, aDestFile); } void CMyConverter::ConvertL() { iConverter->ConvertL(); } void CMyConverter::SetDesSampleRate(TUint aRate) { iConverter->SetDesSampleRate(aRate); } void CMyConverter::Stop() { iConverter->Stop(); } void CMyConverter::MoscoStateChangeEvent() // 观察器函数 { // 在打开和转换结束以后进行的操作 }
################################ 铃音播放工具 ####################################### 提供播放铃音功能,通过CMdaAudioToneUtility来提供该功能。它能用于播放以下类型的铃声: a. 播放指定时间长度的铃音(PrepareToPlayTone()) b. 播放DTMF铃音(PrepareToPlayDTMFString()) c. 播放一个文件定义的铃音序列(PrepareToPlayFileSequence()) d. 播放一个在描述符中定义的铃音序列(PrepareToPlayDesSequence()) e. 播放预定义的指定铃音序列(PrepareToPlayFixedSequence()) 在建立一个CMdaAudioToneUtility对象以后,调用PrepareToPlayXXXX(),该系列的函数是异步的,当它完成以后会调用观察函数MMdaAudioToneObserver::MatoPrepareComplete(),也可以使用PrepareCancel()来取消任何Prepare方法。PrepareToPlayXXXX()在播放铃音是不能被调用。 class CMyTonePlayer::Public CBase, Public MMdaAudioToneObserver { ... public: void CreatePlayerL(); void PrepareTone(TInt aFrequency, TTimeIntervalMicroSeconds& aDuration); void SetVolume(); void PlayTone(); ... // From MMdaAudioToneObserver void MatoPrepareComplete(TInt aError); void MatoPlayComplete(TInt aError); ... private: CMdaAudioToneUtility* iTonePlayer; //CMdaAudioToneUtility是抽象类,用户必须自己继承该类 TMyState iState; } void CMyTonePlayer::CreatePlayerL() { iTonePlayer=CMdaAudioToneUtility::NewL(*this); } void CMyAudioTonePlayer::PrepareTone(TInt aFrequency, TTimeIntervalMicroSeconds& aDuration) { iTonePlayer->PrepareToPlayTone(aFrequency, aDuration); } void CMyAudioTonePlayer::SetVolume(TInt aVolume) { iTonePlayer->SetVolume(aVolume); } void CMyAudioTonePlayer::PlayTone() { iState=EPlaying; iToneplayer->Play(); } void CMyAudioTonePlayer::MatoPrepareComplete(TInt aError) { // check error code if (aError==KErrNone) { iState=EReady; // player now ready } } void CMyAudioPlayer::MatoPlayComplete(TInt aError) { iState=EReady; if (aError!=KErrNone) { // error handling } } ################################ 音频流Audio Streaming ####################################### MMF提供了音频流API: CMdaAudioInputStream用于读取流数据,回调接口为MMdaAudioInputStreamCallBack CMdaAudioOutputStream用于写流数据,回调接口为MMdaAudioOutputStreamCallBack ====================================音频输入流======================================== Audio Input Stream: a. 创建输入流对象 CMdaAudioInputStream::NewL() b. 设置音频属性: SetAudioProperties(): 设置增益,平衡度以及优先级 c. 打开流:完成后调用回调函数 d. 读取数据:完成后调用回调函数 e. 关闭流:完成后调用回调函数 class CMyStream : public CBase, public MMdaAudioInputStreamCallBack { ... public: void CreateStreamerL(); void OpenStream(TMdaPackage* aSettings); void ReadBufferL(TDes8& aBuffer); // From MMdaAudioStreamCallback void MaiscOpenComplete(TInt aError); void MaiscBufferCopied(TInt aError, TDesC8& aBuffer); void MaiscRecordComplete(TInt aError); ... private: CMdaAudioInputStream* iStream; ... } void CMyStream::CreateStreamerL() { iStreamer = CMdaAudioInputStream::NewL(*this); } void CMyStream::OpenStream(TMdaPackage* aSettings) { iStreamer->Open(aSettings); } void CMyStream::ReadBufferL(TDes8& aBuffer) { iStreamer->ReadL(aBuffer); } void CMyStream::MaiscOpenComplete(TInt aError) { if (aError==KErrNone) { // Set properties and volume iStreamer->SetAudioProperties(TMdaAudioDataSettings::ESampleRate8000Hz, TMdaAudioDataSettings::EChannelsMono); iStream->SetVolume(iStream->MaxVolume()); } else { // Open failed – handle error } } void CMyStream::MaiscBufferCopied(TInt /*aError*/, TDesC8& /*aBuffer*/) { // Not used but must be defined } void CMyStream::MaiscRecordComplete(TInt /*aError*/); { // Not used but must be defined }
====================================音频输出流======================================== Audio Output Stream: a. 创建输出流对象 CMdaAudioOutputStream::NewL() b. 设置音频属性: SetAudioProperties(): 设置平衡度,音量以及优先级 c. 打开流:完成后调用回调函数 d. 写数据:完成后调用回调函数 e. 关闭流:完成后调用回调函数 代码和音频输入流类似 ################################ 视频接口 ####################################### 提供基本的视频录制以及回放功能,提供这些的工具类有CVideoPlayerUtility 和 CVideoRecorderUtility,不同视频格式由format/codec插件进行相关的处理。 ====================================视频播放功能======================================== a. 使用CVideoPlayerUtility::NewL()创建一个对象 b. 打开视频文件 OpenFileL()/OpenDesL()/OpenUrlL() c. 配置: 优先级别,音频,帧大小和显示窗口,检查MIME类型和Codec,Bit&Frame rates. d. 调用在播放之前,调用Prepare() e. 播放函数: Play(): 开始播放视频片段 PauseL(): Stop() f. 其他有用的函数: PositionL()/SetPositionL()获取/设定播放位置 DurationL():获取片段的长度 class CMyVideoPlayer:public CBase, public MVideoPlayerUtilityObserver { ... public: void CreatePlayerL(); void OpenFileL(TDesC& aFileName); void Prepare(); void Play(); void PauseL(); void Stop(); // From MVideoPlayerUtilityObserver void MvpuoOpenComplete(TInt aError); void MvpuoPrepareComplete(TInt aError); void MvpuoPlayComplete(TInt aError); private: CViedoPlayerUtility* iVideoPlayer; TBool iIsOpen; TBool iIsPrepared; } void CMyVideoPlayer::CreatePlayerL(TDesC& aFileName) { iPlayer = CVideoPlayerUtility::NewL(*this); } void CMyVideoPlayer::OpenFileL(TDesC& aFileName) { iPlayer->OpenFileL(aFileName); } void CMyVideoPlayer::Prepare() { if (!iIsOpen) { iPlayer->Prepare(); } } void CMyVideoPlayer::Play() { if (!iIsOpen && iIsPrepared) { iPlayer->Play(); } } void CMyVideoPlayer::PauseL() { if (iOpenOK && iIsPrepare) { iPlayer->PauseL(); } } void CMyVideoPlayer::Stop() { if (iIsOpen && iIsPrepared) { iPlayer->Stop(); } } void CMyVideoPlayer::MvpuoOpenComplete(TInt aError) { // If successful then set a flag that Open has completed if (aError == KErrNone) { iIsOpen = ETrue; } } void CMyVideoPlayer::MvpuoPrepareComplete(TInt aError) { // If successful then set a flag that Prepare has completed if (aError == KErrNone) { iIsPrepared = ETrue; } } ====================================视频录制功能======================================== class CMyVideoRecorder : public CBase, public MVideoRecorderUtilityObserver { ... public: void CreateRecorderL(); void OpenFileL(TDesC& aFileName, TInt aCameraHandle, TUid aControllerUid, TUid aVideoFormat); void Prepare(); void Record(); void PauseL(); void Stop(); ... // From MVideoRecorderUtilityObserver void MvruoOpenComplete(TInt aError); void MvruoPrepareComplete(TInt aError); void MvruoRecordComplete(TInt aError); ... private: CVideoRecorderUtility* iRecorder; TBool iIsOpen; TBool iIsPrepared; ... } CMyVideoRecorder::CreateRecorderL() { iRecorder = CVideoRecorderUtility::NewL(*this); } CMyVideoRecorder::OpenFileL(TDesC& aFileName, Tint aCameraHandle, TUid aControllerUid, TUid aVideoFormat) { iRecorder->OpenFileL(aFileName, aCamerHandle, aControllerUid, aVideoFormat); } CMyVideoRecorder::Prepare() { if (!iIsOpen) { iRecorder->Prepare(); } } CMyVideoRecorder::Record() { // Check that a data source has been opened and // that the recorder has been prepared if (!iIsOpen && iIsPrepared) { iRecorder->Record(); } } CMyVideoRecorder::PauseL() { if (iIsOpen && iIsPrepared) { iRecorder->PauseL(); } } CMyVideoRecorder::Stop() { if (iIsOpen && iIsPrepare) { iRecorder->Stop(); } } void CMyVideoRecorder::MvruoOpenComplete(TInt aError) { // If successful then set a flag that Open has completed if (aError == KErrNone) { iIsOpen = ETrue; } } void CMyVideoRecorder::MvruoPrepareComplete(TInt aError) { // If successful then set a flag that Prepare has completed if (aError == KErrNone) { iIsPrepared = ETrue; } }
相关阅读:
|