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!

5
  • Increase verbosity with ffmpeg -loglevel debug -i ... ; see if you get anything useful after Splitting the commandline... Commented May 22, 2015 at 15:49
  • You can perform bash script debugging with set -x.
    – bsd
    Commented May 23, 2015 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
    Commented May 29, 2015 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
    Commented May 29, 2015 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. Commented May 30, 2015 at 13:27

2 Answers 2

0

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)

0

the ffmpeg error

Invalid argument Parse error, at least 3 arguments were expected, only 1 given in string

is fixed by adding

ffmpeg -nostdin

by default, ffmpeg is interactive, which is not helpful when scripting ffmpeg

see also How to force ffmpeg into non-interactive mode

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .