playsvideo 0.1.0 → 0.2.1

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/dist/worker.js ADDED
@@ -0,0 +1,420 @@
1
+ import { WasmFfmpegRunner } from './adapters/wasm-ffmpeg.js';
2
+ import { buildTranscodeResultFromAdts, concatEncodedPacketData, createEmptyTranscodeResult, createLocalAudioTranscoder, makeAacDecoderConfig, } from './pipeline/audio-transcode.js';
3
+ import { audioNeedsTranscode, createBrowserProber } from './pipeline/codec-probe.js';
4
+ import { demuxBlob, demuxUrl, getKeyframeIndex } from './pipeline/demux.js';
5
+ import { generateVodPlaylist } from './pipeline/playlist.js';
6
+ import { buildSegmentPlan } from './pipeline/segment-plan.js';
7
+ import { processSegmentWithAbort } from './pipeline/segment-processor.js';
8
+ import { extractSubtitleData, subtitleDataToWebVTT } from './pipeline/subtitle.js';
9
+ function wlog(msg) {
10
+ console.log(`[worker] ${msg}`);
11
+ }
12
+ function elapsed(start) {
13
+ return `${(performance.now() - start).toFixed(1)}ms`;
14
+ }
15
+ function makeAbortError() {
16
+ return new DOMException('Segment aborted', 'AbortError');
17
+ }
18
+ class TranscodePortPool {
19
+ workers = [];
20
+ queue = [];
21
+ nextJobId = 0;
22
+ addPort(id, port) {
23
+ const entry = { id, port, currentJob: null };
24
+ port.onmessage = (event) => {
25
+ this.handleWorkerMessage(entry, event.data);
26
+ };
27
+ port.start?.();
28
+ this.workers.push(entry);
29
+ this.dispatch();
30
+ }
31
+ hasWorkers() {
32
+ return this.workers.length > 0;
33
+ }
34
+ workerCount() {
35
+ return this.workers.length;
36
+ }
37
+ transcode = async (opts, signal) => {
38
+ if (opts.packets.length === 0) {
39
+ return createEmptyTranscodeResult(opts.sampleRate);
40
+ }
41
+ if (signal?.aborted) {
42
+ throw makeAbortError();
43
+ }
44
+ const startedAt = performance.now();
45
+ const tConcat = performance.now();
46
+ const input = concatEncodedPacketData(opts.packets);
47
+ const concatMs = performance.now() - tConcat;
48
+ return await new Promise((resolve, reject) => {
49
+ const job = {
50
+ id: ++this.nextJobId,
51
+ opts,
52
+ startedAt,
53
+ concatMs,
54
+ inputBytes: input.inputBytes,
55
+ audioDurationSec: input.audioDurationSec,
56
+ inputData: input.data,
57
+ signal,
58
+ settled: false,
59
+ resolve,
60
+ reject,
61
+ };
62
+ const abort = () => {
63
+ if (job.settled) {
64
+ return;
65
+ }
66
+ job.settled = true;
67
+ this.queue = this.queue.filter((queued) => queued !== job);
68
+ reject(makeAbortError());
69
+ this.dispatch();
70
+ };
71
+ if (signal) {
72
+ job.onAbort = abort;
73
+ signal.addEventListener('abort', abort, { once: true });
74
+ }
75
+ this.queue.push(job);
76
+ this.dispatch();
77
+ });
78
+ };
79
+ dispatch() {
80
+ for (const worker of this.workers) {
81
+ if (worker.currentJob !== null) {
82
+ continue;
83
+ }
84
+ const job = this.queue.shift();
85
+ if (!job) {
86
+ return;
87
+ }
88
+ worker.currentJob = job;
89
+ const transferData = new Uint8Array(job.inputData);
90
+ const buffer = transferData.buffer;
91
+ const msg = {
92
+ type: 'transcode-job',
93
+ jobId: job.id,
94
+ inputData: buffer,
95
+ sourceCodec: job.opts.sourceCodec,
96
+ };
97
+ worker.port.postMessage(msg, [buffer]);
98
+ }
99
+ }
100
+ handleWorkerMessage(worker, msg) {
101
+ const job = worker.currentJob;
102
+ worker.currentJob = null;
103
+ if (!job) {
104
+ this.dispatch();
105
+ return;
106
+ }
107
+ if (job.signal && job.onAbort) {
108
+ job.signal.removeEventListener('abort', job.onAbort);
109
+ }
110
+ if (!job.settled) {
111
+ if (msg.type !== 'transcode-result' || msg.jobId !== job.id) {
112
+ job.settled = true;
113
+ job.reject(new Error(`Transcode worker ${worker.id} returned an unexpected job result`));
114
+ }
115
+ else if (!msg.ok) {
116
+ job.settled = true;
117
+ job.reject(new Error(msg.error));
118
+ }
119
+ else {
120
+ job.settled = true;
121
+ const aacData = new Uint8Array(msg.outputData);
122
+ const result = buildTranscodeResultFromAdts({
123
+ inputPackets: job.opts.packets.length,
124
+ inputBytes: job.inputBytes,
125
+ audioDurationSec: job.audioDurationSec,
126
+ concatMs: job.concatMs,
127
+ sampleRate: job.opts.sampleRate,
128
+ audioStartSec: job.opts.audioStartSec,
129
+ aacData,
130
+ ffmpegMetrics: msg.metrics,
131
+ totalMs: performance.now() - job.startedAt,
132
+ });
133
+ job.resolve(result);
134
+ }
135
+ }
136
+ this.dispatch();
137
+ }
138
+ }
139
+ const ffmpeg = new WasmFfmpegRunner();
140
+ const codecProber = createBrowserProber();
141
+ const localAudioTranscoder = createLocalAudioTranscoder(ffmpeg);
142
+ const transcodePool = new TranscodePortPool();
143
+ let demux = null;
144
+ let plan = [];
145
+ let doTranscode = false;
146
+ let audioDecoderConfig = null;
147
+ let initSegment = null;
148
+ const segmentCache = new Map();
149
+ const segmentTasks = new Map();
150
+ let targetSegDuration = 4;
151
+ // Keep pipeline setup ordered, but let individual segment work run independently.
152
+ let pipelineSetup = Promise.resolve();
153
+ // Per-segment abort controllers for cancellation
154
+ const segmentAbortControllers = new Map();
155
+ self.onmessage = (event) => {
156
+ const msg = event.data;
157
+ if (msg.type === 'open') {
158
+ wlog('recv open');
159
+ targetSegDuration = msg.targetSegmentDuration ?? 4;
160
+ queuePipelineSetup(() => handleProbe(() => demuxBlob(msg.file)));
161
+ }
162
+ else if (msg.type === 'open-url') {
163
+ wlog('recv open-url');
164
+ targetSegDuration = msg.targetSegmentDuration ?? 4;
165
+ queuePipelineSetup(() => handleProbe(() => demuxUrl(msg.url)));
166
+ }
167
+ else if (msg.type === 'remux-pipeline') {
168
+ wlog('recv remux-pipeline');
169
+ queuePipelineSetup(() => handleRemuxPipeline(msg.keyframeIndex));
170
+ }
171
+ else if (msg.type === 'passthrough-pipeline') {
172
+ wlog('recv passthrough-pipeline — subtitle-only mode');
173
+ }
174
+ else if (msg.type === 'transcode-port') {
175
+ const portMsg = msg;
176
+ const port = event.ports[0];
177
+ if (port) {
178
+ wlog(`recv transcode-port id=${portMsg.id}`);
179
+ transcodePool.addPort(portMsg.id, port);
180
+ }
181
+ }
182
+ else if (msg.type === 'segment') {
183
+ wlog(`recv segment idx=${msg.index}`);
184
+ void handleSegmentRequest(msg.index);
185
+ }
186
+ else if (msg.type === 'cancel') {
187
+ const controller = segmentAbortControllers.get(msg.index);
188
+ if (controller) {
189
+ wlog(`cancel segment idx=${msg.index}`);
190
+ controller.abort();
191
+ segmentAbortControllers.delete(msg.index);
192
+ }
193
+ }
194
+ else if (msg.type === 'subtitle') {
195
+ wlog(`recv subtitle trackIndex=${msg.trackIndex}`);
196
+ handleSubtitle(msg.trackIndex).catch((err) => self.postMessage({ type: 'error', message: String(err) }));
197
+ }
198
+ };
199
+ function queuePipelineSetup(task) {
200
+ pipelineSetup = pipelineSetup.then(task).catch((err) => {
201
+ self.postMessage({ type: 'error', message: String(err) });
202
+ });
203
+ }
204
+ function makeProcessorConfig() {
205
+ if (!demux) {
206
+ throw new Error('No demux — handleProbe must run first');
207
+ }
208
+ return {
209
+ videoSink: demux.videoSink,
210
+ audioSink: demux.audioSink,
211
+ videoCodec: demux.videoCodec,
212
+ audioCodec: demux.audioCodec,
213
+ videoDecoderConfig: demux.videoDecoderConfig,
214
+ audioDecoderConfig,
215
+ plan,
216
+ doTranscode,
217
+ transcodeAudio: transcodePool.hasWorkers() ? transcodePool.transcode : localAudioTranscoder,
218
+ sourceCodec: demux.audioCodec ?? undefined,
219
+ log: wlog,
220
+ };
221
+ }
222
+ function shouldPrefetchSegments() {
223
+ return doTranscode && transcodePool.workerCount() > 0;
224
+ }
225
+ function schedulePrefetch(startIndex) {
226
+ if (!shouldPrefetchSegments()) {
227
+ return;
228
+ }
229
+ const maxInFlight = transcodePool.workerCount();
230
+ let nextIndex = startIndex;
231
+ while (segmentTasks.size < maxInFlight && nextIndex < plan.length) {
232
+ if (!segmentCache.has(nextIndex) && !segmentTasks.has(nextIndex)) {
233
+ void ensureSegmentTask(nextIndex).catch((err) => {
234
+ self.postMessage({ type: 'error', message: String(err) });
235
+ });
236
+ }
237
+ nextIndex += 1;
238
+ }
239
+ }
240
+ async function ensureSegmentTask(index) {
241
+ const cached = segmentCache.get(index);
242
+ if (cached) {
243
+ return cached;
244
+ }
245
+ const existing = segmentTasks.get(index);
246
+ if (existing) {
247
+ return existing;
248
+ }
249
+ const task = (async () => {
250
+ const t0 = performance.now();
251
+ const result = await processSegmentWithAbort(makeProcessorConfig(), index);
252
+ if (!initSegment && result.initSegment) {
253
+ initSegment = result.initSegment;
254
+ wlog(`init-segment captured size=${initSegment.byteLength}`);
255
+ }
256
+ const mediaData = result.mediaData;
257
+ segmentCache.set(index, mediaData);
258
+ wlog(`seg ${index} done ${elapsed(t0)} size=${mediaData.byteLength}`);
259
+ return mediaData;
260
+ })().finally(() => {
261
+ segmentTasks.delete(index);
262
+ });
263
+ segmentTasks.set(index, task);
264
+ return task;
265
+ }
266
+ async function waitForSegment(index, signal) {
267
+ if (signal?.aborted) {
268
+ throw makeAbortError();
269
+ }
270
+ const task = ensureSegmentTask(index);
271
+ if (!signal) {
272
+ return task;
273
+ }
274
+ return await new Promise((resolve, reject) => {
275
+ const abort = () => reject(makeAbortError());
276
+ signal.addEventListener('abort', abort, { once: true });
277
+ task
278
+ .then(resolve)
279
+ .catch(reject)
280
+ .finally(() => {
281
+ signal.removeEventListener('abort', abort);
282
+ });
283
+ });
284
+ }
285
+ /** Phase 1: demux and send codec info to engine for passthrough decision. */
286
+ async function handleProbe(demuxFn) {
287
+ if (demux) {
288
+ demux.dispose();
289
+ }
290
+ const tDemux = performance.now();
291
+ demux = await demuxFn();
292
+ wlog(`demux done ${elapsed(tDemux)} codec=${demux.videoCodec}/${demux.audioCodec} dur=${demux.duration.toFixed(1)}s`);
293
+ // Send codec info so engine can check canPlayType on the main thread
294
+ self.postMessage({
295
+ type: 'probed',
296
+ videoCodec: demux.videoDecoderConfig.codec,
297
+ audioCodec: demux.audioDecoderConfig?.codec ?? null,
298
+ durationSec: demux.duration,
299
+ subtitleTracks: demux.subtitleTracks,
300
+ });
301
+ }
302
+ /** Phase 2: full pipeline — engine told us native playback isn't possible. */
303
+ async function handleRemuxPipeline(prebuiltKeyframeIndex) {
304
+ if (!demux)
305
+ throw new Error('No demux — handleProbe must run first');
306
+ const t0 = performance.now();
307
+ let index;
308
+ if (prebuiltKeyframeIndex) {
309
+ index = prebuiltKeyframeIndex;
310
+ wlog(`keyframe-index pre-built keyframes=${index.keyframes.length}`);
311
+ }
312
+ else {
313
+ const tIndex = performance.now();
314
+ index = await getKeyframeIndex(demux.videoSink, demux.duration);
315
+ wlog(`keyframe-index done ${elapsed(tIndex)} keyframes=${index.keyframes.length}`);
316
+ }
317
+ const tPlan = performance.now();
318
+ plan = buildSegmentPlan({
319
+ keyframeTimestampsSec: index.keyframes.map((k) => k.timestamp),
320
+ durationSec: index.duration,
321
+ targetSegmentDurationSec: targetSegDuration,
322
+ });
323
+ wlog(`segment-plan done ${elapsed(tPlan)} segments=${plan.length}`);
324
+ doTranscode =
325
+ demux.audioCodec !== null &&
326
+ audioNeedsTranscode(codecProber, demux.audioCodec, demux.audioDecoderConfig?.codec);
327
+ if (doTranscode && demux.audioCodec && !transcodePool.hasWorkers()) {
328
+ await ffmpeg.loadForCodec(demux.audioCodec);
329
+ }
330
+ audioDecoderConfig = doTranscode
331
+ ? makeAacDecoderConfig(demux.audioDecoderConfig)
332
+ : demux.audioDecoderConfig;
333
+ initSegment = null;
334
+ segmentCache.clear();
335
+ segmentTasks.clear();
336
+ const playlist = generateVodPlaylist({
337
+ targetDuration: Math.ceil(Math.max(...plan.map((s) => s.durationSec))),
338
+ mediaSequence: 0,
339
+ mapUri: 'init.mp4',
340
+ entries: plan.map((s) => ({ uri: `seg-${s.sequence}.m4s`, durationSec: s.durationSec })),
341
+ endList: true,
342
+ });
343
+ const tSeg0 = performance.now();
344
+ const seg0Result = await processSegmentWithAbort(makeProcessorConfig(), 0);
345
+ segmentCache.set(0, seg0Result.mediaData);
346
+ if (seg0Result.initSegment) {
347
+ initSegment = seg0Result.initSegment;
348
+ wlog(`init-segment captured size=${initSegment.byteLength}`);
349
+ }
350
+ wlog(`seg0 preprocess done ${elapsed(tSeg0)}`);
351
+ wlog(`pipeline complete ${elapsed(t0)} total`);
352
+ self.postMessage({
353
+ type: 'ready',
354
+ playlist,
355
+ initData: initSegment.buffer,
356
+ totalSegments: plan.length,
357
+ durationSec: demux.duration,
358
+ subtitleTracks: demux.subtitleTracks,
359
+ }, { transfer: [] }); // don't transfer initData — we need to keep it
360
+ schedulePrefetch(1);
361
+ }
362
+ async function handleSegmentRequest(index) {
363
+ const controller = new AbortController();
364
+ segmentAbortControllers.set(index, controller);
365
+ try {
366
+ await pipelineSetup;
367
+ await handleSegment(index, controller.signal);
368
+ }
369
+ catch (err) {
370
+ if (err instanceof DOMException && err.name === 'AbortError') {
371
+ wlog(`seg ${index} aborted`);
372
+ return;
373
+ }
374
+ self.postMessage({ type: 'error', message: String(err) });
375
+ }
376
+ finally {
377
+ segmentAbortControllers.delete(index);
378
+ }
379
+ }
380
+ async function handleSegment(index, signal) {
381
+ if (!demux || index >= plan.length) {
382
+ self.postMessage({ type: 'error', message: `Invalid segment index: ${index}` });
383
+ return;
384
+ }
385
+ // Return cached segment if available (segment 0 is pre-processed during open)
386
+ const cached = segmentCache.get(index);
387
+ if (cached) {
388
+ segmentCache.delete(index);
389
+ wlog(`seg ${index} cache-hit size=${cached.byteLength}`);
390
+ const buffer = cached.buffer.slice(cached.byteOffset, cached.byteOffset + cached.byteLength);
391
+ self.postMessage({ type: 'segment', index, data: buffer }, { transfer: [buffer] });
392
+ return;
393
+ }
394
+ try {
395
+ const mediaData = await waitForSegment(index, signal);
396
+ const buffer = mediaData.buffer.slice(mediaData.byteOffset, mediaData.byteOffset + mediaData.byteLength);
397
+ self.postMessage({ type: 'segment', index, data: buffer }, { transfer: [buffer] });
398
+ segmentCache.delete(index);
399
+ schedulePrefetch(index + 1);
400
+ }
401
+ catch (err) {
402
+ if (err instanceof DOMException && err.name === 'AbortError') {
403
+ wlog(`seg ${index} aborted during processing`);
404
+ return;
405
+ }
406
+ throw err;
407
+ }
408
+ }
409
+ async function handleSubtitle(trackIndex) {
410
+ if (!demux) {
411
+ self.postMessage({ type: 'error', message: 'No file open' });
412
+ return;
413
+ }
414
+ const t0 = performance.now();
415
+ const data = await extractSubtitleData(demux.input, trackIndex);
416
+ const webvtt = subtitleDataToWebVTT(data);
417
+ wlog(`subtitle track=${trackIndex} cues=${data.cues.length} codec=${data.codec} ${elapsed(t0)}`);
418
+ self.postMessage({ type: 'subtitle', trackIndex, webvtt, codec: data.codec });
419
+ }
420
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playsvideo",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Play any video file in the browser — client-side remuxing and audio transcode, no server required.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,7 +21,8 @@
21
21
  ],
22
22
  "scripts": {
23
23
  "dev": "vite",
24
- "build": "vite build",
24
+ "build": "pnpm run build:site && pnpm run build:lib",
25
+ "build:site": "vite build",
25
26
  "build:lib": "rm -rf dist && tsc -p tsconfig.lib.json && mkdir -p dist/vendor && cp -r src/vendor/ffmpeg-core-audio dist/vendor/ffmpeg-core-audio",
26
27
  "build:extension": "vite build --config vite.config.extension.ts",
27
28
  "test": "vitest run",
@@ -37,12 +38,11 @@
37
38
  "download:ffmpeg-core": "node scripts/download-ffmpeg-core.mjs",
38
39
  "setup": "pnpm install && pnpm run download:ffmpeg-core",
39
40
  "deploy:worker": "cd worker && npx wrangler deploy",
40
- "deploy:site": "pnpm run build && pnpm --filter app build && bash scripts/deploy.sh",
41
+ "deploy:site": "pnpm run build:site && pnpm --filter app build && bash scripts/deploy.sh",
41
42
  "deploy": "pnpm run deploy:site && pnpm run deploy:worker",
42
43
  "prepublishOnly": "pnpm run build:lib"
43
44
  },
44
45
  "dependencies": {
45
- "@ffmpeg/ffmpeg": "^0.12.15",
46
46
  "hls.js": "^1.5.0",
47
47
  "mediabunny": "github:kzahel/mediabunny#integration"
48
48
  },