Потоковое видео с Google Диска в VideoView на Android 5.1+

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

Проблема в том, что начиная с Android 5.1 некоторые URL-адреса видео не воспроизводятся. Единственная ошибка в логе

06-02 23:22:53.940 32469-32469/com.example.myapp W/MediaPlayer: Couldn't open https://<URL...>: java.io.FileNotFoundException: No content provider: https://<URL...>
06-02 23:22:54.081 32469-32499/com.example.myapp D/OpenGLRenderer: endAllActiveAnimators on 0x7d9cc48800 (GridView) with handle 0x7d9c084400
06-02 23:22:54.857 32469-32480/com.example.myapp I/art: Background sticky concurrent mark sweep GC freed 53228(4MB) AllocSpace objects, 1(20KB) LOS objects, 33% free, 9MB/13MB, paused 7.612ms total 44.857ms
06-02 23:22:55.487 32469-3238/com.example.myapp E/MediaPlayer: error (1, -2147483648)
06-02 23:22:55.500 32469-32469/com.example.myapp E/MediaPlayer: Error (1,-2147483648)
06-02 23:22:55.500 32469-32469/com.example.myapp D/VideoView: Error: 1,-2147483648
06-02 23:22:55.503 32469-32469/com.example.myapp D/VideoPlayerActivity: MediaPlayer error: what = 1 extra = -2147483648
06-02 23:22:55.556 32469-32474/com.example.myapp I/art: Do partial code cache collection, code=62KB, data=52KB
06-02 23:22:55.556 32469-32474/com.example.myapp I/art: After code cache collection, code=62KB, data=52KB
06-02 23:22:55.556 32469-32474/com.example.myapp I/art: Increasing code cache capacity to 256KB

Теперь некоторые люди скажут вам, что видео, которое вы хотите воспроизвести, просто не поддерживает кодек на устройстве. Ни в коем случае ... во-первых, я все еще могу воспроизводить одно и то же видео на том же устройстве, используя Android 5.0.2, но не 5.1.1. Во-вторых, если я возьму URL-адрес видео и загружу его в WebView на 5.1.1 и выше, он будет воспроизводиться. Так что дело не в кодеке или железе. Я пробовал все варианты кодирования/декодирования URL-адресов, но ничего из этого не сработало.

Вот код, который я использую:

Uri videoUri = Uri.parse(vidAddress);
        MediaController mediaController = new MediaController(this);
        mediaController.setAnchorView(videoView);
        videoView.setMediaController(mediaController);
        videoView.setVideoURI(videoUri, headers);
        videoView.seekTo(resumePoint);
        videoView.setMediaController(null);
        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(final MediaPlayer mp) {
                View loadingIndicator = findViewById(R.id.loading_indicator);
                loadingIndicator.setVisibility(View.GONE);

                videoProgress.setMax(videoView.getDuration());
                videoProgress.setSecondaryProgress(videoView.getDuration());
                endTime.setText(getTimeString(videoView.getDuration()));
            }
        });

        videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(final MediaPlayer mp) {
                finish();
            }
        });

videoView.start();

ОБНОВЛЕНИЕ: Поскольку некоторые URL-адреса действительно работают с приведенным выше кодом, я добавляю дополнительную информацию. Я использую URL-адреса видео в формате MP4, хранящиеся на Google Диске. Переменная videoUri заполняется с использованием поля downloadUrl из ответа Google Drive File, а headers содержит заголовок авторизации с токеном для учетной записи, вошедшей в систему. Как я уже сказал, ВЕСЬ этот код, не измененный выше, без проблем работает с API 5.0.2 и ниже, а не с 5.1.1. Тесты проводились с двумя устройствами с одинаковым оборудованием (два Nexus 5x и два Nexus Player), не меняя ничего, кроме версии ОС. Приведенный выше код работает как на 5x, так и на проигрывателе с версией 5.0.2, но не работает ни на одной из версий 5.1.1.


comment
Этот ответ кажется лучшим в 2019 году: stackoverflow.com/questions/52892844/   -  person Duane    schedule 25.12.2019


Ответы (3)


Под прикрытием, когда вы вызываете setVideoUri(), он вызывает MediaPlayer.setDataSource(Context, Uri)`, который поддерживает только URI контента (т. е. не URL-адреса http/https).

Вместо этого предлагается использовать ExoPlayer, который имеет гораздо больше возможностей и полностью поддерживает потоковую передачу с веб-URL. Если вы хотите поддерживать интерфейс типа VideoView, вы можете использовать библиотеку-оболочку, например ExoMedia.

person ianhanniballake    schedule 03.06.2016
comment
Глядя на исходный код API 21, если схема не является файлом, setDataSource(Context, Uri)в конечном итоге вызывает nativeSetDataSource(MediaHTTPService.createHttpServiceBinderIfNecessary(path),path,keys,values); Так что кажется, что это должно быть хорошо для URL-адресов. И некоторые URL-адреса ДЕЙСТВИТЕЛЬНО работают, только тот, который я использую, почему-то работает только для Android 5.0.2 и ниже. - person Dapp; 04.06.2016

Вы пробовали использовать videoView.start() после videoView.setVideoURI(). Я пробовал это, используя URL-адрес HTTP, и это работает. Или, может быть, что-то не так с протоколом HTTPs?

person Beck    schedule 03.06.2016

Используйте MediaController для воспроизведения видео с URL

VideoView videoview;
MediaController mediacontroller;
try {
            mediacontroller = new MediaController(VideoPlayActivity.this);
            mediacontroller.setAnchorView(videoview);
            Uri video = Uri.parse(VideoURL);
            videoview.setMediaController(mediacontroller);
            videoview.setVideoURI(video);

        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
person Milan Pansuriya    schedule 03.06.2016
comment
Я специально устанавливаю медиа-контроллер на ноль, чтобы использовать собственный элемент управления видео, который я написал. Несмотря на это, медиаконтроллер вообще не должен влиять на возможность воспроизведения, он просто добавляет элементы управления видео (воспроизведение/пауза, поиск) для взаимодействия с потоком во время его воспроизведения. - person Dapp; 04.06.2016