美文网首页
Android NDK开发:利用OpenSL ES实现声音播放

Android NDK开发:利用OpenSL ES实现声音播放

作者: itfitness | 来源:发表于2021-10-06 19:57 被阅读0次

    目录

    OpenSL ES简介

    大家可以参考这篇文章了解一下:OpenSL ES 简介

    实现效果介绍


    点击播放Assets文件的时候播放Assets文件夹下的音频文件,播放之后点击暂停播放按钮的时候就会暂停播放,这时暂停播放按钮会变为继续播放按钮,然后点击继续播放按钮,音频会继续播放。

    实现步骤

    1.添加依赖库

    这里需要加两个Android自带的库
    1.OpenSLES(播放音频)
    2.android(播放Assets文件夹下的文件需要使用AAssetManager等)

    target_link_libraries( # Specifies the target library.
                           native-lib
                           OpenSLES #加入OpenSLES库
                           android #播放Assets文件夹下的文件需要使用AAssetManager等
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} )
    
    2.创建JNI函数

    以下JNI函数分别是用来播放Assets文件、播放网络URL、播放PCM文件、暂停播放、继续播放和释放资源的

     /**
         * 播放Assets文件
         */
        public native void playAssets(AssetManager assetManager,String fileName);
    
        /**
         * 播放Url
         */
        public native void playUrl(String url);
    
        /**
         * 播放PCM
         */
        public native void playPCM(String filePath);
    
        /**
         * 暂停播放(返回值为1为成功,0为失败)
         */
        public native int pause(int type);
        /**
         * 继续播放(返回值为1为成功,0为失败)
         */
        public native int resume(int type);
        /**
         * 释放资源
         */
        public native void releaseAudio();
    

    Activity中的逻辑如下:

    public class MainActivity extends AppCompatActivity {
        private Button btAssets;
        private Button btUrl;
        private Button btPcm;
        private Button btPause;
        private int currentPlayType = 0;//当前播放的类型(1.Assets 2.Url 3.PCM)
        private boolean isPlaying = false;//是否正在播放
        private String pcmFilePath;//pcm文件路径
        // Used to load the 'native-lib' library on application startup.
        static {
            System.loadLibrary("native-lib");
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btAssets = (Button) findViewById(R.id.bt_assets);
            btUrl = (Button) findViewById(R.id.bt_url);
            btPcm = (Button) findViewById(R.id.bt_pcm);
            btPause = (Button) findViewById(R.id.bt_pause);
            //先将PCM数据拷贝到SD卡
            copyPcm2Sd();
            initListener();
        }
    
        private void copyPcm2Sd() {
            pcmFilePath = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/pcmData.pcm";
            new Thread(()->{
                ResourceUtils.copyFileFromAssets("mydream.pcm",pcmFilePath);
            }).start();
        }
    
        private void initListener() {
            btAssets.setOnClickListener(v->{
                currentPlayType = 1;
                isPlaying = true;
                btPause.setText("暂停播放");
                playAssets(getAssets(), "mydream.m4a");
            });
            btUrl.setOnClickListener(v->{
                isPlaying = true;
                currentPlayType = 2;
                btPause.setText("暂停播放");
                playUrl("https://sharefs.ali.kugou.com/202110061758/dbdc2f041d023da2ad0750cb09c43239/G241/M05/1D/09/kYcBAF-OrrqAetTMAEA5laOdkUg776.mp3");
            });
            btPcm.setOnClickListener(v->{
                isPlaying = true;
                currentPlayType = 3;
                btPause.setText("暂停播放");
                playPCM(pcmFilePath);
            });
            btPause.setOnClickListener(v->{
                if(isPlaying){
                    int result = pause(currentPlayType);
                    if(result == 1){
                        isPlaying = false;
                        btPause.setText("继续播放");
                    }
                }else {
                    int result = resume(currentPlayType);
                    if(result == 1){
                        isPlaying = true;
                        btPause.setText("暂停播放");
                    }
                }
            });
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            releaseAudio();
        }
    
        /**
         * 播放Assets文件
         */
        public native void playAssets(AssetManager assetManager,String fileName);
    
        /**
         * 播放Url
         */
        public native void playUrl(String url);
    
        /**
         * 播放PCM
         */
        public native void playPCM(String filePath);
    
        /**
         * 暂停播放(返回值为1为成功,0为失败)
         */
        public native int pause(int type);
        /**
         * 继续播放(返回值为1为成功,0为失败)
         */
        public native int resume(int type);
        /**
         * 释放资源
         */
        public native void releaseAudio();
    }
    

    这里由于C代码有点多就不贴出来了,大家可以下载源码查看

    参考资料

    Google提供的案例:https://github.com/android/ndk-samples/tree/master/native-audio
    Android通过OpenSL ES播放音频套路详解:https://blog.csdn.net/ywl5320/article/details/78503768

    案例源码

    https://gitee.com/itfitness/opensles-demo

    相关文章

      网友评论

          本文标题:Android NDK开发:利用OpenSL ES实现声音播放

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