Android – загрузка видео из частной папки приложения

У меня проблема, что я пытался найти решение в течение длительного времени. Моя ситуация такова:

У меня есть приложение, которое загружает zipped видео и разархивирует их в частной папке приложения и, более конкретно, в подпапке. Например, на /data/data/my.app.package.name.here/files/assets/assets-955.

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

Затем у меня есть другое действие, которое обращается к этой папке, находит видеофайл и пытается его открыть. На этом этапе я получаю сообщение об ошибке «Извините, это видео невозможно воспроизвести» со следующим стеком ошибок:

01-30 17:36:17.770: D/ContentDemoActivity(6757): File: /data/data/xxxx/files/assets/assets-955/bank_2.mp4 01-30 17:36:17.830: I/MediaPlayer(6757): prepareAsync called in state 4 01-30 17:36:17.830: E/MediaPlayer(6757): error (1, -2147483648) 01-30 17:36:17.860: E/MediaPlayer(6757): Error (1,-2147483648) 01-30 17:36:17.860: D/VideoView(6757): Error: 1,-2147483648 01-30 17:36:19.370: E/MediaPlayer(6757): stop called in state 0 01-30 17:36:19.370: E/MediaPlayer(6757): error (-38, 0) 01-30 17:36:19.370: W/MediaPlayer(6757): mediaplayer went away with unhandled events 

Код, с которым я пытаюсь воспроизвести видео, довольно простой:

 mView = (VideoView) findViewById(R.id.videoView); mMediaPlayer = new MediaPlayer(); mView.requestFocus(); mHolder = mView.getHolder(); Log.d(tag, "Populating content. Assets path: " + mAssetsPath); File f = new File(mAssetsPath); File[] files = f.listFiles(); Log.d(tag, "File: " + files[0].toString()); mView.setVideoURI(Uri.parse(files[0].toString())); mView.setMediaController(new MediaController(this)); 

И макет активности имеет простой VideoView, ничего особенного здесь нет.

Самое странное, что для тестирования я использовал одно и то же видео, на этот раз загрузив его из «сырой» папки, и он работает без проблем. В этом случае, хотя мне пришлось загрузить его с помощью:

 Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bank_2); mVideoView.setVideoURI(video); mVideoView.start(); 

Я бы сделал то же самое с загруженными видео, но в API не существует какой-либо функции, которая позволит мне загружать видео Uri из частной папки приложения.

Я нашел различные решения, используя файловые дескрипторы, прослушиватели для videoView, флаги, указывающие MODE_WORLD_READABLE, предварительный расчет размеров видеовизора и т. Д., Но ни один из них не имел положительных результатов.

В двух словах, мои вопросы:

  • Почему я получаю те ошибки, которые в соответствии с тем, что я нашел в Интернете, являются ошибками, связанными с проблемным кодированием видеофайла?
  • Что лучше всего использовать в моем случае, VideoView или surfaceView?
  • Каков идеальный метод для загрузки видео из частной папки приложения и возможности его воспроизведения?

Благодарю.

РЕДАКТИРОВАТЬ

После предложения CommonsWare я пошел со следующей реализацией:

 File f = new File(mAssetsPath); File[] files = f.listFiles(); Log.d(tag, "File: " + files[0].toString()); URI uri = URI.create("file://" + (files[0].toString())); File file = new File(uri); try { Log.d(tag, "1"); ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE); Log.d(tag, "2"); mMediaPlayer.setDataSource(parcel.getFileDescriptor()); Log.d(tag, "3"); mMediaPlayer.start(); Log.d(tag, "4"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Log.d(tag, "5"); 

К сожалению, на этот раз я получаю следующие ошибки:

 01-31 12:40:11.480: D/ContentDemoActivity(15896): File: /data/data/com.houseofradon.meb/files/assets/assets-955/bank_2.mp4 01-31 12:40:11.480: D/ContentDemoActivity(15896): 1 01-31 12:40:11.480: D/ContentDemoActivity(15896): 2 01-31 12:40:11.500: D/ContentDemoActivity(15896): 3 01-31 12:40:11.500: E/MediaPlayer(15896): start called in state 2 01-31 12:40:11.500: E/MediaPlayer(15896): error (-38, 0) 01-31 12:40:11.500: D/ContentDemoActivity(15896): 4 01-31 12:40:11.500: D/ContentDemoActivity(15896): 5 01-31 12:40:11.530: E/MediaPlayer(15896): Error (-38,0) 

Итак, что-то происходит, когда начинается медиаплеер. Код ошибки -38, похоже, не означает ничего конкретного, как я нашел здесь .

Любая идея, что мне не хватает ???

EDIT # 2

Теперь я использую mediaPlayer и SurfaceView для выполнения всего процесса вместе с слушателем surfaceHolder. Вот код:

 mMediaPlayer = new MediaPlayer(); mSurfaceView = (SurfaceView) findViewById(R.id.surface); mHolder = mSurfaceView.getHolder(); mHolder.addCallback(this); public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d(tag, "surfaceChanged"); try { mMediaPlayer.setDisplay(mHolder); Log.d(tag, "7"); mMediaPlayer.start(); Log.d(tag, "8"); } catch (IllegalStateException e) { e.printStackTrace(); } Log.d(tag, "9"); } public void surfaceCreated(SurfaceHolder holder) { Log.d(tag, "surfaceCreated"); File f = new File(mAssetsPath); File[] files = f.listFiles(); Log.d(tag, "File: " + files[0].toString()); URI uri = URI.create("file://" + (files[0].toString())); File file = new File(uri); try { Log.d(tag, "1"); ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE); Log.d(tag, "2"); mMediaPlayer.setDataSource(parcel.getFileDescriptor()); Log.d(tag, "3"); mMediaPlayer.setVolume(100, 100); Log.d(tag, "4"); mMediaPlayer.prepare(); Log.d(tag, "5"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Log.d(tag, "6"); } 

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

 01-31 14:26:01.300: W/AudioSystem(17165): AudioFlinger server died! 01-31 14:26:01.300: W/IMediaDeathNotifier(17165): media server died 01-31 14:26:01.300: E/MediaPlayer(17165): error (100, 0) 01-31 14:26:01.300: E/MediaPlayer(17165): Error (100,0) 

Я использую фактическое устройство, Samsung Galaxy Tab 10.1. Есть идеи ?

Почему я получаю те ошибки, которые в соответствии с тем, что я нашел в Интернете, являются ошибками, связанными с проблемным кодированием видеофайла?

Поскольку механизм воспроизведения мультимедиа работает в своем собственном процессе и у него нет прав на чтение вашего файла.

Что лучше всего использовать в моем случае, VideoView или surfaceView?

VideoView содержит SurfaceView . Используете ли вы VideoView или комбинацию MediaPlayer и SurfaceView , зависит от вас.

Каков идеальный метод для загрузки видео из частной папки приложения и возможности его воспроизведения?

Создайте ContentProvider который может обслуживать ваш локальный файл и использовать провайдера Uri вместо Uri в локальном файле или создать локальный файл с помощью openFileOutput() и MODE_WORLD_READABLE .

Intereting Posts
Один экран установки Android? Как отладить J2V8 в Android с помощью инструментов для создания Chrome? Тест блока Android с ActivityInstrumentationTestCase2, getActivity () зависает, когда предыдущий тестовый случай вызывает запуск другого Activity Какие платформы Android / API совместимы с версиями Google Play Services? Андроид GCI Unicode charcters не получен Как найти серийный номер Android-устройства? Android Очистка всех полей EditText с кнопкой Clear Разрешить все ссылки «market: //» изнутри веб-браузера, чтобы открыть магазин Google Play ImageView adjustViewBounds не работает Как программно переключаться с помощью кнопок buttonclick в Android Не запрашивайте Window.FEATURE_ACTION_BAR и установите для windowActionBar значение false в вашей теме, чтобы вместо этого использовать панель инструментов Перенос изображения через Bluetooth в Android Я никогда не устанавливал пароли в хранилище ключей и псевдоним, так как они созданы? Android Bluetooth от службы IndexOutOfBoundsException для setSpan – вне моего кода приложения