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,532 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DaVinci Resolve Timeline Marker Encoder/Decoder
|
|
3
|
+
*
|
|
4
|
+
* Encodes and decodes timeline markers into DaVinci Resolve's
|
|
5
|
+
* compressed protobuf format stored in Sm2SequenceLockableBlob.FieldsBlob.
|
|
6
|
+
*
|
|
7
|
+
* Format Overview:
|
|
8
|
+
* - FieldsBlob header (Big-Endian): version, field count, "BlobData" field
|
|
9
|
+
* - ZSTD compressed protobuf (magic: 0x28b52ffd)
|
|
10
|
+
* - Nested protobuf with frame, color, name, ref_id, description
|
|
11
|
+
*
|
|
12
|
+
* @module marker-encoder
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const zlib = require('zlib');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* DaVinci Resolve marker color codes
|
|
19
|
+
* Colors are represented as bit positions, not sequential values
|
|
20
|
+
*/
|
|
21
|
+
const MARKER_COLORS = {
|
|
22
|
+
BLUE: 2, // 0x00002 - Default marker color
|
|
23
|
+
YELLOW: 8, // 0x00008
|
|
24
|
+
RED: 32, // 0x00020
|
|
25
|
+
PURPLE: 131072, // 0x20000 (Lavender)
|
|
26
|
+
// Additional colors to be reverse-engineered
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Encode a positive integer as a protobuf varint
|
|
31
|
+
* @param {number} value - Non-negative integer to encode
|
|
32
|
+
* @returns {Buffer} Encoded varint bytes
|
|
33
|
+
*/
|
|
34
|
+
function encodeVarint(value) {
|
|
35
|
+
const bytes = [];
|
|
36
|
+
let remaining = value;
|
|
37
|
+
|
|
38
|
+
while (remaining > 0x7f) {
|
|
39
|
+
bytes.push((remaining & 0x7f) | 0x80);
|
|
40
|
+
remaining = Math.floor(remaining / 128);
|
|
41
|
+
}
|
|
42
|
+
bytes.push(remaining & 0x7f);
|
|
43
|
+
|
|
44
|
+
return Buffer.from(bytes);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Decode a varint from buffer
|
|
49
|
+
* @param {Buffer} data - Buffer containing varint
|
|
50
|
+
* @param {number} offset - Start offset
|
|
51
|
+
* @returns {{value: number, bytesRead: number}} Decoded value and bytes consumed
|
|
52
|
+
*/
|
|
53
|
+
function decodeVarint(data, offset = 0) {
|
|
54
|
+
let value = 0;
|
|
55
|
+
let shift = 0;
|
|
56
|
+
let bytesRead = 0;
|
|
57
|
+
|
|
58
|
+
while (offset + bytesRead < data.length) {
|
|
59
|
+
const byte = data[offset + bytesRead];
|
|
60
|
+
value |= (byte & 0x7f) << shift;
|
|
61
|
+
bytesRead++;
|
|
62
|
+
|
|
63
|
+
if ((byte & 0x80) === 0) {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
shift += 7;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return { value, bytesRead };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Encode a protobuf field tag
|
|
74
|
+
* @param {number} fieldNumber - Field number
|
|
75
|
+
* @param {number} wireType - Wire type (0=varint, 2=length-delimited)
|
|
76
|
+
* @returns {Buffer} Encoded tag
|
|
77
|
+
*/
|
|
78
|
+
function encodeTag(fieldNumber, wireType) {
|
|
79
|
+
const tag = (fieldNumber << 3) | wireType;
|
|
80
|
+
return encodeVarint(tag);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Encode a string as a length-delimited protobuf field
|
|
85
|
+
* @param {number} fieldNumber - Field number
|
|
86
|
+
* @param {string} value - String value
|
|
87
|
+
* @returns {Buffer} Encoded field
|
|
88
|
+
*/
|
|
89
|
+
function encodeString(fieldNumber, value) {
|
|
90
|
+
const tag = encodeTag(fieldNumber, 2);
|
|
91
|
+
const strBytes = Buffer.from(value, 'utf-8');
|
|
92
|
+
const length = encodeVarint(strBytes.length);
|
|
93
|
+
return Buffer.concat([tag, length, strBytes]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Encode a varint field
|
|
98
|
+
* @param {number} fieldNumber - Field number
|
|
99
|
+
* @param {number} value - Integer value
|
|
100
|
+
* @returns {Buffer} Encoded field
|
|
101
|
+
*/
|
|
102
|
+
function encodeVarintField(fieldNumber, value) {
|
|
103
|
+
const tag = encodeTag(fieldNumber, 0);
|
|
104
|
+
const valueBytes = encodeVarint(value);
|
|
105
|
+
return Buffer.concat([tag, valueBytes]);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Encode a length-delimited bytes field
|
|
110
|
+
* @param {number} fieldNumber - Field number
|
|
111
|
+
* @param {Buffer} value - Bytes value
|
|
112
|
+
* @returns {Buffer} Encoded field
|
|
113
|
+
*/
|
|
114
|
+
function encodeBytesField(fieldNumber, value) {
|
|
115
|
+
const tag = encodeTag(fieldNumber, 2);
|
|
116
|
+
const length = encodeVarint(value.length);
|
|
117
|
+
return Buffer.concat([tag, length, value]);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Encode the innermost marker content
|
|
122
|
+
* @param {Object} marker - Marker data
|
|
123
|
+
* @param {number} marker.color - Color code
|
|
124
|
+
* @param {string} [marker.name=''] - Marker name
|
|
125
|
+
* @param {string} marker.refId - Reference ID
|
|
126
|
+
* @param {string} marker.note - Marker description/note
|
|
127
|
+
* @returns {Buffer} Encoded content
|
|
128
|
+
*/
|
|
129
|
+
function encodeMarkerContent(marker) {
|
|
130
|
+
const parts = [];
|
|
131
|
+
|
|
132
|
+
// Field 1 (varint): color code
|
|
133
|
+
parts.push(encodeVarintField(1, marker.color || MARKER_COLORS.BLUE));
|
|
134
|
+
|
|
135
|
+
// Field 3 (string): name (usually empty)
|
|
136
|
+
parts.push(encodeString(3, marker.name || ''));
|
|
137
|
+
|
|
138
|
+
// Field 3 (string): reference ID
|
|
139
|
+
parts.push(encodeString(3, marker.refId || ''));
|
|
140
|
+
|
|
141
|
+
// Field 3 (string): description/note
|
|
142
|
+
parts.push(encodeString(3, marker.note || ''));
|
|
143
|
+
|
|
144
|
+
return Buffer.concat(parts);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Encode inner protobuf wrapper for marker data
|
|
149
|
+
* @param {Object} marker - Marker data
|
|
150
|
+
* @returns {Buffer} Encoded inner protobuf
|
|
151
|
+
*/
|
|
152
|
+
function encodeMarkerInner(marker) {
|
|
153
|
+
const content = encodeMarkerContent(marker);
|
|
154
|
+
// Wrap content in Field 1 (nested message)
|
|
155
|
+
return encodeBytesField(1, content);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Encode complete marker data with 8-byte header
|
|
160
|
+
* @param {Object} marker - Marker data
|
|
161
|
+
* @returns {Buffer} Encoded marker data
|
|
162
|
+
*/
|
|
163
|
+
function encodeMarkerData(marker) {
|
|
164
|
+
const inner = encodeMarkerInner(marker);
|
|
165
|
+
|
|
166
|
+
// 8-byte header (Big-Endian):
|
|
167
|
+
// - 4 bytes: Type = 2
|
|
168
|
+
// - 4 bytes: Inner protobuf length
|
|
169
|
+
const header = Buffer.alloc(8);
|
|
170
|
+
header.writeUInt32BE(2, 0);
|
|
171
|
+
header.writeUInt32BE(inner.length, 4);
|
|
172
|
+
|
|
173
|
+
return Buffer.concat([header, inner]);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Encode a complete marker entry
|
|
178
|
+
* @param {Object} marker - Marker data
|
|
179
|
+
* @param {number} marker.frame - Frame number
|
|
180
|
+
* @param {number} marker.color - Color code
|
|
181
|
+
* @param {string} marker.refId - Reference ID
|
|
182
|
+
* @param {string} marker.note - Description
|
|
183
|
+
* @returns {Buffer} Encoded marker entry
|
|
184
|
+
*/
|
|
185
|
+
function encodeMarkerEntry(marker) {
|
|
186
|
+
const parts = [];
|
|
187
|
+
|
|
188
|
+
// Field 1 (varint): frame number
|
|
189
|
+
parts.push(encodeVarintField(1, marker.frame));
|
|
190
|
+
|
|
191
|
+
// Field 2 (bytes): marker data
|
|
192
|
+
const markerData = encodeMarkerData(marker);
|
|
193
|
+
parts.push(encodeBytesField(2, markerData));
|
|
194
|
+
|
|
195
|
+
return Buffer.concat(parts);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Encode all markers into container
|
|
200
|
+
* @param {Object[]} markers - Array of marker objects
|
|
201
|
+
* @returns {Buffer} Encoded container
|
|
202
|
+
*/
|
|
203
|
+
function encodeMarkerContainer(markers) {
|
|
204
|
+
const parts = [];
|
|
205
|
+
|
|
206
|
+
for (const marker of markers) {
|
|
207
|
+
const entry = encodeMarkerEntry(marker);
|
|
208
|
+
// Each entry wrapped in Field 1 (repeated)
|
|
209
|
+
parts.push(encodeBytesField(1, entry));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return Buffer.concat(parts);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Encode markers to complete protobuf
|
|
217
|
+
* @param {Object[]} markers - Array of marker objects
|
|
218
|
+
* @returns {Buffer} Encoded protobuf
|
|
219
|
+
*/
|
|
220
|
+
function encodeMarkersProtobuf(markers) {
|
|
221
|
+
const container = encodeMarkerContainer(markers);
|
|
222
|
+
// Wrap in Field 2
|
|
223
|
+
return encodeBytesField(2, container);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Compress markers protobuf with ZSTD
|
|
228
|
+
* Note: Node.js doesn't have native ZSTD, uses zlib deflate as fallback
|
|
229
|
+
* For production, use 'zstd-codec' or 'node-zstandard' npm package
|
|
230
|
+
*
|
|
231
|
+
* @param {Object[]} markers - Array of marker objects
|
|
232
|
+
* @returns {Buffer} Compressed data
|
|
233
|
+
*/
|
|
234
|
+
function compressMarkers(markers) {
|
|
235
|
+
const protobuf = encodeMarkersProtobuf(markers);
|
|
236
|
+
|
|
237
|
+
// For full DRP compatibility, use ZSTD compression
|
|
238
|
+
// This requires installing: npm install @pxtrn/zstd or similar
|
|
239
|
+
// For now, return uncompressed with a note
|
|
240
|
+
console.warn('Note: For full DRP compatibility, use ZSTD compression');
|
|
241
|
+
|
|
242
|
+
// Return protobuf as-is (would need ZSTD for actual DRP files)
|
|
243
|
+
return protobuf;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Decode markers from compressed protobuf
|
|
248
|
+
* @param {Buffer} compressed - ZSTD compressed data
|
|
249
|
+
* @returns {Object[]} Array of decoded markers
|
|
250
|
+
*/
|
|
251
|
+
function decodeMarkers(compressed) {
|
|
252
|
+
// For ZSTD decompression, use 'zstd-codec' npm package
|
|
253
|
+
// This is a simplified implementation assuming uncompressed data
|
|
254
|
+
const protobuf = compressed;
|
|
255
|
+
|
|
256
|
+
const markers = [];
|
|
257
|
+
let offset = 0;
|
|
258
|
+
|
|
259
|
+
// Skip Field 2 container tag
|
|
260
|
+
const { bytesRead: tagBytes } = decodeVarint(protobuf, 0);
|
|
261
|
+
offset = tagBytes;
|
|
262
|
+
const { value: containerLen, bytesRead: lenBytes } = decodeVarint(protobuf, offset);
|
|
263
|
+
offset += lenBytes;
|
|
264
|
+
|
|
265
|
+
const container = protobuf.slice(offset, offset + containerLen);
|
|
266
|
+
|
|
267
|
+
// Parse each marker entry
|
|
268
|
+
let containerOffset = 0;
|
|
269
|
+
while (containerOffset < container.length) {
|
|
270
|
+
const tag = container[containerOffset];
|
|
271
|
+
if ((tag & 0x7) !== 2) break;
|
|
272
|
+
|
|
273
|
+
const { value: entryLen, bytesRead } = decodeVarint(container, containerOffset + 1);
|
|
274
|
+
containerOffset += 1 + bytesRead;
|
|
275
|
+
|
|
276
|
+
const entry = container.slice(containerOffset, containerOffset + entryLen);
|
|
277
|
+
containerOffset += entryLen;
|
|
278
|
+
|
|
279
|
+
const marker = parseMarkerEntry(entry);
|
|
280
|
+
markers.push(marker);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return markers;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Parse a single marker entry
|
|
288
|
+
* @param {Buffer} entry - Marker entry bytes
|
|
289
|
+
* @returns {Object} Parsed marker
|
|
290
|
+
*/
|
|
291
|
+
function parseMarkerEntry(entry) {
|
|
292
|
+
const marker = {
|
|
293
|
+
frame: 0,
|
|
294
|
+
color: MARKER_COLORS.BLUE,
|
|
295
|
+
name: '',
|
|
296
|
+
refId: '',
|
|
297
|
+
note: '',
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
let offset = 0;
|
|
301
|
+
while (offset < entry.length) {
|
|
302
|
+
const tag = entry[offset];
|
|
303
|
+
const fieldNum = tag >> 3;
|
|
304
|
+
const wireType = tag & 0x7;
|
|
305
|
+
offset++;
|
|
306
|
+
|
|
307
|
+
if (wireType === 0) {
|
|
308
|
+
// Varint
|
|
309
|
+
const { value, bytesRead } = decodeVarint(entry, offset);
|
|
310
|
+
offset += bytesRead;
|
|
311
|
+
if (fieldNum === 1) {
|
|
312
|
+
marker.frame = value;
|
|
313
|
+
}
|
|
314
|
+
} else if (wireType === 2) {
|
|
315
|
+
// Length-delimited
|
|
316
|
+
const { value: len, bytesRead } = decodeVarint(entry, offset);
|
|
317
|
+
offset += bytesRead;
|
|
318
|
+
const data = entry.slice(offset, offset + len);
|
|
319
|
+
offset += len;
|
|
320
|
+
|
|
321
|
+
if (fieldNum === 2 && data.length > 8) {
|
|
322
|
+
// Skip 8-byte header, parse inner protobuf
|
|
323
|
+
const inner = data.slice(8);
|
|
324
|
+
parseMarkerInner(inner, marker);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return marker;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Parse inner marker protobuf
|
|
334
|
+
* @param {Buffer} inner - Inner protobuf bytes
|
|
335
|
+
* @param {Object} marker - Marker object to populate
|
|
336
|
+
*/
|
|
337
|
+
function parseMarkerInner(inner, marker) {
|
|
338
|
+
let offset = 0;
|
|
339
|
+
while (offset < inner.length) {
|
|
340
|
+
const tag = inner[offset];
|
|
341
|
+
const fieldNum = tag >> 3;
|
|
342
|
+
const wireType = tag & 0x7;
|
|
343
|
+
offset++;
|
|
344
|
+
|
|
345
|
+
if (wireType === 2) {
|
|
346
|
+
const { value: len, bytesRead } = decodeVarint(inner, offset);
|
|
347
|
+
offset += bytesRead;
|
|
348
|
+
const content = inner.slice(offset, offset + len);
|
|
349
|
+
offset += len;
|
|
350
|
+
|
|
351
|
+
// Parse content
|
|
352
|
+
parseMarkerContent(content, marker);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Parse marker content fields
|
|
359
|
+
* @param {Buffer} content - Content bytes
|
|
360
|
+
* @param {Object} marker - Marker object to populate
|
|
361
|
+
*/
|
|
362
|
+
function parseMarkerContent(content, marker) {
|
|
363
|
+
let offset = 0;
|
|
364
|
+
let stringIndex = 0;
|
|
365
|
+
|
|
366
|
+
while (offset < content.length) {
|
|
367
|
+
const tag = content[offset];
|
|
368
|
+
const fieldNum = tag >> 3;
|
|
369
|
+
const wireType = tag & 0x7;
|
|
370
|
+
offset++;
|
|
371
|
+
|
|
372
|
+
if (wireType === 0) {
|
|
373
|
+
// Varint
|
|
374
|
+
const { value, bytesRead } = decodeVarint(content, offset);
|
|
375
|
+
offset += bytesRead;
|
|
376
|
+
marker.color = value;
|
|
377
|
+
} else if (wireType === 2) {
|
|
378
|
+
// String
|
|
379
|
+
const { value: len, bytesRead } = decodeVarint(content, offset);
|
|
380
|
+
offset += bytesRead;
|
|
381
|
+
const str = content.slice(offset, offset + len).toString('utf-8');
|
|
382
|
+
offset += len;
|
|
383
|
+
|
|
384
|
+
if (stringIndex === 0) {
|
|
385
|
+
marker.name = str;
|
|
386
|
+
} else if (stringIndex === 1) {
|
|
387
|
+
marker.refId = str;
|
|
388
|
+
} else if (stringIndex === 2) {
|
|
389
|
+
marker.note = str;
|
|
390
|
+
}
|
|
391
|
+
stringIndex++;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Create FieldsBlob header for markers
|
|
398
|
+
* @param {Buffer} compressedData - ZSTD compressed protobuf
|
|
399
|
+
* @returns {Buffer} Complete FieldsBlob with header
|
|
400
|
+
*/
|
|
401
|
+
function createFieldsBlob(compressedData) {
|
|
402
|
+
const parts = [];
|
|
403
|
+
|
|
404
|
+
// Version (4 bytes BE)
|
|
405
|
+
const version = Buffer.alloc(4);
|
|
406
|
+
version.writeUInt32BE(1, 0);
|
|
407
|
+
parts.push(version);
|
|
408
|
+
|
|
409
|
+
// Field count (4 bytes BE)
|
|
410
|
+
const fieldCount = Buffer.alloc(4);
|
|
411
|
+
fieldCount.writeUInt32BE(1, 0);
|
|
412
|
+
parts.push(fieldCount);
|
|
413
|
+
|
|
414
|
+
// Field name: "BlobData" (UTF-16BE)
|
|
415
|
+
const fieldName = Buffer.from('BlobData', 'utf16le').swap16();
|
|
416
|
+
const nameLen = Buffer.alloc(4);
|
|
417
|
+
nameLen.writeUInt32BE(fieldName.length, 0);
|
|
418
|
+
parts.push(nameLen);
|
|
419
|
+
parts.push(fieldName);
|
|
420
|
+
|
|
421
|
+
// Data length (12 bytes for BlobData metadata)
|
|
422
|
+
const dataLen = Buffer.alloc(4);
|
|
423
|
+
dataLen.writeUInt32BE(12, 0);
|
|
424
|
+
parts.push(dataLen);
|
|
425
|
+
|
|
426
|
+
// BlobData value (12 bytes metadata)
|
|
427
|
+
const blobDataValue = Buffer.alloc(12);
|
|
428
|
+
blobDataValue.writeUInt32BE(2, 0); // Type
|
|
429
|
+
// Remaining bytes can be calculated based on compressed size
|
|
430
|
+
parts.push(blobDataValue);
|
|
431
|
+
|
|
432
|
+
// Magic prefix before ZSTD
|
|
433
|
+
parts.push(Buffer.from([0xad, 0x81]));
|
|
434
|
+
|
|
435
|
+
// Compressed data
|
|
436
|
+
parts.push(compressedData);
|
|
437
|
+
|
|
438
|
+
return Buffer.concat(parts);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Convert timecode string to frame number
|
|
443
|
+
* @param {string} timecode - Timecode in HH:MM:SS:FF format
|
|
444
|
+
* @param {number} frameRate - Frame rate (default 23.976)
|
|
445
|
+
* @returns {number} Frame number
|
|
446
|
+
*/
|
|
447
|
+
function timecodeToFrame(timecode, frameRate = 23.976) {
|
|
448
|
+
const parts = timecode.split(':').map(Number);
|
|
449
|
+
if (parts.length !== 4) {
|
|
450
|
+
throw new Error('Invalid timecode format. Use HH:MM:SS:FF');
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
const [hours, minutes, seconds, frames] = parts;
|
|
454
|
+
const totalSeconds = hours * 3600 + minutes * 60 + seconds;
|
|
455
|
+
return Math.round(totalSeconds * frameRate) + frames;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Convert frame number to timecode string
|
|
460
|
+
* @param {number} frame - Frame number
|
|
461
|
+
* @param {number} frameRate - Frame rate (default 23.976)
|
|
462
|
+
* @returns {string} Timecode in HH:MM:SS:FF format
|
|
463
|
+
*/
|
|
464
|
+
function frameToTimecode(frame, frameRate = 23.976) {
|
|
465
|
+
const totalSeconds = frame / frameRate;
|
|
466
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
467
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
468
|
+
const seconds = Math.floor(totalSeconds % 60);
|
|
469
|
+
const frames = Math.round((totalSeconds % 1) * frameRate);
|
|
470
|
+
|
|
471
|
+
return [hours, minutes, seconds, frames]
|
|
472
|
+
.map((v) => v.toString().padStart(2, '0'))
|
|
473
|
+
.join(':');
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Create a marker object with default values
|
|
478
|
+
* @param {Object} options - Marker options
|
|
479
|
+
* @param {number|string} options.position - Frame number or timecode string
|
|
480
|
+
* @param {string} [options.note=''] - Marker description
|
|
481
|
+
* @param {string} [options.refId=''] - Reference ID
|
|
482
|
+
* @param {number|string} [options.color='blue'] - Color code or name
|
|
483
|
+
* @param {string} [options.name=''] - Marker name
|
|
484
|
+
* @param {number} [options.frameRate=23.976] - Frame rate for timecode conversion
|
|
485
|
+
* @returns {Object} Marker object ready for encoding
|
|
486
|
+
*/
|
|
487
|
+
function createMarker(options) {
|
|
488
|
+
let frame = options.position;
|
|
489
|
+
if (typeof frame === 'string') {
|
|
490
|
+
frame = timecodeToFrame(frame, options.frameRate || 23.976);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
let color = options.color || MARKER_COLORS.BLUE;
|
|
494
|
+
if (typeof color === 'string') {
|
|
495
|
+
const colorName = color.toUpperCase();
|
|
496
|
+
color = MARKER_COLORS[colorName] || MARKER_COLORS.BLUE;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return {
|
|
500
|
+
frame,
|
|
501
|
+
color,
|
|
502
|
+
name: options.name || '',
|
|
503
|
+
refId: options.refId || '',
|
|
504
|
+
note: options.note || '',
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
module.exports = {
|
|
509
|
+
// Main encoding/decoding functions
|
|
510
|
+
encodeMarkersProtobuf,
|
|
511
|
+
decodeMarkers,
|
|
512
|
+
compressMarkers,
|
|
513
|
+
createFieldsBlob,
|
|
514
|
+
|
|
515
|
+
// Marker creation helpers
|
|
516
|
+
createMarker,
|
|
517
|
+
timecodeToFrame,
|
|
518
|
+
frameToTimecode,
|
|
519
|
+
|
|
520
|
+
// Low-level utilities
|
|
521
|
+
encodeVarint,
|
|
522
|
+
decodeVarint,
|
|
523
|
+
encodeTag,
|
|
524
|
+
encodeString,
|
|
525
|
+
encodeVarintField,
|
|
526
|
+
encodeBytesField,
|
|
527
|
+
encodeMarkerEntry,
|
|
528
|
+
parseMarkerEntry,
|
|
529
|
+
|
|
530
|
+
// Constants
|
|
531
|
+
MARKER_COLORS,
|
|
532
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* media-blobs — decode/encode the simple fixed-size 16-byte Media Pool / timeline metadata blobs.
|
|
3
|
+
* Mapped + verified against real Resolve 21 exports (see knowledge/blob-map.md).
|
|
4
|
+
*
|
|
5
|
+
* Resolution = [u32 0][u32 width][u32 0][u32 height] (big-endian)
|
|
6
|
+
* FrameRate = [double fps][double 0] (little-endian) — timeline fps
|
|
7
|
+
* MediaFrameRate = [double fps][double 0] (little-endian) — clip source fps
|
|
8
|
+
* MediaExtents = [double startSeconds][double durationSeconds] (little-endian)
|
|
9
|
+
*
|
|
10
|
+
* @module drp-format/media-blobs
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
function decodeResolutionBlob(hex) {
|
|
14
|
+
const b = Buffer.from(hex, 'hex');
|
|
15
|
+
if (b.length !== 16) return null;
|
|
16
|
+
return { width: b.readUInt32BE(4), height: b.readUInt32BE(12) };
|
|
17
|
+
}
|
|
18
|
+
function encodeResolutionBlob({ width, height }) {
|
|
19
|
+
const b = Buffer.alloc(16);
|
|
20
|
+
b.writeUInt32BE(width >>> 0, 4);
|
|
21
|
+
b.writeUInt32BE(height >>> 0, 12);
|
|
22
|
+
return b.toString('hex');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// FrameRate / MediaFrameRate share the same [double fps][double 0] shape.
|
|
26
|
+
function decodeRateBlob(hex) {
|
|
27
|
+
const b = Buffer.from(hex, 'hex');
|
|
28
|
+
if (b.length !== 16) return null;
|
|
29
|
+
return b.readDoubleLE(0);
|
|
30
|
+
}
|
|
31
|
+
function encodeRateBlob(fps) {
|
|
32
|
+
const b = Buffer.alloc(16);
|
|
33
|
+
b.writeDoubleLE(fps, 0);
|
|
34
|
+
return b.toString('hex');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function decodeMediaExtentsBlob(hex) {
|
|
38
|
+
const b = Buffer.from(hex, 'hex');
|
|
39
|
+
if (b.length !== 16) return null;
|
|
40
|
+
return { startSeconds: b.readDoubleLE(0), durationSeconds: b.readDoubleLE(8) };
|
|
41
|
+
}
|
|
42
|
+
function encodeMediaExtentsBlob({ startSeconds, durationSeconds }) {
|
|
43
|
+
const b = Buffer.alloc(16);
|
|
44
|
+
b.writeDoubleLE(startSeconds, 0);
|
|
45
|
+
b.writeDoubleLE(durationSeconds, 8);
|
|
46
|
+
return b.toString('hex');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = {
|
|
50
|
+
decodeResolutionBlob, encodeResolutionBlob,
|
|
51
|
+
decodeRateBlob, encodeRateBlob,
|
|
52
|
+
decodeMediaExtentsBlob, encodeMediaExtentsBlob,
|
|
53
|
+
};
|