Last active
December 10, 2020 21:11
-
-
Save jacksonrayhamilton/7496687 to your computer and use it in GitHub Desktop.
Text-to-speech bash script using libttspico. Encodes to ogg and/or mp3. Decent quality. Got me through my literature class.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Takes a text file and makes an audiobook for it. | |
# | |
# Specifically: | |
# Converts a single text file to multiple ogg and/or mp3 files. | |
# | |
# Requires: | |
# libttspico-data libttspico0 libttspico-utils | |
# libttspico-dev lame vorbis-tools | |
# | |
# Use: | |
# Say you have a book in plain-text format called "book.txt". | |
# $ bash ~/Apps/bash/tts.sh book.txt | |
# | |
# Process commandline arguments | |
while getopts "f:sh" opt | |
do | |
case $opt in | |
f) | |
format="$OPTARG" | |
;; | |
s) | |
single=1 | |
;; | |
h) | |
echo "Usage: `basename $0` [OPTION]... FILE | |
Perform text-to-speech on FILE. | |
-f specify output format | |
if unspecified, outputs both formats | |
possible arguments: | |
ogg | |
mp3 | |
-s single audio file | |
encode as 'filename.ogg', rather than | |
the default 'filename-part-i-of-n.ogg' | |
-h display help and exit | |
Examples: | |
`basename $0` book.txt | |
`basename $0` -f ogg -s snippet.txt" | |
exit 1 | |
;; | |
esac | |
done | |
shift $(($OPTIND - 1)) | |
file="$1" # book.txt | |
filename="${file%.*}" # book | |
workingDir=".$filename-tts" # .book-tts | |
filePartPrefix="$filename-part-" # book-part- | |
filePartOutput="$workingDir/$filePartPrefix" # .book-tts/book-part- | |
# Determine how many parts there will be | |
bytes=$(wc -c < $file) | |
parts=$(( bytes/32000 )) | |
if [ $(( bytes%32000 )) -gt 0 ] | |
then | |
((parts++)) | |
fi | |
if [ -n "$single" ] && [ "$parts" -gt 1 ] | |
then | |
echo "Error: More than 1 part. | |
Reduce filesize to <= 32000 bytes or do not specify the '-s' flag." | |
exit 1 | |
fi | |
# Make a temporary working directory | |
mkdir "$workingDir" | |
# Split the file into chunks that pico2wave can manage | |
# (the maximum bytes allowed is around 2^15) | |
echo "Splitting file into $parts parts ..." | |
split --bytes=32000 --suffix-length=4 --numeric-suffixes "$file" "$filePartOutput" | |
for aFile in $(ls $filePartOutput*) | |
do | |
mv $aFile ${aFile}.txt | |
done | |
# Perform text-to-speech using pico2wave | |
echo "Performing text-to-speech ..." | |
i=1 | |
for part in $filePartOutput[0-9]*.txt | |
do | |
if [ -n "$single" ] | |
then | |
ttsFilename="$filename" | |
else | |
ttsFilename="$filePartPrefix$i-of-$parts" | |
fi | |
ttsWav="$workingDir/$ttsFilename.wav" | |
# Perform text-to-speech for this part | |
echo "TTSing part $i of $parts ... ($part)" | |
fileContents=$(<"$part") | |
pico2wave -l=en-US -w="$ttsWav" "$fileContents" | |
# Encode audio to distributable formats | |
# Encode to both if '-f' flag is unspecified | |
# If '-f' flag is specified, only encode to the argument format | |
if [ -z "$format" -o "$format" == "ogg" ] | |
then | |
echo "Encoding to ogg ..." | |
oggenc "$ttsWav" --output="$ttsFilename.ogg" | |
fi | |
if [ -z "$format" -o "$format" == "mp3" ] | |
then | |
echo "Encoding to mp3 ..." | |
lame -V 8 --vbr-new -h -q 0 "$ttsWav" "$ttsFilename.mp3" | |
fi | |
((i++)) | |
done | |
# Clean up | |
rm -rf $workingDir | |
echo "TTS complete." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I write Google TTS version.
Check it here: Simple Text To Speech (Bash Script - Google TTS)