webentwicklung-frage-antwort-db.com.de

Problem mit der Pufferzeit des MediaPlayer beim Streaming von Audio

Ich benutze MediaPlayer, um ein Radio über HTTP zu streamen. Bei Lollipop dauert es ungefähr eine Minute, bis der Stream startet, was nicht akzeptabel ist. Es dauert ungefähr 20 Sekunden für KitKat, was bereits schmerzhaft ist und nun unbrauchbar wird.

Es gibt ein bekanntes Problem mit dieser Komponente im Zusammenhang mit dem Puffern: Die Anzahl der Bytes, die gepuffert werden sollen, ist harcodiert und kann nicht geändert werden.

Mein Code ist wirklich Standard

player.reset();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(streamUrl);
player.prepareAsync();

Und auf vorbereitet mache ich

player.start();

Ich habe über Alternativen wie GStreamer gehört, aber ich konnte es nicht unter Windows schaffen.

Ich frage mich, ob jemand eine funktionierende Lösung hat, um Radio mit einer vernünftigen Startverzögerung über HTTP zu streamen.

EDIT

Ich habe den ExoPlayer getestet, aber die niedrigere Startzeit beträgt 15 Sekunden. Der Spieler befindet sich im "Vorbereitungs" -Zustand (nicht zwischenspeichern, das ist später soweit ich sehe).

EDIT

Das Format des Streams ist AAC

EDIT

Ich habe https://code.google.com/p/aacdecoder-Android/ getestet, aber das einzige Problem, das diese Bibliothek hat, ist die fehlende Unterstützung für Stream-Pause. Es ist eine Anforderung meiner Anwendung, die Unterbrechung des Online-Streams zu unterstützen.

10
StackOverflower

Wenn Ihr Anwendungsfall mit GPL/LGPL-Lizenzen kompatibel ist, ist VLC genau das, was Sie benötigen. VLC kann von Ihrer URL in einem 3G-Netzwerk mit einer Verzögerung von ~ 1 Sekunde streamen.

Schritt 1: Laden Sie den VLC-Quellcode herunter und kompilieren Sie ihn anhand der Anweisung

Schritt 2: Die wichtigste Klasse ist org.videolan.vlc.audio.AudioServiceController, die von org.videolan.vlc.gui.MRLPanelFragement.processUri() --> org.videolan.vlc.util.Util.openStream(Context, String) --> AudioServiceController.load(String, boolean) aufgerufen wurde. Sie können den gesamten überflüssigen Code außer AudioServiceController und seinen Unterstützungsklassen entfernen, um die Größe zu verringern

8
Kai

Ich kann vorschlagen, von MediaPlayer zu ExoPlayer zu wechseln. Mit ExoPlayer ist es möglich, die Pufferparameter wie folgt einzurichten:

public static ExoPlayer newInstance(int rendererCount, int minBufferMs, int minRebufferMs) {
  return new ExoPlayerImpl(rendererCount, minBufferMs, minRebufferMs);
}

minBufferMS bedeutet eine Mindestdauer von Daten, die für die Wiedergabe gepuffert werden muss, um nach einer Benutzeraktion wie einer Suche gestartet oder wieder aufgenommen zu werden.

minRebufferMs bedeutet eine Mindestdauer von Daten, die zur Wiedergabe wieder aufgenommen werden müssen, um nach dem Aufrufen eines Wiederaufbereitungsvorgangs durch einen Spieler wieder aufgenommen zu werden (d. h. ein Wiederauffrischungspuffer, der aufgrund eines erschöpften Puffers auftritt und nicht aufgrund einer Benutzeraktion wie Starten der Wiedergabe oder Suche).

Die Standardwerte sind 500 bzw. 5000.

2
Dekra

Sie sollten den Media Player für Live-Radio-Streams vermeiden.

Ich habe die folgende Bibliothek verwendet und sie funktioniert hervorragend: https://code.google.com/p/aacdecoder-Android/

1
Bojan Kseneman

Es gibt zwei Arten von Verzögerungen beim Streaming a. ist die Pufferverzögerung, die die Startverzögerung ist, und b. ist die Broadcast-Verzögerung. 

Im Falle eines Mediaplayers benötigt der Stream 1 Minute für die Pufferung. Wir müssen also erst sehen, wie die Zeit zum Füllen des Puffers reduziert werden kann. Ich bin nicht sicher, ob es im Media-Player-Code von Android möglich ist, die Puffergröße zu konfigurieren. 

Wenn wir jedoch versuchen, die AAC-Decoderbibliothek für Android zu verwenden ( https://code.google.com/p/aacdecoder-Android/downloads/detail?name=aacdecoder- Android-0.8.Zip), dann haben wir die Bereitstellung, um den Eingabepuffer zu füllen.

Pl. Im nachstehenden Codeausschnitt können Sie die Kapazität des Eingangspuffers je nach Anforderung auffüllen. Anschließend können Sie die Wiedergabe starten. Da wir die Kapazität des Eingangspuffers kontrollieren können, können wir versuchen, die Zeitverzögerung zu verringern, um die Wiedergabe zu starten. Pl. Prüfen Sie, ob dies Ihnen helfen kann. 

 /**
 * Sets the audio buffer (AudioTrack) capacity.
 * The capacity can be expressed in time of audio playing of such buffer.
 * For example 1 second buffer capacity is 88100 samples for 44kHz stereo.
 * By setting this the audio will start playing after the audio buffer 
   is    first filled.
 *
 * NOTE: this should be set BEFORE any of the play methods are called.
 *
 * @param audioBufferCapacityMs the capacity of the buffer in milliseconds
 */
  public void setAudioBufferCapacityMs( int audioBufferCapacityMs ) {
    this.audioBufferCapacityMs = audioBufferCapacityMs;
  }
0
shri

ich werde posten, wie ich es mache und hoe es gibt einen Unterschied. Es ist kein Echtzeit-Sound-Element (es ist ein MP3 aus einer Online-API, aber etwa 4-6 MB). Es kann also variieren, aber es dauert weniger als 3-5 Sekunden, um meine genimotion-VM zu laden.

ich weiß, es ist fast das gleiche wie dein Code. Wenn Sie die URL oder eine ähnliche URL mit den gleichen Problemen teilen könnten, könnte ich sie in meiner App testen.

runThread(url);//ran on the oncreate.


 private void runThread(final String url) {
    new Thread() {
        public void run() {
            mediaPlayer  = new MediaPlayer();//mediaplayer is a global variable.
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

                try{
                    mediaPlayer.setDataSource(url);

                    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mediaPlayer) {
                            //audio did finish.

                        }
                    });
                    mediaPlayer.prepare(); // might take long! (for buffering, etc)
                    duration = mediaPlayer.getDuration();
                    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {

                                    //here you should start playing it.
                                }
                            });
                        }
                    });
                }
                catch(Exception e)
                {

                }


            }
    }.start();
}

getestet auf einem Nexus 4 mit Jelly Bean, ähnliche Zeitantworten.

0
CptEric

Wenn Sie bereit sind, etwas Geld für eine Bibliothek auszugeben, empfehle ich Bass Es verfügt über einen vollständigen Satz von API-Aufrufen, die Sie integrieren können, sowie über eine solide Dokumentation. Es gibt eine Shareware-Version, die Sie testen können.

Wenn Sie nicht bereit sind, $ auszugeben. Ich empfehle VLC @Kai wärmstens erwähnt, auch in Zukunft können Sie Ihre Anwendung erweitern, um damit Video zu streamen. Ich habe zuvor mit der API gearbeitet, um einen Livestream für mein Aquarium durchzuführen. @Kai stellte Ihnen die notwendigen Links zur Verfügung.

Schauen Sie sich diesen link für weitere Informationen an.

0