1. 程式人生 > >SoundPool播放短音樂程式碼封裝成jar包提供給unity3d

SoundPool播放短音樂程式碼封裝成jar包提供給unity3d

1.為什麼使用Android的API播放音樂,unity3d本身是有播放音樂的api的?

在Android低端機上音樂延遲明顯,對於節奏感強的遊戲這就是致命的問題,而Android的soundpool正好解決了這一問題

2.怎麼製作jar包?

可以參考我的上一篇文章(https://blog.csdn.net/qq_14931305/article/details/82591314)這裡只做簡單的總結:

  • build.gradle中 apply plugin: 'com.android.application'修改成apply plugin: 'com.android.library'
  • build.gradle中刪除 applicationId "com.*******.****"
  • 重新build專案(點選build---->Rebuild project)
  • 查詢生成的專案aar包,找到專案存放的位置myproject---->build---->outputs---->aar---->myproject.aar
  • myproject.aar修改成myproject.zip
  • myproject.zip解壓
  • 找到classes.jar包,這就是你需要的jar包,為了區別其他的jar包最好把jar包的名字修改一下,如果有資原始檔記得把資原始檔也要放到unity3d中

3.下面要說的就是soundpool的程式碼

程式碼奉上之前我們需要做的是把音樂檔案放到我們的res---->assets---->mysound資料夾下,此處的mysound資料夾是自己新建的,為了區別其他的資原始檔,此資料夾下放得都是要提供給unity3d的音樂檔案,有人問:為什麼不放在raw下面,原因是api提供2個方法 :

getAssets().openFd("mysound/"+soundName),//可以通過soundName找到對應的資原始檔

String[] arr =context.getResources().getAssets().list("mysound");//可以對mysound資料夾下的音樂檔案實現所有的預載入,現用現載入有點慢,我們可以提前載入,用到的時候可以通過音樂名字直接播放音樂,記得最後關閉的時候釋放一下預載入的資源。

具體程式碼如下:

 

package com.gamestar.nativesoundpool;

import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;
import java.io.IOException;
import java.util.HashMap;

public class JavaSoundPool {
	private final static int Max_Stream = 8;

	private SoundPool _pool;

	private HashMap<String, Integer> mSoundIDMap;

	JavaSoundPool(){
		if( android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
			_pool = new SoundPool(Max_Stream, AudioManager.STREAM_MUSIC, 0);
		}else{
			SoundPool.Builder builder = new SoundPool.Builder();
			builder.setAudioAttributes(new AudioAttributes.Builder()
					.setUsage(AudioAttributes.USAGE_GAME)
					.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build());
			builder.setMaxStreams(Max_Stream);
			_pool = builder.build();
		}


		mSoundIDMap = new HashMap<>();
	}


	public int load(Context context, String soundName) {
		// TODO Auto-generated method stub
		try {
			int soundId =_pool.load(context.getAssets().openFd("mysound/"+soundName),0);
			mSoundIDMap.put(soundName.substring(0,soundName.indexOf(".")), soundId);
			Log.e("UnityAndroidPlugin","soundId= "+soundId);
			return soundId;
		} catch (IOException e) {
			e.printStackTrace();
			Log.e("UnityAndroidPlugin","異常"+soundName);
			return 0;
		}
	}

	public void unload(String soundName) {
		Integer soundId = mSoundIDMap.get(soundName);
		if(soundId != null) {
			_pool.unload(soundId);
			mSoundIDMap.remove(soundName);
		}
	}

	public int play(String soundName, float volume, float speed) {
		Integer soundID = mSoundIDMap.get(soundName);
		if(soundID != null) {
			return _pool.play(soundID, volume, volume, 0, 0, speed);
		}else {
			Log.e("UnityAndroidPlugin","soundID為空 "+soundName);
		}
		return -1;
	}

	public void release() {
		_pool.release();
		mSoundIDMap.clear();
	}

}

 

package com.gamestar.nativesoundpool;

import android.content.Context;
import android.util.SparseArray;
import android.util.SparseIntArray;

import java.util.HashMap;

/**
 *	SoundPoolManager
 */
public class SoundPoolManager{
	static private SoundPoolManager instance = null;

	/**
	 * Key is Sound Type defined by ourselves
	 */
	private HashMap<String, JavaSoundPool> mSoundPoolMap;

	private SoundPoolManager() {
		mSoundPoolMap = new HashMap<>();
	}

	public static SoundPoolManager getInstance() {
		if(instance == null) {
			instance = new SoundPoolManager();
		}
		return  instance;
	}


	JavaSoundPool getSoundPoolByName(String instrumentName) {
		if(mSoundPoolMap == null) {
			return null;
		}

		JavaSoundPool soundPool = mSoundPoolMap.get (instrumentName);
		if(soundPool == null) {
			soundPool = new JavaSoundPool();
			mSoundPoolMap.put(instrumentName, soundPool);
		}

		return soundPool;
	}

	void removeSoundPoolByName(String instrumentName) {
		if(mSoundPoolMap == null) {
			return;
		}
		JavaSoundPool soundPool = mSoundPoolMap.get(instrumentName);
		if(soundPool != null) {
			soundPool.release();
			mSoundPoolMap.remove(instrumentName);
		}
	}

}

 

package com.gamestar.nativesoundpool;

import android.app.Activity;
import android.content.Context;
import java.io.IOException;


public class UnityAndroidPlugin {

    static boolean createSoundPool(String soundPoolName) {
        JavaSoundPool soundPool = SoundPoolManager.getInstance().getSoundPoolByName(soundPoolName);
        if(soundPool == null) {
            return false;
        }else{
            return true;
        }
    }

    static void loadSound(final Context context, final String soundPoolName) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String[] arr =context.getResources().getAssets().list("mysound");
                    for (String name:arr){
                        JavaSoundPool soundPool = SoundPoolManager.getInstance().getSoundPoolByName(soundPoolName);
                        soundPool.load(context, name);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    static int playSound(String soundPoolName, String soundName) {
        JavaSoundPool soundPool = SoundPoolManager.getInstance().getSoundPoolByName(soundPoolName);
        return soundPool.play(soundName, 1.0f, 1.0f);
    }

    static void releaseSoundPool(String soundPoolName) {
        SoundPoolManager.getInstance().removeSoundPoolByName(soundPoolName);
    }

}

4.Unity3D呼叫:

  • 複製資原始檔到unity3d中,在unity3d中asset下新建一個Plugins資料夾,一個Android資料夾,一個assets資料夾,一個bin資料夾,將音樂檔案拷貝到mysound資料夾下,jar包放在bin下
  • 呼叫jar包的程式碼
    AndroidJavaObject m_activity = new AndroidJavaObject("com.gamestar.nativesoundpool.UnityAndroidPlugin");
    //預載入所有assets/mysound資料夾下的音樂檔案
    m_activity.CallStatic<bool>("createSoundPool", SOUNDPOOLNAME);
    //播放指定歌曲
    m_activity.CallStatic<int>("playSound", SOUNDPOOLNAME, soundName);
    //釋放資源
    m_activity.CallStatic("releaseSoundPool", GameController.SOUNDPOOLNAME);