{"id":13902929,"url":"https://github.com/kitschpatrol/vidup","last_synced_at":"2026-02-27T18:02:14.776Z","repository":{"id":232242287,"uuid":"783823771","full_name":"kitschpatrol/vidup","owner":"kitschpatrol","description":"Synchronize a local directory of video files to remote streaming services.","archived":false,"fork":false,"pushed_at":"2024-09-14T20:47:30.000Z","size":582,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-09-15T05:30:21.035Z","etag":null,"topics":["bunnycdn","bunnycdn-stream","cli","npm-package","sync","upload","video"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kitschpatrol.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-08T16:36:12.000Z","updated_at":"2024-09-14T20:47:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"2dceefc7-3184-4f22-a195-10a3bd3ff918","html_url":"https://github.com/kitschpatrol/vidup","commit_stats":null,"previous_names":["kitschpatrol/vidup"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fvidup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fvidup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fvidup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fvidup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kitschpatrol","download_url":"https://codeload.github.com/kitschpatrol/vidup/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225368358,"owners_count":17463379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bunnycdn","bunnycdn-stream","cli","npm-package","sync","upload","video"],"created_at":"2024-08-06T22:01:30.292Z","updated_at":"2026-02-27T18:02:09.708Z","avatar_url":"https://github.com/kitschpatrol.png","language":"TypeScript","funding_links":[],"categories":["cli"],"sub_categories":[],"readme":"\u003c!--+ Warning: Content inside HTML comment blocks was generated by mdat and may be overwritten. +--\u003e\n\n\u003c!-- title --\u003e\n\n# vidup\n\n\u003c!-- /title --\u003e\n\n\u003c!-- badges --\u003e\n\n[![NPM Package vidup](https://img.shields.io/npm/v/vidup.svg)](https://npmjs.com/package/vidup)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n\u003c!-- /badges --\u003e\n\n\u003c!-- short-description --\u003e\n\n**Synchronize a local directory of video files to remote streaming services.**\n\n\u003c!-- /short-description --\u003e\n\n\u003e [!WARNING]\n\u003e This tool was built in haste and has been tested only against a relatively narrow use-case. If you use it, please review the docs, invoke with care, and make sure you have local copies of your remote videos and metadata.\n\n## Overview\n\nVidup is a CLI tool and Node library to automate one-way synchronization of local video files to remote video streaming CDN services.\n\nIt checks for differences between your local and remote videos, and automatically creates, updates, or deletes videos on the remote service so that it exactly mirrors the contents of a local directory.\n\nCurrently, only Bunny.net's [Bunny Stream](https://bunny.net/stream/) service is supported as a sync target. Adding support additional platforms like [Mux](https://www.mux.com) and [Cloudflare Stream](https://www.cloudflare.com/products/cloudflare-stream/) wouldn't be too tricky.\n\n## Getting started\n\n### Dependencies\n\nThe vidup CLI tool requires Node 20.9.0+. The exported APIs are ESM-only and share the Node 20.9.0+ requirement. Vidup is implemented in TypeScript and bundles type definitions.\n\nA [Bunny Stream](https://bunny.net/stream/) account, API key, and library ID are required.\n\n### Installation\n\nInvoke directly:\n\n```sh\nnpx vidup\n```\n\nOr, install locally to access the CLI commands in a single project or to import the provided APIs:\n\n```sh\nnpm install vidup\n```\n\nOr, install globally for access across your system:\n\n```sh\nnpm install --global vidup\n```\n\n## Usage\n\nVidup treats local videos' file names as keys, and will look for a file with the same name / title on the remote streaming service.\n\nAny video files present in the local folder that aren't matched to a video on the remote service will be uploaded.\n\nIf you change the name of a local video file, the remote video with the previous name will be deleted, and a new remote video (with a ne GUID) will be created.\n\nVidup tracks the content hash of each local video. If you replace a local video file with another of the same name, the change in content will be detected and the remote video will be updated.\n(_Note that this is currently equivalent to deleting / creating a new remote video since Bunny.net doesn't support in-place video updates. The GUID will change, so you'll need to update any embeds accordingly._)\n\nAny videos present on the remote service that aren't matched to a video file in the local folder **will be deleted from the remote service**.\n\n### CLI\n\n\u003c!-- cli-help --\u003e\n\n#### Command: `vidup`\n\nRun a vidup command.\n\nThis section lists top-level commands for `vidup`.\n\nIf no command is provided, `vidup sync` is run by default.\n\nUsage:\n\n```txt\nvidup [command]\n```\n\n| Command | Argument                  | Description                                                                                                                                                                                                             |\n| ------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `sync`  | `\u003cdirectory\u003e` `[options]` | Synchronize a remote video streaming service to mirror the contents of a local directory. Warning: This command will irrevocably delete remote videos that are not present in the local directory. _(Default command.)_ |\n\n_See the sections below for more information on each subcommand._\n\n#### Subcommand: `vidup sync`\n\nSynchronize a remote video streaming service to mirror the contents of a local directory. Warning: This command will irrevocably delete remote videos that are not present in the local directory.\n\nUsage:\n\n```txt\nvidup sync \u003cdirectory\u003e [options]\n```\n\n| Positional Argument | Description                                                           | Type     |\n| ------------------- | --------------------------------------------------------------------- | -------- |\n| `directory`         | The path to the local directory of video files to sync. _(Required.)_ | `string` |\n\n| Option              | Description                                                                                                                               | Type                             | Default |\n| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------- |\n| `--service`\u003cbr\u003e`-s` | Streaming service / platform to sync local video files to. Only the Bunny.net streaming CDN is supported at this time.                    | `\"bunny\"` `\"mux\"` `\"cloudflare\"` |         |\n| `--key`             | Streaming service API access key.                                                                                                         | `string`                         |         |\n| `--library`         | Streaming service library ID.                                                                                                             | `string`                         |         |\n| `--strip-metadata`  | Remove all metadata from the video files before uploading them to the streaming service. Warning: This will modify local videos in-place. | `boolean`                        | `false` |\n| `--dry-run`\u003cbr\u003e`-d` | Perform a dry run without making any changes. Useful for testing and debugging. Pairs well with the `--json` command.                     | `boolean`                        | `false` |\n| `--json`            | Output the sync report as JSON.                                                                                                           | `boolean`                        | `false` |\n| `--verbose`         | Enable verbose logging. All verbose logs and prefixed with their log level and are printed to `stderr` for ease of redirection.           | `boolean`                        | `false` |\n| `--help`\u003cbr\u003e`-h`    | Show help                                                                                                                                 | `boolean`                        |         |\n| `--version`\u003cbr\u003e`-v` | Show version number                                                                                                                       | `boolean`                        |         |\n\n\u003c!-- /cli-help --\u003e\n\n#### CLI Examples\n\n**Synchronize video files in the current folder to Bunny Stream:**\n\n```sh\nvidup . --service bunny --key \u003cBUNNY_API_KEY\u003e --library \u003cBUNNY_LIBRARY_ID\u003e\n```\n\nLarge uploads can take some time. Upon completion, a report summarizing the actions taken is printed to stdout:\n\n```sh\nNone: an-already-uploaded-video.mov\nCreate: a-new-video.mov\nUpdate: a-changed-video.mp4\nDelete: a-remote-only-video.mp4\n```\n\n**Perform a non-executive dry run and get the synchronization plan report as JSON:**\n\n```sh\nvidup . --json --dry-run --service bunny --key \u003cBUNNY_API_KEY\u003e --library \u003cBUNNY_LIBRARY_ID\u003e\n```\n\nThe JSON version of the output provides some extra info.\n\n### Library\n\n#### API\n\nVidup's functionality is also provided in module form for use in TypeScript or JavaScript Node projects.\n\nThe library exports `syncVideoInDirectory`, which takes an options argument mirroring the arguments available via the command line and returns an object reporting the synchronization steps performed:\n\n```ts\nasync function syncVideoInDirectory(\n  directory: string,\n  options: {\n    credentials: {\n      key: string\n      library: string\n    }\n    dryRun?: boolean // Defaults to false\n    service: Service\n    verbose?: boolean // Defaults to false\n  },\n): Promise\u003cSyncReport\u003e\n```\n\nA `stripVideoMetadataInDirectory` function is also exported, which will remove metadata from all videos in the target directory. It returns a list of video filepaths with metadata:\n\n```ts\nexport async function stripVideoMetadataInFiles(\n  directory: string,\n  options: {\n    dryRun?: boolean // Defaults to false\n    verbose?: boolean // Defaults to false\n  },\n): Promise\u003cstring[]\u003e\n```\n\n#### API Examples\n\n```ts\nimport { syncVideoInDirectory } from 'vidup'\n\nconst syncReport = await syncVideoInDirectory(process.cwd(), {\n  credentials: {\n    key: BUNNY_API_KEY,\n    library: BUNNY_LIBRARY_ID,\n  },\n  service: 'bunny',\n})\n\nconsole.log(JSON.stringify(syncReport, undefined, 2))\n```\n\n## Background\n\n### Motivation\n\nVideo streaming providers have slow and clunky web UIs. I'd rather not maintain the remote collection by hand. The web these days makes Finder.app feel like a CRUD tour-de-force.\n\n## The future\n\n- [ ] Tests\n- [ ] Add [Cosmiconfig](https://github.com/cosmiconfig/cosmiconfig)\n- [ ] Synchronize thumbnails and other metadata\n- [ ] Remote collection / folder support\n- [ ] Mux support\n- [ ] Cloudflare Stream support\n- [ ] Support for additional streaming services\n\n## Maintainers\n\n[@kitschpatrol](https://github.com/kitschpatrol)\n\n## Acknowledgments\n\nThanks to [@dan-online](https://github.com/dan-online) for his super-helpful [bunnycdn-stream](https://github.com/dan-online/bunnycdn-stream) library.\n\n\u003c!-- footer --\u003e\n\n## Contributing\n\n[Issues](https://github.com/kitschpatrol/vidup/issues) and pull requests are welcome.\n\n## License\n\n[MIT](license.txt) © Eric Mika\n\n\u003c!-- /footer --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkitschpatrol%2Fvidup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkitschpatrol%2Fvidup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkitschpatrol%2Fvidup/lists"}