当前位置: 首页 > news >正文

网站第三方登录怎么做湖南省建设厅安许审核公布网站

网站第三方登录怎么做,湖南省建设厅安许审核公布网站,山西推广型网站建设,网站每年服务费系列文章目录 ExoPlayer架构详解与源码分析#xff08;1#xff09;——前言 ExoPlayer架构详解与源码分析#xff08;2#xff09;——Player ExoPlayer架构详解与源码分析#xff08;3#xff09;——Timeline ExoPlayer架构详解与源码分析#xff08;4#xff09;—…系列文章目录 ExoPlayer架构详解与源码分析1——前言 ExoPlayer架构详解与源码分析2——Player ExoPlayer架构详解与源码分析3——Timeline ExoPlayer架构详解与源码分析4——整体架构 ExoPlayer架构详解与源码分析5——MediaSource ExoPlayer架构详解与源码分析6——MediaPeriod ExoPlayer架构详解与源码分析7——SampleQueue ExoPlayer架构详解与源码分析8——Loader ExoPlayer架构详解与源码分析9——TsExtractor ExoPlayer架构详解与源码分析10——H264Reader ExoPlayer架构详解与源码分析11——DataSource ExoPlayer架构详解与源码分析12——Cache ExoPlayer架构详解与源码分析13——TeeDataSource和CacheDataSource ExoPlayer架构详解与源码分析14——ProgressiveMediaPeriod 文章目录 系列文章目录前言ProgressiveMediaPeriod总结 前言 中途间隔了一段时间之前写了那么多铺垫终于看到ProgressiveMediaPeriod实现部分了 ProgressiveMediaPeriod 有了之前的那些铺垫这里直接看源码了 Overridepublic void prepare(Callback callback, long positionUs) {this.callback callback;loadCondition.open();//保证继续加载的开关打开Loader不阻塞startLoading();}private void startLoading() {ExtractingLoadable loadable //创建loadable 共Loader加载new ExtractingLoadable(//extractorOutput监听也就是Loader加载过程中会回调ProgressiveMediaPeriod的trackendTracksuri, dataSource, progressiveMediaExtractor, /* extractorOutput */ this, loadCondition);if (prepared) {//如果已经准备完成Assertions.checkState(isPendingReset());if (durationUs ! C.TIME_UNSET pendingResetPositionUs durationUs) {//当前定位位置已经超过总时长直接加载结束loadingFinished true;pendingResetPositionUs C.TIME_UNSET;return;}//通过seekMap查找出当前时间对于的数据位置loadable.setLoadPosition(checkNotNull(seekMap).getSeekPoints(pendingResetPositionUs).first.position,pendingResetPositionUs);for (SampleQueue sampleQueue : sampleQueues) {//将所有的轨道开始时间同步sampleQueue.setStartTimeUs(pendingResetPositionUs);}pendingResetPositionUs C.TIME_UNSET;}//获取开始加载时所有轨道已经提前的数据块总数后面通过当前的数据块总数和开始的数量对比可以判断出是否加载了新的数据extractedSamplesCountAtStartOfLoad getExtractedSamplesCount();long elapsedRealtimeMs loader.startLoading(//Loader开始加载具体过程参照Loader部分的文章此时加载状态的回调this也就是加载完成后会调用ProgressiveMediaPeriod onLoadCompletedseekMaploadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(dataType));DataSpec dataSpec loadable.dataSpec;//触发监听mediaSourceEventDispatcher.loadStarted(new LoadEventInfo(loadable.loadTaskId, dataSpec, elapsedRealtimeMs),C.DATA_TYPE_MEDIA,C.TRACK_TYPE_UNKNOWN,/* trackFormat */ null,C.SELECTION_REASON_UNKNOWN,/* trackSelectionData */ null,/* mediaStartTimeUs */ loadable.seekTimeUs,durationUs);}Override//Loader加载时如果解析器需要输出Sample数据会先回调track获取TrackOutputpublic TrackOutput track(int id, int type) {return prepareTrackOutput(new TrackId(id, /* isIcyTrack */ false));}//构建TrackOutputprivate TrackOutput prepareTrackOutput(TrackId id) {int trackCount sampleQueues.length;for (int i 0; i trackCount; i) {//查询当前的sampleQueue是否已创建直接返回if (id.equals(sampleQueueTrackIds[i])) {return sampleQueues[i];}}SampleQueue trackOutput //创建新的SampleQueue对应一个新的轨道这里传入了缓存分配器allocatorSampleQueue.createWithDrm(allocator, drmSessionManager, drmEventDispatcher);trackOutput.setUpstreamFormatChangeListener(this);//设置Format改变的监听NullableTypeTrackId[] sampleQueueTrackIds Arrays.copyOf(this.sampleQueueTrackIds, trackCount 1);sampleQueueTrackIds[trackCount] id;this.sampleQueueTrackIds Util.castNonNullTypeArray(sampleQueueTrackIds);//更新全局的SampleQueue数组NullableType SampleQueue[] sampleQueues Arrays.copyOf(this.sampleQueues, trackCount 1);sampleQueues[trackCount] trackOutput;this.sampleQueues Util.castNonNullTypeArray(sampleQueues);return trackOutput;}Override//当解析器已经将所有轨道解析出来时会调用此方法参照H264Reader部分public void endTracks() {sampleQueuesBuilt true;//当前方法在解析的子线程中回调需要将方法方法当前ProgressiveMediaPeriod的线程中执行maybeFinishPreparehandler.post(maybeFinishPrepareRunnable);}private void maybeFinishPrepare() {if (released || prepared || !sampleQueuesBuilt || seekMap null) {return;}//确保所有轨道均已解析for (SampleQueue sampleQueue : sampleQueues) {if (sampleQueue.getUpstreamFormat() null) {return;}}//阻塞住loader的解析防止继续更新sampleQueuesloadCondition.close();//创建TrackGrouptrackState 供后续的selectTracks使用int trackCount sampleQueues.length;TrackGroup[] trackArray new TrackGroup[trackCount];boolean[] trackIsAudioVideoFlags new boolean[trackCount];for (int i 0; i trackCount; i) {Format trackFormat checkNotNull(sampleQueues[i].getUpstreamFormat());Nullable String mimeType trackFormat.sampleMimeType;boolean isAudio MimeTypes.isAudio(mimeType);boolean isAudioVideo isAudio || MimeTypes.isVideo(mimeType);trackIsAudioVideoFlags[i] isAudioVideo;haveAudioVideoTracks | isAudioVideo;...trackFormat trackFormat.copyWithCryptoType(drmSessionManager.getCryptoType(trackFormat));trackArray[i] new TrackGroup(/* id */ Integer.toString(i), trackFormat);}trackState new TrackState(new TrackGroupArray(trackArray), trackIsAudioVideoFlags);prepared true;//标记准备完成checkNotNull(callback).onPrepared(this);//通知上层prepared 上层接下就会去调用ProgressiveMediaPeriod.selectTracks获取轨道信息}Override//获取轨道public long selectTracks(NullableType ExoTrackSelection[] selections,//TrackSelector 部分会说到boolean[] mayRetainStreamFlags,NullableType SampleStream[] streams,//Renderer部分会说的boolean[] streamResetFlags,long positionUs) {assertPrepared();//确保已经准备完成TrackGroupArray tracks trackState.tracks;boolean[] trackEnabledStates trackState.trackEnabledStates;int oldEnabledTrackCount enabledTrackCount;// 去除原来mayRetainStreamFlags标记的无需保留的轨道for (int i 0; i selections.length; i) {if (streams[i] ! null (selections[i] null || !mayRetainStreamFlags[i])) {int track ((SampleStreamImpl) streams[i]).track;Assertions.checkState(trackEnabledStates[track]);enabledTrackCount--;trackEnabledStates[track] false;streams[i] null;}}//如果是第一次selectTracks而且positionUs 位置又不为0或者之前一次selectTracks禁用了所有的轨道这2种情况就需要Seekboolean seekRequired seenFirstTrackSelection ? oldEnabledTrackCount 0 : positionUs ! 0;// 开始通过selections选择新的轨道for (int i 0; i selections.length; i) {if (streams[i] null selections[i] ! null) {ExoTrackSelection selection selections[i];Assertions.checkState(selection.length() 1);Assertions.checkState(selection.getIndexInTrackGroup(0) 0);int track tracks.indexOf(selection.getTrackGroup());Assertions.checkState(!trackEnabledStates[track]);enabledTrackCount;trackEnabledStates[track] true;streams[i] new SampleStreamImpl(track);//向入参中赋值streamResetFlags[i] true;if (!seekRequired) {SampleQueue sampleQueue sampleQueues[track];seekRequired !sampleQueue.seekTo(positionUs, /* allowTimeBeyondBuffer */ true) sampleQueue.getReadIndex() ! 0;}}}if (enabledTrackCount 0) {pendingDeferredRetry false;notifyDiscontinuity false;if (loader.isLoading()) {// Discard as much as we can synchronously.for (SampleQueue sampleQueue : sampleQueues) {sampleQueue.discardToEnd();}loader.cancelLoading();} else {for (SampleQueue sampleQueue : sampleQueues) {sampleQueue.reset();}}} else if (seekRequired) {positionUs seekToUs(positionUs);// Well need to reset renderers consuming from all streams due to the seek.for (int i 0; i streams.length; i) {if (streams[i] ! null) {streamResetFlags[i] true;}}}seenFirstTrackSelection true;return positionUs;}Override//解析器解析出SeekMap时回调public void seekMap(SeekMap seekMap) {handler.post(() - setSeekMap(seekMap));}Overridepublic boolean continueLoading(long playbackPositionUs) {if (loadingFinished//加载完成出错等情况返回false|| loader.hasFatalError()|| pendingDeferredRetry|| (prepared enabledTrackCount 0)) {return false;}boolean continuedLoading loadCondition.open();if (!loader.isLoading()) {//当前没有正在加载startLoading();//再次startLoadingcontinuedLoading true;}return continuedLoading;}Override//Loader加载完成后回调public void onLoadCompleted(ExtractingLoadable loadable, long elapsedRealtimeMs, long loadDurationMs) {if (durationUs C.TIME_UNSET seekMap ! null) {//此时durationUs 未知seekMap 已经有了boolean isSeekable seekMap.isSeekable();long largestQueuedTimestampUs //查询所有轨道中时间戳最大值getLargestQueuedTimestampUs(/* includeDisabledTracks */ true);durationUs //将最大值10毫秒作为当前媒体的时长largestQueuedTimestampUs Long.MIN_VALUE? 0: largestQueuedTimestampUs DEFAULT_LAST_SAMPLE_DURATION_US;//此时durationUs 等信息已知可以通过MediaSource更新一把TimeLinelistener.onSourceInfoRefreshed(durationUs, isSeekable, isLive);}StatsDataSource dataSource loadable.dataSource;//StatsDataSource可以缓存Uri和ResponseHeader获取这些值构建LoadEventInfo LoadEventInfo loadEventInfo new LoadEventInfo(loadable.loadTaskId,loadable.dataSpec,dataSource.getLastOpenedUri(),dataSource.getLastResponseHeaders(),elapsedRealtimeMs,loadDurationMs,dataSource.getBytesRead());loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId);//触发监听mediaSourceEventDispatcher.loadCompleted(loadEventInfo,C.DATA_TYPE_MEDIA,C.TRACK_TYPE_UNKNOWN,/* trackFormat */ null,C.SELECTION_REASON_UNKNOWN,/* trackSelectionData */ null,/* mediaStartTimeUs */ loadable.seekTimeUs,durationUs);loadingFinished true;//此时的loadingFinished 已为true没设置为false前是无法continueLoading的//请求上层继续加载是否继续加载由上层决定如果上层同意继续加载会调用ProgressiveMediaPeriod的continueLoadingcheckNotNull(callback).onContinueLoadingRequested(this);} 这里再总结下ProgressiveMediaPeriod执行过程 首先调用prepare方法启动Loader去获取资源的轨道信息此处参考ExoPlayer架构详解与源码分析8——LoaderLoader中的解析器获取到信息后回回调endTrack通知ProgressiveMediaPeriod prepare完成ProgressiveMediaPeriod 会进一步通知上层此时MeidaSource已经准备完成上层再Renderer四大组件之一绘制前会通过ExoPlayer的另一大组件TrackSelector后面会说到调用ProgressiveMediaPeriod 的selectTracks选择轨道数据也就将SampleQueue中的数据提供出去此处参考ExoPlayer架构详解与源码分析7——SampleQueue同时Loader从打开到当前加载数据量超过1M默认值时就会阻塞当前的Loader然后询问上层是否继续加载上层主要是通过后面要将LoadControl判断如果上层决定继续加载更多数据就会调用ProgressiveMediaPeriod continueLoading解开阻塞的锁继续加载。因为我们知道数据是加载到内存中的如果无限制的加载肯定是不行的需要有节制的加载和释放数据。而LoadControl就负责这块工作后面会讲到。而上面过程当需要释放已经播放的内存时就会调用discardBuffer方法释放Sample中的内存当所有的数据加载完成的时候会调用onLoadCompleted将loadingFinished 标记为true 总结 到这里Exoplayer中最复杂的组件MediaSource就全部分析完毕了之前说了MediaSource在整个运载火箭中的角色就类似于燃料系统确保火箭顺利升空在运行过程中持续稳定的为火箭提供燃料。这些燃料提供给谁了呢或者说是被谁消耗了呢。这就是下面要讲的火箭的核心发动机Renderers也是Exoplayer四大组件中另一个重要的角色。 版权声明 © 本文为CSDN作者山雨楼原创文章 转载请注明出处 原创不易觉得有用的话收藏转发点赞支持
http://www.hyszgw.com/news/103213/

相关文章:

  • 韩国优秀网站欣赏自媒体害了多少人
  • 表单大师做网站做网站找什么公司好
  • 手机网站app凡科登录网
  • 网帆-网站建设官方店如何修改wordpress站
  • 网站推广的主要方式上海最新新闻
  • 购物网站功能模块整站优化seo排名点击
  • 电商网站制作方案百度收录个人网站是什么怎么做
  • 品牌网站建设哪个好广州兼职网网站建设
  • 网站 制作 报价优化模型数学建模
  • 网站备案前置审批 成都akcms做的网站
  • 重庆建网站诚选快忻科技悉心wordpress官网登录
  • 网站代理浏览器插件50m专线做视频网站
  • 做暧昧在线网站wordpress 发布函数
  • 中江移动网站建设响应式网站网站建设
  • 手机网站触摸版校网站建设方案
  • 备案后可以修改网站吗如何搭建企业网站
  • 专业网站定制公司应用宝下载
  • 做网站的运营维护都要学什么杭州网站设计公司有哪些
  • 手机wap网站特效网页设计与制作教程教科书
  • 东台专业做网站做网站应该注意哪些问题
  • 做网站的价格 外贸商用厨房设计书籍
  • 网站开发平台及常用开发工具wordpress 加载图片不显示
  • 旅游网站建设的概念静海网站开发
  • 那里建设网站好广告投放形式有哪些
  • 万网网站建设购买过程深圳电器公司招聘
  • 彩妆网站建设网游开发软件
  • 免费申请账号网站网站建设这个职业是什么
  • 揭阳网站设计公司wordpress加导航栏视频
  • 个人介绍网站模板自建站需要多少钱
  • 做网站运营有前景么做相册集什么网站