如何避免 Android Media Player 播放流时出现 15 秒延迟/缓存

发布于 2024-12-07 22:14:32 字数 582 浏览 0 评论 0原文

我正在实现一个从远程计算机播放流的媒体播放器。通过我的应用程序,我可以控制远程机器(例如寻求第二个)。就像魅力一样,但是:Android 媒体播放器缓冲了一些疯狂的 10-15 秒(!!),这意味着每次点击(“搜索”)需要 10-15 秒才能生效,即使距离新的点击不到一秒数据到达。

我的问题:有什么方法可以控制(限制)缓存吗?或者我只是做错了什么?我是唯一一个有这个问题的人吗?

我的代码非常简单:

player = new MediaPlayer()
player.setDataSource(url);
player.setOnPreparedListener(new OnPreparedListener() {

    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }
});
player.prepareAsync();

我使用本地自建的迷你 HTTP 服务器将我的字节流连接到 Android 媒体播放器。在这种情况下,Android DRM 似乎正在延迟/缓存。仍然不太清楚为什么(以及为什么不连接到托管文件的 IIS)。也不知道如何解决这个问题。

I am implementing a media player that plays a stream from a remote machine. Via my app I can control the remote machine (e.g. seek to second). Works like charm, but: The Android Media Player buffers some insane 10-15 seconds(!!), which means each click ('seek') takes 10-15 seconds to take effect even though it is less than a second until the new data arrives.

My Question: Is there any way to control (limit) that caching? Or am I simply doing something wrong? Am I the only one having this issue?

My code is very simple:

player = new MediaPlayer()
player.setDataSource(url);
player.setOnPreparedListener(new OnPreparedListener() {

    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }
});
player.prepareAsync();

I am using a local self built mini HTTP server to connect my byte stream to Androids media player. It seems like Android DRM is delaying / caching in this case. Still not quite clear why (and why not if I connect to my IIS that hosts a file). Also no idea how to workaround this.

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

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

发布评论

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

评论(4

南薇 2024-12-14 22:14:32

好吧,与此同时我更接近解决方案了。原来我的问题根源是 Android DRM! (不,我没有播放受保护的文件。它是标准 mp3)。

DRM 似乎是在 Android 3.1 中引入的(我在 Galaxy Tab 10.1 上进行测试)。它在模拟器上运行良好(也许那里没有实现 DRM?)

知道如何禁用或加速它吗? Android DRM impl 深处的某个地方似乎有一个 10 秒计时器在等待 - 不管怎样,不知道。我的错误日志:

10-06 17:38:19.020: ERROR/MediaExtractor(226): **********MediaExtractor::Create
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(226): add uniqueid
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 1
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :ADD_UNIQUEID
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 3
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :ADD_CLIENT
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(226): Entering BpDrmManagerService::openDecryptSession
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 27
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION_FROM_URI
10-06 17:38:19.020: ERROR/DrmManagerService(Native)(225): Entering DrmManagerService::openDecryptSession with uri

10 seconds wait

10-06 17:38:29.040: ERROR/DrmManager(Native)(225): DrmManager::openDecryptSession: no capable plug-in found
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): NULL decryptHandle is returned
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): no decryptHandle is generated in service side
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): remove uniqueid
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 2
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :REMOVE_UNIQUEID
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 4
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :REMOVE_CLIENT
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): setDrmServiceListener
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 5
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :SET_DRM_SERVICE_LISTENER
10-06 17:38:29.040: ERROR/DrmManagerService(Native)(225): Entering setDrmServiceListener

Ok, meanwhile I got closer to the solution. Turned out the source of my problem is Android DRM! (No, I am not playing a protected file. Its standard mp3).

DRM seems to have been introduced in Android 3.1 (I was testing on a Galaxy Tab 10.1). It works fine on the Emulator (maybe DRM is not implemented there?)

Any idea how I can disable or accelerate this? There seems to be a 10 seconds timer somewhere deep in the Android DRM impl that waits for - whatever, no idea. My error log:

10-06 17:38:19.020: ERROR/MediaExtractor(226): **********MediaExtractor::Create
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(226): add uniqueid
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 1
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :ADD_UNIQUEID
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 3
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :ADD_CLIENT
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(226): Entering BpDrmManagerService::openDecryptSession
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 27
10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION_FROM_URI
10-06 17:38:19.020: ERROR/DrmManagerService(Native)(225): Entering DrmManagerService::openDecryptSession with uri

10 seconds wait

10-06 17:38:29.040: ERROR/DrmManager(Native)(225): DrmManager::openDecryptSession: no capable plug-in found
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): NULL decryptHandle is returned
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): no decryptHandle is generated in service side
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): remove uniqueid
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 2
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :REMOVE_UNIQUEID
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 4
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :REMOVE_CLIENT
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): setDrmServiceListener
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 5
10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :SET_DRM_SERVICE_LISTENER
10-06 17:38:29.040: ERROR/DrmManagerService(Native)(225): Entering setDrmServiceListener
云淡风轻 2024-12-14 22:14:32

我在较新的 Android 版本中意识到的一件事是,VBR MP3 文件似乎存在问题。它会播放它们,但在开始之前缓冲了太多数据。 (3+ MB,我的大部分测试文件)。

一个(糟糕的黑客)解决方法是从 MP3 文件中删除 XING 标头(这是存储 VBR 信息的位置)。这似乎使播放器退回到更简单的算法,并在仅缓冲 100kb 后成功开始播放我的所有文件...

One thing I realized in the newer Android versions is that it seems to have issues with VBR MP3 files. It plays them, but buffers way too much data before it starts. (3+ MB, the majority of my test files).

A (bad hack) workaround is to remove the XING header from the MP3 files (this is where the VBR information is stored). This seems to make the player fall back to a simpler algorithm and start playback successfully for all my files after buffering only 100kb...

潜移默化 2024-12-14 22:14:32

试试这个。这绝对会对你有帮助::

 private class TouchandshowTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... arg0) {
        try {
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        player.setDataSource("URL");
        player.prepare();
    } catch (Exception e) {
        // TODO: handle exception
    }

        return null;
    }
    protected void onPostExecute(final Void unused) {

    }
}

OnCreate()

new TouchandshowTask().execute();

Try this. this will definatly help to you ::

 private class TouchandshowTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... arg0) {
        try {
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        player.setDataSource("URL");
        player.prepare();
    } catch (Exception e) {
        // TODO: handle exception
    }

        return null;
    }
    protected void onPostExecute(final Void unused) {

    }
}

OnCreate()

new TouchandshowTask().execute();
メ斷腸人バ 2024-12-14 22:14:32

问题可能不仅仅出现在 Android Media Player 上。
流媒体视频的服务器应该支持所需的格式。

如果是 mp4,则需要安装 h264-pseudo-streaming 模块(HLS 相同)
如果是 MSS(微软平滑流)- 有针对 IIS 的特殊模块。

另外,在用户“进行搜索”后,意味着本机播放器将发送范围请求,服务器应该支持该请求。 Nginx 默认支持 ISS 和 ISS。 Apache 对此有一些问题。虽然易于配置。

The problem might be not only at Android Media Player.
Server that is streaming video should support need format.

If it's mp4's you need to install h264-pseudo-streaming module (same for HLS)
If it's MSS (microsoft smooth streaming) - there are special modules for IIS.

Also, after user 'makes seek' that means Native Player will send range request, that should be supported by server. Nginx supports them by default, ISS & Apache have some issues with this. Though easy configurable.

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