【问题标题】:Android Mediaplayer doesnt throw IO exception If file not available at the link如果文件在链接中不可用,Android Mediaplayer 不会抛出 IO 异常
【发布时间】:2017-03-30 15:09:51
【问题描述】:

我正在使用 URL 启动媒体播放器。 URL 假设链接到 video/Audio 。但是我已经从该位置删除了视频/音频文件,因此我希望得到一个 IOException id,该链接上没有可用的内容。

但我没有收到 IO 异常。取而代之的是 mediaplayer 本身尝试去链接 10 次,最后在 onErrorListner 上抛出错误。 以下是 mediaPlayer 准备时打印的日志。

注意:-我的网址不适用于本地存储文件!它用于服务器端文件。

 E/NuCachedSource2: source returned error -1, 10 retries left
 E/NuCachedSource2: source returned error -1, 9 retries left
 E/NuCachedSource2: source returned error -1, 8 retries left
 E/NuCachedSource2: source returned error -1, 7 retries left
 E/NuCachedSource2: source returned error -1, 6 retries left
 E/NuCachedSource2: source returned error -1, 5 retries left
 E/NuCachedSource2: source returned error -1, 4 retries left
 E/NuCachedSource2: source returned error -1, 3 retries left
 E/NuCachedSource2: source returned error -1, 2 retries left
 E/NuCachedSource2: source returned error -1, 1 retries left
 E/NuCachedSource2: source returned error -1, 0 retries left
 E/GenericSource: Failed to init from data source!

我不想等太久,以至于 mediaplayer 尝试使用相同的 URL 重新连接 10 次。我希望在第一时间立即出现 IOException 或错误。

以下是我的代码。请帮忙!!

  mMediaPlayer = new MediaPlayer();
  mMediaPlayer.setDataSource(getContext(), Uri.parse(url));
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mMediaPlayer.setLooping(false);
            mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                    OnErrorReceive("Something is wrong with media player states");

                    return false;
                }
            });
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
    enter code here
               strong text     mMediaPlayer.start();

                }
            });
            mMediaPlayer.prepareAsync();

【问题讨论】:

    标签: android android-mediaplayer


    【解决方案1】:

    如果您正在使用远程媒体资源,我建议您使用其他 mediaPlayer 实现,例如 google/ExoPlayer2

    Android 默认播放器重试次数为 10。对 HTTP 404 响应没有错误处理。

    struct NuCachedSource2 : public DataSource {
    
    ...
    enum {
        kMaxNumRetries = 10,
    };
    

    google/ExoPlayer2 有 2 个。但您可以根据需要进行更改。 my commit in github

          if (retryAction == DONT_RETRY_FATAL) {
            fatalError = currentError;
          } else if (retryAction != DONT_RETRY) { // DONT_RETRY = 2
            errorCount = retryAction == RETRY_RESET_ERROR_COUNT ? 1 : errorCount + 1;
            start(getRetryDelayMillis());
          }
    

    【讨论】:

    • 您好,我们不打算使用任何第三方库,而且我们只是制作一个基本的音频/视频播放器,这只是项目的一小部分。因此,我想向您寻求帮助!我只是在使用 Android Mediaplayer API。如何将此 kMaxNumRetries 从 10 更改为 1 或 2。我必须使用 NDK 吗?
    • 如果您使用HTTP协议访问远程媒体资源,请使用简单的HTTP客户端并同时检查响应码。我认为在 Android 媒体框架中更改默认重试次数非常困难。
    【解决方案2】:

    调用 setDataSource(String path) 且文件不存在时抛出 IOException。

            Uri uri = Uri.parse(url)
            final String scheme = uri.getScheme();
            if ("file".equals(scheme)) {
                path = uri.getPath();
                mMediaPlayer.setDataSource(path); // IOException
            } else {
                mMediaPlayer.setDataSource(getContext(), uri);
            }
    

    【讨论】:

    • 我的网址不适用于本地文件。我的服务器上有文件,因此我使用 mMediaPlayer.setDataSource(getContext(), uri);正如您从我的代码中看到的那样,我没有收到 IOException。相反,无论我得到什么日志,我都已经粘贴了。它检查 10 次,然后在 onErrorListner 上返回错误
    【解决方案3】:

    如果 prepareAsync() 的链接错误,Android Mediaplayer 不会抛出异常。
    对于 prepareAsync 尝试使用以下方法捕获您的错误:

    onError(MediaPlayer mp, int what, int extra);
    

    使用 MediaPlayer.setOnErrorListener()。

    改为使用mMediaPlayer.prepare();

    另一种选择是使用

    URLUtil.isValidUrl(url)
    

    立即检查您的链接是否存在!

    【讨论】:

    • 我正在使用 onError 进行监听,但问题是响应时间过长,至少需要 30 秒。当我看到日志时,我发现媒体播放器内部收到 404 错误,但尝试 10 次重新连接并最终抛出错误。尝试 10 次重新连接需要 30 多秒。看看我的问题。我写了日志,你可以看到媒体播放器尝试 10 次并报告错误
    • mMediaPlayer.prepare() 根本没有解决目的。 URLUtil.isValidUrl(url) 只是查看 url 是否有效。这里我担心的是 URL 是有效的。但是我们已经从服务器中删除了与此 url 对应的内容。现在我希望尽快出现 IOException。默认情况下,检查 10 次后大约需要 30-40 秒,就像我在问题中提到的那样
    • @user2228673 如果您不想等待,URLUtil.isValidUrl(url) 是您最好的选择。 MediaPlayer API 有很多限制。您可以尝试使用 NDK 构建自己的播放器。但这需要时间和大量工作。
    • 我不明白 URLUtil.isValidUrl(url) 如何解决我的问题。如果您查看 isValidUrl。它只是检查它是 http 还是 ot,文件 orl 等等等等。它不会去服务器并检查该 url 上的内容是否可用。在我的情况下,url 是有效的 url,唯一的问题是在这个 URL 的服务器上没有可用的内容。在我的应用程序中,我必须处理这种情况,因此经过深思熟虑,我已经从这个 url 中删除了内容,以便如果服务器上没有内容,我可以在 mediaplayer 捕获 IOException。
    猜你喜欢
    • 2012-06-03
    • 2013-01-31
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    相关资源
    最近更新 更多