Android ExoPlayer - загрузка видео (не DASH/HLS) и потоковое воспроизведение в одно и то же время

Я хотел бы загрузить видео, которое транслируется в ExoPlayer.

В качестве стороннего и даже до использования ExoPlayer я загрузил файл из входного потока, предоставленного HttpURLConnection, и воспроизвел файл из локального хранилища. Это нормально, однако это не решает мою проблему одновременной потоковой передачи и кеширования.

ExoPlayer также предоставляет систему кэширования, и они, похоже, работают только для типов потоков DASH или HLS. Я не использую ни один из них и хочу кэшировать mp4 с помощью ExtractorRendererBuilder. (Эта тема довольно подробно освещена здесь: https://github.com/google/ExoPlayer/issues/420).

DefaultHttpDataSource имеет api, который предоставляет HttpURLConnection, но я не уверен, что повторно использую поток. Вот код из образцов, представленных в ExoPlayer.

    @Override
    public void buildRenderers(DemoPlayer player) {
        Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
        Handler mainHandler = player.getMainHandler();

        // Build the video and audio renderers.
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(mainHandler, null);
        DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter,userAgent);
        ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri,dataSource,allocator,
                BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE, mainHandler, player, 0);
        MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
                sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
                mainHandler, player, 50);
        MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
                MediaCodecSelector.DEFAULT, null, true, mainHandler, player,
                AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
        TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
                mainHandler.getLooper());

        // Invoke the callback.
        TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT];
        renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer;
        renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer;
        renderers[DemoPlayer.TYPE_TEXT] = textRenderer;
        player.onRenderers(renderers, bandwidthMeter);
    }

То, что я сделал сейчас, это расширение DefaultHttpDataSource и использование HttpURLConnection для получения InputStream, запись в файл в getCacheDir(). Вот класс, который расширяет DefaultHttpDataSource:

public class CachedHttpDataSource extends DefaultHttpDataSource {
    public CachedHttpDataSource(String userAgent, Predicate<String> contentTypePredicate) {
        super(userAgent, contentTypePredicate);
    }

    public CachedHttpDataSource(String userAgent, Predicate<String> contentTypePredicate, TransferListener listener) {
        super(userAgent, contentTypePredicate, listener);
    }

    public CachedHttpDataSource(String userAgent, Predicate<String> contentTypePredicate, TransferListener listener, int connectTimeoutMillis, int readTimeoutMillis) {
        super(userAgent, contentTypePredicate, listener, connectTimeoutMillis, readTimeoutMillis);
    }

    public CachedHttpDataSource(String userAgent, Predicate<String> contentTypePredicate, TransferListener listener, int connectTimeoutMillis, int readTimeoutMillis, boolean allowCrossProtocolRedirects) {
        super(userAgent, contentTypePredicate, listener, connectTimeoutMillis, readTimeoutMillis, allowCrossProtocolRedirects);
    }

    public HttpURLConnection getURLConnection(){
        HttpURLConnection connection = getConnection();

        return getConnection();
    }
}

Теперь я могу получить InputStream через getURLConnection(), чтобы сохранить видео в файл, но мне не очень нравится снова использовать InputStream для кэширования видео. Есть ли другой API/или метод, который дает доступ к массиву байтов, который я могу записать в файл во время потоковой передачи?

Мои другие поиски stackoverflow еще не дали решения:

Использование кеша в ExoPlayer

Кэш ExoPlayer

Спасибо за ваше время и терпение.

Ответ 1

Я нашел решение с какой-то проблемой: поиск назад или вперед не работает.

Это фрагмент кода:

public void preparePlayer(String videoUri) {
    MediaSource videoSource =
            new ExtractorMediaSource( Uri.parse( videoUri ), dataSourceFactory, extractorsFactory, handler, null );
    exoPlayer.prepare( videoSource );
    exoPlayer.setPlayWhenReady( true );
}

public DataSource.Factory buildDataSourceFactory() {
    return new DataSource.Factory() {
        @Override
        public DataSource createDataSource() {
            LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor( CACHE_SIZE_BYTES );
            File cacheDir = //Your cache dir
            SimpleCache simpleCache = new SimpleCache( cacheDir, evictor );
            DataSource dataSource = buildMyDataSourceFactory().createDataSource();
            int cacheFlags = CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_CACHE_UNBOUNDED_REQUESTS;
            return new CacheDataSource( simpleCache, dataSource, cacheFlags, CACHE_SIZE_BYTES );
        }
    };
}

private DefaultDataSource.Factory buildMyDataSourceFactory() {
    return new DefaultDataSourceFactory( context, "jesty-android", new DefaultBandwidthMeter() );
}

Источник: https://github.com/google/ExoPlayer/issues/420#issuecomment-244652023