如何修复这个转换音频文件的脚本?

如何修复这个转换音频文件的脚本?

我正在尝试使用我在网上找到的脚本转换一些有声读物,但我认为该脚本可能有问题,因为它似乎没有按预期工作。

Audible 的有声读物已.aax格式化。


剧本:

#!/bin/bash
# audiblefreedom
# audiblefreedom is a simple Linux program that strips the DRM from Audible
# audiobooks, splits it into chapters, tags and names the files and converts
# them to mp3 format.
#
# REQUIREMENTS
# Requires mkvmerge, ffmpeg, lame
# if using Ubuntu 14.04, a ppa is required for ffmpeg
# sudo add-apt-repository ppa:mc3man/trusty-media
# sudo apt-get update
# sudo apt-get install mkvtoolnix ffmpeg lame
# 
# You must also use audible-activator
# (https://github.com/inAudible-NG/audible-activator/) to get your activation
# bytes (to decrypt the AAX files) and save them as a file called bytes.txt in
# the same dir as the script. Note, this will only decrypt AAX files purchased
# on this account.
#
# USAGE
# audiblefreedom AAXFILE [COVERJPG]
# 
# You can optionally specify a .jpg path either from your local machine or URL
# to use for the cover art.
#
# There does not appear to be an Audible player/downloader for Linux, so I use
# the Audible Android app to download the AAX file and copy it to my machine.
#
# Initial script from:
# https://www.reddit.com/r/linux/comments/5g841u/what_are_some_scripts_you_use_for_personal/daro100/
# heavily modified by John Wesorick
#
if [ -e "$PWD/bytes.txt" ]; then
    ABYTES=$(sed '1q;d' "$PWD/bytes.txt")
else
    echo "Activation bytes file (bytes.txt) is missing! Please use"
    echo "audible-activator (https://github.com/inAudible-NG/audible-activator/)"
    echo "to get your activation bytes and save them to a file called bytes.txt."
    exit 1
fi

# Verify that the necessary programs are installed
REQUIREDPROGRAMS=("ffmpeg" "lame" "mkvmerge")
for i in "${REQUIREDPROGRAMS[@]}"; do
    if ! type "$i" >/dev/null; then
        echo "Required program $i is missing! I cannot continue"
        # Check distro to see how to install requirements
        DISTRO=$(cat /etc/issue)
        if [[ "$DISTRO" == "Ubuntu"* ]]; then
            echo "Run the following command(s) to install all required programs"
            if [[ "$DISTRO" == *"14.04"* ]]; then
                echo "sudo add-apt-repository ppa:mc3man/trusty-media"
                echo "sudo apt-get update"
            fi
            echo "sudo apt-get install mkvtoolnix ffmpeg lame"
        fi
        exit 1
    fi
done
# Move into temporary work folder.
mkdir work
cd work

# Remove DRM from AAX file.
echo "Stripping DRM..."
ffmpeg -nostats -loglevel 0 -activation_bytes $ABYTES -i "../$1" \
    -vn -c:a copy "${1%.*}.m4a" ; 
BOOKTITLE=$(ffprobe -v quiet -show_format "${1%.*}.m4a" | grep "TAG:title" | cut -d"=" -f2)
AUTHOR=$(ffprobe -v quiet -show_format "${1%.*}.m4a" | grep "TAG:artist" | cut -d"=" -f2)
YEAR=$(ffprobe -v quiet -show_format "${1%.*}.m4a" | grep "TAG:date" | cut -d"=" -f2)
COMMENT=$(ffprobe -v quiet -show_format "${1%.*}.m4a" | grep "TAG:comment" | cut -d"=" -f2)
TOKENWORDS=("A" "An" "The")
# If a title begins with A, An, or The, we want to rename it so it sorts well
FSBOOKTITLE="$BOOKTITLE"
FSAUTHOR="$AUTHOR"
for i in "${TOKENWORDS[@]}"; do
    if [[ "$FSBOOKTITLE" == "$i "* ]]; then
        FSBOOKTITLE=$(echo $FSBOOKTITLE | perl -pe "s/^$i //")
        # If book has a subtitle, we want the token word to go right before it
        if [[ "$FSBOOKTITLE" == *": "* ]]; then
            FSBOOKTITLE=$(echo $FSBOOKTITLE | perl -pe "s/: /, $i: /")
            break  
        fi
        FSBOOKTITLE="$FSBOOKTITLE, $i"
        break
    fi
done
# Replace special characters in Book Title and Author Name with a - to make
# them file name safe. I'm not actually using the Author Name in the file
# name, but I figured it'd be nice to make it easy to use.
FSBOOKTITLE=$(echo $FSBOOKTITLE | perl -pe 's/[<>:"\/\\\|\?\*]/-/g')
FSAUTHOR=$(echo $FSAUTHOR | perl -pe 's/[<>:"\/\\\|\?\*]/-/g')

# Split stripped M4A file by chapters.
echo "Splitting by chapter..."
mkvmerge -o "${1%.*} .m4a" --split chapters:all "${1%.*}.m4a" 1> /dev/null

rm "${1%.*}.m4a"

# if album art is given as a second argument, grab it
if [ -n "$2" ]; then
    if [[ "$2" == "http"* ]]; then
        wget -q "$2" -O folder.jpg
    else
        mv "../$2" folder.jpg
    fi
fi

# Transcode to .mp3
TOTALTRACKS=$(ls -l *.m4a | wc -l)
TRACK=0

for f in *.m4a ;
do
    TRACK=$(($TRACK+1))
    echo "Transcoding track $TRACK of $TOTALTRACKS..."
    MP3FILE="${f//m4a/mp3}"
    TRACKTITLE="$(mkvinfo "$f" | grep 'ChapterString:' | cut -d":" -f2 | awk '{gsub(/^ +| +$/,"")} {print $0 }')"
    ffmpeg -nostats \
        -loglevel 0 \
        -i "$f" \
        -metadata album="$BOOKTITLE" \
        -metadata genre="Audiobook" \
        -metadata title="$TRACKTITLE" \
        -metadata artist="$AUTHOR" \
        -metadata album_artist="$AUTHOR" \
        -metadata date="$YEAR" \
        -metadata comment="$COMMENT" \
        -metadata track="$TRACK/$TOTALTRACKS" \
        -id3v2_version 3 \
        -codec:a libmp3lame \
        -qscale:a 3 \
        "$MP3FILE"
    # zero padding the track number as a string
    if [ $TOTALTRACKS -ge 100 ] ; then
        if [ $TRACK -le 99 ] ; then
            TRACKSTR="0$TRACK"
        elif [ $TRACK -le 9 ] ; then
            TRACKSTR="00$TRACK"
        else
            TRACKSTR=$TRACK
        fi
    else
        if [ $TRACK -le 9 ] ; then
            TRACKSTR="0$TRACK"
        else
            TRACKSTR=$TRACK
        fi
    fi
    
    # if album art exists, add it
    if [ -a "folder.jpg" ]; then
        # ffmpeg does not allow in-place editing, so create a temp file, then
        # delete the old one and rename.
        ffmpeg -nostats \
            -loglevel 0 \
            -i "$MP3FILE" \
            -i folder.jpg \
            -map 0:0 \
            -map 1:0 \
            -c copy \
            -id3v2_version 3 \
            -metadata:s:v title="Album cover" \
            -metadata:s:v comment="Cover (Front)" \
            out.mp3
        rm "$MP3FILE"
        mv out.mp3 "$MP3FILE"
    fi
    # rename .mp3's. Format: BOOKTITLE@TRACKNUM)TRACKTITLE.mp3
    mv "$MP3FILE" "$FSBOOKTITLE@$TRACKSTR)$TRACKTITLE.mp3"
done

# Move out of work folder.
mkdir "../$FSBOOKTITLE"
mv *.mp3 "../$FSBOOKTITLE" 
if [ -a folder.jpg ]; then
    mv folder.jpg "../$FSBOOKTITLE"
fi
cd ..

# Delete work folder.
echo "Cleaning up..."
rm -rf work

echo

输出:

Stripping DRM...
Splitting by chapter...
rm: cannot remove 'myaudiobook.m4a': No such file or directory
ls: cannot access '*.m4a': No such file or directory
Transcoding track 1 of 0...
rm: cannot remove '*.mp3': No such file or directory
mv: cannot stat 'out.mp3': No such file or directory
mv: cannot stat '*.mp3': No such file or directory
mv: cannot stat '*.mp3': No such file or directory
Cleaning up...

我认为变量可能有问题,所以我尝试将其中一些变量用双引号(")括起来,但这似乎并没有解决问题。

注意!在任何人得到任何想法之前,我已经已购买因此,自己的这些有声读物。


编辑:这是命令的结果bash -x audiblefreedom

$ bash -x audiblefreedom 
+ '[' -e /home/[REDACTED]/Music/audible/audiobooks/fry_stephen-mythos/bytes.txt ']'
++ sed '1q;d' /home/[REDACTED]/Music/audible/audiobooks/fry_stephen-mythos/bytes.txt
+ ABYTES=audible_byte#4-4_0_10000x789935_0.rtc
+ REQUIREDPROGRAMS=("ffmpeg" "lame" "mkvmerge")
+ for i in "${REQUIREDPROGRAMS[@]}"
+ type ffmpeg
+ for i in "${REQUIREDPROGRAMS[@]}"
+ type lame
+ for i in "${REQUIREDPROGRAMS[@]}"
+ type mkvmerge
+ mkdir work
+ cd work
+ echo 'Stripping DRM...'
Stripping DRM...
+ ffmpeg -nostats -loglevel 0 -activation_bytes audible_byte#4-4_0_10000x789935_0.rtc -i ../ -vn -c:a copy .m4a
++ ffprobe -v quiet -show_format .m4a
++ grep TAG:title
++ cut -d= -f2
+ BOOKTITLE=
++ ffprobe -v quiet -show_format .m4a
++ grep TAG:artist
++ cut -d= -f2
+ AUTHOR=
++ ffprobe -v quiet -show_format .m4a
++ grep TAG:date
++ cut -d= -f2
+ YEAR=
++ ffprobe -v quiet -show_format .m4a
++ grep TAG:comment
++ cut -d= -f2
+ COMMENT=
+ TOKENWORDS=("A" "An" "The")
+ FSBOOKTITLE=
+ FSAUTHOR=
+ for i in "${TOKENWORDS[@]}"
+ [[ '' == \A\ * ]]
+ for i in "${TOKENWORDS[@]}"
+ [[ '' == \A\n\ * ]]
+ for i in "${TOKENWORDS[@]}"
+ [[ '' == \T\h\e\ * ]]
++ echo ''
++ perl -pe 's/[<>:"\/\\\|\?\*]/-/g'
+ FSBOOKTITLE=
++ echo ''
++ perl -pe 's/[<>:"\/\\\|\?\*]/-/g'
+ FSAUTHOR=
+ echo 'Splitting by chapter...'
Splitting by chapter...
+ mkvmerge -o _.m4a --split chapters:all .m4a
+ rm .m4a
rm: cannot remove '.m4a': No such file or directory
+ '[' -n '' ']'
++ ls -l '*.m4a'
++ wc -l
ls: cannot access '*.m4a': No such file or directory
+ TOTALTRACKS=0
+ TRACK=0
+ for f in *.m4a
+ TRACK=1
+ echo 'Transcoding track 1 of 0...'
Transcoding track 1 of 0...
+ MP3FILE='*.mp3'
++ mkvinfo '*.m4a'
++ grep ChapterString:
++ cut -d: -f2
++ awk '{gsub(/^ +| +$/,"")} {print $0 }'
+ TRACKTITLE=
+ ffmpeg -nostats -loglevel 0 -i '*.m4a' -metadata album= -metadata genre=Audiobook -metadata title= -metadata artist= -metadata album_artist= -metadata date= -metadata comment= -metadata track=1/0 -id3v2_version 3 -codec:a libmp3lame -qscale:a 3 '*.mp3'
+ '[' 0 -ge 100 ']'
+ '[' 1 -le 9 ']'
+ TRACKSTR=01
+ '[' -a folder.jpg ']'
+ mv '*.mp3' '@01).mp3'
mv: cannot stat '*.mp3': No such file or directory
+ mkdir ../
mkdir: cannot create directory ‘../’: File exists
+ mv '*.mp3' ../
mv: cannot stat '*.mp3': No such file or directory
+ '[' -a folder.jpg ']'
+ cd ..
+ echo 'Cleaning up...'
Cleaning up...
+ rm -rf work
+ echo

我如何知道要手动运行哪些命令?

答案1

第一个失败点是脚本的 ffmpeg 命令。

您可以在 -i 之后看到 " 的值${1}没有报道在你的 -x 输出中。脚本中没有使用 set 命令从脚本内部定义 ${1} 的循环,因此这意味着 $1 必须是调用脚本时期望作为参数提供的文件名。如果有任何空格或特殊字符,请确保名称用双引号引起来。

由于未定义 $1,因此“${1%.*}.m4a”在每次 ffprobe 调用时都会失败。

换句话说,脚本没有被告知要处理哪个文件。

相关内容