39

mp3ファイルをbyte[](サービスからダウンロード)で持っています。ファイルを再生する方法と同じように、デバイスで再生したいと思います。

MediaPlayer mp = new MediaPlayer();
mp.setDataSource(PATH_TO_FILE);
mp.prepare();
mp.start();

しかし、私はそれを行う方法を見つけることができないようです。ファイルを携帯電話に保存して再生してもかまいません。ファイルを再生するにはどうすればよいですか、またはダウンロードしてから再生するにはどうすればよいですか?

4

6 に答える 6

78

OK、ありがとうございましたが、.NETWebサービスから取得するのでbyte[]からmp3を再生する必要がありました(動的に生成されたmp3をサーバーに保存したくない)。

結局のところ、単純なmp3を再生するための「落とし穴」がいくつかあります...これは、それを必要とする人のためのコードです。

private MediaPlayer mediaPlayer = new MediaPlayer();
private void playMp3(byte[] mp3SoundByteArray) {
    try {
        // create temp file that will hold byte array
        File tempMp3 = File.createTempFile("kurchina", "mp3", getCacheDir());
        tempMp3.deleteOnExit();
        FileOutputStream fos = new FileOutputStream(tempMp3);
        fos.write(mp3SoundByteArray);
        fos.close();

        // resetting mediaplayer instance to evade problems
        mediaPlayer.reset();

        // In case you run into issues with threading consider new instance like:
        // MediaPlayer mediaPlayer = new MediaPlayer();                     

        // Tried passing path directly, but kept getting 
        // "Prepare failed.: status=0x1"
        // so using file descriptor instead
        FileInputStream fis = new FileInputStream(tempMp3);
        mediaPlayer.setDataSource(fis.getFD());

        mediaPlayer.prepare();
        mediaPlayer.start();
    } catch (IOException ex) {
        String s = ex.toString();
        ex.printStackTrace();
    }
}

編集:私は4年以上前にこの答えを書きました-明らかにそれ以来多くのことが変わりました。MediaPlayerインスタンスを再利用する方法に関するJustinのコメントを参照してください。また、.deleteOnExit()が機能するかどうかもわかりません。一時ファイルが積み重ならないように、自由に改善を提案してください。

于 2009-12-29T22:04:13.077 に答える
22

MP3 ファイルを Base64 としてエンコードし (Restful API サービスからエンコードされたデータを既に受け取っています)、URL オブジェクトを作成するという簡単な解決策を見つけました。Android 4.1でテストしました。

public void PlayAudio(String base64EncodedString){
        try
        {
            String url = "data:audio/mp3;base64,"+base64EncodedString; 
            MediaPlayer mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource(url);
            mediaPlayer.prepare();
            mediaPlayer.start();
        }
        catch(Exception ex){
            System.out.print(ex.getMessage());
        }
    }
于 2016-08-18T16:57:26.147 に答える
15

Android MarshMellow (バージョン コード 23) 以降、これを可能にする新しい API があります。

MediaPlayer.setDataSource(android.media.MediaDataSource)

MediaDataSource のカスタム実装を提供し、byte[] をラップできます。以下に示す基本的な実装。

import android.annotation.TargetApi;
import android.media.MediaDataSource;
import android.os.Build;
import java.io.IOException;


@TargetApi(Build.VERSION_CODES.M)
public class ByteArrayMediaDataSource extends MediaDataSource {

    private final byte[] data;

    public ByteArrayMediaDataSource(byte []data) {
        assert data != null;
        this.data = data;
    }
    @Override
    public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
        System.arraycopy(data, (int)position, buffer, offset, size);
        return size;
    }

    @Override
    public long getSize() throws IOException {
        return data.length;
    }

    @Override
    public void close() throws IOException {
        // Nothing to do here
    }
}
于 2016-01-13T05:52:15.133 に答える
5

bytearrays / bytestreamsについてはよくわかりませんが、サービスからのURLがある場合は、を呼び出してデータソースをネットワークURIに設定してみてください。

setDataSource(Context context, Uri uri)

APIドキュメントを参照してください。

于 2009-12-28T23:58:46.387 に答える
0

不正なコード:

 MediaPlayer mp = new MediaPlayer();
 mp.setDataSource(PATH_TO_FILE);
 mp.prepare();
 mp.start();

正しいコード:

 MediaPlayer mp = new MediaPlayer();
 mp.setDataSource(PATH_TO_FILE);
 mp.setOnpreparedListener(this);
 mp.prepare();

//Implement OnPreparedListener 
OnPrepared() {
    mp.start();
 }

API デモを参照してください。

于 2009-12-29T14:52:21.540 に答える