Próbowałem przesyłać strumieniowo pliki mp3 przez http przy użyciu wbudowanej w system Android klasy MediaPlayer. Dokumentacja sugeruje mi, że powinno to być tak proste, jak:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(URL_OF_FILE);
mp.prepare();
mp.start();
Jednak wielokrotnie otrzymuję następujące informacje. Próbowałem też różnych adresów URL. Proszę nie mów mi, że przesyłanie strumieniowe nie działa na plikach mp3.
E/PlayerDriver( 31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
W/PlayerDriver( 31): PVMFInfoErrorHandlingComplete
E/MediaPlayer( 198): error (1, -4)
E/MediaPlayer( 198): start called in state 0
E/MediaPlayer( 198): error (-38, 0)
E/MediaPlayer( 198): Error (1,-4)
E/MediaPlayer( 198): Error (-38,0)
Każda pomoc doceniona, dzięki S.
android
mp3
android-mediaplayer
audio-streaming
Pandalover
źródło
źródło
Odpowiedzi:
prosty odtwarzacz multimedialny z przykładem przesyłania strumieniowego. dla części XML potrzebujesz jednego przycisku z identyfikatorem button1 i dwóch obrazów w folderze do rysowania z nazwą button_pause i button_play i nie zapomnij dodać pozwolenia internetowego w swoim manifeście
public class MainActivity extends Activity { private Button btn; /** * help to toggle between play and pause. */ private boolean playPause; private MediaPlayer mediaPlayer; /** * remain false till media is not completed, inside OnCompletionListener make it true. */ private boolean intialStage = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.button1); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); btn.setOnClickListener(pausePlay); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } private OnClickListener pausePlay = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub // TODO Auto-generated method stub if (!playPause) { btn.setBackgroundResource(R.drawable.button_pause); if (intialStage) new Player() .execute("http://www.virginmegastore.me/Library/Music/CD_001214/Tracks/Track1.mp3"); else { if (!mediaPlayer.isPlaying()) mediaPlayer.start(); } playPause = true; } else { btn.setBackgroundResource(R.drawable.button_play); if (mediaPlayer.isPlaying()) mediaPlayer.pause(); playPause = false; } } }; /** * preparing mediaplayer will take sometime to buffer the content so prepare it inside the background thread and starting it on UI thread. * @author piyush * */ class Player extends AsyncTask<String, Void, Boolean> { private ProgressDialog progress; @Override protected Boolean doInBackground(String... params) { // TODO Auto-generated method stub Boolean prepared; try { mediaPlayer.setDataSource(params[0]); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub intialStage = true; playPause=false; btn.setBackgroundResource(R.drawable.button_play); mediaPlayer.stop(); mediaPlayer.reset(); } }); mediaPlayer.prepare(); prepared = true; } catch (IllegalArgumentException e) { // TODO Auto-generated catch block Log.d("IllegarArgument", e.getMessage()); prepared = false; e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block prepared = false; e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block prepared = false; e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block prepared = false; e.printStackTrace(); } return prepared; } @Override protected void onPostExecute(Boolean result) { // TODO Auto-generated method stub super.onPostExecute(result); if (progress.isShowing()) { progress.cancel(); } Log.d("Prepared", "//" + result); mediaPlayer.start(); intialStage = false; } public Player() { progress = new ProgressDialog(MainActivity.this); } @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); this.progress.setMessage("Buffering..."); this.progress.show(); } } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); if (mediaPlayer != null) { mediaPlayer.reset(); mediaPlayer.release(); mediaPlayer = null; } }
źródło
Android MediaPlayer nie obsługuje natywnie strumieniowego przesyłania plików MP3 do wersji 2.2. W starszych wersjach systemu operacyjnego wydaje się, że natywnie strumieniuje tylko 3GP. Możesz wypróbować kod pocketjourney, chociaż jest stary (jest tutaj nowa wersja ) i miałem problem z uczynieniem go lepkim - zacinał się, gdy uzupełniał bufor.
Aplikacja NPR News na Androida jest open source i wykorzystuje lokalny serwer proxy do obsługi strumieniowego przesyłania plików MP3 w wersjach systemu operacyjnego wcześniejszych niż 2.2. Możesz zobaczyć odpowiedni kod w liniach 199-216 (r94) tutaj: http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/ PlaybackService.java?r=7cf2352b5c3c0fbcdc18a5a8c67d836577e7e8e3
A to jest klasa StreamProxy: http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java?r=e4984187f45c39a54ea6c88f71197762dbe10e72
Aplikacja NPR również czasami wyświetla komunikat „Error (-38, 0)” podczas przesyłania strumieniowego. Może to być problem z wątkami lub problem ze zmianą sieci. Sprawdź aktualizacje w narzędziu do śledzenia problemów .
źródło
Wydaje mi się, że próbujesz bezpośrednio odtworzyć plik .pls lub coś podobnego.
wypróbuj to:
1: kod
mediaPlayer = MediaPlayer.create(this, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3")); mediaPlayer.start();
2: plik .pls
Ten adres URL pochodzi z BBC jako przykład. Był to plik .pls, z którym pobrałem w systemie Linux
wget http://foo.bar/file.pls
a potem otworzyłem za pomocą vima (użyj swojego ulubionego edytora;) i zobaczyłem prawdziwe adresy URL wewnątrz tego pliku. Niestety nie wszystkie pliki .pl są takie jak zwykły tekst.
Czytałem, że 1.6 nie obsługuje przesyłania strumieniowego mp3 przez http, ale właśnie przetestowałem kod obove z Androidem 1.6 i 2.2 i nie miałem żadnego problemu.
powodzenia!
źródło
Posługiwać się
mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaplayer.prepareAsync(); mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaplayer.start(); } });
źródło
Miałem ten sam błąd co Ty i okazało się, że z kodem nie ma nic złego. Problem polegał na tym, że serwer WWW wysyłał nieprawidłowy nagłówek Content-Type.
Wypróbuj wireshark lub coś podobnego, aby zobaczyć, jaki typ zawartości wysyła serwer sieciowy.
źródło
Szukam moich projektów:
źródło
Brak wywołania mp.start z OnPreparedListener, aby uniknąć stanu zerowego w dzienniku.
źródło