2013-03-21 47 views
0

我有一個遠程音頻文件的Url。我需要爲跟蹤詳細信息的適配器列表構建數據。這是部分代碼是否可以在不下載的情況下獲得遠程音頻文件的持續時間?

Log.d("audioURL", audio.getUrl()); 
    MediaPlayer tmpMedia; 
    tmpMedia = MediaPlayer.create(getContext(), Uri.parse(audio.getUrl())); 
    holder.txtDuration.setDuration(tmpMedia.getDuration()/1000); 
    tmpMedia.release(); 

但它工作得太慢了。 LogCat寫這樣的事情:

15:05:51.783: D/audioURL(776): http://cs4859.vk.me/u14195999/audios/0cbd695ddf50.mp3 
15:05:51.783: D/MediaPlayer(776): Couldn't open file on client side, trying server side 
15:05:53.813: D/audioURL(776): http://cs4859.vk.me/u14195999/audios/0cbd695ddf50.mp3 
15:05:53.823: D/MediaPlayer(776): Couldn't open file on client side, trying server side 
15:05:55.373: D/audioURL(776): http://cs4859.vk.me/u14195999/audios/0cbd695ddf50.mp3 
15:05:55.383: D/MediaPlayer(776): Couldn't open file on client side, trying server side 
15:05:58.143: D/audioURL(776): http://cs1626.vk.me/u149968/audios/04298447cd3c.mp3 
15:05:58.153: D/MediaPlayer(776): Couldn't open file on client side, trying server side 

...等等。所以,我的約30首歌曲的播放列表初始化時間約爲7分鐘。

我想,MediaPlayer類方法getDuration()順序下載這些軌道(或其中的一些部分)來獲得它們的持續時間。

有沒有辦法快速獲得這些持續時間,而無需下載曲目?

Halim Qarroum,這似乎是一個正確的方式,但我有一些麻煩MediaMetadataRetriever類。

這裏是我上面的代碼:

if (android.os.Build.VERSION.SDK_INT < 10){ 
     holder.txtDuration.setDuration(audio.getTrackDuration()); 
    } else { 
     MediaMetadataRetriever mRetriever = new MediaMetadataRetriever(); 
     Log.d("URI", Uri.parse(audio.getUrl()).toString()); 
     mRetriever.setDataSource(getContext(), Uri.parse(audio.getUrl())); 
     String s = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); 
     holder.txtDuration.setDuration(Long.parseLong(s)); 
     mRetriever.release(); 
    } 

申請終止mRetriever.setDataSource(getContext(), Uri.parse(audio.getUrl()));因爲IllegalArgumentExceptionaudio.getURl()字符串是http://cs4859.vk.me/u14195999/audios/134dfe90d1ec.mp3

爲什麼會發生異常?

回答

4

Dheeb貼好詳細的解答。但是,ID3 tags並不總是出現在mp3文件中。您可以使用Android框架附帶的MediaMetadataRetriever類,而不是查找這些標籤,這會迫使您將此方法限制爲mp3文件。

這個類可以給你幾個來自某些類型的音頻/視頻文件的元數據,其中一個信息是持續時間。這種方法的優勢在於標準,因爲它附帶Android SDK,並且不限於一種音頻格式。

從Android開發相關的頁面:

MediaMetadataRetriever類提供 從輸入的媒體文件檢索框和元數據的統一接口。

使用這個類的代碼簡單的例子:

MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 
retriever.setDataSource(your_data_source); 
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); 
long timeInmillisec = Long.parseLong(time); 
long duration = timeInmillisec/1000; 
long hours = duration/3600; 
long minutes = (duration - hours * 3600)/60; 
long seconds = duration - (hours * 3600 + minutes * 60); 
+0

聽起來不錯,但出現異常(見上面我的評論在我的崗位 – Carlos 2013-03-22 11:10:28

+0

我編輯我的例子,嘗試用以上,它應該工作。 – 2013-03-22 11:27:50

+0

第二行發生異常mRetriever.setDataSource(getContext(),Uri.parse(audio.getUrl())); 此行引發IllegalArgumentException。根據類的描述,setDataSource(Context上下文,Uri uri )方法拋出IllegalArgumentException如果Uri無效,但我的Uri似乎是有效的 - 例如http://cs4859.vk.me/u14195999/audios/134dfe90d1ec.mp3 – Carlos 2013-03-22 11:37:31

4

我會假設mp3,因爲「音頻文件」是一個大括號的短語。

方法1:取ID3標籤

變體1:第三方庫

你需要看看在MP3文件的ID3標籤。 除非你跟蹤你想要的其他元數據。

要明確獲取文件的軌道長度,您需要查看ID3元數據標記,特別是標記的'TRCK'框架。

要僅下載ID3標籤部件,必須首先下載文件的ID3標頭部分。

website包含有關ID3標籤格式的非常具體的信息。您需要查看ID3標籤的版本號,然後,您需要查找有關ID3標籤有多長時間的信息。然後,您必須下載整體標籤,因爲這些框架沒有任何特定的順序。

然後,您應該可以使用第三方庫來查找TRCK幀及其數據。

變2:HTTP哈克

對於ID3v2標籤,搶在文件的開始。 (ID3v2幀可能位於其他地方,但實際上它們總是在那裏。)您無法預知標籤將會提前多長時間。對於純文本標籤,您可能會在第一個512-1024字節中找到所需的信息。不幸的是,越來越多的MP3已經嵌入了'專輯封面'的照片,這可能會更長;嘗試挑選一個ID3庫,它將優雅地忽略截斷的ID3信息。

ID3v1標籤位於文件的末尾。再次,你不能說出他們將會有多久。當然,您事先並不知道該文件是否具有ID3v1標籤,ID3v2標籤,或者兩者都不具備。一般來說,這些天ID3v2是一個更好的選擇。

通讀HTTP文件的一部分,你需要的Range頭。這在任何地方都不被支持。

方法2:估計

文件大小,你可以使用HTTP HEAD請求得到。無需獲取整個文件就無法獲得播放時間的持續時間,以秒爲單位。你可以猜想,通過獲取前幾個MP3幀,看他們的比特率,並假設文件的其餘部分具有相同的比特率,但考慮到可變比特率編碼的普及,這種可能性將接近於準確相當低。

ID3標籤可以在理論上包含可能讓你猜 長度更好,在ASPI和ETCO標籤的信息。但在實踐中 這些很少出現。

現金

現金去上這樣各種各樣的作者和interwebs着,當然在我的腦海一樓的傢伙。

相關問題