@storyteller-platform/audiobook 0.1.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.txt +21 -0
- package/README.md +2217 -0
- package/dist/base.cjs +248 -0
- package/dist/base.d.cts +67 -0
- package/dist/base.d.ts +67 -0
- package/dist/base.js +223 -0
- package/dist/entry.cjs +57 -0
- package/dist/entry.d.cts +19 -0
- package/dist/entry.d.ts +19 -0
- package/dist/entry.js +33 -0
- package/dist/index.cjs +69 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +45 -0
- package/dist/node/entry.cjs +76 -0
- package/dist/node/entry.d.cts +18 -0
- package/dist/node/entry.d.ts +18 -0
- package/dist/node/entry.js +52 -0
- package/dist/node/index.cjs +107 -0
- package/dist/node/index.d.cts +17 -0
- package/dist/node/index.d.ts +17 -0
- package/dist/node/index.js +89 -0
- package/dist/taglib/Uint8ArrayFileAbstraction.cjs +128 -0
- package/dist/taglib/Uint8ArrayFileAbstraction.d.cts +26 -0
- package/dist/taglib/Uint8ArrayFileAbstraction.d.ts +26 -0
- package/dist/taglib/Uint8ArrayFileAbstraction.js +106 -0
- package/package.json +75 -0
package/dist/entry.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Uint8ArrayWriter } from "@zip.js/zip.js";
|
|
2
|
+
import { File } from "node-taglib-sharp";
|
|
3
|
+
import { BaseAudiobookEntry } from "./base.js";
|
|
4
|
+
import { Uint8ArrayFileAbstraction } from "./taglib/Uint8ArrayFileAbstraction.js";
|
|
5
|
+
class AudiobookEntry extends BaseAudiobookEntry {
|
|
6
|
+
constructor(entry) {
|
|
7
|
+
super();
|
|
8
|
+
this.entry = entry;
|
|
9
|
+
this.filename = entry.filename;
|
|
10
|
+
}
|
|
11
|
+
filename;
|
|
12
|
+
file = null;
|
|
13
|
+
async readData() {
|
|
14
|
+
if ("data" in this.entry) {
|
|
15
|
+
return this.entry.data;
|
|
16
|
+
}
|
|
17
|
+
const writer = new Uint8ArrayWriter();
|
|
18
|
+
return await this.entry.getData(writer);
|
|
19
|
+
}
|
|
20
|
+
async getData() {
|
|
21
|
+
const file = await this.getFile();
|
|
22
|
+
return file.fileAbstraction.data;
|
|
23
|
+
}
|
|
24
|
+
async createFile() {
|
|
25
|
+
const data = await this.readData();
|
|
26
|
+
return File.createFromAbstraction(
|
|
27
|
+
new Uint8ArrayFileAbstraction(this.filename, data)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
AudiobookEntry
|
|
33
|
+
};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var index_exports = {};
|
|
20
|
+
__export(index_exports, {
|
|
21
|
+
Audiobook: () => Audiobook
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(index_exports);
|
|
24
|
+
var import_zip = require("@zip.js/zip.js");
|
|
25
|
+
var import_path = require("@storyteller-platform/path");
|
|
26
|
+
var import_base = require("./base.cjs");
|
|
27
|
+
var import_entry = require("./entry.cjs");
|
|
28
|
+
class Audiobook extends import_base.BaseAudiobook {
|
|
29
|
+
constructor(entries) {
|
|
30
|
+
super();
|
|
31
|
+
this.entries = entries;
|
|
32
|
+
}
|
|
33
|
+
static async from(pathOrPathsOrData) {
|
|
34
|
+
if (!Array.isArray(pathOrPathsOrData)) {
|
|
35
|
+
const ext = (0, import_path.extname)(pathOrPathsOrData.filename);
|
|
36
|
+
if (ext === ".zip") {
|
|
37
|
+
const dataReader = new import_zip.Uint8ArrayReader(pathOrPathsOrData.data);
|
|
38
|
+
const zipReader = new import_zip.ZipReader(dataReader);
|
|
39
|
+
const zipEntries = await zipReader.getEntries();
|
|
40
|
+
const entries = zipEntries.map((entry) => new import_entry.AudiobookEntry(entry));
|
|
41
|
+
return new Audiobook(entries);
|
|
42
|
+
}
|
|
43
|
+
return new Audiobook([new import_entry.AudiobookEntry(pathOrPathsOrData)]);
|
|
44
|
+
}
|
|
45
|
+
return new Audiobook(
|
|
46
|
+
pathOrPathsOrData.map((path) => new import_entry.AudiobookEntry(path))
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
static create(metadata) {
|
|
50
|
+
const audiobook = new Audiobook([]);
|
|
51
|
+
audiobook.metadata = metadata;
|
|
52
|
+
return audiobook;
|
|
53
|
+
}
|
|
54
|
+
async save() {
|
|
55
|
+
for (const entry of this.entries) {
|
|
56
|
+
entry.save();
|
|
57
|
+
}
|
|
58
|
+
return await Promise.all(
|
|
59
|
+
this.entries.map(async (entry) => ({
|
|
60
|
+
filename: entry.filename,
|
|
61
|
+
data: await entry.getData()
|
|
62
|
+
}))
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
67
|
+
0 && (module.exports = {
|
|
68
|
+
Audiobook
|
|
69
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseAudiobook, AudiobookMetadata } from './base.cjs';
|
|
2
|
+
import { AudiobookEntry, Uint8ArrayEntry } from './entry.cjs';
|
|
3
|
+
import 'node-taglib-sharp';
|
|
4
|
+
import '@zip.js/zip.js';
|
|
5
|
+
|
|
6
|
+
declare class Audiobook extends BaseAudiobook {
|
|
7
|
+
protected entries: AudiobookEntry[];
|
|
8
|
+
protected constructor(entries: AudiobookEntry[]);
|
|
9
|
+
static from(pathOrPathsOrData: Uint8ArrayEntry | Uint8ArrayEntry[]): Promise<Audiobook>;
|
|
10
|
+
static create(metadata: AudiobookMetadata): Audiobook;
|
|
11
|
+
save(): Promise<Uint8ArrayEntry[]>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { Audiobook };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseAudiobook, AudiobookMetadata } from './base.js';
|
|
2
|
+
import { AudiobookEntry, Uint8ArrayEntry } from './entry.js';
|
|
3
|
+
import 'node-taglib-sharp';
|
|
4
|
+
import '@zip.js/zip.js';
|
|
5
|
+
|
|
6
|
+
declare class Audiobook extends BaseAudiobook {
|
|
7
|
+
protected entries: AudiobookEntry[];
|
|
8
|
+
protected constructor(entries: AudiobookEntry[]);
|
|
9
|
+
static from(pathOrPathsOrData: Uint8ArrayEntry | Uint8ArrayEntry[]): Promise<Audiobook>;
|
|
10
|
+
static create(metadata: AudiobookMetadata): Audiobook;
|
|
11
|
+
save(): Promise<Uint8ArrayEntry[]>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { Audiobook };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Uint8ArrayReader, ZipReader } from "@zip.js/zip.js";
|
|
2
|
+
import { extname } from "@storyteller-platform/path";
|
|
3
|
+
import { BaseAudiobook } from "./base.js";
|
|
4
|
+
import { AudiobookEntry } from "./entry.js";
|
|
5
|
+
class Audiobook extends BaseAudiobook {
|
|
6
|
+
constructor(entries) {
|
|
7
|
+
super();
|
|
8
|
+
this.entries = entries;
|
|
9
|
+
}
|
|
10
|
+
static async from(pathOrPathsOrData) {
|
|
11
|
+
if (!Array.isArray(pathOrPathsOrData)) {
|
|
12
|
+
const ext = extname(pathOrPathsOrData.filename);
|
|
13
|
+
if (ext === ".zip") {
|
|
14
|
+
const dataReader = new Uint8ArrayReader(pathOrPathsOrData.data);
|
|
15
|
+
const zipReader = new ZipReader(dataReader);
|
|
16
|
+
const zipEntries = await zipReader.getEntries();
|
|
17
|
+
const entries = zipEntries.map((entry) => new AudiobookEntry(entry));
|
|
18
|
+
return new Audiobook(entries);
|
|
19
|
+
}
|
|
20
|
+
return new Audiobook([new AudiobookEntry(pathOrPathsOrData)]);
|
|
21
|
+
}
|
|
22
|
+
return new Audiobook(
|
|
23
|
+
pathOrPathsOrData.map((path) => new AudiobookEntry(path))
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
static create(metadata) {
|
|
27
|
+
const audiobook = new Audiobook([]);
|
|
28
|
+
audiobook.metadata = metadata;
|
|
29
|
+
return audiobook;
|
|
30
|
+
}
|
|
31
|
+
async save() {
|
|
32
|
+
for (const entry of this.entries) {
|
|
33
|
+
entry.save();
|
|
34
|
+
}
|
|
35
|
+
return await Promise.all(
|
|
36
|
+
this.entries.map(async (entry) => ({
|
|
37
|
+
filename: entry.filename,
|
|
38
|
+
data: await entry.getData()
|
|
39
|
+
}))
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
Audiobook
|
|
45
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var entry_exports = {};
|
|
20
|
+
__export(entry_exports, {
|
|
21
|
+
AudiobookEntry: () => AudiobookEntry
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(entry_exports);
|
|
24
|
+
var import_promises = require("node:fs/promises");
|
|
25
|
+
var import_zip = require("@zip.js/zip.js");
|
|
26
|
+
var import_node_taglib_sharp = require("node-taglib-sharp");
|
|
27
|
+
var import_fs = require("@storyteller-platform/fs");
|
|
28
|
+
var import_base = require("../base.cjs");
|
|
29
|
+
var import_Uint8ArrayFileAbstraction = require("../taglib/Uint8ArrayFileAbstraction.cjs");
|
|
30
|
+
class AudiobookEntry extends import_base.BaseAudiobookEntry {
|
|
31
|
+
constructor(entry) {
|
|
32
|
+
super();
|
|
33
|
+
this.entry = entry;
|
|
34
|
+
this.filename = typeof entry === "string" ? entry : entry.filename;
|
|
35
|
+
}
|
|
36
|
+
filename;
|
|
37
|
+
file = null;
|
|
38
|
+
async createFile() {
|
|
39
|
+
if (typeof this.entry === "string") {
|
|
40
|
+
const file = import_node_taglib_sharp.File.createFromPath(this.entry);
|
|
41
|
+
return file;
|
|
42
|
+
}
|
|
43
|
+
const data = await this.readData();
|
|
44
|
+
return import_node_taglib_sharp.File.createFromAbstraction(
|
|
45
|
+
new import_Uint8ArrayFileAbstraction.Uint8ArrayFileAbstraction(this.filename, data)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
async getData() {
|
|
49
|
+
if (typeof this.entry === "string") {
|
|
50
|
+
return await (0, import_promises.readFile)(this.entry);
|
|
51
|
+
}
|
|
52
|
+
const file = await this.getFile();
|
|
53
|
+
return file.fileAbstraction.data;
|
|
54
|
+
}
|
|
55
|
+
async readData() {
|
|
56
|
+
if (typeof this.entry === "string") {
|
|
57
|
+
return await (0, import_fs.streamFile)(this.entry);
|
|
58
|
+
}
|
|
59
|
+
if ("data" in this.entry) {
|
|
60
|
+
return this.entry.data;
|
|
61
|
+
}
|
|
62
|
+
const writer = new import_zip.Uint8ArrayWriter();
|
|
63
|
+
return await this.entry.getData(writer);
|
|
64
|
+
}
|
|
65
|
+
persisted() {
|
|
66
|
+
return typeof this.entry === "string";
|
|
67
|
+
}
|
|
68
|
+
close() {
|
|
69
|
+
var _a;
|
|
70
|
+
(_a = this.file) == null ? void 0 : _a.dispose();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
74
|
+
0 && (module.exports = {
|
|
75
|
+
AudiobookEntry
|
|
76
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Entry } from '@zip.js/zip.js';
|
|
2
|
+
import { File } from 'node-taglib-sharp';
|
|
3
|
+
import { BaseAudiobookEntry } from '../base.cjs';
|
|
4
|
+
import { Uint8ArrayEntry } from '../entry.cjs';
|
|
5
|
+
|
|
6
|
+
declare class AudiobookEntry extends BaseAudiobookEntry {
|
|
7
|
+
protected entry: string | Uint8ArrayEntry | Entry;
|
|
8
|
+
filename: string;
|
|
9
|
+
protected file: File | null;
|
|
10
|
+
constructor(entry: string | Uint8ArrayEntry | Entry);
|
|
11
|
+
createFile(): Promise<File>;
|
|
12
|
+
getData(): Promise<Uint8Array>;
|
|
13
|
+
protected readData(): Promise<Uint8Array>;
|
|
14
|
+
persisted(): boolean;
|
|
15
|
+
close(): void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { AudiobookEntry };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Entry } from '@zip.js/zip.js';
|
|
2
|
+
import { File } from 'node-taglib-sharp';
|
|
3
|
+
import { BaseAudiobookEntry } from '../base.js';
|
|
4
|
+
import { Uint8ArrayEntry } from '../entry.js';
|
|
5
|
+
|
|
6
|
+
declare class AudiobookEntry extends BaseAudiobookEntry {
|
|
7
|
+
protected entry: string | Uint8ArrayEntry | Entry;
|
|
8
|
+
filename: string;
|
|
9
|
+
protected file: File | null;
|
|
10
|
+
constructor(entry: string | Uint8ArrayEntry | Entry);
|
|
11
|
+
createFile(): Promise<File>;
|
|
12
|
+
getData(): Promise<Uint8Array>;
|
|
13
|
+
protected readData(): Promise<Uint8Array>;
|
|
14
|
+
persisted(): boolean;
|
|
15
|
+
close(): void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { AudiobookEntry };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { Uint8ArrayWriter } from "@zip.js/zip.js";
|
|
3
|
+
import { File } from "node-taglib-sharp";
|
|
4
|
+
import { streamFile } from "@storyteller-platform/fs";
|
|
5
|
+
import { BaseAudiobookEntry } from "../base.js";
|
|
6
|
+
import { Uint8ArrayFileAbstraction } from "../taglib/Uint8ArrayFileAbstraction.js";
|
|
7
|
+
class AudiobookEntry extends BaseAudiobookEntry {
|
|
8
|
+
constructor(entry) {
|
|
9
|
+
super();
|
|
10
|
+
this.entry = entry;
|
|
11
|
+
this.filename = typeof entry === "string" ? entry : entry.filename;
|
|
12
|
+
}
|
|
13
|
+
filename;
|
|
14
|
+
file = null;
|
|
15
|
+
async createFile() {
|
|
16
|
+
if (typeof this.entry === "string") {
|
|
17
|
+
const file = File.createFromPath(this.entry);
|
|
18
|
+
return file;
|
|
19
|
+
}
|
|
20
|
+
const data = await this.readData();
|
|
21
|
+
return File.createFromAbstraction(
|
|
22
|
+
new Uint8ArrayFileAbstraction(this.filename, data)
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
async getData() {
|
|
26
|
+
if (typeof this.entry === "string") {
|
|
27
|
+
return await readFile(this.entry);
|
|
28
|
+
}
|
|
29
|
+
const file = await this.getFile();
|
|
30
|
+
return file.fileAbstraction.data;
|
|
31
|
+
}
|
|
32
|
+
async readData() {
|
|
33
|
+
if (typeof this.entry === "string") {
|
|
34
|
+
return await streamFile(this.entry);
|
|
35
|
+
}
|
|
36
|
+
if ("data" in this.entry) {
|
|
37
|
+
return this.entry.data;
|
|
38
|
+
}
|
|
39
|
+
const writer = new Uint8ArrayWriter();
|
|
40
|
+
return await this.entry.getData(writer);
|
|
41
|
+
}
|
|
42
|
+
persisted() {
|
|
43
|
+
return typeof this.entry === "string";
|
|
44
|
+
}
|
|
45
|
+
close() {
|
|
46
|
+
var _a;
|
|
47
|
+
(_a = this.file) == null ? void 0 : _a.dispose();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
AudiobookEntry
|
|
52
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var node_exports = {};
|
|
20
|
+
__export(node_exports, {
|
|
21
|
+
Audiobook: () => Audiobook
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(node_exports);
|
|
24
|
+
var import_promises = require("node:fs/promises");
|
|
25
|
+
var import_zip = require("@zip.js/zip.js");
|
|
26
|
+
var import_node_taglib_sharp = require("node-taglib-sharp");
|
|
27
|
+
var import_fs = require("@storyteller-platform/fs");
|
|
28
|
+
var import_path = require("@storyteller-platform/path");
|
|
29
|
+
var import_base = require("../base.cjs");
|
|
30
|
+
var import_entry2 = require("./entry.cjs");
|
|
31
|
+
class Audiobook extends import_base.BaseAudiobook {
|
|
32
|
+
constructor(entries, zipPath) {
|
|
33
|
+
super();
|
|
34
|
+
this.entries = entries;
|
|
35
|
+
this.zipPath = zipPath;
|
|
36
|
+
}
|
|
37
|
+
static async from(pathOrPathsOrData) {
|
|
38
|
+
if (Array.isArray(pathOrPathsOrData)) {
|
|
39
|
+
return new Audiobook(
|
|
40
|
+
pathOrPathsOrData.map((path) => new import_entry2.AudiobookEntry(path))
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
const filepath = typeof pathOrPathsOrData === "string" ? pathOrPathsOrData : pathOrPathsOrData.filename;
|
|
44
|
+
const ext = (0, import_path.extname)(filepath);
|
|
45
|
+
if (ext === ".zip") {
|
|
46
|
+
const dataReader = new import_zip.Uint8ArrayReader(
|
|
47
|
+
typeof pathOrPathsOrData === "string" ? await (0, import_fs.streamFile)(pathOrPathsOrData) : pathOrPathsOrData.data
|
|
48
|
+
);
|
|
49
|
+
const zipReader = new import_zip.ZipReader(dataReader);
|
|
50
|
+
const zipEntries = await zipReader.getEntries();
|
|
51
|
+
const entries = zipEntries.map((entry) => new import_entry2.AudiobookEntry(entry));
|
|
52
|
+
return new Audiobook(entries, filepath);
|
|
53
|
+
}
|
|
54
|
+
return new Audiobook([new import_entry2.AudiobookEntry(pathOrPathsOrData)]);
|
|
55
|
+
}
|
|
56
|
+
async save() {
|
|
57
|
+
const result = [];
|
|
58
|
+
for (const entry of this.entries) {
|
|
59
|
+
entry.save();
|
|
60
|
+
if (!entry.persisted()) {
|
|
61
|
+
result.push({ filename: entry.filename, data: await entry.getData() });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (this.zipPath) {
|
|
65
|
+
const dataWriter = new import_zip.Uint8ArrayWriter();
|
|
66
|
+
const zipWriter = new import_zip.ZipWriter(dataWriter);
|
|
67
|
+
await Promise.all(
|
|
68
|
+
this.entries.map(async (entry) => {
|
|
69
|
+
const data2 = await entry.getData();
|
|
70
|
+
const reader = new import_zip.Uint8ArrayReader(data2);
|
|
71
|
+
try {
|
|
72
|
+
return await zipWriter.add(entry.filename, reader);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
if (e instanceof Error && e.message === import_zip.ERR_DUPLICATED_NAME) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Failed to add file "${entry.filename}" to zip archive: ${e.message}`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
throw e;
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
);
|
|
83
|
+
const data = await zipWriter.close();
|
|
84
|
+
await (0, import_promises.writeFile)(this.zipPath, data);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (result.length) return result;
|
|
88
|
+
return void 0;
|
|
89
|
+
}
|
|
90
|
+
async setCoverArt(picture) {
|
|
91
|
+
if (typeof picture === "string") {
|
|
92
|
+
const filename = (0, import_path.basename)(picture);
|
|
93
|
+
picture = import_node_taglib_sharp.Picture.fromPath(picture);
|
|
94
|
+
picture.filename = filename;
|
|
95
|
+
}
|
|
96
|
+
return super.setCoverArt(picture);
|
|
97
|
+
}
|
|
98
|
+
close() {
|
|
99
|
+
for (const entry of this.entries) {
|
|
100
|
+
entry.close();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
+
0 && (module.exports = {
|
|
106
|
+
Audiobook
|
|
107
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IPicture } from 'node-taglib-sharp';
|
|
2
|
+
import { BaseAudiobook } from '../base.cjs';
|
|
3
|
+
import { Uint8ArrayEntry } from '../entry.cjs';
|
|
4
|
+
import { AudiobookEntry } from './entry.cjs';
|
|
5
|
+
import '@zip.js/zip.js';
|
|
6
|
+
|
|
7
|
+
declare class Audiobook extends BaseAudiobook {
|
|
8
|
+
protected entries: AudiobookEntry[];
|
|
9
|
+
protected zipPath?: string | undefined;
|
|
10
|
+
protected constructor(entries: AudiobookEntry[], zipPath?: string | undefined);
|
|
11
|
+
static from(pathOrPathsOrData: string | string[] | Uint8ArrayEntry | Uint8ArrayEntry[]): Promise<Audiobook>;
|
|
12
|
+
save(): Promise<Uint8ArrayEntry[] | undefined>;
|
|
13
|
+
setCoverArt(picture: string | IPicture): Promise<void>;
|
|
14
|
+
close(): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { Audiobook };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IPicture } from 'node-taglib-sharp';
|
|
2
|
+
import { BaseAudiobook } from '../base.js';
|
|
3
|
+
import { Uint8ArrayEntry } from '../entry.js';
|
|
4
|
+
import { AudiobookEntry } from './entry.js';
|
|
5
|
+
import '@zip.js/zip.js';
|
|
6
|
+
|
|
7
|
+
declare class Audiobook extends BaseAudiobook {
|
|
8
|
+
protected entries: AudiobookEntry[];
|
|
9
|
+
protected zipPath?: string | undefined;
|
|
10
|
+
protected constructor(entries: AudiobookEntry[], zipPath?: string | undefined);
|
|
11
|
+
static from(pathOrPathsOrData: string | string[] | Uint8ArrayEntry | Uint8ArrayEntry[]): Promise<Audiobook>;
|
|
12
|
+
save(): Promise<Uint8ArrayEntry[] | undefined>;
|
|
13
|
+
setCoverArt(picture: string | IPicture): Promise<void>;
|
|
14
|
+
close(): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { Audiobook };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
2
|
+
import {
|
|
3
|
+
ERR_DUPLICATED_NAME,
|
|
4
|
+
Uint8ArrayReader,
|
|
5
|
+
Uint8ArrayWriter,
|
|
6
|
+
ZipReader,
|
|
7
|
+
ZipWriter
|
|
8
|
+
} from "@zip.js/zip.js";
|
|
9
|
+
import { Picture } from "node-taglib-sharp";
|
|
10
|
+
import { streamFile } from "@storyteller-platform/fs";
|
|
11
|
+
import { basename, extname } from "@storyteller-platform/path";
|
|
12
|
+
import { BaseAudiobook } from "../base.js";
|
|
13
|
+
import { AudiobookEntry } from "./entry.js";
|
|
14
|
+
class Audiobook extends BaseAudiobook {
|
|
15
|
+
constructor(entries, zipPath) {
|
|
16
|
+
super();
|
|
17
|
+
this.entries = entries;
|
|
18
|
+
this.zipPath = zipPath;
|
|
19
|
+
}
|
|
20
|
+
static async from(pathOrPathsOrData) {
|
|
21
|
+
if (Array.isArray(pathOrPathsOrData)) {
|
|
22
|
+
return new Audiobook(
|
|
23
|
+
pathOrPathsOrData.map((path) => new AudiobookEntry(path))
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
const filepath = typeof pathOrPathsOrData === "string" ? pathOrPathsOrData : pathOrPathsOrData.filename;
|
|
27
|
+
const ext = extname(filepath);
|
|
28
|
+
if (ext === ".zip") {
|
|
29
|
+
const dataReader = new Uint8ArrayReader(
|
|
30
|
+
typeof pathOrPathsOrData === "string" ? await streamFile(pathOrPathsOrData) : pathOrPathsOrData.data
|
|
31
|
+
);
|
|
32
|
+
const zipReader = new ZipReader(dataReader);
|
|
33
|
+
const zipEntries = await zipReader.getEntries();
|
|
34
|
+
const entries = zipEntries.map((entry) => new AudiobookEntry(entry));
|
|
35
|
+
return new Audiobook(entries, filepath);
|
|
36
|
+
}
|
|
37
|
+
return new Audiobook([new AudiobookEntry(pathOrPathsOrData)]);
|
|
38
|
+
}
|
|
39
|
+
async save() {
|
|
40
|
+
const result = [];
|
|
41
|
+
for (const entry of this.entries) {
|
|
42
|
+
entry.save();
|
|
43
|
+
if (!entry.persisted()) {
|
|
44
|
+
result.push({ filename: entry.filename, data: await entry.getData() });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (this.zipPath) {
|
|
48
|
+
const dataWriter = new Uint8ArrayWriter();
|
|
49
|
+
const zipWriter = new ZipWriter(dataWriter);
|
|
50
|
+
await Promise.all(
|
|
51
|
+
this.entries.map(async (entry) => {
|
|
52
|
+
const data2 = await entry.getData();
|
|
53
|
+
const reader = new Uint8ArrayReader(data2);
|
|
54
|
+
try {
|
|
55
|
+
return await zipWriter.add(entry.filename, reader);
|
|
56
|
+
} catch (e) {
|
|
57
|
+
if (e instanceof Error && e.message === ERR_DUPLICATED_NAME) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`Failed to add file "${entry.filename}" to zip archive: ${e.message}`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
throw e;
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
);
|
|
66
|
+
const data = await zipWriter.close();
|
|
67
|
+
await writeFile(this.zipPath, data);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (result.length) return result;
|
|
71
|
+
return void 0;
|
|
72
|
+
}
|
|
73
|
+
async setCoverArt(picture) {
|
|
74
|
+
if (typeof picture === "string") {
|
|
75
|
+
const filename = basename(picture);
|
|
76
|
+
picture = Picture.fromPath(picture);
|
|
77
|
+
picture.filename = filename;
|
|
78
|
+
}
|
|
79
|
+
return super.setCoverArt(picture);
|
|
80
|
+
}
|
|
81
|
+
close() {
|
|
82
|
+
for (const entry of this.entries) {
|
|
83
|
+
entry.close();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
Audiobook
|
|
89
|
+
};
|