0

Complete change to the question!

I now have the following script:

@echo off
REM keep a counter for files converted
set /A nfile=0
REM do not copy empty folders or any files
@echo Copying directory structure from %0 to %1 ...
xcopy /T %1 %2
REM walk directory structure and convert each file in quiet mode
for /R %1 %%v in (*.mp4, *.aac, *.flv, *.m4a, *.mp3) do (
    echo converting "%%~nxv" ...
    ffmpeg -v quiet -i "%%v" -vcodec libx264 "%2\%%~nv-converted.mp4"
    set /A nfile+=1
)
echo Done! Converted %nfile% file(s)

Taken from: http://mostlybuggy.wordpress.com/2012/09/25/windows-batch-file-how-to-copy-and-convert-folders-recursively-with-ffmpeg/

The videos are converting as expected when I run the following command:

convert ..\..\folder ..\..\converted\

However, the converted files end up in "converted" and not in their respective sub-folders.

Any ideas?

Tisch
  • 2,598
  • 4
  • 27
  • 34

2 Answers2

3

You need to incorporate the relative path of each source file into your destination. That is not trivial to do if you want the script to be bullet proof.

The untested code below uses a batch function to determine the length of a string. There are many techniques for computing string length in batch.

Once I know the length of the root source path, it is easy to do a substring operation on the full path of a source file to get the relative path.

@echo off
setlocal disableDelayedExpansion

REM get absolute path of source and destination roots
for %%F in ("%~1\x") do set "src=%%~dpF"
for %%F in ("%~2\x") do set "dst=%%~dpF"

REM get length of root source path
call :strlen src srcLen

REM keep a counter for files converted
set /A nfile=0
REM do not copy empty folders or any files
@echo Copying directory structure from %1 to %2 ...
xcopy /T "%src%\." "%dst%\."

REM walk directory structure and convert each file in quiet mode
for /R "%src%" %%F in (*.mp4, *.aac, *.flv, *.m4a, *.mp3) do (
  set "file=%%~fF"
  set "file2=%%~dpnF"
  echo converting "%%~nxF" ...
  setlocal enableDelayedExpansion
  ffmpeg -v quiet -i "!file!" -vcodec libx264 "!dst!!file2:~%srcLen%!-converted.mp4"
  endlocal
  set /A nfile+=1
)
echo Done! Converted %nfile% file(s)
exit /b


:strlen  strVar  [rtnVar]
setlocal EnableDelayedExpansion
set "s=!%~1!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
  if "!s:~%%P,1!" NEQ "" (
    set /a "len+=%%P"
    set "s=!s:~%%P!"
  )
)
(
  endlocal
  if "%~2" equ "" (echo %len%) else set "%~2=%len%"
  exit /b
)

There is a really simple solution if you have two unassigned drive letters that can be mapped to your root source and destination folders. That would allow you to use the full absolute path (without the drive letter). I'm assuming X: and Y: are available

@echo off
setlocal disableDelayedExpansion

REM map unused drive letters to source and destination
for %%F in ("%~1\.") do subst x: "%%~fF"
for %%F in ("%~2\.") do subst y: "%%~fF"

REM keep a counter for files converted
set /A nfile=0
REM do not copy empty folders or any files
@echo Copying directory structure from %1 to %2 ...
xcopy /T x:\ y:\

REM walk directory structure and convert each file in quiet mode
for /R x:\ %%F in (*.mp4, *.aac, *.flv, *.m4a, *.mp3) do (
  echo converting "%%~nxF" ...
  ffmpeg -v quiet -i "%%F" -vcodec libx264 "y:%%~pnF-converted.mp4"
  set /A nfile+=1
)
echo Done! Converted %nfile% file(s)
exit /b

REM release mapped drive letters
subst /d x:
subst /d y:
Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • I used the second example with the drive mapping, this is a fantastic solution. The command I then used was: so-convert ..\..\folder ..\..\converted\ – Tisch Sep 30 '13 at 21:17
0

try this:

@echo off &setlocal
set /a nfile=0
echo Copying directory structure from %1 to %2 ...
xcopy /T "%~1" "%~2"
REM walk directory structure and convert each file in quiet mode
set "sourcefolder=%~1"
set "targetfolder=%~2"
for /R "%sourcefolder%" %%a in (*.mp4 *.aac *.flv *.m4a *.mp3) do (
    echo converting "%%~nxa" ...
    set "sourcefile=%%~fa"
    set "sourcepath=%%~dpa"
    set "targetfile=%%~na-converted.mp4"
    setlocal enabledelayedexpansion
    set "targetfolder=%targetfolder%!sourcepath:%sourcefolder%=!"
    ffmpeg -v quiet -i "!sourcefile!" -vcodec libx264 "!targetfolder!!targetfile!"
    endlocal
    set /A nfile+=1
)
echo Done! Converted %nfile% file(s)
Endoro
  • 37,015
  • 8
  • 50
  • 63
  • This can only work as written if `%1` contains full absolute source path and both `%1` and `%2` have trailing back slash. Even if that problem is fixed, the search and replace technique cannot work if sourcepath contains `=` or `!` character. – dbenham Sep 30 '13 at 18:42