1

I have a batch file that recursively encodes videos to a sub folder "encode" then deletes the original and moves the new file to the original directory. The problem I'm having is that after each video is encoded, the for loop picks up the newly encoded video and runs again. After that, it moves on to the next video. I'm not sure why it runs twice instead of once or infinitely. What am I misunderstanding? I am a complete novice, so my apologies if it's a simple mistake.

@echo off
set /A count = 0
pushd %~dp0
for /R %%f in (*.mp2, *.mpg, *.vob, *.avi, *.wmv, *.mov, *.mp4, *.m4v, *.mpeg) do (
mkdir %%~dpf\encode
C:\HandBrakeCLI -i "%%f" -o "%%~dpf\encode%%~nf.mp4"
del "%%f"
move "%%~dpf\encode\%%~nf.mp4" %%~dpf
rmdir %%~dpf\encode
set /A count+=1
)
popd
echo Count is: %count%
pause
RossV
  • 195
  • 3
  • 12
  • Do you need `*.mp4` in the for loop's file list? Your conversion is creating another file that will end up being processed. – Tony Nov 26 '18 at 19:30
  • Ideally, yes. I'm reducing the quality of the videos, so I'd like to reduce the original mp4s down to a smaller size mp4 as well. However, I could live with ignoring these if I can't figure this out. They are probabaly only about 20% of the videos. – RossV Nov 26 '18 at 19:33
  • I would just put all of the new files in a new folder to start with, then delete the original folder contents after all of the encoding is done, and copy the new ones over to the original folder. An alternative would be to read all of the filenames into an array before encoding anything and loop through that, rather than the folder contents directly, but I'm not sure how you'd do that in a batch file. – 3Dave Nov 26 '18 at 19:41
  • Do you need to retain the original file folder's structure, keeping the converted files in the same folder location? – Tony Nov 26 '18 at 19:44
  • I do need to retain folder structure. – RossV Nov 26 '18 at 19:47

2 Answers2

1

The reason it processes twice is because the file conversion creates another video clip that matches the criteria in the FOR loop.

To avoid dealing with folder structures and syncing, a simple way to get around this is to split the process into two loops, performing the *.mp4 files first:

@echo off
set /A count = 0
pushd %~dp0
for /R %%f in (*.mp4) do (
   mkdir %%~dpf\encode
   C:\HandBrakeCLI -i "%%f" -o "%%~dpf\encode%%~nf.mp4"
   del "%%f"
   move "%%~dpf\encode\%%~nf.mp4" %%~dpf
   rmdir %%~dpf\encode
   set /A count+=1
   )
for /R %%f in (*.mp2, *.mpg, *.vob, *.avi, *.wmv, *.mov, *.m4v, *.mpeg) do (
   mkdir %%~dpf\encode
   C:\HandBrakeCLI -i "%%f" -o "%%~dpf\encode%%~nf.mp4"
   del "%%f"
   move "%%~dpf\encode\%%~nf.mp4" %%~dpf
   rmdir %%~dpf\encode
   set /A count+=1
   )
popd
echo Count is: %count%
pause

Don't forget to remove the *.mp4 from the second loop's file list.


Edit: Here's a solution that's more elegant.

@echo off
set /A count = 0
pushd %~dp0
for %%e in (mp4 mp2 mpg vob avi wmv mov m4v mpeg) do (
   for /R %%f in (*.%%e) do (
      mkdir %%~dpf\encode
      C:\HandBrakeCLI -i "%%f" -o "%%~dpf\encode%%~nf.mp4"
      del "%%f"
      move "%%~dpf\encode\%%~nf.mp4" %%~dpf
      rmdir %%~dpf\encode
      set /A count+=1
   )
)
popd
echo Count is: %count%
pause

Make sure the mp4 is listed first so it's not reconverted once the other file types are processed.

Tony
  • 2,658
  • 2
  • 31
  • 46
0

I've tested it to see why it behaves so strangely like this, well, and the only answer I could come up with is that it simply acts strangely. my guess is that it depends on the order of operations.

this is my take on it: in some implementations of the code, the for /r avoids an infinite loop. what it does, is run on the files that are not .mp4 first. then, probably because it was renamed, it doesn't recognize it as the same file. probably, after it runs on the .mp4, the second time, it's file inode (except for the last time opened and edited) shouldn't be different at least to the point where the system won't recognize it as the same file anymore. I tested a bit different version of the code that did produce an infinite loop:

set /A count = 0
pushd %~dp0
for /R %%f in (*.mp2, *.mpg, *.vob, *.avi, *.wmv, *.mov, *.mp4, *.m4v, *.mpeg) do (
mkdir %%~dpf\encode

move %%f %%~dpf\encode
rename %%~dpf\encode\%%f %%~dpf\encode\%%~nf.mp4

move %%~dpf\encode\%%~nf.mp4 %%~dpf
rmdir %%~dpf\encode
set /A count+=1
)
popd
echo Count is: %count%
pause 

and strangely, not only it ran an infinite loop, but it also created an infinite amount of subfolders named '\encode\encode\encode...', but the reason for that doesn't matter. what's different in this version of the code, is that I always rename the files. that is probably why it produces an infinite loop.

the for /r command reiterates files that have been renamed, and not necessarily on those edited. the solution seems to be, indeed, to run the code on all .mp4 files first, and the other ones second.

blahh
  • 47
  • 12