2

I have a bunch of audio files (type opus, m4a, webm, mp3) and thumbnail files (jpg, webp) in a folder. Most of the audio files have a corresponding thumbnail (same name, different file extension). What I am trying to do is to loop through that directory and convert the audio files into mp3 format (if not already) and merge in the corresponding thumbnail if existing. My problem: some of the file names contain special characters like parentheses and that's where my script breaks. It keeps saying

) was unexpected at this time.

So my question is: How can I escape all those file names properly so it doesn't interfere anymore?

My code:

@echo off
setlocal EnableDelayedExpansion
set "FFMPEG=C:\ffmpeg\bin\ffmpeg.exe"
for /f "delims=" %%i in ('dir /b') do (
  if "%%i"=="convert.cmd" ( 
    goto error1
  )
  if "%%~xi"==".jpg" (
    goto error2
  )
  if "%%~xi"==".webp" (
    goto error2
  )
  if "%%~xi"==".mp3" (
    goto error3
  )

  if exist "%%~ni".jpg (
    "%FFMPEG%" -i "%%i" -i "%%~ni".jpg -y -map_metadata 0 -map 0 -map 1 -movflags use_metadata_tags -vcodec jpeg2000 -acodec libmp3lame ..\output\\"%%~ni".mp3 
    del "%%~ni".jpg
    del "%%i"
    goto continue
  )

  if exist "%%~ni".webp (
    "%FFMPEG%" -i "%%i" -i "%%~ni".webp -y -map_metadata 0 -map 0 -map 1 -movflags use_metadata_tags -vcodec jpeg2000 -acodec libmp3lame ..\output\\"%%~ni".mp3 
    del "%%~ni".webp
    del "%%i"
    goto continue
  )

  "%FFMPEG%" -i "%%i" -y -map_metadata 0 -map 0 -movflags use_metadata_tags -vcodec jpeg2000 -acodec libmp3lame ..\output\\"%%~ni".mp3 
  del "%%i"
  goto continue

  :error1
  echo Ignore script file
  goto continue

  :error2
  echo File doesn't contain an audio stream
  goto continue

  :error3
  echo File is already in mp3 format
  goto continue

  :continue
)
endlocal
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • 3
    You cannot have labels inside a `for` loop `do` block. – Compo Oct 20 '21 at 19:08
  • Thank you for your answer I'll try it out later. – Alexander Hunger Oct 20 '21 at 19:21
  • Use proper quoting as well. `if exist "%%~ni.jpg"` and `"%FFMPEG%" -i "%%i" -i "%%~ni.webp"`. Change to this style of quoting with all your file name and file path references. Quotes should always surround the entire file and folder path. Not just the variable. – Squashman Oct 20 '21 at 19:44
  • You could get rid of the majority of those `IF` commands if you just specified the files you want to process. `for /f "delims=" %%i in ('dir /b *.m4a *.webm') do` – Squashman Oct 20 '21 at 19:51
  • 1
    This answer was helping me understanding the issue. https://stackoverflow.com/a/8481978/17074368 – Alexander Hunger Oct 20 '21 at 21:18

1 Answers1

1

This code worked for me now:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FFMPEG=C:\ffmpeg\bin\ffmpeg.exe"
for /f "delims=" %%i in ('dir /b') do (
  if /I not "%%i"=="%~nx0" if /I not "%%~xi"==".jpg" if /I not "%%~xi"==".webp" if /I not "%%~xi"==".mp3" ( 
    if exist "%%~ni.jpg" (
      "%FFMPEG%" -i "%%i" -i "%%~ni.jpg" -y -map_metadata 0 -map 0 -map 1 -movflags use_metadata_tags -acodec libmp3lame -f mp3 ..\output\\"%%~ni.mp3"
      del "%%~ni.jpg"
      del "%%i"
    ) else if exist "%%~ni.webp" (
      "%FFMPEG%" -i "%%i" -i "%%~ni.webp" -y -map_metadata 0 -map 0 -map 1 -movflags use_metadata_tags -acodec libmp3lame -f mp3 ..\output\\"%%~ni.mp3" 
      del "%%~ni.webp"
      del "%%i"
    ) else (
      "%FFMPEG%" -i "%%i" -y -map_metadata 0 -map 0 -movflags use_metadata_tags -acodec libmp3lame ..\output\\"%%~ni.mp3" 
      del "%%i"
    )
  )
)
endlocal

In fact, the problem was not caused by parentheses. It is just not possible to use "goto" within a for loop as @Compo stated in his comment above.