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


86

私は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


いくつかの質問:(1)どのSDKバージョンを使用していますか?(2)どのデバイスでテストしていますか?これはSDK2.0.1で正常に機能し、Droidでテストします。
Roman Nurik 2009

こんにちはローマン、時間を割いていただきありがとうございます。私はこれを1.6に対して試していますが、HTCHeroを使用しています。私はあなたのコメントに照らして2.01でそれを試してみますが、これが2.x以上のデバイスでのみ機能した場合、それはばかげた結果になります。
パンダラバー2009

2.01エミュレータで試してみました。残念ながら動作しません。実際の1.6デバイスと実際の2.01デバイスに対してこれを試してみることに興味があります。私は4日にGoogleのテストを行っています。多分それまで待たなければならないでしょう。でも、そうする必要はありません。
パンダラバー2009

2.0と2.0.1で違いが出るとは思いませんが、エミュレーターとライブデバイスで違いが出る可能性があります。これがヒーローで機能しなかったことに驚いています。私はそれを調べて、より良い答えを得ることができるかどうかを確認します。また、サニティチェックと同様に、マニフェストでインターネットアクセス許可を要求したことを確認する必要があります。
Roman Nurik 2009

ちょっと議論の外に私は質問があります。mp.setDataSource(URL_OF_FILE);を使用する場合 オーディオストリーミング用にファイルを保存する必要はありません。そうですね。そのため、どの場所からでもオーディオをストリーミングするための最良の方法です。何か案は?
ボヘミアン

回答:


78

ストリーミングの例を使用した単純なメディアプレーヤー。xml部分の場合、id button1のボタン1つと、名前が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;
    }
}

これにはわずかな問題があります。MediaPlayerの再生中に携帯電話をロックすると、ロックを解除するとアプリがクラッシュします。
CiaranC94 2016

3
私はちょうどコメントアウトonPause(中「mediaPlayer.release()」の行を)試してみた、そして今、私のアプリは、ロック解除時にクラッシュしていません。
CiaranC94 2016

@PiyushMishraこれらの機能は開発者コンソールで受け入れられますか?私のアプリが拒否されたので、私はVitamio 4.xバージョンを使用しました
Pallavi

35

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

Android用のNPRNewsアプリはオープンソースであり、ローカルプロキシサーバーを使用して、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=7cf2352b5c3c0fbcdc18a5a8c67d836577e7e8e3

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

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


あなたはこれについて絶対に確信していますか?私の理解では、それはmimeタイプに関係しているということです。tが2.1より前の正しいMIMEタイプで機能するかどうかを確認できますか?私は今何か他のものに取り組んでいて、しばらくの間チェックすることができませんでした。
パンダラバー2010

1
2.2リリースノート(developer.android.com/sdk/android-2.2-highlights.html)によると、「ローカルファイルの再生とHTTPプログレッシブストリーミングをサポートする新しいメディアフレームワーク(Stagefright)」が含まれています。すべてのテストで、2.1デバイスをshoutcastサーバーから直接ストリーミングすることができませんでした。問題は、shoutcastサーバーがHTTP /1.1ではなくICY / 1.1のプロトコルを返し、メディアプレーヤーがそのコンテンツに応答する方法を知らないため、これにつまずくということだと思います。
jwadsa​​ck 2010

@jwadsa​​ckオーディオファイルを一度ダウンロードする必要があり、ユーザーがファイルをオフラインでも再生できる場合はどうなりますか?
Devendra Singh 2015

@DevendraSingh現在のメディアプレーヤーの実装でストリーミング中にファイルを保存できるかどうかはわかりません(この回答はほぼ5年前のものであり、2.2以降多くの変更があります)。他に何もない場合は、この例に従ってプロキシを構築し、プロキシを通過する間にファイルをストレージに書き込むことができます。
jwadsa​​ck 2015

11

.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を確認しました。残念ながら、すべての.plがそのようなプレーンテキストであるとは限りません。

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

幸運を!


7
音楽をストリーミングする場合は、mediaplayer.prepareではなくmediaplayer.prepareAsyncを使用する必要があることに注意してください。したがって、mediaplayer.create()を使用することはできません。これは、.create()関数のいずれかがMedia Playerオブジェクトを直接Prepared状態にし、そこからストリーミングするために必要なprepareAsyncを呼び出すことができないためです。developer.android.com/reference/android/media/MediaPlayer.html
marienke 2013年

4

使用する

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

2

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

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


mp3ファイルの場合はContent-Type:audio / mpegである必要があります。これで問題は解決しました:)
doep 2010

1
そのファイルをどのようにストリーミングしましたか?
Nauman Khalid 2014

2

私のプロジェクトを見てください:

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

1

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


05-22 20:26:13.625:E / MediaPlayer(23818):prepared()関数でMedia Playerを起動しても、状態0で呼び出されるのを停止します。MediaPlayerオブジェクトをリセットするonError関数もあります。ストリームの再生が開始されるまで、まだ最大2分かかります。ここで私の質問を参照してください:stackoverflow.com/questions/16672568/...
marienke
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.