You are not logged in.
Hey all,
Recently, I decided to get an audio-book from Audible and discovered the mp3 player they advertise about is only for ipods. This meant that the only legit way to transfer it to my mp3 player (an .aa file/DRM protected) was to use iTunes burn it to multiple cds. Doingthis had the book span 14 disks and now I'm trying to put it back together. I used a great program called 'ripit' to rip the files back to Linux and now I'm faced with the task of concatenating the files back together again. Ripit ripped the disks to 14 separate folders:
Unknown Artist - Unknown Album
Unknown Artist - Unknown Album 1
Unknown Artist - Unknown Album 2
...
Unknown Artist - Unknown Album 13
To get these to appear in correct order I first rename the first album:
mv Unknown\ Artist\ -\ Unknown\ Album/ Unknown\ Artist\ -\ Unknown\ Album\ 0
replaced white spaces with hyphens (necessary for the next step):
find -name "* *" -type d | rename 's/ /-/g'
Zeropad the numbers to show in the right order (using this persons excellent script - http://www.walkingrandomly.com/?p=2850):
for i in *; do mv "$i" $(zeropad "$i"); done
#!/bin/bash
# zeropad
# Filter that will take input with basic numbering and zero pad it (i.e. file002)
# e.g. mv file1.png `$(zeropad) $i`
# http://www.walkingrandomly.com/?p=2850
num=`expr match "$1" '[^0-9]*\([0-9]\+\).*'`
paddednum=`printf "%03d" $num`
echo ${1/$num/$paddednum}
So now my directories look like this:
Unknown-Artist---Unknown-Album-000
Unknown-Artist---Unknown-Album-001
...
Unknown-Artist---Unknown-Album-013
Now I'm trying to create a bash script that will put this mp3s back together again. mp3cat is the right utility to do this so I need to create a bash script that I can tell what folders to use to put them together. Originally the book from Audible came in three parts:
SK...part1.aa
SK...part2.aa
SK...part3.aa
part 1 covers directories 000 to 004, part 2 005 to 008, part 3 009 to 013. The script though I'd like to be generic (to be able to accept input if I decided to ever do this again). Here it is thus as I have it so far figured out:
echo "Join multiple mp3s from which folders?"
echo -n "First folder number [0xx]: "
read first_folder
echo -n " to folder number [0xx]: "
read final_folder
echo -n " Name of file [name].mp3: "
read filename
for f in Unknown-Artist---Unknown-Album-[$first_folder-$final_folder]; do
cat "$f"/*.mp3 | mp3cat - - > "$filename".mp3
done
I'd like to be able to input which directory to begin with and then input which directory to end with. My use of [$first_folder-$final_folder] here shows my limited use of bash and I know that this this is only going to work for a single digit. Any ideas what I can do here?
Last edited by Gen2ly (2011-09-19 02:25:04)
Setting Up a Scripting Environment | Proud donor to wikipedia - link
Offline
Try this:
#!/bin/bash
declare -a filelist
for (( i="$1"; i <= "$2"; i++ )); do
suffix=$(printf '%03d' "$i")
f="Unknown-Artist---Unknown-Album-$suffix"
filelist+=($(ls $f/*))
done
cat "${filelist[@]}" | mp3cat - - > "$3.mp3"
This assumes that the files within the directory will be listed in the correct order. Then run it:
$ scriptname 0 4 filename
Last edited by rockin turtle (2011-09-17 07:24:14)
Offline
I think bashs' brace expansion might help here. Try something like:
# Join multiple audio book cds to singular mp3. Audible download aa ripped to audio cd, then used 'ripit' to mp3. This script joins multiple folders mp3s into their original large mp3.
echo "Join multiple mp3s from which folders?"
echo -n "First folder number [0xx]: "
read first_folder
echo -n " to folder number [0xx]: "
read final_folder
echo -n " Name of file [name].mp3: "
read filename
for f in Unknown-Artist---Unknown-Album-{$first_folder..$final_folder}; do
cat "$f"/*.mp3 | mp3cat - - > "$filename".mp3
done
Check man bash for how brace expansion works if in doubt.
Cheers
You're just jealous because the voices only talk to me.
Offline
@Gen2ly Looks like a lot of unnecessary work and detail here. Could have defined the problem simpler and clearer...
@rockin turtle The `ls` call should be avoided, moreover, any whitespace in filenames breaks it.
@moetunes That won't work. Only literals like {0..4} are expanded, since brace expansion is performed before any other expansions.
Last edited by lolilolicon (2011-09-17 14:32:15)
This silver ladybug at line 28...
Offline
@Gen2ly Looks like a lot of unnecessary work and detail here. Could have defined the problem simpler and clearer...
Agreed. Cleaned up post a little bit but left details in as I think they might be useful to other people down the road (I hope ).
Try this:
#!/bin/bash declare -a filelist for (( i="$1"; i <= "$2"; i++ )); do suffix=$(printf '%03d' "$i") f="Unknown-Artist---Unknown-Album-$suffix" filelist+=($(ls $f/*)) done cat "${filelist[@]}" | mp3cat - - > "$3.mp3"
This assumes that the files within the directory will be listed in the correct order. Then run it:
$ scriptname 0 4 filename
Was afraid my basic script would become more complicated. From what I know of the i and i++ stuff this is a counting thing. Pretty neat. Unfortunately I'm getting the problem that lolilolicon referred. The mp3s have spaces so it's not working with 'ls'. Is there another tools we can use?
Setting Up a Scripting Environment | Proud donor to wikipedia - link
Offline
Yup, could have been more explicit. Pathname Expansion is the relevant section in bash(1) man page.
This silver ladybug at line 28...
Offline
If there are spaces in the filenames then using globbing won't change anything. When stored in an array the new elements are split at spaces. This has the same problem as using ls. edit: ok so, "newer" versions of bash won't split the elements at spaces but the spaces still screw up when the array is expanded to command arguments.
As usual all problems of existence are just a primitive form of bending. I mean, sorting! Crap. No need to remove the spaces and rename everything. sort and awk like spaces.
# Must... have... number!
mv "Unknown Artist - Unknown Album" "Unknown Artist - Unknown Album 0" \
2>/dev/null
# Sort & awk read as many number chars as possible, then give up.
# ./Unknown Artist - Unknown Album 1/Track 1.mp3
# (Fields) 6_/*^^^^^^ *^^^^\_7
find . -name '*.mp3' | sort -n -k6 -k7 | \
# $6+0 coerces $6 into a number.
awk -v beg="$1" -v end="$2" '$6+0 >= beg && $6+0 <= end' |
# Use NULL chars instead of newlines to make xargs happy.
tr '\n' '\0' | xargs -0 cat
# Without NULL chars and -0, xargs splits on lines AND spaces. Bad.
Instead of changing the data (paths) to make it sort lexicographically, I simply sorted the data explicitly. Two args: beginning number and ending number. It's probably too late, since you renamed everything but maybe you can use the tr | xargs trick. Avoid using bash arrays or get rid of the spaces in the filenames.
Last edited by juster (2011-09-18 13:02:59)
Offline
Globbing plays quite well with spaces. If you're having problems seeing this in an array, then I assume you're not quoting properly on expansion.
$ touch one "two three" four "five six"
$ f=(*)
$ printf '%s\n' ${f[@]}
five
six
four
one
two
three
$ printf '%s\n' "${f[@]}"
five six
four
one
two three
$ printf '%s\n' "${f[*]}" #for the sake of completeness
five six four one two three
Offline
Ah you are right, I forgot the double quotes.
Offline
Thanks for the help guys. rockin turtle, your script was very helpful. Also, thank you falconindy for the clarification. The only think I changed was:
f="Unknown Artist - Unknown Album $suffix"
because I learned that this code will work with spaces. Again, appreciate the help.
Setting Up a Scripting Environment | Proud donor to wikipedia - link
Offline