5

I have a ton of videos I need to convert from mp4 to wmv using ffmpeg and break up each file into 10 minute segments, but I am a total cmd scripting newb (in fact, I am a scripting newb :)

After spending six hours trying to find an answer, I thought I would bring it to you guys.

The code I have is working a little bit, but I need to be able to read data coming from the command line and send it back into the script for evaluation. I am not sure what code ffmpeg will spit out when it is done processing a video file (when the timestamp reaches an end), but this FOR loop just keeps on trying to create new file segments even though the video is over. This is what I saw when it tried to create a new file, so I think it might work to search for this:

frame= 0 fps=0.0 q=0.0 Lsize= 1kB time=00:00:00.00 bitrate=N/A

This is the code I have come up with so far (Don't laugh :)

@echo off
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION

for %%a in ("*.mp4") do (
set hour=00

for /L %%i IN (1,1,10) do (
:Beginning
    set /a start=%%i-1
        set end=%%i
        if !start! lss 10 set start=!start!0
        if !end! lss 10 set end=!end!0
        ffmpeg -ss !hour!:!start!:00 -i "%%a" -b:v 1500k -vcodec msmpeg4 -acodec wmav2 -t !hour!:!end!:00 "Converted\%%~na-!hour!-!start!-!end!.wmv"
        if end==60 CALL :Increment
    )   
)

:Increment
    set /a !hour!+1
    set %%i=1
    GOTO :Beginning
pause

Based on reading this thread was thinking something like this might go in the code, but not sure what to do with it:

set "dosstring=%*"

echo.!dosstring!|findstr /C:"frame=    0 fps=0.0 q=0.0 Lsize=       1kB time=00:00:00.00 bitrate=N/A" >nul 2>&1

Thanks so much for you help!

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
bobafetta
  • 59
  • 1
  • 4
  • I don't think the label `:Beginning` will work inside (), put it before `FOR %%A` [look at the bugs section](http://ss64.com/nt/goto.html) . Also test your batch with `echo` in front of `ffmpeg` command. Seems infintie loop in `goto :Beginning` because there is no `IF` statement – Paul Sep 07 '15 at 22:12
  • hehe my coding skills are what you might call jury rigged. That statement was strung together from like 10 different web pages. I will try what you said, but I have a feeling I can't get it to work lol – bobafetta Sep 07 '15 at 23:34

1 Answers1

2

A more efficient method is to invoke ffmpeg just once per file and use its segmenting feature.

The segments will be numbered sequentially so if you absolutely need to include timestamps in the name we'll also generate a list of the segment's timestamps in CSV format:

tmp000.wmv,0.000000,60.281000
tmp001.wmv,60.281000,120.041000

Then parse it and rename the segments.

@echo off

for %%a in (*.mp4) do (

    ffmpeg -i "%%a" ^
        -f segment -segment_time 10:00 -segment_list tmp.csv -reset_timestamps 1 ^
        -b:v 1500k -vcodec msmpeg4 -acodec wmav2 converted\tmp%%03d.wmv

    setlocal enableDelayedExpansion
    for /f "delims=, tokens=1-3" %%b in (tmp.csv) do (
        set sec=%%c & set sec=!sec:.*=!
        set /a hour="sec / 3600"
        set /a mins1="sec / 60 %% 60" & set mins1=0!mins1!
        set sec=%%d & set sec=!sec:.*=!
        set /a mins2="sec / 60 %% 60" & set mins2=0!mins2!

        ren "converted\%%b" "%%~na-!hour!-!mins1:~-2!-!mins2:~-2!.*"
    )
    endlocal
    del tmp.csv
)
pause

This example won't rename files with ! in the name as I didn't want to overcomplicate the code to work around this case.

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • Wow that is awesome thank you so much :) I'm sure it took you two seconds lol. It worked almost perfectly, but I tried a long file that produced 12 segments, and it named them perfect until it got to: -1-00-00 -1-10-10 Then it skipped to: -1-60-60 -1-70-70 etc. I am trying to fix it, but maybe it would just be easier to put a counter after the name with 10, 20, etc. I just need to know which files I watched, so anything sequential is good. I will try to figure it out, but you got the hardest part down. Thanks again! :) – bobafetta Sep 07 '15 at 23:30
  • very well batch, just tried to demux a small mp4 and it works smoothly. `%ffmpeg% -i "%%a" ^ -f segment -segment_time 1:00 -segment_list tmp.csv -reset_timestamps 1 ^ -codec copy -c:v copy -c:a copy -flags +global_header converted\tmp%%03d.mp4` Thank you. – Paul Sep 08 '15 at 00:26
  • 2
    @bobafetta, there was a typo and the wrong formula to calculate the minutes after 1 hour length. – wOxxOm Sep 08 '15 at 05:01
  • You are the best! I can't tell you how much I appreciate your help :D – bobafetta Sep 09 '15 at 03:49