{"id":27817205,"url":"https://github.com/transformrs/trv","last_synced_at":"2025-05-01T14:43:27.815Z","repository":{"id":278385287,"uuid":"935411114","full_name":"transformrs/trv","owner":"transformrs","description":"Transform slides and speaker notes into video","archived":false,"fork":false,"pushed_at":"2025-04-12T13:12:52.000Z","size":128,"stargazers_count":35,"open_issues_count":9,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-24T13:48:42.900Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","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/transformrs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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-02-19T11:59:41.000Z","updated_at":"2025-04-19T17:40:18.000Z","dependencies_parsed_at":"2025-04-03T21:28:15.814Z","dependency_job_id":"24512594-c8a7-4fb5-9fa0-ae75e43060b6","html_url":"https://github.com/transformrs/trv","commit_stats":null,"previous_names":["transformrs/tv","transformrs/trv"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transformrs%2Ftrv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transformrs%2Ftrv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transformrs%2Ftrv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transformrs%2Ftrv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/transformrs","download_url":"https://codeload.github.com/transformrs/trv/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251892521,"owners_count":21660983,"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":[],"created_at":"2025-05-01T14:43:27.300Z","updated_at":"2025-05-01T14:43:27.805Z","avatar_url":"https://github.com/transformrs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# trv\n\nTransform slides and speaker notes into video.\n\n[![Demo video](https://transformrs.github.io/trv/demo.png)](https://transformrs.github.io/trv/demo.mp4)\n\n## Features\n\n- 🛠️ Version control friendly - store your video source in git.\n- 🚀 Caching of audio files to avoid redundant API calls.\n- 🚀 Caching of video files for quick re-builds.\n- 🚀 A development mode with a built-in web server for fast feedback.\n- 🌐 Support for multiple languages and voices.\n- 🚀 Small file sizes for easy sharing and hosting.\n- 🔒 Support for fully offline video generation via the Kokoro text-to-speech model.\n\n## Installation\n\n```raw\n$ cargo install trv\n```\n\nIt also requires [`ffmpeg`](https://ffmpeg.org/) and [`typst`](https://github.com/typst/typst?tab=readme-ov-file#installation) to be installed.\n\n## Usage\n\nThis tool is designed to work with [Typst](https://github.com/typst/typst) presentations.\nTypst is a new typesetting system that is similar to LaTeX.\nTo create a video, create a Typst presentation with speaker notes (we show only the first slide here):\n\n```typ\n#import \"@preview/polylux:0.4.0\": *\n\n#set page(paper: \"presentation-16-9\")\n\n// --- trv config:\n// provider = \"openai-compatible(kokoros.transformrs.org)\"\n// model = \"tts-1\"\n// voice = \"af_sky\"\n// speed = 0.95\n// audio_format = \"wav\"\n// ---\n\n#slide[\n    #set page(fill: black)\n    #set text(fill: white)\n    #v(6em)\n    #set text(size: 35pt)\n    #align(center)[*Text to video*]\n    #toolbox.pdfpc.speaker-note(\n    ```md\n    What if you could easily generate videos from text?\n    ```\n    )\n]\n```\n\nNext, we can work on the video with the following command:\n\n```raw\n$ trv watch examples/first.typ\n```\n\nThis will start a local web server that will automatically update the video as you make changes to the presentation.\n\nOnce everything looks good, we can build the final video with the following command:\n\n```raw\n$ trv build examples/first.typ\n```\n\nThis generates the following video:\n\n[![First demo video](https://transformrs.github.io/trv/first.png)](https://transformrs.github.io/trv/first.mp4)\n\n## Offline\n\nTo create a video without an API key nor an internet connection, you can self-host [Kokoros](https://github.com/lucasjinreal/Kokoros).\nSee the [Kokoros section](#kokoros) for more information.\n\n## Via DeepInfra\n\nFor more voices and faster audio generation, you can use the Kokoro models hosted at DeepInfra.\n\n```raw\n$ export DEEPINFRA_KEY=\"\u003cYOUR KEY\u003e\"\n\n$ trv --input=presentation.typ\n INFO Generating audio file for slide 0\n INFO Generating audio file for slide 1\n INFO Creating video clip _out/1.mp4\n INFO Created video clip _out/1.mp4\n INFO Creating video clip _out/2.mp4\n INFO Created video clip _out/2.mp4\n INFO Concatenated video clips into _out/out.mp4\n```\n\n\nTo create a video without an API key nor an internet connection, you can self-host [Kokoros](https://github.com/lucasjinreal/Kokoros).\nSee the [Kokoros section](#kokoros) for more information.\nOr for a state-of-the-art model with voice cloning capabilities, see the [Zyphra Zonos section](#zyphra-zonos).\n\n## Kokoros\n\nKokoros is available at `kokoros.transformrs.org`, to use that one, set the following in your `trv` config:\n\n```typ\n// --- trv config:\n// provider = \"openai-compatible(kokoros.transformrs.org)\"\n// model = \"tts-1\"\n// voice = \"af_sky\"\n// audio_format = \"wav\"\n// ---\n```\n\nIf you want to use Kokoros locally, the easiest way is to use the Docker image.\n\n```raw\n$ git clone https://github.com/lucasjinreal/Kokoros.git\n\n$ cd Kokoros/\n\n$ docker build --rm -t kokoros .\n\n$ docker run -it --rm -p 3000:3000 kokoros openai\n```\n\nThen, you can use the Docker image as the provider:\n\n```typ\n#import \"@preview/polylux:0.4.0\": *\n\n// --- trv config:\n// provider = \"openai-compatible(localhost:3000)\"\n// model = \"tts-1\"\n// voice = \"af_sky\"\n// audio_format = \"wav\"\n// ---\n\n...\n```\n\n```raw\n$ trv build presentation.typ\n```\n\n## Google\n\nAnother text-to-speech engine is the one from Google.\n\n```raw\n$ export GOOGLE_KEY=\"\u003cYOUR KEY\u003e\"\n\n$ trv build examples/google.typ\n```\n\n[![Google demo video](https://transformrs.github.io/trv/google.png)](https://transformrs.github.io/trv/google.mp4)\n\n## ElevenLabs\n\nThe following settings use the \"Brian\" voice from ElevenLabs:\n\n```typst\n#import \"@preview/polylux:0.4.0\": *\n\n// --- trv config:\n// provider = \"elevenlabs\"\n// seed = 42\n// model = \"eleven_multilingual_v2\"\n// voice = \"nPczCjzI2devNBz1zQrb\"\n// ---\n```\n\nQuality is [generally higher](https://huggingface.co/spaces/TTS-AGI/TTS-Arena), but note that the price is also much higher.\nWith DeepInfra Kokoro, you pay about $0.80 per million characters.\nWith ElevenLabs, you pay $0.30 per 1000 credits (equals 1000 characters), or $300 for 1 million credits.\n\nHere is a YouTube video that was made with ElevenLabs:\n\n[![ElevenLabs demo](https://img.youtube.com/vi/Ni-dKlCpnb4/0.jpg)](https://www.youtube.com/watch?v=Ni-dKlCpnb4)\n\n## Zyphra Zonos\n\nTo use the Zyphra Zonos model, you need 8 GB of VRAM.\nSo it's probably easiest to use DeepInfra:\n\n```typst\n#import \"@preview/polylux:0.4.0\": *\n\n// --- trv config:\n// provider = \"deepinfra\"\n// model = \"Zyphra/Zonos-v0.1-transformer\"\n// voice = \"american_male\"\n// audio_format = \"mp3\"\n// ---\n```\n\n```raw\n$ export DEEPINFRA_KEY=\"\u003cYOUR KEY\u003e\"\n\n$ trv build examples/zonos.typ\n```\n\n[![Zyphra Zonos demo video](https://transformrs.github.io/trv/zonos.png)](https://transformrs.github.io/trv/zonos.mp4)\n\nHere the model was set to the transformer (`Zonos-v0.1-transformer`) model instead of the hybrid one (`Zonos-v0.1-hybrid`).\nAccording to the [Zyphra Zonos playground](https://playground.zyphra.com/audio), the transformer model is better for \"clear articulation\" and \"better with long texts\".\nThe hybrid model is better for \"emotional speech\", with a \"more natural prosody\", and is \"better for short phrases\".\nSince slides typically have relatively long texts, the transformer model is probably the better option.\n\n## Portrait Video\n\nTo create a portrait video, like a YouTube Short, you can set the page to\n\n```typ\n#set page(width: 259.2pt, height: 460.8pt)\n```\n\nThe rest should work as usual.\nThis will automatically create slides with 1080 x 1920 resolution since Typst is set to 300 DPI.\nNext, ffmpeg will automatically scale the video to a height of 1920p so in this case the height will not be changed.\nFor landscape videos, it might scale the image down to 1920p.\n\n## Static Videos\n\nThe videos created by `trv` consist only of static images.\nThis might seem limiting, but as long as the content of the video is high, static images should be fine.\nHere are some YouTubers that have hundreds of thousands to millions of views with only static images:\n\n- [Asianometry](https://www.youtube.com/@Asianometry)\n- [Perun](https://www.youtube.com/@PerunAU)\n- [No Boilerplate](https://www.youtube.com/@NoBoilerplate)\n- [The Histocrat](https://www.youtube.com/@TheHistocrat)\n- [Christopher Manning](https://youtu.be/5Aer7MUSuSU)\n- [Richard McElreath](https://www.youtube.com/@rmcelreath)\n\nStatic images with a talking-head:\n\n- [Tony Seba](https://www.youtube.com/@tonyseba)\n- [The Wild West Extravaganza](https://www.youtube.com/@WildWestExtravaganza)\n- [Andrej Karpathy](https://youtu.be/zjkBMFhNj_g)\n\nStatic images with a computer-generated moving hand:\n\n- [Simplilearn](https://www.youtube.com/@SimplilearnOfficial)\n\n## Subtitles\n\nTo add subtitles to the video, you can use OpenAI's [`whisper`](https://github.com/openai/whisper):\n\n```raw\n$ whisper _out/out.mp4 -f srt --model small --language=en\n```\n\nThis will create a `out.srt` file with the subtitles.\n\n## Extracting the Speaker Notes\n\nThe speaker notes (narration) can be extracted from the Typst file with the `notes` command.\nFor example:\n\n```raw\n$ trv notes presentation.typ\n```\n\nThis will print the speaker notes to the terminal.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftransformrs%2Ftrv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftransformrs%2Ftrv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftransformrs%2Ftrv/lists"}