{"_id":"@blackbelt-technology/pi-dashboard-video-transcription","_rev":"6-87ed1b55240cfcf35218f949d0f0117b","name":"@blackbelt-technology/pi-dashboard-video-transcription","dist-tags":{"latest":"0.9.0"},"versions":{"0.5.4":{"name":"@blackbelt-technology/pi-dashboard-video-transcription","version":"0.5.4","keywords":["pi-package","pi-skill","video-transcription","transcription","srt","subtitles","soniox","ffmpeg","speaker-diarization"],"license":"MIT","_id":"@blackbelt-technology/pi-dashboard-video-transcription@0.5.4","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"skills":[".pi/skills/video-transcription"]},"bin":{"pi-transcribe":"src/bin/transcribe.ts"},"dist":{"shasum":"cc1c878ae50a1022ce8caee323c73d3832a5d084","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-dashboard-video-transcription/-/pi-dashboard-video-transcription-0.5.4.tgz","fileCount":11,"integrity":"sha512-PEXQsciI+3QZ1gdNf9H+HD9En1sGJlDrxQYs2o+MXJftTvN9rTkPQFSKnzuz16yNojftcixmWH3mpU3heGzh0w==","signatures":[{"sig":"MEUCIQCqCntp5ZYEPP04E9vMo8GiP1rIiJgwmYWxk0ywKAlCPwIgFdwGTy049cUj6Vfahf1NJy4NRUtoMZ20Hh4GOZyLUfk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33710},"type":"module","gitHead":"66b8aac8c4506cfed35102154e3ad04cdf424848","scripts":{"test":"vitest run","parity":"tsx parity/parity-check.ts","parity:docker":"parity/run.sh"},"_npmUser":{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/video-transcription"},"_npmVersion":"10.9.3","description":"Full TypeScript port of the video-transcription pi skill. Transcribes local video/audio to speaker-diarized SRT via the Soniox async API, with long-recording chunking and idempotent re-runs. ffmpeg/ffprobe are external prerequisites.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"@blackbelt-technology/pi-dashboard-shared":"^0.5.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typebox":"*","@earendil-works/pi-coding-agent":"*"},"peerDependencies":{"typebox":"*","@earendil-works/pi-coding-agent":"*"},"peerDependenciesMeta":{"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-dashboard-video-transcription_0.5.4_1783019198372_0.13652606192661","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@blackbelt-technology/pi-dashboard-video-transcription","version":"0.6.0","keywords":["pi-package","pi-skill","video-transcription","transcription","srt","subtitles","soniox","ffmpeg","speaker-diarization"],"license":"MIT","_id":"@blackbelt-technology/pi-dashboard-video-transcription@0.6.0","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"skills":[".pi/skills/video-transcription"]},"bin":{"pi-transcribe":"src/bin/transcribe.ts"},"dist":{"shasum":"a79cd9bf36ace0dfb130017036fdd7e4fc7f80ad","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-dashboard-video-transcription/-/pi-dashboard-video-transcription-0.6.0.tgz","fileCount":13,"integrity":"sha512-bksrzGyqHK5l58kOamU6xMhlcB8w1VdueKwDn59ho1v9gAYWH8pxY7UNS1KKCFpiuH24iILX/bOsjU08rhA0jw==","signatures":[{"sig":"MEQCIGfoTNWGIlGLqfFPfgXvaAAumnLNjzhwjP8owDyf6lH9AiBTu2+xNpmkTCusjur8sc5NDryCixDQHawPD5Qv093sAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-dashboard-video-transcription@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36332},"type":"module","gitHead":"53c737b1bae56fcd8e02a93ae921b83de19df343","scripts":{"test":"vitest run","parity":"tsx parity/parity-check.ts","parity:docker":"parity/run.sh"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:eb1c9b85-717d-4747-9a5b-6cc54f317ddf"}},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/video-transcription"},"_npmVersion":"11.12.1","description":"Full TypeScript port of the video-transcription pi skill. Transcribes local video/audio to speaker-diarized SRT via the Soniox async API, with long-recording chunking and idempotent re-runs. ffmpeg/ffprobe are external prerequisites.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@blackbelt-technology/pi-dashboard-shared":"^0.6.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typebox":"*","@earendil-works/pi-coding-agent":"*"},"peerDependencies":{"typebox":"*","@earendil-works/pi-coding-agent":"*"},"peerDependenciesMeta":{"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-dashboard-video-transcription_0.6.0_1784567288750_0.4323164931582715","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@blackbelt-technology/pi-dashboard-video-transcription","version":"0.6.1","keywords":["pi-package","pi-skill","video-transcription","transcription","srt","subtitles","soniox","ffmpeg","speaker-diarization"],"license":"MIT","_id":"@blackbelt-technology/pi-dashboard-video-transcription@0.6.1","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"skills":[".pi/skills/video-transcription"]},"bin":{"pi-transcribe":"src/bin/transcribe.ts"},"dist":{"shasum":"a5ba1f23731384f35015660a50f900260ce2dc62","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-dashboard-video-transcription/-/pi-dashboard-video-transcription-0.6.1.tgz","fileCount":13,"integrity":"sha512-5g8PcxK6agPvj7fwh7ZpM/N4Ac40i9ZijjVqyQ7yl86l+pdAkLQiIrkX1bUtvBi4zzTGvdLxFCkEjdYMs4rI5A==","signatures":[{"sig":"MEUCIAmCB0OICzeOLZ6eEOqzoguJo0pwbVH/LlwEI/x4thqDAiEAsuu7DeDQJVlUWbLK4v44CVLqYWXNdxyAHxo03lqs/K4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-dashboard-video-transcription@0.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36332},"type":"module","gitHead":"88a0cf3cc7d7c7c4e44eb61df3cceff19ed919ad","scripts":{"test":"vitest run","parity":"tsx parity/parity-check.ts","parity:docker":"parity/run.sh"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:eb1c9b85-717d-4747-9a5b-6cc54f317ddf"}},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/video-transcription"},"_npmVersion":"11.12.1","description":"Full TypeScript port of the video-transcription pi skill. Transcribes local video/audio to speaker-diarized SRT via the Soniox async API, with long-recording chunking and idempotent re-runs. ffmpeg/ffprobe are external prerequisites.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@blackbelt-technology/pi-dashboard-shared":"^0.6.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typebox":"*","@earendil-works/pi-coding-agent":"*"},"peerDependencies":{"typebox":"*","@earendil-works/pi-coding-agent":"*"},"peerDependenciesMeta":{"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-dashboard-video-transcription_0.6.1_1784571763979_0.0836951695506285","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@blackbelt-technology/pi-dashboard-video-transcription","version":"0.7.0","keywords":["pi-package","pi-skill","video-transcription","transcription","srt","subtitles","soniox","ffmpeg","speaker-diarization"],"license":"MIT","_id":"@blackbelt-technology/pi-dashboard-video-transcription@0.7.0","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"skills":[".pi/skills/video-transcription"]},"bin":{"pi-transcribe":"src/bin/transcribe.ts"},"dist":{"shasum":"5f42a3da3cad72ed61226c4e396fe60dc1ae46d9","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-dashboard-video-transcription/-/pi-dashboard-video-transcription-0.7.0.tgz","fileCount":13,"integrity":"sha512-HtZWv7DwadlwSPLT+SBqXxIkAD3tUlz2B78V3PZddbTMx2EJnu/HxeJ/LWgC4EzUJ9VGZskWD5soVnKDu1X6oA==","signatures":[{"sig":"MEYCIQC/G6/j5hZ7g07VUBk3mk+VnTrPt28zoCy1BULRjELceQIhAPM4PP54AYYCu4veegmstCwOPrIeJOHWV5nR8S3AYQh9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-dashboard-video-transcription@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":39126},"type":"module","gitHead":"9203d6a89f1b81c516e9351072ee5cb4c6579e0a","scripts":{"test":"vitest run","parity":"tsx parity/parity-check.ts","parity:docker":"parity/run.sh"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:eb1c9b85-717d-4747-9a5b-6cc54f317ddf"}},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/video-transcription"},"_npmVersion":"12.0.1","description":"Full TypeScript port of the video-transcription pi skill. Transcribes local video/audio to speaker-diarized SRT via the Soniox async API, with long-recording chunking and idempotent re-runs. ffmpeg/ffprobe are external prerequisites.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@blackbelt-technology/pi-dashboard-shared":"^0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typebox":"*","@earendil-works/pi-coding-agent":"*"},"peerDependencies":{"typebox":"*","@earendil-works/pi-coding-agent":"*"},"peerDependenciesMeta":{"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-dashboard-video-transcription_0.7.0_1784899158336_0.46667447869550704","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@blackbelt-technology/pi-dashboard-video-transcription","version":"0.8.0","keywords":["pi-package","pi-skill","video-transcription","transcription","srt","subtitles","soniox","ffmpeg","speaker-diarization"],"license":"MIT","_id":"@blackbelt-technology/pi-dashboard-video-transcription@0.8.0","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"skills":[".pi/skills/video-transcription"]},"bin":{"pi-transcribe":"src/bin/transcribe.ts"},"dist":{"shasum":"e6bccd3cbba956242c0b8cd3ee2de32b2828b25f","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-dashboard-video-transcription/-/pi-dashboard-video-transcription-0.8.0.tgz","fileCount":11,"integrity":"sha512-UKBSvukBsZuM7dbqetvW8it+GFG+7oP5oz66zWYBPJdmlBAtRfWpPvOxCW2A+c62PxPM/I6BgapubhK2hZn9mw==","signatures":[{"sig":"MEUCIQCnVyeR2Z9yJEMoRcnDSEctKLkprhI2lTKnkNnSTfJm4QIgXPf3hPr/6uufoF/72A4ut0Kqmm9RllA6QWMSiqAXmGM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-dashboard-video-transcription@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36339},"type":"module","gitHead":"9373dfa416660a285475febc0383608fe14270b1","scripts":{"test":"vitest run","parity":"tsx parity/parity-check.ts","parity:docker":"parity/run.sh"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:eb1c9b85-717d-4747-9a5b-6cc54f317ddf"}},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/video-transcription"},"_npmVersion":"12.0.2","description":"Full TypeScript port of the video-transcription pi skill. Transcribes local video/audio to speaker-diarized SRT via the Soniox async API, with long-recording chunking and idempotent re-runs. ffmpeg/ffprobe are external prerequisites.","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@blackbelt-technology/pi-dashboard-shared":"^0.8.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typebox":">=1.3.6","@earendil-works/pi-coding-agent":">=0.80.10"},"peerDependencies":{"typebox":">=1.3.6","@earendil-works/pi-coding-agent":">=0.80.10"},"peerDependenciesMeta":{"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-dashboard-video-transcription_0.8.0_1787746054533_0.19195724453190666","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"pi":{"tools":[{"id":"ffmpeg","probe":"resolve","optional":true},{"id":"ffprobe","probe":"resolve","optional":true},{"id":"SONIOX_API_KEY","probe":"env"},{"id":"ASSEMBLY_AI_KEY","probe":"env","optional":true}],"skills":[".pi/skills/video-transcription",".pi/skills/speaker-id",".pi/skills/youtube-srt"]},"_id":"@blackbelt-technology/pi-dashboard-video-transcription@0.9.0","bin":{"pi-voiceid":"src/bin/voiceid.ts","pi-transcribe":"src/bin/transcribe.ts"},"bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"dist":{"shasum":"c4760b4f8b7bf308e29c84768a61c5b8233b3e10","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-dashboard-video-transcription/-/pi-dashboard-video-transcription-0.9.0.tgz","fileCount":26,"integrity":"sha512-5jlP2bILny1yn/v39MIQJm3ZLnJSY0JUPTHVnmHeI2zshPA3MsP9R3xzok8lTET4aK4Wa3dIJWbtA0sm/W0ReQ==","signatures":[{"sig":"MEYCIQDxEGJIpfHrkdtm1jJ9vnKHXlLQIdFLk13glaHlMavEdAIhAOhR0YbtYBnPOfbY2aLmzITLUvVBlvGLcfeDuVmeRCT2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICxn+eX4ZoSymdV1arFd8AHtrJXk/nolaexAUlqthrNIAiBHZmzXElEfYu9Hx4OUlFPlJ5ExaAHNGh7LU34sI+x17Q=="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-dashboard-video-transcription@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":173836},"name":"@blackbelt-technology/pi-dashboard-video-transcription","type":"module","gitHead":"60a155465d55e4438e1425c07b0ab5459083a9b5","license":"MIT","scripts":{"test":"vitest run","parity":"tsx parity/parity-check.ts","parity:docker":"parity/run.sh"},"version":"0.9.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"eb1c9b85-717d-4747-9a5b-6cc54f317ddf"}},"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","keywords":["pi-package","pi-skill","video-transcription","transcription","srt","subtitles","soniox","assemblyai","ffmpeg","speaker-diarization"],"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/video-transcription"},"_npmVersion":"12.2.0","description":"Full TypeScript port of the video-transcription pi skill. Transcribes local video/audio to speaker-diarized SRT via the Soniox async API (default) or AssemblyAI (opt-in, EU endpoint), with long-recording chunking and idempotent re-runs. ffmpeg/ffprobe are","directories":{},"maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"_nodeVersion":"24.21.0","dependencies":{"@blackbelt-technology/pi-dashboard-shared":"^0.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typebox":">=1.3.6","@earendil-works/pi-coding-agent":"^1.0.0"},"peerDependencies":{"typebox":">=1.3.6","@earendil-works/pi-coding-agent":">=1.0.0"},"optionalDependencies":{"ffmpeg-static":"^5.3.0","sherpa-onnx-node":"^1.13.6","@ffprobe-installer/ffprobe":"^2.1.2"},"peerDependenciesMeta":{"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-dashboard-video-transcription_0.9.0_1791297236386_0.5805109205246388"}}},"time":{"created":"2026-07-02T19:06:38.020Z","modified":"2026-10-06T14:33:56.783Z","0.5.4":"2026-07-02T19:06:38.510Z","0.6.0":"2026-07-20T17:08:09.020Z","0.6.1":"2026-07-20T18:22:44.120Z","0.7.0":"2026-07-24T13:19:18.512Z","0.8.0":"2026-08-26T12:07:34.667Z","0.9.0":"2026-10-06T14:33:56.490Z"},"bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"license":"MIT","homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","keywords":["pi-package","pi-skill","video-transcription","transcription","srt","subtitles","soniox","assemblyai","ffmpeg","speaker-diarization"],"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/video-transcription"},"description":"Full TypeScript port of the video-transcription pi skill. Transcribes local video/audio to speaker-diarized SRT via the Soniox async API (default) or AssemblyAI (opt-in, EU endpoint), with long-recording chunking and idempotent re-runs. ffmpeg/ffprobe are","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"readme":"# @blackbelt-technology/pi-dashboard-video-transcription\n\nTranscribe local video/audio files in-place to speaker-diarized SRT subtitles.\nTwo interchangeable backends: [Soniox](https://soniox.com) (default) and\n[AssemblyAI](https://www.assemblyai.com) (opt-in, for its speaker diarization).\nFull TypeScript port of the standalone `video-transcription` pi skill — no\nPython. Its only runtime npm dependency is\n`@blackbelt-technology/pi-dashboard-shared` (the repo's safe-subprocess\nwrapper); everything else rides pi's bundled peers.\n\nExposed two ways:\n\n- **pi skill** — `.pi/skills/video-transcription` (triggers like `/transcribe`).\n- **CLI bin** — `pi-transcribe [directory | file ...]`.\n\nIt also ships a second, additive CLI — `pi-voiceid` (skill\n`.pi/skills/speaker-id`) — which puts **real names** on the anonymous speaker\nlabels a diarizer produces, using a persistent local voiceprint library, and\nrepairs speaker drift on long recordings. See [Speaker ID](#speaker-id-pi-voiceid).\n\n## Prerequisites\n\n- **`ffmpeg`** and **`ffprobe`** on `PATH` — used for audio extraction from\n  video, duration probing, and chunk slicing. Audio-only files still need\n  `ffprobe` for the long-recording duration guard.\n  - macOS: `brew install ffmpeg`\n  - Ubuntu/Debian: `sudo apt install ffmpeg`\n  - Windows: <https://ffmpeg.org/download.html>\n- **An API key for each selected backend** — `SONIOX_API_KEY` (default backend),\n  `ASSEMBLY_AI_KEY` (`TRANSCRIBE_BACKEND=assemblyai`), or both\n  (`TRANSCRIBE_BACKEND=both`). All use the same resolver: environment first,\n  then an optional gitignored `.env` file (current directory, then the skill\n  dir). Only the selected backends' keys are required, and they are all\n  resolved before any audio is uploaded.\n  No secret is committed in the package.\n\n## Install\n\n```bash\npi install @blackbelt-technology/pi-dashboard-video-transcription\n```\n\nDelivery is published + opt-in. The package is NOT auto-loaded by the monorepo.\n\n## Usage\n\n```bash\npi-transcribe                      # scan ~/Movies (default)\npi-transcribe /path/to/recordings  # scan a directory\npi-transcribe a.m4a b.mp4          # transcribe explicit files\n```\n\n- **No argument** — scans `~/Movies`.\n- **Single directory** — scans it for `.mkv`, `.mp4`, `.m4a`, `.mp3`.\n- **One or more file paths** — transcribes exactly those files.\n\nDiscovered files are processed oldest-first by modification time. A file is\nskipped when the sibling subtitle file for the active backend already exists\n(idempotent). Output `.mp3` (extracted audio) and the subtitle file are written\nalongside each source file.\n\n### Backends\n\n| | Soniox (default) | AssemblyAI (`TRANSCRIBE_BACKEND=assemblyai`) |\n|---|---|---|\n| Key | `SONIOX_API_KEY` | `ASSEMBLY_AI_KEY` |\n| Output | `<name>.srt` | `<name>.diarize.srt` |\n| Endpoint | `api.soniox.com` | `api.eu.assemblyai.com` (EU data residency) |\n| Model | `stt-async-v3` | `speech_models: [\"universal-3-5-pro\", \"universal-2\"]` |\n| Per-request duration cap | 5 h (chunk default 4.5 h) | 10 h (chunk default 9 h) |\n\nBecause the two backends write different suffixes, the same source file can be\ntranscribed by both — side-by-side SRTs for comparing diarization quality.\n\n`TRANSCRIBE_BACKEND=both` (or `all`, or a comma list such as\n`soniox,assemblyai`) runs every backend in one pass:\n\n```bash\nTRANSCRIBE_BACKEND=both pi-transcribe ~/Movies\n```\n\nEach file is discovered once and, for videos, its audio is extracted once; that\nsingle `.mp3` then feeds both APIs, which run one after the other per file. The\nresult is `<name>.srt` (Soniox) **and** `<name>.diarize.srt` (AssemblyAI).\nIdempotency is per backend: a file already carrying `<name>.srt` from an earlier\nSoniox run is not re-transcribed by Soniox, but still gets its missing\n`.diarize.srt`. A file is skipped entirely only when every selected backend's\nSRT exists. If one backend errors, the other's SRT is still written.\n\nAssemblyAI runs with `speaker_labels` and `language_detection` on.\n`universal-3-5-pro` natively covers 18 languages; anything outside that set\n(Hungarian included) automatically falls back to `universal-2` (99 languages).\nSpeaker letters (`A`, `B`, …) are normalised to `Speaker 1`, `Speaker 2`, … so\nboth backends emit the same SRT format.\n\n### Environment overrides\n\n| Variable | Default | Meaning |\n|---|---|---|\n| `TRANSCRIBE_BACKEND` | `soniox` | `soniox`, `assemblyai`, `both`/`all`, or a comma-separated list. Unknown values fall back to `soniox`. |\n| `SONIOX_API_KEY` | _(required for soniox)_ | Soniox API key. |\n| `ASSEMBLY_AI_KEY` | _(required for assemblyai)_ | AssemblyAI API key. |\n| `MAX_CHUNK_HOURS` | `4.5` / `9` | Chunk size for long recordings; default depends on each backend's duration cap. Applies to all selected backends. |\n| `MAX_AUDIO_MB` | `200` | Reserved size guard; `0` disables. |\n| `TRANSCRIBE_CONCURRENCY` | `8` | Files transcribed in parallel via a worker pool. Clamped to `1`–`100` (100 = Soniox pending-job cap); `1` = serial. |\n| `TRANSCRIBE_SRT_SUFFIX` | per backend | Override the sibling subtitle suffix. Ignored when more than one backend is selected. |\n| `TRANSCRIBE_LANGUAGE` | _(unset)_ | AssemblyAI only: pin a language (e.g. `hu`) instead of auto-detecting. |\n| `TRANSCRIBE_MAX_SPEAKERS` | _(unset)_ | AssemblyAI only: hard cap on speaker labels (extra speakers get merged). |\n\n## Long recordings (>5 h)\n\nSoniox enforces a hard per-request limit on audio **duration** (18000 s / 5 h),\nindependent of file size. Recordings over the limit are split into\n`MAX_CHUNK_HOURS`-sized chunks, transcribed separately, and merged into a single\nSRT with correct absolute timestamps — full coverage, no truncation. Duration is\nprobed via `ffprobe` since the limit is on duration, not megabytes.\n\n## Speaker ID (`pi-voiceid`)\n\nGive diarized transcripts real names and repair the drift that clustering\ndiarizers produce on long recordings. Post-hoc relabeling — it does **not**\ncreate diarization. Fully local, CPU-only, no API key; no audio or embedding\nleaves the machine.\n\n```bash\npi-voiceid analyze --srt talk.srt                         # drift report, no enrollment\npi-voiceid enroll  --name \"Alice\" --srt talk.srt --label \"Speaker 1\"\npi-voiceid label   --srt talk.srt --dry-run               # read the decision table\npi-voiceid label   --srt talk.srt                         # writes talk.named.srt\npi-voiceid list                                           # library + cohort state\npi-voiceid forget  --name \"Alice\"                         # biometric erasure\n```\n\nThe source SRT is never overwritten. Full procedure, thresholds and limitations\nare in [`.pi/skills/speaker-id/SKILL.md`](.pi/skills/speaker-id/SKILL.md); the\nmodel comparison behind the default is in\n[`.pi/skills/speaker-id/BENCHMARK.md`](.pi/skills/speaker-id/BENCHMARK.md).\n\n**Native dependency.** Speaker embeddings come from `sherpa-onnx-node`, declared\nas an **optionalDependency** so a platform without a prebuilt binary still\ninstalls and the existing transcription path keeps working. When it is absent,\n`pi-voiceid` fails with a message naming the dependency and the install command\nrather than a raw module-resolution error.\n\n**Model.** A 28 MB ONNX model, downloaded on demand into\n`~/.pi/models/speaker/`. It is **not** vendored into the npm package.\n\n**Voiceprint store.** Default `~/.pi/voiceprints/voiceprints.json`, overridable\nwith `--store` or `PI_VOICEPRINT_STORE`. This is **biometric-derived data about\nidentifiable people**: it lives outside the repo by default and must never be\ncommitted. `enroll` also stores embeddings of the source recording's *other*\nspeakers so the centering mean stays multi-speaker; `forget --recording <id>` is\nthe instrument that erases those.\n\n## Development\n\n```bash\nnpm test   # vitest: pure-logic + mocked I/O (no network, no binaries)\n```\n\nThe bin runs as TypeScript via pi's jiti loader — no build step. Standalone\nexecution outside pi is out of scope for this package.\n","readmeFilename":"README.md"}