分享一下怎麼樣用 {N}-Vue 做出一個簡單的健身倒數計時器,安裝2個套件,讀取手機內部聲音檔案,倒數計時完後播放聲音。
環境
- nativescript 5.2.0
- Sidekick
- MacOS
Step 1.建立專案
使用 sidekick 建立 Vue 專案
看到以下表示專案建立完成:
Step 2.安裝相關套件
tns plugin add nativescript-mediafilepicker
tns plugin add nativescript-audio
提醒:
nativescript-audio
和nativescript-audio-player
是不同的,別搞混
若安裝成功可以在 package.json 裡看到
安裝完 plugin 後,記得下指令 rm -rf platforms
編輯 app/components/Home.vue
看官網文件得知 import 的方式:
<script>
const { Mediafilepicker } = require("nativescript-mediafilepicker");
import { TNSPlayer } from "nativescript-audio";
</script>
Step 3.版面
<template>
<Page class="page">
<ActionBar class="action-bar">
<Label class="action-bar-title" text="Workout rest timer"></Label>
</ActionBar>
<StackLayout>
<FlexboxLayout class="center">
<Button @tap="pickFile" text="Select audio"></Button>
<Button @tap="count_down(3)" text="3 sec"></Button>
<Button @tap="count_down(60)" text="1 min"></Button>
<Button @tap="reset" text="reset"></Button>
</FlexboxLayout>
<Label :text="display_num" class="display"></Label>
<Label :text="'play:' + audioPath"></Label>
<Button v-if="showStopbtn" @tap="clickStop" text="暫停"></Button>
</StackLayout>
</Page>
</template>
style:
<style scoped lang="scss">
.display {
font-size: 85;
text-align: center;
}
.center {
justify-content: center;
align-items: center;
}
</style>
Step 4. 商業邏輯
Step 4.0 解釋data
data() {
return {
display_num: 0,
c_id: null,
audioPath: null,
player: null,
showStopbtn: false
};
},
display_num
為螢幕上顯示倒數的數字
audioPath
:存儲使用者選擇的音樂檔
showStopbtn
:判斷是否顯示「暫停」按鈕的 flag
函數結構:
methods: {
pickFile() {
// Put it later
},
count_down(num) {
// Put it later
},
play() {
// Put it later
},
clickStop() {
// Put it later
},
reset() {
// Put it later
}
}
Step 4.1 pickFile
按下 Select Audio
按鈕後,使用 nativescript-mediafilepicker plugin,挑選手機內部聲音檔
根據 nativescript-mediafilepicker
的文件
pickFile() {
let options = {
android: {
maxNumberFiles: 1, // 只接受挑選一個檔案
extensions: ["mp3"] //只接受 *.mp3
}
};
let mpicker = new Mediafilepicker();
mpicker.openFilePicker(options);
mpicker.on("getFiles", res => {
let results = res.object.get("results");
// 選到的檔案路徑為 results[0].file,設定到 `this.audioPath` 裡
this.audioPath = results[0].file;
console.log("Set path: ", this.audioPath);
});
mpicker.on("error", res => {
let msg = res.object.get("msg");
console.log(msg);
});
mpicker.on("cancel", res => {
let msg = res.object.get("msg");
console.log(msg);
});
},
Step 4.2 count_down
當按下 3 sec
的按鈕時,執行count_down(3)
,如果還有其他的計時器正在倒數,先停止其他計器器。再開始新的倒數。倒數結束時,呼叫 this.play()
播放音樂。
count_down(num) {
if (this.c_id) clearInterval(this.c_id);
this.display_num = num;
this.showStopbtn = true //顯示「Stop」按鈕
this.c_id = setInterval(() => {
this.display_num = this.display_num - 1;
if (this.display_num === 0) {
this.display_num = `Time's up`;
this.play(); //播放音樂
clearInterval(this.c_id); //把計時器清空
}
}, 1000);
}
Step 4.3 play
當倒數結束時,執行 this.play()
來播放音樂
根據 nativescript-audio 的文件,學習使用方式。
把要播放的檔案路徑,設定到 audioFile
中。
play() {
if (!this.audioPath) return;
this.player = new TNSPlayer();
const playerOptions = {
// 把 4.1 選到的 audioPath 指定給 audioFile 參數
audioFile: this.audioPath,
loop: false,
completeCallback: function() {
console.log("finished playing");
},
errorCallback: function(errorObject) {
console.log(JSON.stringify(errorObject));
},
infoCallback: function(args) {
console.log(JSON.stringify(args));
}
};
this.player
.playFromUrl(playerOptions)
.then(res => {
console.log(res);
})
.catch(err => {
console.log("something went wrong...", err);
});
}, // end play
Step 4.4 clickStop
當下按 暫停
按鈕時,呼叫 clickStop
clickStop() {
if (this.c_id) clearInterval(this.c_id);
if (this.player) this.player.pause();
this.showStopbtn = false;
this.display_num = 0;
},
Step 4.5 reset
當按下 Reset
的按鈕時,執行reset()
reset() {
if (this.c_id) clearInterval(this.c_id);
this.display_num = 0;
this.audioPath = null;
if (this.player) this.player.pause();
this.showStopbtn = false;
},
Step 5. 打開模擬器
tns run android --bundle
Step 6. 在模擬器裡新增檔案
把聲音檔用拖拉的方式拉到 emulator 裡,他會存在 /sdcard/download
這時候請長按模擬器的電源,重新開機,如此程式才能正常讀取到檔案。