流式传输到 Android MediaPlayer
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2511045/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Streaming to the Android MediaPlayer
提问by Rob Szumlakowski
I'm trying to write a light-weight HTTP
server in my app to feed
dynamically generated MP3
data to the built-in Android
MediaPlayer
. I am not permitted to store my content on the SD card
.
我正在尝试HTTP
在我的应用程序中编写一个轻量级服务器来feed
动态生成的MP3
数据到内置的Android
MediaPlayer
. 我不允许将我的内容存储在SD card
.
My input data is essentially of an infinite length. I tell MediaPlayer
that its data source should basically be something like "http://localhost/myfile.mp3"
. I've a simple server set up that waits for MediaPlayer
to make this request. However, MediaPlayer
isn't very cooperative. At first, it makes an HTTP GET
and tries to grab the whole file. It times out if we try and simply dump data into the socket
so we tried using the HTTP
Range header to write data in chunks. MediaPlayer
doesn't like this and doesn't keep requesting the subsequent chunks.
我的输入数据本质上是无限长的。我告诉MediaPlayer
它的数据源基本上应该是这样的"http://localhost/myfile.mp3"
。我有一个简单的服务器设置,等待MediaPlayer
发出此请求。然而,MediaPlayer
不是很合作。首先,它创建一个HTTP GET
并尝试获取整个文件。如果我们尝试简单地将数据转储到 中,它会超时,socket
因此我们尝试使用HTTP
Range 标头以块的形式写入数据。 MediaPlayer
不喜欢这样并且不会继续请求后续块。
Has anyone had any success streaming data directly into MediaPlayer
? Do I need to implement an RTSP
or Shoutcast
server instead? Am I simply missing a critical HTTP header
? What strategy should I use here?
有没有人成功地将数据直接导入MediaPlayer
?我需要实现一个RTSP
或Shoutcast
服务器吗?我只是错过了一个关键HTTP header
吗?我应该在这里使用什么策略?
回答by Robert Harvey
The
HTTP
Server was indeed hosted on the phone itself. It was very simple: just athread
listening on a socket for anHTTP GET
request. When it got theHTTP
request, it would one anew socket
, write back someHTTP
headers and start dumping theMP3
audio data back to thesocket
. ThisHTTP
server didn't do anything else.The
Android Media Player
was playing the music as I was streaming to it. TheMedia Player
behaved very poorly if its playbackbuffer
was emptied while it was playing audio. It was very important for me to make sure myHTTP
server kept writing data into thatsocket
. I moved bytes into the socket in small chunks (10 kB). The headers on myHTTP
response ended up looking like this:// Build response headers StringBuilder sb = new StringBuilder(); sb.append( "HTTP/1.1 200 OK\r\n"); sb.append( "Content-Type: audio/mpeg\r\n"); sb.append( "Connection: close\r\n" ); sb.append( "Accept-Ranges: bytes\r\n" ); sb.append( "Content-Length: " + totalFileSize + "\r\n" ); sb.append( "Content-Disposition: inline; filename=xxxxx.mp3\r\n\r\n");
As long as I kept the pipe stoked, the
Android Media Player
kept consuming it without complaint. Playing audio only required one request and response. It ended up working pretty well.
该
HTTP
服务器确实举办了手机本身。这很简单:只是thread
在套接字上侦听HTTP GET
请求。当它收到HTTP
请求时,它会发出一个 anew socket
,写回一些HTTP
标头并开始将MP3
音频数据转储回socket
. 该HTTP
服务器没有做任何其他事情。该
Android Media Player
是播放音乐,因为我是流给它。该Media Player
如果回放表现很差buffer
它播放音频,而被掏空。确保我的HTTP
服务器不断向其中写入数据对我来说非常重要socket
。我将字节以小块 (10 kB) 的形式移动到套接字中。我HTTP
回复的标题 最终看起来像这样:// Build response headers StringBuilder sb = new StringBuilder(); sb.append( "HTTP/1.1 200 OK\r\n"); sb.append( "Content-Type: audio/mpeg\r\n"); sb.append( "Connection: close\r\n" ); sb.append( "Accept-Ranges: bytes\r\n" ); sb.append( "Content-Length: " + totalFileSize + "\r\n" ); sb.append( "Content-Disposition: inline; filename=xxxxx.mp3\r\n\r\n");
只要我一直在点燃管道,
Android Media Player
人们就会毫无怨言地继续消费。播放音频只需要一个请求和响应。它最终工作得很好。