8
votes

Comment jouer à Inpretstream d'un fichier audio qui n'est pas dans une URL ou un stockage?

Fond

J'ai réussi à télécharger un fichier audio (3GP) dans Google-Drive.

Maintenant, je veux pouvoir jouer au fichier dans l'application.

L'API Google Drive permet uniquement d'obtenir le flux d'entrée du fichier qui est stocké là-bas.

Le problème

Toutes les capacités MediaPlayer des intrants ne sont pas disponibles dans mon cas, qui n'est qu'une entréeSteam:

HTTP: // Developer. android.com/reference/android/media/mediaplayer.html#setdataSource(java.io.filedescriptor)

Je sais que je peux enregistrer le fichier de Google-lecteur vers le cache et la lire, mais je souhaite éviter la manipulation de stockage et lire le fichier à la volée.

Qu'est-ce que j'ai essayé

J'ai essayé de rechercher ce problème et j'ai constaté que cela pourrait être possible avec l'audiotrack ( ici ). Il pourrait également être possible d'utiliser de nouvelles fonctionnalités de haricot de jelly (montré ici < / a>, trouvé de ici ), mais je ne suis pas sûr car il est assez faible niveau.

Malheureusement, en utilisant l'audiotrack, j'ai eu des sons mal joués (bruit).

J'ai également remarqué que MediaPlayer ait la possibilité de définir la DataSource pour être MediaDatasource ( ici ), mais pas seulement je ne suis pas sûr de savoir comment l'utiliser, cela nécessite également une API 23 et plus.

Bien sûr, j'ai essayé d'utiliser une URL donnée dans Google-Drive, mais celle-ci n'est utilisée que à d'autres fins et n'est pas adressée au fichier audio. Il ne peut donc pas être utilisé à l'aide de MediaPlayer.

la question

Étant donné une introuve, est-il possible d'utiliser audiotrack ou autre chose, pour lire un fichier audio 3GP?

y a-t-il peut-être une solution de bibliothèque de support pour cela?


3 commentaires

Avez-vous déjà eu une solution pour cela?


@newenglander. La réponse ci-dessous est trop générale pour moi et je n'avais pas le temps d'enquêter plus loin.


@newenglander, j'ai créé une demande pour elle si cependant: issuTracker.google.com/issues/37093023


4 Réponses :


4
votes

Si votre MINSDKVersion est 23 ou supérieur, vous pouvez Utilisez setdataSource (MediaDataSource) et fournissez votre propre sous-classe du abstrait MediaDataSource classe .

Pour les appareils plus anciens, vous devriez pouvoir utiliser un tuyau créé à partir de ParcelfileDeScriptor . Vous auriez un fil qui écrit des données à votre fin du tuyau et transmettez le filedescriptor (à partir de getfiledescriptor () ) pour la fin du lecteur à setDatasource (FileDeScriptor ) .


7 commentaires

À propos de MediaDataSource, c'est une solution que j'ai trouvée, mais je ne vois aucun exemple de la façon de l'utiliser. Pouvez-vous s'il vous plaît montrer du code pour les deux manières?


@androidDeveloper: Je n'ai jamais utilisé MediaDatasource ; Je viens de courir dans l'autre jour pour aider quelqu'un d'autre. Bien que je n'ai pas utilisé de ParcelfileDeScriptor tuyaux pour la lecture multimédia, je l'ai utilisé pour Enregistrement de média , Servir des documents , etc.


C'est dommage. Merci quand même.


@Commonsware J'ai vérifié setdataSource (FileDescriptor) . Il produit `w / system.err: java.io.ioException: SetDatasourcefd a échoué .: Statut = 0x80000000 W / System.err: à Android.Media.MediaPlayer._sedataSource (méthode natif) W / System.err: à Android.Media .Mediapplayer.setdataSource (mediaplayer.java:113 3) w / system.err: à android.media.mediaplayer.sedia.mediaplayer.setdatasource (mediaplayer.java:111 8) 'S'il n'y a juste pas d'introuvream sous FileDescriptor et non un fichier réel Sur le système de fichiers Android, Mark :(


@isabsent: la lecture des médias a besoin d'un fichier ou d'un protocole de serveur de flux pris en charge (HTTP, RTSP, etc.). Cela ne fonctionne pas bien quand il ne peut pas rembobiner, et un flux sur un tuyau (par exemple, ParcelfileDedescriptor.Createaipe () ) ne peut pas être rembobiné.


Donc, la seule façon d'aller avec de vieux appareils est un serveur HTTP implémentant sur le flux d'hôte local et de lecture?


@isabsent: Afaik, oui. Vous pourriez voir si ExoPlayer offre d'autres options. Par exemple, cela pourrait faire suffisamment de mise en cache pour dépasser la limitation de rembobinage.



-1
votes

Si vous demandez à propos du lecteur multimédia qui définit notre chemin audio peut-être que ce code peut aider ce code peut aider.

p>

File directory = Environment.getExternalStorageDirectory();
		File file = new File( directory + "/AudioRecorder" );
		String AudioSavePathInDevice = file.getAbsolutePath() + "/" + "sample.wav" ;
    
     mediaPlayer = new MediaPlayer();
     
      try {
            mediaPlayer.setDataSource(AudioSavePathInDevice);
            mediaPlayer.prepare();
          } catch (IOException e) {
              e.printStackTrace();
          }

      mediaPlayer.start();


0 commentaires

0
votes

Pour toute personne intéressée par l'utilisation d'une implémentation MediaDataSource, j'ai créé un qui lit à venir et cache des tampons de données. Cela fonctionne à partir de n'importe quel InputStream, je l'ai principalement créé pour lire des fichiers en réseau à l'aide de JCIFS SMBFILE's.

Vous pouvez le trouver à https://github.com/stevegreetape/bufferedmediaDataSource


2 commentaires

Bien que cela puisse répondre théoriquement à la question, Il serait préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence . Voir ici pour obtenir des instructions Comment écrire mieux "Basé sur le lien". Merci!


Joli. Merci.



2
votes

L'exemple de implémentation MediaDataSource la plus simple:

InputStream is = drive.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute().getContent();


16 commentaires

Pouvez-vous s'il vous plaît montrer comment l'utiliser et quoi faire avec API <23 (qui est encore beaucoup d'utilisateurs)?


S'il vous plaît montrer comment obtenir le "Mediafe" de travailler avec l'INTERPENStream donné par l'API de lecteur. C'est ce que la question était de ...


Il y a plus de 20 cours Java dans l'ancienne version de Nanohttpd patché à mes fins de configurer un serveur ... Je dois penser à représenter tout ce code.


N'y a-t-il pas une meilleure façon? Voir ce qui a été écrit ici: Stackoverflow.com/a/36829873/878126 .


Voulez-vous dire exoplayer ou quoi?


Le lien passe à une réponse ci-dessus, disant "pour les appareils plus anciens, vous devriez pouvoir utiliser un tuyau créé à partir de ParcelfileDedescriptor. Vous auriez un fil qui écrit des données à votre extrémité du tuyau et transmettez le fichier FileDeDedescriptor () ) pour la fin du joueur à SetDataSource (FileDescriptor). "


Il est impossible avec le descripteur Parcelfile. J'ai essayé de cette façon couple il y a quelques années. Jetez un coup d'œil à notre discussion ultérieure avec @commonsware dans cette réponse.


Oh je n'ai pas remarqué que cela a eu de nouveaux commentaires. Alors peut-être que c'est possible avec l'exoplayer? C'est une bibliothèque de Google, non?


Je ne suis pas sûr :( Je n'ai jamais vu dans Docs que ExoPlayer peut prendre l'introuvream sur son entrée. Avez-vous lu? Je suppose que, il est nécessaire de regarder le code source pour le comprendre. De plus, ma condition était de soutenir API> = 14, mais ExoPlayer ne prend en charge que l'API> = 16.


Désolé. J'ai laissé ce fil il y a longtemps (alors j'ai cessé de faire des recherches à ce sujet), comme je n'avais plus besoin de cela. Je vous accorderai de +1 pour l'effort cependant. Si vous réussissez à montrer une belle solution pour Pre API 23, même avec EXPPlayer, cela pourrait être très agréable.


Merci. Je suppose que la meilleure solution à ce moment est d'utiliser Android VLC Bibliothèques dans votre application en tant que média joueur. Il prend en charge une lecture de flux équitable, beaucoup de fichiers multimédia et joue bien et stable comme je peux voir - VLC et 321


Connaissez-vous un échantillon de la manière de l'utiliser, pour ce cas d'utilisation?


Vous devez installer ContentProvider dans votre application avec la méthode ParcelfileDedescriptor OpenFile (UriR Uri, Mode String) . Dans cette méthode, vous devez implémenter le schéma @commonsware avec ParceFileDedescriptor et INTRISTREAM et envoyer à l'intention du monde externe avec URI contenu: //vour.content.provider.name /... qui identifiera votre intrigue. VLC attrapera cette intention et demandera à Android de fournir une application qui a un tel introuvream (c'est-à-dire votre application - au moyen de votre ContentProvider ). Après cela, VLC commencera à pomper InputStream que vous avez fourni.


Oui, je comprends l'idée, mais y a-t-il une application d'exemple pour le tester?


Je n'ai pas d'application d'échantillon, cela fonctionne dans le cadre de BestCrypt Explorateur . Mais il n'y a pas beaucoup de code et je peux écrire un échantillon de code un peu plus tard.


@android développeur: J'ai préparé un échantillon de code pour vous. Demandez à une nouvelle question sur afin que je le sais ici et je vais y répondre.