美文网首页
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