Android-多媒体

Android万能音频播放器05--添加加载、暂停、播放状态

2019-01-07  本文已影响0人  张俊峰0613

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);
    }
}

到这里就完成了加载、暂停播放和继续播放的流程!

上一篇下一篇

猜你喜欢

热点阅读