{"id":30459670,"url":"https://github.com/profullstack/viral-video","last_synced_at":"2026-05-09T19:01:43.953Z","repository":{"id":309242050,"uuid":"1034884206","full_name":"profullstack/viral-video","owner":"profullstack","description":"Make a viral video from the CLI","archived":false,"fork":false,"pushed_at":"2025-08-10T18:17:52.000Z","size":205,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-23T21:49:05.275Z","etag":null,"topics":["ffmpeg","node","video","viral"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/profullstack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2025-08-09T07:16:17.000Z","updated_at":"2025-08-11T01:02:00.000Z","dependencies_parsed_at":"2025-08-10T20:29:38.024Z","dependency_job_id":null,"html_url":"https://github.com/profullstack/viral-video","commit_stats":null,"previous_names":["profullstack/viral-video"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/profullstack/viral-video","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profullstack%2Fviral-video","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profullstack%2Fviral-video/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profullstack%2Fviral-video/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profullstack%2Fviral-video/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/profullstack","download_url":"https://codeload.github.com/profullstack/viral-video/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profullstack%2Fviral-video/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32831504,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["ffmpeg","node","video","viral"],"created_at":"2025-08-23T18:48:54.866Z","updated_at":"2026-05-09T19:01:43.944Z","avatar_url":"https://github.com/profullstack.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# @profullstack/viral-video\n\nGenerate 60‑sec Viral Video Kits\n\n\u003c!-- BADGES:START --\u003e\n\u003cp align=\"left\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@profullstack/viral-video\"\u003e\u003cimg alt=\"npm version\" src=\"https://img.shields.io/npm/v/%40profullstack%2Fviral-video?style=for-the-badge\"\u003e\u003c/a\u003e\n  \u003ca href=\"#license\"\u003e\u003cimg alt=\"license\" src=\"https://img.shields.io/badge/license-MIT-green?style=for-the-badge\"\u003e\u003c/a\u003e\n  \u003ca href=\"./package.json\"\u003e\u003cimg alt=\"node\" src=\"https://img.shields.io/badge/node-%3E%3D20.0.0-339933?logo=node.js\u0026amp;logoColor=white\u0026amp;style=for-the-badge\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pnpm.io/\"\u003e\u003cimg alt=\"pnpm\" src=\"https://img.shields.io/badge/pnpm-9%2B-F69220?logo=pnpm\u0026amp;logoColor=white\u0026amp;style=for-the-badge\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://mochajs.org/\"\u003e\u003cimg alt=\"tests\" src=\"https://img.shields.io/badge/tests-Mocha-8D6748?logo=mocha\u0026amp;logoColor=white\u0026amp;style=for-the-badge\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://nodejs.org/api/esm.html\"\u003e\u003cimg alt=\"esm\" src=\"https://img.shields.io/badge/ESM-Enabled-000000?style=for-the-badge\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003c!-- BADGES:END --\u003e\nGenerate a complete short‑video kit from a topic: script, scene images, captions, voiceover, and an optional rendered MP4. Built for Node.js 20+ using modern ESM.\n\nCore files:\n- CLI entry: [bin/viral.js](bin/viral.js)\n- Main runtime: [run()](src/index.js:460)\n- Image generation helper: [generateImage()](src/index.js:176)\n- CLI helpers: [usage()](bin/viral.js:72), [setupCommand()](bin/viral.js:143), [prompt()](bin/viral.js:107)\n\nFeatures\n- 1080×1920 vertical target with smooth zoom pan\n- Script+captions tailored to the requested duration\n- Per‑scene image prompts; styles: cartoon, realistic, ai-generated\n- Voiceover via OpenAI TTS (ElevenLabs key persisted for future TTS integration)\n- Config precedence: environment \u003e user config \u003e defaults\n\nRequirements\n- Node.js 20+\n- pnpm 9+\n- ffmpeg (optional, for auto‑render)\n\nInstall\n\n```bash\npnpm add -D @profullstack/viral-video\n# or run without installing:\npnpm dlx @profullstack/viral-video viral --help\n```\n\nOptionally link CLI globally:\n\n```bash\npnpm add -g @profullstack/viral-video\n# or from a local checkout:\npnpm link --global\n# then you can run: viral ...\n```\n\nSetup\n\nUse interactive mode to save API keys at ~/.config/viral-video/config.json (0600 perms):\n\n```bash\nviral setup\n```\n\nOr non‑interactive:\n\n```bash\nviral setup --openai-key sk-... --elevenlabs-key el-... --voice luna --video-sec 60\n```\n\nCreate a video kit\n\n```bash\nviral create --topic \"How to make money while you sleep\" --male --cartoon\n```\n\nFlags\n- --topic \"...\" required\n- --male | --female sets TTS voice preset\n- --cartoon | --realistic | --ai-generated image style\n- --dry-run validate flow without calling APIs or ffmpeg\n\nWhat gets generated\n\nInside build/your-topic/:\n- vertical/\n  - scenes/sceneXX.png: portrait frames (generated at 1024×1536, upscaled to 1080×1920 on render)\n  - audio/voiceover.mp3 (copied)\n  - captions.ass\n  - storyboard.csv\n  - build/: intermediate segments and rendered artifacts\n  - output.mp4: final portrait video (when ffmpeg available)\n- horizontal/\n  - scenes/sceneXX.png: landscape frames (generated at 1536×1024, upscaled to 1920×1080 on render)\n  - audio/voiceover.mp3 (copied)\n  - captions.ass\n  - storyboard.csv\n  - build/: intermediate segments and rendered artifacts\n  - output.mp4: final landscape video (when ffmpeg available)\n- audio/voiceover.mp3: root voiceover source\n- README.md: per‑video instructions\n\nRendering details\n\nThe pipeline scales frames using ffmpeg to 1080×1920:\n- We request OpenAI images at 1024×1536 (portrait) due to API constraints, then upscale to 1080×1920 during render.\n- If ffmpeg is installed, rendering runs automatically:\n  - macOS: brew install ffmpeg\n  - Ubuntu: sudo apt-get update \u0026\u0026 sudo apt-get install -y ffmpeg\n\nConfiguration\n\nPrecedence: env \u003e user config \u003e defaults. The config loader lives in [run()](src/index.js:460) and the setup logic is in [setupCommand()](bin/viral.js:143).\n\nEnvironment variables\n- OPENAI_API_KEY: required unless DRY_RUN=1\n- ELEVENLABS_API_KEY: optional (future TTS)\n- TEXT_MODEL (default gpt-5)\n- IMAGE_MODEL (default gpt-image-1)\n- TTS_MODEL (default gpt-4o-mini-tts)\n- TTS_VOICE (default alloy; use luna for female)\n- VIDEO_SEC (default 60)\n- SCENES_COUNT (default 6)\n\nUser config file\n- Path: ~/.config/viral-video/config.json or $XDG_CONFIG_HOME/viral-video/config.json\n- Written by [setupCommand()](bin/viral.js:143) with chmod 600\n\nExamples\n\nValidate without APIs:\n\n```bash\nDRY_RUN=1 viral create --topic \"SEC Bitcoin ETF timeline\" --ai-generated\n```\n\nFemale realistic style:\n\n```bash\nviral create --topic \"Dollar-cost averaging explained\" --female --realistic\n```\n\nTroubleshooting\n- Missing OPENAI_API_KEY: run viral setup or export OPENAI_API_KEY.\n- “Unsupported image size”: fixed by generating 1024×1536 and scaling during render in [generateImage()](src/index.js:176).\n- Interactive setup “hang”: resolved by releasing stdin in [prompt()](bin/viral.js:107).\n\nDevelopment\n\n```bash\npnpm test\npnpm lint\npnpm format\n```\n\nLicense\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprofullstack%2Fviral-video","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprofullstack%2Fviral-video","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprofullstack%2Fviral-video/lists"}