exoplayer2同时播放多个音频文件

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的强大。因为可以同时播多个音频,还可以同时播多个轨道。目前为止还没看到有其他的可以做到。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值