@torrent-tv/proxy 2.87.5 → 2.87.7
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/.claude/commands/opsx/apply.md +155 -155
- package/.claude/commands/opsx/archive.md +160 -160
- package/.claude/commands/opsx/explore.md +174 -174
- package/.claude/commands/opsx/propose.md +109 -109
- package/.claude/commands/opsx/sync.md +143 -143
- package/.claude/skills/openspec-apply-change/SKILL.md +159 -159
- package/.claude/skills/openspec-archive-change/SKILL.md +117 -117
- package/.claude/skills/openspec-explore/SKILL.md +289 -289
- package/.claude/skills/openspec-propose/SKILL.md +113 -113
- package/.claude/skills/openspec-sync-specs/SKILL.md +147 -147
- package/.dockerignore +5 -5
- package/AGENTS.md +322 -322
- package/CHANGELOG.md +8 -0
- package/Dockerfile +30 -30
- package/LICENSE +16 -16
- package/README.md +369 -369
- package/assets/calibration/NOTICE.md +100 -100
- package/assets/diagnostics/sctpstate.gdb +31 -31
- package/bin/cli.js +684 -684
- package/bin/thread-pool.js +30 -30
- package/biome.json +411 -411
- package/docs/browser-proxy-contract.md +101 -94
- package/docs/container-architecture.md +218 -218
- package/docs/download-architecture.md +261 -261
- package/docs/encode-architecture.md +729 -729
- package/docs/encode-run-state.md +96 -96
- package/docs/logs.md +97 -97
- package/docs/socks5-egress-research.md +114 -114
- package/docs/storage-architecture.md +267 -267
- package/knip.json +14 -14
- package/openspec/changes/adaptive-bitrate/design.md +92 -92
- package/openspec/changes/adaptive-bitrate/proposal.md +56 -56
- package/openspec/changes/adaptive-bitrate/specs/adaptive-bitrate/spec.md +51 -51
- package/openspec/changes/adaptive-bitrate/tasks.md +40 -40
- package/openspec/changes/binary-distribution/.openspec.yaml +2 -2
- package/openspec/changes/binary-distribution/proposal.md +53 -53
- package/openspec/changes/chunked-request-bodies/design.md +81 -81
- package/openspec/changes/chunked-request-bodies/proposal.md +53 -53
- package/openspec/changes/chunked-request-bodies/specs/chunked-request-bodies/spec.md +30 -30
- package/openspec/changes/chunked-request-bodies/tasks.md +40 -40
- package/openspec/changes/cold-start/design.md +98 -98
- package/openspec/changes/cold-start/proposal.md +62 -62
- package/openspec/changes/cold-start/specs/cold-start/spec.md +47 -47
- package/openspec/changes/cold-start/tasks.md +48 -48
- package/openspec/changes/disk-cap/.openspec.yaml +2 -2
- package/openspec/changes/disk-cap/proposal.md +37 -37
- package/openspec/changes/disk-cap/specs/disk-cap/spec.md +25 -25
- package/openspec/changes/disk-cap/tasks.md +19 -19
- package/openspec/changes/proxy-observability/.openspec.yaml +2 -2
- package/openspec/changes/proxy-observability/design.md +38 -38
- package/openspec/changes/proxy-observability/proposal.md +49 -49
- package/openspec/changes/proxy-observability/specs/observability/spec.md +33 -33
- package/openspec/changes/proxy-observability/tasks.md +21 -21
- package/openspec/changes/seek-debounce/design.md +118 -118
- package/openspec/changes/seek-debounce/proposal.md +59 -59
- package/openspec/changes/seek-debounce/specs/seek-debounce/spec.md +41 -41
- package/openspec/changes/seek-debounce/tasks.md +33 -33
- package/openspec/changes/subtitle-language/.openspec.yaml +2 -2
- package/openspec/changes/subtitle-language/proposal.md +50 -50
- package/openspec/changes/subtitle-language/specs/subtitle-language/spec.md +34 -34
- package/openspec/changes/subtitle-language/tasks.md +26 -26
- package/openspec/changes/track-selection/.openspec.yaml +2 -2
- package/openspec/changes/track-selection/design.md +47 -47
- package/openspec/changes/track-selection/proposal.md +45 -45
- package/openspec/changes/track-selection/specs/track-selection/spec.md +41 -41
- package/openspec/changes/track-selection/tasks.md +20 -20
- package/openspec/changes/transcode-quality/.openspec.yaml +2 -2
- package/openspec/changes/transcode-quality/proposal.md +51 -51
- package/openspec/changes/transcode-quality/specs/transcode-quality/spec.md +139 -139
- package/openspec/changes/transcode-quality/tasks.md +63 -63
- package/openspec/config.yaml +38 -38
- package/package.json +1 -1
- package/public/.well-known/appspecific/com.chrome.devtools.json +1 -1
- package/research/delivery-wedge-stand-ladder-2026-09-13.md +329 -329
- package/research/double-spawn-2026-09-10.md +171 -171
- package/research/handover-2026-09-13.md +209 -209
- package/research/handover-reader-claims-removal-2026-09-12.md +166 -166
- package/research/piece-withdrawn-but-still-claimed-2026-09-12.md +175 -175
- package/research/preset-benchmark-size-scaling-2026-08-22.md +55 -55
- package/research/priority-map-is-the-truth-2026-09-12.md +225 -225
- package/routes/api/client-logs/post.js +86 -86
- package/routes/api/delivery-sink/get.js +72 -72
- package/routes/api/link-probe/get.js +51 -51
- package/routes/api/playback-plan/audio-tracks/post.js +29 -0
- package/routes/api/playback-plan/post.js +53 -53
- package/routes/api/sources/files/get.js +100 -100
- package/routes/api/sources/post.js +36 -36
- package/routes/api/sources/stats/get.js +132 -132
- package/routes/api/subtitles/get.js +230 -230
- package/routes/api/transcode-sessions/fragment-far/post.js +60 -60
- package/routes/api/transcode-sessions/net-report/post.js +129 -129
- package/routes/api/transcode-sessions/post.js +160 -160
- package/routes/api/transcode-sessions/progress/get.js +27 -27
- package/routes/api/transcode-sessions/release/post.js +41 -41
- package/routes/api/transcode-sessions/seek/post.js +63 -63
- package/routes/health/get.js +13 -13
- package/routes/healthz/get.js +13 -13
- package/routes/stream/get.js +361 -361
- package/routes/transcode/audio-file/get.js +64 -64
- package/routes/transcode/audio-warm/get.js +84 -84
- package/routes/transcode/session-file/get.js +52 -52
- package/routes/transcode/variant-file/get.js +95 -95
- package/routes/transcode/variant-warm/get.js +84 -84
- package/scripts/render-run-graph.js +173 -173
- package/server.js +4 -0
- package/services/encode/CoverageMap.js +428 -428
- package/services/encode/CushionReport.js +345 -345
- package/services/encode/EncodeAdmission.js +332 -332
- package/services/encode/EncodeOrchestrator.js +1217 -1217
- package/services/encode/EncodePlan.js +1366 -1366
- package/services/encode/EncodeRun.js +776 -776
- package/services/encode/EncodeRuns.js +1229 -1229
- package/services/encode/Encoder.js +142 -142
- package/services/encode/EncoderSelection.js +38 -38
- package/services/encode/LocalObservations.js +359 -359
- package/services/encode/NvencEncoder.js +50 -50
- package/services/encode/OutputOpening.js +755 -755
- package/services/encode/OutputTimes.js +579 -579
- package/services/encode/QsvEncoder.js +58 -58
- package/services/encode/Renditions.js +2162 -2162
- package/services/encode/RunProgress.js +84 -84
- package/services/encode/SegmentDemand.js +95 -95
- package/services/encode/SoftwareEncoder.js +121 -121
- package/services/encode/V4l2m2mEncoder.js +53 -53
- package/services/encode/VaapiEncoder.js +66 -66
- package/services/encode/args.js +416 -416
- package/services/encode/available-share.js +89 -89
- package/services/encode/calibration.js +361 -361
- package/services/encode/contention.js +128 -128
- package/services/encode/decode-cost-fit.js +363 -363
- package/services/encode/encode-exit.js +114 -114
- package/services/encode/encode-run-state.js +551 -551
- package/services/encode/encoder-readings.js +45 -45
- package/services/encode/fingerprint.js +322 -322
- package/services/encode/host-load.js +174 -174
- package/services/encode/hwaccel.js +1894 -1894
- package/services/encode/index.js +9 -9
- package/services/encode/learned-median.js +90 -90
- package/services/encode/output/EncodedOutput.js +57 -57
- package/services/encode/output/Output.js +131 -131
- package/services/encode/output/OutputCatalog.js +414 -414
- package/services/encode/output/OutputSpec.js +390 -390
- package/services/encode/output/Timeline.js +308 -308
- package/services/encode/output/cut-grid.js +107 -107
- package/services/encode/output/index.js +20 -20
- package/services/encode/output/ladder.js +32 -32
- package/services/encode/output/playlists.js +284 -284
- package/services/encode/output/rates.js +125 -125
- package/services/encode/output-key-format.js +21 -21
- package/services/encode/quality/EncodeCost.js +1083 -1083
- package/services/encode/quality/HostLoad.js +525 -525
- package/services/encode/quality/HostTimings.js +249 -249
- package/services/encode/quality/OutputQualityState.js +28 -28
- package/services/encode/quality/QualityController.js +935 -935
- package/services/encode/quality/QualityOffer.js +416 -416
- package/services/encode/quality/drain-threat.js +47 -47
- package/services/encode/quality/link-budget.js +254 -254
- package/services/encode/quality/output-format.js +266 -266
- package/services/encode/quality/serving-output.js +216 -216
- package/services/encode/quality/visible-rung.js +57 -57
- package/services/encode/run-budget.js +97 -97
- package/services/encode/run-command.js +747 -747
- package/services/encode/run-costs.js +155 -155
- package/services/encode/run-inputs.js +42 -42
- package/services/encode/segment-formats/fmp4.js +437 -437
- package/services/encode/segment-formats/index.js +77 -77
- package/services/encode/segment-formats/init-compat.js +324 -324
- package/services/encode/segment-formats/mp4-boxes.js +311 -311
- package/services/encode/segment-formats/mpegts.js +134 -134
- package/services/encode/start-stop-cost.js +178 -178
- package/services/encode/throughput.js +97 -97
- package/services/encode/torrent-cost.js +88 -88
- package/services/identity/installation-id.js +38 -38
- package/services/media/ContainerOrchestrator.js +149 -149
- package/services/media/KeyframeTables.js +316 -316
- package/services/media/SourceFile.js +298 -298
- package/services/media/SubtitleCues.js +520 -520
- package/services/media/SubtitleOrchestrator.js +167 -167
- package/services/media/audio-inventory.js +245 -212
- package/services/media/container/AviContainer.js +266 -266
- package/services/media/container/Container.js +603 -603
- package/services/media/container/ContainerFactory.js +56 -56
- package/services/media/container/KeyframeTable.js +272 -272
- package/services/media/container/MatroskaContainer.js +1494 -1494
- package/services/media/container/Mp4Container.js +1244 -1244
- package/services/media/container/SubtitleFileContainer.js +322 -322
- package/services/media/container/ebml-reader.js +159 -159
- package/services/media/ffmpeg-banner.js +260 -260
- package/services/media/keyframe-probe.js +157 -157
- package/services/media/media-info-probe.js +93 -93
- package/services/media/playback-planner.js +131 -59
- package/services/media/tracks/AudioTrack.js +131 -131
- package/services/media/tracks/ContainerTrack.js +75 -75
- package/services/media/tracks/ImageSubtitleTrack.js +19 -19
- package/services/media/tracks/SubtitleTrack.js +38 -38
- package/services/media/tracks/TextSubtitleTrack.js +287 -287
- package/services/media/tracks/VideoTrack.js +33 -33
- package/services/media/tracks/index.js +15 -15
- package/services/media/tracks/language-detect.js +174 -174
- package/services/server/OutputLifecycle.js +418 -418
- package/services/server/SegmentServing.js +1146 -1146
- package/services/server/ViewerRequests.js +522 -522
- package/services/server/WaitLedger.js +142 -142
- package/services/server/controllers/PlaybackController.js +40 -36
- package/services/server/controllers/SubtitleController.js +109 -109
- package/services/server/http-responses.js +60 -60
- package/services/server/transcode-session-files.js +325 -325
- package/services/server/wire-outputs.js +983 -983
- package/services/storage/Diagnostics.js +202 -202
- package/services/storage/MachineBudget.js +235 -235
- package/services/storage/allowance.js +107 -107
- package/services/storage/core-dumps.js +106 -106
- package/services/storage/files/CompletedFiles.js +391 -391
- package/services/storage/files/piece-from-whole-file.js +118 -118
- package/services/storage/free.js +71 -71
- package/services/storage/keep.js +48 -48
- package/services/storage/machine-memory.js +56 -56
- package/services/storage/memory-report.js +575 -575
- package/services/storage/piece-store/piece-disk-store.js +516 -516
- package/services/storage/piece-store/piece-lru.js +495 -495
- package/services/storage/piece-store/shared-piece-store.js +1880 -1880
- package/services/storage/returns.js +103 -103
- package/services/storage/segment-store/SegmentStore.js +1196 -1196
- package/services/storage/wire.js +175 -175
- package/services/torrent/Contents.js +324 -324
- package/services/torrent/demand/DemandRegister.js +202 -202
- package/services/torrent/demand/Urgency.js +137 -137
- package/services/torrent/demand/Window.js +118 -118
- package/services/torrent/demand/index.js +8 -8
- package/services/torrent/demand/pieces.js +140 -140
- package/services/torrent/download/SwarmSelection.js +386 -386
- package/services/torrent/download/registry.js +102 -102
- package/services/torrent/download/withdraw-claim.js +80 -80
- package/services/torrent/files.js +455 -455
- package/services/torrent/naming.js +619 -619
- package/services/torrent/piece-store-of.js +29 -29
- package/services/torrent/supply-margin.js +262 -262
- package/services/torrent/torrent-pool.js +2 -2
- package/services/torrent/worker/background-fill.js +213 -213
- package/services/torrent/worker/channel.js +271 -271
- package/services/torrent/worker/fastest-wires.js +342 -342
- package/services/torrent/worker/handle-state.js +23 -23
- package/services/torrent/worker/held-bytes.js +155 -155
- package/services/torrent/worker/install-webrtc-shim.js +32 -32
- package/services/torrent/worker/piece-reader.js +1078 -1078
- package/services/torrent/worker/pool-adapter.js +1 -1
- package/services/torrent/worker/resume-warm.js +107 -107
- package/services/torrent/worker/webrtc-shim.js +219 -219
- package/services/transport/data-channel-handler.js +1356 -1356
- package/services/transport/delivery-probe.js +842 -842
- package/services/transport/health-collector.js +53 -53
- package/services/transport/nat-classifier.js +231 -231
- package/services/transport/packet-witness.js +808 -808
- package/services/transport/port-mapper.js +235 -235
- package/services/transport/registry-api.js +81 -81
- package/services/transport/tunnel-client.js +447 -447
- package/services/transport/usrsctp-state.js +175 -175
- package/services/transport/webrtc-manager.js +484 -484
- package/services/viewer/Assignments.js +340 -340
- package/services/viewer/PriorityMap.js +390 -390
- package/services/viewer/PriorityOrchestrator.js +325 -325
- package/services/viewer/Viewer.js +657 -657
- package/services/viewer/Viewers.js +368 -368
- package/services/viewer/active-output.js +37 -37
- package/services/viewer/audio-start.js +46 -46
- package/services/viewer/buffer-trend.js +81 -81
- package/services/viewer/choices.js +647 -647
- package/services/viewer/positions.js +126 -126
- package/services/viewer/report-intake.js +46 -46
- package/store/source-registry.js +71 -71
- package/test/asset-paths.test.js +28 -28
- package/test/audio-inventory.test.js +212 -176
- package/test/audio-track-bitrate.test.js +40 -40
- package/test/auto-quality-step.test.js +707 -707
- package/test/available-share.test.js +76 -76
- package/test/background-fill.test.js +190 -190
- package/test/client-log-file.test.js +110 -110
- package/test/completed-files.test.js +115 -115
- package/test/concurrent-cost.test.js +148 -148
- package/test/container-media-info.test.js +228 -228
- package/test/contention.test.js +76 -76
- package/test/core-dumps.test.js +57 -57
- package/test/coverage-follows-the-disk.test.js +228 -228
- package/test/coverage-map.test.js +195 -195
- package/test/cue-push-carries-what-the-walk-found.test.js +58 -58
- package/test/cut-times-timeline.test.js +65 -65
- package/test/cuts-follow-published-grid.test.js +109 -109
- package/test/data-channel-frame.test.js +63 -63
- package/test/dead-torrent-handle.test.js +52 -52
- package/test/declared-rates.test.js +116 -116
- package/test/declared-tracks.test.js +35 -35
- package/test/decode-cost-fit.test.js +202 -202
- package/test/decode-cost.test.js +462 -462
- package/test/delivery-probe.test.js +393 -393
- package/test/demand-register.test.js +206 -206
- package/test/dht-bootstrap.test.js +72 -72
- package/test/drain-threat.test.js +65 -65
- package/test/duplicate-add.test.js +48 -48
- package/test/encode-admission.test.js +146 -146
- package/test/encode-cost.test.js +283 -283
- package/test/encode-exit.test.js +111 -111
- package/test/encode-orchestrator.test.js +419 -419
- package/test/encode-plan-viewers.test.js +718 -718
- package/test/encode-plan.test.js +545 -545
- package/test/encode-run-state.test.js +314 -314
- package/test/encode-run.test.js +161 -161
- package/test/encode-slope.test.js +46 -46
- package/test/encoded-output.test.js +39 -39
- package/test/encoder-kinds.test.js +122 -122
- package/test/encoder-readings.test.js +46 -46
- package/test/every-claimant-is-told-its-share.test.js +152 -152
- package/test/failed-encoder-still-serves-what-exists.test.js +354 -354
- package/test/failed-start-breaker.test.js +202 -202
- package/test/fastest-wires.test.js +143 -143
- package/test/ffmpeg-stream-counts.test.js +78 -78
- package/test/file-edges.test.js +191 -191
- package/test/fmp4-self-contained.test.js +80 -80
- package/test/fmp4-timestamps.test.js +140 -140
- package/test/fmp4-track-completeness.test.js +41 -41
- package/test/format-keyed-outputs.test.js +78 -78
- package/test/health-metrics.test.js +38 -38
- package/test/held-request-width.test.js +157 -157
- package/test/helpers/encode-run.js +136 -136
- package/test/helpers/held-file.js +29 -29
- package/test/helpers/manager.js +57 -57
- package/test/helpers/output-spec.js +63 -63
- package/test/host-load.test.js +68 -68
- package/test/index-accuracy-is-about-the-file.test.js +128 -128
- package/test/init-compat.test.js +219 -219
- package/test/input-lost-quiets-the-plan.test.js +261 -261
- package/test/input-unavailable.test.js +48 -48
- package/test/installation-id.test.js +39 -39
- package/test/keeping-period.test.js +83 -83
- package/test/keyframe-index-accuracy.test.js +188 -188
- package/test/keyframe-table-budget.test.js +102 -102
- package/test/keyframes-belong-to-the-file.test.js +249 -249
- package/test/learned-median.test.js +37 -37
- package/test/letting-go-asks-who-is-watching.test.js +191 -191
- package/test/limit-row-by-area.test.js +60 -60
- package/test/link-budget.test.js +111 -111
- package/test/link-probe.test.js +56 -56
- package/test/local-encoding-data.test.js +273 -273
- package/test/logger-repeats.test.js +134 -134
- package/test/look-ahead-coverage.test.js +56 -56
- package/test/manager-surface.test.js +292 -292
- package/test/matroska-cues-track.test.js +192 -192
- package/test/memory-budget.test.js +390 -390
- package/test/move-cost.test.js +216 -216
- package/test/mp4-subtitles.test.js +173 -173
- package/test/one-authority.test.js +285 -285
- package/test/one-budget.test.js +149 -149
- package/test/one-output-one-session.test.js +204 -204
- package/test/one-resource-divided.test.js +185 -185
- package/test/one-serving-output-per-height.test.js +458 -458
- package/test/orchestrator-wired.test.js +206 -206
- package/test/output-catalog.test.js +39 -39
- package/test/output-shape.test.js +21 -21
- package/test/output-spec.test.js +251 -251
- package/test/output-speed.test.js +88 -88
- package/test/outputs-being-prepared.test.js +40 -40
- package/test/packet-witness-ring.test.js +236 -236
- package/test/packet-witness.test.js +148 -148
- package/test/piece-disk-store.test.js +381 -381
- package/test/piece-from-whole-file.test.js +129 -129
- package/test/piece-lru.test.js +319 -319
- package/test/piece-reader.test.js +162 -162
- package/test/piece-selection-offset.test.js +85 -85
- package/test/piece-store-eviction.test.js +560 -560
- package/test/piece-store-never-refuses.test.js +153 -153
- package/test/piece-store-reservations.test.js +318 -318
- package/test/piece-store-slow-disk.test.js +159 -159
- package/test/piece-tail.test.js +97 -97
- package/test/plan-host-timings.test.js +68 -68
- package/test/plan-is-steady.test.js +225 -225
- package/test/priority-map-download.test.js +174 -174
- package/test/priority-map-emptied.test.js +204 -204
- package/test/priority-map-per-output.test.js +215 -215
- package/test/priority-map.test.js +163 -163
- package/test/probe-wedge-certainty.test.js +60 -60
- package/test/produced-copy-choice.test.js +213 -213
- package/test/published-timeline.test.js +83 -83
- package/test/quality-offer.test.js +162 -162
- package/test/quality-variants.test.js +1229 -1229
- package/test/rate-control-in-the-output.test.js +180 -180
- package/test/read-survives-withdrawal.test.js +164 -164
- package/test/read-window.test.js +365 -365
- package/test/resume-warm.test.js +39 -39
- package/test/run-graph-drift.test.js +37 -37
- package/test/run-inputs.test.js +80 -80
- package/test/run-intervals.test.js +100 -100
- package/test/run-position-follows-published-grid.test.js +89 -89
- package/test/run-progress.test.js +65 -65
- package/test/same-height-switch.test.js +664 -664
- package/test/seek-frees-the-viewers-requests.test.js +217 -217
- package/test/seek-landing.test.js +109 -109
- package/test/seek-target-not-superseded.test.js +195 -195
- package/test/segment-closed-on-both-branches.test.js +96 -96
- package/test/segment-cut-times.test.js +63 -63
- package/test/segment-demand.test.js +80 -80
- package/test/segment-hold-supersede.test.js +91 -91
- package/test/segment-judged-by-its-own-header.test.js +221 -221
- package/test/segment-serve-wiring.test.js +475 -475
- package/test/segment-store-eviction.test.js +247 -247
- package/test/segment-store.test.js +323 -323
- package/test/segment-true-start.test.js +86 -86
- package/test/segments-are-shared.test.js +176 -176
- package/test/send-chunk-bytes.test.js +86 -86
- package/test/serving-existing-output.test.js +102 -102
- package/test/serving-output.test.js +102 -102
- package/test/shared-piece-store.test.js +310 -310
- package/test/sidecar-naming.test.js +142 -142
- package/test/source-file.test.js +133 -133
- package/test/source-files-route.test.js +103 -103
- package/test/source-registry.test.js +18 -18
- package/test/split-a-stretch.test.js +139 -139
- package/test/stale-request-after-seek.test.js +158 -158
- package/test/startup-readings.test.js +124 -124
- package/test/stream-route.test.js +182 -182
- package/test/subtitle-cue-framing.test.js +200 -200
- package/test/subtitle-cue-source.test.js +102 -102
- package/test/subtitle-cue-walk.test.js +370 -370
- package/test/subtitle-cursor.test.js +63 -63
- package/test/subtitle-defaults.test.js +118 -118
- package/test/subtitle-language.test.js +252 -252
- package/test/subtitle-track-numbering.test.js +386 -386
- package/test/supply-margin.test.js +177 -177
- package/test/swarm-follows-readers.test.js +174 -174
- package/test/swarm-reach.test.js +130 -130
- package/test/swarm-selection.test.js +220 -220
- package/test/tail-duplication.test.js +167 -167
- package/test/the-channel-has-both-ends.test.js +91 -91
- package/test/the-torrent-thread-serves-bytes.test.js +107 -107
- package/test/thread-pool.test.js +53 -53
- package/test/timeline.test.js +84 -84
- package/test/torrent-contents.test.js +235 -235
- package/test/torrent-cost.test.js +71 -71
- package/test/torrent-files.test.js +221 -221
- package/test/torrent-naming.test.js +255 -255
- package/test/tracks-begin-together.test.js +209 -209
- package/test/tunnel-renewal.test.js +167 -167
- package/test/two-viewers-one-picture.test.js +407 -407
- package/test/upload-hurry.test.js +186 -186
- package/test/usrsctp-state.test.js +131 -131
- package/test/video-facts.test.js +102 -102
- package/test/viewer-assignments.test.js +143 -143
- package/test/viewer-outputs.test.js +285 -285
- package/test/viewer-presence.test.js +116 -116
- package/test/viewer-requests-admission.test.js +89 -89
- package/test/viewer-states.test.js +189 -189
- package/test/viewer-subtitle-subscription.test.js +96 -96
- package/test/viewer.test.js +139 -139
- package/test/viewing-generations.test.js +390 -390
- package/test/visible-rung.test.js +37 -37
- package/test/wait-ledger.test.js +100 -100
- package/test/webrtc-shim.test.js +149 -149
- package/test/wedge-certainty.test.js +131 -131
- package/test/withdraw-piece-claim.test.js +212 -212
- package/test/worker-channel.test.js +158 -158
- package/utils/client-log-file.js +151 -151
- package/utils/logger.js +312 -312
- package/utils/parse-range.js +25 -25
- package/utils/perf.js +59 -59
- package/{services/torrent → utils}/torrent-source-key.js +38 -38
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Base container track — what the container declares about one track.
|
|
3
|
-
*
|
|
4
|
-
* Spec sources:
|
|
5
|
-
* - Matroska RFC 9559 §5.1.4.1 TrackEntry: TrackNumber(0xD7), TrackType(0x83),
|
|
6
|
-
* FlagEnabled(0xB9, default 1), FlagDefault(0x88, default 1),
|
|
7
|
-
* Language(0x22B59C, default "eng"), LanguageBCP47(0x22B59D, MUST ignore
|
|
8
|
-
* Language when present), Name(0x536E), CodecID(0x86), CodecPrivate(0x63A2).
|
|
9
|
-
* - MP4 ISO/IEC 14496-12 §8.3.2 tkhd (track_ID, flags track_enabled 0x000001,
|
|
10
|
-
* alternate_group), §8.4.2 mdhd (language, timescale), §8.4.5 hdlr
|
|
11
|
-
* (handler_type), §8.4.6 elng (extended language).
|
|
12
|
-
*
|
|
13
|
-
* Only fields that exist for EVERY track type live here. Type-specific flags
|
|
14
|
-
* (FlagForced, FlagHearingImpaired, FlagVisualImpaired, FlagOriginal,
|
|
15
|
-
* FlagCommentary) belong to subclasses — RFC 9559 states FlagForced "Applies
|
|
16
|
-
* only to subtitles", so VideoTrack must not carry it.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
export class ContainerTrack {
|
|
20
|
-
/**
|
|
21
|
-
* @param {object} params
|
|
22
|
-
* @param {number} params.trackNumber - Matroska TrackNumber or MP4 track_ID.
|
|
23
|
-
* @param {number} params.declaredIndex - Position among ALL subtitle/audio/video tracks as container orders them; equals ffmpeg 0:s:N / 0:a:N for that type. Stable across image/text filtering.
|
|
24
|
-
* @param {string} params.type - "video" | "audio" | "subtitle" | "other"
|
|
25
|
-
* @param {string} params.codecId - Matroska CodecID or MP4 sample entry type (e.g. "S_TEXT/UTF8", "avc1", "mp4a").
|
|
26
|
-
* @param {string} params.language - Three-letter code or packed mdhd code; empty when absent. For Matroska, when LanguageBCP47 is present this is the BCP47 value ignored per MUST — caller stores both, but `language` here is the resolved one.
|
|
27
|
-
* @param {string} params.languageBcp47 - RFC 5646 tag from LanguageBCP47 / elng, or "".
|
|
28
|
-
* @param {boolean} params.declaresLanguage - Whether the file explicitly supplies a language rather than relying on a container default.
|
|
29
|
-
* @param {string} params.name - Track Name / title, or "".
|
|
30
|
-
* @param {boolean} params.isEnabled - FlagEnabled / tkhd track_enabled. Default true per both specs. Matroska zero-length element means default, not disabled.
|
|
31
|
-
* @param {boolean} params.isDefault - FlagDefault / tkhd? For MP4, derived from handler default? For Matroska, after applying default 1.
|
|
32
|
-
* @param {boolean} params.declaresDefault - Whether FlagDefault was explicitly written (Matroska) or inferred. Needed because ffmpeg banner cannot distinguish "every track marked" from "no track marked".
|
|
33
|
-
* @param {string} [params.codecPrivateB64] - Base64 of CodecPrivate (ASS header etc.), or "".
|
|
34
|
-
* @param {number} [params.alternateGroup] - MP4 alternate_group (0 = no group).
|
|
35
|
-
*/
|
|
36
|
-
constructor({
|
|
37
|
-
trackNumber,
|
|
38
|
-
declaredIndex,
|
|
39
|
-
type,
|
|
40
|
-
codecId,
|
|
41
|
-
language,
|
|
42
|
-
languageBcp47,
|
|
43
|
-
declaresLanguage,
|
|
44
|
-
name,
|
|
45
|
-
isEnabled,
|
|
46
|
-
isDefault,
|
|
47
|
-
declaresDefault,
|
|
48
|
-
codecPrivateB64 = "",
|
|
49
|
-
alternateGroup = 0
|
|
50
|
-
}) {
|
|
51
|
-
this.trackNumber = trackNumber;
|
|
52
|
-
this.declaredIndex = declaredIndex;
|
|
53
|
-
this.type = type;
|
|
54
|
-
this.codecId = codecId ?? "";
|
|
55
|
-
this.language = language ?? "";
|
|
56
|
-
this.languageBcp47 = languageBcp47 ?? "";
|
|
57
|
-
this.declaresLanguage = declaresLanguage === true;
|
|
58
|
-
this.name = name ?? "";
|
|
59
|
-
this.isEnabled = isEnabled !== false;
|
|
60
|
-
this.isDefault = isDefault === true;
|
|
61
|
-
this.declaresDefault = declaresDefault === true;
|
|
62
|
-
this.codecPrivateB64 = codecPrivateB64 ?? "";
|
|
63
|
-
this.alternateGroup = Number.isFinite(alternateGroup) ? alternateGroup : 0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** Whether this track should be offered in UI menus. Base rule: disabled tracks hidden but still counted for declaredIndex. */
|
|
67
|
-
isOfferable() {
|
|
68
|
-
return this.isEnabled;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** RFC 5646 tag wins over three-letter code when present. */
|
|
72
|
-
resolvedLanguage() {
|
|
73
|
-
return this.languageBcp47 || this.language;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @file Base container track — what the container declares about one track.
|
|
3
|
+
*
|
|
4
|
+
* Spec sources:
|
|
5
|
+
* - Matroska RFC 9559 §5.1.4.1 TrackEntry: TrackNumber(0xD7), TrackType(0x83),
|
|
6
|
+
* FlagEnabled(0xB9, default 1), FlagDefault(0x88, default 1),
|
|
7
|
+
* Language(0x22B59C, default "eng"), LanguageBCP47(0x22B59D, MUST ignore
|
|
8
|
+
* Language when present), Name(0x536E), CodecID(0x86), CodecPrivate(0x63A2).
|
|
9
|
+
* - MP4 ISO/IEC 14496-12 §8.3.2 tkhd (track_ID, flags track_enabled 0x000001,
|
|
10
|
+
* alternate_group), §8.4.2 mdhd (language, timescale), §8.4.5 hdlr
|
|
11
|
+
* (handler_type), §8.4.6 elng (extended language).
|
|
12
|
+
*
|
|
13
|
+
* Only fields that exist for EVERY track type live here. Type-specific flags
|
|
14
|
+
* (FlagForced, FlagHearingImpaired, FlagVisualImpaired, FlagOriginal,
|
|
15
|
+
* FlagCommentary) belong to subclasses — RFC 9559 states FlagForced "Applies
|
|
16
|
+
* only to subtitles", so VideoTrack must not carry it.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export class ContainerTrack {
|
|
20
|
+
/**
|
|
21
|
+
* @param {object} params
|
|
22
|
+
* @param {number} params.trackNumber - Matroska TrackNumber or MP4 track_ID.
|
|
23
|
+
* @param {number} params.declaredIndex - Position among ALL subtitle/audio/video tracks as container orders them; equals ffmpeg 0:s:N / 0:a:N for that type. Stable across image/text filtering.
|
|
24
|
+
* @param {string} params.type - "video" | "audio" | "subtitle" | "other"
|
|
25
|
+
* @param {string} params.codecId - Matroska CodecID or MP4 sample entry type (e.g. "S_TEXT/UTF8", "avc1", "mp4a").
|
|
26
|
+
* @param {string} params.language - Three-letter code or packed mdhd code; empty when absent. For Matroska, when LanguageBCP47 is present this is the BCP47 value ignored per MUST — caller stores both, but `language` here is the resolved one.
|
|
27
|
+
* @param {string} params.languageBcp47 - RFC 5646 tag from LanguageBCP47 / elng, or "".
|
|
28
|
+
* @param {boolean} params.declaresLanguage - Whether the file explicitly supplies a language rather than relying on a container default.
|
|
29
|
+
* @param {string} params.name - Track Name / title, or "".
|
|
30
|
+
* @param {boolean} params.isEnabled - FlagEnabled / tkhd track_enabled. Default true per both specs. Matroska zero-length element means default, not disabled.
|
|
31
|
+
* @param {boolean} params.isDefault - FlagDefault / tkhd? For MP4, derived from handler default? For Matroska, after applying default 1.
|
|
32
|
+
* @param {boolean} params.declaresDefault - Whether FlagDefault was explicitly written (Matroska) or inferred. Needed because ffmpeg banner cannot distinguish "every track marked" from "no track marked".
|
|
33
|
+
* @param {string} [params.codecPrivateB64] - Base64 of CodecPrivate (ASS header etc.), or "".
|
|
34
|
+
* @param {number} [params.alternateGroup] - MP4 alternate_group (0 = no group).
|
|
35
|
+
*/
|
|
36
|
+
constructor({
|
|
37
|
+
trackNumber,
|
|
38
|
+
declaredIndex,
|
|
39
|
+
type,
|
|
40
|
+
codecId,
|
|
41
|
+
language,
|
|
42
|
+
languageBcp47,
|
|
43
|
+
declaresLanguage,
|
|
44
|
+
name,
|
|
45
|
+
isEnabled,
|
|
46
|
+
isDefault,
|
|
47
|
+
declaresDefault,
|
|
48
|
+
codecPrivateB64 = "",
|
|
49
|
+
alternateGroup = 0
|
|
50
|
+
}) {
|
|
51
|
+
this.trackNumber = trackNumber;
|
|
52
|
+
this.declaredIndex = declaredIndex;
|
|
53
|
+
this.type = type;
|
|
54
|
+
this.codecId = codecId ?? "";
|
|
55
|
+
this.language = language ?? "";
|
|
56
|
+
this.languageBcp47 = languageBcp47 ?? "";
|
|
57
|
+
this.declaresLanguage = declaresLanguage === true;
|
|
58
|
+
this.name = name ?? "";
|
|
59
|
+
this.isEnabled = isEnabled !== false;
|
|
60
|
+
this.isDefault = isDefault === true;
|
|
61
|
+
this.declaresDefault = declaresDefault === true;
|
|
62
|
+
this.codecPrivateB64 = codecPrivateB64 ?? "";
|
|
63
|
+
this.alternateGroup = Number.isFinite(alternateGroup) ? alternateGroup : 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Whether this track should be offered in UI menus. Base rule: disabled tracks hidden but still counted for declaredIndex. */
|
|
67
|
+
isOfferable() {
|
|
68
|
+
return this.isEnabled;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** RFC 5646 tag wins over three-letter code when present. */
|
|
72
|
+
resolvedLanguage() {
|
|
73
|
+
return this.languageBcp47 || this.language;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Image subtitle track — PGS / VobSub / subp / clcp. Not convertible to WebVTT.
|
|
3
|
-
*
|
|
4
|
-
* Matroska: S_HDMV/PGS, S_VOBSUB, S_IMAGE/BMP etc.
|
|
5
|
-
* MP4: stpp is TTML (XML, excluded from Text), subp (VobSub), clcp (closed captions)
|
|
6
|
-
* Kept in the model only to preserve declaredIndex alignment with ffmpeg 0:s:N.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { SubtitleTrack } from "./SubtitleTrack.js";
|
|
10
|
-
|
|
11
|
-
export class ImageSubtitleTrack extends SubtitleTrack {
|
|
12
|
-
constructor(params) {
|
|
13
|
-
super(params);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
isTextBased() {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @file Image subtitle track — PGS / VobSub / subp / clcp. Not convertible to WebVTT.
|
|
3
|
+
*
|
|
4
|
+
* Matroska: S_HDMV/PGS, S_VOBSUB, S_IMAGE/BMP etc.
|
|
5
|
+
* MP4: stpp is TTML (XML, excluded from Text), subp (VobSub), clcp (closed captions)
|
|
6
|
+
* Kept in the model only to preserve declaredIndex alignment with ffmpeg 0:s:N.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { SubtitleTrack } from "./SubtitleTrack.js";
|
|
10
|
+
|
|
11
|
+
export class ImageSubtitleTrack extends SubtitleTrack {
|
|
12
|
+
constructor(params) {
|
|
13
|
+
super(params);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
isTextBased() {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Subtitle track — extends ContainerTrack with subtitle-only flags.
|
|
3
|
-
*
|
|
4
|
-
* Matroska RFC 9559:
|
|
5
|
-
* - FlagForced 0x55AA default 0, applies ONLY to subtitles.
|
|
6
|
-
* - FlagHearingImpaired 0x55AB, FlagVisualImpaired 0x55AC (SDH etc.)
|
|
7
|
-
* - FlagTextDescriptions 0x55AD also subtitle-related.
|
|
8
|
-
* - FlagEnabled 0xB9 still handled in base (disabled tracks counted but not offered).
|
|
9
|
-
* MP4 ISO 14496-12 + Apple tx3g extension:
|
|
10
|
-
* - handler sbtl/subt/text/wvtt vs subp/clcp (image)
|
|
11
|
-
* - tx3g displayFlags forced bits 0x40000000 / 0x80000000 (unconfirmed primary source, carried as raw flags)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { ContainerTrack } from "./ContainerTrack.js";
|
|
15
|
-
|
|
16
|
-
export class SubtitleTrack extends ContainerTrack {
|
|
17
|
-
/**
|
|
18
|
-
* @param {object} params - See ContainerTrack plus:
|
|
19
|
-
* @param {boolean} params.isForced - FlagForced (matroska) or tx3g forced display flag.
|
|
20
|
-
* @param {boolean} params.isHearingImpaired - FlagHearingImpaired
|
|
21
|
-
* @param {boolean} params.isVisualImpaired - FlagVisualImpaired
|
|
22
|
-
* @param {number[]} params.clusterPositions - Matroska: file offsets of clusters whose CuePoints name this track (for push). Empty when indexless.
|
|
23
|
-
* @param {Array<{offset:number,size:number,startSeconds:number,endSeconds:number}>} params.samples - MP4: per-cue byte ranges from sample tables.
|
|
24
|
-
*/
|
|
25
|
-
constructor(params) {
|
|
26
|
-
super({ ...params, type: "subtitle" });
|
|
27
|
-
this.isForced = params.isForced === true;
|
|
28
|
-
this.isHearingImpaired = params.isHearingImpaired === true;
|
|
29
|
-
this.isVisualImpaired = params.isVisualImpaired === true;
|
|
30
|
-
this.clusterPositions = Array.isArray(params.clusterPositions) ? params.clusterPositions : [];
|
|
31
|
-
this.samples = Array.isArray(params.samples) ? params.samples : [];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** Whether this track can be converted to WebVTT in current pipeline. Overridden by subclasses. */
|
|
35
|
-
isTextBased() {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @file Subtitle track — extends ContainerTrack with subtitle-only flags.
|
|
3
|
+
*
|
|
4
|
+
* Matroska RFC 9559:
|
|
5
|
+
* - FlagForced 0x55AA default 0, applies ONLY to subtitles.
|
|
6
|
+
* - FlagHearingImpaired 0x55AB, FlagVisualImpaired 0x55AC (SDH etc.)
|
|
7
|
+
* - FlagTextDescriptions 0x55AD also subtitle-related.
|
|
8
|
+
* - FlagEnabled 0xB9 still handled in base (disabled tracks counted but not offered).
|
|
9
|
+
* MP4 ISO 14496-12 + Apple tx3g extension:
|
|
10
|
+
* - handler sbtl/subt/text/wvtt vs subp/clcp (image)
|
|
11
|
+
* - tx3g displayFlags forced bits 0x40000000 / 0x80000000 (unconfirmed primary source, carried as raw flags)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { ContainerTrack } from "./ContainerTrack.js";
|
|
15
|
+
|
|
16
|
+
export class SubtitleTrack extends ContainerTrack {
|
|
17
|
+
/**
|
|
18
|
+
* @param {object} params - See ContainerTrack plus:
|
|
19
|
+
* @param {boolean} params.isForced - FlagForced (matroska) or tx3g forced display flag.
|
|
20
|
+
* @param {boolean} params.isHearingImpaired - FlagHearingImpaired
|
|
21
|
+
* @param {boolean} params.isVisualImpaired - FlagVisualImpaired
|
|
22
|
+
* @param {number[]} params.clusterPositions - Matroska: file offsets of clusters whose CuePoints name this track (for push). Empty when indexless.
|
|
23
|
+
* @param {Array<{offset:number,size:number,startSeconds:number,endSeconds:number}>} params.samples - MP4: per-cue byte ranges from sample tables.
|
|
24
|
+
*/
|
|
25
|
+
constructor(params) {
|
|
26
|
+
super({ ...params, type: "subtitle" });
|
|
27
|
+
this.isForced = params.isForced === true;
|
|
28
|
+
this.isHearingImpaired = params.isHearingImpaired === true;
|
|
29
|
+
this.isVisualImpaired = params.isVisualImpaired === true;
|
|
30
|
+
this.clusterPositions = Array.isArray(params.clusterPositions) ? params.clusterPositions : [];
|
|
31
|
+
this.samples = Array.isArray(params.samples) ? params.samples : [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Whether this track can be converted to WebVTT in current pipeline. Overridden by subclasses. */
|
|
35
|
+
isTextBased() {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|