美文网首页Android-多媒体
Android万能音频播放器05--添加加载、暂停、播放状态

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

作者: 张俊峰0613 | 来源:发表于2019-01-07 16:12 被阅读0次

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

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

    相关文章

      网友评论

        本文标题:Android万能音频播放器05--添加加载、暂停、播放状态

        本文链接:https://www.haomeiwen.com/subject/cdjdrqtx.html