Howler.js 离子和电容器媒体控制器

问题描述

我正在使用“Howler.js”和“Capacitor Music Controls Plugin”编写带有离子的应用程序。使用“howler.js”,我可以根据需要管理应用内音频文件,但是当应用程序继续在后台运行时,我想在状态栏上添加媒体控制功能。正如我所提到的,作为我研究的结果,我找到了“电容音乐控制插件”并成功地将其包含在项目中。如果我们遇到我的问题;虽然我可以在应用程序中“播放/暂停”,但我会在状态栏上暂停,但是当我再次按下播放时,它会尝试一遍又一遍地播放相同的音频文件。我在下面分享我编写和使用的函数

注意:据我在控制台上查看,它不止一次调用“CapacitorMusicControls”。您可以在下面详细查看。

https://ibb.co/Ld80LNX
https://ibb.co/6sPcmsd
https://ibb.co/Cs9Nw2L
https://ibb.co/Bj0h9fP
https://ibb.co/2hhqhQW

import { Injectable } from '@angular/core';
import { Howl } from 'howler';
import { Plugins } from '@capacitor/core';
const { CapacitorMusicControls } = Plugins;
@Injectable({
    providedIn: 'root'
})
export class GeneralService {
    public detail: string;
    public activeTrack;
    player: Howl = null;
    public isPlaying = false;
    public progress = 0;
    public durationSongHour = Number();
    public durationSongMin = Number();
    public durationSongSec = Number();
    public currentTime = Number();
    public currentTimeHour = Number();
    public currentTimeSec = Number();
    public currentTimeMin = Number();
    public durationSong = Number();
    public playlist: any;

constructor(
) {
    CapacitorMusicControls.addListener('controlsNotification',(info: any) => {
        console.log('listener',info.message);
        this.handleControlsEvent(info);
    });
}
public createMusicControl(track) {
    CapacitorMusicControls.create({
        track: track.title,// optional,default : ''
        artist: track.subtitle,default : ''
        cover: track.img,default : nothing
        // cover can be a local path (use fullpath 'file:///storage/emulated/...',or only 'my_image.jpg' if my_image.jpg is in the www folder of your app)
        //           or a remote url ('http://...','https://...','ftp://...')

        // hide prevIoUs/next/close buttons:
        hasPrev: true,// show prevIoUs button,optional,default: true
        hasNext: true,// show next button,default: true
        hasClose: true,// show close button,default: false

        // iOS only,optional
        duration: 60,default: 0
        elapsed: 10,default: 0
        hasSkipForward: true,//optional,default: false. true value overrides hasNext.
        hasSkipBackward: true,default: false. true value overrides hasPrev.
        skipForwardInterval: 15,//optional. default: 15.
        skipBackwardInterval: 15,//optional. default: 15.
        hasScrubbing: false,//optional. default to false. Enable scrubbing from control center progress bar 

        // Android only,optional
        isPlaying: true,default : true
        dismissable: true,default : false
        // text displayed in the status bar when the notification (and the ticker) are updated
        ticker: 'Now playing "Time is Running Out"',//All icons default to their built-in android equivalents
        //The supplied drawable name,e.g. 'media_play',is the name of a drawable found under android/res/drawable* folders

        playIcon: 'media_play',pauseIcon: 'media_pause',prevIcon: 'media_prev',nextIcon: 'media_next',closeIcon: 'media_close',notificationIcon: 'notification'
    },(res) => {
        console.log('res: ' + res);
    },(err) => {
        console.log('err: ' + err);
    });

}

public start(track) {
    if (this.player) {
        CapacitorMusicControls.destroy();
        this.player.stop();
    }
    this.player = new Howl({
        src: [track.path],html5: true,onplay: () => {
            console.log('onplay');
            this.detail = track;
            this.isPlaying = true;
            this.createMusicControl(track);
            this.activeTrack = track.id;
            this.durationSong = this.player.duration();
            this.durationSongHour = Math.floor(this.durationSong / 3600);
            this.durationSongMin = Math.floor(this.durationSong % 3600 / 60);
            this.durationSongSec = Math.floor(this.durationSong % 3600 % 60);
            this.acurrenTime();
            this.updateProgress();
        },onend: () => {
            this.nextSongAfterFinished();
        }
    });
    this.player.play();
}

public tooglePlayer(pause) {
    if (pause == "pause") {
        this.player.pause();
        this.isPlaying = false;
    } else if (pause == "play") {
        this.player.play();
        this.isPlaying = true;
    } else {
        this.player.pause();
        this.isPlaying = false;
    }
}

public nextSong(playlist) {
    var index = playlist.findindex(x => x.id === this.activeTrack);
    if (index != playlist.length - 1) {
        this.start(playlist[index + 1]);
    } else {
        this.start(playlist[0]);
    }
}

public nextSongAfterFinished() {
    console.log('sıradaki sıradaki',this.playlist);
    var index = this.playlist.findindex(x => x.id === this.activeTrack);
    if (index != this.playlist.length - 1) {
        this.start(this.playlist[index + 1]);
    } else {
        this.start(this.playlist[0]);
    }
}

public prevSong(playlist) {
    var index = playlist.findindex(x => x.id === this.activeTrack);
    if (index > 0) {
        this.start(playlist[index - 1]);
    } else {
        this.start(playlist[playlist.length - 1]);
    }
}

public acurrenTime() {
    this.currentTime = this.player.seek();
    this.currentTimeHour = Math.floor(this.currentTime / 3600);
    this.currentTimeMin = Math.floor(this.currentTime % 3600 / 60);
    this.currentTimeSec = Math.floor(this.currentTime % 3600 % 60);
    setTimeout(() => {
        this.currentTimeHour = Math.floor(this.currentTime / 3600);
        this.currentTimeMin = Math.floor(this.currentTime % 3600 / 60);
        this.currentTimeSec = Math.floor(this.currentTime % 3600 % 60);
        this.acurrenTime();
    },1000)
}

public seek(range) {
    let duration = this.player.duration();
    this.player.seek(duration * (range / 100));
}

public updateProgress() {
    let seek = this.player.seek();
    this.progress = (seek / this.player.duration()) * 100 || 0;
    setTimeout(() => {
        this.updateProgress();
    },1000)
}

handleControlsEvent(action) {
    const message = action.message;

    console.log("message: " + message)

    switch (message) {
        case 'music-controls-next':
            //do something               
            break;
        case 'music-controls-prevIoUs':
            //do something
            break;
        case 'music-controls-pause':
            this.isPlaying = false;
            this.player.pause();
            break;
        case 'music-controls-play':

            this.isPlaying = true;
            this.player.play();
            break;
        case 'music-controls-destroy':
            this.player.stop();
            this.activeTrack = null;
            CapacitorMusicControls.destroy();
            console.log('destroyed',message);
            break;
        // External controls (iOS only)
        case 'music-controls-toggle-play-pause':
            // do something
            break;
        case 'music-controls-seek-to':
            // do something
            break;
        case 'music-controls-skip-forward':
            // Do something
            break;
        case 'music-controls-skip-backward':
            // Do something
            break;
        // Headset events (Android only)
        // All media button events are listed below
        case 'music-controls-media-button':
            this.player.pause();
            break;
        case 'music-controls-headset-unplugged':
            // Do something
            break;
        case 'music-controls-headset-plugged':
            this.player.pause();
            break;
        default:
            break;
    }
}

}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)