forked from extern/whisper.cpp
9fe7306f4b
The old "large" model is now renamed "large-v1". If you have been using it, make sure to rename it and download the new "large" model for best results.
99 lines
2.8 KiB
Bash
Executable File
99 lines
2.8 KiB
Bash
Executable File
#!/bin/bash
|
|
set -eo pipefail
|
|
# Transcribe audio livestream by feeding ffmpeg output to whisper.cpp at regular intervals
|
|
# Idea by @semiformal-net
|
|
# ref: https://github.com/ggerganov/whisper.cpp/issues/185
|
|
#
|
|
# TODO:
|
|
# - Currently, there is a gap between sequential chunks, so some of the words are dropped. Need to figure out a
|
|
# way to produce a continuous stream of audio chunks.
|
|
#
|
|
|
|
url="http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_world_service.m3u8"
|
|
fmt=aac # the audio format extension of the stream (TODO: auto detect)
|
|
step_s=30
|
|
model="base.en"
|
|
|
|
if [ -z "$1" ]; then
|
|
echo "Usage: $0 stream_url [step_s] [model]"
|
|
echo ""
|
|
echo " Example:"
|
|
echo " $0 $url $step_s $model"
|
|
echo ""
|
|
echo "No url specified, using default: $url"
|
|
else
|
|
url="$1"
|
|
fi
|
|
|
|
if [ -n "$2" ]; then
|
|
step_s="$2"
|
|
fi
|
|
|
|
if [ -n "$3" ]; then
|
|
model="$3"
|
|
fi
|
|
|
|
# Whisper models
|
|
models=( "tiny.en" "tiny" "base.en" "base" "small.en" "small" "medium.en" "medium" "large-v1" "large" )
|
|
|
|
# list available models
|
|
function list_models {
|
|
printf "\n"
|
|
printf " Available models:"
|
|
for model in "${models[@]}"; do
|
|
printf " $model"
|
|
done
|
|
printf "\n\n"
|
|
}
|
|
|
|
if [[ ! " ${models[@]} " =~ " ${model} " ]]; then
|
|
printf "Invalid model: $model\n"
|
|
list_models
|
|
|
|
exit 1
|
|
fi
|
|
|
|
running=1
|
|
|
|
trap "running=0" SIGINT SIGTERM
|
|
|
|
printf "[+] Transcribing stream with model '$model', step_s $step_s (press Ctrl+C to stop):\n\n"
|
|
|
|
# continuous stream in native fmt (this file will grow forever!)
|
|
ffmpeg -loglevel quiet -y -re -probesize 32 -i $url -c copy /tmp/whisper-live0.${fmt} &
|
|
if [ $? -ne 0 ]; then
|
|
printf "Error: ffmpeg failed to capture audio stream\n"
|
|
exit 1
|
|
fi
|
|
|
|
printf "Buffering audio. Please wait...\n\n"
|
|
sleep $(($step_s))
|
|
|
|
# do not stop script on error
|
|
set +e
|
|
|
|
i=0
|
|
SECONDS=0
|
|
while [ $running -eq 1 ]; do
|
|
# extract the next piece from the main file above and transcode to wav. -ss sets start time and nudges it by -0.5s to catch missing words (??)
|
|
err=1
|
|
while [ $err -ne 0 ]; do
|
|
if [ $i -gt 0 ]; then
|
|
ffmpeg -loglevel quiet -v error -noaccurate_seek -i /tmp/whisper-live0.${fmt} -y -ar 16000 -ac 1 -c:a pcm_s16le -ss $(($i*$step_s-1)).5 -t $step_s /tmp/whisper-live.wav 2> /tmp/whisper-live.err
|
|
else
|
|
ffmpeg -loglevel quiet -v error -noaccurate_seek -i /tmp/whisper-live0.${fmt} -y -ar 16000 -ac 1 -c:a pcm_s16le -ss $(($i*$step_s)) -t $step_s /tmp/whisper-live.wav 2> /tmp/whisper-live.err
|
|
fi
|
|
err=$(cat /tmp/whisper-live.err | wc -l)
|
|
done
|
|
|
|
./main -t 8 -m ./models/ggml-base.en.bin -f /tmp/whisper-live.wav --no-timestamps -otxt 2> /tmp/whispererr | tail -n 1
|
|
|
|
while [ $SECONDS -lt $((($i+1)*$step_s)) ]; do
|
|
sleep 1
|
|
done
|
|
((i=i+1))
|
|
done
|
|
|
|
killall -v ffmpeg
|
|
killall -v main
|