29 votes

Décodage MP3 sur Android

Nous mettons en œuvre un programme pour les téléphones Android qui lit les fichiers audio en streaming à partir d'internet. Voici environ ce que nous faisons:

  1. Télécharger personnalisé format crypté.
  2. Décrypter pour obtenir des morceaux de régulière des données MP3.
  3. Décoder les MP3 de données raw PCM données dans une mémoire tampon.
  4. Pipe raw PCM données à un AudioTrack

Notre cible appareils de mesure sont Droid et le Nexus One. Tout fonctionne très bien sur Nexus One, mais le décodage MP3 est trop lent sur le Droid. La lecture de la vidéo commence à ignorer si nous avons mis le Droid sous la charge. Nous ne sommes pas autorisés à décoder les MP3 de données sur la carte SD, mais je sais que c'est pas notre problème, de toute façon.

Nous n'avons pas d'écrire notre propre décodeur MP3, mais utilisé MPADEC (http://sourceforge.net/projects/mpadec/). C'est gratuit et simple à intégrer avec notre programme. Nous le compiler avec le NDK.

Après analyse exhaustive avec les différents outils de profilage, nous sommes convaincus que c'est ce décodeur qui est à la traîne.

Voici les options que nous réfléchissons:

  1. Trouver un autre décodeur MP3 que l'on peut compiler avec l'Android NDK. Ce décodeur MP3, devrait être optimisé pour fonctionner sur mobile, appareils ARM ou peut-être utiliser des entiers des mathématiques ou de quelques autres optimisations pour améliorer les performances.

  2. Depuis le haut-Android MediaPlayer service d'Url, nous pourrions être en mesure de mettre en œuvre un petit serveur HTTP dans notre programme et servir le lecteur multimédia avec la restitution des fichiers Mp3. De cette façon, nous pouvons tirer parti de l'intégré dans le décodeur MP3.

  3. Obtenir l'accès à la fonction intégrée dans MP3 decoder par le NDK. Je ne sais pas si c'est possible.

Quelqu'un aurait-il des suggestions sur ce que nous pouvons faire pour accélérer notre décodage MP3?

-- Rob Sz

2voto

CommonsWare Points 402670

La bonne façon de le faire est de construire votre propre firmware et de faire le déchiffrement dans le cadre d'une coutume OpenCORE codec. Qui, bien sûr, vous limitera aux appareils sur lesquels vous pouvez installer ce firmware.

Gardez à l'esprit que le reste de ce qui est un peu spéculatif. En fait, j'ai besoin de faire quelque chose de similaire à ce que vous décrivez, mais je n'ai pas le temps de mettre de côté pour s'attaquer au problème pour un couple de mois. Donc, je vais vous décrire à la manière de comment j'allais aborder le problème.

La seule solution est celle décrite dans la twk de réponse. Vous n'avez pas à utiliser la carte SD, mais vous n'avez probablement avoir un texte lisible fichier temporaire dans votre app-local de stockage des fichiers (getFilesDir()). Télécharger le premier morceau, de les décrypter, de les écrire comme un univers complet, lisible fichier MP3 (mais avec assez obscure répertoire/chemin), et le remettre à un MediaPlayer par setDataSource(). Alors que qui joue, vous télécharger/décrypter et mettre en place une deuxième MediaPlayer de l'instance, dont la lecture commence dès que la première se termine, comme une transition transparente que possible. Vous réinitialisez le premier MediaPlayer et le réutiliser à votre troisième partie, table de ping-ponging entre les deux.

Une solution connexe serait en jleedev commentaire. C'est à peu près la même chose, sauf que vous fournissez un FileDescriptor via un ContentProvider. Cela a une option pour vous permettre d'utiliser une socket, ce qui peut vous permettre d'éviter le fichier temporaire. Cependant, l' ContentProvider devra lui-même être accessible au public, et donc le fichier temporaire, avec un obscur répertoire, pourrait en fait être plus privé.

Si vous êtes inquiet sur le fait que ces choses peuvent être lus par d'autres processus, s'il vous plaît comprendre que MediaPlayer (ou, plutôt, la OpenCORE sous-système) est dans un autre processus. Aussi, votre proposition de serveur HTTP est lisible par tout le monde sur l'appareil. Ainsi, la sécurité par l'obscurité est votre seule option viable si vous allez laisser MediaPlayer ne le décodage.

Autant que je sache, le NDK ne donne pas accès à OpenCORE, même si j'avoue que pour avoir limité NDK expérience, donc j'ai peut-être tort. Il y a certainement d'autres décodeurs MP3 disponible (ffmpeg/mplayer, etc.), bien que la manière dont ceux-ci pourraient facilement être converti en un NDK bibliothèque n'est pas claire.

Donc, vraiment résume à qui vous êtes en essayant de se défendre contre. Si vous êtes en essayant de défendre l'encontre de l'utilisateur, vous allez probablement avoir à décoder de vous-même, en quelque sorte.

1voto

crazyscot Points 6675

MAD est une bibliothèque de décodage à arithmétique entière qui semble être bien considérée.

(Le décodage des données sur la carte SD ne vous ralentirait-il pas de toute façon?)

0voto

twk Points 6300

Je n'ai pas essayé cela, mais je pense que vous pouvez donner au lecteur multimédia un descripteur de fichier:

 public void setDataSource (FileDescriptor fd, long offset, long length)
 

Vous pouvez peut-être écrire le mp3 déchiffré dans un fichier et le lire à l'aide du descripteur de fichier. Cela peut même fonctionner pour le streaming en supposant que vous connaissez la longueur du fichier à l'avance. Si cela fonctionne, ce serait beaucoup plus simple que de faire un serveur web localhost.

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