使用MediaPlayer从Android中的URLstream式传输audio?
我一直在尝试通过使用内置MediaPlayer类的Android来传输mp3。 这个文档会告诉我,这应该和以下一样简单:
MediaPlayer mp = new MediaPlayer(); mp.setDataSource(URL_OF_FILE); mp.prepare(); mp.start();
但是我反复得到以下几点。 我也尝试了不同的url。 请不要告诉我,stream式传输不适用于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)
任何帮助非常感谢,谢谢S
简单的媒体播放器与stream例子。对于XML部分,你需要一个button与ID button1和你的可绘制文件夹中的名字button_pause和button_play两个图像,请不要忘记在您的清单中添加Internet权限。
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; } }
直到2.2之前,Android MediaPlayer本身不支持MP3的stream式传输。 在操作系统的旧版本中,它似乎只是本地stream3GP。 你可以尝试pocketjourney代码,虽然它是旧的(这里有一个新的版本 ),我很难使它粘稠 – 它会填充缓冲区时会结结巴巴。
Android的NPR新闻应用程序是开源的,使用本地代理服务器来处理2.2版本之前的操作系统版本中的MP3stream。 你可以在这里看到199-216行(r94)的相关代码: http : //code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/ PlaybackService.java?r=7cf2352b5c3c0fbcdc18a5a8c67d836577e7e8e3
这是StreamProxy类: http : //code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java? r=e4984187f45c39a54ea6c88f71197762dbe10e72
NPR应用程序在stream式传输时有时也会遇到“错误(-38,0)”。 这可能是线程问题或networking更改问题。 检查问题跟踪器的更新 。
我想你正在尝试直接播放.pls或类似的东西。
试试这个:
1:代码
mediaPlayer = MediaPlayer.create(this, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3")); mediaPlayer.start();
2:.pls文件
这个URL来自BBC,就是一个例子。 这是一个.pls文件,我在linux下载
wget http://foo.bar/file.pls
然后我用vim打开(使用你最喜欢的编辑器),我已经看到了这个文件中的真实URL。 不幸的是,并不是所有的.pls都是纯文本的。
我读过1.6不支持通过HTTPstream媒体mp3,但是,我刚刚testing了Android 1.6和2.2的obove代码,并没有任何问题。
祝你好运!
我有和你一样的错误,结果代码没有错。 问题是Web服务器发送了错误的Content-Type头。
尝试wireshark或类似的东西,看看什么内容types的networking服务器发送。
使用
mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaplayer.prepareAsync(); mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaplayer.start(); } });
没有与OnPreparedListener调用mp.start以避免零状态我的日志..
看我的项目:
- https://github.com/master255/ImmortalPlayer http / FTP支持,一个线程读取,发送并保存到caching数据。 最简单的方法和最快的工作。 复杂的逻辑 – 最好的方法!
- https://github.com/master255/VideoViewCache简单的videocaching。; 两个线程用于播放和保存数据。 坏的逻辑,但如果你需要然后使用这个。