Android 2.2 MediaPlayer 与一个 SHOUTcast URL 一起工作正常,但与另一个不兼容

Posted

技术标签:

【中文标题】Android 2.2 MediaPlayer 与一个 SHOUTcast URL 一起工作正常,但与另一个不兼容【英文标题】:Android 2.2 MediaPlayer is working fine with one SHOUTcast URL but not with the other one 【发布时间】:2012-01-30 16:18:33 【问题描述】:

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

这个有效:

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

但不是这个:

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

SimpleMusicStream.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 + "%");
 

    

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_
 android:layout_>
 <Button
  android:text="Play"
  android:id="@+id/play"
  android:layout_
  android:layout_></Button>
 <Button
  android:text="Pause"
  android:id="@+id/pause"
  android:layout_
  android:layout_></Button>
 <Button
  android:text="Stop"
  android:id="@+id/stop"
  android:layout_
  android:layout_></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。

谢谢

【问题讨论】:

基于一些快速的谷歌搜索,它的音频编码 audio/aacp 也让其他人有些头疼。 另一个非常好的讨论可以在这里找到:***.com/questions/1650983/… 帮助我***.com/questions/16264225/… 你能和我分享一下 ShoutCast URL Streaming Andriod 的源代码吗? 【参考方案1】:

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

在 2.2 以下,Android 操作系统无法在不使用流端代理或设备上的流代理类来捕获流并将其传递给音频播放器的情况下原生播放直播流,就像NPR 所做的那样。

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

【讨论】:

Shoutcast 流从 2.2 开始受支持,我知道但为什么它与 url 之一一起工作而另一个不工作? 正如我所说,Android 2.2 仅支持 Shoutcast mp3 流。您的一个网址是内容类型“audio/aacp”,我猜它不会播放,另一个是“audio/mpeg”,它在 android 2.2 及更高版本中受支持。对于 AACP,您要么将内容保存在文件中然后播放,要么使用我提到的任何解码库..但在使用时还要考虑法律问题。 @SanthoshShetigar 帮我解决这个问题***.com/questions/16264225/…【参考方案2】:

问题在于音频/aacp 中的编码

问题是 Android 媒体播放器没有正确渲染 aacp。您将不得不尝试其他编解码器或编写自己的解码器。

【讨论】:

请帮助我***.com/questions/16264225/…@the100rabh【参考方案3】:

Mediaplayer 仅支持these formats,如 android 开发者文档中所述。

有些流可能会满足这一点,但有些则不会

【讨论】:

【参考方案4】:

有一个Freeware Advanced Audio (AAC) Decoder for Android。您可以将其用于帮助和指导,或使用其中的 Multiplayer 类来播放 aac 音频。里面有一个示例应用程序和库,可以帮助您理解。我已经使用这个库来播放 Shoutcast 在线流。我使用库中提供的 Multiplayer 类播放 AAC 和 MP3

希望对你有帮助

【讨论】:

【参考方案5】:

最后,我得到了一个简单的直播应用程序。 试试this。只需更改 StreamService.java 中的流式传输 url。

【讨论】:

以上是关于Android 2.2 MediaPlayer 与一个 SHOUTcast URL 一起工作正常,但与另一个不兼容的主要内容,如果未能解决你的问题,请参考以下文章

Android MediaPlayer 在 Android 4.2.2 上播放视频时闪烁

在使用 Android 2.2 的 HTC Desire 上使用 Android MediaPlayer 进行流式传输时的奇怪行为

[OpenGL]从零开始写一个Android平台下的全景视频播放器——2.2 使用GLSurfaceView和MediaPlayer播放一个平面视频(中)

Android MediaPlayer+SurfaceView播放视频(附Demo)

Android MediaPlayer:同时播放多个声音。我的代码是

Android MediaPlayer 播放音频