Quantcast
Channel: Active questions tagged jq - Stack Overflow
Viewing all articles
Browse latest Browse all 657

Is there a way to batch split a file by chapter with ffmpeg and then reassemble with mkvmerge in windows?

$
0
0

So I made a batch script originally with the ability to relatively precision trim a video into chapters without having to run by keyframes, but the code looks horrible and I can't get it to loop through all mp4 files nor get mkvmerge to append the files after splitting them. Code is below but be gentle it is my first try.

@echo offsetlocal enableDelayedExpansionREM CODE BELOW CREATES JSON FILES FOR ALL MP4 FILES WITHIN THE SAME DIRECTORYffprobe -v quiet -print_format json -show_chapters -loglevel error "01x01.mp4" > "01x01.json"REM CODE BELOW SETS VARIABLES FROM EACH SPECIFIC JSONFOR /F "delims=" %%i in ('jq .chapters[2].start ^< 01x01.json') DO SET /A start1=%%iFOR /F "delims=" %%j in ('jq .chapters[2].end ^< 01x01.json') DO SET /A end1=%%jFOR /F "delims=" %%k in ('jq .chapters[4].start ^< 01x01.json') DO SET /A start2=%%kFOR /F "delims=" %%l in ('jq .chapters[4].end ^< 01x01.json') DO SET /A end2=%%lFOR /F "delims=" %%m in ('jq .chapters[6].start ^< 01x01.json') DO SET /A start3=%%mFOR /F "delims=" %%n in ('jq .chapters[6].end ^< 01x01.json') DO SET /A end3=%%nFOR /F "delims=" %%o in ('jq .chapters[8].start ^< 01x01.json') DO SET /A start4=%%oFOR /F "delims=" %%p in ('jq .chapters[8].end ^< 01x01.json') DO SET /A end4=%%pREM SETS THE DURATION OF EACH FILE TO USE PRECISION TIMING FOR START AND STOP TIMESCALL vbs (%end1%-%start1%)/1000SET duration1=%val%CALL vbs (%end2%-%start2%)/1000SET duration2=%val%CALL vbs (%end3%-%start3%)/1000SET duration3=%val%CALL vbs (%end4%-%start4%)/1000SET duration4=%val%REM SETS THE START TIME IN SECONDS VS MILLISECONDSCALL vbs (%start1%)/1000SET start1=%val%CALL vbs (%start2%)/1000SET start2=%val%CALL vbs (%start3%)/1000SET start3=%val%CALL vbs (%start4%)/1000SET start4=%val%REM TRIM AND SPLIT ORIGINAL FILE INTO SEPERATE SECTIONS BASED ON CHAPTER MARKERSffmpeg -ss %START1% -i 01x01.mp4 -ss 0 -c copy -to %DURATION1% -avoid_negative_ts make_zero 01x01-1.mp4ffmpeg -ss %START2% -i 01x01.mp4 -ss 0 -c copy -to %DURATION2% -avoid_negative_ts make_zero 01x01-2.mp4ffmpeg -ss %START3% -i 01x01.mp4 -ss 0 -c copy -to %DURATION3% -avoid_negative_ts make_zero 01x01-3.mp4ffmpeg -ss %START4% -i 01x01.mp4 -ss 0 -c copy -to %DURATION4% -avoid_negative_ts make_zero 01x01-4.mp4REM DELETES UNNEEDED JSON AFTER USEdel /s *.jsonREM APPEND ALL MP4 FILES INTO COHESIVE MKVfor /d /r %%D in (*) do (    pushd %%D    set files=    for %%F in (*.mp4) do set files=!files! + ^( "%%F" ^)    if not "!files!"=="" %mkvmerge% -o "01x01-FINAL.mkv" !files:~2!    popd)REM DELETE UNNEEDED MP4 ORIGINALS AND SPLIT FILESdel /s *.mp4

I know it is super long and every time I try to use a variable or a loop to run through all files it can't read the json file. I've been at this all day and I can use the script as is but I have to make a file for each iteration.

I was also hoping to be able to have it only pull chapters labeled as "video" but I haven't quite figured that one out yet.

I'll add the vbs batch file for the arithmetic section as well as the sample json if it will help.

@echo off>"%temp%\VBS.vbs" echo Set fso = CreateObject("Scripting.FileSystemObject") : Wscript.echo (%*)for /f "delims=" %%a in ('cscript /nologo "%temp%\VBS.vbs"') do set "val=%%a"del "%temp%\VBS.vbs"
{"chapters": [        {"id": 0,"time_base": "1/1000","start": 0,"start_time": "0.000000","end": 5590,"end_time": "5.590000","tags": {"title": "Video"            }        },        {"id": 1,"time_base": "1/1000","start": 5590,"start_time": "5.590000","end": 13994,"end_time": "13.994000","tags": {"title": "Advertisement"            }        },        {"id": 2,"time_base": "1/1000","start": 13994,"start_time": "13.994000","end": 163964,"end_time": "163.964000","tags": {"title": "Video"            }        },        {"id": 3,"time_base": "1/1000","start": 163964,"start_time": "163.964000","end": 195940,"end_time": "195.940000","tags": {"title": "Advertisement"            }        },        {"id": 4,"time_base": "1/1000","start": 195940,"start_time": "195.940000","end": 547849,"end_time": "547.849000","tags": {"title": "Video"            }        },        {"id": 5,"time_base": "1/1000","start": 547849,"start_time": "547.849000","end": 595850,"end_time": "595.850000","tags": {"title": "Advertisement"            }        },        {"id": 6,"time_base": "1/1000","start": 595850,"start_time": "595.850000","end": 1413588,"end_time": "1413.588000","tags": {"title": "Video"            }        },        {"id": 7,"time_base": "1/1000","start": 1413588,"start_time": "1413.588000","end": 1477569,"end_time": "1477.569000","tags": {"title": "Advertisement"            }        },        {"id": 8,"time_base": "1/1000","start": 1477569,"start_time": "1477.569000","end": 1529696,"end_time": "1529.696000","tags": {"title": "Video"            }        }    ]}

I also tried using the start_time so I didn't have to do extra calculations but jq didn't like that either.

mkvmerge doesn't even try to run when I have it in here and I still need to cut 7 seconds off the end and 12 seconds off the front of it once it is all one file again.

Any help would be appreciated, I know it's a lot but I seem to have hit a roadblock or just sleep deprived at this point.

UPDATE

This works amazing I just need to figure out how to use files with spaces and I'm all set. I guess I could run a batch before hand replacing all spaces with underscores. That would probably work but I would like to not change filenames if I can help it.

@echo offfor %%i in (*.mp4) do (FOR /F "delims=" %%A IN ('ffprobe -v quiet -print_format json -show_chapters -loglevel error "%%i" ^| xidel - -se "$json/(chapters)()[id!=0 and tags/title='Video']/concat('ffmpeg -ss ',start div 1000,' -i %%i -to ',((end - start) div 1000),' -c copy -avoid_negative_ts make_zero %%~ni-',position(),'.mp4')"') DO %%AFOR /F "delims=" %%A IN ('xidel -s --xquery "concat('mkvmerge -o &quot;%%~ni-FINAL.mkv&quot; &quot;',join(file:list(.,false(),'%%~ni-*.mp4'),'&quot; +&quot;'),'&quot;')"') DO %%A)

Viewing all articles
Browse latest Browse all 657

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>