音频流缓冲
我需要播放实时音频流,实际上它是广播。问题是我还需要管理 20 分钟的流媒体缓冲区。据我了解,用android实现并不容易。
首先我检查了MediaPlayer,但它没有提供任何缓冲区管理方法。事实上你甚至不能直接设置缓冲区大小。
其次,我尝试使用本地文件管理缓冲区:逐步将流下载到临时文件并切换它们。但是当您想切换到以下文件(更改 MediaPlayer 中的数据源)时,音频不会连续播放。您可以听到短暂的中断。
最后一个想法是使用流代理。通常用于在Android 8以下版本中播放流。在流代理中,您创建ServerSocket,从音频流中读取并写入播放器。所以实际上我可以在那里管理缓冲。我可以缓存流并写入 MediaPlayer 任何我想要的内容。但。它不适用于 Android 8。
我遇到异常:Connection Reset by Peer java.net.SocketException:Connection Reset by Peer。 MediaPlayer 8 不想从套接字读取数据。
因此我有两个问题: 1)还有什么其他方法可以实现流缓冲? 2)如何将StreamProxy适配为android 8?
任何想法表示赞赏。
谢谢
I need to play live audio stream, actually it is radio. The problem is that I also need to manage 20 minute buffer for streaming. As far as I understand it's not easy to implement with android.
Firstly I checked MediaPlayer, but it doesn't provide any methods for buffer management. In fact you even can't set buffer size directly.
Secondly I tried to manage buffer using local files: progressively download the stream to a temporary files and switch them. But when you want to switch to following file (change datasource in MediaPlayer), audio is not played continuously. You can hear short interruptions.
The last idea is to use stream proxy. Usually it is used for playing streams in Android versions below 8. In stream proxy you create ServerSocket, read from audio stream and write to player. So actually I can manage buffering there. I can cache stream and write to MediaPlayer whatever I want. But. It doesn't work with Android 8.
I got exception: Connection reset by peer java.net.SocketException: Connection reset by peer. MediaPlayer 8 doesn't want to read data from socket.
Thus I have two questions:
1) What other way to implement stream buffering?
2) how to adapt StreamProxy for android 8?
Any ideas are appreciated.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我使用与 NPR 项目相同的 StreamProxy - https://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java
因此它获取原始音频流:
并从该流写入客户端套接字:(
您可以从上面的链接获取完整代码。)
最后他们如何初始化播放器(PlaybackService):
所以他们检查 SDK 版本。但如果我省略此检查并使用 SDK 8 的代理,则会出现异常。
奇怪的是,MediaPlayer 甚至不尝试读取流:
看来 MediaPlayer 变得更聪明了。如果我传递这样的 url
"http://127.0.0.1:%d/%s"
它不仅希望获得字节,还希望获得“完整”http 响应。另外我想知道是否还有其他方法实现缓冲?据我所知,MediaPlayer 仅使用文件和网址。
文件解决方案不起作用。所以我必须使用套接字进行流传输。
谢谢
I use the same StreamProxy that guys used for NPR project - https://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java
So it gets original audio stream:
And writes from this stream to client socket:
(You can get whole code from the link above.)
And finally how they initialize the player (PlaybackService):
So they check SDK version. But if I omit this check and use proxy for SDK 8 as well I get an exception.
It is strange that MediaPlayer even doesn't try to read the stream:
It seems that MediaPlayer became more clever. And If i pass such url
"http://127.0.0.1:%d/%s"
it wants to get not only bytes but "full" http responce.Also I wonder if there any other ways implement buffering? As I know the MediaPlayer consumes only files and urls.
Solution with files doesn't work. So I have to use socket for stream transmitting.
Thanks
我刚刚测试了以下修复,它有效。此问题是由
StreamProxy
的processRequest()
方法中的标头中使用的 "\n" 引起的。将其更改为“\r\n”应该会使错误消失。至于实现自定义流媒体,我过去曾使用过它,尽管它似乎主要用于无限流媒体广播。 http:// blog.pocketjourney.com/2009/12/27/android-streaming-mediaplayer-tutorial-updated-to-v1-5-cupcake/
I just tested the following fix, and it works. This issue is caused by the "\n" used in the headers in the
processRequest()
method ofStreamProxy
. Changing this to "\r\n" should make the error go away.As for implementing custom streaming, I've used this in the past, though it seems to be mainly for infinitely streaming radio. http://blog.pocketjourney.com/2009/12/27/android-streaming-mediaplayer-tutorial-updated-to-v1-5-cupcake/
当您查找或跳过或连接丢失并且 MediaPlayer 不断重新连接到代理服务器时,您必须在从客户端收到请求和范围(int)后发送状态为 206 的此响应。
当您收到来自 MediaPlayer 的 HTTP 标头中不包含 Range 的请求时,它正在请求一个新的流文件,在这种情况下,您的响应标头应如下所示:
Enjoy!
When you seek or skip or the connection is lost and MediaPlayer keeps reconnecting to the proxy server, you must send this response with Status 206 after you get the request and range(int) from the client.
And when you receive a request from MediaPlayer that does not contain Range in the HTTP header , then it is requesting a new stream file, in this case your response header should look like this:
Enjoy!
SDK 8 中的 Mediaplayer 将无法读取代理 URL。但根据我目前的工作,这因设备而异。在我的 Samsung ACE (SDK 8) 中,代理连接工作正常,但在我的 HTC Incredible S 中,代理连接会出现与您相同的问题。直接连接到音频流工作正常,但这会导致某些设备(例如 sprint 上的 EVO)出现杂音和杂音。
您找到这个问题的解决方案了吗?你是怎么处理的?
-哈里
The Mediaplayer from SDK 8 would not be able to read a proxy url. But based on my current work, this is differing from device to device. In my Samsung ACE (SDK 8) the proxy connection works fine, but in my HTC Incredible S, the proxy connection would give the same issue as you have. A direct connection to the audio stream works fine but this causes blips and boops in some devices like EVO on sprint.
Did you get a resolution for this issue? How did you handle this?
-Hari
我意识到这个问题已经有 5 年历史了,但以防万一其他人在徘徊:ExoPlayer 是来自 Google 的库,它可以让您更好地控制缓冲区大小等选项。
这是我创建的一个小项目,用于学习如何使用它。
https://github.com/feresr/MyMediaPlayer
http://developer.android.com/guide/topics/media/exoplayer.html
https://github.com/google/ExoPlayer
I realise this Question is like 5 years old but in case some one else is wandering: ExoPlayer is library from Google that gives you much more control over options like buffer size.
Here's a small project I created to learn how to use it.
https://github.com/feresr/MyMediaPlayer
http://developer.android.com/guide/topics/media/exoplayer.html
https://github.com/google/ExoPlayer