Manim Voiceover supports translating scenes into other languages. It uses the gettext convention of wrapping translatable strings in
_(). gettext is an established internationalization and localization (i18n and l10n) system commonly used for writing multilingual programs. It allows you to keep your Manim scenes and all of the translations organized neatly in the same git repository.
Check out the translation example:
import os from manim import * from manim_voiceover import VoiceoverScene from manim_voiceover.services.gtts import GTTSService from manim_voiceover.translate import get_gettext # It is good practice to get the LOCALE and DOMAIN from environment variables LOCALE = os.getenv("LOCALE") DOMAIN = os.getenv("DOMAIN") # The following function uses LOCALE and DOMAIN to set the language, and # returns a gettext function that is used to insert translations. _ = get_gettext() class TranslationExample(VoiceoverScene): def construct(self): # We use the free TTS service from Google Translate # The TTS language is set via the LOCALE environment variable self.set_speech_service(GTTSService(lang=LOCALE)) circle = Circle() square = Square().shift(2 * RIGHT) # The voiceover strings are wrapped in _() # This means that their translations will be looked up in the .po files # and used to replace the original strings with self.voiceover(text=_("This circle is drawn as I speak.")) as tracker: self.play(Create(circle), run_time=tracker.duration) with self.voiceover(text=_("Let's shift it to the left 2 units.")) as tracker: self.play(circle.animate.shift(2 * LEFT), run_time=tracker.duration) with self.voiceover( text=_("Now, let's transform it into a square.") ) as tracker: self.play(Transform(circle, square), run_time=tracker.duration) with self.voiceover(text=_("Thank you for watching.")): self.play(Uncreate(circle)) self.wait()
We have introduced the command line utility
manim_render_translation to make it easier to render translations. It is similar to calling
manim render, but it also lets you choose which locale (i.e. language) to render:
# Assuming you are in the root directory of manim-voiceover repo cd examples/translation-example manim_render_translation translation-example.py \ -s TranslationExample \ -d translation-example \ -l de,vi \ -qh
-s: Scene to render.
-d: gettext domain (the name of the translation file wihout the
-l: Locale to render. If not specified, all locales will be rendered.
-q: Render quality, same as in
For more information, run
Translating scenes with machine translation#
We have also introduced the command line utility
manim_translate to make it easier to translate scenes. It uses the DeepL API to translate the voiceover strings in a scene into other languages. DeepL is a paid service, but it allows you to translate up to 500,000 characters per month for free. You can sign up for a free account here.
Once you have signed up for a DeepL account, generate an API key and set it as the environment variable
DEEPL_API_KEY. If you save it in a file
.env in the root directory of the project, it will be automatically loaded when you run
manim_translate. For example,
# Assuming you are in the root directory of manim-voiceover repo cd examples/translation-example manim_translate translation-example.py \ -s en \ -t tr \ -d translation-example
-s: Original (source) language of the scene.
-t: Target language to translate to.
-d: gettext domain to save the translation to (the name of the translation file wihout the
Running this command will generate a file
locale/tr/LC_MESSAGES/translation-example.po containing the translated strings. You can then render the scene in Turkish by running
manim_render_translation translation-example.py -s TranslationExample -d translation-example -l tr
For more information, run
Manim Voiceover follows the ISO 639-1 standard for language codes. For example, the language code for English is
en, and the language code for Vietnamese is
The DeepL API documentation has more detailed information about the available languages. If DeepL has added support for a new language and it is not yet available in Manim Voiceover, please open an issue or submit a pull request to get it included.
Editing and maintaining translations#
The translations generated by
manim_translate can be edited manually in the
.po files. You can also use a GUI tool such as Poedit to edit the translations. The
.po files are in the gettext format, which is a standard for storing translations. You can find more information about the format here.
manim_translate will not overwrite your existing translations, and instead will only fill in the missing translations. If you make changes to the original scene, you can run
manim_translate again. This will insert the new strings into the
locale/<domain>/LC_MESSAGES/<domain>.po files, and use DeepL to translate the new strings into the target languages.
We recommend to start a git repository for your project, and include the
.po files. This will make it easier to track changes to the translations and to merge changes from other contributors. It will also allow you to revert back to an earlier version of the translations if you make a mistake.
Do not include
.mo files in your git repository. These are binary files that are automatically generated from the
.po files. Add the line
*.mo to your
.gitignore file to prevent them from being added to your git repository.