Exoplayer使用记录3-网络播放相关的一些事
2018-02-25 00:37
232 查看
Exoplayer使用记录3-网络播放相关的一些事
By Xdestiny. 2018/2/5概述
网络播放本来其实没啥好说的,毕竟ExoPlayer都已经封装的很完善了。但毕竟有时候还需要一些特殊功能,例如缓存功能、限制下载速度,等等。缓存功能
对于在线播放来说,缓存可以说不可或缺的。那么在ExoPlayer中要怎么做呢?先翻翻文档好了。果然,有一个SimpleCache是可以使用的。那么,大体上来说,缓存功能可以这么做
- 首先搞一个用于下载、删除缓存的接口。利用
SimpleCache将视频存储在本地的某一个位置
- 读取URL的时候,同样声明一个
SimpleCache到同样的路径。这样Exoplayer内部会匹配URL与缓存文件。如果之前有缓存,那么就能够直接使用缓存
下载速度限制
有了缓存功能,那么就又来了个新问题…缓存的时候总不好把人带宽占满吧?那么就需要限制下下载速度老样子,先上Issue上搜搜有啥思路没。搜一下立刻发现已经有人问过了
Is there a method to limit the downloading bandwidth
里面也给了个思路,大致是对
DataSource进行一些限制。其实,在缓存的时候,必然会启动一个线程进行下载的操作,那么可以在这个时候线程进行一段时间,然后暂停一段时间。
具体代码
class MyCache(activity: Activity, uri: String, isExternalCache: Boolean = true) : CacheDataSource.EventListener { private val TAG = "MyCache" private val MAX_BYTE_SIZE: Long = 4L*1024*1024*1024 private val m_context = activity private val m_isExternalCache = isExternalCache private val m_uri = uri private val simpleCache = SimpleCache(File(if(m_isExternalCache) m_context.externalCacheDir else m_context.cacheDir, "media_cache"), NoOpCacheEvictor()) private val cacheDataSourceFactory = CacheDataSourceFactory(simpleCache, DefaultDataSourceFactory(m_context, Util.getUserAgent(m_context, "ExoPlayerBridge"), DefaultBandwidthMeter()), FileDataSourceFactory(), CacheDataSinkFactory(simpleCache, Long.MAX_VALUE), 0, this) var IsCaching = false private set(value) {field = value} get() = field var LimitSpeedRatio: Float = 0.0f var CacheByte: Long = Math.max(0, simpleCache.getCachedBytes(m_uri, 0, MAX_BYTE_SIZE)) get() = field private set(value) { field = value } var ContentByte: Long = -1 get() = simpleCache.getContentLength(m_uri) var CachedSpace: Long = 0 get() = simpleCache.cacheSpace private var th : Thread? = null init{ } fun PreCache(){ //缓存功能 if(!m_uri.startsWith("http") || IsCaching) return Log.d(TAG, "Start cache. Uri = $m_uri") LimitSpeedRatio = 0.0f //限速比例 th = thread(true){ IsCaching = true val dataSpec = DataSpec(Uri.parse(m_uri)) val dataSource = cacheDataSourceFactory.createDataSource() try{ dataSource.open(dataSpec) val scratchSpace = ByteArray(32 * 1024) var bytesRead = 0 CacheByte = 0 var miliSec = 0L while (bytesRead != C.RESULT_END_OF_INPUT && IsCaching) { val lastMiliSec = System.currentTimeMillis() CacheByte += bytesRead bytesRead = dataSource.read(scratchSpace, 0, scratchSpace.size) miliSec += System.currentTimeMillis() - lastMiliSec if(miliSec > 100 && LimitSpeedRatio > 0.01){ Thread.sleep((LimitSpeedRatio * 100L).toLong()) miliSec = 0 } } } catch (e : IOException){ Log.e(TAG, e.toString()) } finally { try{ IsCaching = false dataSource.close() } catch (e : Exception){ e.printStackTrace() } } } } fun CleanCache(){ //删除缓存 if(!m_uri.startsWith("http") || IsCaching) return Log.d(TAG, "Clean cache. Uri = $m_uri") simpleCache.getCachedSpans(m_uri)?.forEach { it -> simpleCache.removeSpan(it) } CacheByte = 0 } fun StopCache(){ //停止缓存 if(!m_uri.startsWith("http") || !IsCaching) return Log.d(TAG, "Stop cache. Uri = $m_uri") IsCaching = false } override fun onCachedBytesRead(cacheSizeBytes: Long, cachedBytesRead: Long) { } }
这里我省略很多东西,比如空间满了之类的…
之后就是在建立
ExoPlayer的时候,将
SimpleCache作为参数输入即可
exoPlayer = MyExoPlayer(MyTrackRenderersFactory(activity, null, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF, videoCnt, audioCnt), DefaultTrackSelector()) simpleCache = SimpleCache(File(m_context.externalCacheDir, "media_cache"), NoOpCacheEvictor()) cacheDataSourceFactory = CacheDataSourceFactory(simpleCache, DefaultHttpDataSourceFactory(Util.getUserAgent(m_context, "ExoPlayer"), DefaultBandwidthMeter()), FileDataSourceFactory(), null, 0, this) videoSource = ExtractorMediaSource(Uri.parse(url), cacheDataSourceFactory, DefaultExtractorsFactory(), null, null, url) exoPlayer.prepare(videoSource)
相关文章推荐
- Exoplayer使用记录1-播放多音轨视频
- 开源视频播放器IjkPlayer使用记录之(三)--播放视频从上次播放的时间点播放。
- 记录下用MPMoviePlayerViewController做视频播放的一些问题
- VideoView (Vitamioplayer使用)播放网络视频
- 一些docker使用的相关记录
- 使用JiaoZiVideoPlayer播放网络视频,暂停继续
- 新版网络学堂播放视频升级,使用Flowplayer插件, 一款免费的WEB视频播放器
- 使用JiaoZiVideoPlayer播放网络视频,暂停继续(三)
- ExoPlayer播放视频的简单使用及播放视频宽高设置的源码分析
- 网络相关的一些基本的命令的使用(ping、ifconfig、route、netstat)---Linux学习笔记
- 关于iOS网络音频播放的一些详解(使用AVPlayer播放网络音频)
- XUtils3.0+ 关于网络请求使用的一些相关整理
- 一些linux应用小技巧,网络相关,系统管理,shell,程序使用
- Android视频播放框架Vitamio集成及使用MediaPlayer+SurfaceView、VideoView+MediaController实现播放网络视频
- Exoplayer使用记录4-调节音轨中某个频道的声音
- 使用JiaoZiVideoPlayer播放网络视频,暂停继续
- VS2005 && MasterPage && Form 的一些相关使用记录
- 初学eclipse,记录一些有关eclipse IDE使用的东东
- C#、VB.NET 使用System.Media.SoundPlayer播放音乐
- 百度笔试题2005题目大致是这样的: 第一部分选择题: 有几道网络相关的题目,巨简单,比如第一题是TCP、RIP、IP、FTP中哪个协议是传输层的......。有一道linux的 chown使用题目。其他的全是数据结构的题目!什么链,表