我使用了和 NPR 项目使用的相同的 StreamProxy -
https://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java。
因此,它可以得到原始音频流:
String url = request.getRequestLine().getUri();
HttpResponse realResponse = download(url);
...
InputStream data = realResponse.getEntity().getContent();
从此流向客户端套接字进行写入:
byte[] buff = new byte[1024 * 50];
while (isRunning && (readBytes = data.read(buff, 0, buff.length)) != -1) {
client.getOutputStream().write(buff, 0, readBytes);
}
您可以从上面的链接中获取整个代码。
最后,他们如何初始化播放器(PlaybackService):
if (stream && sdkVersion < 8) {
if (proxy == null) {
proxy = new StreamProxy();
proxy.init();
proxy.start();
}
String proxyUrl = String.format("http://127.0.0.1:%d/%s", proxy.getPort(), url);
playUrl = proxyUrl;
}
...
mediaPlayer.setDataSource(playUrl);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepareAsync();
所以他们检查SDK版本。但是如果我省略这个检查并且也使用代理来处理SDK 8,那么我会得到一个异常。奇怪的是MediaPlayer甚至不尝试读取流:
12-30 15:09:41.576: DEBUG/StreamProxy(266): downloading...
12-30 15:09:41.597: DEBUG/StreamProxy(266): reading headers
12-30 15:09:41.597: DEBUG/StreamProxy(266): headers done
12-30 15:09:41.647: DEBUG/StreamProxy(266): writing to client
12-30 15:09:41.857: INFO/AwesomePlayer(34): mConnectingDataSource->connect() returned - 1007
12-30 15:09:41.857: ERROR/MediaPlayer(266): error (1, -1007)
12-30 15:09:41.867: ERROR/MediaPlayer(266): Error (1,-1007)
12-30 15:09:41.867: WARN/AudioService(266): onError(1, -1007)
12-30 15:09:41.867: WARN/AudioService(266): MediaPlayer refused to play current item. Bailing on prepare.
12-30 15:09:41.867: WARN/AudioService(266): onComplete()
12-30 15:09:42.097: ERROR/StreamProxy(266): Connection reset by peer
java.net.SocketException: Connection reset by peer
at org.apache.harmony.luni.platform.OSNetworkSystem.writeSocketImpl(Native Method)
at org.apache.harmony.luni.platform.OSNetworkSystem.write(OSNetworkSystem.java:723)
at org.apache.harmony.luni.net.PlainSocketImpl.write(PlainSocketImpl.java:578)
at org.apache.harmony.luni.net.SocketOutputStream.write(SocketOutputStream.java:59)
at com.skyblue.service.media.StreamProxy.processRequest(StreamProxy.java:204)
at com.skyblue.service.media.StreamProxy.run(StreamProxy.java:103)
at java.lang.Thread.run(Thread.java:1096)
似乎MediaPlayer变得更加聪明了。如果我传递这样的url
"http://127.0.0.1:%d/%s"
,它不仅想要获取字节,还想要获取完整的http响应。
此外,我想知道是否有其他实现缓冲的方法?据我所知,MediaPlayer只能消耗文件和URL。解决方案中的文件无法正常工作。因此,我必须使用socket进行流传输。
谢谢