audio-channel-queue 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +249 -13
- package/dist/core.d.ts +53 -0
- package/dist/core.js +189 -0
- package/dist/events.d.ts +59 -0
- package/dist/events.js +162 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +47 -0
- package/dist/info.d.ts +122 -0
- package/dist/info.js +240 -0
- package/dist/types.d.ts +115 -0
- package/dist/types.js +5 -0
- package/dist/utils.d.ts +52 -0
- package/dist/utils.js +106 -0
- package/package.json +7 -4
- package/src/core.ts +209 -0
- package/src/events.ts +189 -0
- package/src/index.ts +66 -0
- package/src/info.ts +262 -0
- package/src/types.ts +127 -0
- package/src/utils.ts +109 -0
- package/dist/audio.d.ts +0 -10
- package/dist/audio.js +0 -66
package/src/utils.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Utility functions for the audio-channel-queue package
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { AudioInfo, QueueSnapshot, ExtendedAudioQueueChannel, QueueItem } from './types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extracts the filename from a URL string
|
|
9
|
+
* @param url - The URL to extract the filename from
|
|
10
|
+
* @returns The extracted filename or 'unknown' if extraction fails
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* extractFileName('https://example.com/audio/song.mp3') // Returns: 'song.mp3'
|
|
14
|
+
* extractFileName('/path/to/audio.wav') // Returns: 'audio.wav'
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export const extractFileName = (url: string): string => {
|
|
18
|
+
try {
|
|
19
|
+
const urlObj: URL = new URL(url);
|
|
20
|
+
const pathname: string = urlObj.pathname;
|
|
21
|
+
const segments: string[] = pathname.split('/');
|
|
22
|
+
const fileName: string = segments[segments.length - 1];
|
|
23
|
+
return fileName || 'unknown';
|
|
24
|
+
} catch {
|
|
25
|
+
// If URL parsing fails, try simple string manipulation
|
|
26
|
+
const segments: string[] = url.split('/');
|
|
27
|
+
const fileName: string = segments[segments.length - 1];
|
|
28
|
+
return fileName || 'unknown';
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Extracts comprehensive audio information from an HTMLAudioElement
|
|
34
|
+
* @param audio - The HTML audio element to extract information from
|
|
35
|
+
* @returns AudioInfo object with current playback state or null if audio is invalid
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const audioElement = new Audio('song.mp3');
|
|
39
|
+
* const info = getAudioInfoFromElement(audioElement);
|
|
40
|
+
* console.log(info?.progress); // Current progress as decimal (0-1)
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export const getAudioInfoFromElement = (audio: HTMLAudioElement): AudioInfo | null => {
|
|
44
|
+
if (!audio) return null;
|
|
45
|
+
|
|
46
|
+
const duration: number = isNaN(audio.duration) ? 0 : audio.duration * 1000; // Convert to milliseconds
|
|
47
|
+
const currentTime: number = isNaN(audio.currentTime) ? 0 : audio.currentTime * 1000; // Convert to milliseconds
|
|
48
|
+
const progress: number = duration > 0 ? Math.min(currentTime / duration, 1) : 0;
|
|
49
|
+
const isPlaying: boolean = !audio.paused && !audio.ended && audio.readyState > 2;
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
currentTime,
|
|
53
|
+
duration,
|
|
54
|
+
fileName: extractFileName(audio.src),
|
|
55
|
+
isPlaying,
|
|
56
|
+
progress,
|
|
57
|
+
src: audio.src
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates a complete snapshot of a queue's current state
|
|
63
|
+
* @param channelNumber - The channel number to create a snapshot for
|
|
64
|
+
* @param audioChannels - Array of audio channels
|
|
65
|
+
* @returns QueueSnapshot object or null if channel doesn't exist
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const snapshot = createQueueSnapshot(0, audioChannels);
|
|
69
|
+
* console.log(`Queue has ${snapshot?.totalItems} items`);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export const createQueueSnapshot = (
|
|
73
|
+
channelNumber: number,
|
|
74
|
+
audioChannels: ExtendedAudioQueueChannel[]
|
|
75
|
+
): QueueSnapshot | null => {
|
|
76
|
+
const channel: ExtendedAudioQueueChannel = audioChannels[channelNumber];
|
|
77
|
+
if (!channel) return null;
|
|
78
|
+
|
|
79
|
+
const items: QueueItem[] = channel.queue.map((audio: HTMLAudioElement, index: number) => ({
|
|
80
|
+
duration: isNaN(audio.duration) ? 0 : audio.duration * 1000,
|
|
81
|
+
fileName: extractFileName(audio.src),
|
|
82
|
+
isCurrentlyPlaying: index === 0 && !audio.paused && !audio.ended,
|
|
83
|
+
src: audio.src
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
channelNumber,
|
|
88
|
+
currentIndex: 0, // Current playing is always index 0 in our queue structure
|
|
89
|
+
items,
|
|
90
|
+
totalItems: channel.queue.length
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Removes webpack hash patterns from filenames to get clean, readable names
|
|
96
|
+
* @param fileName - The filename that may contain webpack hashes
|
|
97
|
+
* @returns The cleaned filename with webpack hashes removed
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* cleanWebpackFilename('song.a1b2c3d4.mp3') // Returns: 'song.mp3'
|
|
101
|
+
* cleanWebpackFilename('notification.1a2b3c4d5e6f7890.wav') // Returns: 'notification.wav'
|
|
102
|
+
* cleanWebpackFilename('music.12345678.ogg') // Returns: 'music.ogg'
|
|
103
|
+
* cleanWebpackFilename('clean-file.mp3') // Returns: 'clean-file.mp3' (unchanged)
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export const cleanWebpackFilename = (fileName: string): string => {
|
|
107
|
+
// Remove webpack hash pattern: filename.hash.ext → filename.ext
|
|
108
|
+
return fileName.replace(/\.[a-f0-9]{8,}\./i, '.');
|
|
109
|
+
};
|
package/dist/audio.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export type AudioQueue = HTMLAudioElement[];
|
|
2
|
-
export type AudioQueueChannel = {
|
|
3
|
-
queue: AudioQueue;
|
|
4
|
-
};
|
|
5
|
-
export declare const audioChannels: AudioQueueChannel[];
|
|
6
|
-
export declare const queueAudio: (audioUrl: string, channelNumber?: number) => Promise<void>;
|
|
7
|
-
export declare const playAudioQueue: (channelNumber: number) => Promise<void>;
|
|
8
|
-
export declare const stopCurrentAudioInChannel: (channelNumber?: number) => void;
|
|
9
|
-
export declare const stopAllAudioInChannel: (channelNumber?: number) => void;
|
|
10
|
-
export declare const stopAllAudio: () => void;
|
package/dist/audio.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.stopAllAudio = exports.stopAllAudioInChannel = exports.stopCurrentAudioInChannel = exports.playAudioQueue = exports.queueAudio = exports.audioChannels = void 0;
|
|
13
|
-
exports.audioChannels = [];
|
|
14
|
-
const queueAudio = (audioUrl_1, ...args_1) => __awaiter(void 0, [audioUrl_1, ...args_1], void 0, function* (audioUrl, channelNumber = 0) {
|
|
15
|
-
if (!exports.audioChannels[channelNumber]) {
|
|
16
|
-
exports.audioChannels[channelNumber] = { queue: [] };
|
|
17
|
-
}
|
|
18
|
-
const audio = new Audio(audioUrl);
|
|
19
|
-
exports.audioChannels[channelNumber].queue.push(audio);
|
|
20
|
-
if (exports.audioChannels[channelNumber].queue.length === 1) {
|
|
21
|
-
return (0, exports.playAudioQueue)(channelNumber);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
exports.queueAudio = queueAudio;
|
|
25
|
-
const playAudioQueue = (channelNumber) => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
-
const channel = exports.audioChannels[channelNumber];
|
|
27
|
-
if (channel.queue.length === 0)
|
|
28
|
-
return;
|
|
29
|
-
const currentAudio = channel.queue[0];
|
|
30
|
-
return new Promise((resolve) => {
|
|
31
|
-
currentAudio.addEventListener('ended', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
-
channel.queue.shift();
|
|
33
|
-
yield (0, exports.playAudioQueue)(channelNumber);
|
|
34
|
-
resolve();
|
|
35
|
-
}));
|
|
36
|
-
currentAudio.play();
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
exports.playAudioQueue = playAudioQueue;
|
|
40
|
-
const stopCurrentAudioInChannel = (channelNumber = 0) => {
|
|
41
|
-
const channel = exports.audioChannels[channelNumber];
|
|
42
|
-
if (channel && channel.queue.length > 0) {
|
|
43
|
-
const currentAudio = channel.queue[0];
|
|
44
|
-
currentAudio.pause();
|
|
45
|
-
channel.queue.shift();
|
|
46
|
-
(0, exports.playAudioQueue)(channelNumber);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
exports.stopCurrentAudioInChannel = stopCurrentAudioInChannel;
|
|
50
|
-
const stopAllAudioInChannel = (channelNumber = 0) => {
|
|
51
|
-
const channel = exports.audioChannels[channelNumber];
|
|
52
|
-
if (channel) {
|
|
53
|
-
if (channel.queue.length > 0) {
|
|
54
|
-
const currentAudio = channel.queue[0];
|
|
55
|
-
currentAudio.pause();
|
|
56
|
-
}
|
|
57
|
-
channel.queue = [];
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
exports.stopAllAudioInChannel = stopAllAudioInChannel;
|
|
61
|
-
const stopAllAudio = () => {
|
|
62
|
-
exports.audioChannels.forEach((_channel, index) => {
|
|
63
|
-
(0, exports.stopAllAudioInChannel)(index);
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
exports.stopAllAudio = stopAllAudio;
|