@maxmellon/cue-parser 1.0.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/LICENSE +21 -0
- package/README.md +374 -0
- package/bin/index.js +283 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +34 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/parser.d.ts +49 -0
- package/dist/src/parser.d.ts.map +1 -0
- package/dist/src/parser.js +395 -0
- package/dist/src/parser.js.map +1 -0
- package/dist/src/serializer.d.ts +31 -0
- package/dist/src/serializer.d.ts.map +1 -0
- package/dist/src/serializer.js +240 -0
- package/dist/src/serializer.js.map +1 -0
- package/dist/src/types.d.ts +95 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +5 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils.d.ts +72 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +142 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/src/youtube-serializer.d.ts +11 -0
- package/dist/src/youtube-serializer.d.ts.map +1 -0
- package/dist/src/youtube-serializer.js +40 -0
- package/dist/src/youtube-serializer.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { formatCueTime } from './utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* CUE Sheet serializer - converts parsed CueSheet objects back to CUE format
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Serialize a CueSheet object back to CUE sheet format string
|
|
7
|
+
* @param cueSheet - The parsed CueSheet object
|
|
8
|
+
* @returns CUE sheet format string
|
|
9
|
+
*/
|
|
10
|
+
export function serializeCueSheet(cueSheet) {
|
|
11
|
+
const lines = [];
|
|
12
|
+
// Add global section
|
|
13
|
+
serializeGlobal(cueSheet.global, lines);
|
|
14
|
+
// Add tracks with optimized FILE handling
|
|
15
|
+
serializeTracksOptimized(cueSheet.tracks, lines);
|
|
16
|
+
return lines.join('\n') + '\n';
|
|
17
|
+
} /**
|
|
18
|
+
* Serialize the global section of a CUE sheet
|
|
19
|
+
* @param global - Global CUE sheet information
|
|
20
|
+
* @param lines - Array to append lines to
|
|
21
|
+
*/
|
|
22
|
+
function serializeGlobal(global, lines) {
|
|
23
|
+
// Add remarks first
|
|
24
|
+
if (global.remarks && global.remarks.length > 0) {
|
|
25
|
+
global.remarks.forEach(remark => {
|
|
26
|
+
lines.push(`REM ${remark}`);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
// Add catalog
|
|
30
|
+
if (global.catalog) {
|
|
31
|
+
lines.push(`CATALOG ${global.catalog}`);
|
|
32
|
+
}
|
|
33
|
+
// Add CD-TEXT file
|
|
34
|
+
if (global.cdTextFile) {
|
|
35
|
+
lines.push(`CDTEXTFILE "${global.cdTextFile}"`);
|
|
36
|
+
}
|
|
37
|
+
// Add global FILE
|
|
38
|
+
if (global.file) {
|
|
39
|
+
const formatStr = global.file.format ? ` ${global.file.format}` : '';
|
|
40
|
+
if (global.file.filename.includes(' ') || global.file.filename.includes('"')) {
|
|
41
|
+
lines.push(`FILE "${escapeString(global.file.filename)}"${formatStr}`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
lines.push(`FILE ${global.file.filename}${formatStr}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Add CD-TEXT fields
|
|
48
|
+
if (global.title) {
|
|
49
|
+
lines.push(`TITLE "${escapeString(global.title)}"`);
|
|
50
|
+
}
|
|
51
|
+
if (global.performer) {
|
|
52
|
+
lines.push(`PERFORMER "${escapeString(global.performer)}"`);
|
|
53
|
+
}
|
|
54
|
+
if (global.songwriter) {
|
|
55
|
+
lines.push(`SONGWRITER "${escapeString(global.songwriter)}"`);
|
|
56
|
+
}
|
|
57
|
+
if (global.composer) {
|
|
58
|
+
lines.push(`COMPOSER "${escapeString(global.composer)}"`);
|
|
59
|
+
}
|
|
60
|
+
if (global.arranger) {
|
|
61
|
+
lines.push(`ARRANGER "${escapeString(global.arranger)}"`);
|
|
62
|
+
}
|
|
63
|
+
if (global.message) {
|
|
64
|
+
lines.push(`MESSAGE "${escapeString(global.message)}"`);
|
|
65
|
+
}
|
|
66
|
+
if (global.discId) {
|
|
67
|
+
lines.push(`DISC_ID "${escapeString(global.discId)}"`);
|
|
68
|
+
}
|
|
69
|
+
if (global.genre) {
|
|
70
|
+
lines.push(`GENRE "${escapeString(global.genre)}"`);
|
|
71
|
+
}
|
|
72
|
+
if (global.upcEan) {
|
|
73
|
+
lines.push(`UPC_EAN "${escapeString(global.upcEan)}"`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Serialize tracks without FILE fields
|
|
78
|
+
* @param tracks - Array of tracks
|
|
79
|
+
* @param lines - Array to append lines to
|
|
80
|
+
*/
|
|
81
|
+
function serializeTracksOptimized(tracks, lines) {
|
|
82
|
+
tracks.forEach(track => {
|
|
83
|
+
serializeTrackContent(track, lines);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Serialize a track's content (without FILE)
|
|
88
|
+
* @param track - Track information
|
|
89
|
+
* @param lines - Array to append lines to
|
|
90
|
+
*/
|
|
91
|
+
function serializeTrackContent(track, lines) {
|
|
92
|
+
// Add track line
|
|
93
|
+
lines.push(`\t\tTRACK ${track.number.toString().padStart(2, '0')} ${track.mode}`);
|
|
94
|
+
// Add track-level CD-TEXT
|
|
95
|
+
if (track.title) {
|
|
96
|
+
lines.push(`\t\t\tTITLE "${escapeString(track.title)}"`);
|
|
97
|
+
}
|
|
98
|
+
if (track.performer) {
|
|
99
|
+
lines.push(`\t\t\tPERFORMER "${escapeString(track.performer)}"`);
|
|
100
|
+
}
|
|
101
|
+
if (track.songwriter) {
|
|
102
|
+
lines.push(`\t\t\tSONGWRITER "${escapeString(track.songwriter)}"`);
|
|
103
|
+
}
|
|
104
|
+
if (track.composer) {
|
|
105
|
+
lines.push(`\t\t\tCOMPOSER "${escapeString(track.composer)}"`);
|
|
106
|
+
}
|
|
107
|
+
if (track.arranger) {
|
|
108
|
+
lines.push(`\t\t\tARRANGER "${escapeString(track.arranger)}"`);
|
|
109
|
+
}
|
|
110
|
+
if (track.message) {
|
|
111
|
+
lines.push(`\t\t\tMESSAGE "${escapeString(track.message)}"`);
|
|
112
|
+
}
|
|
113
|
+
// Add ISRC
|
|
114
|
+
if (track.isrc) {
|
|
115
|
+
lines.push(`\t\t\tISRC ${track.isrc}`);
|
|
116
|
+
}
|
|
117
|
+
// FILE field is omitted in serialization
|
|
118
|
+
// Add flags
|
|
119
|
+
if (track.flags && track.flags.length > 0) {
|
|
120
|
+
lines.push(`\t\t\tFLAGS ${track.flags.join(' ')}`);
|
|
121
|
+
}
|
|
122
|
+
// Add pregap
|
|
123
|
+
if (track.pregap) {
|
|
124
|
+
lines.push(`\t\t\tPREGAP ${formatCueTime(track.pregap)}`);
|
|
125
|
+
}
|
|
126
|
+
// Add indexes
|
|
127
|
+
if (track.indexes && track.indexes.length > 0) {
|
|
128
|
+
// Sort indexes by number
|
|
129
|
+
const sortedIndexes = [...track.indexes].sort((a, b) => a.number - b.number);
|
|
130
|
+
sortedIndexes.forEach(index => {
|
|
131
|
+
lines.push(`\t\t\tINDEX ${index.number.toString().padStart(2, '0')} ${formatCueTime(index.time)}`);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Add postgap
|
|
135
|
+
if (track.postgap) {
|
|
136
|
+
lines.push(`\t\t\tPOSTGAP ${formatCueTime(track.postgap)}`);
|
|
137
|
+
}
|
|
138
|
+
// Add track remarks
|
|
139
|
+
if (track.remarks && track.remarks.length > 0) {
|
|
140
|
+
track.remarks.forEach(remark => {
|
|
141
|
+
lines.push(`\t\t\tREM ${remark}`);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Serialize a track (legacy function for backward compatibility)
|
|
147
|
+
* @param track - Track information
|
|
148
|
+
* @param lines - Array to append lines to
|
|
149
|
+
*/
|
|
150
|
+
function serializeTrack(track, lines) {
|
|
151
|
+
// Use serializeTrackContent which now includes FILE inside the track
|
|
152
|
+
serializeTrackContent(track, lines);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Escape special characters in strings for CUE format
|
|
156
|
+
* @param str - String to escape
|
|
157
|
+
* @returns Escaped string
|
|
158
|
+
*/
|
|
159
|
+
function escapeString(str) {
|
|
160
|
+
// Escape double quotes by doubling them
|
|
161
|
+
return str.replace(/"/g, '""');
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Format a CueSheet with proper indentation and spacing
|
|
165
|
+
* @param cueSheet - The CueSheet to format
|
|
166
|
+
* @param options - Formatting options
|
|
167
|
+
* @returns Formatted CUE sheet string
|
|
168
|
+
*/
|
|
169
|
+
export function formatCueSheet(cueSheet, options = {}) {
|
|
170
|
+
const indent = options.indent || ' ';
|
|
171
|
+
const trackSpacing = options.trackSpacing ?? true;
|
|
172
|
+
const lines = [];
|
|
173
|
+
// Add global section
|
|
174
|
+
serializeGlobal(cueSheet.global, lines);
|
|
175
|
+
// Add empty line before tracks if there's global content
|
|
176
|
+
if (lines.length > 0 && trackSpacing) {
|
|
177
|
+
lines.push('');
|
|
178
|
+
}
|
|
179
|
+
// Add tracks with optional spacing
|
|
180
|
+
cueSheet.tracks.forEach((track, index) => {
|
|
181
|
+
if (index > 0 && trackSpacing) {
|
|
182
|
+
lines.push('');
|
|
183
|
+
}
|
|
184
|
+
const trackLines = [];
|
|
185
|
+
serializeTrackContent(track, trackLines);
|
|
186
|
+
// Apply custom indentation (always apply to ensure consistent formatting)
|
|
187
|
+
trackLines.forEach((line, lineIndex) => {
|
|
188
|
+
if (line.startsWith('\t\t\t')) {
|
|
189
|
+
trackLines[lineIndex] = line.replace(/^\t\t\t/, indent + indent + indent);
|
|
190
|
+
}
|
|
191
|
+
else if (line.startsWith('\t\t')) {
|
|
192
|
+
trackLines[lineIndex] = line.replace(/^\t\t/, indent + indent);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
lines.push(...trackLines);
|
|
196
|
+
});
|
|
197
|
+
return lines.join('\n') + '\n';
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Create a minimal CUE sheet with only essential information
|
|
201
|
+
* @param cueSheet - The CueSheet to minimize
|
|
202
|
+
* @returns Minimal CUE sheet string
|
|
203
|
+
*/
|
|
204
|
+
export function createMinimalCueSheet(cueSheet) {
|
|
205
|
+
const lines = [];
|
|
206
|
+
// Only include essential global fields
|
|
207
|
+
if (cueSheet.global.title) {
|
|
208
|
+
lines.push(`TITLE "${escapeString(cueSheet.global.title)}"`);
|
|
209
|
+
}
|
|
210
|
+
if (cueSheet.global.performer) {
|
|
211
|
+
lines.push(`PERFORMER "${escapeString(cueSheet.global.performer)}"`);
|
|
212
|
+
}
|
|
213
|
+
// Add global FILE in minimal version too
|
|
214
|
+
if (cueSheet.global.file) {
|
|
215
|
+
const formatStr = cueSheet.global.file.format ? ` ${cueSheet.global.file.format}` : '';
|
|
216
|
+
if (cueSheet.global.file.filename.includes(' ') || cueSheet.global.file.filename.includes('"')) {
|
|
217
|
+
lines.push(`FILE "${escapeString(cueSheet.global.file.filename)}"${formatStr}`);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
lines.push(`FILE ${cueSheet.global.file.filename}${formatStr}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Add tracks with minimal information
|
|
224
|
+
cueSheet.tracks.forEach(track => {
|
|
225
|
+
lines.push(`\t\tTRACK ${track.number.toString().padStart(2, '0')} ${track.mode}`);
|
|
226
|
+
if (track.title) {
|
|
227
|
+
lines.push(`\t\t\tTITLE "${escapeString(track.title)}"`);
|
|
228
|
+
}
|
|
229
|
+
// FILE field is omitted in minimal serialization
|
|
230
|
+
// Only include INDEX 01 (main index)
|
|
231
|
+
if (track.indexes) {
|
|
232
|
+
const mainIndex = track.indexes.find(idx => idx.number === 1);
|
|
233
|
+
if (mainIndex) {
|
|
234
|
+
lines.push(`\t\t\tINDEX 01 ${formatCueTime(mainIndex.time)}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
return lines.join('\n') + '\n';
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../src/serializer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;GAEG;AAEH;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAkB;IAClD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,qBAAqB;IACrB,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAExC,0CAA0C;IAC1C,wBAAwB,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEjD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC,CAAA;;;;GAIE;AACH,SAAS,eAAe,CAAC,MAAiB,EAAE,KAAe;IACzD,oBAAoB;IACpB,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YAC9B,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,cAAc;IACd,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,mBAAmB;IACnB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;IAClD,CAAC;IAED,kBAAkB;IAClB,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7E,KAAK,CAAC,IAAI,CAAC,SAAS,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,SAAS,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,UAAU,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,cAAc,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,eAAe,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,aAAa,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,aAAa,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,UAAU,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,wBAAwB,CAAC,MAAe,EAAE,KAAe;IAChE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACrB,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,KAAY,EAAE,KAAe;IAC1D,iBAAiB;IACjB,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAElF,0BAA0B;IAC1B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,gBAAgB,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,oBAAoB,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,qBAAqB,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,mBAAmB,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,mBAAmB,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,kBAAkB,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IAED,WAAW;IACX,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,yCAAyC;IAEzC,YAAY;IACZ,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,aAAa;IACb,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,gBAAgB,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,cAAc;IACd,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,yBAAyB;QACzB,MAAM,aAAa,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;QAC7E,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC5B,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrG,CAAC,CAAC,CAAC;IACL,CAAC;IAED,cAAc;IACd,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,iBAAiB,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,oBAAoB;IACpB,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YAC7B,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,KAAY,EAAE,KAAe;IACnD,qEAAqE;IACrE,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,wCAAwC;IACxC,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAkB,EAAE,UAG/C,EAAE;IACJ,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;IACrC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC;IAElD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,qBAAqB;IACrB,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAExC,yDAAyD;IACzD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,mCAAmC;IACnC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACvC,IAAI,KAAK,GAAG,CAAC,IAAI,YAAY,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,qBAAqB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAEzC,0EAA0E;QAC1E,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE;YACrC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC;YAC5E,CAAC;iBAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnC,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;YACjE,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAkB;IACtD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,uCAAuC;IACvC,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,UAAU,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,cAAc,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACvE,CAAC;IAED,yCAAyC;IACzC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/F,KAAK,CAAC,IAAI,CAAC,SAAS,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,QAAQ,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,SAAS,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAC9B,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAElF,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,gBAAgB,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3D,CAAC;QAED,iDAAiD;QAEjD,qCAAqC;QACrC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;YAC9D,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,CAAC,IAAI,CAAC,kBAAkB,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CUE Sheet file format type definitions
|
|
3
|
+
*/
|
|
4
|
+
/** Time format representation (Hours:Minutes:Seconds) */
|
|
5
|
+
export interface HMSTime {
|
|
6
|
+
hour: number;
|
|
7
|
+
minute: number;
|
|
8
|
+
second: number;
|
|
9
|
+
}
|
|
10
|
+
/** Track flags */
|
|
11
|
+
export type TrackFlag = 'PRE' | 'DCP' | '4CH' | 'SCMS';
|
|
12
|
+
/** Track modes */
|
|
13
|
+
export type TrackMode = 'AUDIO' | 'CDG' | 'MODE1/2048' | 'MODE1/2352' | 'MODE2/2336' | 'MODE2/2352' | 'CDI/2336' | 'CDI/2352';
|
|
14
|
+
/** File formats */
|
|
15
|
+
export type FileFormat = 'BINARY' | 'MOTOROLA' | 'AIFF' | 'WAVE' | 'MP3';
|
|
16
|
+
/** CD-TEXT field types */
|
|
17
|
+
export interface CDText {
|
|
18
|
+
TITLE?: string;
|
|
19
|
+
PERFORMER?: string;
|
|
20
|
+
SONGWRITER?: string;
|
|
21
|
+
COMPOSER?: string;
|
|
22
|
+
ARRANGER?: string;
|
|
23
|
+
MESSAGE?: string;
|
|
24
|
+
DISC_ID?: string;
|
|
25
|
+
GENRE?: string;
|
|
26
|
+
TOC_INFO?: string;
|
|
27
|
+
TOC_INFO2?: string;
|
|
28
|
+
UPC_EAN?: string;
|
|
29
|
+
SIZE_INFO?: string;
|
|
30
|
+
ISRC?: string;
|
|
31
|
+
}
|
|
32
|
+
/** Track index definition */
|
|
33
|
+
export interface TrackIndex {
|
|
34
|
+
number: number;
|
|
35
|
+
time: HMSTime;
|
|
36
|
+
}
|
|
37
|
+
/** File definition */
|
|
38
|
+
export interface FileInfo {
|
|
39
|
+
filename: string;
|
|
40
|
+
format?: FileFormat;
|
|
41
|
+
}
|
|
42
|
+
/** Track definition */
|
|
43
|
+
export interface Track {
|
|
44
|
+
number: number;
|
|
45
|
+
mode: TrackMode;
|
|
46
|
+
file?: FileInfo;
|
|
47
|
+
title?: string;
|
|
48
|
+
performer?: string;
|
|
49
|
+
songwriter?: string;
|
|
50
|
+
composer?: string;
|
|
51
|
+
arranger?: string;
|
|
52
|
+
message?: string;
|
|
53
|
+
isrc?: string;
|
|
54
|
+
flags?: TrackFlag[];
|
|
55
|
+
indexes?: TrackIndex[];
|
|
56
|
+
pregap?: HMSTime;
|
|
57
|
+
postgap?: HMSTime;
|
|
58
|
+
cdtext?: CDText;
|
|
59
|
+
remarks?: string[];
|
|
60
|
+
}
|
|
61
|
+
/** Global CUE Sheet information */
|
|
62
|
+
export interface CueGlobal {
|
|
63
|
+
catalog?: string;
|
|
64
|
+
cdTextFile?: string;
|
|
65
|
+
file?: FileInfo;
|
|
66
|
+
title?: string;
|
|
67
|
+
performer?: string;
|
|
68
|
+
songwriter?: string;
|
|
69
|
+
composer?: string;
|
|
70
|
+
arranger?: string;
|
|
71
|
+
message?: string;
|
|
72
|
+
discId?: string;
|
|
73
|
+
genre?: string;
|
|
74
|
+
upcEan?: string;
|
|
75
|
+
cdtext?: CDText;
|
|
76
|
+
remarks?: string[];
|
|
77
|
+
}
|
|
78
|
+
/** Complete CUE Sheet representation */
|
|
79
|
+
export interface CueSheet {
|
|
80
|
+
global: CueGlobal;
|
|
81
|
+
tracks: Track[];
|
|
82
|
+
}
|
|
83
|
+
/** Parse error with line information */
|
|
84
|
+
export interface ParseError {
|
|
85
|
+
line: number;
|
|
86
|
+
message: string;
|
|
87
|
+
rawLine: string;
|
|
88
|
+
}
|
|
89
|
+
/** Parse result */
|
|
90
|
+
export interface ParseResult {
|
|
91
|
+
cueSheet?: CueSheet;
|
|
92
|
+
errors: ParseError[];
|
|
93
|
+
warnings: ParseError[];
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { HMSTime } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* HMS (Hours:Minutes:Seconds) time format utilities
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Parse HH:MM:SS time string format into HMSTime object
|
|
7
|
+
* @param timeString - Time string in format "h:m:s" (e.g., "1:30:45")
|
|
8
|
+
* @returns Parsed HMSTime object
|
|
9
|
+
* @throws Error if format is invalid
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseHMSTime(timeString: string): HMSTime;
|
|
12
|
+
/**
|
|
13
|
+
* Convert HMSTime object to string format "h:m:s"
|
|
14
|
+
* @param time - HMSTime object
|
|
15
|
+
* @param zeroPad - Whether to zero-pad values (default: true)
|
|
16
|
+
* @returns Formatted time string
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatHMSTime(time: HMSTime, zeroPad?: boolean): string;
|
|
19
|
+
/**
|
|
20
|
+
* Convert HMSTime object to CUE format string "MM:SS:FF"
|
|
21
|
+
* In CUE format, we treat our HMSTime as Minutes:Seconds:Frames for compatibility
|
|
22
|
+
* @param time - HMSTime object
|
|
23
|
+
* @returns CUE format time string (MM:SS:FF)
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatCueTime(time: HMSTime): string;
|
|
26
|
+
/**
|
|
27
|
+
* Convert HMSTime to total seconds
|
|
28
|
+
* @param time - HMSTime object
|
|
29
|
+
* @returns Total time in seconds
|
|
30
|
+
*/
|
|
31
|
+
export declare function hmsToSeconds(time: HMSTime): number;
|
|
32
|
+
/**
|
|
33
|
+
* Convert seconds to HMSTime
|
|
34
|
+
* @param seconds - Time in seconds
|
|
35
|
+
* @returns HMSTime object
|
|
36
|
+
*/
|
|
37
|
+
export declare function secondsToHMS(seconds: number): HMSTime;
|
|
38
|
+
/**
|
|
39
|
+
* Convert HMSTime to total seconds (alias for hmsToSeconds)
|
|
40
|
+
* @param time - HMSTime object
|
|
41
|
+
* @returns Total seconds
|
|
42
|
+
*/
|
|
43
|
+
export declare function msfToFrames(time: HMSTime): number;
|
|
44
|
+
/**
|
|
45
|
+
* Convert total seconds to HMSTime (alias for secondsToHMS)
|
|
46
|
+
* @param totalSeconds - Total seconds
|
|
47
|
+
* @returns HMSTime object
|
|
48
|
+
*/
|
|
49
|
+
export declare function framesToMSF(totalSeconds: number): HMSTime;
|
|
50
|
+
/**
|
|
51
|
+
* Add two HMSTime objects
|
|
52
|
+
* @param time1 - First time
|
|
53
|
+
* @param time2 - Second time
|
|
54
|
+
* @returns Sum of the two times
|
|
55
|
+
*/
|
|
56
|
+
export declare function addHMSTime(time1: HMSTime, time2: HMSTime): HMSTime;
|
|
57
|
+
/**
|
|
58
|
+
* Subtract time2 from time1
|
|
59
|
+
* @param time1 - First time (minuend)
|
|
60
|
+
* @param time2 - Second time (subtrahend)
|
|
61
|
+
* @returns Difference (time1 - time2)
|
|
62
|
+
* @throws Error if result would be negative
|
|
63
|
+
*/
|
|
64
|
+
export declare function subtractHMSTime(time1: HMSTime, time2: HMSTime): HMSTime;
|
|
65
|
+
/**
|
|
66
|
+
* Compare two HMSTime objects
|
|
67
|
+
* @param time1 - First time
|
|
68
|
+
* @param time2 - Second time
|
|
69
|
+
* @returns -1 if time1 < time2, 0 if equal, 1 if time1 > time2
|
|
70
|
+
*/
|
|
71
|
+
export declare function compareHMSTime(time1: HMSTime, time2: HMSTime): -1 | 0 | 1;
|
|
72
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;GAEG;AAEH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAmCxD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,OAAc,GAAG,MAAM,CAM5E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAMnD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAElD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAIlE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CASvE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAOzE"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMS (Hours:Minutes:Seconds) time format utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Parse HH:MM:SS time string format into HMSTime object
|
|
6
|
+
* @param timeString - Time string in format "h:m:s" (e.g., "1:30:45")
|
|
7
|
+
* @returns Parsed HMSTime object
|
|
8
|
+
* @throws Error if format is invalid
|
|
9
|
+
*/
|
|
10
|
+
export function parseHMSTime(timeString) {
|
|
11
|
+
const trimmed = timeString.trim();
|
|
12
|
+
const parts = trimmed.split(':');
|
|
13
|
+
if (parts.length !== 3) {
|
|
14
|
+
throw new Error(`Invalid time format: "${timeString}". Expected format: "h:m:s"`);
|
|
15
|
+
}
|
|
16
|
+
const [hoursStr, minutesStr, secondsStr] = parts;
|
|
17
|
+
if (!hoursStr || !minutesStr || !secondsStr) {
|
|
18
|
+
throw new Error(`Invalid time format: "${timeString}". Missing time components.`);
|
|
19
|
+
}
|
|
20
|
+
const hours = parseInt(hoursStr, 10);
|
|
21
|
+
const minutes = parseInt(minutesStr, 10);
|
|
22
|
+
const seconds = parseInt(secondsStr, 10);
|
|
23
|
+
if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) {
|
|
24
|
+
throw new Error(`Invalid time format: "${timeString}". All parts must be numbers.`);
|
|
25
|
+
}
|
|
26
|
+
if (hours < 0 || minutes < 0 || seconds < 0) {
|
|
27
|
+
throw new Error(`Invalid time format: "${timeString}". All parts must be non-negative.`);
|
|
28
|
+
}
|
|
29
|
+
if (minutes >= 60) {
|
|
30
|
+
throw new Error(`Invalid time format: "${timeString}". Minutes must be less than 60.`);
|
|
31
|
+
}
|
|
32
|
+
if (seconds >= 60) {
|
|
33
|
+
throw new Error(`Invalid time format: "${timeString}". Seconds must be less than 60.`);
|
|
34
|
+
}
|
|
35
|
+
return { hour: hours, minute: minutes, second: seconds };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Convert HMSTime object to string format "h:m:s"
|
|
39
|
+
* @param time - HMSTime object
|
|
40
|
+
* @param zeroPad - Whether to zero-pad values (default: true)
|
|
41
|
+
* @returns Formatted time string
|
|
42
|
+
*/
|
|
43
|
+
export function formatHMSTime(time, zeroPad = true) {
|
|
44
|
+
if (zeroPad) {
|
|
45
|
+
return `${time.hour.toString().padStart(2, '0')}:${time.minute.toString().padStart(2, '0')}:${time.second.toString().padStart(2, '0')}`;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return `${time.hour}:${time.minute}:${time.second}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Convert HMSTime object to CUE format string "MM:SS:FF"
|
|
53
|
+
* In CUE format, we treat our HMSTime as Minutes:Seconds:Frames for compatibility
|
|
54
|
+
* @param time - HMSTime object
|
|
55
|
+
* @returns CUE format time string (MM:SS:FF)
|
|
56
|
+
*/
|
|
57
|
+
export function formatCueTime(time) {
|
|
58
|
+
// For CUE format, map hour->minutes, minute->seconds, second->frames
|
|
59
|
+
const minutes = time.hour * 60 + time.minute;
|
|
60
|
+
const seconds = time.second;
|
|
61
|
+
const frames = 0;
|
|
62
|
+
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}:${frames.toString().padStart(2, '0')}`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Convert HMSTime to total seconds
|
|
66
|
+
* @param time - HMSTime object
|
|
67
|
+
* @returns Total time in seconds
|
|
68
|
+
*/
|
|
69
|
+
export function hmsToSeconds(time) {
|
|
70
|
+
return time.hour * 3600 + time.minute * 60 + time.second;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Convert seconds to HMSTime
|
|
74
|
+
* @param seconds - Time in seconds
|
|
75
|
+
* @returns HMSTime object
|
|
76
|
+
*/
|
|
77
|
+
export function secondsToHMS(seconds) {
|
|
78
|
+
const totalSeconds = Math.floor(seconds);
|
|
79
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
80
|
+
const remainingSeconds = totalSeconds % 3600;
|
|
81
|
+
const mins = Math.floor(remainingSeconds / 60);
|
|
82
|
+
const secs = remainingSeconds % 60;
|
|
83
|
+
return { hour: hours, minute: mins, second: secs };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Convert HMSTime to total seconds (alias for hmsToSeconds)
|
|
87
|
+
* @param time - HMSTime object
|
|
88
|
+
* @returns Total seconds
|
|
89
|
+
*/
|
|
90
|
+
export function msfToFrames(time) {
|
|
91
|
+
return hmsToSeconds(time);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Convert total seconds to HMSTime (alias for secondsToHMS)
|
|
95
|
+
* @param totalSeconds - Total seconds
|
|
96
|
+
* @returns HMSTime object
|
|
97
|
+
*/
|
|
98
|
+
export function framesToMSF(totalSeconds) {
|
|
99
|
+
return secondsToHMS(totalSeconds);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Add two HMSTime objects
|
|
103
|
+
* @param time1 - First time
|
|
104
|
+
* @param time2 - Second time
|
|
105
|
+
* @returns Sum of the two times
|
|
106
|
+
*/
|
|
107
|
+
export function addHMSTime(time1, time2) {
|
|
108
|
+
const seconds1 = hmsToSeconds(time1);
|
|
109
|
+
const seconds2 = hmsToSeconds(time2);
|
|
110
|
+
return secondsToHMS(seconds1 + seconds2);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Subtract time2 from time1
|
|
114
|
+
* @param time1 - First time (minuend)
|
|
115
|
+
* @param time2 - Second time (subtrahend)
|
|
116
|
+
* @returns Difference (time1 - time2)
|
|
117
|
+
* @throws Error if result would be negative
|
|
118
|
+
*/
|
|
119
|
+
export function subtractHMSTime(time1, time2) {
|
|
120
|
+
const seconds1 = hmsToSeconds(time1);
|
|
121
|
+
const seconds2 = hmsToSeconds(time2);
|
|
122
|
+
if (seconds1 < seconds2) {
|
|
123
|
+
throw new Error('Cannot subtract: result would be negative');
|
|
124
|
+
}
|
|
125
|
+
return secondsToHMS(seconds1 - seconds2);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Compare two HMSTime objects
|
|
129
|
+
* @param time1 - First time
|
|
130
|
+
* @param time2 - Second time
|
|
131
|
+
* @returns -1 if time1 < time2, 0 if equal, 1 if time1 > time2
|
|
132
|
+
*/
|
|
133
|
+
export function compareHMSTime(time1, time2) {
|
|
134
|
+
const seconds1 = hmsToSeconds(time1);
|
|
135
|
+
const seconds2 = hmsToSeconds(time2);
|
|
136
|
+
if (seconds1 < seconds2)
|
|
137
|
+
return -1;
|
|
138
|
+
if (seconds1 > seconds2)
|
|
139
|
+
return 1;
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CueSheet } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* YouTube timeline serializer for CUE sheets
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Serialize CUE sheet to YouTube timeline format
|
|
7
|
+
* @param cueSheet - Parsed CUE sheet object
|
|
8
|
+
* @returns YouTube timeline string
|
|
9
|
+
*/
|
|
10
|
+
export declare function serializeYouTubeTimeline(cueSheet: CueSheet): string;
|
|
11
|
+
//# sourceMappingURL=youtube-serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube-serializer.d.ts","sourceRoot":"","sources":["../../src/youtube-serializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAmCnE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YouTube timeline serializer for CUE sheets
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Serialize CUE sheet to YouTube timeline format
|
|
6
|
+
* @param cueSheet - Parsed CUE sheet object
|
|
7
|
+
* @returns YouTube timeline string
|
|
8
|
+
*/
|
|
9
|
+
export function serializeYouTubeTimeline(cueSheet) {
|
|
10
|
+
const lines = [];
|
|
11
|
+
// Add header
|
|
12
|
+
lines.push('🎵 Tracklist :');
|
|
13
|
+
lines.push('Generated by melocilde/cue-parser (https://melocil.de/cue-parser/)');
|
|
14
|
+
// Add each track
|
|
15
|
+
cueSheet.tracks.forEach((track) => {
|
|
16
|
+
const performer = track.performer || '';
|
|
17
|
+
const title = track.title || 'Untitled';
|
|
18
|
+
// Get the main index time (usually INDEX 01)
|
|
19
|
+
let timeStr = '00:00:00';
|
|
20
|
+
if (track.indexes && track.indexes.length > 0) {
|
|
21
|
+
// Find INDEX 01, or use the last index if INDEX 01 doesn't exist
|
|
22
|
+
const mainIndex = track.indexes.find(idx => idx.number === 1) || track.indexes[track.indexes.length - 1];
|
|
23
|
+
if (mainIndex && mainIndex.time) {
|
|
24
|
+
// For YouTube timeline, use HH:MM:SS format
|
|
25
|
+
const hours = mainIndex.time.hour;
|
|
26
|
+
const minutes = mainIndex.time.minute;
|
|
27
|
+
const seconds = mainIndex.time.second;
|
|
28
|
+
timeStr = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (performer.trim() === '') {
|
|
32
|
+
lines.push(`${timeStr} ${title}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
lines.push(`${timeStr} ${performer} - ${title}`);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return lines.join('\n');
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=youtube-serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube-serializer.js","sourceRoot":"","sources":["../../src/youtube-serializer.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAkB;IACzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,aAAa;IACb,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IAEjF,iBAAiB;IACjB,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAChC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC;QAExC,6CAA6C;QAC7C,IAAI,OAAO,GAAG,UAAU,CAAC;QACzB,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,iEAAiE;YACjE,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACzG,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;gBAChC,4CAA4C;gBAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;gBAClC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;gBACtC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;gBAEtC,OAAO,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YACjI,CAAC;QACH,CAAC;QAED,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,IAAI,SAAS,MAAM,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|