2017-06-07 47 views
6

我知道Android的MediaPlayer是件好事。它允許我們播放本地文件以及媒體流。它是很容易使用(只是舉例):如何使用自定義android.media.MediaDataSource和android.media.MediaPlayer?

MediaPlayer mediaPlayer = new MediaPlayer(); 
mediaPlayer.setDataSource("http://streaming.shoutcast.com/80sPlanet"); // this steam broadcasts audio/mpeg 
mediaPlayer.prepareAsync(); 
mediaPlayer.start(); 

有可能通過與不同的參數調用重載setDataSource()設置不同類型的數據源的。 而有此功能的一個有趣的原型:

void setDataSource(MediaDataSource dataSource) 

看起來它可能與自己的實現完全覆蓋DataSource。和它的作品確實是:

import android.media.MediaDataSource; 
import java.io.BufferedInputStream; 
import java.io.IOException; 
import java.net.URL; 
import java.net.HttpURLConnection; 

public class UrlMediaDataSource extends MediaDataSource { 
    URL url; 
    HttpURLConnection connection; 
    BufferedInputStream stream; 

    public UrlMediaDataSource(URL url) throws IOException { 
     this.url = url; 
     connection = (HttpURLConnection) url.openConnection(); 
    } 

    @Override 
    public long getSize() { 
     return 0; 
    } 

    @Override 
    public int readAt(long position, byte[] buffer, int offset, int size) throws IOException { 
     if (stream == null) 
      stream = new BufferedInputStream(connection.getInputStream()); 
     return stream.read(buffer, offset, size); 
    } 

    @Override 
    public void close() throws IOException { 
     stream.close(); 
     stream = null; 
     connection.disconnect(); 
     connection = null; 
    } 
} 

,並在主代碼:

UrlMediaDataSource dataSource = new UrlMediaDataSource(new URL("http://streaming.shoutcast.com/80sPlanet")); 
mediaPlayer.setDataSource(dataSource); 

是的,這工作正常。但是,如果我嘗試播放音頻/ aacp流(例如:「http://111.223.51.8:8005」 - 它是「COOLfahrenheit 93」收音機),播放器不播放。 logcat的跟蹤:

06-07 23:26:01.680 1352-1147/? E/GenericSource: Failed to init from data source! 
06-07 23:26:01.681 1352-1093/? D/NuPlayerDriver: notifyListener_l(0xf3e051e0), (100, 1, -2147483648) 
06-07 23:26:01.735 1352-2013/? D/NuPlayerDriver: reset(0xf3e051e0) 
06-07 23:26:01.735 1352-2013/? D/NuPlayerDriver: notifyListener_l(0xf3e051e0), (8, 0, 0) 
06-07 23:26:01.736 1352-1093/? D/NuPlayerDriver: notifyResetComplete(0xf3e051e0) 

雖然,URL工作正常(音樂劇),當沒有自定義MediaDataSource用於:

mediaPlayer.setDataSource("http://111.223.51.8:8005"); 

有誰知道管理這個正確的方式? 只是不建議我直接使用URL - 我需要定製MediaDataSource才能訪問流的原始數據。

回答

2

主要的一點是MediaPlayer不播放音頻/MPEG(兩種方式 - 通過URL,並通過自定義MediaDataSource),但音頻/ AACP流只能通過網址爲DataSource回放。

因此,讓我們來了解引擎蓋下發生了什麼。

你逝去的URL作爲數據源,正在執行然後this檢查:

 

    if ("file".equals(scheme)) { 
     path = uri.getPath(); 
    } else if (scheme != null) { 
     // handle non-file sources 
     nativeSetDataSource(
      MediaHTTPService.createHttpServiceBinderIfNecessary(path), 
      path, 
      keys, 
      values); 
     return; 
    } 
 

MediaPlayerusesMediaHTTPService類,which is responsiblehttphttpswidevine協議提供數據。 MediaHTTPService內部使用MediaHTTPConnection,這需要所有繁重的工作與這種類型的流。不幸的是,這些API尚未公開(但是),但您可以看到如何在MediaHTTPConnection源(尤其是seekTo method)中完成連接建立。因此,您向MediaPlayer提供的自定義數據源應近似描述類實現的邏輯。

+0

謝謝你的關注。你對'getSize()'返回-1的猜測是公平的,但它不能解決問題(在這種情況下,LogCat跟蹤是相同的)。重點是'MediaPlayer'_does_ playback ** audio/mpeg **(通過URL和通過自定義的'MediaDataSource'),但是** audio/aacp **流只能通過URL作爲DataSource播放...我只是不知道在哪裏挖掘.. – Eugene

+0

我明白你的意思。更新一些信息。 – azizbekian

+0

我想,我可以繞過這個「錯誤」(或「功能」或「現象」,請不要介意)通過使用'MediaCodec' +'AudioTrack',而不是'MediaPlayer',但該死的Android不會讓我做這件事:HTTPS: //stackoverflow.com/questions/45288285/mediaextractor-does-not-understand-audio-aacp-streams :( – Eugene

相關問題