Android ExoPlayer-同时下载视频(非DASH/HLS)并流式传输 [英] Android ExoPlayer - downloading video (non DASH / HLS) and streaming at the same time

查看:142
本文介绍了Android ExoPlayer-同时下载视频(非DASH/HLS)并流式传输的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to download a video that is streaming in ExoPlayer.

顺便说一句,甚至在使用ExoPlayer之前,我都从HttpURLConnection提供的输入流中下载了一个文件,并从本地存储中播放了该文件.可以,但是并不能解决我同时进行流式传输和缓存的问题.

As an aside and even before using ExoPlayer I downloaded a file from an input stream provided by HttpURLConnection and played the file from local storage. This is ok, however it does not solve my problem of simultaneous streaming and caching.

ExoPlayer还提供了一个缓存系统,这些似乎仅适用于DASH或HLS流类型.我没有使用任何这些,并且想用ExtractorRendererBuilder缓存mp4. (此主题在此处广泛涉及: https://github.com/google/ExoPlayer/issues/420 ).

ExoPlayer also provides a caching system and these seem to work only for DASH or HLS stream types. I am using none of these and want to cache mp4 with the ExtractorRendererBuilder. (This topic is covered quite extensively here: https://github.com/google/ExoPlayer/issues/420).

DefaultHttpDataSource确实具有公开HttpURLConnection的api,但是我不确定我是否在重用流.这是ExoPlayer中提供的示例代码.

DefaultHttpDataSource does have an api that exposes HttpURLConnection but I am not sure I am reusing the stream. Here is the code from the samples provided in 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的类:

What I have done now is extend DefaultHttpDataSourceand use HttpURLConnection to get an InputStream, write to a file in getCacheDir(). Here is the class that extends 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/或方法可以访问流传输发生时可以写入文件的字节数组?

I can now get an InputStream via getURLConnection() to save video into a file but I am not really happy using an InputStream again to cache the video. Is there any other API/ or method that gives access to a byte array that I can write to a file while streaming takes place ?

我的其他stackoverflow搜索尚未提供解决方案:

My other stackoverflow searches have not given a solution yet:

在ExoPlayer中使用缓存

ExoPlayer缓存

感谢您的时间和耐心.

推荐答案

我找到了一个仅有问题的解决方案:向后或向前搜索不起作用.

I found a solution with just an issue: seeking backward or forward is not working.

这是一段代码:

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

这篇关于Android ExoPlayer-同时下载视频(非DASH/HLS)并流式传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆