cocos2dx 音频模块分析(2):背景音乐
来源:互联网 发布:网络性能测试 编辑:程序博客网 时间:2024/05/23 19:49
cocos2dx 音频模块分析(2): 背景音乐部分
我在(1)已经分析了一些东西,这里接着分析,这一篇我们主要分析背景音乐文件的播放,还是基于android平台:1、这里只是背景音乐的预加载,为什么要进行预加载呢?主要是加载音乐文件是比较耗时的,如果我们没有预加载就直接播放也是可以的,但是会有一定的延时,因为如果没有预加载,就直接播放,也是会先进行加载音乐文件,然后进行播放。void SimpleAudioEngine::preloadBackgroundMusic(const char* pszFilePath){ std::string fullPath = getFullPathWithoutAssetsPrefix(pszFilePath); preloadBackgroundMusicJNI(fullPath.c_str());}其实加载背景音乐最终调用android端:public void preloadBackgroundMusic(final String pPath) {if ((this.mCurrentPath == null) || (!this.mCurrentPath.equals(pPath))) {// preload new background music// release old resource and create a new one// 如果我们播放的是一个新的背景音乐文件,那么我们需要先释放旧的播放器,然后创建一个新的// Releases resources associated with this MediaPlayer object.if (this.mBackgroundMediaPlayer != null) {this.mBackgroundMediaPlayer.release();} //创建一个播放器即MediaPlayer类的实例this.mBackgroundMediaPlayer = this.createMediaplayer(pPath);// record the path// 记录当前播放的背景音乐文件,因为下次如果播放的是同一个音乐// 文件,那么我们就可以直接进行播放了,不用再重新创建MediaPlayer类的实例this.mCurrentPath = pPath; }}----->>>/** * create mediaplayer for music * * @param pPath * the pPath relative to assets * @return */private MediaPlayer createMediaplayer(final String pPath) {MediaPlayer mediaPlayer = new MediaPlayer();try { //对绝对路径和包里的路径进行区分处理,当最终的目的就是设置播放源if (pPath.startsWith("/")) {final FileInputStream fis = new FileInputStream(pPath);mediaPlayer.setDataSource(fis.getFD());fis.close();} else {final AssetFileDescriptor assetFileDescritor = this.mContext.getAssets().openFd(pPath);mediaPlayer.setDataSource(assetFileDescritor.getFileDescriptor(), assetFileDescritor.getStartOffset(), assetFileDescritor.getLength());} //播放器前需要做些准备工作,这个只是android的api,不明白的话,查下文档。/** * Prepares the player for playback, synchronously. * * After setting the datasource and the display surface, you need to either * call prepare() or prepareAsync(). For files, it is OK to call prepare(), * which blocks until MediaPlayer is ready for playback. * * @throws IllegalStateException if it is called in an invalid state */mediaPlayer.prepare(); //设置声音音量mediaPlayer.setVolume(this.mLeftVolume, this.mRightVolume);} catch (final Exception e) {mediaPlayer = null;Log.e(Cocos2dxMusic.TAG, "error: " + e.getMessage(), e);}return mediaPlayer;}2、音乐播放函数//pszFilePath: 音乐文件名//bLoop: 是否循环播放,音乐文件我们一般设置为循环播放,看具体情况void SimpleAudioEngine::playBackgroundMusic(const char* pszFilePath, bool bLoop){ std::string fullPath = getFullPathWithoutAssetsPrefix(pszFilePath); playBackgroundMusicJNI(fullPath.c_str(), bLoop);}--->>> 最终都会调用到android端的playBackgroundMusic函数,并把文件路径,是否循环播放传进来public void playBackgroundMusic(final String path, final boolean isLoop) {if (mCurrentPath == null) {// it is the first time to play background music or end() was called// 如果以前没有播放过音乐文件,那么重新创建一个,上面的英文注释很清楚mBackgroundMediaPlayer = createMediaplayer(path);mCurrentPath = path;} else {if (!mCurrentPath.equals(path)) {// play new background music //如果这次播放的音乐文件和上次的不同,即是一个新的音乐文件,//那么就需要先释放掉旧的,然后创建一个新的。// release old resource and create a new oneif (mBackgroundMediaPlayer != null) {mBackgroundMediaPlayer.release();}mBackgroundMediaPlayer = createMediaplayer(path);// record the pathmCurrentPath = path;}}if (mBackgroundMediaPlayer == null) {Log.e(Cocos2dxMusic.TAG, "playBackgroundMusic: background media player is null");} else {try {// if the music is playing or paused, stop it// 对playing or paused, stop三种情况进行分别处理if (mPaused) { //如果是暂停状态,那么就把播放进度设置到0,然后开始。//这就意味着,如果我们调用了暂停,然后又调用play,那么//音乐将会从头开始播放,而不是从暂停的地方接着播放。 /** * Seeks to specified time position. * * @param msec the offset in milliseconds from the start to seek to * @throws IllegalStateException if the internal player engine has not been * initialized */mBackgroundMediaPlayer.seekTo(0);/** * Starts(开始) or resumes playback(恢复播放). If playback had previously been paused, * playback will continue from where it was paused. If playback had * been stopped, or never started before, playback will start at the * beginning. * start函数两个功能,一个是开始播放,一个是恢复播放 * 1、如果stopped或者never started before(第一次开始),那么就从头开始播放 * 2、如果paused即暂停,那么将会从暂停的地方接着播放。 */mBackgroundMediaPlayer.start();} else if (mBackgroundMediaPlayer.isPlaying()) { //如果处于播放状态,则回到开始,从头播放mBackgroundMediaPlayer.seekTo(0);} else { //如果处于stop状态,则从新播放,上面已经说明了start函数的两个作用mBackgroundMediaPlayer.start();} /*总结:其实对上面三种情况分别处理,最终达到的效果都是一样的,那就是从头开始播放背景音乐文件。*///设置是否循环播放mBackgroundMediaPlayer.setLooping(isLoop);//mPaused 表示设为false,表示不处于暂停状态mPaused = false;//是否循环播放记录mIsLoop = isLoop;} catch (final Exception e) {Log.e(Cocos2dxMusic.TAG, "playBackgroundMusic: error state");}}}3、总结:从上面的分析我们可以知道,如果预先进行加载即先创建一个MediaPlayer,那么我们播放时可以直接进行播放,如果我们我们没有提前进行预加载,而是直接调用playBackgroundMusic函数,也可以进行播放,只不过会有一个创建MediaPlayer的过程,会有一些时间上的延时。
0 0
- cocos2dx 音频模块分析(2):背景音乐
- cocos2dx 音频模块分析(3): 背景音乐部分
- cocos2dx 音频模块分析(1):背景音乐
- cocos2dx 音频模块分析(2): 音效部分
- cocos2dx 音频模块分析(1)
- cocos2dx 音频模块分析(4): 音效部分
- cocos2dx 音频模块分析(5): 音效部分
- cocos2dx背景音乐
- WebRTC源码分析:音频模块结构分析
- WebRTC源码分析:音频模块结构分析
- 关于cocos2dx的背景音乐和音效(2)
- WebRTC源码分析二:音频模块结构
- WebRTC源码分析二:音频模块结构
- WebRTC源码分析二:音频模块结构
- WebRTC源码分析二:音频模块结构
- WebRTC源码分析二:音频模块结构
- WebRTC源码分析二:音频模块结构
- WebRTC源码分析二:音频模块结构
- ActionBar样式解析
- Android 中几种更新UI界面的方法
- Android Studio "Error:Failed to find: com.android.support:XXXX"错误解决办法
- 按字节截取字符串 (有汉字)
- c#对第三方缓存redis的操作(七)
- cocos2dx 音频模块分析(2):背景音乐
- 22.UIWindow 程序启动
- 上下文切换和锁
- 贝叶斯公式的简单介绍
- 探讨最近比较火的网络招聘平台
- 携程App的网络性能优化实践
- webservlet不能识别为type原因
- java根据jar包反编译后修改再打包回jar的做法
- linux arp z组播检测IP冲突