SoundPool播放短音樂程式碼封裝成jar包提供給unity3d
阿新 • • 發佈:2018-11-12
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);