A new tool from Storyteller: stalign
It’s been a long time coming: there’s now a standalone Storyteller alignment command line tool (and npm library)!
Continuing tefkah’s amazing work with Ghost Story,
we now publish stalign to npm as
@storyteller-platform/align
and to GitLab as
stalign.
The packages published to the GitLab Package Registry are standalone executable
applications — this means that you don’t need Node.js installed to run them! You
will still need ffmpeg installed and available on your PATH in order for
the audio processing and transcription steps to run.
What is stalign?
This is a command line interface (CLI) for running just the alignment pipeline that Storyteller uses to automatically align audiobooks and ebooks. It’s also an npm package, and Storyteller uses it directly through this programmatic interface. That means that when you run the CLI, you’re using exactly the same code that Storyteller uses for alignment!
How to use it
Installation
If you already have Node.js and npm installed, you can use npx to run the CLI.
Note that stalign requires at least Node.js v24 or higher:
npx @storyteller-platform/align --help
If you want to use the standalone executable instead, so that you don’t have to
worry about Node.js versions, you can download the latest executable from
GitLab:
https://gitlab.com/storyteller-platform/storyteller/-/packages?orderBy=created_at&sort=desc&search[]=stalign.
Make sure you download the executable for your operating system and
architecture. On macOS and Linux, you can use chmod +x ./stalign-<os>-<arch>
to make the downloaded file executable. You can also place the file somewhere on
your path, e.g., ~/.local/bin, and rename it to stalign. Then you can simply
run:
stalign --help
Usage
$ ~/Downloads/stalign-linux-x64 --help
Usage: stalign process [--parallel INTEGER] [--codec TYPE] [--bitrate BITRATE] [--max-length INTEGER] [--no-progress] [--log-level TYPE] [--time]
INPUT OUTPUT
stalign-linux-x64 transcribe [--parallel INTEGER] [--language LOCALE] (--engine/-e whisper.cpp [--model/-m MODEL] [--threads INTEGER] [--processors
INTEGER] [--cpu-override CPU_ENGINE] | --engine/-e whisper-server --whisper-server-url URL [--whisper-server-api-key STRING] | --engine/-e
openai-cloud [--openai-model STRING] [--openai-api-key STRING] [--openai-organization STRING] [--openai-base-url URL] | --engine/-e google-cloud
--google-cloud-api-key STRING | --engine/-e microsoft-azure --azure-service-region STRING --azure-subscription-key STRING | --engine/-e
amazon-transcribe --amazon-transcribe-region STRING --amazon-transcribe-access-key-id STRING --amazon-transcribe-secret-access-key STRING | --engine/
-e deepgram --deepgram-api-key STRING [--deepgram-model STRING]) [--no-progress] [--log-level TYPE] [--time] INPUT OUTPUT
stalign-linux-x64 markup [--granularity/-g TYPE] [--language LOCALE] [--no-progress] [--log-level TYPE] [--time] INPUT_PATH OUTPUT_PATH
stalign-linux-x64 align --transcriptions PATH --output PATH --audiobook PATH --epub PATH [--reports PATH] [--no-progress] [--log-level TYPE] [--time]
[--language LOCALE] [--granularity/-g TYPE]
stalign-linux-x64 [--processed-audio PATH] [--transcriptions PATH] [--markedup PATH] [--parallel-transcodes INTEGER] [--parallel-transcribes INTEGER]
--output PATH [--codec TYPE] [--bitrate BITRATE] [--max-length INTEGER] (--engine/-e whisper.cpp [--model/-m MODEL] [--threads INTEGER] [--processors
INTEGER] [--cpu-override CPU_ENGINE] | --engine/-e whisper-server --whisper-server-url URL [--whisper-server-api-key STRING] | --engine/-e
openai-cloud [--openai-model STRING] [--openai-api-key STRING] [--openai-organization STRING] [--openai-base-url URL] | --engine/-e google-cloud
--google-cloud-api-key STRING | --engine/-e microsoft-azure --azure-service-region STRING --azure-subscription-key STRING | --engine/-e
amazon-transcribe --amazon-transcribe-region STRING --amazon-transcribe-access-key-id STRING --amazon-transcribe-secret-access-key STRING | --engine/
-e deepgram --deepgram-api-key STRING [--deepgram-model STRING]) [--granularity/-g TYPE] [--language LOCALE] --audiobook PATH --epub PATH [--reports
PATH] [--no-progress] [--log-level TYPE] [--time]
stalign-linux-x64 help [COMMAND...]
stalign-linux-x64 completion [SHELL] [ARG...]
stalign-linux-x64 completions [SHELL] [ARG...]
stalign-linux-x64 --help
stalign-linux-x64 --version
A CLI to automatically align audiobooks and EPUB files, producing EPUBs with Media Overlays.
help Show help information.
completion Generate shell completion script or provide completions.
completions Generate shell completion script or provide completions.
--help Show help information.
--version Show version information.
process Process audiobook files for transcription.
transcribe Transcribe a directory of audiobook files.
markup Mark up an EPUB file at the provided granularity level
align Run forced alignment to determine where each sentence|word is spoken in the audiobook and produce a new EPUB package with
Media Overlays and embedded audio.
--processed-audio PATH
--transcriptions PATH
--markedup PATH
--parallel-transcodes INTEGER [1]
--parallel-transcribes INTEGER [1]
--output PATH
--granularity, -g TYPE [sentence] (choices: word, sentence)
--language LOCALE BCP 47 language tag representing the primary language of the audio (e.g. en-US)
--no-progress Disable the progress bar
--log-level TYPE Log level. If enabled, will disable progress bar. [silent] (choices: silent, debug, info, warn, error)
--time Whether to print timing statistics
Audio processing:
--codec TYPE The audio codec to transcode to. If unspecified, will copy audio data without transcoding. [copy] (choices: libopus,
lipmp3lame, aac, copy)
--bitrate BITRATE The audio bitrate to transcode to ()
--max-length INTEGER The maximum allowed length of a processed audio track, in minutes [120]
whisper.cpp:
--engine, -e whisper.cpp (choices: whisper.cpp)
--model, -m MODEL The whisper model to use [tiny.en] (choices: tiny, tiny.en, tiny-q5_1, tiny.en-q5_1, tiny-q8_0, base, base.en, base-q5_1, ...)
--threads INTEGER [4]
--processors INTEGER The number of processors to use (values greater than 1 may affect timing accuracy) [1]
--cpu-override CPU_ENGINE When provided, will use this whisper variant even if another is available (choices: blas, cpu)
whisper-server:
--engine, -e whisper-server (choices: whisper-server)
--whisper-server-url URL
--whisper-server-api-key STRING
openai-cloud:
--engine, -e openai-cloud (choices: openai-cloud)
--openai-model STRING
--openai-api-key STRING
--openai-organization STRING
--openai-base-url URL
google-cloud:
--engine, -e google-cloud (choices: google-cloud)
--google-cloud-api-key STRING
microsoft-azure:
--engine, -e microsoft-azure (choices: microsoft-azure)
--azure-service-region STRING
--azure-subscription-key STRING
amazon-transcribe:
--engine, -e amazon-transcribe (choices: amazon-transcribe)
--amazon-transcribe-region STRING
--amazon-transcribe-access-key-id STRING
--amazon-transcribe-secret-access-key STRING
deepgram:
--engine, -e deepgram (choices: deepgram)
--deepgram-api-key STRING
--deepgram-model STRING [nova-3]
Alignment:
--audiobook PATH
--epub PATH
--reports PATH
stalign has four subcommands: process, markup, transcribe, and align.
It can also be run without specifying a subcommand, in which case the entire
alignment pipeline will be run on the input book files.
stalign help process
Usage: stalign process [--parallel INTEGER] [--codec TYPE] [--bitrate BITRATE] [--max-length INTEGER] [--no-progress] [--log-level TYPE] [--time]
INPUT OUTPUT
Process audiobook files for transcription.
--parallel INTEGER How many files to attempt to transcode in parallel. [1]
--no-progress Disable the progress bar
--log-level TYPE Log level. If enabled, will disable progress bar. [silent] (choices: silent, debug, info, warn, error)
--time Whether to print timing statistics
INPUT
OUTPUT
Audio processing:
--codec TYPE The audio codec to transcode to. If unspecified, will copy audio data without transcoding. [copy] (choices: libopus,
lipmp3lame, aac, copy)
--bitrate BITRATE The audio bitrate to transcode to ()
--max-length INTEGER The maximum allowed length of a processed audio track, in minutes [120]
stalign help markup
Usage: stalign-linux-x64 markup [--granularity/-g TYPE] [--language LOCALE] [--no-progress] [--log-level TYPE] [--time] INPUT_PATH OUTPUT_PATH
Mark up an EPUB file at the provided granularity level
--granularity, -g TYPE [sentence] (choices: word, sentence)
--language LOCALE BCP 47 language tag representing the primary language of the audio (e.g. en-US)
--no-progress Disable the progress bar
--log-level TYPE Log level. If enabled, will disable progress bar. [silent] (choices: silent, debug, info, warn, error)
--time Whether to print timing statistics
INPUT_PATH
OUTPUT_PATH
stalign help transcribe
Usage: stalign transcribe [--parallel INTEGER] [--language LOCALE] (--engine/-e whisper.cpp [--model/-m MODEL] [--threads INTEGER] [--processors
INTEGER] [--cpu-override CPU_ENGINE] | --engine/-e whisper-server --whisper-server-url URL [--whisper-server-api-key STRING] | --engine/-e
openai-cloud [--openai-model STRING] [--openai-api-key STRING] [--openai-organization STRING] [--openai-base-url URL] | --engine/-e google-cloud
--google-cloud-api-key STRING | --engine/-e microsoft-azure --azure-service-region STRING --azure-subscription-key STRING | --engine/-e
amazon-transcribe --amazon-transcribe-region STRING --amazon-transcribe-access-key-id STRING --amazon-transcribe-secret-access-key STRING | --engine/
-e deepgram --deepgram-api-key STRING [--deepgram-model STRING]) [--no-progress] [--log-level TYPE] [--time] INPUT OUTPUT
Transcribe a directory of audiobook files.
--parallel INTEGER How many files to attempt to transcode in parallel. [1]
--language LOCALE BCP 47 language tag representing the primary language of the audio (e.g. en-US)
--no-progress Disable the progress bar
--log-level TYPE Log level. If enabled, will disable progress bar. [silent] (choices: silent, debug, info, warn, error)
--time Whether to print timing statistics
INPUT
OUTPUT
whisper.cpp:
--engine, -e whisper.cpp (choices: whisper.cpp)
--model, -m MODEL The whisper model to use [tiny.en] (choices: tiny, tiny.en, tiny-q5_1, tiny.en-q5_1, tiny-q8_0, base, base.en, base-q5_1, ...)
--threads INTEGER [4]
--processors INTEGER The number of processors to use (values greater than 1 may affect timing accuracy) [1]
--cpu-override CPU_ENGINE When provided, will use this whisper variant even if another is available (choices: blas, cpu)
whisper-server:
--engine, -e whisper-server (choices: whisper-server)
--whisper-server-url URL
--whisper-server-api-key STRING
openai-cloud:
--engine, -e openai-cloud (choices: openai-cloud)
--openai-model STRING
--openai-api-key STRING
--openai-organization STRING
--openai-base-url URL
google-cloud:
--engine, -e google-cloud (choices: google-cloud)
--google-cloud-api-key STRING
microsoft-azure:
--engine, -e microsoft-azure (choices: microsoft-azure)
--azure-service-region STRING
--azure-subscription-key STRING
amazon-transcribe:
--engine, -e amazon-transcribe (choices: amazon-transcribe)
--amazon-transcribe-region STRING
--amazon-transcribe-access-key-id STRING
--amazon-transcribe-secret-access-key STRING
deepgram:
--engine, -e deepgram (choices: deepgram)
--deepgram-api-key STRING
--deepgram-model STRING [nova-3]
stalign help align
Usage: stalign align --transcriptions PATH --output PATH --audiobook PATH --epub PATH [--reports PATH] [--no-progress] [--log-level TYPE] [--time]
[--language LOCALE] [--granularity/-g TYPE]
Run forced alignment to determine where each sentence|word is spoken in the audiobook and produce a new EPUB package with Media Overlays and embedded audio.
--transcriptions PATH
--output PATH
--no-progress Disable the progress bar
--log-level TYPE Log level. If enabled, will disable progress bar. [silent] (choices: silent, debug, info, warn, error)
--time Whether to print timing statistics
--language LOCALE BCP 47 language tag representing the primary language of the audio (e.g. en-US)
--granularity, -g TYPE [sentence] (choices: word, sentence)
Alignment:
--audiobook PATH
--epub PATH
--reports PATH
Caveats
The --granulariy flag doesn’t currently do anything — support for word-level
granularity is coming soon!
There seems to be an issue with our macOS automated builds, and we haven’t
figured out Windows builds yet. In the meantime, you can still use npx to run
stalign on those platforms. We will have full OS support soon!