Android 2.2 MediaPlayer 在一个 SHOUTcast URL 上工作正常,但在另一个 URL 上却不行

标签 android media-player uri audio-streaming shoutcast

请查看我用于流式传输 shoutcast 流的代码,它适用于一个 URL,但不适用于另一个 URL。

这个有效:

Uri myUri = Uri.parse("http://fr3.ah.fm:9000/");

但这个不是:

Uri myUri =  Uri.parse("http://someOtherURL");

简单音乐流.java

import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class SimpleMusicStream extends Activity implements
  MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener,
  MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener {

 private String TAG = getClass().getSimpleName();
 private MediaPlayer mp = null;

 private Button play;
 private Button pause;
 private Button stop;

 @Override
 public void onCreate(Bundle icicle) {
  super.onCreate(icicle);
  setContentView(R.layout.main);

  play = (Button) findViewById(R.id.play);
  pause = (Button) findViewById(R.id.pause);
  stop = (Button) findViewById(R.id.stop);

  play.setOnClickListener(new View.OnClickListener() {
   public void onClick(View view) {
    play();
   }
  });

  pause.setOnClickListener(new View.OnClickListener() {
   public void onClick(View view) {
    pause();
   }
  });

  stop.setOnClickListener(new View.OnClickListener() {
   public void onClick(View view) {
    stop();
   }
  });
 }

 private void play() {
  Uri myUri = Uri.parse("http://fr3.ah.fm:9000/");
  try {
   if (mp == null) {
    this.mp = new MediaPlayer();
   } else {
    mp.stop();
    mp.reset();
   }
   mp.setDataSource(this, myUri); // Go to Initialized state
   mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
   mp.setOnPreparedListener(this);
   mp.setOnBufferingUpdateListener(this);

   mp.setOnErrorListener(this);
   mp.prepareAsync();

   Log.d(TAG, "LoadClip Done");
  } catch (Throwable t) {
   Log.d(TAG, t.toString());
  }
 }

 @Override
 public void onPrepared(MediaPlayer mp) {
  Log.d(TAG, "Stream is prepared");
  mp.start();
 }

 private void pause() {
  mp.pause();
 }

 private void stop() {
  mp.stop();

 }

 @Override
 public void onDestroy() {
  super.onDestroy();
  stop();

 }

 public void onCompletion(MediaPlayer mp) {
  stop();
 }

 public boolean onError(MediaPlayer mp, int what, int extra) {
  StringBuilder sb = new StringBuilder();
  sb.append("Media Player Error: ");
  switch (what) {
  case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
   sb.append("Not Valid for Progressive Playback");
   break;
  case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
   sb.append("Server Died");
   break;
  case MediaPlayer.MEDIA_ERROR_UNKNOWN:
   sb.append("Unknown");
   break;
  default:
   sb.append(" Non standard (");
   sb.append(what);
   sb.append(")");
  }
  sb.append(" (" + what + ") ");
  sb.append(extra);
  Log.e(TAG, sb.toString());
  return true;
 }

 public void onBufferingUpdate(MediaPlayer mp, int percent) {
  Log.d(TAG, "PlayerService onBufferingUpdate : " + percent + "%");
 }

    }

主.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <Button
  android:text="Play"
  android:id="@+id/play"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"></Button>
 <Button
  android:text="Pause"
  android:id="@+id/pause"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"></Button>
 <Button
  android:text="Stop"
  android:id="@+id/stop"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"></Button>
</LinearLayout>

Log-cat 显示错误:

NuHTTPDataSource(33): Server did not give us the content length!

Media Player Error: Unknown (1) -2147483648
Media Player Error: Unknown (1) -1002

有人可以帮我解决吗?

编辑:

只是为了与大家分享,我们的current code works with Android 2.1 & minor versions, but not works with Android 2.2 or higher .

谢谢

最佳答案

原生支持从 Android 2.2 开始的 Shoutcast mp3 流式传输。

在 2.2 以下,如果不在流端使用代理或在设备上使用流代理类来捕获流并将其传递给音频播放器,Android 操作系统无法在 native 播放 shoutcast 流,就像 NPR 一样。

不直接支持音频/aacp 流。为此,您可以使用 ffmpeg、opencore 或 faad2 库将其解码为 PCM 并使用 audiotrack 播放。 Reference

关于Android 2.2 MediaPlayer 在一个 SHOUTcast URL 上工作正常,但在另一个 URL 上却不行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8681550/

相关文章:

android - 如何在 Activity 和 Fragment 之间传递对象

c# - 在C#.NET Dim语句中创建共鸣板不会变成蓝色

html - 数据 URI 的用途是什么?

android - Soloud + OpenSLES 后端,非 Activity 音轨

android - 无法找到 DialogFragment 中的 NavController

iphone - 使用 MPVolumeView 后如何重新打开系统音量覆盖?

android - 当用户恢复 Activity 时再次播放声音

java - Android 4.3 中我的 ContentProvider 有什么问题?

java - 无法转换 .toURI() 的 URL 示例?

android - 带 SnackBar 和 CoordinatorLayout 的 FloatingActionButton 不适用于混淆器