【问题标题】:Enabling cache for exoplayer为 exoplayer 启用缓存
【发布时间】:2020-01-28 08:03:56
【问题描述】:

我已经为 hls 视频链接实现了 exoplayer,一旦视频再次播放,它就会加载要播放的视频,任何人都可以建议如何在视频完全流式传输后停止再次加载并在不缓冲的情况下播放。 如何为hls流媒体视频存储缓存。如有解决方案,请提供。 在此先感谢:)

 TrackSelector trackSelector = new DefaultTrackSelector(this);

    DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
            .setBufferDurationsMs(1024, 64 * 1024, 1024, 1024)
            .createDefaultLoadControl();


    videoView = findViewById(R.id.video_view);
    player = ExoPlayerFactory.newSimpleInstance(this, trackSelector,loadControl);

// player = ExoPlayerFactory.newSimpleInstance(this);

    player.setPlayWhenReady(true);
    videoView.setPlayer(player);

    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
    Util.getUserAgent(this, "ExoPlayer"));

// Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();


    MediaSource mediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(videoUrl));

    player.prepare(mediaSource);
    player.setPlayWhenReady(true);

【问题讨论】:

标签: android caching video http-live-streaming exoplayer


【解决方案1】:

方法一:使用Exoplayer缓存策略

第 1 步:实施 Exoplayer

implementation 'com.google.android.exoplayer:exoplayer-core:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.15.0'

第 2 步:在您的应用程序类中创建缓存策略

public SimpleCache simpleCache;
@Override
    public void onCreate() {
        super.onCreate();

        LeastRecentlyUsedCacheEvictor leastRecentlyUsedCacheEvictor = new LeastRecentlyUsedCacheEvictor(100 * 1024 * 1024);
        if (simpleCache == null) {
            simpleCache = new SimpleCache(getCacheDir(), leastRecentlyUsedCacheEvictor, new ExoDatabaseProvider(this));
        }
}

第 3 步:像下面的方法一样缓存内容

Uri videoUri = Uri.parse("YOUR URL");
        MediaItem mediaItem = MediaItem.fromUri(videoUri);
        DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true);
        DefaultDataSource.Factory defaultDataSourceFactory = new DefaultDataSourceFactory(requireContext(), httpDataSourceFactory);
        CacheDataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory()
                .setCache(MyApplication.getAppInstance().simpleCache)
                .setUpstreamDataSourceFactory(defaultDataSourceFactory)
                .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);

        MediaSource mediaSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
                .createMediaSource(mediaItem);
        player.setMediaSource(mediaSource, true);

方法二: Android 视频缓存库完全符合您的要求。按照以下步骤缓存您的视频。

第 1 步:implementation 'com.danikula:videocache:2.7.1'

第 2 步:将共享代理存储在您的应用程序类中

public class MyApplication extends Application {
    private HttpProxyCacheServer proxy;
        public static HttpProxyCacheServer getProxy(Context context) {
            MyApplication app = (MyApplication) context.getApplicationContext();
            return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;
        }
    
        private HttpProxyCacheServer newProxy() {
            return new HttpProxyCacheServer.Builder(this)
                    .maxCacheSize(1024 * 1024 * 1024)
                    .build();
            //return new HttpProxyCacheServer(this);
    
        }
}

第 3 步:将 MyApplication 类放入清单文件中,如

<application
        android:name=". MyApplication">
.
.
.
</application>

第 4 步:使用来自代理的 url 而不是原始 url 来添加缓存

HttpProxyCacheServer proxy = MyApplication.getProxy(activity);
            String proxyUrl = proxy.getProxyUrl(VIDEO_URL);
            videoView.setVideoPath(proxyUrl);

如果你正在使用 exoplayer

HttpProxyCacheServer proxy = getProxy(activity);
                String proxyUrl = proxy.getProxyUrl(VIDEO_URL);
PlayerView playerView = findViewById(R.id.video_view);
      ExoPlayer player = ExoPlayerFactory.newSimpleInstance(VideoActivity.this,
                new DefaultRenderersFactory(this),
                new DefaultTrackSelector());
        MediaSource mediaSource = buildMediaSource(proxyUrl);
        player.prepare(mediaSource, true, false);
        playerView.setPlayer(player);

快乐编码:)

【讨论】:

  • 感谢您的回复,我会实施并让您知道是否有任何问题。再次感谢。
  • 返回 app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;给出错误。 (无法解析符号“代理”)
  • 第二步:在你的Application类中存储共享代理,这是什么意思。
  • @AkashManjhi 以非常简单的方式编辑了我的答案。如果您想了解,请进行谷歌搜索,您将得到错误的所有答案。
  • 我已经实现了你的代码,但是视频没有播放。
【解决方案2】:

这应该在单例类中的某个地方

    val dbProvider = ExoDatabaseProvider(context)
    val cacheSize = 100 * 1024 * 1024 //100 mb
    simpleCache = SimpleCache(
        File(context.filesDir, "media"),
        LeastRecentlyUsedCacheEvictor(cacheSize), 
        dbProvider
    )

使用播放器写入您的片段或活动

val defaultDataSourceFactory = DefaultDataSourceFactory(context, DefaultHttpDataSourceFactory("Exo Player"))
val cacheFactory = CacheDataSourceFactory(simpleCache, defaultDataSourceFactory)
val mediaSource = DownloadHelper.createMediaSource(request, cacheFactory)
player.prepare(mediaSource)

附:您可以以不同的方式计算缓存大小。 Google 建议根据设备 RAM 创建它

    // Get max available VM memory, exceeding this amount will throw an
    // OutOfMemory exception. Stored in kilobytes as LruCache takes an
    // int in its constructor.
    val maxMemory = Runtime.getRuntime().maxMemory()

    // Use 1/8th of the available memory for this memory cache.
    val cacheSize = maxMemory / 8
    val evictor  = LeastRecentlyUsedCacheEvictor(cacheSize)

【讨论】:

    猜你喜欢
    • 2014-11-23
    • 2015-04-26
    • 2019-03-18
    • 1970-01-01
    • 2021-08-19
    • 2015-03-16
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    相关资源
    最近更新 更多