我必须播放视频A一次,完成后,无限循环播放视频B.我正在尝试使用ConcatenatingMediaSource:
private SimpleExoPlayer initPlayer(ViewGroup layout, int playerViewId, ExoPlayer.EventListener eventListener) {
// 1. Create a default TrackSelector
TrackSelector trackSelector = new DefaultTrackSelector();
// 2. Create a default LoadControl
LoadControl loadControl = new DefaultLoadControl();
// 3. Create the player
this.player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, loadControl);
SimpleExoPlayerView simpleExoPlayerView = (SimpleExoPlayerView) layout.findViewById(playerViewId);
// Bind the player to the view.
simpleExoPlayerView.setUseController(false);
simpleExoPlayerView.setPlayer(player);
if (eventListener != null)
player.addListener(eventListener);
// Prepare the player with the source.
player.setPlayWhenReady(true);
return player;
}
public void startPlayer(String firstURL, String loopingURL) {
initProxy();
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
MediaSource firstSource = getVideoPlayerMediaSource(bandwidthMeter, firstURL);
MediaSource secondSource = new LoopingMediaSource(getVideoPlayerMediaSource(bandwidthMeter, loopingURL));
ConcatenatingMediaSource concatenatedSource =
new ConcatenatingMediaSource(firstSource, secondSource);
player.setPlayWhenReady(true);
player.prepare(concatenatedSource);
player.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
setPlayerPlaying(true);
}
private void initProxy() {
if (proxy == null)
proxy = VideoCache.getProxy(getContext());
}
@NonNull
private MediaSource getVideoPlayerMediaSource(DefaultBandwidthMeter bandwidthMeter, String videoUrl) {
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(),
Util.getUserAgent(getContext(), "com.myapp"), bandwidthMeter);
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
Uri url = Uri.parse(videoUrl);
MediaSource videoSource;
if (videoUrl.contains(".mp4")) {
url = Uri.parse(proxy.getProxyUrl(videoUrl));
videoSource = new ExtractorMediaSource(url,
dataSourceFactory, extractorsFactory, null, null);
} else {
videoSource = new HlsMediaSource(url, dataSourceFactory, null, null);
}
return videoSource;
}
但是这引发了:
Internal runtime error.
java.lang.IndexOutOfBoundsException
at com.google.android.exoplayer2.util.Assertions.checkIndex(Assertions.java:66)
at com.google.android.exoplayer2.ExoPlayerImplInternal.getPeriodPosition(ExoPlayerImplInternal.java:1077)
at com.google.android.exoplayer2.ExoPlayerImplInternal.getPeriodPosition(ExoPlayerImplInternal.java:1059)
at com.google.android.exoplayer2.ExoPlayerImplInternal.getPeriodPosition(ExoPlayerImplInternal.java:1050)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleSourceInfoRefreshed(ExoPlayerImplInternal.java:872)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:320)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
at com.google.android.exoplayer2.util.PriorityHandlerThread.run(PriorityHandlerThread.java:40)
仅在将secondSource用作LoopingMediaSource
时才会出现此问题。它没有它,但显然不会循环第二个视频。
(ExoPlayer版本r2.3.1)
答案 0 :(得分:0)
尝试使用LoopingMediaSource的其他构造函数,在其中指定循环计数并查看是否有效:
public LoopingMediaSource(MediaSource childSource, int loopCount) {
Assertions.checkArgument(loopCount > 0);
this.childSource = childSource;
this.loopCount = loopCount;
}
看起来您正在获取一个handleSourceInfoRefreshed消息,该消息是从LoopingMediaSource prepareSource()方法发送的:
@Override
public void prepareSource(ExoPlayer player, boolean isTopLevelSource, final Listener listener) {
childSource.prepareSource(player, false, new Listener() {
@Override
public void onSourceInfoRefreshed(Timeline timeline, Object manifest) {
childPeriodCount = timeline.getPeriodCount();
listener.onSourceInfoRefreshed(new LoopingTimeline(timeline, loopCount), manifest);
}
});
}
但是这会创建一个新的LoopingTimeline对象并传递给它loopCount,在你的情况下为0。 LoopingTimeline类重写getWindowCount():
@Override
public int getWindowCount() {
return childWindowCount * loopCount;
}
如果loopCount为0,则返回0。
如果可以,那么你可以通过传递(Integer.MAX_VALUE - 1)作为loopCount来无限循环你的视频,因为LoopingTimeline无论如何都会限制循环计数。