9

I'm trying to covert all m4a to mp3 my code look like this:

find . -name '*.m4a' -print0 | while read -d '' -r file; do
  ffmpeg -i "$file" -n -acodec libmp3lame -ab 128k "${file%.m4a}.mp3";
done

but it only work for first mp3 file for next it show error:

Parse error, at least 3 arguments were expected, only 1 given in string '<All files in one line>'

Enter command: <target>|all <time>|-1 <command>[ <argument>]

The files contain spaces ampersands and parenthesis.

3
  • 2
    You could replace ffmpeg with echo -- and inspect the output to ensure all is right.
    – thecarpy
    Commented Apr 20, 2018 at 12:44
  • set IFS to the null string as well ... |while IFS= read -d '' -r file; ... . You could use all with find instead of using a shell while-loop Commented Apr 20, 2018 at 14:47
  • @thecarpy I was testing with echo and I've got each file with its own ffmpeg
    – jcubic
    Commented Apr 20, 2018 at 15:33

3 Answers 3

6

When reading a file line by line, if a command inside the loop also reads stdin, it can exhaust the input file.

Continue reading here: Bash FAQ 89

So the code should look like this:

find . -name '*.m4a' -print0 | while read -d '' -r file; do
  ffmpeg -i "$file" -n -acodec libmp3lame -ab 128k "${file%.m4a}.mp3" < /dev/null
done
1
3

Why not just use the -exec argument of find? So find -iname '*.m4a' -exec ffmpeg -i {} -n -acodec libmp3lame -ab 128k {}.mp3 \; and run a rename command afterward?

1
  • This answer from the askubuntu stack combines everything into a single find command. Duplicated and updated here for higher quality and forced overwrite: find -name '*.m4a' -exec bash -c 'ffmpeg -i "$0" -y -b:a 256k "${0/%m4a/mp3}"' '{}' \; ... Works on Ubuntu 20.04.
    – Trevor
    Commented Jan 17, 2022 at 17:01
0

Your question asked about converting m4a to mp3.

This is a bash script I have been using for a while.

Adjust the avconv command to suite your needs.

#!/bin/bash
## jc 2016
## convert [m4a mp3 wma] to mp3 128k
## [-vn] disable video recording
##
## avconv with lame mp3 plugin
## [-acodec libmp3lame]
##
## 192 k constant bitrate
## [-ab 192k]
## [-ab 128k]
##
## 44.1kHz sampling rate
## [-ar 44100]
##
## 2 channel audio
## [-ac 2]
##

##  force the shell to do a case insensitive comparison
shopt -s nocasematch

working_directory="./mp3_converted"
# check if dir exist
if [ ! -d "$working_directory" ];
then
  # dir does not exist
      echo "convert directory does not exist $working_directory..."
  `mkdir -p "$working_directory"`
       echo "convert directory created $working_directory..."
fi

COUNT=0

for i in *; do

  case $i in
    *.mp3)
      avconv -analyzeduration 999999999 -map_metadata 0 -i "$i" -vn -acodec libmp3lame -ac 2 -ab 128k -ar 44100 "$working_directory/`basename "$i" .mp3`.mp3"
      echo $i
      ;;
    *.m4a)
      ##avconv -analyzeduration 999999999 -map_metadata 0 -i "$i" -vn -acodec libmp3lame -ac 2 -ab 128k -ar 44100 "$working_directory/`basename "$i" .m4a`.mp3"
      # adjusted for ffmpeg to test. 
      ffmpeg -i "$i" -n -acodec libmp3lame -ab 128k "$working_directory/`basename "$i" .m4a`.mp3" 
      echo $i
      ;;
    *.wma)
      avconv -analyzeduration 999999999 -map_metadata 0 -i "$i" -vn -acodec libmp3lame -ac 2 -ab 128k -ar 44100 "$working_directory/`basename "$i" .wma`.mp3"
      echo $i
      ;;
    *)
      echo "other"
      ;;
  esac

done

## back to normal comparison
shopt -u nocasematch
exit 0

You must log in to answer this question.

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