【问题标题】:Android ExoPlayer - downloading video (non DASH / HLS) and streaming at the same timeAndroid ExoPlayer - 同时下载视频(非 DASH / HLS)和流式传输
【发布时间】:2016-10-12 23:38:00
【问题描述】:

我想下载在 ExoPlayer 中流式传输的视频。

顺便说一句,甚至在使用 ExoPlayer 之前,我从HttpURLConnection 提供的输入流中下载了一个文件,并从本地存储中播放了该文件。这没关系,但它并不能解决我同时流式传输和缓存的问题。

ExoPlayer 还提供了一个缓存系统,这些似乎只适用于 DASH 或 HLS 流类型。我没有使用这些,想用ExtractorRendererBuilder 缓存mp4。 (这个话题在这里被广泛讨论:https://github.com/google/ExoPlayer/issues/420)。

DefaultHttpDataSource 确实有一个公开 HttpURLConnection 的 api,但我不确定我是否正在重用流。这是 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();
    }
}

我现在可以通过 getURLConnection() 获取 InputStream 以将视频保存到文件中,但我不太高兴再次使用 InputStream 来缓存视频。是否有任何其他 API/或方法可以访问字节数组,我可以在流式传输时写入文件?

我的其他stackoverflow搜索还没有给出解决方案:

Using cache in ExoPlayer

ExoPlayer cache

感谢您的时间和耐心。

【问题讨论】:

    标签: android offline-caching 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

    【讨论】:

    • 你能告诉我如何在按钮点击时开始缓存视频,比如当用户想要下载在 exoplayer 中运行的 hls 视频时如何实现这一点,任何帮助将不胜感激:)
    猜你喜欢
    • 2014-03-27
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多