exoplayer2是谷歌出的一个非常强大的播放器,言归正转。想要同时播放多个MP3文件或者视频文件exoplayer2本身是不支持的,但是可以通过重写几个类做到。
重写TrackSelector
public class MultiTrackSelector extends TrackSelector {
@Override
public TrackSelectorResult selectTracks(RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups, MediaSource.MediaPeriodId periodId, Timeline timeline) throws ExoPlaybackException {
// int rendererCount = rendererCapabilities.length;
// TrackSelection[] rendererTrackSelections = new TrackSelection[rendererCount];
// LogUtils.E("345","rendererCount==="+rendererCount);
// int length = trackGroups.length;
// for (int i = 0; i < rendererCount; i++) {
// int trackType = rendererCapabilities[i].getTrackType();
//
//
// LogUtils.E("345","length111==="+length);
// if (trackType == C.TRACK_TYPE_AUDIO) {
// if (trackGroups.length > i) {
// LogUtils.E("345","length==="+length);
// rendererTrackSelections[i] = new FixedTrackSelection(trackGroups.get(i), 0);
// }
// }
// }
//
// RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCapabilities.length];
// for (int i = 0; i < rendererCount; i++) {
// rendererConfigurations[i] = rendererTrackSelections[i] != null ? RendererConfiguration.DEFAULT : null;
// }
//
//
// return new TrackSelectorResult(rendererConfigurations, rendererTrackSelections, new Object());
Queue<Integer> audioRenderers = new ArrayDeque<>();
RendererConfiguration[] configs = new RendererConfiguration[rendererCapabilities.length];
TrackSelection[] selections = new TrackSelection[rendererCapabilities.length];
for (int i = 0; i < rendererCapabilities.length; i++) {
if(rendererCapabilities[i].getTrackType() == C.TRACK_TYPE_AUDIO) {
audioRenderers.add(i);
configs[i] = RendererConfiguration.DEFAULT;
}
}
for (int i = 0; i < trackGroups.length; i++) {
if (MimeTypes.isAudio(trackGroups.get(i).getFormat(0).sampleMimeType)) {
Integer index = audioRenderers.poll();
if (index != null) {
selections[index] = new FixedTrackSelection(trackGroups.get(i), 0);
}
}
}
return new TrackSelectorResult(configs, selections, new Object());
}
@Override
public void onSelectionActivated(Object info) {
}
}
我这主要是音频文件,如果是视频文件上面的TRACK_TYPE_AUDIO就要改成TRACK_TYPE_VIDEO。
然后就是
public class MultiTrackRenderersFactory extends DefaultRenderersFactory {
private int audioTrackCnt;
private Context context;
private List<MultiMediaCodecAudioRenderer>audioSinkList= new ArrayList<>();
private List<AudioSink>audioSinks= new ArrayList<>();
public List<AudioSink> getAudioSinks() {
return audioSinks;
}
public void setAudioSinks(List<AudioSink> audioSinks) {
this.audioSinks = audioSinks;
}
public List<MultiMediaCodecAudioRenderer> getAudioSinkList() {
return audioSinkList;
}
public void setAudioSinkList(List<MultiMediaCodecAudioRenderer> audioSinkList) {
this.audioSinkList = audioSinkList;
}
public MultiTrackRenderersFactory(int audioTrackCnt, Context context) {
super(context);
this.audioTrackCnt = audioTrackCnt;
this.context = context;
}
@Override
protected void buildAudioRenderers(Context context, int extensionRendererMode, MediaCodecSelector mediaCodecSelector,
boolean enableDecoderFallback, AudioSink audioSink, Handler eventHandler,
AudioRendererEventListener eventListener, ArrayList<Renderer> out) {
audioSinkList.clear();
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
DefaultAudioSink.DefaultAudioProcessorChain defaultAudioProcessorChain= new DefaultAudioSink.DefaultAudioProcessorChain(
new AudioProcessor[] {},
new SilenceSkippingAudioProcessor(),
sonicAudioProcessor);
AudioSink myAudioSink =new DefaultAudioSink(
AudioCapabilities.getCapabilities(context),
defaultAudioProcessorChain,
true,
true,
true);
for (int i = 0; i < audioTrackCnt; i++) {
MultiMediaCodecAudioRenderer multiMediaCodecAudioRenderer =
new MultiMediaCodecAudioRenderer(i, context,MediaCodecSelector.DEFAULT,eventHandler,eventListener,audioSink);
out.add(multiMediaCodecAudioRenderer);
audioSinkList.add(multiMediaCodecAudioRenderer);
audioSinks.add(audioSink);
}
}
}
这里面主要用到audioSinkList,我们知道播放它是用audiotrck去播放的。我们可以用MultiMediaCodecAudioRenderer来控制每个音频的声音大小和速度大小。具体怎么控制看
MultiMediaCodecAudioRenderer里面的源代码。速度可以直接控制,声音要绕一绕了,看源码应该可以处理。
public class MultiMediaCodecAudioRenderer extends MediaCodecAudioRenderer {
private int index;
public MultiMediaCodecAudioRenderer(int index, Context context, MediaCodecSelector mediaCodecSelector,Handler eventHandler,AudioRendererEventListener eventListener,AudioSink audioSink) {
// super(context,mediaCodecSelector,eventHandler,eventListener,audioSink);
super(context,mediaCodecSelector);
this.index = index;
}
@Override
public MediaClock getMediaClock() {
if (index == 0) {
return super.getMediaClock();
}
return null;
}
}
完成这三个重写后,加入到SimpleExoPlayer实例就可以同时播放多个音频了。视频同理。最后感叹下exoplayer2的强大。因为可以同时播多个音频,还可以同时播多个轨道。目前为止还没看到有其他的可以做到。