SurfaceView, SurfaceTexture и MediaPlayer не могут воспроизводить мое видео в android

Я пытаюсь воспроизвести видео в прямом эфире в своем приложении с помощью SurfaceView, когда я пытаюсь использовать его с Vitamio, он играет хорошо, но поскольку это HTTP-ссылка, я пытался избавиться от любой сторонней библиотеки и использовал родные классы. Я пробовал VideoView, как всегда, тогда я попробовал базовую реализацию SurfaceView после сбоя. Я попробовал текстуру videw следующим образом:

@Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {

        Surface surface = new Surface(surfaceTexture);

        try {

            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(getApplicationContext(), Uri.parse(link));
            mMediaPlayer.setSurface(surface);
            mMediaPlayer.setLooping(true);
            mMediaPlayer.prepareAsync();

            // Play video when the media source is ready for playback.
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.start();
                }
            });

            mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {

                    Log.d(TAG, "Error occured");

                    return false;
                }
            });

        } catch (IllegalArgumentException e) {
            Log.d(TAG, e.getMessage());
        } catch (SecurityException e) {
            Log.d(TAG, e.getMessage());
        } catch (IllegalStateException e) {
            Log.d(TAG, e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, e.getMessage());
        }

    }

но не удача каждый раз, когда вызывается MediaPlayer OnError и в logcat я получаю следующее:

06-28 16:00:56.612     144-8044/? E/GenericSource﹕ Failed to prefill data cache!
06-28 16:00:56.614    7997-8016/? E/MediaPlayer﹕ error (1, -2147483648)
06-28 16:00:56.614    7997-7997/? E/MediaPlayer﹕ Error (1,-2147483648)

но дело в том, что с URL-адресом нет проблем, этот URL-адрес отлично работает на витамио и на всех других играх, на которых я могу протестировать, пожалуйста, помогите!

Ответ 1

У меня была собственная боль, пытаясь заставить видео играть на Android через MediaPlayer, и я также пробовал Vitamio. В большинстве случаев, если видео не воспроизводилось должным образом на Android MediaPlayer, это было потому, что он не поддерживался.

http://developer.android.com/guide/appendix/media-formats.html

Это может быть не тот ответ, который вы хотите, но вам, вероятно, придется перекодировать все, что вы пытаетесь воспроизвести, в поддерживаемый формат. Возможности воспроизведения видео на Android намного слабее, чем у iphone, и это то, что вам нужно будет принять.

Если вместо этого вы захотите добавить (много) больше работы, вы можете скомпилировать ffmpeg самостоятельно для android, сделать jni-интерфейс для него многими компонентами и воспроизвести видео в виде поверхности/текстуры. Я лично не рекомендую этот маршрут, так как мой опыт потокового видео 1080p через ffmpeg был невелик.

Ваша лучшая и простая ставка - просто перекодировать ваши видео.

Справочная информация. Я сделал приложение, в котором было воспроизведено до 5 видеороликов с использованием различных продавцов.

Ответ 2

Кажется, это одна из двух проблем. Либо формат неверен, либо возникают проблемы с файлом, и он не может его открыть.

Сначала конвертируйте видео, используя ffmpeg. Я использую эту команду для преобразования в потоковый mp4:

ffmpeg -i InputVideo.mp4 -c: v libx264 -profile: v baseline -c: libfaac -ar 44100 -ac 2 -b: 128k -movflags faststart OutputVideo.mp4

Во-вторых, сначала попробуйте загрузить видео в качестве файла, а затем передайте источник данных в медиаплеер. Это необходимо время от времени, поскольку я заметил, что при использовании MediaPlayer для открытия файла он запускает вызов уровня ОС для загрузки файла, когда файл находится в частной папке приложений и поэтому недоступен ОС. Мы делаем это так:

AssetFileDescriptor afd = contxt.getResources().openRawResourceFd(R.raw.prepare_artwork);

if (afd == null) {
    Log.e(TAG, "Failed to load video.");
} else {
    mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
    afd.close();
}