48 votes

Pourquoi le MediaPlayer d'Android met-il si longtemps à préparer certains flux en direct pour la lecture ?

Je constate de grandes différences dans le temps que prend le MediaPlayer Android pour se préparer à la lecture d'un flux en direct avec différents flux.

Les données concrètes

J'ai ajouté la journalisation entre prepareAsync() et le rappel onPrepared(MediaPlayer mp) et testé plusieurs flux plusieurs fois chacun. Les temps pour chaque flux étaient très cohérents (+/- une seconde), et voici les résultats :

  1. Flux de nouvelles MPR : 27 secondes (http://newsstream1.publicradio.org:80/)
  2. Flux de musique classique MPR : 15 secondes (http://classicalstream1.publicradio.org:80/)
  3. MPR The Current stream : 7 secondes (http://currentstream1.publicradio.org:80/)
  4. Flux PRI : 52 secondes (http://pri-ice.streamguys.biz/pri1)

Les tests ont été effectués sur un Nexus S avec Android 2.3.4 sur une connexion 3G (~1100 Kbps).

La lecture de fichiers audio MP3 non diffusés en continu ne pose pas de problème.

Voici des extraits de la façon dont je joue les flux :

Préparez MediaPlayer :

...
mediaPlayer.setDataSource(playUrl);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepareAsync();
...

Puis dans onPrepared(MediaPlayer mp) :

mediaPlayer.start();

Pourquoi la préparation de certains cours d'eau prend-elle autant de temps que celle d'autres ? Les données ci-dessus semblent suggérer que pourrait se fonder sur le montant de données qui ont été mises en mémoire tampon et non pas la durée du contenu audio mis en mémoire tampon. Est-ce vraiment possible ?

Mise à jour : J'ai testé le streaming en direct sur des appareils physiques avec Android 1.6, 2.2 et 2.3.4 et des émulateurs avec 1.6, 2.1, 2.2, 2.3.1 et 2.3.3. Je ne vois le long délai que sur 2.3.3 et 2.3.4. Les versions plus anciennes commencent la lecture dans les 5 secondes.

24voto

aroth Points 28424

Il semble qu'il mette en mémoire tampon une quantité fixe de données plutôt qu'une quantité fixe de temps. Pour tous ceux qui ne connaissent pas les débits binaires des différents types de flux NPR, les données ressemblent à ceci :

  1. Flux d'informations MPR : 27 secondes ( http://newsstream1.publicradio.org:80/ ), 64 kbps
  2. Flux de musique classique de MPR : 15 secondes ( http://classicalstream1.publicradio.org:80/ ), 128 kbps
  3. MPR Le flux actuel : 7 secondes ( http://currentstream1.publicradio.org:80/ ), 128 kbps
  4. Flux PRI : 52 secondes ( http://pri-ice.streamguys.biz/pri1 ), 32 kbps

Mis à part l'écart entre les deux flux de 128 kbps, il existe une très bonne corrélation entre le débit binaire et la durée de mise en mémoire tampon.

Dans tous les cas, Android est open-source, donc vous pouvez toujours regardez ce qu'il fait . Malheureusement, prepareAsync() et prepare() sont des méthodes natives, et il semble que les événements liés à la mémoire tampon soient également distribués par un processus natif.

Avez-vous essayé d'attacher un OnBufferingUpdateListener au MediaPlayer pour obtenir des mises à jour plus fines de l'état de la mémoire tampon ? Il pourrait être intéressant de comparer la vitesse à laquelle les événements sont délivrés et le pourcentage de remplissage de la mémoire tampon pour chaque événement sur les différents flux. Vous pouvez croiser ces données avec les débits binaires des flux et si 4 secondes de mise en mémoire tampon à 32 kbps remplissent la mémoire tampon au même pourcentage qu'une seconde de mise en mémoire tampon à 128 kbps, je pense que vous aurez trouvé votre réponse.

8voto

astinx Points 828

Interrupteur MediaPlayer par FFmpegMediaPlayer fonctionne beaucoup mieux que le MediaPlayer si vous souhaitez tester vos flux, vous pouvez le faire par le biais de la fonction Démonstration qu'ils ont.

5voto

Nick Campion Points 7263

J'ai récemment débogué ce même problème avec un fournisseur de streaming audio. Le problème est lié au stagefright et aux sources de streaming de 32 kbps et moins. Nous avons procédé au même streaming en mesurant le temps de réponse à 24, 32, 48, 64 et 128 kbps.

  • 24 -> 46 secondes pour commencer le streaming
  • 32 -> 24 secondes pour commencer le streaming
  • 48 -> 2 secondes pour commencer le streaming
  • 64 -> 2 secondes pour commencer le streaming
  • 128 -> 2 secondes pour commencer le streaming

Il s'agit d'une connexion sans fil constante, dont la moyenne a été calculée sur 10 essais à chaque débit binaire. La clé, comme Travis l'a souligné, est que Stagefright ne pouvait pas déterminer la durée de la mise en mémoire tampon de l'audio. Parfois, je voyais un message 'error : 1,-21492389' ou quelque chose comme ça, ce qui semblait faire planter le lecteur Stagefright en silence. J'ai essayé de trouver la cause de ce problème et j'en suis venu à la conclusion que les flux très lents (moins de 24 kbps) semblaient provoquer un débordement de la mémoire tampon, car ils étaient mis en mémoire tampon jusqu'à ce que le périphérique manque d'espace pour le flux audio.

Je voulais ajouter que OnBufferingUpdateListener n'a pas tiré du tout pendant tout le test. Je ne sais pas à quoi il sert. Je pense que la seule façon de savoir comment se déroule le chargement est d'utiliser un proxy pour le chargement, de la même façon que l'application NPR mentionnée ci-dessus.

2voto

Matt Harrington Points 628

Si vous faites du streaming à partir d'Icecast, jetez un coup d'œil à l'écran suivant burst-size réglage :

La taille de la rafale est la quantité de données (en octets) à envoyer en rafale à un client au moment de la connexion. au moment de la connexion. Comme pour le burst-on-connect, il s'agit de remplir rapidement le pré-buffer utilisé par les lecteurs multimédia. pré-buffer utilisé par les lecteurs multimédia. La valeur par défaut est de 64 koctets, ce qui est un taille typique utilisée par la plupart des clients, il n'est donc généralement pas nécessaire. Ce paramètre s'applique à tous les points de montage sauf s'il est surchargé dans les dans les paramètres de montage. Assurez-vous que cette valeur est inférieure à queue-size, si nécessaire, augmentez queue-size pour qu'elle soit plus grande que votre taille de rafale souhaitée. Si vous ne le faites pas, vous risquez d'interrompre les tentatives de connexion des clients client, en raison de la rafale initiale menant à la connexion. déjà dépassé la limite de la taille de la file d'attente.

J'ai augmenté le burst-size à 131072 sur mon serveur, et maintenant mon application Android basée sur MediaPlayer joue les flux sans beaucoup de retard.

1voto

Travis Biehn Points 106

J'ai essayé cela avec 10 points de données, trois rapides, sept lents. C'est cohérent, c'est-à-dire qu'un flux rapide est rapide et un flux lent est toujours lent.

Je pense que c'est lié au serveur qui délivre 'content-length', Android ne sait pas combien mettre en mémoire tampon si le content-length n'est pas correctement spécifié.

Je peux me tromper, je ne suis pas allé jusqu'à faire du wiresharking.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X