【问题标题】:MediaMetadataRetriever setDataSource throws IllegalArgumentExceptionMediaMetadataRetriever setDataSource 抛出 IllegalArgumentException
【发布时间】:2015-02-18 09:57:36
【问题描述】:

我正在尝试使用此类获取远程视频的大小,如果视频是远程的,我会收到 IllegalArgumentException。

视频是存储在一台服务器中的 mp4...

如果我使用 mediaplayer 播放视频,视频播放正确,但如果我尝试这样做,则会出现错误:

try {
    MediaMetadataRetriever retriever = new  MediaMetadataRetriever();
    Bitmap bmp = null;      
    retriever.setDataSource(context, uri);
    bmp = retriever.getFrameAtTime();           
    videoHeight = (int) (bmp.getHeight()*((float)getIntWidth()/bmp.getWidth()));
} catch (Exception e) {
    e.printStackTrace();
}   

在这一行抛出了错误:

retriever.setDataSource(context, uri);

并且 uri 包含 Uri.parse("http://www.myweb.com/myvideo.mp4");

代码有什么问题?

12-19 13:38:08.610: W/System.err(13333): java.lang.IllegalArgumentException
12-19 13:38:08.611: W/System.err(13333):    at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:175)

【问题讨论】:

  • 您解决了这个问题吗?

标签: android mediametadataretriever


【解决方案1】:

也许您遇到了this 错误。如果是这样试试:

try {
    MediaMetadataRetriever retriever = new  MediaMetadataRetriever();
    Bitmap bmp = null;      
    retriever.setDataSource("http://www.myweb.com/myvideo.mp4", new HashMap<String, String>());
    bmp = retriever.getFrameAtTime();           
    videoHeight = (int) (bmp.getHeight()*((float)getIntWidth()/bmp.getWidth()));
} catch (Exception e) {
    e.printStackTrace();
}

如果这不起作用,您可以随时尝试FFmpegMediaMetadataRetriever

FFmpegMediaMetadataRetriever retriever = new  FFmpegMediaMetadataRetriever();

try {
    Bitmap bmp = null;      
    retriever.setDataSource("http://www.myweb.com/myvideo.mp4"));
    bmp = retriever.getFrameAtTime();           
    videoHeight = (int) (bmp.getHeight()*((float)getIntWidth()/bmp.getWidth()));
} catch (Exception e) {
    e.printStackTrace();
}

retriever.release();

【讨论】:

  • MediaMetadataRetriever 类型中的方法 setDataSource(String) 不适用于参数 (String, HashMap)
  • FFmpegMediaMetadataRetriever 只需要 5 MB 的空间。使用 NDK 时,您应该为每个架构制作单独的 APK。
  • 我以为你可以添加 maven repo 并使用 ffmpegmediametadataretriever,还是我误解了这个概念? +1 对于可能的答案
  • 这是现在的首选方法,因为 Android Studio 已经取代了 Eclipse。
【解决方案2】:

我遇到了同样的错误,我使用的是 android 10。

我解决了将android:requestLegacyExternalStorage="true" 放在application 内的Manifest 中。

看这里

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
    android:requestLegacyExternalStorage="true"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

【讨论】:

  • 我已经设置了 "android:requestLegacyExternalStorage="true" 但仍然面临同样的错误
【解决方案3】:

就我而言,我正在创建一个简单的元数据提取测试应用程序,因此我使用 adb 将文件复制到了我的手机中,如下所示:

adb push 350950598.mp4 /sdcard/Movies

但是我忘记在应用清单中添加读取外部存储目录权限。

具体来说:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.cool.package.name">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    ...
</manifest>

添加这些权限为我修复了它,即使是简单的文件字符串调用:

    MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
    mediaMetadataRetriever.setDataSource(movie.getPath());

当然,如果您的目标是 API 23+ marshmallow,那么您还必须动态请求这些权限。

【讨论】:

    【解决方案4】:

    如果您使用的是 Android Marshmallow 或更高版本,则需要授予运行时权限。

    Android 清单文件:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.cool.package.name">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    ...
    

    然后在您的活动中添加运行时权限代码。之后,运行您的应用程序,它应该可以工作了。

    【讨论】:

    • 为什么需要 WRITE_EXTERNAL_STORAGE ?
    【解决方案5】:
    try {
        MediaMetadataRetriever retriever = new  MediaMetadataRetriever();
        Bitmap bmp = null;      
        retriever.setDataSource(uri.toString(), new HashMap<String, String>());
        bmp = retriever.getFrameAtTime();           
        videoHeight = (int) (bmp.getHeight()*((float)getIntWidth()/bmp.getWidth()));
    } catch (Exception e) {
        e.printStackTrace();
    }   
    

    【讨论】:

      【解决方案6】:

      如果您使用的是 android 10 或更高版本,那么您需要提及 requestLegacyExternalStorage 为 true。

      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      
      <application
          android:label="@string/app_name"
          android:roundIcon="@mipmap/ic_launcher_round"
          android:requestLegacyExternalStorage="true"
          android:supportsRtl="true"
          android:theme="@style/AppTheme">
      

      注意:如果这样做仍然遇到同样的问题,那么您需要重新安装应用程序。 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-14
        • 2016-06-04
        • 2020-06-05
        • 2014-09-18
        • 2014-11-05
        • 1970-01-01
        相关资源
        最近更新 更多