欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

AndroidVitamio和ExoPlayer两种播放器优劣分析,

来源: 开发者 投稿于  被查看 49635 次 评论:163

AndroidVitamio和ExoPlayer两种播放器优劣分析,


Vitamio是一个功能强大而稳定的播放器库,它支持多种视频格式和编解码方式,并且具有快速、流畅的播放效果,因此在一些对播放质量要求比较高的应用场景下可以考虑使用。但是需要注意的是,Vitamio的开发团队近些年来已经较少更新和维护,不支持较新的Android版本(如Android 7.0及以上版本),因此在一些需要支持最新Android版本的应用中,可能需要考虑其他选项。

ExoPlayer是Google推出的一个功能强大的播放器库,它支持多种视频格式和编解码方式,具有良好的扩展性和定制性,可以通过插件等方式支持更多的功能和数据源。与Vitamio相比,ExoPlayer的开发团队更新迭代更为频繁,并且具有良好的Google生态环境(如与Android Studio的良好兼容等),因此在一些需要开发更加灵活、定制化的应用中,可以优先考虑使用。

总之,Vitamio和ExoPlayer都是非常优秀的播放器库,具体使用哪一个要根据你的实际需求来选择。如果你的应用比较老,需要支持7.0以下的Android版本,那么可以考虑使用Vitamio;如果你需要开发更加灵活、定制化的播放器,那么可以考虑使用ExoPlayer。

ExoPlayer支持音频播放。事实上,ExoPlayer可以用于播放视频、音频和流媒体等多种媒体格式。由于其良好的架构设计和强大的扩展性,ExoPlayer可以通过插件等方式支持更多的格式和功能,满足不同应用场景下的需求。

如果你需要使用ExoPlayer进行音频播放,可以通过以下步骤进行操作:

  • 添加ExoPlayer库依赖,可以通过Gradle等方式进行添加。
  • 创建一个SimpleExoPlayer对象,并设置数据源。
  • 通过SimpleExoPlayer对象进行播放控制,包括播放、暂停、停止、音量控制等操作。

示例代码如下:

// 添加ExoPlayer库依赖
implementation 'com.google.android.exoplayer:exoplayer-core:2.14.1'
// 创建SimpleExoPlayer对象
SimpleExoPlayer player = new SimpleExoPlayer.Builder(context).build();
MediaItem mediaItem = MediaItem.fromUri(audioUri);
player.setMediaItem(mediaItem);
// 进行播放控制
player.prepare();
player.play();

需要注意的是,这只是一个简单的音频播放示例,实际使用中可能需要更复杂的逻辑处理,例如错误处理、缓冲控制等。另外,需要根据实际需求选择合适的数据源类型、音频编码等参数。

进一步封装ExoPlayer使用:

对于ExoPlayer的使用,我们可以进行一些进一步的封装,将ExoPlayer的初始化、播放等操作封装在一个类里,便于在整个应用程序中使用。

封装需要考虑以下几个方面:

  • 简单易用:封装的类和接口应该易于理解和使用,不需要过多的配置和参数即可完成基本的操作。
  • 错误处理:封装的类应该能够处理各种错误情况,并且提供相应的错误回调或异常机制,方便使用者进行错误处理和调试。
  • 状态管理:封装的类应该能够管理ExoPlayer的播放状态和进度,能够提供相应的状态回调,方便使用者进行状态变化的处理和UI更新。
  • 可扩展性:封装的类应该具备可扩展性,能够满足使用者的各种需求,如添加播放列表、支持不同的媒体源等。

以下是一个完美封装的示例:

public class AudioPlayer implements Player.EventListener {
  private SimpleExoPlayer player;
  private PlayerStateListener playerStateListener;
  private Context context;
  private Uri currentUri;
  private boolean playWhenReady = true;
  // 播放器状态回调接口
  public interface PlayerStateListener {
    void onPlayerStateChanged(boolean playWhenReady, int playbackState);
    void onPositionUpdated(long position, long duration);
    void onError(ExoPlaybackException error);
  }
  // 初始化操作,在Activity或Fragment中调用
  public void init(Context context, Uri uri) {
    this.context = context;
    this.currentUri = uri;
    player = new SimpleExoPlayer.Builder(context).build();
    player.setMediaItem(MediaItem.fromUri(uri));
    player.addListener(this);
    player.prepare();
  }
  // 播放操作
  public void play() {
    if (player != null) {
      player.setPlayWhenReady(playWhenReady);
    }
  }
  // 暂停操作
  public void pause() {
    if (player != null) {
      player.setPlayWhenReady(false);
    }
  }
  // 停止操作
  public void stop() {
    if (player != null) {
      player.stop();
    }
  }
  // 释放操作,在Activity或Fragment销毁时调用
  public void release() {
    if (player != null) {
      player.release();
      player.removeListener(this);
      player = null;
    }
  }
  // 设置播放状态回调接口
  public void setPlayerStateListener(PlayerStateListener listener) {
    this.playerStateListener = listener;
  }
  // 获取当前播放的媒体源Uri
  public Uri getCurrentUri() {
    return currentUri;
  }
  // 获取当前播放状态和播放进度
  public void getCurrentPosition() {
    if (player != null) {
      long position = player.getCurrentPosition();
      long duration = player.getDuration();
      if (playerStateListener != null) {
        playerStateListener.onPositionUpdated(position, duration);
      }
    }
  }
  // Player.EventListener 事件回调方法
  @Override
  public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    this.playWhenReady = playWhenReady;
    if (playerStateListener != null) {
      playerStateListener.onPlayerStateChanged(playWhenReady, playbackState);
    }
  }
  // Player.EventListener 事件回调方法
  @Override
  public void onPlayerError(ExoPlaybackException error) {
    if (playerStateListener != null) {
      playerStateListener.onError(error);
    }
  }
}

这个示例封装了ExoPlayer的初始化、播放、暂停、停止和释放等操作,可以在应用程序中方便地调用。使用时,只需要创建一个AudioPlayer对象,然后调用相应的方法即可。还有以下几个功能:

  • 增加了播放器状态回调接口,方便使用者进行状态变化的处理和UI更新。
  • 增加了获取当前播放进度和媒体源Uri的方法,方便使用者进行状态显示和媒体源管理。
  • 实现了ExoPlayer的Player.EventListener回调接口,方便使用者进行错误处理和调试。

这个封装示例可能仍然不是完美的,但是对于大多数应用程序的使用场景已经足够成熟。如果需要更加复杂的功能,可以根据实际需。

在使用这个封装类的时候,你需要按以下步骤进行:

在你的Activity或Fragment中创建一个AudioPlayer实例,例如:

private AudioPlayer audioPlayer;

2.在创建完AudioPlayer实例后,调用init方法初始化。

audioPlayer = new AudioPlayer();
audioPlayer.init(this, Uri.parse("https://example.com/audio.mp3"));

其中,第一个参数传入当前的Context,第二个参数传入媒体源的Uri。

3.在需要播放的时候,调用play方法:

audioPlayer.play();

4.如果需要暂停播放,调用pause方法:

audioPlayer.pause();

5.如果需要停止播放,调用stop方法:

audioPlayer.stop();

6.如果需要释放播放器实例,取消实例化,调用release方法:

audioPlayer.release();

7.如果需要监听播放器状态回调,可以通过setPlayerStateListener方法来设置:

audioPlayer.setPlayerStateListener(new AudioPlayer.PlayerStateListener() {
  @Override
  public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    // do something
  }
  @Override
  public void onPositionUpdated(long position, long duration) {
    // do something
  }
  @Override
  public void onError(ExoPlaybackException error) {
    // do something
  }
});

8.如果需要获取当前播放进度和媒体源Uri,可以调用getCurrentPosition和getCurrentUri方法:

Uri uri = audioPlayer.getCurrentUri();
audioPlayer.getCurrentPosition();

以上就是大致的调用步骤,具体情况可以根据自己的场景进行调整。

public class AudioPlayer {
    private static final String TAG = AudioPlayer.class.getSimpleName();
    private Context context;
    private SimpleExoPlayer player;
    private boolean isPlaying;
    private int currentPosition;
    private List < Integer > audioList;
    private List < OnProgressListener > progressListeners = new ArrayList < > ();
    private List < OnErrorListener > errorListeners = new ArrayList < > ();
    public AudioPlayer(Context context) {
        this.context = context;
    }
    public void init() {
        TrackSelector trackSelector = new DefaultTrackSelector();
        player = new SimpleExoPlayer.Builder(context)
            .setTrackSelector(trackSelector)
            .build();
        player.addListener(new Player.EventListener() {
                @Override
                public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                    switch (playbackState) {
                        case Player.STATE_IDLE:
                            Log.d(TAG, "onPlayerStateChanged: STATE_IDLE");
                            break;
                        case Player.STATE_BUFFERING:
                            Log.d(TAG, "on
                                case Player.STATE_ENDED:
                                Log.d(TAG, "onPlayerStateChanged: STATE_ENDED"); isPlaying = false;
                                break;
                                default:
                                break;
                            }
                    }
                    @Override
                    public void onPlayerError(ExoPlaybackException error) {
                        Log.e(TAG, "onPlayerError: " + error.getMessage());
                        for (OnErrorListener listener: errorListeners) {
                            listener.onError(error);
                        }
                        release();
                    }
                });
            player.addAnalyticsListener(new AnalyticsListener() {
                @Override
                public void onPositionDiscontinuity(
                    AnalyticsListener.EventTime eventTime,
                    int reason) {
                    Log.d(TAG, "onPositionDiscontinuity");
                    if (player.getPlaybackError() != null) {
                        Log.e(TAG, "onPlayerError: " + player.getPlaybackError().getMessage());
                        for (OnErrorListener listener: errorListeners) {
                            listener.onError(player.getPlaybackError().getCause());
                        }
                        release();
                    }
                    currentPosition = player.getCurrentWindowIndex();
                    int duration = (int) player.getDuration();
                    int currentPosition = (int) player.getCurrentPosition();
                    for (OnProgressListener listener: progressListeners) {
                        listener.onProgress(currentPosition, duration);
                    }
                }
            });
        }
        public void addOnErrorListener(OnErrorListener listener) {
            errorListeners.add(listener);
        }
        public void addOnProgressListener(OnProgressListener listener) {
            progressListeners.add(listener);
        }
        public void setAudioList(List < Integer > audioList) {
            this.audioList = audioList;
        }
        public void play(int position) {
            if (audioList == null || audioList.size() == 0) {
                return;
            }
            currentPosition = position;
            Uri audioUri = RawResourceDataSource.buildRawResourceUri(audioList.get(currentPosition));
            MediaSource audioSource = new ProgressiveMediaSource.Factory(
                new DefaultDataSourceFactory(context, "ExoplayerDemo")
            ).createMediaSource(audioUri);
            player.prepare(audioSource);
            player.setPlayWhenReady(true);
            isPlaying = true;
        }
        public void pause() {
            if (player != null) {
                player.setPlayWhenReady(false);
                isPlaying = false;
            }
        }
        public void resume() {
            if (player != null) {
                player.setPlayWhenReady(true);
                isPlaying = true;
            }
        }
        public void stop() {
            if (player != null) {
                player.stop();
                isPlaying = false;
            }
        }
        public void release() {
            if (player != null) {
                player.release();
                player = null;
                isPlaying = false;
            }
        }
        public boolean isPlaying() {
            return isPlaying;
        }
        public int getCurrentPosition() {
            return currentPosition;
        }
        public interface OnProgressListener {
            void onProgress(int currentPosition, int duration);
        }
        public interface OnErrorListener {
            void onError(Exception e);
        }
    }

在以上代码中,我们添加了两个接口,OnProgressListener是用来监听进度的,OnErrorListener是用来监听播放异常的。在init方法中,我们给player对象添加了Player.EventListener接口和AnalyticsListener接口,分别用来监听播放状态的变化和进度的变化。播放异常包括播放开始前的异常和播放过程中的异常。在onPlaybackError方法中,我们回调OnErrorListener接口的onError方法。注意,在捕获到播放异常时,我们要调用release方法释放资源。

最后,通过调用addOnErrorListener和addOnProgressListener方法,我们可以将外部传进来的OnErrorListener和OnProgressListener实例添加到AudioPlayer类中。这样,在播放过程中,我们就可以监听到错误和进度的变化了。

至此,我们已经完整地实现了一个支持播放暂停、恢复、停止、进度和错误监听的AudioPlayer类。

到此这篇关于Android Vitamio和ExoPlayer两种播放器优劣分析的文章就介绍到这了,更多相关Android Vitamio和ExoPlayer内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

您可能感兴趣的文章:
  • Android使用vitamio插件实现视频播放器
  • Android 使用Vitamio打造自己的万能播放器(10)—— 本地播放 (缩略图、视频信息、视频扫描服务)
  • Android 开发音频组件(Vitamio FAQ)详细介绍

用户评论