git: 065e40e5f9b3 - main - misc/py-kokoro: Add programs; Add model URL to WWW; Add to pkg-descr
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 18 Mar 2026 16:43:49 UTC
The branch main has been updated by yuri:
URL: https://cgit.FreeBSD.org/ports/commit/?id=065e40e5f9b35adbd23c4fbae602f0bdf34bb67b
commit 065e40e5f9b35adbd23c4fbae602f0bdf34bb67b
Author: Yuri Victorovich <yuri@FreeBSD.org>
AuthorDate: 2026-03-18 16:03:30 +0000
Commit: Yuri Victorovich <yuri@FreeBSD.org>
CommitDate: 2026-03-18 16:43:47 +0000
misc/py-kokoro: Add programs; Add model URL to WWW; Add to pkg-descr
Programs:
* bin/kokoro-text-to-audio - speaks a given text
* bin/kokoro-text-to-wav - converts a given text to a WAV file
---
misc/py-kokoro/Makefile | 19 ++++++++++--
misc/py-kokoro/files/kokoro-text-to-audio.py | 44 ++++++++++++++++++++++++++++
misc/py-kokoro/files/kokoro-text-to-wav.py | 42 ++++++++++++++++++++++++++
misc/py-kokoro/pkg-descr | 3 ++
4 files changed, 105 insertions(+), 3 deletions(-)
diff --git a/misc/py-kokoro/Makefile b/misc/py-kokoro/Makefile
index 38e460daedaa..0deca2a331f4 100644
--- a/misc/py-kokoro/Makefile
+++ b/misc/py-kokoro/Makefile
@@ -1,12 +1,14 @@
PORTNAME= kokoro
DISTVERSION= 0.9.4
+PORTREVISION= 1
CATEGORIES= misc python # machine-learning
MASTER_SITES= PYPI
PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}
MAINTAINER= yuri@FreeBSD.org
COMMENT= Text-to-speech inference library for Kokoro-82M model
-WWW= https://github.com/hexgrad/kokoro
+WWW= https://github.com/hexgrad/kokoro \
+ https://huggingface.co/hexgrad/Kokoro-82M
LICENSE= APACHE20
LICENSE_FILE= ${WRKSRC}/LICENSE
@@ -20,17 +22,28 @@ RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}huggingface-hub>0:misc/py-huggingface-hub@${
${PYTHON_PKGNAMEPREFIX}pytorch>0:misc/py-pytorch@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}spacy>0:textproc/py-spacy@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}transformers>=0:misc/py-transformers@${PY_FLAVOR}
-TEST_DEPENDS= ${PYTHON_PKGNAMEPREFIX}ipython>0:devel/ipython@${PY_FLAVOR} \
+# extra run dependencies for kokoro-text-to-audio and kokoro-text-to-wav
+RUN_DEPENDS+= ${PYTHON_PKGNAMEPREFIX}ipython>0:devel/ipython@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}SoundFile>0:audio/py-SoundFile@${PY_FLAVOR} \
mpv:multimedia/mpv
USES= python
-USE_PYTHON= autoplist concurrent pep517
+USE_PYTHON= pep517 concurrent autoplist
NO_ARCH= yes
+PLIST_FILES= bin/kokoro-text-to-audio \
+ bin/kokoro-text-to-wav
+
TEST_ENV= ${MAKE_ENV} PYTHONPATH=${STAGEDIR}${PYTHONPREFIX_SITELIBDIR}
+post-install:
+ ${INSTALL_SCRIPT} ${FILESDIR}/kokoro-text-to-audio.py ${STAGEDIR}${PREFIX}/bin/kokoro-text-to-audio
+ ${INSTALL_SCRIPT} ${FILESDIR}/kokoro-text-to-wav.py ${STAGEDIR}${PREFIX}/bin/kokoro-text-to-wav
+ @${REINPLACE_CMD} -i '' 's|%%PYTHON%%|${PYTHON_CMD}|' \
+ ${STAGEDIR}${PREFIX}/bin/kokoro-text-to-audio \
+ ${STAGEDIR}${PREFIX}/bin/kokoro-text-to-wav
+
do-test:
@cd ${WRKSRC} && \
${SETENV} ${TEST_ENV} ${PYTHON_CMD} ${FILESDIR}/example.py && \
diff --git a/misc/py-kokoro/files/kokoro-text-to-audio.py b/misc/py-kokoro/files/kokoro-text-to-audio.py
new file mode 100644
index 000000000000..71cb682737d6
--- /dev/null
+++ b/misc/py-kokoro/files/kokoro-text-to-audio.py
@@ -0,0 +1,44 @@
+#!%%PYTHON%%
+
+import sys
+import os
+import shutil
+import subprocess
+from datetime import datetime
+from kokoro import KPipeline
+import soundfile as sf
+
+def main():
+ if len(sys.argv) != 2:
+ print("Usage: kokoro-text-to-audio <text>", file=sys.stderr)
+ sys.exit(1)
+
+ text = sys.argv[1]
+
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S%f")
+ temp_dir = f"/tmp/kokoro-{timestamp}"
+ temp_wav = os.path.join(temp_dir, "output.wav")
+
+ try:
+ os.makedirs(temp_dir, exist_ok=True)
+
+ pipeline = KPipeline(lang_code='a')
+ generator = pipeline(text, voice='af_heart')
+
+ audio_data = None
+ for _, _, audio in generator:
+ audio_data = audio
+
+ if audio_data is not None:
+ sf.write(temp_wav, audio_data, 24000)
+ subprocess.run(['mpv', temp_wav], check=True)
+ else:
+ print("Error: No audio generated", file=sys.stderr)
+ sys.exit(1)
+
+ finally:
+ if os.path.exists(temp_dir):
+ shutil.rmtree(temp_dir)
+
+if __name__ == '__main__':
+ main()
diff --git a/misc/py-kokoro/files/kokoro-text-to-wav.py b/misc/py-kokoro/files/kokoro-text-to-wav.py
new file mode 100644
index 000000000000..3b14fa09c6c9
--- /dev/null
+++ b/misc/py-kokoro/files/kokoro-text-to-wav.py
@@ -0,0 +1,42 @@
+#!%%PYTHON%%
+
+import sys
+import os
+import shutil
+from datetime import datetime
+from kokoro import KPipeline
+import soundfile as sf
+
+def main():
+ if len(sys.argv) != 3:
+ print("Usage: kokoro-text-to-wav <text> <wav-output-file>", file=sys.stderr)
+ sys.exit(1)
+
+ text = sys.argv[1]
+ output_file = sys.argv[2]
+
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S%f")
+ temp_dir = f"/tmp/kokoro-{timestamp}"
+
+ try:
+ os.makedirs(temp_dir, exist_ok=True)
+
+ pipeline = KPipeline(lang_code='a')
+ generator = pipeline(text, voice='af_heart')
+
+ audio_data = None
+ for _, _, audio in generator:
+ audio_data = audio
+
+ if audio_data is not None:
+ sf.write(output_file, audio_data, 24000)
+ else:
+ print("Error: No audio generated", file=sys.stderr)
+ sys.exit(1)
+
+ finally:
+ if os.path.exists(temp_dir):
+ shutil.rmtree(temp_dir)
+
+if __name__ == '__main__':
+ main()
diff --git a/misc/py-kokoro/pkg-descr b/misc/py-kokoro/pkg-descr
index a551be6f5900..7692605e9411 100644
--- a/misc/py-kokoro/pkg-descr
+++ b/misc/py-kokoro/pkg-descr
@@ -6,3 +6,6 @@ and the Hugging Face ecosystem. The library supports multiple languages
and voices through the Misaki grapheme-to-phoneme engine.
For full English language support, install textproc/py-phonemizer separately.
+
+Kokoro is the fastest production quality English Text-To-Speech convertor
+available as of early 2026.