通过 ExoPlayer 或其他选项播放多个音频文件?

Posted

技术标签:

【中文标题】通过 ExoPlayer 或其他选项播放多个音频文件?【英文标题】:Play Multiple audio files through ExoPlayer or some other option? 【发布时间】:2019-07-11 13:31:54 【问题描述】:

我的问题:我想在我的应用程序中加载 70 个声音,然后想播放多个声音(一次最多 8 个声音)。示例应用程序如下: https://play.google.com/store/apps/details?id=net.relaxio.sleepo

我在我的应用程序中尝试了 SoundPool 系统,但它给我的加载带来了问题。 SoundPool 大约需要 60 多秒来加载 70 个文件。所以这个选项不适合我的应用程序。 然后我尝试媒体播放器。 MediaPlayer 可以加载,但会出现另一个问题。当我在媒体播放器中设置循环时,它会在重新启动之间产生间隙。 然后我找到了一个 github 项目,它一次播放多个声音,加载速度也很快,但我仍然对这个项目有问题。它无法正确加载超过 30 种声音。在这个项目中,他们使用 ExoPlayer(链接如下)。 https://github.com/zoenb/Soft-Sound

请帮助我如何解决加载声音和循环间隙问题。

【问题讨论】:

您的声音是嵌入到您的应用程序中还是必须先下载?你的声音有多长?我实际上在我的应用程序的服务中使用了多个 Exoplayer 实例,我什至可以一次播放超过八个声音。 (没有循环,但可以重新启动)。在这里查看:play.google.com/store/apps/details?id=de.jahpress.android 一次 8 个声音没有问题。当实例超过 35 时会出现 exoplayer 问题。我已将它用于 70 种声音。所以它可以工作到 35 但之后它不会播放一些声音 如果您只想一次最多播放 8 个声音,我建议您应该有 8 个 exoplayer 实例并切换声音,而不是为每个声音保留一个实例。如果我理解正确 【参考方案1】:

是的,你必须创建多个 (8) exoplayer 实例,你不能用一个实例来做

这是我的代码,

    private void initPlayer() 
      if (player == null) 
        trackSelectorParameters = new DefaultTrackSelector.ParametersBuilder().build();
        TrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory();
        trackSelector = new DefaultTrackSelector(trackSelectionFactory);
        trackSelector.setParameters(trackSelectorParameters);

        RenderersFactory renderersFactory = ((MyAppApplication) context.getApplicationContext()).buildRenderersFactory();

        player = ExoPlayerFactory.newSimpleInstance(context, renderersFactory, trackSelector);

        player.setPlayWhenReady(true);

        //to print log of ExoPlayer
        //player.addAnalyticsListener(new EventLogger(trackSelector));

        progressiveMediaSourceFactory = new ProgressiveMediaSource.Factory(dataSourceFactory);

      
    

使用上述代码初始化exoplayer,调用该方法将8个URIs全部同时播放

 public void startPlaying(Uri uri) 
        if (player == null) initPlayer();
        MediaSource mediaSource = progressiveMediaSourceFactory.createMediaSource(uri);
        player.prepare(mediaSource, true, false);
  

这里是 Github 链接 - https://github.com/google/ExoPlayer

使用exoplayer-core

为此,我建议您为 ExoPlayer 创建一个单独的类来初始化、启动、停止等等......

public class MyAppExoPlayer 

private final Context context;


private DataSource.Factory dataSourceFactory;
private SimpleExoPlayer player;
private DefaultTrackSelector trackSelector;
private DefaultTrackSelector.Parameters trackSelectorParameters;


private ProgressiveMediaSource.Factory progressiveMediaSourceFactory;


private ConcatenatingMediaSource concatenatingMediaSource;
private int currentMediaPlayerIndex = 0;

public MyAppExoPlayer(Context context) 
    this.context = context;

    dataSourceFactory = ((MyAppApplication) context.getApplicationContext()).buildDataSourceFactory();

    initPlayer();


private void initPlayer() 
    if (player == null) 
        trackSelectorParameters = new DefaultTrackSelector.ParametersBuilder().build();
        TrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory();
        trackSelector = new DefaultTrackSelector(trackSelectionFactory);
        trackSelector.setParameters(trackSelectorParameters);

        RenderersFactory renderersFactory = ((MyAppApplication) context.getApplicationContext()).buildRenderersFactory();

        player = ExoPlayerFactory.newSimpleInstance(context, renderersFactory, trackSelector);

        player.setPlayWhenReady(true);

        //to print log of ExoPlayer
        //player.addAnalyticsListener(new EventLogger(trackSelector));

        progressiveMediaSourceFactory = new ProgressiveMediaSource.Factory(dataSourceFactory);

    

    concatenatingMediaSource = new ConcatenatingMediaSource();


public void startPlaying(Uri uri) 
    if (player == null) initPlayer();
    MediaSource mediaSource = progressiveMediaSourceFactory.createMediaSource(uri);
    player.prepare(mediaSource, true, false);


public void addToQ(Uri uri) 
    if (player == null) return;
    MediaSource mediaSource = progressiveMediaSourceFactory.createMediaSource(uri);
    concatenatingMediaSource.addMediaSource(mediaSource);


public void stopPlaying() 
    if (player != null) 
        player.stop(true);
        concatenatingMediaSource.clear();
    


public long getCurrentPosition() 
    if (player != null)
        return player.getCurrentPosition();
    return 0;


public void releasePlayer() 
    if (player != null) 

        if (trackSelector != null) 
            trackSelectorParameters = trackSelector.getParameters();
        

        player.release();
        player = null;
        trackSelector = null;
    


如果MyAppExoPlayer 并调用startPlaying(),现在创建8 个实例

【讨论】:

ProgressiveMediaSource 显示错误“未知符号”。我使用 exoplayer 版本库“2.8.4” 与“ExoPlayerStateListener”相同 使用 2.10.0 implementation 'com.google.android.exoplayer:exoplayer-core:2.10.0' ProgressiveMediaSource 问题已解决,但 ExoPlayerStateListener 仍然存在 你可以使用 player.setVolume(volume);使用 0f 静音 & 1f 全音量,音量应在 0 到 1 之间

以上是关于通过 ExoPlayer 或其他选项播放多个音频文件?的主要内容,如果未能解决你的问题,请参考以下文章

Android音频开发:使用ExoPlayer播放音频

Android音频开发:使用ExoPlayer播放音频

Android音频开发:使用ExoPlayer播放音频

Exoplayer 音频播放背景,甚至视频已关闭

如何使用 exoplayer 一起播放单独的音频和视频?

使用 ExoPlayer 缓冲音频直播