UXP v2.1.5: import-flow — await all premierepro calls (runtime is async despite docs saying sync)
This commit is contained in:
parent
11cb93aa51
commit
1fb790a569
1 changed files with 18 additions and 54 deletions
|
|
@ -1,20 +1,11 @@
|
|||
// import-flow.js — v2.1.4
|
||||
// Root cause of "Cannot read properties of undefined (reading)":
|
||||
// response.body is null when redirect:'manual' is used — that fetch option
|
||||
// is NOT supported in UXP. UXP auto-follows redirects and does NOT expose
|
||||
// manual redirect control. Dropping redirect:'manual' entirely.
|
||||
//
|
||||
// Download strategy:
|
||||
// response.arrayBuffer() → write entire buffer via fs.writeFile()
|
||||
// Simpler than fd-based chunked write, works for proxy files (typically <2GB).
|
||||
// Progress reporting is approximate (0% → 100% on completion).
|
||||
// import-flow.js — v2.1.5
|
||||
// premierepro API: docs say sync, runtime returns Promises. Await everything.
|
||||
|
||||
(function () {
|
||||
const Import = {};
|
||||
|
||||
const fs = require('fs');
|
||||
// window.path is a UXP global (v6.4+) — no require('path')
|
||||
// os.tmpdir() not in UXP — use env.TEMP or uxp storage
|
||||
let os; try { os = require('os'); } catch (_) { os = {}; }
|
||||
let uxpFs; try { uxpFs = require('uxp').storage.localFileSystem; } catch (_) { uxpFs = null; }
|
||||
|
||||
|
|
@ -46,25 +37,21 @@
|
|||
return path.join(base, 'dragonflight-' + safeName);
|
||||
};
|
||||
|
||||
// ── Write ArrayBuffer to disk ────────────────────────────────────
|
||||
// fs.writeFile with flag:'w' creates/overwrites the file.
|
||||
// Write ArrayBuffer to disk via fs.writeFile
|
||||
Import._writeBuffer = async function (destPath, arrayBuffer) {
|
||||
await fs.writeFile(destPath, arrayBuffer);
|
||||
return destPath;
|
||||
};
|
||||
|
||||
// ── Fetch with auth — UXP-safe ───────────────────────────────────
|
||||
// UXP auto-follows redirects. 'redirect' option is NOT supported.
|
||||
// We only add Authorization for same-origin requests (server URL base).
|
||||
// For S3 presigned URLs (off-origin) we do NOT add Bearer — that would
|
||||
// break the presigned signature.
|
||||
// Fetch — no redirect option (not supported in UXP)
|
||||
// addAuth: only for same-origin proxy URLs, NOT for S3 presigned URLs
|
||||
async function _fetch(url, addAuth) {
|
||||
const headers = {};
|
||||
if (addAuth && API.state.apiToken) {
|
||||
headers['Authorization'] = 'Bearer ' + API.state.apiToken;
|
||||
}
|
||||
const r = await fetch(url, { headers });
|
||||
if (!r.ok) throw new Error('HTTP ' + r.status + ' from ' + url);
|
||||
if (!r.ok) throw new Error('HTTP ' + r.status + ' fetching ' + url);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -76,15 +63,16 @@
|
|||
return Import._ppro_mod;
|
||||
}
|
||||
|
||||
// Import a file already on disk into the active Premiere project.
|
||||
// project.importFiles() is async (it actually imports the file).
|
||||
// Import a file into the active Premiere project.
|
||||
// ALL premierepro calls must be awaited — runtime returns Promises
|
||||
// even though docs list them as synchronous.
|
||||
Import.importIntoProject = async function (filePath) {
|
||||
const P = _ppro();
|
||||
const project = P.Project.getActiveProject(); // sync
|
||||
const project = await P.Project.getActiveProject();
|
||||
if (!project) throw new Error('No active Premiere project');
|
||||
const root = project.getRootItem(); // sync
|
||||
const root = await project.getRootItem();
|
||||
const ok = await project.importFiles([filePath], true, root, false);
|
||||
if (!ok) throw new Error('Premiere refused to import file');
|
||||
if (!ok) throw new Error('Premiere refused to import the file');
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
@ -97,8 +85,7 @@
|
|||
const { url } = await API.getProxyUrl(asset.id);
|
||||
|
||||
UI.showProgress('Downloading ' + safeName + '…', 10);
|
||||
// Same-origin proxy URL — add auth
|
||||
const r = await _fetch(url, true);
|
||||
const r = await _fetch(url, true); // same-origin — add auth
|
||||
|
||||
UI.showProgress('Writing to disk…', 70);
|
||||
const buf = await r.arrayBuffer();
|
||||
|
|
@ -119,8 +106,7 @@
|
|||
const dest = await Import._tempPath(safeName);
|
||||
|
||||
UI.showProgress('Downloading ' + safeName + ' (' + UI.formatBytes(Number(info.file_size || 0)) + ')…', 8);
|
||||
// Presigned S3 URL — no auth header (would break signature)
|
||||
const r = await _fetch(info.url, false);
|
||||
const r = await _fetch(info.url, false); // presigned S3 — no auth
|
||||
|
||||
UI.showProgress('Writing to disk…', 75);
|
||||
const buf = await r.arrayBuffer();
|
||||
|
|
@ -133,32 +119,10 @@
|
|||
return { localPath: dest, safeName };
|
||||
};
|
||||
|
||||
// Expose for timeline.js batch relink (it downloads hi-res files too)
|
||||
Import._streamToFile = async function (response, destPath, onProgress) {
|
||||
// In UXP, response.body may be null — fall back to arrayBuffer()
|
||||
if (response.body && response.body.getReader) {
|
||||
const total = Number(response.headers.get('content-length') || 0);
|
||||
const reader = response.body.getReader();
|
||||
const fd = await fs.open(destPath, 'w');
|
||||
let received = 0, filePos = 0;
|
||||
try {
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) break;
|
||||
const buf = value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);
|
||||
const { bytesWritten } = await fs.write(fd, buf, 0, buf.byteLength, filePos);
|
||||
filePos += bytesWritten;
|
||||
received += value.byteLength;
|
||||
if (onProgress) onProgress({ received, total });
|
||||
}
|
||||
} finally { await fs.close(fd); }
|
||||
} else {
|
||||
// Fallback: buffer entire response
|
||||
if (onProgress) onProgress({ received: 0, total: 0 });
|
||||
const buf = await response.arrayBuffer();
|
||||
await Import._writeBuffer(destPath, buf);
|
||||
if (onProgress) onProgress({ received: buf.byteLength, total: buf.byteLength });
|
||||
}
|
||||
// Used by timeline.js batch relink
|
||||
Import._streamToFile = async function (response, destPath /*, onProgress */) {
|
||||
const buf = await response.arrayBuffer();
|
||||
await Import._writeBuffer(destPath, buf);
|
||||
return destPath;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue