在java層中聲明一個方法用於創建一個audiotrack,在C層中調用這個方法並獲取audiotrack對象。
先看下面的代碼:SuPlayer.java
public AudioTrack createAudioTrack(int sampleRateInHz, int nb_channels) {
//固定格式的音頻碼流
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
//聲道佈局
int channelConfig;
if (nb_channels == 1) {
channelConfig = android.media.AudioFormat.CHANNEL_OUT_MONO;
} else if (nb_channels == 2) {
channelConfig = android.media.AudioFormat.CHANNEL_OUT_STEREO;
} else {
channelConfig = android.media.AudioFormat.CHANNEL_OUT_STEREO;
}
int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
sampleRateInHz, channelConfig,
audioFormat,
bufferSizeInBytes, AudioTrack.MODE_STREAM);
//播放
//audioTrack.play();
//寫入PCM
//audioTrack.write(audioData, offsetInBytes, sizeInBytes);
return audioTrack;
}
//只播放視頻
public static native int playVideo(String url, Surface surface);
//音視頻同步播放
public native void playSyncVideo(String url, Surface surface);
C層實現:
JNIEXPORT void
JNICALL Java_com_eebbk_suplayer_SuPlayer_playSyncVideo(JNIEnv *env, jobject thiz, jstring inputPath_, jobject surface) {
int i = 1;
//JNI begin------------------
jclass player_class = env->GetObjectClass(jthiz);//獲取當前類的class
//獲取methodID,調java層的createAudioTrack函數,返回值是(II)Landroid/media/AudioTrack;
//詳細參考:http://hubeihuyanwei.blog.163.com/blog/static/28205284201282911925396/
jmethodID create_audio_track_mid = env->GetMethodID(player_class, "createAudioTrack",
"(II)Landroid/media/AudioTrack;");
if (create_audio_track_mid == NULL) {
LOGE("%s", "createAudioTrack 方法沒找到!\n");
}
//獲取audio_track對象,傳入methodid、java層中對應方法的形參
jobject audio_track = env->CallObjectMethod(jthiz, create_audio_track_mid, i, i);
//調用AudioTrack.play方法
jclass audio_track_class = env->GetObjectClass(audio_track);
jmethodID audio_track_play_mid = env->GetMethodID(audio_track_class, "play", "()V");
env->CallVoidMethod(audio_track, audio_track_play_mid);
//AudioTrack.write
jmethodID audio_track_write_mid = env->GetMethodID(audio_track_class, "write", "([BII)I");
LOGE("%s", "44444");
//JNI end------------------
}
就這麼簡單的調用順序,爲什麼要寫這篇筆記呢???因爲在寫這個的時候,把SuPlayer.java中public AudioTrack createAudioTrack(int sampleRateInHz, int nb_channels)這個方法寫成了靜態方法public static AudioTrack createAudioTrack(int sampleRateInHz, int nb_channels)。導致排查的時候一直以爲env->GetMethodID()這個函數寫的有問題。