流式传输到 Android MediaPlayer

发布于 2024-08-26 09:33:39 字数 600 浏览 7 评论 0原文

我正在尝试在我的应用程序中编写一个轻量级 HTTP 服务器,以将动态生成的 MP3 数据提供给内置 Android MediaPlayer。我无权将我的内容存储在SD 卡上。

我的输入数据本质上是无限长度的。我告诉 MediaPlayer 它的数据源基本上应该类似于“http://localhost/myfile.mp3”。我设置了一个简单的服务器,等待 MediaPlayer 发出此请求。但是,MediaPlayer 不太配合。首先,它发出一个 HTTP GET 并尝试获取整个文件。如果我们尝试简单地将数据转储到套接字中,则会超时,因此我们尝试使用 HTTP Range 标头以块的形式写入数据。 MediaPlayer 不喜欢这样,并且不会继续请求后续块。

有没有人成功地将数据直接流式传输到 MediaPlayer 中?我是否需要实施 RTSPShoutcast 服务器?我只是缺少一个关键的 HTTP header 吗?我应该在这里使用什么策略?

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.

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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月如刀 2024-09-02 09:33:39

HTTP 服务器确实托管在手机本身上。这是非常
简单:只是一个线程在套接字上侦听HTTP GET
要求。当它收到 HTTP 请求时,它会创建一个新套接字
写回一些 HTTP 标头并开始转储 MP3 音频数据
返回套接字。此 HTTP 服务器没有执行任何其他操作。

当我流式传输时,Android Media Player 正在播放音乐
它。如果播放缓冲区媒体播放器的表现会非常糟糕
播放音频时被清空。这对我来说非常重要
确保我的 HTTP 服务器不断将数据写入该套接字。我
将字节以小块 (10 kB) 的形式移入套接字。我的标题
HTTP 响应最终如下所示:

// 构建响应头
StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1 200 OK\r\n");
sb.append(“内容类型:音频/mpeg\r\n”);
sb.append( "连接:关闭\r\n" );
sb.append(“接受范围:字节\r\n”);
sb.append( "内容长度: " + TotalFileSize + "\r\n" );
sb.append(“内容处理:内联;文件名=xxxxx.mp3\r\n\r\n”);

只要我一直给管道加油,Android Media Player 就会一直保持
毫无怨言地消费它。播放音频只需要一个
请求和响应。最终效果非常好。

The HTTP Server was indeed hosted on the phone itself. It was very
simple: just a thread listening on a socket for an HTTP GET
request. When it got the HTTP request, it would one a new socket,
write back some HTTP headers and start dumping the MP3 audio data
back to the socket. This HTTP server didn't do anything else.

The Android Media Player was playing the music as I was streaming to
it. The Media Player behaved very poorly if its playback buffer
was emptied while it was playing audio. It was very important for me
to make sure my HTTP server kept writing data into that socket. I
moved bytes into the socket in small chunks (10 kB). The headers on my
HTTP 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文