這次想要練怎麼在手機上播放媒體,真的難! 最後整個是照著 Play Music in Ionic Capacitor apps 這篇文章在做練習。
npm install cordova-plugin-media
npm install @ionic-native/media
ionic cap sync
在 app.module 中 import。
我這邊卡了一陣子 原來我把 Media 放到 imports: 應該放在 providers:
這時候先跑 ionic cap open android 在 Android Studio 建置看看。
XDDD
music.page.html
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button defaultHref="/"></ion-back-button>
</ion-buttons>
<ion-title>music</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-thumbnail>
<img src="assets/album/BLACKPINK.jpg" />
</ion-thumbnail>
<p class="song-name">Lovesick Girls</p>
<ion-range min="0" max="{{duration}}" [(ngModel)]="position"> </ion-range>
<div class="playtime">
<ion-label class="start">{{ displayPosition }}</ion-label>
<ion-label class="end" *ngIf="duration == -1">--:--</ion-label>
<ion-label class="end" *ngIf="duration != -1"
>{{ displayDuration }}</ion-label
>
</div>
<ion-grid>
<ion-row style="height: 100%">
<ion-col>
<div class="player">
<ion-button fill="clear" (click)="controlSeconds('back')">
<ion-icon name="play-back"></ion-icon>
</ion-button>
<ion-button *ngIf="!isPlaying" (click)="play()">
<ion-icon name="play-outline" class="darkColor"></ion-icon>
</ion-button>
<ion-button *ngIf="isPlaying" (click)="pause()">
<ion-icon name="pause-outline" class="darkColor"></ion-icon>
</ion-button>
<ion-button fill="clear" (click)="controlSeconds('forward')">
<ion-icon name="play-forward"></ion-icon>
</ion-button>
</div>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
music.page.ts
getMusic() 主要只是取得音樂的時間而已。
按下播放鍵 (執行 play 方法) 執行 setToPlayback() 才真正開始放音樂。
在 setToPlayback() 中,也可以取得目前的狀態,看是否是在播放中。 最後執行 getAndSetCurrentAudioPosition(); 主要是設置 ion-range 元件,音樂播放到哪裡。
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Media, MediaObject } from '@ionic-native/media/ngx';
import { Platform } from '@ionic/angular';
@Component({
selector: 'app-music',
templateUrl: './music.page.html',
styleUrls: ['./music.page.scss'],
})
export class MusicPage implements OnInit, OnDestroy {
myMusic: MediaObject;
duration: any = -1;
isPlaying = false;
isReady = false;
getDurationInterval: any;
getPositionInterval: any;
position: any = 0;
displayPosition: any = '00:00';
displayDuration: any = '00:00';
constructor(public platform: Platform, private media: Media) {}
ngOnInit() {
this.platform.ready().then((res) => {
this.getMusic();
});
}
ngOnDestroy(): void {
this.stop();
}
getMusic() {
this.myMusic = this.media.create(
'/android_asset/public/assets/album/Lovesick Girls.mp3'
);
this.myMusic.play();
this.myMusic.setVolume(0.0);
let temp = this.duration; // 持續時間
this.getDurationInterval = setInterval(() => {
if (this.duration === -1 || !this.duration) {
this.duration = ~~this.myMusic.getDuration();
} else {
if (this.duration !== temp) {
temp = this.duration;
} else {
this.myMusic.stop();
this.myMusic.release();
clearInterval(this.getDurationInterval);
this.displayDuration = this.toHHMMSS(this.duration);
this.setToPlayback();
}
}
}, 100);
}
play() {
this.myMusic.play();
}
pause() {
this.myMusic.pause();
}
stop() {
this.myMusic.stop();
this.myMusic.release();
}
setToPlayback() {
this.myMusic = this.media.create(
'/android_asset/public/assets/album/Lovesick Girls.mp3'
);
this.myMusic.onStatusUpdate.subscribe((status) => {
switch (status) {
case 1:
break;
case 2:
this.isPlaying = true;
break;
case 3:
this.isPlaying = false;
break;
case 4:
default:
this.isPlaying = false;
break;
}
});
this.isReady = true;
this.getAndSetCurrentAudioPosition();
}
getAndSetCurrentAudioPosition() {
const diff = 1;
const self = this;
this.getPositionInterval = setInterval(() => {
const lastPosition = self.position;
this.myMusic.getCurrentPosition().then((position) => {
if (position >= 0 && position < self.duration) {
if (Math.abs(lastPosition - position) >= diff) {
this.myMusic.seekTo(lastPosition * 1000);
} else {
self.position = position;
this.displayPosition = this.toHHMMSS(self.position);
}
} else if (position >= self.duration) {
self.stop();
self.setToPlayback();
}
});
}, 100);
}
controlSeconds(action) {
const step = 5;
const numberRange = this.position;
switch (action) {
case 'back':
this.position = numberRange < step ? 0.001 : numberRange - step;
break;
case 'forward':
this.position = numberRange + step < this.duration ? numberRange + step : this.duration;
break;
default:
break;
}
}
toHHMMSS(secs) {
const secNum = parseInt(secs, 10);
const minutes = Math.floor(secNum / 60) % 60;
const seconds = secNum % 60;
return [minutes, seconds]
.map((v) => (v < 10 ? '0' + v : v))
.filter((v, i) => v !== '00' || i >= 0)
.join(':');
}
}
真心覺得一個 Player 不好做QQ...
參考:
Play Music in Ionic Capacitor apps