MediaPlayer bégaie au début de la lecture de mp3
J'ai eu un problème de lecture d'un fichier mp3 stockés dans une ressource brute: lorsque le fichier de la première commence à jouer, il génère peut-être un quart de seconde de son, puis redémarre. (Je sais que c'est fondamentalement un double du problème décrit ici, mais la solution proposée n'a pas fonctionné pour moi.) J'ai essayé plusieurs choses et ont fait des progrès sur le problème, mais il n'est pas totalement fixe.
Voici comment je me suis mise à lire un fichier:
mPlayer.reset();
try {
AssetFileDescriptor afd = getResources().openRawResourceFd(mAudioId);
if (afd == null) {
Toast.makeText(mOwner, "Could not load sound.",
Toast.LENGTH_LONG).show();
return;
}
mPlayer.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getLength());
afd.close();
mPlayer.prepare();
} catch (Exception e) {
Log.d(LOG_TAG, "Could not load sound.", e);
Toast.makeText(mOwner, "Could not load sound.", Toast.LENGTH_LONG)
.show();
}
Si je quitte l'activité (qui appelle mPlayer.release()
) et de revenir à elle (la création d'un nouveau lecteur multimédia), le bégaiement est généralement (mais pas toujours) disparu—fourni je charge le même fichier audio. J'ai essayé un couple de choses que ne fait pas de différence:
- Charger le fichier audio comme un atout plutôt que comme une ressource.
- Créer le lecteur multimédia à l'aide de
MediaPlayer.create(getContext(), mAudioId)
et ignorer les appels àsetDataSource(...)
etprepare()
.
Puis j'ai remarqué que LogCat montre toujours cette ligne à environ le temps que la lecture commence:
DEBUG/AudioSink(37): bufferCount (4) is too small and increased to 12
Il m'a demande si le bégaiement est en raison de l'apparente rebuffering. Cela m'a conduit à essayer quelque chose d'autre:
- Après l'appel de
prepare()
, appelmPlayer.start()
et appeler immédiatementmPlayer.pause()
.
À mon agréable surprise, ça a eu un grand effet. Une grande partie de la bégaiement est parti, plus aucun son (que je peux entendre) est effectivement joué à ce point dans le processus.
Cependant, il bégaie toujours de temps en temps quand je l'appelle mPlayer.start()
pour de vrai. De Plus, cela semble être un énorme bidouille. Est-il possible de tuer ce problème complètement et proprement?
MODIFIER Plus d'infos; vous ne savez pas si liés. Si je l'appelle pause()
pendant la lecture, demander à une position antérieure, et d'appeler start()
de nouveau, j'entends un peu court (~1/4 s) de sons supplémentaires, d'où il a été interrompu avant qu'il ne commence à jouer à la nouvelle position. Cela semble plus de mise en mémoire tampon des problèmes.
Aussi, le bégaiement (en pause et en mémoire tampon) les problèmes apparaissent sur les émulateurs de 1,6 à 3.0.
- Pour ceux avec de bons souvenirs, appelant
start()
etpause()
, comme cela pourrait vous rappeler de la tour que nous avons l'habitude d'avoir à faire à force de pré-chargement d'unAudioClip
dans une page web applet. 🙂 - C'est peut-être à voir avec l'encodage du fichier audio, ou, éventuellement, la longueur de celui-ci. Avez-vous essayé d'utiliser votre code avec un autre fichier audio?
- ce qui se passe avec quatre fichiers, allant de 56 secondes à peine plus de 4 minutes. Chacun est un seul flux de données audio à l'aide de MPEG Audio Layer 1/2/3 (mpga), dans le stéréo de 44100 hz fréquence d'échantillonnage de 128 ko/s débit binaire. Ils ont été générés avec GarageBand 5.1. J'ai essayé de ré-enregistrer les fichiers avec Audacity 1.3. Pas de changement. La lecture de fichiers amende dans les médias de joueurs sur mon ordinateur.
- Faire des fichiers MP3 à jouer dans la valeur par défaut d'Android media player ou autre lecteur média Android apps. Si oui, alors il semble que vous avez exclu l'encodage/débit binaire du fichier. Si non, alors essayer quelques-uns des Mp3 que viendra avec Android.
- La lecture de fichiers très bien quand je les ai mis sur la carte sd et de les jouer avec l'application Musique.
- Pourriez-vous m'aider à ce Question
Vous devez vous connecter pour publier un commentaire.
Autant que je sache, les tampons qui MediaPlayer crée en interne sont pour le stockage de décompressé échantillons, pas pour le stockage de prefetched données compressées. Je soupçonne votre bégaiement vient de I/O lenteur qu'il se charge plus MP3 de données pour la décompression.
J'ai récemment eu à résoudre un problème similaire avec la lecture vidéo. Grâce à
MediaPlayer
étant pas en mesure de jouer un arbitraireInputStream
(l'API est étrangement boiteux) la solution je suis venu avec était d'écrire un petit cours de processus de serveur pour servir des fichiers locaux (sur la carte SD) via HTTP.MediaPlayer
charge ensuite via une URI de la forme http://127.0.0.1:8888/videofilename.EDIT:
Ci-dessous est la StreamProxy classe-je utiliser pour nourrir le contenu dans un lecteur multimédia instance. L'utilisation de base est que vous instanciez, start (), et votre lecteur multimédia aller avec quelque chose comme
MediaPlayer.setDataSource("http://127.0.0.1:8888/localfilepath");
Je note que c'est plutôt expérimental et n'est probablement pas entièrement exempt de bogues. Il a été écrit pour résoudre un problème similaire à la vôtre, à savoir que MediaPlayer ne peut pas lire un fichier qui est également en cours de téléchargement. De la diffusion d'un fichier localement dans cette façon fonctionne autour de cette restriction (c'est à dire, j'ai un fil de télécharger le fichier alors que la StreamProxy insère dans mediaplayer).
seekTo(500)
. DansonSeekComplete
, je vérifie le drapeau et, si elle est définie, j'clair et appelerseekTo(0)
; sinon, j'appellestart()
. Simple.boolean initialSeek; /* member field */ mp.reset(); mp.prepare(); mp.setOnSeekCompleteListener(new OnSeekCompleteListener() { @Override public void onSeekComplete(MediaPlayer mp) { if (initialSeek) { initialSeek = false; mp.seek(0); } else { mp.start(); } } }); initialSeek = true; mp.seekTo(500);
Serait à l'aide d'
prepareAsync
et de répondre àsetOnPreparedListener
vous conviennent le mieux? En fonction de votre activité flux de travail, lorsque leMediaPlayer
est d'abord initialisé à définir les préparation de l'auditeur et ensuite appelermPlayer.prepareAsync()
plus tard, une fois que vous êtes en fait le chargement de la ressource, puis démarrez la lecture. J'utilise quelque chose de similaire, mais pour un réseau de diffusion de ressources:Il y a évidemment plus d'une solution complète (gestion des erreurs, etc.) mais je pense que cela doit fonctionner comme un bon exemple pour démarrer à partir de ce que vous pouvez tirer le streaming de.
start()
est appelé. Mais alors, je serai le premier à admettre que je n'ai pas de comprendre pleinement comment MediaPlayer fonctionne en interne.