webentwicklung-frage-antwort-db.com.de

Audio-Streaming von einer URL in Android mit MediaPlayer?

Ich habe versucht, MP3s über http zu streamen, indem ich die in MediaPlayer integrierte Klasse von Android verwendete. Die Dokumentation würde mir vorschlagen, dass dies so einfach sein sollte wie:

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

Allerdings bekomme ich immer wieder folgendes. Ich habe auch verschiedene URLs ausprobiert. Bitte sag mir nicht, dass das Streamen von MP3s nicht funktioniert.

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)

Jede Hilfe sehr geschätzt, danke S

85
Pandalover

einfacher Media Player mit Streaming-Beispiel. Für den XML-Teil benötigen Sie eine Schaltfläche mit der ID button1 und zwei Bilder in Ihrem Zeichenordner mit den Namen button_pause und button_play. Vergessen Sie nicht, die Internet-Berechtigung in Ihrem Manifest hinzuzufügen.

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 unterstützt das Streamen von MP3 erst ab Version 2.2. In älteren Versionen des Betriebssystems scheint es nur 3GP nativ zu streamen. Sie können den Taschenreisecode ausprobieren, obwohl er alt ist (es gibt ein neue Version hier ) und ich Probleme hatte, ihn klebrig zu machen - er würde stottern, wenn er den Puffer auffüllt.

Die NPR News-App für Android ist Open Source und verwendet einen lokalen Proxyserver, um MP3-Streaming in Betriebssystemversionen vor 2.2 zu verarbeiten. Den entsprechenden Code finden Sie in den Zeilen 199-216 (r94). hier: http://code.google.com/p/npr-Android-app/source/browse/Npr/src/org/npr/Android/news/PlaybackService.java?r=7cf2352b5c3c0fbcdc18a5a8c67d836577e7e8e

Und das ist die StreamProxy-Klasse: http://code.google.com/p/npr-Android-app/source/browse/Npr/src/org/npr/Android/news/StreamProxy.java?r = e4984187f45c39a54ea6c88f71197762dbe10e72

Die NPR-App erhält manchmal beim Streaming auch immer noch den "Fehler (-38, 0)". Dies kann ein Threading-Problem oder ein Netzwerkänderungsproblem sein. Überprüfen Sie die Issue Tracker für Updates .

35
jwadsack

Ich vermute, dass Sie versuchen, eine .pls direkt oder etwas ähnliches zu spielen.

probier das mal aus:

1: der Code

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

2: die .pls-Datei

Diese URL ist nur ein Beispiel von BBC. Es war eine .pls-Datei, die ich unter Linux heruntergeladen habe

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

und dann habe ich mit vim geöffnet (benutze deinen Lieblingseditor;) und ich habe die echten URLs in dieser Datei gesehen. Leider sind nicht alle .pls so reine Texte.

Ich habe gelesen, dass 1.6 das Streamen von MP3 über http nicht unterstützen würde, aber ich habe gerade den obigen Code mit Android 1.6 und 2.2) getestet und hatte kein Problem.

viel Glück!

9
Pabluez

Verwenden

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

Ich hatte den gleichen Fehler wie Sie und es stellte sich heraus, dass am Code nichts falsch war. Das Problem war, dass der Webserver den falschen Content-Type-Header gesendet hat.

Probieren Sie wireshark oder ähnliches aus, um festzustellen, welchen Inhaltstyp der Webserver sendet.

2
doep

Meine Projekte ansehen:

  1. https://github.com/master255/ImmortalPlayer http/FTP-Unterstützung, Ein Thread zum Lesen, Senden und Speichern von Daten im Cache. Einfachster Weg und schnellste Arbeit. Komplexe Logik - der beste Weg!
  2. https://github.com/master255/VideoViewCache Einfache Videoanzeige mit Cache. Zwei Threads zum Abspielen und Speichern von Daten. Schlechte Logik, aber wenn Sie dann brauchen, verwenden Sie diese.
1
Master

Kein Aufruf von mp.start mit einem OnPreparedListener, um den Nullzustand im Log zu vermeiden.

1
Fred Grott