First commit.
This commit is contained in:
		
						commit
						8cdf42cedd
					
				
					 2 changed files with 192 additions and 0 deletions
				
			
		
							
								
								
									
										34
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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.
 | 
			
		||||
							
								
								
									
										158
									
								
								get-tracks.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										158
									
								
								get-tracks.sh
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -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 <single-file-playlist> <song-list>"
 | 
			
		||||
	echo "command: rip  <single-file-playlist> <song-list>"
 | 
			
		||||
	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
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue