成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

HarmonyOS Sample 之 DistributedMusicPlayer分布式音樂(lè)播放器

開(kāi)發(fā) 前端 分布式 OpenHarmony
本示例主要演示了如何通過(guò)遷移數(shù)據(jù)進(jìn)行音樂(lè)的分布式播放。實(shí)現(xiàn)了音樂(lè)播放的跨設(shè)備遷移,包括:播放哪首歌曲、播放進(jìn)度、以及播放狀態(tài)的保持。

[[419218]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

DistributedMusicPlayer分布式音樂(lè)播放器

介紹

本示例主要演示了如何通過(guò)遷移數(shù)據(jù)進(jìn)行音樂(lè)的分布式播放。實(shí)現(xiàn)了音樂(lè)播放的跨設(shè)備遷移,包括:播放哪首歌曲、播放進(jìn)度、以及播放狀態(tài)的保持。

效果展示

搭建環(huán)境

安裝DevEco Studio,詳情請(qǐng)參考DevEco Studio下載

設(shè)置DevEco Studio開(kāi)發(fā)環(huán)境,DevEco Studio開(kāi)發(fā)環(huán)境需要依賴(lài)于網(wǎng)絡(luò)環(huán)境,需要連接上網(wǎng)絡(luò)才能確保工具的正常使用,可以根據(jù)如下兩種情況來(lái)配置開(kāi)發(fā)環(huán)境:

如果可以直接訪(fǎng)問(wèn)Internet,只需進(jìn)行下載HarmonyOS SDK操作

如果網(wǎng)絡(luò)不能直接訪(fǎng)問(wèn)Internet,需要通過(guò)代理服務(wù)器才可以訪(fǎng)問(wèn),請(qǐng)參考配置開(kāi)發(fā)環(huán)境

下載源碼,導(dǎo)入項(xiàng)目。

代碼結(jié)構(gòu)

  1.   config.json #全局配置文件 
  2. │ 
  3. ├─java 
  4. │  └─ohos 
  5. │      └─samples 
  6. │          └─distributedmusicplayer 
  7. │              │  MainAbility.java 
  8. │              │ 
  9. │              ├─slice 
  10. │              │      MainAbilitySlice.java     #播放器主能力Slice 
  11. │              │ 
  12. │              └─utils 
  13. │                      LogUtil.java     #日志工具類(lèi) 
  14. │                      PlayerManager.java   #播放器管理者 
  15. │                      PlayerStateListener.java #播放器狀態(tài)監(jiān)聽(tīng)器 
  16. │ 
  17. └─resources 
  18.     ├─base 
  19.     │  ├─element 
  20.     │  │      string.json 
  21.     │  │ 
  22.     │  ├─graphic 
  23.     │  │      button_bg.xml 
  24.     │  │ 
  25.     │  ├─layout 
  26.     │  │      main_ability_slice.xml        #播放器頁(yè)面布局 
  27.     │  │ 
  28.     │  └─media                  #海報(bào)、按鈕圖片資源 
  29.     │          album.png 
  30.     │          album2.png 
  31.     │          bg_blurry.png 
  32.     │          icon.png 
  33.     │          ic_himusic_next.png 
  34.     │          ic_himusic_pause.png 
  35.     │          ic_himusic_play.png 
  36.     │          ic_himusic_previous.png 
  37.     │          remote_play_selected.png 
  38.     │ 
  39.     └─rawfile                   #歌曲媒體資源 
  40.             Homey.mp3 
  41.             Homey.wav 
  42.             Technology.mp3 
  43.             Technology.wav 

實(shí)現(xiàn)步驟

1.實(shí)現(xiàn)跨設(shè)備遷移標(biāo)準(zhǔn)步驟,參見(jiàn)HarmonyOS Sample 之 AbilityInteraction設(shè)備遷移

2.實(shí)現(xiàn)一個(gè)播放器管理者PlayerManager

2.1.定義播放器的狀態(tài),包括: 播放、暫停、完成、播放中

  1. private static final int PLAY_STATE_PLAY = 0x0000001; 
  2. private static final int PLAY_STATE_PAUSE = 0x0000002; 
  3. private static final int PLAY_STATE_FINISH = 0x0000003; 
  4. private static final int PLAY_STATE_PROGRESS = 0x0000004; 

2.2.實(shí)現(xiàn)基本的方法,包括:播放、暫停、切換歌曲、更新播放進(jìn)度方法

還有一些輔助方法,包括:設(shè)置媒體資源、定時(shí)更新播放進(jìn)度、獲取播放總時(shí)長(zhǎng)、

要用到Player/Timer/自定義的PlayerStateListener/EventHandler事件處理/PlayCallBack播放器回調(diào)類(lèi)

  1. /** 
  2.  * play 
  3.  */ 
  4. public void play() { 
  5.     try { 
  6.         if (!isPrepared) { 
  7.             LogUtil.error(TAG, "prepare fail"); 
  8.             return
  9.         } 
  10.         //如果開(kāi)始播放則返回真; 否則返回 false。 
  11.         if (!musicPlayer.play()) { 
  12.             LogUtil.error(TAG, "play fail"); 
  13.             return
  14.         } 
  15.         startTask(); 
  16.         handler.sendEvent(PLAY_STATE_PLAY); 
  17.     } catch (IllegalArgumentException e) { 
  18.         LogUtil.error(TAG, e.getMessage()); 
  19.         e.printStackTrace(); 
  20.     } 
  21.  
  22. /** 
  23.  * pause 
  24.  */ 
  25. public void pause() { 
  26.     if (!musicPlayer.pause()) { 
  27.         LogUtil.info(TAG, "pause fail"); 
  28.         return
  29.     } 
  30.     //停止計(jì)時(shí) 
  31.     finishTask(); 
  32.     // 
  33.     handler.sendEvent(PLAY_STATE_PAUSE); 
  34. /** 
  35.  * switch music 
  36.  * 
  37.  * @param uri music uri 
  38.  */ 
  39. public void switchMusic(String uri) { 
  40.     currentUri = uri; 
  41.     //設(shè)置資源 
  42.     setResource(currentUri); 
  43.     //播放 
  44.     play(); 
  45.  
  46. /** 
  47.  * changes the playback position 
  48.  * 更新當(dāng)前播放進(jìn)度 
  49.  * 
  50.  * @param currentTime current time 
  51.  */ 
  52. public void rewindTo(int currentTime) { 
  53.     musicPlayer.rewindTo(currentTime * 1000); 
  54.  
  55. /** 
  56.  * set source 
  57.  * 
  58.  * @param uri music uri 
  59.  */ 
  60. public void setResource(String uri) { 
  61.     LogUtil.info(TAG, "setResource,uri:  " + uri); 
  62.     try { 
  63.         RawFileEntry rawFileEntry = context.getResourceManager().getRawFileEntry(uri); 
  64.         BaseFileDescriptor baseFileDescriptor = rawFileEntry.openRawFileDescriptor(); 
  65.         //LogUtil.info(TAG, "setResource,baseFileDescriptor :  " + baseFileDescriptor); 
  66.         if (!musicPlayer.setSource(baseFileDescriptor)) { 
  67.             LogUtil.info(TAG, "uri is invalid"); 
  68.             return
  69.         } 
  70.         //準(zhǔn)備播放環(huán)境并緩沖媒體數(shù)據(jù)。 
  71.         isPrepared = musicPlayer.prepare(); 
  72.         LogUtil.info(TAG, "setResource,isPrepared:  " + isPrepared); 
  73.         //歌曲名稱(chēng) 
  74.         String listenerUri = currentUri.substring(currentUri.lastIndexOf("/") + 1, currentUri.lastIndexOf(".")); 
  75.         playerStateListener.onUriSet(listenerUri); 
  76.         LogUtil.info(TAG, "setResource,listenerUri:  " + listenerUri); 
  77.     } catch (IOException e) { 
  78.         LogUtil.error(TAG, "io exception"); 
  79.     } 
  80. /** 
  81.  * 定時(shí)事件通知更新進(jìn)度條 
  82.  */ 
  83. private void startTask() { 
  84.     LogUtil.debug(TAG, "startTask"); 
  85.     finishTask(); 
  86.     timerTask = new TimerTask() { 
  87.         @Override 
  88.         public void run() { 
  89.             handler.sendEvent(PLAY_STATE_PROGRESS); 
  90.         } 
  91.     }; 
  92.     timer = new Timer(); 
  93.     timer.schedule(timerTask, DELAY_TIME, PERIOD); 
  94.  
  95. private void finishTask() { 
  96.     LogUtil.debug(TAG, "finishTask"); 
  97.     if (timer != null && timerTask != null) { 
  98.         timer.cancel(); 
  99.         timer = null
  100.         timerTask = null
  101.     } 
  102. }  

2.3.PlayerStateListener播放器狀態(tài)監(jiān)聽(tīng)器有如下方法:

onPlaySuccess播放成功時(shí)被調(diào)用

onPauseSuccess暫停時(shí)被調(diào)用

onPositionChange進(jìn)度發(fā)生變化時(shí)被調(diào)用

onMusicFinished音樂(lè)播放完成時(shí)被調(diào)用

onUriSet資源被設(shè)置時(shí)被調(diào)用

  1. /** 
  2.  * PlayerStateListener 
  3.  */ 
  4. public interface PlayerStateListener { 
  5.     void onPlaySuccess(int totalTime); 
  6.  
  7.     void onPauseSuccess(); 
  8.  
  9.     void onPositionChange(int currentTime); 
  10.  
  11.     void onMusicFinished(); 
  12.  
  13.     void onUriSet(String name); 

2.4.PlayCallBack播放器回調(diào)類(lèi)實(shí)現(xiàn)了Player.IPlayerCallback接口,實(shí)現(xiàn)了如下方法:

onPrepared 當(dāng)媒體文件準(zhǔn)備好播放時(shí)調(diào)用。

onMessage當(dāng)收到播放器消息或警報(bào)時(shí)調(diào)用。

onError收到播放器錯(cuò)誤消息時(shí)調(diào)用。

onResolutionChanged當(dāng)視頻大小改變時(shí)調(diào)用。

onPlayBackComplete播放完成時(shí)調(diào)用。

onRewindToComplete 當(dāng)播放位置被 Player.rewindTo(long) 改變時(shí)調(diào)用。

onBufferingChange當(dāng)緩沖百分比更新時(shí)調(diào)用。

onNewTimedMetaData當(dāng)有新的定時(shí)元數(shù)據(jù)可用時(shí)調(diào)用。

onMediaTimeIncontinuity當(dāng)媒體時(shí)間連續(xù)性中斷時(shí)調(diào)用,例如播放過(guò)程中出現(xiàn)錯(cuò)誤,播放位置被Player.rewindTo(long)改變,或者播放速度突然改變。

  1. /** 
  2.  * 在播放完成、播放位置更改和視頻大小更改時(shí)提供媒體播放器回調(diào)。 
  3.  */ 
  4. private class PlayCallBack implements Player.IPlayerCallback { 
  5.  
  6.     /** 
  7.      * 當(dāng)媒體文件準(zhǔn)備好播放時(shí)調(diào)用。 
  8.      */ 
  9.     @Override 
  10.     public void onPrepared() { 
  11.         LogUtil.info(TAG, "onPrepared"); 
  12.     } 
  13.  
  14.     /** 
  15.      * 當(dāng)收到播放器消息或警報(bào)時(shí)調(diào)用。 
  16.      * 
  17.      * @param type 
  18.      * @param extra 
  19.      */ 
  20.     @Override 
  21.     public void onMessage(int type, int extra) { 
  22.         LogUtil.info(TAG, "onMessage  " + type + "-" + extra); 
  23.     } 
  24.  
  25.  
  26.     /** 
  27.      * 收到播放器錯(cuò)誤消息時(shí)調(diào)用。 
  28.      * 
  29.      * @param errorType 
  30.      * @param errorCode 
  31.      */ 
  32.     @Override 
  33.     public void onError(int errorType, int errorCode) { 
  34.         LogUtil.info(TAG, "onError  " + errorType + "-" + errorCode); 
  35.     } 
  36.  
  37.     /** 
  38.      * 當(dāng)視頻大小改變時(shí)調(diào)用。 
  39.      * 
  40.      * @param width 
  41.      * @param height 
  42.      */ 
  43.     @Override 
  44.     public void onResolutionChanged(int width, int height) { 
  45.         LogUtil.info(TAG, "onResolutionChanged  " + width + "-" + height); 
  46.     } 
  47.  
  48.     /** 
  49.      * 播放完成時(shí)調(diào)用。 
  50.      */ 
  51.     @Override 
  52.     public void onPlayBackComplete() { 
  53.         //不會(huì)自動(dòng)被調(diào)用???? 
  54.         LogUtil.info(TAG, "onPlayBackComplete----------------"); 
  55.         handler.sendEvent(PLAY_STATE_FINISH); 
  56.  
  57.     } 
  58.  
  59.     /** 
  60.      * 當(dāng)播放位置被 Player.rewindTo(long) 改變時(shí)調(diào)用。 
  61.      */ 
  62.     @Override 
  63.     public void onRewindToComplete() { 
  64.         LogUtil.info(TAG, "onRewindToComplete"); 
  65.     } 
  66.  
  67.     /** 
  68.      * 當(dāng)緩沖百分比更新時(shí)調(diào)用。 
  69.      * 
  70.      * @param percent 
  71.      */ 
  72.     @Override 
  73.     public void onBufferingChange(int percent) { 
  74.         LogUtil.info(TAG, "onBufferingChange:" + percent); 
  75.     } 
  76.  
  77.     /** 
  78.      * 當(dāng)有新的定時(shí)元數(shù)據(jù)可用時(shí)調(diào)用。 
  79.      * 
  80.      * @param mediaTimedMetaData 
  81.      */ 
  82.     @Override 
  83.     public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) { 
  84.         LogUtil.info(TAG, "onNewTimedMetaData"); 
  85.     } 
  86.  
  87.  
  88.     /** 
  89.      * 當(dāng)媒體時(shí)間連續(xù)性中斷時(shí)調(diào)用,例如播放過(guò)程中出現(xiàn)錯(cuò)誤,播放位置被Player.rewindTo(long)改變,或者播放速度突然改變。 
  90.      * 
  91.      * @param mediaTimeInfo 
  92.      */ 
  93.     @Override 
  94.     public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) { 
  95.         LogUtil.info(TAG, "onNewTimedMetaData"); 
  96.     } 

3.MainAbilitySlice 中 implements PlayerStateListener , IAbilityContinuation接口

  1. public class MainAbilitySlice extends AbilitySlice implements PlayerStateListener, IAbilityContinuation { 
  2. ... 

3.1.實(shí)現(xiàn)PlayerStateListener接口方法

  1. @Override 
  2. public void onPlaySuccess(int totalTime) { 
  3.     LogUtil.debug(TAG, "onPlaySuccess"); 
  4.     //設(shè)置圖標(biāo) 
  5.     musicPlayButton.setPixelMap(ResourceTable.Media_ic_himusic_pause); 
  6.     //設(shè)置總時(shí)長(zhǎng)文本 
  7.     this.totalTimeText.setText(getTime(totalTime)); 
  8.     //設(shè)置進(jìn)度條 
  9.     slider.setMaxValue(totalTime); 
  10.     //設(shè)置當(dāng)前歌曲海報(bào) 
  11.     musicPosters.setPixelMap(posters[currentPos]); 
  12.  
  13. @Override 
  14. public void onPauseSuccess() { 
  15.     LogUtil.debug(TAG, "onPauseSuccess"); 
  16.     //設(shè)置圖標(biāo) 
  17.     musicPlayButton.setPixelMap(ResourceTable.Media_ic_himusic_play); 
  18.  
  19. @Override 
  20. public void onUriSet(String name) { 
  21.     LogUtil.debug(TAG, "onUriSet"); 
  22.     //設(shè)置歌曲名稱(chēng) 
  23.     musicNameText.setText(name); 
  24.  
  25. @Override 
  26. public void onPositionChange(int currentTime) { 
  27.    if(currentTime < totalTime){ 
  28.        LogUtil.info(TAG, "onPositionChange currentTime = " + currentTime+",totalTime="+totalTime); 
  29.        this.currentTime = currentTime; 
  30.         //設(shè)置播放時(shí)間文本 
  31.         this.currentTimeText.setText(getTime(currentTime)); 
  32.         //設(shè)置進(jìn)度條的當(dāng)前播放時(shí)間 
  33.         slider.setProgressValue(currentTime); 
  34.     }else
  35.        LogUtil.info(TAG, "onPositionChange, current song end"); 
  36.  
  37.        //設(shè)置播放器圖標(biāo) 
  38.         musicPlayButton.setPixelMap(ResourceTable.Media_ic_himusic_play); 
  39.     } 
  40.  
  41. /** 
  42.  *音樂(lè)播放完成時(shí)應(yīng)該被調(diào)用,但是沒(méi)被調(diào)用 
  43.  */ 
  44. @Override 
  45. public void onMusicFinished() { 
  46.     //TODO??????????? 
  47.     LogUtil.debug(TAG, "onMusicFinished"); 
  48.     currentPos = currentPos == 0 ? 1 : 0; 
  49.     currentUri = musics[currentPos]; 
  50.     //切換歌曲 
  51.     playerManager.switchMusic(currentUri); 
  52.     //總時(shí)長(zhǎng) 
  53.     totalTime=playerManager.getTotalTime(); 

3.2.實(shí)現(xiàn)IAbilityContinuation接口方法

  1. @Override 
  2. public boolean onStartContinuation() { 
  3.     LogUtil.debug(TAG, "onStartContinuation"); 
  4.     return true
  5.  
  6. @Override 
  7. public boolean onSaveData(IntentParams intentParams) { 
  8.     LogUtil.debug(TAG, "onSaveData"); 
  9.     // 
  10.     intentParams.setParam(KEY_CURRENT_TIME, currentTime); 
  11.     intentParams.setParam(KEY_POSITION, currentPos); 
  12.     intentParams.setParam(KEY_PLAY_STATE, String.valueOf(playerManager.isPlaying())); 
  13.     LogUtil.info(TAG, "onSaveData:" + currentTime); 
  14.     return true
  15.  
  16. @Override 
  17. public boolean onRestoreData(IntentParams intentParams) { 
  18.     LogUtil.debug(TAG, "onRestoreData"); 
  19.     if (!(intentParams.getParam(KEY_POSITION) instanceof Integer)) { 
  20.         return false
  21.     } 
  22.     if (!(intentParams.getParam(KEY_CURRENT_TIME) instanceof Integer)) { 
  23.         return false
  24.     } 
  25.     if (!(intentParams.getParam(KEY_PLAY_STATE) instanceof String)) { 
  26.         return false
  27.     } 
  28.  
  29.     //恢復(fù)數(shù)據(jù),獲取遷移過(guò)來(lái)的參數(shù):播放位置、時(shí)間和播放狀態(tài) 
  30.     currentPos = (int) intentParams.getParam(KEY_POSITION); 
  31.     currentTime = (int) intentParams.getParam(KEY_CURRENT_TIME); 
  32.     Object object = intentParams.getParam(KEY_PLAY_STATE); 
  33.  
  34.  
  35.     if (object instanceof String) { 
  36.         isPlaying = Boolean.parseBoolean((String) object); 
  37.     } 
  38.     isInteractionPlay = true
  39.     LogUtil.info(TAG, "onRestoreData:" + currentTime); 
  40.     return true
  41.  
  42. @Override 
  43. public void onCompleteContinuation(int i) { 
  44.     terminate(); 

3.3.定義ValueChangedListenerImpl進(jìn)度值變化的監(jiān)聽(tīng)事件

實(shí)現(xiàn) Slider.ValueChangedListener 接口方法

  1. /** 
  2.  *進(jìn)度條值變化的監(jiān)聽(tīng)事件 
  3.  */ 
  4. private class ValueChangedListenerImpl implements Slider.ValueChangedListener { 
  5.     @Override 
  6.     public void onProgressUpdated(Slider slider, int progress, boolean fromUser) { 
  7.         currentTime = progress; 
  8.     } 
  9.  
  10.     @Override 
  11.     public void onTouchStart(Slider slider) { 
  12.         LogUtil.debug(TAG, "onTouchStart"); 
  13.     } 
  14.  
  15.     @Override 
  16.     public void onTouchEnd(Slider slider) { 
  17.         LogUtil.debug(TAG, "onTouchEnd"); 
  18.         //快速更改播放進(jìn)度 
  19.         playerManager.rewindTo(currentTime); 
  20.         //當(dāng)前播放時(shí)間 
  21.         currentTimeText.setText(getTime(currentTime)); 
  22.     } 

3.4.定義遷移數(shù)據(jù)的KEY,音樂(lè)當(dāng)前的播放時(shí)間、播放的歌曲索引(位置)、播放狀態(tài)

  1. private static final String KEY_CURRENT_TIME = "main_ability_slice_current_time"
  2. private static final String KEY_POSITION = "main_ability_slice_position"
  3. private static final String KEY_PLAY_STATE = "main_ability_slice_play_state"
  4. private int currentPos = 0; 
  5. private String currentUri; 
  6. //是否是互動(dòng)播放,true表示遠(yuǎn)端遷移恢復(fù)的 
  7. private boolean isInteractionPlay; 
  8. private int currentTime; 
  9. //當(dāng)前播放歌曲總時(shí)長(zhǎng) 
  10. private int totalTime; 
  11. private boolean isPlaying; 

 3.5.定義播放的音樂(lè)URI,這里準(zhǔn)備了2首,還有對(duì)應(yīng)的海報(bào)

  1. private static final String URI1 = "resources/rawfile/Technology.wav"
  2. private static final String URI2 = "resources/rawfile/Homey.wav"
  3. private final String[] musics = {URI1, URI2}; 
  4. private final int[] posters = {ResourceTable.Media_album, ResourceTable.Media_album2}; 

 3.6.onStart完成數(shù)據(jù)的初始化

  1. @Override 
  2. public void onStart(Intent intent) { 
  3.     super.onStart(intent); 
  4.     super.setUIContent(ResourceTable.Layout_main_ability_slice); 
  5.  
  6.     initComponents(); 
  7.  
  8.     initMedia(); 
  9.  
  10.     updateUI(); 

初始化界面組件,實(shí)現(xiàn)對(duì)應(yīng)按鈕的監(jiān)聽(tīng)事件

播放或暫停、上一首、下一首、遷移以及進(jìn)度條的進(jìn)度變化事件的監(jiān)聽(tīng)

  1. /** 
  2.  * 初始化界面組件,實(shí)現(xiàn)對(duì)應(yīng)按鈕的監(jiān)聽(tīng)事件 
  3.  * 播放或暫停、上一首、下一首、遷移以及進(jìn)度條的進(jìn)度變化事件的監(jiān)聽(tīng) 
  4.  */ 
  5. private void initComponents() { 
  6.     LogUtil.debug(TAG, "initComponents"); 
  7.     musicNameText = (Text) findComponentById(ResourceTable.Id_music_name); 
  8.     currentTimeText = (Text) findComponentById(ResourceTable.Id_play_progress_time); 
  9.     totalTimeText = (Text) findComponentById(ResourceTable.Id_play_total_time); 
  10.  
  11.     musicPosters = (Image) findComponentById(ResourceTable.Id_music_posters); 
  12.  
  13.     musicPlayButton = (Image) findComponentById(ResourceTable.Id_music_play_btn); 
  14.     findComponentById(ResourceTable.Id_remote_play).setClickedListener(this::continueAbility); 
  15.     findComponentById(ResourceTable.Id_music_play_prev_btn).setClickedListener(this::prevMusic); 
  16.     findComponentById(ResourceTable.Id_music_play_next_btn).setClickedListener(this::nextMusic); 
  17.  
  18.     musicPlayButton.setClickedListener(this::playOrPauseMusic); 
  19.  
  20.     // 
  21.     slider = (Slider) findComponentById(ResourceTable.Id_play_progress_bar); 
  22.     slider.setValueChangedListener(new ValueChangedListenerImpl()); 
  23.  
  24. private void continueAbility(Component component) { 
  25.     try { 
  26.         continueAbility(); 
  27.     } catch (IllegalStateException e) { 
  28.         LogUtil.info(TAG, e.getMessage()); 
  29.     } 
  30.  
  31. /** 
  32.  * 上一首 
  33.  * @param component 
  34.  */ 
  35. private void prevMusic(Component component) { 
  36.     currentPos = currentPos == 0 ? 1 : 0; 
  37.     currentUri = musics[currentPos]; 
  38.     // 
  39.     playerManager.switchMusic(currentUri); 
  40.     //總時(shí)長(zhǎng) 
  41.     totalTime=playerManager.getTotalTime(); 
  42.  
  43. /** 
  44.  * 下一首 
  45.  * @param component 
  46.  */ 
  47. private void nextMusic(Component component) { 
  48.     currentPos = currentPos == 0 ? 1 : 0; 
  49.     currentUri = musics[currentPos]; 
  50.     //切換音樂(lè) 
  51.     playerManager.switchMusic(currentUri); 
  52.     //總時(shí)長(zhǎng) 
  53.     totalTime=playerManager.getTotalTime(); 
  54.  
  55. /** 
  56.  * 播放或暫停音樂(lè) 
  57.  * @param component 
  58.  */ 
  59. private void playOrPauseMusic(Component component) { 
  60.     // 
  61.     playOrPause(); 
  62.  
  63. /** 
  64.  * 播放或暫停 
  65.  */ 
  66. private void playOrPause() { 
  67.  
  68.     LogUtil.debug(TAG, "playOrPause,playerManager:"+playerManager); 
  69.     try { 
  70.         // 
  71.         if (playerManager.isPlaying()) { 
  72.             LogUtil.debug(TAG, "playOrPause pause"); 
  73.             playerManager.pause(); 
  74.         }else
  75.             //設(shè)置資源 
  76.             playerManager.setResource(currentUri); 
  77.             //設(shè)置進(jìn)度 
  78.             playerManager.rewindTo(currentTime); 
  79.             playerManager.play(); 
  80.             LogUtil.debug(TAG, "playOrPause play"); 
  81.         } 
  82.     } catch (Exception e) { 
  83.         LogUtil.error(TAG, "playOrPause"); 
  84.         e.printStackTrace(); 
  85.     } 

3.7.初始化媒體對(duì)象

當(dāng)前播放歌曲資源,播放器管理者

  1. /** 
  2.  * 初始化媒體對(duì)象 
  3.  * 當(dāng)前播放歌曲資源 
  4.  * 播放器管理者 
  5.  */ 
  6. private void initMedia() { 
  7.     LogUtil.debug(TAG, "initMedia"); 
  8.     //當(dāng)前媒體URI 
  9.     currentUri = musics[currentPos]; 
  10.     LogUtil.debug(TAG, "initMedia,currentUri:"+currentUri); 
  11.     //初始化playerManager 
  12.     playerManager = new PlayerManager(getApplicationContext(), currentUri); 
  13.  
  14.     //弱引用對(duì)象,不會(huì)阻止它們的引用對(duì)象被終結(jié)、終結(jié)和回收。 弱引用最常用于實(shí)現(xiàn)規(guī)范化映射。 
  15.     WeakReference<PlayerStateListener> playerStateListener = new WeakReference<>(this); 
  16.     //設(shè)置狀態(tài)監(jiān)聽(tīng)器 
  17.     playerManager.setPlayerStateListener(playerStateListener.get()); 
  18.     //初始化播放器信息 
  19.     playerManager.init(); 
  20.     LogUtil.debug(TAG, "initMedia FINISH"); 

3.8.遠(yuǎn)端遷移后恢復(fù)播放界面

恢復(fù)播放器的播放進(jìn)度、播放狀態(tài)、海報(bào)、當(dāng)前時(shí)間和總時(shí)長(zhǎng)、slider播放進(jìn)度

  1. /** 
  2.  * 遠(yuǎn)端遷移后恢復(fù)的播放,恢復(fù)播放器的播放進(jìn)度 
  3.  * 更新UI界面 
  4.  */ 
  5. private void updateUI() { 
  6.     LogUtil.debug(TAG, "updateUI"); 
  7.     //海報(bào) 
  8.     musicPosters.setPixelMap(posters[currentPos]); 
  9.     //當(dāng)前時(shí)間和總時(shí)長(zhǎng) 
  10.     currentTimeText.setText(getTime(currentTime)); 
  11.     totalTimeText.setText(getTime(playerManager.getTotalTime())); 
  12.     //播放進(jìn)度 
  13.     slider.setMaxValue(playerManager.getTotalTime()); 
  14.     slider.setProgressValue(currentTime); 
  15.  
  16.     //總時(shí)長(zhǎng) 
  17.     totalTime=playerManager.getTotalTime(); 
  18.  
  19.     //遠(yuǎn)端遷移恢復(fù) 
  20.     if (isInteractionPlay) { 
  21.         LogUtil.debug(TAG, "remotePlay,rewindTo:"+currentTime); 
  22.         playerManager.rewindTo(currentTime); 
  23.         if (!isPlaying) { 
  24.             return
  25.         } 
  26.         //播放 
  27.         playerManager.play(); 
  28.     } 

問(wèn)題總結(jié)

1.onMusicFinished 音樂(lè)播放完成時(shí)應(yīng)該被調(diào)用,但是多數(shù)沒(méi)被調(diào)用,只是偶爾會(huì)調(diào)用,難道是我電腦性能跟不上了?

2.優(yōu)化了源碼中應(yīng)用啟動(dòng)后,點(diǎn)擊播放無(wú)法播放的問(wèn)題

3.優(yōu)化了播放器播放完當(dāng)前歌曲更新播放圖標(biāo)

4.增加了相關(guān)的注釋說(shuō)明

附件直接下載DistributedMusicPlayer.zip

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來(lái)源: 鴻蒙社區(qū)
相關(guān)推薦

2022-11-08 15:48:35

應(yīng)用開(kāi)發(fā)音樂(lè)播放器

2021-10-19 14:27:07

鴻蒙HarmonyOS應(yīng)用

2021-10-21 16:00:07

鴻蒙HarmonyOS應(yīng)用

2021-12-10 15:06:56

鴻蒙HarmonyOS應(yīng)用

2021-12-02 10:11:44

鴻蒙HarmonyOS應(yīng)用

2011-06-27 11:23:21

Qt 音樂(lè)播放器

2009-12-17 15:10:31

Linux音樂(lè)播放器

2014-12-31 16:52:53

音樂(lè)播放器源碼

2018-07-17 08:14:22

分布式分布式鎖方位

2017-03-01 14:01:31

android多媒體音樂(lè)代碼

2011-04-06 10:03:45

谷歌云計(jì)算Android音

2017-02-20 09:15:34

Linux播放器Qmmp

2019-02-11 09:20:35

Linux音樂(lè)播放器

2022-06-28 14:23:51

分布式音樂(lè)播放器

2025-06-13 07:30:51

2013-07-23 17:55:14

酷狗音樂(lè)mac

2011-08-30 09:48:07

Ubuntu

2022-03-06 21:43:05

Citus架構(gòu)PostgreSQL

2019-02-13 13:41:07

MemCache分布式HashMap

2019-09-26 15:43:52

Hadoop集群防火墻
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲一区欧美 | 日韩在线精品 | 国产精品久久久久久中文字 | 91色站 | 久久综合成人精品亚洲另类欧美 | 中文字幕av在线一二三区 | 国产精品亚洲综合 | 日韩欧美一区二区三区免费观看 | 91久久久久久久久久久 | 中文字幕一区二区三区不卡在线 | 一级做a爰片久久毛片免费看 | 亚洲三级在线 | 欧美一级α片 | 男女激情网 | 亚洲电影专区 | 成人在线视频观看 | 久久久国产精品 | 欧美三级久久久 | 涩涩视频网站在线观看 | 97人人超碰| 亚洲一区国产精品 | 一区在线视频 | 97久久精品午夜一区二区 | 日韩av在线免费 | 欧美成人精品在线观看 | 一本一道久久a久久精品蜜桃 | 欧美在线视频二区 | 欧美激情精品久久久久久 | 美女国内精品自产拍在线播放 | 日韩一区二区三区在线视频 | 欧美性猛片aaaaaaa做受 | 亚洲在线一区二区 | 91精品久久久久久久久99蜜臂 | 日韩免费毛片视频 | 免费一区在线观看 | 99re在线观看 | 久久高清免费视频 | 日韩一级 | 一区二区三区视频在线 | 五月综合色啪 | 欧美精品在线一区二区三区 |