Play audio file from the assets directory

2019-01-01 14:54发布

问题:

I have the following code:

AssetFileDescriptor afd = getAssets().openFd(\"AudioFile.mp3\");
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor());
player.prepare();
player.start();

The problem is that, when I run this code, it starts playing all the audio files in the assets directory, in alphabetical order instead of just playing the audio file I requested. What am I doing wrong? Is there a better way to play audio files from the assets directory?

Follow-up question: Is there a difference between keeping audio files in the assets directory and keeping them in the res/raw directory? Besides the fact that they don\'t get ids if they are in the assets directory. If I move the audio files to the res/raw folder then I have a problem with reusing MediaPlayers because there is no id parameter for setDataSource(). I can\'t find a good guideline for handling this kind of problem.

回答1:

player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());

Your version would work if you had only one file in the assets directory. The asset directory contents are not actually \'real files\' on disk. All of them are put together one after another. So, if you do not specify where to start and how many bytes to read, the player will read up to the end (that is, will keep playing all the files in assets directory)



回答2:

This function will work properly :)

// MediaPlayer m; /*assume, somewhere in the global scope...*/

public void playBeep() {
    try {
        if (m.isPlaying()) {
            m.stop();
            m.release();
            m = new MediaPlayer();
        }

        AssetFileDescriptor descriptor = getAssets().openFd(\"beepbeep.mp3\");
        m.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
        descriptor.close();

        m.prepare();
        m.setVolume(1f, 1f);
        m.setLooping(true);
        m.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}


回答3:

Fix of above function for play and pause

  public void playBeep ( String word )
{
    try
    {
        if ( ( m == null ) )
        {

            m = new MediaPlayer ();
        }
        else if( m != null&&lastPlayed.equalsIgnoreCase (word)){
            m.stop();
            m.release ();
            m=null;
            lastPlayed=\"\";
            return;
        }else if(m != null){
            m.release ();
            m = new MediaPlayer ();
        }
        lastPlayed=word;

        AssetFileDescriptor descriptor = context.getAssets ().openFd ( \"rings/\" + word + \".mp3\" );
        long                start      = descriptor.getStartOffset ();
        long                end        = descriptor.getLength ();

        // get title
        // songTitle=songsList.get(songIndex).get(\"songTitle\");
        // set the data source
        try
        {
            m.setDataSource ( descriptor.getFileDescriptor (), start, end );
        }
        catch ( Exception e )
        {
            Log.e ( \"MUSIC SERVICE\", \"Error setting data source\", e );
        }

        m.prepare ();
        m.setVolume ( 1f, 1f );
        // m.setLooping(true);
        m.start ();
    }
    catch ( Exception e )
    {
        e.printStackTrace ();
    }
}


回答4:

Here my static version:

public static void playAssetSound(Context context, String soundFileName) {
    try {
        MediaPlayer mediaPlayer = new MediaPlayer();

        AssetFileDescriptor descriptor = context.getAssets().openFd(soundFileName);
        mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
        descriptor.close();

        mediaPlayer.prepare();
        mediaPlayer.setVolume(1f, 1f);
        mediaPlayer.setLooping(false);
        mediaPlayer.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}