web-dev-qa-db-ja.com

MediaPlayerを使用してAndroidのURLからオーディオをストリーミングしますか?

Androidの組み込みMediaPlayerクラスを使用して、httpでmp3をストリーミングしようとしています。ドキュメントは、これが次のように簡単でなければならないことを私に示唆するでしょう:

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

しかし、私は繰り返し以下を取得しています。別のURLも試しました。ストリーミングがmp3で機能しないと言わないでください。

E/PlayerDriver(   31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
W/PlayerDriver(   31): PVMFInfoErrorHandlingComplete
E/MediaPlayer(  198): error (1, -4)
E/MediaPlayer(  198): start called in state 0
E/MediaPlayer(  198): error (-38, 0)
E/MediaPlayer(  198): Error (1,-4)
E/MediaPlayer(  198): Error (-38,0)

助けてくれてありがとう、S

85
Pandalover

ストリーミングのサンプルを使用したシンプルなメディアプレーヤー。xml部分には、button1というidのボタンと、button_pauseおよびbutton_playという名前のドロアブルフォルダーに2つの画像が必要です。マニフェストにインターネットアクセス許可を追加することを忘れないでください。

public class MainActivity extends Activity {
private Button btn;
/**
 * help to toggle between play and pause.
 */
private boolean playPause;
private MediaPlayer mediaPlayer;
/**
 * remain false till media is not completed, inside OnCompletionListener make it true.
 */
private boolean intialStage = true;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btn = (Button) findViewById(R.id.button1);
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    btn.setOnClickListener(pausePlay);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

private OnClickListener pausePlay = new OnClickListener() {

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        // TODO Auto-generated method stub

        if (!playPause) {
            btn.setBackgroundResource(R.drawable.button_pause);
            if (intialStage)
                new Player()
                        .execute("http://www.virginmegastore.me/Library/Music/CD_001214/Tracks/Track1.mp3");
            else {
                if (!mediaPlayer.isPlaying())
                    mediaPlayer.start();
            }
            playPause = true;
        } else {
            btn.setBackgroundResource(R.drawable.button_play);
            if (mediaPlayer.isPlaying())
                mediaPlayer.pause();
            playPause = false;
        }
    }
};
/**
 * preparing mediaplayer will take sometime to buffer the content so prepare it inside the background thread and starting it on UI thread.
 * @author piyush
 *
 */

class Player extends AsyncTask<String, Void, Boolean> {
    private ProgressDialog progress;

    @Override
    protected Boolean doInBackground(String... params) {
        // TODO Auto-generated method stub
        Boolean prepared;
        try {

            mediaPlayer.setDataSource(params[0]);

            mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

                @Override
                public void onCompletion(MediaPlayer mp) {
                    // TODO Auto-generated method stub
                    intialStage = true;
                    playPause=false;
                    btn.setBackgroundResource(R.drawable.button_play);
                    mediaPlayer.stop();
                    mediaPlayer.reset();
                }
            });
            mediaPlayer.prepare();
            prepared = true;
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            Log.d("IllegarArgument", e.getMessage());
            prepared = false;
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            prepared = false;
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            prepared = false;
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            prepared = false;
            e.printStackTrace();
        }
        return prepared;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        if (progress.isShowing()) {
            progress.cancel();
        }
        Log.d("Prepared", "//" + result);
        mediaPlayer.start();

        intialStage = false;
    }

    public Player() {
        progress = new ProgressDialog(MainActivity.this);
    }

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        this.progress.setMessage("Buffering...");
        this.progress.show();

    }
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    if (mediaPlayer != null) {
        mediaPlayer.reset();
        mediaPlayer.release();
        mediaPlayer = null;
    }
}
75
PiyushMishra

Android MediaPlayerは、2.2まではMP3のネイティブストリーミングをサポートしていません。 OSの古いバージョンでは、3GPをネイティブにストリーミングするだけです。 pocketjourneyコードを試すことができますが、古い( 新しいバージョン があります)ため、スティッキーにするのに苦労しました-バッファーを補充するたびに途切れてしまいます。

AndroidのNPR Newsアプリはオープンソースであり、ローカルプロキシサーバーを使用して、2.2より前のバージョンのOSでMP3ストリーミングを処理します。関連するコードは、199行目から216行目(r94)にあります: http://code.google.com/p/npr-Android-app/source/browse/Npr/src/org/npr/ Android/news/PlaybackService.java?r = 7cf2352b5c3c0fbcdc18a5a8c67d836577e7e8e

そして、これはStreamProxyクラスです。 http://code.google.com/p/npr-Android-app/source/browse/Npr/src/org/npr/Android/news/StreamProxy.java?r = e4984187f45c39a54ea6c88f71197762dbe10e72

NPRアプリでも、ストリーミング中に「エラー(-38、0)」が発生することがあります。これは、スレッドの問題またはネットワークの変更の問題である可能性があります。 アップデートの問題トラッカー を確認してください。

35
jwadsack

私はあなたが.plsを直接または類似のものを再生しようとしていると思います。

これを試してください:

1:コード

mediaPlayer = MediaPlayer.create(this, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3"));
mediaPlayer.start();

2:.plsファイル

このURLは、例としてBBCからのものです。 Linuxでダウンロードした.plsファイルでした

wget http://foo.bar/file.pls

そして、vimで開き(お気に入りのエディターを使用してください)、このファイル内の実際のURLを確認しました。残念ながら、すべての.plsがそのようなプレーンテキストではありません。

1.6はhttpを介したmp3のストリーミングをサポートしないことを読みましたが、Android 1.6および2.2で上記のコードをテストしたばかりで、問題はありませんでした。

幸運を!

9
Pabluez

つかいます

 mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaplayer.prepareAsync();
 mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
      @Override
      public void onPrepared(MediaPlayer mp) {
          mediaplayer.start();
      }
 });
3
Shshank Bhong

私はあなたと同じエラーを経験しましたが、コードには何も問題がないことがわかりました。問題は、Webサーバーが間違ったContent-Typeヘッダーを送信していたことです。

Wiresharkなどを試して、ウェブサーバーが送信しているコンテンツタイプを確認してください。

2
doep

私のプロジェクトを探しています:

  1. https://github.com/master255/ImmortalPlayer http/FTPサポート、読み取り、送信、キャッシュデータへの保存を行う1つのスレッド。最も簡単な方法と最も速い作業。複雑なロジック-最良の方法!
  2. https://github.com/master255/VideoViewCache キャッシュ付きのシンプルなビデオビュー。データを再生および保存するための2つのスレッド。悪いロジックですが、必要な場合はこれを使用してください。
1
Master

ログのゼロ状態を回避するために、OnPreparedListenerでmp.startを呼び出しません。

1
Fred Grott