weex開發後臺音樂播放功能

找遍weex及相應第三方框架,沒發現有支持音樂播放的組件標籤,則自己動手實現這一功能

效果如圖(具體代碼及樣式在這裏不提供)


條件:

    1.使用基於weex的第三方框架eros

    2.會module擴展開發

    3.有java及android開發基礎


正文開始:

一.開發service

public class MusicService extends Service {

    public final IBinder binder = new MyBinder();
    public class MyBinder extends Binder{
       public MusicService getService() {
            return MusicService.this;
        }
    }
    public static MediaPlayer mp = new MediaPlayer();
    public MusicService() {

    }

    public void setVideoUrl(Context context, String videoUrl){
        try {
            YhTools.Log(videoUrl);
            mp.reset();
            Uri uri = Uri.parse(videoUrl);
            mp.setDataSource(context,uri);
            mp.prepare();
        } catch (Exception e) {
            YhTools.Log("can't get to the song");
            e.printStackTrace();
        }
    }

    public void start() {
        mp.start();
    }
    public boolean isPlaying() {
        return mp.isPlaying();
    }
    public void playOrPause() {
        if(mp.isPlaying()){
            mp.pause();
        } else {
            mp.start();
        }
    }
    public void stop() {
        if(mp != null) {
            mp.stop();
            try {
                mp.prepare();
                mp.seekTo(0);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onDestroy() {
        mp.stop();
        mp.release();
        super.onDestroy();
    }

    /**
     * onBind 是 Service 的虛方法,因此我們不得不實現它。
     * 返回 null,表示客服端不能建立到此服務的連接。
     */
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
}

二.在Application中添加全局靜態變量

public class App extends BMWXApplication {
private static Context appContext;
private static MusicService musicService = null;
private static LessonInfo lessonInfo = null;
.....此省略非重要代碼
@Override
public void onCreate() {
    super.onCreate();
    try {
        WXSDKEngine.registerModule("MusicModule", MusicModule.class);
    } catch (WXException e) {
        e.printStackTrace();
    }
.....此省略非重要代碼
appContext = getApplicationContext();
}
.....此省略非重要代碼

public static Context getContext() {
    return appContext;
}
public static void setMusicService(MusicService service){
    musicService = service;
}
public static MusicService getMusicService(){
    return musicService;
}

public static void setLessonInfo(LessonInfo lesson){
    lessonInfo = lesson;
}

public static LessonInfo getLessonInfo(){
    return lessonInfo;
}
}

三.module模塊開發

public class MusicModule extends WXModule {

    private ServiceConnection sc = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            App.setMusicService(((MusicService.MyBinder)iBinder).getService());
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            App.setMusicService(null);
        }
    };

    private void bindServiceConnection() {
        Intent intent = new Intent(mWXSDKInstance.getContext(), MusicService.class);
        App.getContext().startService(intent);
        App.getContext().bindService(intent, sc, Activity.BIND_AUTO_CREATE);
    }

    public void initService(){
        if(App.getMusicService() == null){
            YhTools.Log("ready to new MusicService");
            App.setMusicService(new MusicService());
            YhTools.Log("finish to new MusicService");
            bindServiceConnection();
        }
    }
    /**
     * 開始播放,默認播放路徑,並保存播放信息,爲後面切換回播放頁面時判斷是否是當前正在播放的 
     * @param
     */
    @JSMethod(uiThread = true)
    public void play(Map data) {
        if (data != null && data.size() > 0){
            String videoUrl = data.get("videourl").toString();
            int id = Integer.valueOf(data.get("id").toString());
            int sectionid = Integer.valueOf(data.get("sectionid").toString());

            if (!TextUtils.isEmpty(videoUrl)){
                initService();
                App.getMusicService().setVideoUrl( App.getContext(),videoUrl);
                App.getMusicService().start();

                LessonInfo lessonInfo = new LessonInfo();
                lessonInfo.setId(id);
                lessonInfo.setSectionid(sectionid);
                lessonInfo.setVideoUrl(videoUrl);
                App.setLessonInfo(lessonInfo);
            }
        }

    }

    /**
     * 開始/暫停播放
     * @param
     */
    @JSMethod(uiThread = true)
    public void playOrPause() {
        App.getMusicService().playOrPause();
    }

    /**
     * 停止播放
     * @param
     */
    @JSMethod(uiThread = true)
    public void stop() {
        App.getMusicService().stop();
    }
/**
 * 判斷是否正在播放,及最新播放的課程信息
 * @param callback
 */
@JSMethod (uiThread = false)
public void checkLesson(JSCallback callback){
    boolean isPlaying = false;
    if(App.getMusicService() != null){
        isPlaying = App.getMusicService().isPlaying();
    }

    Map<String, Object> map = new HashMap<>();
    map.put("isPlaying", isPlaying);
    map.put("lessonInfo", App.getLessonInfo());
    callback.invokeAndKeepAlive(map);
}
}

四.AndroidManifest.xml添加service

<service android:name=".service.MusicService" android:exported="true"></service>

五.weex前端核心代碼

1.播放功能

startLearn(){
    var lessonInfo = {
        id:this.id,
        sectionid:this.sectionid,
        videourl:this.videourl
    }
    this.playing = true;
    weex.requireModule('MusicModule').play(lessonInfo);
},

2.暫停與開始

weex.requireModule('MusicModule').playOrPause();

當從其他頁面跳轉播放頁面,頁面加載完成時調用

checkIsPlaying(){
    var _this = this;
    weex.requireModule('MusicModule').checkLesson(function (ret) {
        if(!ret.isPlaying){
            _this.startLearn();
        }else{

            if(typeof(ret.lessonInfo) != "undefined"){
                //如果正在播放的與現在的不是同一課程,則切換到現在這個
                if(ret.lessonInfo.id!=_this.id){
                    _this.startLearn();
                }else{
                    ...這裏查找正在播放的章節信息  
                }
                _this.playing = true;
            }

        }
    });
},

4.實現上一章節或下一章節,章節切換,設置sectionid,和vidourl,並調用startLearn方法即可


待完成功能

1.播放時間及進度條

2.封裝爲component組件或插件形式方便調用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章