5

I'm working on a bash script to convert my music library to ogg* but executing the right command is somehow eluding me. This is the line that should accomplish it:

ffmpeg -i "${file}" -f flac pipe:1 | oggenc - -o "${NEWOGGFILE}"

In fact, if I copy the output of this line, it encodes as expected:

echo "ffmpeg -i \"${file}\" -f flac pipe:1 | oggenc - -o \"${NEWOGGFILE}\""

E.g.:

ffmpeg -i "./Music/Oldies/Sam Cooke/23 Shake.m4a" -f flac pipe:1 | oggenc - -o "/mnt/Primary/Audio_OGG_Cache/./Music/Oldies/Sam Cooke/23 Shake.ogg"

But, when I run the script, ffmpeg gives me error messages, including: Unable to find a suitable output format for 'pipe:1' pipe:1: Invalid argument Parse error, at least 3 arguments were expected, only 1 given in string 'al Warmups/Voice Lessons To Go - V1 Vocalize & Breath/01-05- 123454321.mp3'

So, how is the first line not executing the command if the second line echos it correctly? The complete script is as follows:

#!/bin/bash
pushd "${1}"

find ./ | while read file
do
  BASENAME=`basename "${file}"`
  NEWOGGFILE=${2}`dirname "${file}"`/${BASENAME%.*}.ogg
  NEWFILE=${2}`dirname "${file}"`/${BASENAME}

  # Ignore directories, and don't re-copy existing files.
  if [ ! -d "${file}" ] && [ ! -f "${NEWFILE}" ] && [ ! -f "${NEWOGGFILE}" ]; then
    mkdir -p "`dirname "${NEWFILE}"`"
    # m4a, mp3, and flac get converted
    if [ "${file##*.}" = "flac" ]; then
      oggenc "${file}" -o "${NEWOGGFILE}"
    elif [ "${file##*.}" = "m4a" ] || [ "${file##*.}" = "mp3" ]; then
      ffmpeg -i "${file}" -f flac pipe:1 | oggenc - -o "${NEWOGGFILE}"
    # any other remaining types of files (typically album art) are copied directly.
    else
      cp "${file}" "${NEWFILE}"
    fi
  else
    echo "${NEWFILE}" already exists.
  fi
done

popd

*In a separate, cached directory; don't have a heart attack, audiophiles!

  • Increase verbosity with ffmpeg -loglevel debug -i ... ; see if you get anything useful after Splitting the commandline... – don_crissti May 22 '15 at 15:49
  • You can perform bash script debugging with set -x. – bsd May 23 '15 at 9:45
  • You posted an error that mentions a string: 'al Warmups/Voice[...]21.mp3' Is 'al Warmups' the full dir name? Or was the first half not detected? It runs fine on my system. I tried creating file and dir names that would be problematic but your script handled them all perfectly. – bntser May 29 '15 at 5:21
  • I have now reproduced the parse error by creating a destination folder with a single quote.The script removes the first part of the pathname and recursively creates dirs and files. I'm very curious what the full pathname of your folder is. Bash Manual Section 3.1.2.3: gnu.org/software/bash/manual/bashref.html#Double-Quotes Enclosing characters in double quotes (‘"’) preserves the literal value of all characters within the quotes, with the exception of ‘$’, ‘‘’, ‘\’, and, when history expansion is enabled, ‘!’. – bntser May 29 '15 at 5:41
  • 1
    Thanks; that's a great finding! The full name is: /mnt/Primary/Audio/Vocal\ Warmups/Voice\ Lessons\ To\ Go\ -\ V1\ Vocalize\ \&\ Breath/01-05-\ 123454321.mp3 Since there's no single quote, my money is on the ampersand being the culprit. I'm going to try a tweak using single-quotes to encapsulate it. – Peter Bailey May 30 '15 at 13:27
1

There's something odd going on with the command line - whether it is a file-system problem or something more elementary (like unprintable characters in a directory name).

The error message "Unable to find a suitable output format for pipe:1" is due to the previous "-f flac" being ignored.

I have tried renaming an mp3 to your stated problem filename, and running the script, only to find it was fine (up until oggenc didn't like encoding flac from stdin).

I recommend (as don_crissti suggested) adding -loglevel debug to the command line, and then trying to isolate the files or directories that are causing problems by running the script on a subset of directories to determine what is really going on. (At debug level, ffmpeg even reports what it interpreted the command line as)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.