问题遇到的现象和发生背景
想要通过vlc-android 获取到pcm数据对音频进行后续处理,但是我写的回调方法无法获取到正确的PCM数据,下面是我写的回调方法
问题相关代码,请勿粘贴截图
//自己添加的方法-音频回调
static pthread_mutex_t myMutexForAudio = PTHREAD_MUTEX_INITIALIZER;
//设置音频格式
void
Java_org_videolan_libvlc_MediaPlayer_nativeSetAudioFormat(JNIEnv *env, jobject thiz,
jstring format, jint rate, jint channels) {
//获取到VLC单例
vlcjni_object *p_obj=VLCJniObject_getInstance(env,thiz);
//判断是否为空,如果为空证明播放器未初始化或已经被释放
if (!p_obj)
{
return;
}
//通过jni将string转为char
const char *formatStr=(*env)->GetStringUTFChars(env,format,NULL);
//设置音频格式的方法
libvlc_audio_set_format(p_obj->u.p_mp,formatStr,rate,channels);
//释放资源
(*env)->ReleaseStringUTFChars(env,format,formatStr);
}
struct myfieldForAudio {
jclass mediaPlayerClazz;
jmethodID onDisplayCallback;
jobject thiz;
void *buffer;
} myfieldForAudio;
//处理回调数据的方法
static void displayForAudio(void *data, const void *samples,unsigned count,int64_t pts) {
JavaVM jvm = fields.jvm; //这个地方需要修改 "utils.h" 中的struct fields,增加成员JavaVM jvm,并且在libvlcjni.c的中进行赋值
JNIEnv *env;
int stat = (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2);
if (stat == JNI_EDETACHED) {
if ((*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL) != 0) {
return;
}
} else if (stat == JNI_OK) {
} else if (stat == JNI_EVERSION) {
return;
}
//将音频数据传递
samples=myfieldForAudio.buffer;
//它在这里特意加个锁大概率就是别的地方写,它才特意要确保传进这个函数的时候你自己把buffer保存起来
pthread_mutex_lock(&myMutexForAudio);
if (myfieldForAudio.thiz != NULL) {
//将数据回调
(*env)->CallVoidMethod(env, myfieldForAudio.thiz, myfieldForAudio.onDisplayCallback);
}
pthread_mutex_unlock(&myMutexForAudio);
(*jvm)->DetachCurrentThread(jvm);
}
//回调音频的native方法
void
Java_org_videolan_libvlc_MediaPlayer_nativeSetAudioBuffer(JNIEnv *env, jobject thiz,jobject buffer) {
//获取到VLC单例
vlcjni_object *p_obj=VLCJniObject_getInstance(env,thiz);
//获取媒体播放器对象
libvlc_media_player_t *mp=p_obj->u.p_mp;
//判断是否为空,如果为空证明播放器未初始化或已经被释放
if (!mp)
{
return;
}
//如果java层传递来的buffer缓存区对象为空时,释放资源
if (buffer == NULL)
{
(*env)->DeleteGlobalRef(env,myfieldForAudio.mediaPlayerClazz);
pthread_mutex_lock(&myMutexForAudio);
(*env)->DeleteGlobalRef(env,myfieldForAudio.thiz);
myfieldForAudio.thiz=NULL;
pthread_mutex_unlock(&myMutexForAudio);
return;
}
//通过反射获取到MediaPlayer类的字节马
myfieldForAudio.mediaPlayerClazz= (*env)->FindClass(env,"org/videolan/libvlc/MediaPlayer");
//创建一个MediaPlayer类
myfieldForAudio.mediaPlayerClazz=(jclass)(*env)->NewGlobalRef(env,myfieldForAudio.mediaPlayerClazz);
//设置回调方法
myfieldForAudio.onDisplayCallback=(*env)->GetMethodID(env,myfieldForAudio.mediaPlayerClazz,"onAudioFrameCallBack","()V");
myfieldForAudio.thiz=(*env)->NewGlobalRef(env,thiz);
//获取到java传来的biffer的地址
myfieldForAudio.buffer=(*env)->GetDirectBufferAddress(env,buffer);
//回调音频数据的方法
libvlc_audio_set_callbacks(mp,displayForAudio,NULL,NULL,NULL,NULL,NULL);
}
//自己创建的方法-结束
运行结果及报错内容
没有收到报错信息
我的解答思路和尝试过的方法
有可能是回调方法写错了,c代码还是不熟练
我想要达到的结果
能够正确回调PCM数据