davinci-resolve-mcp 2.57.4 → 2.58.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/AGENTS.md +20 -0
- package/CHANGELOG.md +197 -2
- package/LICENSE +1 -1
- package/README.md +73 -1
- package/bin/davinci-resolve-advanced-mcp.mjs +20 -0
- package/docs/README.md +19 -0
- package/docs/SKILL.md +62 -1
- package/docs/contributing.md +1 -1
- package/docs/guides/control-panel.md +9 -0
- package/docs/kernels/README.md +21 -0
- package/docs/kernels/audio-fairlight-kernel.md +22 -0
- package/docs/kernels/color-grade-kernel.md +51 -0
- package/docs/kernels/fusion-composition-kernel.md +17 -0
- package/docs/kernels/media-pool-ingest-kernel.md +20 -0
- package/docs/kernels/render-deliver-kernel.md +32 -0
- package/docs/kernels/timeline-conform-interchange-kernel.md +39 -0
- package/docs/kernels/timeline-edit-kernel.md +17 -0
- package/docs/process/release-process.md +29 -7
- package/docs/reference/api-coverage.md +1 -1
- package/docs/reference/api-limitations.md +38 -1
- package/install.py +27 -4
- package/package.json +23 -2
- package/resolve-advanced/README.md +194 -0
- package/resolve-advanced/package.json +50 -0
- package/resolve-advanced/server/black-balance.mjs +92 -0
- package/resolve-advanced/server/capabilities.mjs +86 -0
- package/resolve-advanced/server/cdl-io.mjs +76 -0
- package/resolve-advanced/server/contrast-normalize.mjs +180 -0
- package/resolve-advanced/server/db-patch.mjs +91 -0
- package/resolve-advanced/server/deliverable-entities.mjs +86 -0
- package/resolve-advanced/server/deliverable-qc.mjs +270 -0
- package/resolve-advanced/server/editorial.mjs +370 -0
- package/resolve-advanced/server/exposure-level.mjs +129 -0
- package/resolve-advanced/server/extract-frames.mjs +196 -0
- package/resolve-advanced/server/ffprobe-media.mjs +88 -0
- package/resolve-advanced/server/gamut-legal.mjs +112 -0
- package/resolve-advanced/server/grade-body-patch.mjs +246 -0
- package/resolve-advanced/server/grade-transfer.mjs +66 -0
- package/resolve-advanced/server/group-grade-read.mjs +137 -0
- package/resolve-advanced/server/index.mjs +105 -0
- package/resolve-advanced/server/lib.mjs +84 -0
- package/resolve-advanced/server/libs.mjs +65 -0
- package/resolve-advanced/server/lineage-db.mjs +479 -0
- package/resolve-advanced/server/lut-apply.mjs +61 -0
- package/resolve-advanced/server/match-to-reference.mjs +173 -0
- package/resolve-advanced/server/media-inventory.mjs +169 -0
- package/resolve-advanced/server/media-ops.mjs +243 -0
- package/resolve-advanced/server/node-meta-db.mjs +62 -0
- package/resolve-advanced/server/node-provenance.mjs +102 -0
- package/resolve-advanced/server/offline-ref-db.mjs +420 -0
- package/resolve-advanced/server/offline-ref.mjs +179 -0
- package/resolve-advanced/server/project-db.mjs +233 -0
- package/resolve-advanced/server/provenance-audit.mjs +210 -0
- package/resolve-advanced/server/qc-frame.mjs +224 -0
- package/resolve-advanced/server/qc-sampler.mjs +67 -0
- package/resolve-advanced/server/readback.mjs +77 -0
- package/resolve-advanced/server/render-manifest.mjs +93 -0
- package/resolve-advanced/server/reverse-clip-db.mjs +270 -0
- package/resolve-advanced/server/runner-apply-contract.mjs +64 -0
- package/resolve-advanced/server/runner.mjs +244 -0
- package/resolve-advanced/server/saturation-match.mjs +108 -0
- package/resolve-advanced/server/scope-read.mjs +257 -0
- package/resolve-advanced/server/season-look.mjs +96 -0
- package/resolve-advanced/server/shot-intent.mjs +82 -0
- package/resolve-advanced/server/shot-match.mjs +147 -0
- package/resolve-advanced/server/skin-match.mjs +205 -0
- package/resolve-advanced/server/spec-compile.mjs +217 -0
- package/resolve-advanced/server/tone-curve-transfer.mjs +184 -0
- package/resolve-advanced/server/tool-catalog.mjs +265 -0
- package/resolve-advanced/server/tools/audio.mjs +54 -0
- package/resolve-advanced/server/tools/audio_plan.mjs +58 -0
- package/resolve-advanced/server/tools/capabilities.mjs +16 -0
- package/resolve-advanced/server/tools/color_trace.mjs +165 -0
- package/resolve-advanced/server/tools/conform.mjs +291 -0
- package/resolve-advanced/server/tools/deliverable.mjs +105 -0
- package/resolve-advanced/server/tools/drp.mjs +232 -0
- package/resolve-advanced/server/tools/drt.mjs +200 -0
- package/resolve-advanced/server/tools/drx.mjs +943 -0
- package/resolve-advanced/server/tools/editorial.mjs +69 -0
- package/resolve-advanced/server/tools/fairlight.mjs +108 -0
- package/resolve-advanced/server/tools/fusion.mjs +64 -0
- package/resolve-advanced/server/tools/media.mjs +102 -0
- package/resolve-advanced/server/tools/offline_ref.mjs +123 -0
- package/resolve-advanced/server/tools/pipeline.mjs +137 -0
- package/resolve-advanced/server/tools/project_db.mjs +200 -0
- package/resolve-advanced/server/tools/project_read.mjs +212 -0
- package/resolve-advanced/server/tools/provenance.mjs +73 -0
- package/resolve-advanced/server/verify-grade.mjs +113 -0
- package/resolve-advanced/server/white-balance-match.mjs +122 -0
- package/resolve-advanced/vendor/audio/format-converter.js +330 -0
- package/resolve-advanced/vendor/audio/split.js +173 -0
- package/resolve-advanced/vendor/audio/trim.js +188 -0
- package/resolve-advanced/vendor/audio-fairlight/index.js +391 -0
- package/resolve-advanced/vendor/conform-qc/adapters/frame-sampler.js +56 -0
- package/resolve-advanced/vendor/conform-qc/adapters/local-ffmpeg-sampler.js +65 -0
- package/resolve-advanced/vendor/conform-qc/adapters/rendernode-ffmpeg-sampler.js +50 -0
- package/resolve-advanced/vendor/conform-qc/adapters/resolve/driver.py +176 -0
- package/resolve-advanced/vendor/conform-qc/adapters/resolve-driver.js +61 -0
- package/resolve-advanced/vendor/conform-qc/adapters/resolve-headless-driver.js +86 -0
- package/resolve-advanced/vendor/conform-qc/adapters/vision-validator.js +75 -0
- package/resolve-advanced/vendor/conform-qc/cli.js +63 -0
- package/resolve-advanced/vendor/conform-qc/compare/advisory.js +106 -0
- package/resolve-advanced/vendor/conform-qc/compare/decode.js +36 -0
- package/resolve-advanced/vendor/conform-qc/compare/index.js +61 -0
- package/resolve-advanced/vendor/conform-qc/compare/locate.js +70 -0
- package/resolve-advanced/vendor/conform-qc/compare/metrics.js +409 -0
- package/resolve-advanced/vendor/conform-qc/docs/runbook.md +72 -0
- package/resolve-advanced/vendor/conform-qc/index.js +49 -0
- package/resolve-advanced/vendor/conform-qc/knowledge/index.js +110 -0
- package/resolve-advanced/vendor/conform-qc/ops/conform-core.js +137 -0
- package/resolve-advanced/vendor/conform-qc/ops/conform-diff.js +109 -0
- package/resolve-advanced/vendor/conform-qc/ops/insert.js +108 -0
- package/resolve-advanced/vendor/conform-qc/ops/local-conform.js +61 -0
- package/resolve-advanced/vendor/conform-qc/ops/patch.js +80 -0
- package/resolve-advanced/vendor/conform-qc/ops/trigger.js +32 -0
- package/resolve-advanced/vendor/conform-qc/ops/verify.js +105 -0
- package/resolve-advanced/vendor/conform-qc/ops/workflow.js +30 -0
- package/resolve-advanced/vendor/conform-qc/oracle/emulate.js +155 -0
- package/resolve-advanced/vendor/conform-qc/oracle/index.js +38 -0
- package/resolve-advanced/vendor/conform-qc/oracle/resolve.js +196 -0
- package/resolve-advanced/vendor/conform-qc/package.json +16 -0
- package/resolve-advanced/vendor/conform-qc/packaging/emit-aaf.js +30 -0
- package/resolve-advanced/vendor/conform-qc/packaging/emit-fcp7.js +64 -0
- package/resolve-advanced/vendor/conform-qc/packaging/index.js +169 -0
- package/resolve-advanced/vendor/conform-qc/packaging/media-ops.js +56 -0
- package/resolve-advanced/vendor/conform-qc/packaging/otio.js +50 -0
- package/resolve-advanced/vendor/conform-qc/packaging/relink.js +50 -0
- package/resolve-advanced/vendor/conform-qc/packaging/surgical-relink.js +195 -0
- package/resolve-advanced/vendor/conform-qc/parse/index.js +54 -0
- package/resolve-advanced/vendor/conform-qc/parse/merge-dto.js +27 -0
- package/resolve-advanced/vendor/conform-qc/parse/xmeml-geometry.js +256 -0
- package/resolve-advanced/vendor/conform-qc/reference/burnin-ocr.js +100 -0
- package/resolve-advanced/vendor/conform-qc/reference/sidecar.js +37 -0
- package/resolve-advanced/vendor/conform-qc/repair/analysis.js +62 -0
- package/resolve-advanced/vendor/conform-qc/repair/index.js +78 -0
- package/resolve-advanced/vendor/conform-qc/repair/media-analysis.js +139 -0
- package/resolve-advanced/vendor/conform-qc/repair/media-index.js +135 -0
- package/resolve-advanced/vendor/conform-qc/repair/strategies.js +250 -0
- package/resolve-advanced/vendor/conform-qc/report/index.js +133 -0
- package/resolve-advanced/vendor/conform-qc/roles/index.js +96 -0
- package/resolve-advanced/vendor/conform-qc/synthetic/generate.js +233 -0
- package/resolve-advanced/vendor/conform-qc/test/advisory.test.js +85 -0
- package/resolve-advanced/vendor/conform-qc/test/cli.test.js +39 -0
- package/resolve-advanced/vendor/conform-qc/test/compare.test.js +152 -0
- package/resolve-advanced/vendor/conform-qc/test/conform-diff.test.js +70 -0
- package/resolve-advanced/vendor/conform-qc/test/emulate.test.js +51 -0
- package/resolve-advanced/vendor/conform-qc/test/frame-sampler.test.js +30 -0
- package/resolve-advanced/vendor/conform-qc/test/geometry.test.js +112 -0
- package/resolve-advanced/vendor/conform-qc/test/knowledge.test.js +56 -0
- package/resolve-advanced/vendor/conform-qc/test/lifecycle.test.js +110 -0
- package/resolve-advanced/vendor/conform-qc/test/local-ffmpeg-sampler.test.js +66 -0
- package/resolve-advanced/vendor/conform-qc/test/locate.test.js +63 -0
- package/resolve-advanced/vendor/conform-qc/test/media-analysis.test.js +63 -0
- package/resolve-advanced/vendor/conform-qc/test/media-index-normalized.test.js +65 -0
- package/resolve-advanced/vendor/conform-qc/test/media-index-origin.test.js +53 -0
- package/resolve-advanced/vendor/conform-qc/test/metrics-fast.test.js +91 -0
- package/resolve-advanced/vendor/conform-qc/test/oracle-reverse.test.js +86 -0
- package/resolve-advanced/vendor/conform-qc/test/oracle.test.js +136 -0
- package/resolve-advanced/vendor/conform-qc/test/p0-acceptance.test.js +60 -0
- package/resolve-advanced/vendor/conform-qc/test/p1-acceptance.test.js +75 -0
- package/resolve-advanced/vendor/conform-qc/test/p45-patch-acceptance.test.js +102 -0
- package/resolve-advanced/vendor/conform-qc/test/packaging.test.js +133 -0
- package/resolve-advanced/vendor/conform-qc/test/parse-stubs.test.js +28 -0
- package/resolve-advanced/vendor/conform-qc/test/repair-strategies.test.js +128 -0
- package/resolve-advanced/vendor/conform-qc/test/repair.test.js +84 -0
- package/resolve-advanced/vendor/conform-qc/test/report.test.js +52 -0
- package/resolve-advanced/vendor/conform-qc/test/resolve-readback.test.js +71 -0
- package/resolve-advanced/vendor/conform-qc/test/roles.test.js +107 -0
- package/resolve-advanced/vendor/conform-qc/test/runbook.test.js +30 -0
- package/resolve-advanced/vendor/conform-qc/test/scale-residual.test.js +40 -0
- package/resolve-advanced/vendor/conform-qc/test/sidecar.test.js +51 -0
- package/resolve-advanced/vendor/conform-qc/test/smoke.test.js +87 -0
- package/resolve-advanced/vendor/conform-qc/test/surgical-relink.test.js +73 -0
- package/resolve-advanced/vendor/conform-qc/test/synthetic.test.js +98 -0
- package/resolve-advanced/vendor/conform-qc/test/verify.test.js +93 -0
- package/resolve-advanced/vendor/conform-qc/test/vision-validator.test.js +43 -0
- package/resolve-advanced/vendor/conform-qc/test/workflow-driver.test.js +46 -0
- package/resolve-advanced/vendor/conform-qc/toolset/index.js +53 -0
- package/resolve-advanced/vendor/drp-format/README.md +116 -0
- package/resolve-advanced/vendor/drp-format/__tests__/_resolve-verify.js +39 -0
- package/resolve-advanced/vendor/drp-format/__tests__/add-media-clip.test.js +30 -0
- package/resolve-advanced/vendor/drp-format/__tests__/assemble-timeline.test.js +68 -0
- package/resolve-advanced/vendor/drp-format/__tests__/author-project.test.js +57 -0
- package/resolve-advanced/vendor/drp-format/__tests__/composition-text.test.js +98 -0
- package/resolve-advanced/vendor/drp-format/__tests__/diff.test.js +272 -0
- package/resolve-advanced/vendor/drp-format/__tests__/effect-filters-compressed.test.js +143 -0
- package/resolve-advanced/vendor/drp-format/__tests__/fixtures/p0-3-session30-empty-effectfilters.drp +0 -0
- package/resolve-advanced/vendor/drp-format/__tests__/fixtures/retimed-timemap-50pct.hex +1 -0
- package/resolve-advanced/vendor/drp-format/__tests__/fixtures/retimed-timemap-dynamic.hex +1 -0
- package/resolve-advanced/vendor/drp-format/__tests__/inject-grades.test.js +238 -0
- package/resolve-advanced/vendor/drp-format/__tests__/keyed-dict.test.js +85 -0
- package/resolve-advanced/vendor/drp-format/__tests__/lut-refs.test.js +119 -0
- package/resolve-advanced/vendor/drp-format/__tests__/media-blobs.test.js +25 -0
- package/resolve-advanced/vendor/drp-format/__tests__/media-timemap.test.js +119 -0
- package/resolve-advanced/vendor/drp-format/__tests__/place-fusion-title.test.js +52 -0
- package/resolve-advanced/vendor/drp-format/__tests__/place-generator.test.js +40 -0
- package/resolve-advanced/vendor/drp-format/__tests__/place-transition.test.js +48 -0
- package/resolve-advanced/vendor/drp-format/__tests__/protobuf-wire.test.js +64 -0
- package/resolve-advanced/vendor/drp-format/__tests__/relink-media.test.js +106 -0
- package/resolve-advanced/vendor/drp-format/__tests__/splice-clips.test.js +256 -0
- package/resolve-advanced/vendor/drp-format/assemble-timeline.js +65 -0
- package/resolve-advanced/vendor/drp-format/author-project.js +118 -0
- package/resolve-advanced/vendor/drp-format/composition-text.js +213 -0
- package/resolve-advanced/vendor/drp-format/curves-encoder.js +763 -0
- package/resolve-advanced/vendor/drp-format/diff.js +310 -0
- package/resolve-advanced/vendor/drp-format/drp-packager.js +201 -0
- package/resolve-advanced/vendor/drp-format/drp-validator.js +809 -0
- package/resolve-advanced/vendor/drp-format/effect-encoder.js +640 -0
- package/resolve-advanced/vendor/drp-format/extract-lut-refs.js +119 -0
- package/resolve-advanced/vendor/drp-format/grade-encoder.example.js +133 -0
- package/resolve-advanced/vendor/drp-format/grade-encoder.js +401 -0
- package/resolve-advanced/vendor/drp-format/grade-encoder.test.js +171 -0
- package/resolve-advanced/vendor/drp-format/grade-encoder.verify.js +249 -0
- package/resolve-advanced/vendor/drp-format/grade-node-extractor.js +495 -0
- package/resolve-advanced/vendor/drp-format/grade-parameter-decoder.js +774 -0
- package/resolve-advanced/vendor/drp-format/index.js +174 -0
- package/resolve-advanced/vendor/drp-format/inject-grades.js +219 -0
- package/resolve-advanced/vendor/drp-format/keyed-dict.js +227 -0
- package/resolve-advanced/vendor/drp-format/marker-encoder.js +532 -0
- package/resolve-advanced/vendor/drp-format/media-blobs.js +53 -0
- package/resolve-advanced/vendor/drp-format/media-timemap.js +164 -0
- package/resolve-advanced/vendor/drp-format/mp-folder-builder.js +293 -0
- package/resolve-advanced/vendor/drp-format/node-tree-encoder.js +1246 -0
- package/resolve-advanced/vendor/drp-format/package.json +18 -0
- package/resolve-advanced/vendor/drp-format/place-fusion-title.js +131 -0
- package/resolve-advanced/vendor/drp-format/place-generator.js +77 -0
- package/resolve-advanced/vendor/drp-format/place-transition.js +91 -0
- package/resolve-advanced/vendor/drp-format/power-window-encoder.js +776 -0
- package/resolve-advanced/vendor/drp-format/protobuf-wire.js +111 -0
- package/resolve-advanced/vendor/drp-format/qualifier-encoder.js +706 -0
- package/resolve-advanced/vendor/drp-format/relink-media.js +218 -0
- package/resolve-advanced/vendor/drp-format/rich-title-encoder.js +447 -0
- package/resolve-advanced/vendor/drp-format/seq-container-builder.js +572 -0
- package/resolve-advanced/vendor/drp-format/seq-surgery.js +155 -0
- package/resolve-advanced/vendor/drp-format/splice-clips.js +445 -0
- package/resolve-advanced/vendor/drp-format/templates/empty-project.drp +0 -0
- package/resolve-advanced/vendor/drp-format/templates/fusion-title.xml +56 -0
- package/resolve-advanced/vendor/drp-format/templates/generator-solid-color.xml +21 -0
- package/resolve-advanced/vendor/drp-format/templates/media-clip-h264.drp +0 -0
- package/resolve-advanced/vendor/drp-format/templates/transition-cross-dissolve.xml +22 -0
- package/resolve-advanced/vendor/drp-format/tool-registry.descriptor.js +80 -0
- package/resolve-advanced/vendor/drp-format/utils/safe-archive.js +54 -0
- package/resolve-advanced/vendor/drp-format/xml-builder.js +759 -0
- package/resolve-advanced/vendor/drt-format/__tests__/_resolve-verify.js +21 -0
- package/resolve-advanced/vendor/drt-format/__tests__/build.test.js +113 -0
- package/resolve-advanced/vendor/drt-format/__tests__/multi-format.test.js +93 -0
- package/resolve-advanced/vendor/drt-format/__tests__/parse-real-resolve21.test.js +51 -0
- package/resolve-advanced/vendor/drt-format/__tests__/parse.test.js +134 -0
- package/resolve-advanced/vendor/drt-format/__tests__/resolve-versions.test.js +120 -0
- package/resolve-advanced/vendor/drt-format/__tests__/schema-fingerprint.test.js +62 -0
- package/resolve-advanced/vendor/drt-format/__tests__/smoke.test.js +27 -0
- package/resolve-advanced/vendor/drt-format/__tests__/validate.test.js +109 -0
- package/resolve-advanced/vendor/drt-format/capabilities.js +69 -0
- package/resolve-advanced/vendor/drt-format/capability-domains.js +56 -0
- package/resolve-advanced/vendor/drt-format/drt-builder.js +42 -0
- package/resolve-advanced/vendor/drt-format/drt-parser.js +164 -0
- package/resolve-advanced/vendor/drt-format/drt-validator.js +98 -0
- package/resolve-advanced/vendor/drt-format/index.js +45 -0
- package/resolve-advanced/vendor/drt-format/package.json +17 -0
- package/resolve-advanced/vendor/drt-format/resolve-versions.js +153 -0
- package/resolve-advanced/vendor/drt-format/schema-fingerprint.js +74 -0
- package/resolve-advanced/vendor/drt-format/templates/drt-project-shell.xml +124 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/curves-roundtrip.test.js +148 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-face-refinement.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-filmgrain.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-glow.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-lens-flare.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-3-beauty-25.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-3-beauty-75.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p5-1-node-no-lut.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p5-1-node-with-lut.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/hsl-curves-roundtrip.test.js +117 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/lut-refs-roundtrip.test.js +112 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/matte-roundtrip.test.js +167 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/ofx-roundtrip.test.js +215 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/ofx-slugs-discovery.test.js +149 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/power-window-roundtrip.test.js +230 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/qualifier-roundtrip.test.js +226 -0
- package/resolve-advanced/vendor/drx-codec/cdl-exporter.js +470 -0
- package/resolve-advanced/vendor/drx-codec/color-nlp-parser.js +833 -0
- package/resolve-advanced/vendor/drx-codec/data/color-nlp-action-mappings.json +2232 -0
- package/resolve-advanced/vendor/drx-codec/drx-generator.js +4123 -0
- package/resolve-advanced/vendor/drx-codec/drx-merger.js +320 -0
- package/resolve-advanced/vendor/drx-codec/drx-parser.js +1808 -0
- package/resolve-advanced/vendor/drx-codec/extract-custom-curves.js +215 -0
- package/resolve-advanced/vendor/drx-codec/extract-hsl-curves.js +180 -0
- package/resolve-advanced/vendor/drx-codec/extract-lut-refs.js +158 -0
- package/resolve-advanced/vendor/drx-codec/extract-matte-finesse.js +83 -0
- package/resolve-advanced/vendor/drx-codec/extract-ofx-params.js +226 -0
- package/resolve-advanced/vendor/drx-codec/extract-power-window.js +184 -0
- package/resolve-advanced/vendor/drx-codec/extract-qualifier.js +99 -0
- package/resolve-advanced/vendor/drx-codec/index.js +109 -0
- package/resolve-advanced/vendor/drx-codec/node-layout.js +249 -0
- package/resolve-advanced/vendor/drx-codec/resolved-drx-generator.js +393 -0
- package/resolve-advanced/vendor/drx-codec/tool-resolver.js +974 -0
- package/resolve-advanced/vendor/drx-codec/training-examples.js +548 -0
- package/resolve-advanced/vendor/drx-codec/vocabulary-intents.js +539 -0
- package/resolve-advanced/vendor/drx-parameters/CALIBRATION-STATUS.md +319 -0
- package/resolve-advanced/vendor/drx-parameters/DRX-VALUE-SCALING.md +251 -0
- package/resolve-advanced/vendor/drx-parameters/calibrated-ranges.json +17737 -0
- package/resolve-advanced/vendor/drx-parameters/corrector-types.js +120 -0
- package/resolve-advanced/vendor/drx-parameters/index.js +193 -0
- package/resolve-advanced/vendor/drx-parameters/parameter-codec.js +451 -0
- package/resolve-advanced/vendor/drx-parameters/parameter-ids.js +1292 -0
- package/resolve-advanced/vendor/drx-parameters/parameter-ranges.js +570 -0
- package/resolve-advanced/vendor/drx-parameters/parameter-validator.js +392 -0
- package/resolve-advanced/vendor/drx-parameters/resolvefx-registry.json +14973 -0
- package/resolve-advanced/vendor/drx-parameters/tool-registry.descriptor.js +38 -0
- package/resolve-advanced/vendor/drx-parameters/tools/drx-analyzer.js +371 -0
- package/resolve-advanced/vendor/fairlight/index.js +833 -0
- package/resolve-advanced/vendor/fusion-codec/composition-generator.js +401 -0
- package/resolve-advanced/vendor/fusion-codec/templates/blur-region.js +103 -0
- package/resolve-advanced/vendor/fusion-codec/templates/color-correct.js +87 -0
- package/resolve-advanced/vendor/fusion-codec/templates/film-grain.js +106 -0
- package/resolve-advanced/vendor/fusion-codec/templates/lower-third.js +241 -0
- package/resolve-advanced/vendor/fusion-codec/templates/picture-in-picture.js +188 -0
- package/resolve-advanced/vendor/fusion-codec/templates/text-overlay.js +161 -0
- package/resolve-advanced/vendor/fusion-codec/templates/title-card.js +184 -0
- package/resolve-advanced/vendor/fusion-codec/templates/vignette.js +107 -0
- package/resolve-advanced/vendor/fusion-codec/templates/watermark.js +101 -0
- package/scripts/agent-rules/README.md +68 -0
- package/src/analysis_dashboard.py +233 -1
- package/src/granular/common.py +1 -1
- package/src/server.py +479 -29
- package/src/utils/api_truth.py +117 -0
- package/src/utils/cut_ir.py +1 -1
- package/src/utils/failure_tracker.py +0 -2
- package/src/utils/timeline_xml.py +405 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* media-timemap — decode/encode the per-clip MediaTimemapBA (retime / speed map).
|
|
3
|
+
*
|
|
4
|
+
* Resolve writes this blob in TWO forms:
|
|
5
|
+
*
|
|
6
|
+
* 1. IDENTITY (1× speed) — compact: [u8 0x02][ BE float64 seconds … ]
|
|
7
|
+
* The doubles are source time extents in seconds; a media clip's identity map is
|
|
8
|
+
* `[02][end,0,end',0,end]` (end == lastFrameIndex/fps). Generators/titles carry the
|
|
9
|
+
* degenerate `[02][duration]`.
|
|
10
|
+
*
|
|
11
|
+
* 2. RETIMED (non-1×) — a `Sm2TimeMap` keyed-dict:
|
|
12
|
+
* YMin/YMax : -1 (sentinels)
|
|
13
|
+
* XMax (double) : RECORD (timeline) duration in seconds
|
|
14
|
+
* LastValidYOffset : SOURCE duration in seconds
|
|
15
|
+
* KeyframesBA : protobuf curve — field 1 holds [double recordSec][double sourceSec]
|
|
16
|
+
* DbType : "Sm2TimeMap"
|
|
17
|
+
* => constant SPEED = LastValidYOffset / XMax (source/record).
|
|
18
|
+
*
|
|
19
|
+
* Verified live: a 50% clip exported XMax=305.33, LastValidYOffset=152.65 → speed 0.4999.
|
|
20
|
+
* encode(decode(x)) reproduces both forms exactly. See knowledge/blob-map.md.
|
|
21
|
+
*
|
|
22
|
+
* @module drp-format/media-timemap
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const { decodeKeyedDict, encodeKeyedDict, T_DOUBLE, T_STRING, T_BYTES } = require('./keyed-dict');
|
|
26
|
+
const { decodeProtobuf, encodeProtobuf } = require('./protobuf-wire');
|
|
27
|
+
|
|
28
|
+
const TYPE_LINEAR = 0x02;
|
|
29
|
+
|
|
30
|
+
function _isKeyedForm(b) {
|
|
31
|
+
return b.length >= 8 && b.readUInt32BE(0) === 1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Decode → for identity form { form:'identity', type, seconds }.
|
|
36
|
+
* for retimed form { form:'retimed', speed, sourceDurationSec, recordDurationSec, entries }.
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Parse the KeyframesBA protobuf → ordered keyframe points [{ recordSec, sourceSec }].
|
|
40
|
+
* KeyframesBA = { field 160: 0, field 1 (REPEATED): Keyframe{ f1: recordSec, f2: sourceSec } }
|
|
41
|
+
* (fixed64 LE doubles). The map starts at the implicit (0,0); constant speed has one keyframe,
|
|
42
|
+
* a variable-speed ramp has one keyframe per added speed point.
|
|
43
|
+
*/
|
|
44
|
+
function _decodeKeyframes(hex) {
|
|
45
|
+
if (hex == null) return [];
|
|
46
|
+
const fields = decodeProtobuf(hex);
|
|
47
|
+
return fields
|
|
48
|
+
.filter((f) => f.field === 1 && f.wire === 2)
|
|
49
|
+
.map((f) => ({ recordSec: f.value.readDoubleLE(1), sourceSec: f.value.readDoubleLE(10) }));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Per-segment speeds from the keyframe points (slope Δsource/Δrecord); starts at (0,0). */
|
|
53
|
+
function _segments(keyframes) {
|
|
54
|
+
const pts = [{ recordSec: 0, sourceSec: 0 }, ...keyframes];
|
|
55
|
+
const segs = [];
|
|
56
|
+
for (let i = 1; i < pts.length; i++) {
|
|
57
|
+
const dr = pts[i].recordSec - pts[i - 1].recordSec;
|
|
58
|
+
const ds = pts[i].sourceSec - pts[i - 1].sourceSec;
|
|
59
|
+
segs.push({ fromRecordSec: pts[i - 1].recordSec, toRecordSec: pts[i].recordSec, speed: dr ? ds / dr : 0 });
|
|
60
|
+
}
|
|
61
|
+
return segs;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function decodeTimemap(input) {
|
|
65
|
+
const b = Buffer.isBuffer(input) ? input : Buffer.from(input, 'hex');
|
|
66
|
+
if (_isKeyedForm(b)) {
|
|
67
|
+
const { entries } = decodeKeyedDict(b);
|
|
68
|
+
const get = (k) => { const e = entries.find((x) => x.key === k); return e ? e.value : undefined; };
|
|
69
|
+
const recordDurationSec = get('XMax');
|
|
70
|
+
const sourceDurationSec = get('LastValidYOffset');
|
|
71
|
+
const keyframes = _decodeKeyframes(get('KeyframesBA'));
|
|
72
|
+
const segments = _segments(keyframes);
|
|
73
|
+
// The EXACT speed lives in the keyframe ratios (source/record per segment); XMax and
|
|
74
|
+
// LastValidYOffset are frame-quantized. `speed` is the first segment's (whole clip if 1 kf);
|
|
75
|
+
// `segments` carries the full variable-speed ramp.
|
|
76
|
+
const speed = segments.length ? segments[0].speed : sourceDurationSec / recordDurationSec;
|
|
77
|
+
const variable = segments.length > 1;
|
|
78
|
+
return {
|
|
79
|
+
form: 'retimed', variable, speed, segments, keyframes,
|
|
80
|
+
sourceDurationSec, recordDurationSec, entries,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (b.length < 1 || (b.length - 1) % 8 !== 0) {
|
|
84
|
+
throw new Error(`MediaTimemapBA: unexpected length ${b.length}`);
|
|
85
|
+
}
|
|
86
|
+
const seconds = [];
|
|
87
|
+
for (let o = 1; o + 8 <= b.length; o += 8) seconds.push(b.readDoubleBE(o));
|
|
88
|
+
return { form: 'identity', type: b[0], seconds };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Encode the identity (compact) form { type, seconds } → Buffer (round-trips exactly). */
|
|
92
|
+
function encodeTimemap({ type = TYPE_LINEAR, seconds }) {
|
|
93
|
+
const b = Buffer.alloc(1 + seconds.length * 8);
|
|
94
|
+
b.writeUInt8(type, 0);
|
|
95
|
+
seconds.forEach((s, i) => b.writeDoubleBE(s, 1 + i * 8));
|
|
96
|
+
return b;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Re-encode a decoded retimed timemap ({ entries }) → Buffer (round-trips exactly). */
|
|
100
|
+
function encodeRetimedTimemap({ entries }) {
|
|
101
|
+
return encodeKeyedDict({ hdr: 1, entries });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Build the identity (1×) compact map for a clip of `frameCount` frames at `fps`.
|
|
106
|
+
* Matches the real Resolve shape `[02][end,0,end,0,end]` (end = (frameCount-1)/fps).
|
|
107
|
+
*/
|
|
108
|
+
function identityTimemap(frameCount, fps) {
|
|
109
|
+
const end = (frameCount - 1) / fps;
|
|
110
|
+
return encodeTimemap({ type: TYPE_LINEAR, seconds: [end, 0, end, 0, end] });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Encode KeyframesBA from ordered (recordSec, sourceSec) points. */
|
|
114
|
+
function _encodeKeyframes(keyframes) {
|
|
115
|
+
const msgs = keyframes.map((k) => {
|
|
116
|
+
const inner = Buffer.alloc(18);
|
|
117
|
+
inner.writeUInt8(0x09, 0); inner.writeDoubleLE(k.recordSec, 1);
|
|
118
|
+
inner.writeUInt8(0x11, 9); inner.writeDoubleLE(k.sourceSec, 10);
|
|
119
|
+
return { field: 1, wire: 2, value: inner };
|
|
120
|
+
});
|
|
121
|
+
return encodeProtobuf([{ field: 160, wire: 0, value: 0n }, ...msgs]);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Build a retimed `Sm2TimeMap` keyed-dict from explicit keyframe points
|
|
126
|
+
* `[{ recordSec, sourceSec }]` (ordered; the implicit (0,0) start is NOT included).
|
|
127
|
+
* `sourceDurationSec` = LastValidYOffset; `recordDurationSec` defaults to the last keyframe's
|
|
128
|
+
* recordSec (= XMax). This is the general (variable-speed) authoring entry point.
|
|
129
|
+
*/
|
|
130
|
+
function buildTimemap({ keyframes, sourceDurationSec, recordDurationSec, uniqueId }) {
|
|
131
|
+
if (!keyframes || !keyframes.length) throw new Error('need at least one keyframe');
|
|
132
|
+
const record = recordDurationSec == null ? keyframes[keyframes.length - 1].recordSec : recordDurationSec;
|
|
133
|
+
const entries = [
|
|
134
|
+
{ key: 'YMin', type: T_DOUBLE, subType: 0, value: -1 },
|
|
135
|
+
{ key: 'YMax', type: T_DOUBLE, subType: 0, value: -1 },
|
|
136
|
+
{ key: 'XMax', type: T_DOUBLE, subType: 0, value: record },
|
|
137
|
+
{ key: 'UniqueId', type: T_STRING, subType: 0, value: uniqueId },
|
|
138
|
+
{ key: 'LastValidYOffset', type: T_DOUBLE, subType: 0, value: sourceDurationSec },
|
|
139
|
+
{ key: 'KeyframesBA', type: T_BYTES, subType: 0, value: _encodeKeyframes(keyframes).toString('hex') },
|
|
140
|
+
{ key: 'DbType', type: T_STRING, subType: 0, value: 'Sm2TimeMap' },
|
|
141
|
+
];
|
|
142
|
+
return encodeKeyedDict({ hdr: 1, entries });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Build a constant-speed retimed map for a clip whose source runs `sourceDurationSec`, played
|
|
147
|
+
* at `speed` (0.5 = half speed → 2× longer). Single keyframe at the geometric line end.
|
|
148
|
+
*/
|
|
149
|
+
function buildConstantSpeedTimemap({ speed, sourceDurationSec, uniqueId, recordDurationSec }) {
|
|
150
|
+
if (!(speed > 0)) throw new Error('speed must be > 0');
|
|
151
|
+
// XMax is Resolve's frame-quantized record duration. Default to source/speed; pass the
|
|
152
|
+
// exact value for byte-parity with a specific Resolve export.
|
|
153
|
+
const record = recordDurationSec == null ? sourceDurationSec / speed : recordDurationSec;
|
|
154
|
+
return buildTimemap({
|
|
155
|
+
keyframes: [{ recordSec: record, sourceSec: record * speed }],
|
|
156
|
+
sourceDurationSec, recordDurationSec: record, uniqueId,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
module.exports = {
|
|
161
|
+
decodeTimemap, encodeTimemap, encodeRetimedTimemap,
|
|
162
|
+
identityTimemap, buildConstantSpeedTimemap, buildTimemap, decodeProtobuf,
|
|
163
|
+
TYPE_LINEAR,
|
|
164
|
+
};
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DaVinci Resolve MpFolder XML Builder
|
|
3
|
+
*
|
|
4
|
+
* Generates MpFolder (Media Pool) XML files for DRP packages.
|
|
5
|
+
* Defines the media pool structure with folders and clips.
|
|
6
|
+
*
|
|
7
|
+
* @module mp-folder-builder
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { generateUUID, buildXmlElement, encodeFrameRate } = require('./xml-builder');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Folder color tags supported by DaVinci Resolve
|
|
14
|
+
*/
|
|
15
|
+
const FOLDER_COLORS = {
|
|
16
|
+
NONE: 'FOLDER_COLOR_NONE',
|
|
17
|
+
BLUE: 'FOLDER_COLOR_BLUE',
|
|
18
|
+
CYAN: 'FOLDER_COLOR_CYAN',
|
|
19
|
+
GREEN: 'FOLDER_COLOR_GREEN',
|
|
20
|
+
YELLOW: 'FOLDER_COLOR_YELLOW',
|
|
21
|
+
RED: 'FOLDER_COLOR_RED',
|
|
22
|
+
PINK: 'FOLDER_COLOR_PINK',
|
|
23
|
+
PURPLE: 'FOLDER_COLOR_PURPLE',
|
|
24
|
+
ORANGE: 'FOLDER_COLOR_ORANGE',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Build a complete MpFolder XML file for DRP
|
|
29
|
+
*
|
|
30
|
+
* @param {Object} mediaPool - Media pool configuration
|
|
31
|
+
* @param {string} mediaPool.name - Root folder name (default: 'Master')
|
|
32
|
+
* @param {Array} mediaPool.clips - Root-level clips
|
|
33
|
+
* @param {Array} mediaPool.folders - Subfolders
|
|
34
|
+
* @returns {string} Complete MpFolder XML
|
|
35
|
+
*/
|
|
36
|
+
function buildMpFolderFile(mediaPool) {
|
|
37
|
+
const rootId = generateUUID();
|
|
38
|
+
const rootUniqueId = generateUUID();
|
|
39
|
+
|
|
40
|
+
// Build subfolders recursively
|
|
41
|
+
const folderElements = (mediaPool.folders || []).map((folder) =>
|
|
42
|
+
buildFolderElement(folder)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Build root-level clips
|
|
46
|
+
const clipElements = buildClipElements(mediaPool.clips || []);
|
|
47
|
+
|
|
48
|
+
const children = [
|
|
49
|
+
buildXmlElement('Name', {}, mediaPool.name || 'Master'),
|
|
50
|
+
buildXmlElement('UniqueMediaPoolItemId', {}, rootUniqueId),
|
|
51
|
+
buildXmlElement('ColorTag', {}, mediaPool.colorTag || FOLDER_COLORS.NONE),
|
|
52
|
+
buildXmlElement('Folded', {}, mediaPool.folded ? 'true' : 'false'),
|
|
53
|
+
buildXmlElement('FolderVec', {}, folderElements),
|
|
54
|
+
buildXmlElement('MediaVec', {}, clipElements),
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
const mpFolder = buildXmlElement('Sm2MpFolder', { DbId: rootId }, children);
|
|
58
|
+
|
|
59
|
+
return `<?xml version="1.0" encoding="UTF-8"?>\n${mpFolder}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Build a folder element with its contents
|
|
64
|
+
*
|
|
65
|
+
* @param {Object} folder - Folder configuration
|
|
66
|
+
* @returns {string} Folder XML element
|
|
67
|
+
*/
|
|
68
|
+
function buildFolderElement(folder) {
|
|
69
|
+
const folderId = generateUUID();
|
|
70
|
+
const uniqueId = generateUUID();
|
|
71
|
+
|
|
72
|
+
// Build subfolders recursively
|
|
73
|
+
const subfolderElements = (folder.subfolders || folder.folders || []).map((sub) =>
|
|
74
|
+
buildFolderElement(sub)
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Build clips in this folder
|
|
78
|
+
const clipElements = buildClipElements(folder.clips || []);
|
|
79
|
+
|
|
80
|
+
const children = [
|
|
81
|
+
buildXmlElement('Name', {}, folder.name || 'Folder'),
|
|
82
|
+
buildXmlElement('UniqueMediaPoolItemId', {}, uniqueId),
|
|
83
|
+
buildXmlElement('ColorTag', {}, folder.colorTag || FOLDER_COLORS.NONE),
|
|
84
|
+
buildXmlElement('Folded', {}, folder.folded ? 'true' : 'false'),
|
|
85
|
+
buildXmlElement('FolderVec', {}, subfolderElements),
|
|
86
|
+
buildXmlElement('MediaVec', {}, clipElements),
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
return buildXmlElement('Sm2MpFolder', { DbId: folderId }, children);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Build clip elements from array
|
|
94
|
+
*/
|
|
95
|
+
function buildClipElements(clips) {
|
|
96
|
+
return clips.map((clip) => {
|
|
97
|
+
if (clip.type === 'audio' || clip.trackType === 'audio') {
|
|
98
|
+
return buildAudioClipElement(clip);
|
|
99
|
+
}
|
|
100
|
+
return buildVideoClipElement(clip);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Build a video clip element
|
|
106
|
+
*
|
|
107
|
+
* @param {Object} clip - Clip data
|
|
108
|
+
* @returns {string} Video clip XML element
|
|
109
|
+
*/
|
|
110
|
+
function buildVideoClipElement(clip) {
|
|
111
|
+
const clipId = generateUUID();
|
|
112
|
+
const uniqueId = generateUUID();
|
|
113
|
+
|
|
114
|
+
const frameRateHex = encodeFrameRate(clip.frameRate || 24);
|
|
115
|
+
|
|
116
|
+
const children = [
|
|
117
|
+
buildXmlElement('Name', {}, clip.name || clip.clipName || 'Clip'),
|
|
118
|
+
buildXmlElement('MediaFilePath', {}, clip.filePath || clip.sourceFile || ''),
|
|
119
|
+
buildXmlElement('UniqueMediaPoolItemId', {}, uniqueId),
|
|
120
|
+
buildXmlElement('MediaFrameRate', {}, frameRateHex),
|
|
121
|
+
buildXmlElement('FieldsBlob', {}, '0000000000000000'),
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
// Add optional fields
|
|
125
|
+
if (clip.reelNumber || clip.reelName) {
|
|
126
|
+
children.push(buildXmlElement('MediaReelNumber', {}, clip.reelNumber || clip.reelName));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (clip.duration || clip.durationFrames) {
|
|
130
|
+
children.push(buildXmlElement('Duration', {}, String(clip.duration || clip.durationFrames)));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (clip.startTimecode) {
|
|
134
|
+
children.push(buildXmlElement('StartTC', {}, clip.startTimecode));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Add resolution if available
|
|
138
|
+
if (clip.resolution || (clip.width && clip.height)) {
|
|
139
|
+
const [w, h] = clip.resolution
|
|
140
|
+
? clip.resolution.split('x').map(Number)
|
|
141
|
+
: [clip.width, clip.height];
|
|
142
|
+
children.push(buildXmlElement('MediaWidth', {}, String(w || 1920)));
|
|
143
|
+
children.push(buildXmlElement('MediaHeight', {}, String(h || 1080)));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return buildXmlElement('Sm2MpVideoClip', { DbId: clipId }, children);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Build an audio clip element
|
|
151
|
+
*
|
|
152
|
+
* @param {Object} clip - Clip data
|
|
153
|
+
* @returns {string} Audio clip XML element
|
|
154
|
+
*/
|
|
155
|
+
function buildAudioClipElement(clip) {
|
|
156
|
+
const clipId = generateUUID();
|
|
157
|
+
const uniqueId = generateUUID();
|
|
158
|
+
|
|
159
|
+
const children = [
|
|
160
|
+
buildXmlElement('Name', {}, clip.name || clip.clipName || 'Audio Clip'),
|
|
161
|
+
buildXmlElement('MediaFilePath', {}, clip.filePath || clip.sourceFile || ''),
|
|
162
|
+
buildXmlElement('UniqueMediaPoolItemId', {}, uniqueId),
|
|
163
|
+
buildXmlElement('FieldsBlob', {}, '0000000000000000'),
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
// Add audio-specific fields
|
|
167
|
+
if (clip.sampleRate) {
|
|
168
|
+
children.push(buildXmlElement('SampleRate', {}, String(clip.sampleRate)));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (clip.channels || clip.audioChannels) {
|
|
172
|
+
children.push(buildXmlElement('Channels', {}, String(clip.channels || clip.audioChannels)));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (clip.duration) {
|
|
176
|
+
children.push(buildXmlElement('Duration', {}, String(clip.duration)));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return buildXmlElement('Sm2MpAudioClip', { DbId: clipId }, children);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Build media pool from document line items
|
|
184
|
+
*
|
|
185
|
+
* @param {Array} lineItems - Document line items
|
|
186
|
+
* @param {Object} options - Options
|
|
187
|
+
* @returns {Object} Media pool configuration
|
|
188
|
+
*/
|
|
189
|
+
function buildMediaPoolFromLineItems(lineItems, options = {}) {
|
|
190
|
+
const { groupByFolder = true, groupByReel = false } = options;
|
|
191
|
+
|
|
192
|
+
// Extract unique clips (by source file path)
|
|
193
|
+
const uniqueClips = new Map();
|
|
194
|
+
|
|
195
|
+
for (const item of lineItems) {
|
|
196
|
+
if (!item.sourceFile) continue;
|
|
197
|
+
|
|
198
|
+
const key = item.sourceFile;
|
|
199
|
+
if (!uniqueClips.has(key)) {
|
|
200
|
+
uniqueClips.set(key, {
|
|
201
|
+
name: item.clipName || key.split('/').pop(),
|
|
202
|
+
filePath: item.sourceFile,
|
|
203
|
+
type: item.trackType || 'video',
|
|
204
|
+
frameRate: item.frameRate || 24,
|
|
205
|
+
resolution: item.resolution,
|
|
206
|
+
reelName: item.reelName,
|
|
207
|
+
codec: item.codec,
|
|
208
|
+
colorSpace: item.colorSpace,
|
|
209
|
+
folder: extractFolderFromPath(item.sourceFile),
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const clips = Array.from(uniqueClips.values());
|
|
215
|
+
|
|
216
|
+
// Group clips by folder if requested
|
|
217
|
+
if (groupByFolder) {
|
|
218
|
+
const folderMap = new Map();
|
|
219
|
+
|
|
220
|
+
for (const clip of clips) {
|
|
221
|
+
const folder = clip.folder || 'Unsorted';
|
|
222
|
+
if (!folderMap.has(folder)) {
|
|
223
|
+
folderMap.set(folder, []);
|
|
224
|
+
}
|
|
225
|
+
folderMap.get(folder).push(clip);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const folders = Array.from(folderMap.entries()).map(([name, folderClips]) => ({
|
|
229
|
+
name,
|
|
230
|
+
clips: folderClips,
|
|
231
|
+
}));
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
name: 'Master',
|
|
235
|
+
folders,
|
|
236
|
+
clips: [], // Root clips go in folders
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Group by reel if requested
|
|
241
|
+
if (groupByReel) {
|
|
242
|
+
const reelMap = new Map();
|
|
243
|
+
|
|
244
|
+
for (const clip of clips) {
|
|
245
|
+
const reel = clip.reelName || 'Unidentified';
|
|
246
|
+
if (!reelMap.has(reel)) {
|
|
247
|
+
reelMap.set(reel, []);
|
|
248
|
+
}
|
|
249
|
+
reelMap.get(reel).push(clip);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const folders = Array.from(reelMap.entries()).map(([name, reelClips]) => ({
|
|
253
|
+
name,
|
|
254
|
+
clips: reelClips,
|
|
255
|
+
}));
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
name: 'Master',
|
|
259
|
+
folders,
|
|
260
|
+
clips: [],
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// No grouping - all clips at root
|
|
265
|
+
return {
|
|
266
|
+
name: 'Master',
|
|
267
|
+
folders: [],
|
|
268
|
+
clips,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Extract folder name from file path
|
|
274
|
+
*/
|
|
275
|
+
function extractFolderFromPath(filePath) {
|
|
276
|
+
if (!filePath) return 'Unsorted';
|
|
277
|
+
|
|
278
|
+
const parts = filePath.split('/');
|
|
279
|
+
if (parts.length < 2) return 'Unsorted';
|
|
280
|
+
|
|
281
|
+
// Return parent folder name
|
|
282
|
+
return parts[parts.length - 2] || 'Unsorted';
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
module.exports = {
|
|
286
|
+
FOLDER_COLORS,
|
|
287
|
+
buildMpFolderFile,
|
|
288
|
+
buildFolderElement,
|
|
289
|
+
buildVideoClipElement,
|
|
290
|
+
buildAudioClipElement,
|
|
291
|
+
buildMediaPoolFromLineItems,
|
|
292
|
+
extractFolderFromPath,
|
|
293
|
+
};
|