Remove xxd dep & '\'. Change fun. names. </d/n in while read block. Comments.
parent
3f892dc644
commit
51538fd5c3
|
@ -1,7 +1,8 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
# From a single byte in hexadecimal per line
|
# From a single byte in hexadecimal per line to lines ending with 0a
|
||||||
# to lines ending with 0a (hex for '\n').
|
# (hex for '\n'). Ex: 61 62 63 0a
|
||||||
|
# Required to easily match (and remove) multi-byte characters.
|
||||||
regroup_lines() awk '
|
regroup_lines() awk '
|
||||||
BEGIN {
|
BEGIN {
|
||||||
line_start=1
|
line_start=1
|
||||||
|
@ -32,25 +33,40 @@ simple_quote() sed "s/e2 80 99/27/g"
|
||||||
# From / to '-'
|
# From / to '-'
|
||||||
replace_slashes() sed "s/2f/2d/g"
|
replace_slashes() sed "s/2f/2d/g"
|
||||||
|
|
||||||
|
remove_backslashes() sed "s/5c//g"
|
||||||
|
|
||||||
remove_multibyte_characters() sed "s/e2 80 .. //g"
|
remove_multibyte_characters() sed "s/e2 80 .. //g"
|
||||||
|
|
||||||
|
uppercase() tr "[a-z]" "[A-Z]"
|
||||||
|
|
||||||
|
# One column decimal to plain text.
|
||||||
|
from_dec() awk '{ printf ("%c", $1 + 0) }'
|
||||||
|
|
||||||
|
# Replace spaces by line returns, outputs a single column.
|
||||||
|
spaces_to_line_returns() tr " " "\n"
|
||||||
|
|
||||||
# Convert input into hexadecimal and a single byte per line.
|
# Convert input into hexadecimal and a single byte per line.
|
||||||
to_hex_one_column() xxd -p -c 1
|
to_hex_one_column() { od -An -tx1 | awk '{for(i=1;i<=NF;i++){ print $i }}'; }
|
||||||
|
|
||||||
# Reverse hexadecimal to original value.
|
# One column hexa to one column decimal.
|
||||||
from_hex() xxd -p -r
|
hex_to_dec() { { echo "obase=10;ibase=16;" ; cat ; } | bc ; }
|
||||||
|
|
||||||
# Remove non ascii characters, convert "’" to "'", or remove invalid filename characters.
|
# Reverse hexadecimal (with space separators) to original value.
|
||||||
|
from_hex() { spaces_to_line_returns | uppercase | hex_to_dec | from_dec; }
|
||||||
|
|
||||||
|
# Remove non ascii, backslashes and invalid filename characters,
|
||||||
|
# convert "’" to "'", "/" to " - ".
|
||||||
to_ascii(){
|
to_ascii(){
|
||||||
to_hex_one_column | # Convert input into hexadecimal and a single byte per line.
|
to_hex_one_column | # Input to hexadecimal, 1-byte representation per line.
|
||||||
regroup_lines | # Required to easily match multi-byte characters.
|
regroup_lines | # From 1-byte to x-byte lines with space separators.
|
||||||
simple_quote | # Convert "’" to "'".
|
simple_quote | # From "’" to "'".
|
||||||
replace_slashes | # Replace / by ' - ', since it isn't a valid filename character.
|
replace_slashes | # From / to '-'.
|
||||||
remove_multibyte_characters | # Remove non ascii values.
|
remove_multibyte_characters | # Remove non ascii values.
|
||||||
from_hex # Convert back from hex.
|
remove_backslashes | # Can mess with the script.
|
||||||
|
from_hex # Convert back from hex (x-byte per line, space separator).
|
||||||
}
|
}
|
||||||
|
|
||||||
process_end_of_songs() awk -v NONUMBER="$NONUMBER" -v SEPARATOR="$SEPARATOR" '
|
comp_end_of_tracks() awk -v NONUMBER="$NONUMBER" -v SEPARATOR="$SEPARATOR" '
|
||||||
BEGIN {
|
BEGIN {
|
||||||
OFS=" "
|
OFS=" "
|
||||||
}
|
}
|
||||||
|
@ -106,7 +122,7 @@ first_column_to_seconds() awk '
|
||||||
'
|
'
|
||||||
|
|
||||||
# Get a more usable time representation for the beginning and the end of songs.
|
# Get a more usable time representation for the beginning and the end of songs.
|
||||||
process_time_file(){ to_ascii | first_column_to_seconds | process_end_of_songs ; }
|
get_timestamps(){ to_ascii | first_column_to_seconds | comp_end_of_tracks; }
|
||||||
|
|
||||||
run_ffmpeg(){
|
run_ffmpeg(){
|
||||||
file=$1
|
file=$1
|
||||||
|
@ -139,15 +155,15 @@ run_ffmpeg(){
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [ "$SIMULATION" = "" ]; then
|
if [ "$SIMULATION" = "" ]; then
|
||||||
$(< /dev/null ffmpeg $LOG_LEVEL $FROM $TO -i "$INPUT_FILE" "$OUTPUT_FILE")
|
ffmpeg $LOG_LEVEL $FROM $TO -i "$INPUT_FILE" "$OUTPUT_FILE"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
rip(){
|
extraction(){
|
||||||
audio_file="$1"
|
audio_file="$1"
|
||||||
time_file="$2"
|
time_file="$2"
|
||||||
|
|
||||||
process_time_file < "$time_file" | while read LINE; do
|
get_timestamps < "$time_file" | while read LINE; do
|
||||||
track_start=$(echo $LINE | cut -d ' ' -f 1)
|
track_start=$(echo $LINE | cut -d ' ' -f 1)
|
||||||
track_end=$(echo $LINE | cut -d ' ' -f 2)
|
track_end=$(echo $LINE | cut -d ' ' -f 2)
|
||||||
track_title=$(echo $LINE | cut -d ' ' -f 3-)
|
track_title=$(echo $LINE | cut -d ' ' -f 3-)
|
||||||
|
@ -156,7 +172,12 @@ rip(){
|
||||||
track_end=""
|
track_end=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
run_ffmpeg "${audio_file}" "${track_start}" "${track_end}" "${track_title}.${FORMAT}"
|
# Input is /dev/null, otherwise subshells will take the output
|
||||||
|
# of "get_timestamps" as input.
|
||||||
|
# Be careful: "while read X" is a dangerous shell design.
|
||||||
|
< /dev/null run_ffmpeg "${audio_file}" \
|
||||||
|
"${track_start}" "${track_end}" \
|
||||||
|
"${track_title}.${FORMAT}"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,11 +213,6 @@ Environment variables:
|
||||||
END
|
END
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ $# -lt 1 ]; then
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
header(){
|
header(){
|
||||||
if [ "$HEADERS" = "1" ]; then
|
if [ "$HEADERS" = "1" ]; then
|
||||||
echo $*
|
echo $*
|
||||||
|
@ -237,20 +253,9 @@ if [ "$SIMULATION" != "" ]; then
|
||||||
header "SIMULATION envvar is set: this is a simulation."
|
header "SIMULATION envvar is set: this is a simulation."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
</dev/null xxd -p >/dev/null 2>/dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "xxd: you don't have an xxd program with '-p' option." 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
</dev/null xxd -r >/dev/null 2>/dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "xxd: you don't have an xxd program with '-r' option." 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $# in
|
case $# in
|
||||||
1) process_time_file < "$1" ;;
|
0) usage; exit 0;;
|
||||||
2) rip "$1" "$2" ;;
|
1) get_timestamps < "$1" ;;
|
||||||
|
2) extraction "$1" "$2" ;;
|
||||||
*) usage 1>&2 ; exit 1 ;;
|
*) usage 1>&2 ; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
Loading…
Reference in New Issue