Подтвердить что ты не робот

MediaMetadataRetriever setDataSource вызывает IllegalArgumentException

Я пытаюсь получить размер удаленного видео с помощью этого класса, и я получаю IllegalArgumentException, если видео является удаленным.

видео - это mp4, хранящийся на одном сервере...

видео воспроизводится правильно, если я воспроизвожу его с помощью медиаплеера, но он дает ошибку, если я попытаюсь сделать это:

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)
4b9b3361

Ответ 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();

Ответ 2

В моем случае я создавал простое приложение для извлечения метаданных, поэтому я скопировал файл на свой телефон с помощью 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+, вам также придется динамически запрашивать эти разрешения.

Ответ 3

Вы должны дать разрешения времени выполнения, если вы используете 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" />
...

Затем добавьте код для прав доступа в вашей деятельности. После этого запустите ваше приложение, и оно должно работать.