1、实现原理
加载:判断队列里面是否有数据,没有的话就是加载状态,否则是播放状态。
主要是C++调用Java方法。
暂停:
(*pcmPlayerPlay)->SetPlayState(pcmPlayerPlay, SL_PLAYSTATE_PAUSED);
播放:
(*pcmPlayerPlay)->SetPlayState(pcmPlayerPlay, SL_PLAYSTATE_PLAYING);
2、加载
C++调用Java方法
底层与UI进行交互,先实现接口层:
public interface JfOnLoadingListener {
/**
* 加载回调
* @param loading true :加载中
* false :
*/
void onLoading(boolean loading);
}
JfPlayer.java
private JfOnLoadingListener jfOnLoadingListener;
public void setJfOnLoadingListener(JfOnLoadingListener jfOnLoadingListener) {
this.jfOnLoadingListener = jfOnLoadingListener;
}
public void onCallLoading(boolean loading){
if (jfOnLoadingListener != null) {
jfOnLoadingListener.onLoading(loading);
}
}
C++层先实现调用Java代码:
先在JfCallJava.cpp的构造方法中得到方法ID
jmid_loading = env->GetMethodID(jclz,"onCallLoading","(Z)V");
实现调用Java层方法的方法:
void JfCallJava::onCallLoading(int threadType, bool loading) {
if (threadType == MAIN_THREAD){
jniEnv->CallVoidMethod(jobj,jmid_loading,loading);
} else if (threadType == CHILD_THREAD){
JNIEnv *jniEnv;
if (javaVM->AttachCurrentThread(&jniEnv,0) != JNI_OK){
if (LOG_DEBUG) {
LOGE("GET CHILD THREAD JNIENV ERROR");
return;
}
}
jniEnv->CallVoidMethod(jobj,jmid_loading,loading);
javaVM->DetachCurrentThread();
}
}
在JfAudio中调用:
添加头文件后,创建JfCallJava指针,然后从构造方法中传入:
#include "JfCallJava.h"
JfCallJava *callJava;
JfAudio(JfPlayStatus *playStatus,int sample_rate,JfCallJava *callJava);
然后在JfPlayStatus添加一个全局状态-loading,判断是否在加载状态,JfAudio::resampleAudio()中显示加载:
if (queue->getQueueSize() == 0){//加载状态
if (!playStatus->loading){
playStatus->loading = true;
callJava->onCallLoading(CHILD_THREAD,playStatus->loading);
}
continue;
} else {//播放状态
if (playStatus->loading){
playStatus->loading = false;
callJava->onCallLoading(CHILD_THREAD,playStatus->loading);
}
}
在MainActivity.java中设置监听:
jfPlayer.setJfOnLoadingListener(new JfOnLoadingListener() {
@Override
public void onLoading(boolean loading) {
if (loading) {
JfLog.d("加载中。。。");
} else {
JfLog.d("播放中。。。");
}
}
});
3、暂停与继续播放
Java层代码,声明native方法,调用native方法,设置监听:
/**
* 暂停播放
*/
public void pause(){
n_pause();
if (jfOnPauseResumeListener != null) {
jfOnPauseResumeListener.onPause(true);
}
}
/**
* 继续播放
*/
public void resume(){
n_resume();
if (jfOnPauseResumeListener != null) {
jfOnPauseResumeListener.onPause(false);
}
}
private native void n_pause();
private native void n_resume();
native层,
首先,native-lib.cpp调用JfFFmpeg的方法;
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myplayer_player_JfPlayer_n_1pause(JNIEnv *env, jobject instance) {
// TODO
if (ffmpeg != NULL){
ffmpeg->pause();
}
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myplayer_player_JfPlayer_n_1resume(JNIEnv *env, jobject instance) {
// TODO
if (ffmpeg != NULL){
ffmpeg->resume();
}
}
然后,JfFFmpeg调用JfAudio方法;
void JfFFmpeg::pause() {
if (audio != NULL){
audio->pause();
}
}
void JfFFmpeg::resume() {
if (audio != NULL){
audio->resume();
}
}
最后,JfAudio.cpp中实现:
void JfAudio::pause() {
if (pcmPlayerObject != NULL){
(*pcmPlayerPlay)->SetPlayState(pcmPlayerPlay, SL_PLAYSTATE_PAUSED);
}
}
void JfAudio::resume() {
if (pcmPlayerObject != NULL){
(*pcmPlayerPlay)->SetPlayState(pcmPlayerPlay, SL_PLAYSTATE_PLAYING);
}
}
到这里就完成了加载、暂停播放和继续播放的流程!
网友评论