Exoplayer启动过程
ExoplayerImpl.prepare() →
ExoPlayerImplInternal.prepare() ->
ExoPlayerImplInternal.prepareInternal() ->
ExoPlayerImplInternal.doSomeWork()
ExoplayerImpl
public void prepare() {
//如果非STATE_IDLE 状态直接返回
if (playbackInfo.playbackState != Player.STATE_IDLE) {
return;
}
//调用ExoPlayerImplInternal.prepare()
internalPlayer.prepare();
}
ExoPlayerImplInternal
public void prepare() {
//发送MSG_PREPARE 消息
handler.obtainMessage(MSG_PREPARE).sendToTarget();
}
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_PREPARE:
prepareInternal();
}
private void prepareInternal() {
//设置播放器状态 Player.STATE_BUFFERING
setState(playbackInfo.timeline.isEmpty() ? Player.STATE_ENDED : Player.STATE_BUFFERING);
//发送MSG_DO_SOME_WORK消息
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
}
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_DO_SOME_WORK:
doSomeWork();
}
doSomeWork()
/*
* doSomeWork()的核心逻辑,
* 1. 每隔ACTIVE_INTERVAL_MS, 检测和打开数据流,
* 2. 开启渲染器渲染
* 3. 检测和校验播放条件设置播放状态
*/
private void doSomeWork() throws ExoPlaybackException, IOException {
//移除MSG_DO_SOME_WORK 消息
handler.removeMessages(MSG_DO_SOME_WORK);
//查询媒和打开MediaSourceList中保存到媒体数据源,
updatePeriods();
/* 尝试获取在updatePeriods()中打开的数据源, playingPeriodHolder 可以理解为打开的数据源
* 如果获取播放中的数据源为空,ACTIVE_INTERVAL_MS间隔后重新尝试调用 doSomeWork()
* 同时返回,不再执行后续逻辑
*/
MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
if (playingPeriodHolder == null) {
scheduleNextWork(operationStartTimeMs, ACTIVE_INTERVAL_MS);
return;
}
//更新播放进度
updatePlaybackPositions();
boolean renderersEnded = true;
boolean renderersAllowPlayback = true;
if (playingPeriodHolder.prepared) {
//当前渲染器开渲染时间
long rendererPositionElapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i];
if (!isRendererEnabled(renderer)) {
//如果当前渲染器不支持渲染,跳过循环 (例如纯播放音频过程中,视频Renderer不可用)
continue;
}
//开启渲染器
renderer.render(rendererPositionUs, rendererPositionElapsedRealtimeUs);
//渲染是否结束
renderersEnded = renderersEnded && renderer.isEnded();
//是否预加载数据
boolean isReadingAhead = playingPeriodHolder.sampleStreams[i] != renderer.getStream();
//是否等待下一个视频播放
boolean isWaitingForNextStream = !isReadingAhead && renderer.hasReadStreamToEnd();
//是否允许播放
boolean allowsPlayback =
isReadingAhead || isWaitingForNextStream || renderer.isReady() || renderer.isEnded();
//允许渲染,
renderersAllowPlayback = renderersAllowPlayback && allowsPlayback;
if (!allowsPlayback) {
//不允许渲染,抛出异常
renderer.maybeThrowStreamError();
}
}
} else {
//如果打开的数据源没准备好,抛出异常
playingPeriodHolder.mediaPeriod.maybeThrowPrepareError();
}
long playingPeriodDurationUs = playingPeriodHolder.info.durationUs;
boolean finishedRendering =
renderersEnded
&& playingPeriodHolder.prepared
&& (playingPeriodDurationUs == C.TIME_UNSET
|| playingPeriodDurationUs <= playbackInfo.positionUs);
if (finishedRendering && playingPeriodHolder.info.isFinal) {
/* 如果是视频序列的最后一个视频正在结束渲染, 设置播放器为STATE_ENDED 状态,
* 关闭所有的渲染器
*/
setState(Player.STATE_ENDED);
stopRenderers();
} else if (playbackInfo.playbackState == Player.STATE_BUFFERING
&& shouldTransitionToReadyState(renderersAllowPlayback)) {
//如果缓存状态,并且要切换到渲染, 设置播放器状态为STATE_READY
setState(Player.STATE_READY);
if (shouldPlayWhenReady()) {
//开启渲染
startRenderers();
}
} else if (playbackInfo.playbackState == Player.STATE_READY
&& !(enabledRendererCount == 0 ? isTimelineReady() : renderersAllowPlayback)) {
// STATE_READY状态下,如果不允许渲染,切换播放器状态为缓冲态STATE_BUFFERING
isRebuffering = shouldPlayWhenReady();
setState(Player.STATE_BUFFERING);
stopRenderers();
}
boolean isPlaying = shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY;
boolean sleepingForOffload = offloadSchedulingEnabled && requestForRendererSleep && isPlaying;
if (playbackInfo.sleepingForOffload != sleepingForOffload) {
playbackInfo = playbackInfo.copyWithSleepingForOffload(sleepingForOffload);
}
requestForRendererSleep = false;
if (sleepingForOffload || playbackInfo.playbackState == Player.STATE_ENDED) {
//离线睡眠或者播放结束,直接返回
return;
} else if (isPlaying || playbackInfo.playbackState == Player.STATE_BUFFERING) {
//播放中或者缓存中,间隔 ACTIVE_INTERVAL_MS时间调用doSomeWork
scheduleNextWork(operationStartTimeMs, ACTIVE_INTERVAL_MS);
} else if (playbackInfo.playbackState == Player.STATE_READY && enabledRendererCount != 0) {
//已经准备好,但是还没开始播放,间隔 ACTIVE_INTERVAL_MS时间调用doSomeWork
scheduleNextWork(operationStartTimeMs, IDLE_INTERVAL_MS);
}
}