Pull to refresh

Не используйте MediaPlayer и MediaMetadataRetriever в Android

Development for Android *
Sandbox
Как показывает мой скромный опыт, родные MediaPlayer, MediaMetadataRetriever, а так же другие классы, которые так или иначе основываются на них (VideoView, ThumbnailUtils, к примеру), являются крайне ненадежными в использовании. Возможно, проблема в том, что они реализованы нативно, и меняются от версии к версии, но факт остается фактом — их поведение на разных устройствах предсказать невозможно, причем это даже не зависит от мощности железа.

Хорошим примером стал небольшой проект, где требовалось реализовать воспроизведение видео. Формат и кодек можно было выбрать любой, я проводил тесты на mp4 и avi с различными кодеками. На всех попавшихся под руку устройствах, воспроизведение шло гладко и без нареканий. Старые устройства и версии ОС <4.0 поддерживать не требовалось, и я думал, что на данных форматах проблем уже не будет. Затем на HTC desire V обнаружилось, что несколько видео не воспроизводятся, встроенным проигрывателем в галерее тоже. Была мысль, что устройство слабовато, но сюрпризом стало то, что на Nexus 5 не воспроизводились вообще почти никакие тестовые видео. Хоть какую-то закономерность мне найти не удалось — даже с одинаковыми кодеками один файл мог читаться, а другой — нет. Файлы не были повреждены, поэтому грешить оставалось только на VideoView с MediaPlayer внутри.

К счастью, нашлись хорошие альтернативы, которые работают не только надежнее, но и быстрее:

  • Библиотека FFmpeg. Вы можете сами скомпилировать ее с помощью Android NDK. Хорошо, но минусы этого подхода очевидны — нужно разбираться с NDK, заниматься сборкой, да еще и сделать это можно только под Linux. На это я не захотел тратить время.
  • FFmpegMediaPlayer. Собственно, основывается на первой библиотеке, но вам не нужно заниматься сборкой, и уже предоставляется интерфейс, полностью аналогичный родному MediaPlayer. Чисто для проверки я пробовал ее использовать, но по какой-то причине видео не рисовалось на SurfaceView, при этом точно такой же код, но с родным MediaPlayer работал без проблем. Возможно, это был мой косяк, но быстрого решения я найти так и не смог.
    (UPD: Как заметили в комментариях, эта библиотека только для аудио)
  • Vitamio. Тоже берет за основу FFmpeg и тоже предоставляет готовые сборки. При этом имеет еще свой VideoView и MediaMetadataRetriever, с интерфейсом, как у родного из Android SDK, который сильно упрощает жизнь при создании плеера. Есть возможность использовать свои билды FFmpeg, поддерживает OS 2.1+ и практически все форматы. На этой библиотеке я и остановился, никаких проблем с ней не возникло. Обратите внимание, что в сборке изначально нет билда для x86. Так же стоит ожидать, что ваш APK потолстеет мегабайт на ~8 с этой библиотекой.
  • Есть и другие варианты, большинство из них используют тот же FFmpeg, но меня полностью устроил и Vitamio.

В общем, я крайне не рекомендую использовать стандартные классы даже для небольших проектов и «обычных» распространенных форматов видео\аудио. Кто-то может не согласиться и сказать, что у него и так все хорошо работает. Тут можно посоветовать только тестирование на большем количестве файлов и устройств… с помощью Genymotion, например.
Tags:
Hubs:
Total votes 15: ↑9 and ↓6 +3
Views 22K
Comments Comments 15