溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android?Vitamio和ExoPlayer播放器的優(yōu)劣勢(shì)是什么

發(fā)布時(shí)間:2023-04-08 10:40:03 來(lái)源:億速云 閱讀:80 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“Android Vitamio和ExoPlayer播放器的優(yōu)劣勢(shì)是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

Vitamio是一個(gè)功能強(qiáng)大而穩(wěn)定的播放器庫(kù),它支持多種視頻格式和編解碼方式,并且具有快速、流暢的播放效果,因此在一些對(duì)播放質(zhì)量要求比較高的應(yīng)用場(chǎng)景下可以考慮使用。但是需要注意的是,Vitamio的開(kāi)發(fā)團(tuán)隊(duì)近些年來(lái)已經(jīng)較少更新和維護(hù),不支持較新的Android版本(如Android 7.0及以上版本),因此在一些需要支持最新Android版本的應(yīng)用中,可能需要考慮其他選項(xiàng)。

ExoPlayer是Google推出的一個(gè)功能強(qiáng)大的播放器庫(kù),它支持多種視頻格式和編解碼方式,具有良好的擴(kuò)展性和定制性,可以通過(guò)插件等方式支持更多的功能和數(shù)據(jù)源。與Vitamio相比,ExoPlayer的開(kāi)發(fā)團(tuán)隊(duì)更新迭代更為頻繁,并且具有良好的Google生態(tài)環(huán)境(如與Android Studio的良好兼容等),因此在一些需要開(kāi)發(fā)更加靈活、定制化的應(yīng)用中,可以優(yōu)先考慮使用。

總之,Vitamio和ExoPlayer都是非常優(yōu)秀的播放器庫(kù),具體使用哪一個(gè)要根據(jù)你的實(shí)際需求來(lái)選擇。如果你的應(yīng)用比較老,需要支持7.0以下的Android版本,那么可以考慮使用Vitamio;如果你需要開(kāi)發(fā)更加靈活、定制化的播放器,那么可以考慮使用ExoPlayer。

ExoPlayer支持音頻播放。事實(shí)上,ExoPlayer可以用于播放視頻、音頻和流媒體等多種媒體格式。由于其良好的架構(gòu)設(shè)計(jì)和強(qiáng)大的擴(kuò)展性,ExoPlayer可以通過(guò)插件等方式支持更多的格式和功能,滿足不同應(yīng)用場(chǎng)景下的需求。

如果你需要使用ExoPlayer進(jìn)行音頻播放,可以通過(guò)以下步驟進(jìn)行操作:

  • 添加ExoPlayer庫(kù)依賴,可以通過(guò)Gradle等方式進(jìn)行添加。

  • 創(chuàng)建一個(gè)SimpleExoPlayer對(duì)象,并設(shè)置數(shù)據(jù)源。

  • 通過(guò)SimpleExoPlayer對(duì)象進(jìn)行播放控制,包括播放、暫停、停止、音量控制等操作。

示例代碼如下:

// 添加ExoPlayer庫(kù)依賴
implementation 'com.google.android.exoplayer:exoplayer-core:2.14.1'
// 創(chuàng)建SimpleExoPlayer對(duì)象
SimpleExoPlayer player = new SimpleExoPlayer.Builder(context).build();
MediaItem mediaItem = MediaItem.fromUri(audioUri);
player.setMediaItem(mediaItem);
// 進(jìn)行播放控制
player.prepare();
player.play();

需要注意的是,這只是一個(gè)簡(jiǎn)單的音頻播放示例,實(shí)際使用中可能需要更復(fù)雜的邏輯處理,例如錯(cuò)誤處理、緩沖控制等。另外,需要根據(jù)實(shí)際需求選擇合適的數(shù)據(jù)源類型、音頻編碼等參數(shù)。

進(jìn)一步封裝ExoPlayer使用:

對(duì)于ExoPlayer的使用,我們可以進(jìn)行一些進(jìn)一步的封裝,將ExoPlayer的初始化、播放等操作封裝在一個(gè)類里,便于在整個(gè)應(yīng)用程序中使用。

封裝需要考慮以下幾個(gè)方面:

  • 簡(jiǎn)單易用:封裝的類和接口應(yīng)該易于理解和使用,不需要過(guò)多的配置和參數(shù)即可完成基本的操作。

  • 錯(cuò)誤處理:封裝的類應(yīng)該能夠處理各種錯(cuò)誤情況,并且提供相應(yīng)的錯(cuò)誤回調(diào)或異常機(jī)制,方便使用者進(jìn)行錯(cuò)誤處理和調(diào)試。

  • 狀態(tài)管理:封裝的類應(yīng)該能夠管理ExoPlayer的播放狀態(tài)和進(jìn)度,能夠提供相應(yīng)的狀態(tài)回調(diào),方便使用者進(jìn)行狀態(tài)變化的處理和UI更新。

  • 可擴(kuò)展性:封裝的類應(yīng)該具備可擴(kuò)展性,能夠滿足使用者的各種需求,如添加播放列表、支持不同的媒體源等。

以下是一個(gè)完美封裝的示例:

public class AudioPlayer implements Player.EventListener {
  private SimpleExoPlayer player;
  private PlayerStateListener playerStateListener;
  private Context context;
  private Uri currentUri;
  private boolean playWhenReady = true;
  // 播放器狀態(tài)回調(diào)接口
  public interface PlayerStateListener {
    void onPlayerStateChanged(boolean playWhenReady, int playbackState);
    void onPositionUpdated(long position, long duration);
    void onError(ExoPlaybackException error);
  }
  // 初始化操作,在Activity或Fragment中調(diào)用
  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銷毀時(shí)調(diào)用
  public void release() {
    if (player != null) {
      player.release();
      player.removeListener(this);
      player = null;
    }
  }
  // 設(shè)置播放狀態(tài)回調(diào)接口
  public void setPlayerStateListener(PlayerStateListener listener) {
    this.playerStateListener = listener;
  }
  // 獲取當(dāng)前播放的媒體源Uri
  public Uri getCurrentUri() {
    return currentUri;
  }
  // 獲取當(dāng)前播放狀態(tài)和播放進(jìn)度
  public void getCurrentPosition() {
    if (player != null) {
      long position = player.getCurrentPosition();
      long duration = player.getDuration();
      if (playerStateListener != null) {
        playerStateListener.onPositionUpdated(position, duration);
      }
    }
  }
  // Player.EventListener 事件回調(diào)方法
  @Override
  public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    this.playWhenReady = playWhenReady;
    if (playerStateListener != null) {
      playerStateListener.onPlayerStateChanged(playWhenReady, playbackState);
    }
  }
  // Player.EventListener 事件回調(diào)方法
  @Override
  public void onPlayerError(ExoPlaybackException error) {
    if (playerStateListener != null) {
      playerStateListener.onError(error);
    }
  }
}

這個(gè)示例封裝了ExoPlayer的初始化、播放、暫停、停止和釋放等操作,可以在應(yīng)用程序中方便地調(diào)用。使用時(shí),只需要?jiǎng)?chuàng)建一個(gè)AudioPlayer對(duì)象,然后調(diào)用相應(yīng)的方法即可。還有以下幾個(gè)功能:

  • 增加了播放器狀態(tài)回調(diào)接口,方便使用者進(jìn)行狀態(tài)變化的處理和UI更新。

  • 增加了獲取當(dāng)前播放進(jìn)度和媒體源Uri的方法,方便使用者進(jìn)行狀態(tài)顯示和媒體源管理。

  • 實(shí)現(xiàn)了ExoPlayer的Player.EventListener回調(diào)接口,方便使用者進(jìn)行錯(cuò)誤處理和調(diào)試。

這個(gè)封裝示例可能仍然不是完美的,但是對(duì)于大多數(shù)應(yīng)用程序的使用場(chǎng)景已經(jīng)足夠成熟。如果需要更加復(fù)雜的功能,可以根據(jù)實(shí)際需。

在使用這個(gè)封裝類的時(shí)候,你需要按以下步驟進(jìn)行:

在你的Activity或Fragment中創(chuàng)建一個(gè)AudioPlayer實(shí)例,例如:

private AudioPlayer audioPlayer;

2.在創(chuàng)建完AudioPlayer實(shí)例后,調(diào)用init方法初始化。

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

其中,第一個(gè)參數(shù)傳入當(dāng)前的Context,第二個(gè)參數(shù)傳入媒體源的Uri。

3.在需要播放的時(shí)候,調(diào)用play方法:

audioPlayer.play();

4.如果需要暫停播放,調(diào)用pause方法:

audioPlayer.pause();

5.如果需要停止播放,調(diào)用stop方法:

audioPlayer.stop();

6.如果需要釋放播放器實(shí)例,取消實(shí)例化,調(diào)用release方法:

audioPlayer.release();

7.如果需要監(jiān)聽(tīng)播放器狀態(tài)回調(diào),可以通過(guò)setPlayerStateListener方法來(lái)設(shè)置:

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.如果需要獲取當(dāng)前播放進(jìn)度和媒體源Uri,可以調(diào)用getCurrentPosition和getCurrentUri方法:

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

以上就是大致的調(diào)用步驟,具體情況可以根據(jù)自己的場(chǎng)景進(jìn)行調(diào)整。

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);
        }
    }

在以上代碼中,我們添加了兩個(gè)接口,OnProgressListener是用來(lái)監(jiān)聽(tīng)進(jìn)度的,OnErrorListener是用來(lái)監(jiān)聽(tīng)播放異常的。在init方法中,我們給player對(duì)象添加了Player.EventListener接口和AnalyticsListener接口,分別用來(lái)監(jiān)聽(tīng)播放狀態(tài)的變化和進(jìn)度的變化。播放異常包括播放開(kāi)始前的異常和播放過(guò)程中的異常。在onPlaybackError方法中,我們回調(diào)OnErrorListener接口的onError方法。注意,在捕獲到播放異常時(shí),我們要調(diào)用release方法釋放資源。

最后,通過(guò)調(diào)用addOnErrorListener和addOnProgressListener方法,我們可以將外部傳進(jìn)來(lái)的OnErrorListener和OnProgressListener實(shí)例添加到AudioPlayer類中。這樣,在播放過(guò)程中,我們就可以監(jiān)聽(tīng)到錯(cuò)誤和進(jìn)度的變化了。

“Android Vitamio和ExoPlayer播放器的優(yōu)劣勢(shì)是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI