Vitamio和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进行音频播放,可以通过以下步骤进行操作:

  1. 添加ExoPlayer库依赖,可以通过Gradle等方式进行添加。
  2. 创建一个SimpleExoPlayer对象,并设置数据源。
  3. 通过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的初始化、播放等操作封装在一个类里,便于在整个应用程序中使用。

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

  1. 简单易用:封装的类和接口应该易于理解和使用,不需要过多的配置和参数即可完成基本的操作。

  2. 错误处理:封装的类应该能够处理各种错误情况,并且提供相应的错误回调或异常机制,方便使用者进行错误处理和调试。

  3. 状态管理:封装的类应该能够管理ExoPlayer的播放状态和进度,能够提供相应的状态回调,方便使用者进行状态变化的处理和UI更新。

  4. 可扩展性:封装的类应该具备可扩展性,能够满足使用者的各种需求,如添加播放列表、支持不同的媒体源等。

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

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;}// 获取当前播放的媒体源Uripublic 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 事件回调方法@Overridepublic void onPlayerStateChanged(boolean playWhenReady, int playbackState) {this.playWhenReady = playWhenReady;if (playerStateListener != null) {playerStateListener.onPlayerStateChanged(playWhenReady, playbackState);}}// Player.EventListener 事件回调方法@Overridepublic void onPlayerError(ExoPlaybackException error) {if (playerStateListener != null) {playerStateListener.onError(error);}}
}

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

  1. 增加了播放器状态回调接口,方便使用者进行状态变化的处理和UI更新。

  2. 增加了获取当前播放进度和媒体源Uri的方法,方便使用者进行状态显示和媒体源管理。

  3. 实现了ExoPlayer的Player.EventListener回调接口,方便使用者进行错误处理和调试。

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

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

  1. 在你的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() {@Overridepublic void onPlayerStateChanged(boolean playWhenReady, int playbackState) {// do something}@Overridepublic void onPositionUpdated(long position, long duration) {// do something}@Overridepublic 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() {@Overridepublic 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, "oncase Player.STATE_ENDED:Log.d(TAG, "onPlayerStateChanged: STATE_ENDED"); isPlaying = false;break;default:break;}}@Overridepublic void onPlayerError(ExoPlaybackException error) {Log.e(TAG, "onPlayerError: " + error.getMessage());for (OnErrorListener listener: errorListeners) {listener.onError(error);}release();}});player.addAnalyticsListener(new AnalyticsListener() {@Overridepublic 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类。

Vitamio和ExoPlayer哪个更好相关推荐

  1. Android Vitamio的使用解析

    概述 Vitamio 是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染,底层音视频解码原理基于FFmpeg开发.Vitamio 凭借其简洁易用的 API ...

  2. Android 在线视频播放器(Vitamio)

    概述 Vitamio 是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染,底层音视频解码原理基于FFmpeg开发.Vitamio 凭借其简洁易用的 API ...

  3. 简单的MediaPlayer+SurfaceView实现视频横竖屏播放

    一.概述 目前就我的认知中,Android实现视频播放的话,有2中方式,第一种是MediaPlayer+surfaceView实现,第二种是直接用VideoView来实现,当然市面上也有一些主流的视频 ...

  4. Android音视频API - MediaCodec/MediaMuxer/MediaStore/MediaController等

    AudioTrack播放音频PCM.[Android] 混音器AudioMixer. MediaPlayer/MediaRecorder, AudioTrack/AudioRecorder, Medi ...

  5. 全网最全Android开发工具,Android开发框架大全

    涵盖Android方方面面的技术, 目前保持更新. 时刻与Android开发流行前沿同步. 目录 一.工具 Android开发工具 在线工具宝典大全 二.框架 *缓存框架* DiskLruCache ...

  6. 音视频的流程:录制、播放、编码解码、上传下载等

    仿网易云音乐 安卓版-- https://github.com/aa112901/remusic Android本地视频播放器开发- http://blog.csdn.NET/jwzhangjie/a ...

  7. Android 直播RTMP流

    原文链接 : How To Stream RTMP live in Android 原文作者 : Mohit Gupt 译文出自 : 开发技术前线 www.devtf.cn 译者 : ayyb1988 ...

  8. Android 音视频开发相关知识

    音视频开发技能 要在Android上进行音视频开发,需要掌握以下技能: Android开发:首先,您需要掌握Android应用程序的基本开发技能,包括Java或Kotlin编程语言,Android S ...

  9. 中国五十六个民族简介

    56个民族是中华人民共和国灿烂星空中(五十六个星座). 中华民族共包括56个民族,汉族是中国的主体民族,占全部人口的91.51%,其他还有55个民族,占8.49%(第六次人口普查).汉族和55个少数民 ...

最新文章

  1. 从搞笑到高效,构建敏捷团队的基础原则
  2. 信息资源管理的标准与法规
  3. HTML5 audio与video标签实现视频播放,音频播放
  4. GitNote 基于 Git 的跨平台笔记软件正式发布
  5. 基于mybatis-generator代码生成工具改(链式方法实体版)
  6. python语音合法命名-下列哪些语句在Python中是合法的( )
  7. html iframe jsp页面跳转页面,js页面跳转和js对iframe进行页面跳转、刷新
  8. 每周分享第 26 期
  9. 关于WiFi密码破解的一些心得
  10. 高等数学张宇18讲 第三讲 一元函数微分学的概念与计算
  11. 学用计算机 关机,电脑关机命令是什么?快速关机必备(你学会了吗)
  12. 草稿cfmm~yuyu 22.9.26 Linux
  13. 跟小甲鱼学Web开发笔记06(最新进展不按进度顺序)
  14. codevs1380 没有丧尸的舞会
  15. 洛谷千题详解 | P1010 [NOIP1998 普及组] 幂次方【C++、Java、Python、Pascal语言】
  16. html可以有多个h1,HTML5大纲和多个H1 SEO
  17. 【菜鸟进阶之路】P5461 赦免战俘 题解笔记(持更)
  18. WebDAV之葫芦儿·派盘+书藏家
  19. Blender教程之魔方全自动特效教学
  20. python中row是什么意思_Python中的2D列表(row total/grand total)

热门文章

  1. xbox series s 运行游戏显示网络异常 0x80072ee2
  2. SQL每日一题(20201218)来查找与之前(昨天的)日期相比温度更高的所有日期
  3. 【iPad升级iOS7正式版图文教程】
  4. 美国学生在使用计算机小短文,美国中学生的一篇作文
  5. android实现连连看,附源码
  6. 全球半导体厂商以及硬件设备代工厂一览
  7. 界面超漂亮的桌面时钟
  8. 网络工程师 入门基础(Telnet)
  9. ssm整合(简单的增删改查)
  10. 2015华为实习生招聘机试题长沙站