UNPKG

tunzo-player

Version:

A music playback service for Angular and Ionic apps with native audio control support.

163 lines (162 loc) 4.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Player = void 0; const rxjs_1 = require("rxjs"); class Player { /** Initialize with playlist and quality */ static initialize(playlist, quality = 3) { this.playlist = playlist; this.selectedQuality = quality; } /** Call this once on user gesture to unlock audio in WebView */ static unlockAudio() { this.audio.src = ''; this.audio.load(); this.audio.play().catch(() => { }); } static play(song, index = 0) { var _a; if (!song || !song.downloadUrl) return; this.currentSong = song; this.currentIndex = index; let url = ((_a = song.downloadUrl[this.selectedQuality]) === null || _a === void 0 ? void 0 : _a.url) || ''; // 🚀 Auto-convert http → https if (url.startsWith('http://')) { url = url.replace('http://', 'https://'); } this.audio.src = url; this.audio.load(); // Ensure audio is loaded before play this.audio.play().then(() => { this.isPlaying = true; }).catch((err) => { this.isPlaying = false; console.warn('Audio play failed:', err); }); // Set duration this.audio.onloadedmetadata = () => { this.duration = this.audio.duration; }; // Set current time this.audio.ontimeupdate = () => { this.currentTime = this.audio.currentTime; }; // Auto-play next song this.audio.onended = () => { this.autoNext(); }; // Catch errors this.audio.onerror = (e) => { console.error('Audio error:', this.audio.error, e); }; } static pause() { this.audio.pause(); this.isPlaying = false; } static resume() { this.audio.play(); this.isPlaying = true; } static togglePlayPause() { if (this.isPlaying) { this.pause(); } else { this.resume(); } } static next() { if (this.queue.length > 0) { const nextQueued = this.queue.shift(); this.queue$.next([...this.queue]); const index = this.playlist.findIndex(s => s.id === nextQueued.id); this.play(nextQueued, index); } else if (this.isShuffle) { this.playRandom(); } else if (this.currentIndex < this.playlist.length - 1) { this.play(this.playlist[this.currentIndex + 1], this.currentIndex + 1); } } static prev() { if (this.currentIndex > 0) { this.play(this.playlist[this.currentIndex - 1], this.currentIndex - 1); } } static seek(seconds) { this.audio.currentTime = seconds; } static autoNext() { this.next(); } static playRandom() { if (this.playlist.length <= 1) return; let randomIndex; do { randomIndex = Math.floor(Math.random() * this.playlist.length); } while (randomIndex === this.currentIndex); this.play(this.playlist[randomIndex], randomIndex); } static toggleShuffle() { this.isShuffle = !this.isShuffle; } static getShuffleStatus() { return this.isShuffle; } static addToQueue(song) { if (!this.queue.some(q => q.id === song.id)) { this.queue.push(song); this.queue$.next([...this.queue]); } } static removeFromQueue(index) { this.queue.splice(index, 1); this.queue$.next([...this.queue]); } static reorderQueue(from, to) { const item = this.queue.splice(from, 1)[0]; this.queue.splice(to, 0, item); this.queue$.next([...this.queue]); } static getCurrentTime() { return this.currentTime; } static getDuration() { return this.duration; } static formatTime(time) { const minutes = Math.floor(time / 60); const seconds = Math.floor(time % 60); return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`; } static isPlayingSong() { return this.isPlaying; } static getCurrentSong() { return this.currentSong; } static setQuality(index) { this.selectedQuality = index; } static getQueue() { return this.queue; } static getPlaylist() { return this.playlist; } } exports.Player = Player; Player.audio = new Audio(); Player.currentSong = null; Player.currentIndex = 0; Player.isPlaying = false; Player.currentTime = 0; Player.duration = 0; Player.isShuffle = true; Player.queue = []; Player.queue$ = new rxjs_1.BehaviorSubject([]); Player.playlist = []; Player.selectedQuality = 3;