Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Плеер не играет некоторые видео #1

Closed
sadr0b0t opened this issue Dec 3, 2019 · 6 comments
Closed

Плеер не играет некоторые видео #1

sadr0b0t opened this issue Dec 3, 2019 · 6 comments
Labels
bug Something isn't working content

Comments

@sadr0b0t
Copy link
Owner

sadr0b0t commented Dec 3, 2019

Сначала простые - требуют логин для указания возраста, а мы не логинимся:

Илья Муромец
https://www.youtube.com/watch?v=hooaKxdXbfM

Руслан и Людмила 1-ая серия / Ruslan and Lyudmila film 1
https://www.youtube.com/watch?v=2UoO2t536Ko

А вот эти логин не просят, но не играют, в ньюпайпе тоже не играют, в браузере играют без логина:

Боевые страницы (1939) фильм смотреть онлайн
https://www.youtube.com/watch?v=AEW85bEznCw

Кошкин дом (1982) Кукольный мультфильм | Золотая коллекция
https://www.youtube.com/watch?v=AlQuWA5vHVI

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

16 Адаптация Организма
https://www.youtube.com/watch?v=AWCiltL3wJY

(с иконкой, похоже, понятно, просто она не задана для видео, в браузере ее тоже нет)

Еще бывают ролики, для которых ютюб сразу возвращает неопределенное время проигрывания (вроде сервисных заставок), но это не они.

@sadr0b0t sadr0b0t added the bug Something isn't working label Dec 3, 2019
@sadr0b0t
Copy link
Owner Author

sadr0b0t commented Dec 3, 2019

Код загрузки видео здесь - метод playVideoStream
https://github.com/sadr0b0t/yashlang/blob/master/app/src/main/java/su/sadrobot/yashlang/WatchVideoActivity.java

Адрес потока stream url получаем отсюда (через NewPipe)
ContentLoader.getInstance().extractYtStreamUrl(currentVideo.getYtId())

Текущая версия (exoplayer 2.7.3)

по инструкции отсюда
https://androidwave.com/play-youtube-video-in-exoplayer/

        com.google.android.exoplayer2.upstream.DataSource.Factory videoDataSourceFactory
                = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "yashlang"), bandwidthMeter);
...
        Uri mp4VideoUri = Uri.parse(streamUrl);
        MediaSource videoSource;
        if (streamUrl.toUpperCase().contains("M3U8")) {
            videoSource = new HlsMediaSource(mp4VideoUri, videoDataSourceFactory, null, null);
        } else {
            videoSource = new ExtractorMediaSource(mp4VideoUri, videoDataSourceFactory, new DefaultExtractorsFactory(),
                    null, null);
        }

        ((SimpleExoPlayer) videoPlayerView.getPlayer()).prepare(videoSource);

Вот здесь советуют использовать OkHttpDataSourceFactory вместо обычной OkHttpDataSourceFactory
https://stackoverflow.com/questions/40453444/exoplayer-not-working-for-some-streams
https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.html
google/ExoPlayer#1157
https://square.github.io/okhttp/

Попробовал:

в build.gradle (уровень приложения) добавил

    implementation 'com.squareup.okhttp3:okhttp:4.2.1'
    implementation 'com.google.android.exoplayer:extension-okhttp:r2.0.1'
        MediaSource videoSource = new ExtractorMediaSource(
                mp4VideoUri,
                new OkHttpDataSourceFactory(
                        new OkHttpClient(),
                        Util.getUserAgent(this, "yashlang"),
                        null
                ),
                new DefaultExtractorsFactory(),
                null,
                null
        );
...
        ((SimpleExoPlayer) videoPlayerView.getPlayer()).prepare(videoSource);

легче не стало, старые ролики вроде продолжают открываться, проблемные ролики всё равно не открываются, apk потолстел на 1 Мб.

@sadr0b0t
Copy link
Owner Author

sadr0b0t commented Dec 3, 2019

Обновиил ExoPlayer до последней версии 2.10.8

https://exoplayer.dev/hello-world.html
google/ExoPlayer#5276

android {
    compileOptions {
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
...
implementation 'com.google.android.exoplayer:exoplayer:2.10.8'

Вариант с OkHttpDataSourceFactory на проблемных видео не заработал, на обычных видео начал вылетать с эксепшеном, в общем, это вариант нах.

старый вариант тоже перестал компилироваться из-за изменений в API. Сравнение на "M3U8" не очень понятно, когда срабатывается, те видео, на которые попадают в плейлист, похоже все загружаются с датасорсом ExtractorMediaSource. Теперь вместо него ProgressiveMediaSource.

https://stackoverflow.com/questions/56661984/android-exoplayer-extractormediasource-is-deprecated
https://exoplayer.dev/progressive.html

теперь видео загружается так:

final MediaSource videoSource = new ProgressiveMediaSource.Factory(videoDataSourceFactory)
                .createMediaSource(mp4VideoUri);
...
        ((SimpleExoPlayer) videoPlayerView.getPlayer()).prepare(videoSource);

играет, как и раньше, - в основном ролики открываются, проблемные ролики так и не открываются, ну хоть обновились до последнего API.

на всякий случай: HlsMediaSource теперь создается так (но мы его использовать пока больше не будем):

HlsMediaSource videoSource =
                new HlsMediaSource.Factory(videoDataSourceFactory).createMediaSource(mp4VideoUri);

283081e

@sadr0b0t
Copy link
Owner Author

sadr0b0t commented Dec 3, 2019

Проведить дальше:

  • Посмотреть, какую ссылку на поток экстрактит для проблемных роликов NewPipe, может она не рабочая

  • Посмотреть, какой адрес потока экстрактится в старой инструкции
    https://androidwave.com/play-youtube-video-in-exoplayer/

они там используют некий youtubeExtractor (я раньше его тоже не использовал)

implementation 'com.github.HaarigerHarald:android-youtubeExtractor:v1.7.0'

@sadr0b0t
Copy link
Owner Author

sadr0b0t commented Dec 3, 2019

Код для YouTubeExtractor примерно такой:

    implementation 'com.github.HaarigerHarald:android-youtubeExtractor:v1.7.0'
    private void extractYoutubeUrl(String ytUrl) {
        YouTubeExtractor mExtractor = new YouTubeExtractor(this) {
            @Override
            protected void onExtractionComplete(SparseArray<YtFile> sparseArray, VideoMeta videoMeta) {
                if (sparseArray != null) {

                    System.out.println(sparseArray.size());
                    System.out.println("yte: " + sparseArray.get(17).getUrl());
                }
            }
        };
        mExtractor.extract(ytUrl, true, true);
    }
// загрузить поток видео
//String ytId = "AEW85bEznCw"; // боевые страницы
//String ytId = "AlQuWA5vHVI"; // кошкин дом
String ytId = "AWCiltL3wJY"; // адаптация организма
//String ytId = "9M286oRxFxs"; // колобок (играет ок)

extractYoutubeUrl("https://www.youtube.com/watch?v=%s".replace("%s", ytId));

для Колобка (который обычно играет ок) вылетает с null pointer на sparseArray.get(17).getUrl()

Для тех, которые не играют, эксепшен в консоль:

java.io.FileNotFoundException: https://s.ytimg.com/yts/jsbin/null
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:251)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:26)
    at at.huber.youtubeExtractor.YouTubeExtractor.decipherSignature(YouTubeExtractor.java:454)
    at at.huber.youtubeExtractor.YouTubeExtractor.getStreamUrls(YouTubeExtractor.java:394)
    at at.huber.youtubeExtractor.YouTubeExtractor.doInBackground(YouTubeExtractor.java:194)
    at at.huber.youtubeExtractor.YouTubeExtractor.doInBackground(YouTubeExtractor.java:33)
    at android.os.AsyncTask$2.call(AsyncTask.java:333)

NewPipe адреса проблемных стримов не выдаёт просто (ContentLoader.extractYtStreamUrl возвращает null).

отсюда null:

final String streamUrl = extractor.getVideoStreams().size() > 0 ? extractor.getVideoStreams().get(0).getUrl() : null;

Для примера, адрес стрима Колобка (который выдает NewPipe):
https://r2---sn-045oxu-31oe.googlevideo.com/videoplayback?expire=1575431557&ei=JdnmXff1IYSGyQXN3JmQCw&ip=185.44.11.0&id=o-AB5sVsktciL5Ka8EjJkXTpMMcb_DPkPTDzjCCtnflccR&itag=22&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-045oxu-31oe%2Csn-n8v7zns6&ms=au%2Crdu&mv=m&mvi=1&pcm2cms=yes&pl=24&gcr=ru&initcwndbps=2016250&mime=video%2Fmp4&ratebypass=yes&dur=814.068&lmt=1547838310320952&mt=1575409810&fvip=6&fexp=23842630&c=WEB&txp=5535432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cgcr%2Cmime%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRgIhALuF20qi5ZrKbjI5EWygGz1YZAmsLE0Eprx70XYR20-qAiEA7q6p3tJOZz3VwIW_8FKBqAs9ND0wRbZhmyOoscNyjHo%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpcm2cms%2Cpl%2Cinitcwndbps&lsig=AHylml4wRQIhAJIkJEW8XpXvAMnOrP2Ew7UkgPaSTAPLvR01tup19XEgAiAlmJub9K5XofgiR6gLyxCKe2286YpW1cErw6U3tzZTng%3D%3D

@sadr0b0t
Copy link
Owner Author

sadr0b0t commented Dec 3, 2019

Да, из этого сразу видно, что дело не в плеере, а в экстракторе адреса стрима в NewPipe, можно засабмитить им баг.

@sadr0b0t
Copy link
Owner Author

sadr0b0t commented Dec 4, 2019

Обновил NewPipeExtractor до 0.17.4, все заработало (кроме тех роликов, которые требуют авторизацию, и у которых изначально нулевая длина, но они и не должны)

ae9bf60

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working content
Projects
None yet
Development

No branches or pull requests

1 participant