使用Android流式传输AAC音频

问题描述:

据我所知,如果将Android编码为MPEG-4或3GPP,Android将只播放AAC格式的音频。使用Android流式传输AAC音频

我可以播放以M4A格式编码的AAC音频,但它在从服务器获取时会失败。

以下工作,因为m4a文件在res/raw目录中保存在本地。

MediaPlayer mp = MediaPlayer.create(this, R.raw.*file*); 
mp.start(); 

以下不起作用。 (但与MP3的)。

Uri uri = Uri.parse("http://*example.com*/blah.m4a"); 
MediaPlayer mp = MediaPlayer.create(this, uri); 
mp.start(); 

任何人都可以说明为什么它失败时,m4a音频文件不是本地?

这里的(一些)的错误...

ERROR/PlayerDriver(542): Command PLAYER_INIT completed with an error or info UNKNOWN PVMFStatus 
ERROR/MediaPlayer(769): error (200, -32) 
WARN/PlayerDriver(542): PVMFInfoErrorHandlingComplete 
DEBUG/MediaPlayer(769): create failed: 
DEBUG/MediaPlayer(769): java.io.IOException: Prepare failed.: status=0xC8 
DEBUG/MediaPlayer(769):  at android.media.MediaPlayer.prepare(Native Method) 
DEBUG/MediaPlayer(769):  at android.media.MediaPlayer.create(MediaPlayer.java:530) 
DEBUG/MediaPlayer(769):  at android.media.MediaPlayer.create(MediaPlayer.java:507) 
... 

我针对SDK 1.6。

+0

你在编码与文件格式混淆。 AAC是一种音频编码格式。 M4A是位于AAC数据周围的文件类型或包。 3GPP类似,但可以包含其他类型的编码音频。看到这里http://developer.android.com/guide/appendix/media-formats.html和这里http://en.wikipedia.org/wiki/M4a。 – greg7gkb 2010-09-28 18:28:28

+0

的确,我应该将3GPP和M4A描述为AAC音频的“容器”。我认为* M4A只能用于静态文件,而3GPP只能使用RTSP而不是HTTP进行流式传输?这会导致HTTP流式传输出现问题。纠正我,如果我错了... – bdls 2010-09-30 21:40:50

这是在黑暗中拍摄的一张照片,但我已经看到与flash播放器类似的行为,它实际上忽略了文件名,并且仅依赖于服务器发送的MIME类型。任何想法什么标题被发送从example.com?您可能想要尝试将blah.m4a包装在可设置标题的页面中,然后对二进制数据进行流式处理。给这些类型的射击和社会各界希望了解的是什么在起作用确认:

音频/ MPEG 音频/ MP4A 音频/ MP4A-个大气压 音频/ AAC 音频/ X-AAC

+0

一个很好的建议 - 谢谢。不幸的是,我没有尝试尝试一组可能的内容类型。作为参考,我列出了那些在下面不起作用的。它仍然有可能与HTTP头文件有关 - 或者可能是因为它可以提供什么东西非常挑剔。 '音频/ M4A音频/ AAC音频/ AACP音频/ X-AAC音频/ MPEG音频/ MP4A音频/ MP4A-LATM音频/ mp4' – bdls 2009-11-04 18:18:42

+1

我确实遇到了问题这一点。对于我们的流媒体目的,MediaPlayer不会播放流媒体文件,除非Http头内容类型设置正确。有趣的是,内容长度并不是必需的。 – greg7gkb 2010-09-28 18:30:12

工作(#)允许您播放网络中的M4A文件(以及其他容器中的AAC文件,如MP4 & 3GP)。它只是下载文件并从缓存中播放。

private File mediaFile; 

private void playAudio(String mediaUrl) { 
    try { 
     URLConnection cn = new URL(mediaUrl).openConnection(); 
     InputStream is = cn.getInputStream(); 

     // create file to store audio 
     mediaFile = new File(this.getCacheDir(),"mediafile"); 
     FileOutputStream fos = new FileOutputStream(mediaFile); 
     byte buf[] = new byte[16 * 1024]; 
     Log.i("FileOutputStream", "Download"); 

     // write to file until complete 
     do { 
      int numread = is.read(buf); 
      if (numread <= 0) 
       break; 
      fos.write(buf, 0, numread); 
     } while (true); 
     fos.flush(); 
     fos.close(); 
     Log.i("FileOutputStream", "Saved"); 
     MediaPlayer mp = new MediaPlayer(); 

     // create listener to tidy up after playback complete 
     MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() { 
      public void onCompletion(MediaPlayer mp) { 
       // free up media player 
       mp.release(); 
       Log.i("MediaPlayer.OnCompletionListener", "MediaPlayer Released"); 
      } 
     }; 
     mp.setOnCompletionListener(listener); 

     FileInputStream fis = new FileInputStream(mediaFile); 
     // set mediaplayer data source to file descriptor of input stream 
     mp.setDataSource(fis.getFD()); 
     mp.prepare(); 
     Log.i("MediaPlayer", "Start Player"); 
     mp.start(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+5

好主意,但当然这需要整个文件在可以播放之前先下载。可能对某些情况有用,但显然不适合作为流式传输解决方案。 – greg7gkb 2010-09-28 18:31:08

+0

确实如此,尽管此代码可以构建于使用本地文件或文件作为临时循环缓冲区来创建流式解决方案。不幸的是,MediaPlayer无法从InputStream接收,或者您可以以标准方式执行循环缓冲区。 – bdls 2010-09-30 21:34:43

尝试 -

1)MP.prepareAsync()

2)onPrepared() { mp.start() }

我写了一篇关于我使用的音乐播放器我​​正在开发一个基于云的解决方案SMaL公司博客。它基于尚未推出的年轻Android云服务(ACS)项目,但它仍然展示了使用基于云的转码技术来传输任何媒体文件的潜在解决方案。看看:http://positivelydisruptive.blogspot.com/2010/08/streaming-m4a-files-using-android-cloud.html

乔尔

+0

嗨,Joel。这是一个可能的选择,但是它最终将流式传输MP3放在了其他格式(较低比特率下更高的感知质量)上,从而消除了AAC的优势。 – bdls 2010-08-10 15:52:52

有一个Freeware Advanced Audio (AAC) Decoder for Android。你可以使用它来获得帮助和指导,或者使用它来使用Multiplayer类来播放aac音频。这里面一个示例应用程序和库,以帮助您了解

希望这有助于

+0

它被写为“请注意,使用此软件可能需要支付专利使用费。在开始构建衍生作品之前,您需要考虑此问题。我们不保证或以任何方式保障您的专利权利!对您自己的行为负责! 欲了解有关AAC专利的更多信息,请访问http://www.vialicensing.com/licensing/aac-fees.aspx“ =>不确定这是一个好主意使用这个库! – 2014-06-25 09:53:34

有一个演示如何同时处理本地文件或在线/流源音频open source OpenMXPlayer。它不仅支持AAC,还支持其他常用格式。

它背后的想法是使用Android 4.1中引入的MEdiaCodec API。

希望这提供了一个很好的出发点,对任何人都需要一个快速和轻松*的音频播放器的实现。

我也试过了,但是我找不到解决方案!

在最后的Google I/O中,我看到了一些对我有所帮助的东西。它是从MediaPlayer扩展并改进了很多东西!看一看。

EXOPLAYER可以帮助你LOT

检查这部分示例:

private static final int BUFFER_SEGMENT_SIZE = 64 * 1024; 
private static final int BUFFER_SEGMENT_COUNT = 256; 
... 

// String with the url of the radio you want to play 
String url = getRadioUrl(); 
Uri radioUri = Uri.parse(url); 
// Settings for exoPlayer 
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE); 
String userAgent = Util.getUserAgent(context, "ExoPlayerDemo"); 
DataSource dataSource = new DefaultUriDataSource(context, null, userAgent); 
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
radioUri, dataSource, allocator, BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT); 
audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); 
// Prepare ExoPlayer 
exoPlayer.prepare(audioRenderer); 

EXOPLAYER-我可以播放从串流(视频和音频)的东西!

让我知道如果您需要帮助实施它! :)