UNPKG

4.29 kBJavaScriptView Raw
1import _defineProperty from "@babel/runtime/helpers/defineProperty";
2import { ArchiveDir, ArchiveHdi, createArchiveByFileExtension } from '@shockpkg/archive-files';
3import fse from 'fs-extra';
4/**
5 * Projector constructor.
6 *
7 * @param path Output path.
8 */
9
10export class Projector extends Object {
11 /**
12 * Path to hdiutil binary.
13 */
14
15 /**
16 * Output path.
17 */
18 constructor(path) {
19 super();
20
21 _defineProperty(this, "hdiutil", null);
22
23 _defineProperty(this, "path", void 0);
24
25 this.path = path;
26 }
27 /**
28 * The movie appended marker.
29 *
30 * @returns Hex string.
31 */
32
33
34 get movieAppendMarker() {
35 return '563412FA';
36 }
37 /**
38 * Get the player file or directory as an Archive instance.
39 *
40 * @param path File path.
41 * @returns Archive instance.
42 */
43
44
45 async openAsArchive(path) {
46 const stat = await fse.stat(path);
47
48 if (stat.isDirectory()) {
49 return new ArchiveDir(path);
50 }
51
52 if (!stat.isFile()) {
53 throw new Error(`Archive path not file or directory: ${path}`);
54 }
55
56 const r = createArchiveByFileExtension(path);
57
58 if (!r) {
59 throw new Error(`Archive file type unknown: ${path}`);
60 }
61
62 if (r instanceof ArchiveHdi) {
63 const {
64 hdiutil
65 } = this;
66
67 if (hdiutil) {
68 r.mounterMac.hdiutil = hdiutil;
69 }
70
71 r.nobrowse = true;
72 }
73
74 return r;
75 }
76 /**
77 * Write out projector with player and file.
78 *
79 * @param player Player path.
80 * @param movieFile Movie file.
81 */
82
83
84 async withFile(player, movieFile) {
85 const movieData = movieFile ? await fse.readFile(movieFile) : null;
86 await this.withData(player, movieData);
87 }
88 /**
89 * Write out projector with player and data.
90 *
91 * @param player Player path.
92 * @param movieData Movie data.
93 */
94
95
96 async withData(player, movieData) {
97 await this._checkOutput();
98 await this._writePlayer(player);
99 await this._modifyPlayer();
100 await this._writeMovie(movieData);
101 }
102 /**
103 * Check that output path is valid, else throws.
104 */
105
106
107 async _checkOutput() {
108 if (await fse.pathExists(this.path)) {
109 throw new Error(`Output path already exists: ${this.path}`);
110 }
111 }
112 /**
113 * Append movie data to a file.
114 * Format string characters:
115 * - d: Movie data.
116 * - m: Marker bytes.
117 * - s: Size, 32LE.
118 * - S: Size, 32BE.
119 * - l: Size, 64LE.
120 * - L: Size, 64BE.
121 *
122 * @param file File to append to.
123 * @param data Movie data.
124 * @param format Format string.
125 */
126
127
128 async _appendMovieData(file, data, format) {
129 const buffers = [];
130
131 for (const c of format) {
132 switch (c) {
133 case 'd':
134 {
135 buffers.push(data);
136 break;
137 }
138
139 case 'm':
140 {
141 buffers.push(Buffer.from(this.movieAppendMarker, 'hex'));
142 break;
143 }
144
145 case 's':
146 {
147 const b = Buffer.alloc(4);
148 b.writeUInt32LE(data.length, 0);
149 buffers.push(b);
150 break;
151 }
152
153 case 'S':
154 {
155 const b = Buffer.alloc(4);
156 b.writeUInt32BE(data.length, 0);
157 buffers.push(b);
158 break;
159 }
160
161 case 'l':
162 {
163 // 64-bit, just write 32-bit, SWF cannot be larger.
164 const b = Buffer.alloc(8, 0);
165 b.writeUInt32LE(data.length, 0);
166 buffers.push(b);
167 break;
168 }
169
170 case 'L':
171 {
172 // 64-bit, just write 32-bit, SWF cannot be larger.
173 const b = Buffer.alloc(8, 0);
174 b.writeUInt32BE(data.length, 4);
175 buffers.push(b);
176 break;
177 }
178
179 default:
180 {
181 throw new Error(`Unknown format string character: ${c}`);
182 }
183 }
184 }
185
186 const stat = await fse.stat(file);
187
188 if (!stat.isFile()) {
189 throw new Error(`Path not a file: ${file}`);
190 }
191
192 const fd = await fse.open(file, 'a');
193
194 try {
195 for (const b of buffers) {
196 // eslint-disable-next-line no-await-in-loop
197 await fse.appendFile(fd, b);
198 }
199 } finally {
200 await fse.close(fd);
201 }
202 }
203 /**
204 * Projector file extension.
205 *
206 * @returns File extension.
207 */
208
209
210}
211//# sourceMappingURL=projector.mjs.map