commit 8cdf42cedde434dc4a5e06eabbbce43fa84f453f Author: Karchnu Date: Sat Mar 27 21:18:08 2021 +0100 First commit. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b8ad8f7 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# Required applications + +* soxi +* ffmpeg + +# Usage + +```Bash +get-tracks.sh rip audio-file time-file +``` + + +`audio-file` can be in any format understood by `soxi` and `ffmpeg` + +In the `time-file`: + +``` +0:00 First song +2:20 Second song +3:18 Awesome song +``` + +# Environment variables + +* SIMULATION [0|1] do not invoke ffmpeg +* FORMAT [mp3,ogg,opus,…] for the song file format +* WITH_NUMBER [separator] if not null, write song number with this separator + example: WITH_NUMBER=_ Song names will be 1_song.opus 2_song.opus (...) +* QUIET: if set to any value, ffmpeg commands are not displayed + + +# More + +Run `get-track.sh` without arguments. diff --git a/get-tracks.sh b/get-tracks.sh new file mode 100755 index 0000000..bf7b47a --- /dev/null +++ b/get-tracks.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env sh + +get_time(){ + echo "$*" | sed "s/[ \t].*//" +} + +get_title(){ + echo "$*" | cut -d ' ' -f 2- +} + +reverse_word_order(){ + local result= + for word in $@; do + result="$word $result" + done + echo "$result" +} + +# bc is mandatory: arythmetic operations are very limited in ash. +get_seconds(){ + local n=0 + local v=0 + + values=$(echo "$*" | sed 's/:/\ +/g' | sed "s/^0//") + for i in $(reverse_word_order $values); do + case $n in + 0) v=$(echo "$v + $i " | bc);; + 1) v=$(echo "$v + (60 * $i)" | bc);; + 2) v=$(echo "$v + (3600 * $i)" | bc);; + *) echo "invalid timecode $*"; exit 1;; + esac + + n=$((n+1)) + done + + echo $v +} + +# Get a more usable time representation for the beginning and the end of songs. +get_values(){ + + audio_file="$1" + time_file="$2" + total_length=$(soxi -D "${audio_file}" | sed "s/\..*//") # integer values only + + n=0 + + while read X; do + + if [ $n -ne 0 ]; then + to=$(get_time $X) + to_s=$(get_seconds $to) + echo -e "$from_s\t$to_s\t$title" + fi + + #echo $X + from=$(get_time $X) + from_s=$(get_seconds $from) + title=$(get_title $X) + + if [ -z "${WITH_NUMBER}" ]; then + : + else + title="${n}${WITH_NUMBER}${title}" + fi + + n=$(echo $n + 1 | bc) + done < "${time_file}" + + echo -e "$from_s\t$total_length\t$title" +} + +run_ffmpeg(){ + local file=$1 + local from=$2 + local duration=$3 + local title=$4 + + if [ "${SIMULATION}" -eq 1 ]; then + [ -z "${QUIET}" ] && echo "ffmpeg -loglevel error -ss '$from' -t '$duration' -i '${file}' '${title}'" + else + [ -z "${QUIET}" ] && echo "ffmpeg -loglevel error -ss '$from' -t '$duration' -i '${file}' '${title}'" + $(< /dev/null ffmpeg -loglevel quiet -ss "$from" -t "$duration" -i "${file}" "${title}") + fi +} + +rip(){ + n=0 + from=0 + to=0 + + audio_file="$1" + time_file="$2" + + [ "$FORMAT" = "" ] && echo "default format: opus" && FORMAT="opus" + + #echo "from to duration title" + get_values "$audio_file" "$time_file" | while read LINE; do + from=$(echo $LINE | cut -d ' ' -f 1) + to=$(echo $LINE | cut -d ' ' -f 2) + title=$(echo $LINE | cut -d ' ' -f 3-) + duration=$(echo "$to - $from" | bc) + + run_ffmpeg "${audio_file}" "${from}" "${duration}" "${title}.${FORMAT}" + n=$((n + 1)) + done +} + +usage(){ + echo "usage: $0 command" + echo "command: show " + echo "command: rip " + echo + echo "song-list line format example: 1:30 My second track of the playlist" + echo "show output format: start end title" + echo + echo "envvar: SIMULATION [0|1] (do not invoke ffmpeg)" + echo "envvar: FORMAT [mp3,ogg,opus,…] (see the ffmpeg documentation)" + echo "envvar: WITH_NUMBER [separator] (not null = write song number, with this separator)" + echo " example: WITH_NUMBER=_ Song names will be 1_song.opus 2_song.opus…" + echo "envvar: QUIET (if set to any value, ffmpeg commands are not displayed)" +} + +if [ $# -lt 1 ]; then + usage + exit 0 +fi + +command=$1 +shift + +case "x-${command}" in + x-show) + + # Takes the audio file in first parameter + if [ $# -ne 2 ]; then + echo "Usage: $0 show music-file time-stamps-file" + exit 1 + fi + + get_values "$1" "$2" + ;; + + x-rip) + + # Takes the audio file in first parameter + if [ $# -ne 2 ]; then + echo "Usage: $0 show music-file time-stamps-file" + exit 1 + fi + + rip "$1" "$2" + ;; + *) + usage 1>&2 + exit 1 +esac