0

This script works fine when directly typed into the console:

N | find . -type f -iname "*.aac" -exec bash -c 'FILE="$1"; ffmpeg -i "${FILE}" -acodec libmp3lame "${FILE%.aac}.mp3";' _ '{}' \;

But as I'm trying to add it as an alias into my ~/.zshrc file:

alias aac-to-mp3="N | find . -type f -iname \"*.aac\" -exec bash -c 'FILE=\"$1\"; ffmpeg -i \"${FILE}\" -acodec libmp3lame \"${FILE%.aac}.mp3\";' _ '{}' \;"

It yields:

 ✔  aac-to-mp3
_: N: command not found
ffmpeg version 4.4.1 Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 13.0.0 (clang-1300.0.29.3)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.4.1_3 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-avresample --enable-videotoolbox
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
: No such file or directory

I tried moving the N | into the command itself:

alias aac-to-mp3="find . -type f -iname \"*.aac\" -exec bash -c 'FILE=\"$1\"; N | ffmpeg -i \"${FILE}\" -acodec libmp3lame \"${FILE%.aac}.mp3\";' _ '{}' \;"

But it generates the same output.

I did restart the shell between each alias change.

How do I make that script usable as an alias? I don't understand the issue.

2 Answers2

3

Aliases cannot take arguments. You need a function here instead. Also, please avoid using CAPS for shell variable names. By convention, global environment variables are capitalized so using caps for your own variable names can lead to unexpected bugs. Try adding this to your ~/.zshrc file:

aac-to-mp3(){
    find . -type f -iname "*.aac" -exec \
        bash -c 'file="$1"; ffmpeg -n -i "$file" -acodec libmp3lame "${file%.aac}.mp3";' _ '{}' \;
}

ffmpeg's -n option will respond N to any prompts, so you don't need to try to pass N to it (which is what the N | was attempting to do, albeit in a way that wouldn't work).

terdon
  • 242,166
  • The N | is for prefilling the y/N answer. – Vadorequest Dec 22 '21 at 13:11
  • OK, but what is it? Is it an alias? Is it some binary installed on your system? – terdon Dec 22 '21 at 13:14
  • 1
    Since they're using zsh, for f (**/*.(#i)aac(N.)) ffmpeg -i $f -acodec libmp3lame $f:r.mp3 (with extendededglob for (#i)) would make it shorter. Note that ${file%.aac} is not case insensitive (-iname '*.aac' is). – Stéphane Chazelas Dec 22 '21 at 13:15
  • It's not an alias, it's literally the y/N answer that is pre-filled. File './20211110134633.mp3' already exists. Overwrite? [y/N] – Vadorequest Dec 22 '21 at 13:16
  • @Vadorequest oh. That's not how it works, you can only use | to pipe the output of a command, not to pass a string. Try the command yes N | ffmpeg .... – terdon Dec 22 '21 at 13:20
  • I've made an edit after testing the behavior, thanks for pointing all those things out. For reference's sake, I found this script and adapted it from https://stackoverflow.com/questions/3255674/convert-audio-files-to-mp3-using-ffmpeg – Vadorequest Dec 22 '21 at 13:22
2

Your command contains parameters that are being expanded when defining the alias due to use of double quotes. To quote it for an alias, try single quotes:

alias aac-to-mp3='N | find . -type f -iname "*.aac" -exec bash -c '\''FILE="$1"; ffmpeg -i "${FILE}" -acodec libmp3lame "${FILE%.aac}.mp3";'\'' _ '\''{}'\'' \;'

You should probably just use zsh though. Maybe:

aac-to-mp3 () {
  setopt localoptions extendedglob
  local f
  for f (**/*.(#i)aac(ND.)) {
    ffmpeg -n -i $f -c:a libmp3lame $f:r.mp3
  }
}

This assumes that N is something like yes n to say "No" to "overwrite file?" prompts from ffmpeg, in which case you can just use ffmpeg's -n option.

rowboat
  • 2,791
  • This code looks too complicated for me (unfamiliar), I prefer the bash approach. But well done for pointing out the built-in -n option! – Vadorequest Dec 22 '21 at 13:22