【问题标题】:How to play audio from mp3 array [Android]如何播放 mp3 数组中的音频 [Android]
【发布时间】:2019-08-28 06:43:09
【问题描述】:

在一个测试项目上工作,我目前的目标是使用一个 int 来指定在应用程序初始化时播放哪个 mp3 文件,而无需事先知道音轨的名称(可扩展性问题,因为我希望能够添加新的mp3 文件到随机化池中,以后不接触代码)。但是,当我运行以下代码时,出现以下描述的错误:

错误:没有找到适合 create(MainActivity,String) 方法的方法 MediaPlayer.create(Context,Uri) 不适用(参数不匹配;字符串无法转换为 Uri)方法 MediaPlayer.create(Context,int) 不适用适用(参数不匹配;String 无法转换为 int)

import android.content.res.AssetManager;
import android.content.res.Resources;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.widget.ArrayAdapter;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    RecyclerView bensonRecycler;
    ArrayList<String> arrayList;

    ArrayAdapter bensonAdapter;
    MediaPlayer bensonPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AssetManager assetManager = getAssets();
        String[] audios = assetManager.list("sound");

        int i = 1;

        final MediaPlayer mp = MediaPlayer.create(this, audios[i]);
        mp.start();

    }
}

我的 mp3 文件资产具有以下结构:

所以我的问题是我应该怎么做才能在 mp3 资产数组中使用 int i 指定要播放的 mp3 音轨(事先不知道 mp3 音轨的名称)? (我必须使用一个变量来指定在这个测试项目中播放的配乐)

【问题讨论】:

  • 您想在 Android Studio 或 Android 应用中播放声音吗?见标题
  • 我想在Android应用中播放声音,标题已编辑非常感谢。

标签: android arrays int mp3 assets


【解决方案1】:

“assets”文件夹根本不是真正的文件夹,而是捆绑的字节流。这就是为什么会有AssetManager

AssetManager

提供对应用程序原始资产文件的访问;有关大多数应用程序想要检索其资源数据的方式,请参阅资源。此类提供了一个较低级别的 API,允许您以简单的字节流形式打开和读取与应用程序捆绑在一起的原始文件。

AssetManager 让我们可以轻松地构建文件的字符串数组,并且我们可以将这些文件视为属于一种小型文件系统。诀窍是如何将这些文件(实际上是字节流)呈现给MediaPlayer,以便可以根据声音资源的索引播放声音。

以下代码将播放索引声音。代码中的注释解释了它是如何工作的。为了测试,我刚刚构建了一个简单的布局,其中包含三个按钮,分别在索引 0、1 和 2 处播放声音。

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    private void playSoundFromAssets(int index) {
        try {
            AssetManager assetManager = getAssets();
            String[] audios = assetManager.list(SOUNDFILE_PATH);
            if (audios == null || index >= audios.length) {
                return;
            }
            String soundFilePath = new File(SOUNDFILE_PATH, audios[index]).getPath();
            AssetFileDescriptor afd = getAssets().openFd(soundFilePath);
            final MediaPlayer mp = new MediaPlayer();

            /*  For API 24+, we can just use the AssetFileDescriptor to play the sound. However,
                for API 23-, we can't use the AssetFileDescriptor directly but can retrieve a
                FileDescriptor from it that points to the beginning of our assets. The offset
                and length from the AssetFileDescriptor serve for the FileDescriptor as well.
             */

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                mp.setDataSource(afd);
            } else {
                FileDescriptor fd = afd.getFileDescriptor();
                Log.d("MainActivity", String.format("<<<< %s %d %d", soundFilePath, afd.getStartOffset(), afd.getLength()));
                mp.setDataSource(fd, afd.getStartOffset(), afd.getLength());

                // One might think that mp.setDataSource(fd) would play the sound file we want, but
                // it actually plays all sound files one after another. It seems that fd is a
                // FileDescriptor that points to the beginning of the assets.
            }
            afd.close();
            mp.prepare();
            mp.start();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void playSound(View view) {

        switch (view.getId()) {
            case R.id.play0:
                playSoundFromAssets(0);
                break;

            case R.id.play1:
                playSoundFromAssets(1);
                break;

            case R.id.play2:
                playSoundFromAssets(2);
                break;
        }
    }

    private static final String SOUNDFILE_PATH = "sound";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-05
    相关资源
    最近更新 更多