2009-10-30 204 views
19

據我所知,如果將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

回答

0

這是在黑暗中拍攝的一張照片,但我已經看到與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

5

工作(#)允許您播放網絡中的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

-2

嘗試 -

1)MP.prepareAsync()

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

0

我寫了一篇關於我使用的音樂播放器我​​正在開發一個基於雲的解決方案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

2

有一個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

3

有一個演示如何同時處理本地文件或在線/流源音頻open source OpenMXPlayer。它不僅支持AAC,還支持其他常用格式。

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

希望這提供了一個很好的出發點,對任何人都需要一個快速和輕鬆自由的音頻播放器的實現。

1

我也試過了,但是我找不到解決方案!

在最後的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-我可以播放從串流(視頻和音頻)的東西!

讓我知道如果您需要幫助實施它! :)