Batch ffmpeg auto convert

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
central10
Posts: 11
Joined: 12 May 2010 10:30

Batch ffmpeg auto convert

#1 Post by central10 » 12 May 2010 10:35

Hello,

Over the past few days I have been trying to automate the ffmpeg conversion process to save my self some time.

I have a monitoring program that automatically executes/runs a program every time a video file is added to a folder. This program doesn’t have any arguments for the file and simply runs any program upon addition of a new file. What I have done is created a bat file named “auto.bat” which is being run automatically by the program every time a file is added to the folder.

The bat file looks like this:

C:\ffmpeg\ffmpeg.exe -y -i %1 -vcodec flv -b 250k -r 14.985 -acodec libmp3lame -ab 40k -ar 22050 -ac 1 -vol 276 -qscale 5 %1.flv


This bat file works if I drag and drop the avi file into it however this isn’t how I want it to function. I would like the batch file to automatically grab the new file in the folder and start ffmpeg. I’ve poked around on the Internet and can’t seem to find a solution. I’m new to writing batch files so I don’t have the expertise to finish this off. I’m wondering if someone can guide me in the right direction.

Any help would be greatly appreciated.
Regards,
Dave

jeb
Expert
Posts: 1042
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Batch ffmpeg auto convert

#2 Post by jeb » 12 May 2010 12:57

Hi central10,

something like this should work

Code: Select all

@echo off
SETLOCAL EnableDelayedExpansion
set "latestFile="
call :findlatestfile latestFile

::###############################
:monitor
call :findlatestfile currentlatestFile
if "%currentlatestFile%" NEQ "%latestFile%" (
  echo "%currentlatestFile%" NEQ "%latestFile%"
  set "latestFile=%currentlatestFile%"
  call :openFile %latestFile%
)
rem to preseve the cpu usage
call :sleep
goto :monitor

::###############################
:openFile <file>
C:\ffmpeg\ffmpeg.exe -y -i %~n1 -vcodec flv -b 250k -r 14.985 -acodec libmp3lame -ab 40k -ar 22050 -ac 1 -vol 276 -qscale 5 %~n1.flv
goto :eof

::###############################
:findlatestfile
for /F "delims=" %%a in ('dir  /b /od *.flv') DO (
   set %~1=%%a
)
goto :eof

::###############################
:sleep
ping -n 2 localhost > nul
goto :eof


jeb

central10
Posts: 11
Joined: 12 May 2010 10:30

Re: Batch ffmpeg auto convert

#3 Post by central10 » 12 May 2010 13:29

Hey Jeb,

thank you for the quick reply.

I have copied the batch file an replaced it on my current "auto.bat" file. I'm not certain on the usage though because when i execute it I get the echo "file not found".

What I have done i just placed the batch file into the folder where new files are being placed. Do I need to set a directory for the bath file to watch?

Thank you in advance.
Dave

jeb
Expert
Posts: 1042
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Batch ffmpeg auto convert

#4 Post by jeb » 13 May 2010 03:31

Hi central10,

you got "file not found", because in the local path are no *.flv files found.

I changed it a bit, so it suppress the error message and it is more verbose.

Code: Select all

@echo off
SETLOCAL EnableDelayedExpansion
set "latestFile="
call :findlatestfile latestFile
echo the latest file is "%latestFile%"
::###############################
:monitor
call :findlatestfile currentlatestFile
if "%currentlatestFile%" NEQ "%latestFile%" (
  echo new file "%currentlatestFile%"
  set "latestFile=%currentlatestFile%"
  call :openFile %latestFile%
)
rem to preseve the cpu usage
call :sleep
goto :monitor

::###############################
:openFile <file>
echo Start ffmpeg with -y -i %~n1 -vcodec flv -b 250k -r 14.985 -acodec libmp3lame -ab 40k -ar 22050 -ac 1 -vol 276 -qscale 5 %~n1.flv
C:\ffmpeg\ffmpeg.exe -y -i %~n1 -vcodec flv -b 250k -r 14.985 -acodec libmp3lame -ab 40k -ar 22050 -ac 1 -vol 276 -qscale 5 %~n1.flv
goto :eof

::###############################
:findlatestfile
set "%~1=NO FILE"
for /F "delims=" %%a in ('dir  /b /od *.flv 2^> nul') DO (
   set %~1=%%a
)
goto :eof

::###############################
:sleep
ping -n 2 localhost > nul
goto :eof


jeb

central10
Posts: 11
Joined: 12 May 2010 10:30

Re: Batch ffmpeg auto convert

#5 Post by central10 » 13 May 2010 13:09

Hello Jeb,

The files that are being added to the folder are avi files. These files are then converted in flash flv files. So I went ahead and changed the *.flv in your script to *.avi.

After running the bat file and adding “fileone.avi” to the folder I had an error saying “fileone no such file in directory”. So I added on the file extension to the end of the n1 command and it worked but with some issues. Let me explain.

I grabbed 5 avi files from my hard-drive and renamed them FILEONE.avi … FILEFIVE.avi based on when they were downloaded. I started the bat file and placed fileone into the proper folder and this is what was generated in the command line.

the latest file is "NO FILE"
new file "FILEONE.avi"
Start ffmpeg with -y -i NO.avi -vcodec flv -b 250k -r 14.985 -acodec libmp3lame
-ab 40k -ar 22050 -ac 1 -vol 276 -qscale 5 NO.flv
FFmpeg version UNKNOWN, Copyright (c) 2000-2008 Fabrice Bellard, et al.
configuration: --disable-shared --enable-memalign-hack --enable-gpl --cpu=i686
--enable-libmp3lame --enable-libfaac --enable-liba52 --enable-libfaad --enable-
libamr-nb --enable-libamr-wb --disable-devices
libavutil 49.11. 0 / 49.11. 0
libavcodec 52. 0. 0 / 52. 0. 0
libavformat 52.22. 1 / 52.22. 1
libavdevice 52. 1. 0 / 52. 1. 0
built on Sep 29 2008 01:17:53, gcc: 4.2.1-sjlj (mingw32-2)
NO.avi: no such file or directory

For what ever reason the file that was added to ffmpeg was named “no.avi” which is non-existent.

The next thing I did was add FILETWO.avi to the folder which then started up ffmpeg but rather then converting filetwo.avi it started to convert fileone.avi. Then if I add another file such as FILETHREE.avi then filetwo.avi will start to convert.

Sometimes there will be three files added to the folder within a few minutes of each other. Rather then have then in a que like it is now, is there a way that the bat file can execute ffmpeg in multiple instances for every newly added file rather then wait for the conversion process of the first file to be completed?

For instance, could there be two bat files? The first file will monitor the folder and every time a new file is added to the folder it would run the second bat file, which would start the conversion process for the newly added file. Then multiple ffmpeg conversions could be going on at once.

Sorry to ask you for so much. I’ve tried to learn batch but this is way to complex for me.
Thank you in advance.
Dave

jeb
Expert
Posts: 1042
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Batch ffmpeg auto convert

#6 Post by jeb » 13 May 2010 23:15

hi central10,

the problem, that always the "previous" file will be taken, is a batch specific behaviour at

Code: Select all

if "%currentlatestFile%" NEQ "%latestFile%" (
  echo new file "%currentlatestFile%"
  set "latestFile=%currentlatestFile%"
  call :openFile %latestFile%
)


The %latestFile% will not be updated in the block, you can use delayed Expansion !latestFile! or the %currentlatestFile%.

central10 wrote:For instance, could there be two bat files? The first file will monitor the folder and every time a new file is added to the folder it would run the second bat file, which would start the conversion process for the newly added file. Then multiple ffmpeg conversions could be going on at once.


A simple way is to start the conversion with "start", it will start the conversion in an new window

Code: Select all

start C:\ffmpeg\ffmpeg.exe -y -i %~n1.avi -vcodec flv -b 250k -r 14.985 -acodec libmp3lame -ab 40k -ar 22050 -ac 1 -vol 276 -qscale 5 %~n1.flv


jeb

central10
Posts: 11
Joined: 12 May 2010 10:30

Re: Batch ffmpeg auto convert

#7 Post by central10 » 14 May 2010 10:24

Hello Jeb,

The folder-monitoring program that I was using has allowed me to successfully make this batch program work/function nearly the way I would like it to. Every time a new file is added to the folder the program will run the batch file, which will grab the latest modified file and convert it. I’ve changed the last “goto :eof” to “exit” so that the command line will exit once ffmpeg has started.

Now, there’s another problem that I noticed. The batch script only recognizes the files based on their modification date and not necessarily by the most recently added file. For instance “fileone.avi” was modified on 5/12/2010 1:33 PM while “filetwo.avi” was modified on 5/12/2010 11:33 AM but regardless if “filetwo.avi” was the most recently added file to the folder it will still start to convert “fileone.avi” because of it’s modification date. Is there any other way to fix that?

If there isn’t an option to fix that then maybe it’s possible to have the batch file scan the folder and see which avi file doesn’t have a duplicate file name but with the .flv extension. If the avi files doesn’t have a duplicate then it would be grab the file and start the conversion process.

This batch command is almost perfect; all that needs doing is this last past.

Thank you in advance for your help.
Regards,
Dave

Code: Select all

@echo off

SETLOCAL EnableDelayedExpansion
set "latestFile="
call :findlatestfile latestFile
echo the latest file is "%latestFile%"
::###############################
:monitor

if "%currentlatestFile%" NEQ "%latestFile%" (
  echo new file "%currentlatestFile%"
  set "latestFile=%currentlatestFile%"
  call :openFile %latestFile%

)
rem to preseve the cpu usage
call :sleep
goto :monitor

::###############################
:openFile <file>
echo Start ffmpeg with -y -i %~n1.avi -vcodec flv -b 250k -r 14.985 -acodec libmp3lame -ab 40k -ar 22050 -ac 1 -vol 276 -qscale 5 %~n1.flv
start C:\ffmpeg\ffmpeg.exe -y -i %~n1.avi -vcodec flv -b 250k -r 14.985 -acodec libmp3lame -ab 40k -ar 22050 -ac 1 -vol 276 -qscale 5 %~n1.flv

exit

::###############################
:findlatestfile
set "%~1=NO FILE"
for /F "delims=" %%a in ('dir  /b /od *.avi 2^> nul') DO (
   set %~1=%%a
)

goto :eof

::###############################
:sleep
ping -n 2 localhost > nul

exit


central10
Posts: 11
Joined: 12 May 2010 10:30

Re: Batch ffmpeg auto convert

#8 Post by central10 » 14 May 2010 11:46

Hi,

It will work if there's a way to grab the file based on it's creation date rather then it's modified date.

Regards,
Dave

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Batch ffmpeg auto convert

#9 Post by aGerman » 14 May 2010 12:04

Hi,

if you work on a NTFS formatted drive you could use the DIR switch /TC instead of /OD.

Regards
aGerman

central10
Posts: 11
Joined: 12 May 2010 10:30

Re: Batch ffmpeg auto convert

#10 Post by central10 » 15 May 2010 10:36

I'm not sure what kind of drive I have. How do I go about changing the directory switch?

Dave

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Batch ffmpeg auto convert

#11 Post by aGerman » 15 May 2010 13:20

I think you misunderstood. I talked about the switch (option) of the DIR command.
In this line:-

Code: Select all

for /F "delims=" %%a in ('dir  /b /od *.avi 2^> nul') DO (
   set %~1=%%a
)

... you could try to replace the switch /od by /tc to finally get this line:-

Code: Select all

for /F "delims=" %%a in ('dir  /b /tc *.avi 2^> nul') DO (
   set %~1=%%a
)

But this will not work on say FAT file systems (often used on flash drives) but only on a NTFS file system (often used on hard drives). To verify the file system do a right click to the drive letter and have a look to the properties. Otherwise you could write eg.
fsutil fsinfo volumeinfo C:\
to the command prompt.

Regards
aGerman

central10
Posts: 11
Joined: 12 May 2010 10:30

Re: Batch ffmpeg auto convert

#12 Post by central10 » 16 May 2010 12:17

Hello aGerman,

I tried changing the code as you outline in the previous post but I get the same result as before.

Any other options?

Regards,
Dave

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Batch ffmpeg auto convert

#13 Post by aGerman » 16 May 2010 12:49

Well the c in /tc is for Creation.

Other options would be
/ta for Last Access
/tw for Last Written

If /tc doesn't work then you should try /ta.

Regards
aGerman

[EDIT]
Think I found the problem. In each iteration of :monitor you have to call the :findlatestfile function to get the new latest file.

Code: Select all

:monitor

if "%currentlatestFile%" NEQ "%latestFile%" (
  echo new file "%currentlatestFile%"
  set "latestFile=%currentlatestFile%"
  call :openFile %latestFile%

)
rem to preseve the cpu usage
call :sleep
:: *** This line added: ***
call :findlatestfile latestFile
goto :monitor

[/EDIT]

central10
Posts: 11
Joined: 12 May 2010 10:30

Re: Batch ffmpeg auto convert

#14 Post by central10 » 17 May 2010 12:55

Hello aGerman,

I added the new call line as you had said and it continued to grab the most recently modified file. I tried all the different variations that you had mentioned but none seemed to work.

Anyway, long story short; it wasn't working because there was no file ordering before the tc ta tw commands.

This is what I am using and it works perfectly now :)

Code: Select all

:findlatestfile
set "%~1=NO FILE"
for /F "delims=" %%a in ('dir  /b /od /tc *.avi 2^> nul') DO (
   set %~1=%%a
)


Thank you very much for your help. I feel like I have a much better understanding of batch files now.

Regards,
Dave

Samir
Posts: 384
Joined: 16 Jul 2013 12:00
Location: HSV
Contact:

Re: Batch ffmpeg auto convert

#15 Post by Samir » 16 Jul 2013 12:41

I hate to bump such an old thread, but I have to add some experience that I used in the late 1990s for mass converting mp3s. What I had created was a n-scalable batch file for mass parallel encoding files. :mrgreen:

So you have a source batch file on a file server with your files to be encoded. This batch file basically has the following logic:

Code: Select all

for all the .wav files in the directory
if the same root filename exists with .mp3, skip it and go to the next one (this helped with using multiple computers since the file existed when created by a system)
encode the .wav to .mp3
It was pretty simple, but the power of it was that you could map this server drive to as many computers as you wanted and execute the batch file. If the .mp3 already existed, the system skipped the file and started encoding the next one. I used a half dozen computers to batch encode in almost real-time back then. :mrgreen:

The same logic could be used for what you're trying to accomplish with the video files. I'd just add a delay timer to check the directory every 15 minutes for any file that doesn't have an .flv equivalent. If it doesn't, encode it.

Post Reply