FFMPEG - Automatic Stream Copy Then Encode On Fail - ffmpeg

I've embarked on a mission to get rid of all of my MKV files since the MP4 container works better for me. So to that end, I did some research and wrote a small script that searches my data files for MKVs and stream copies them to MP4. The script works most of the time, but I get the occasional file that fails and since the script deletes the originals, I lose the file completely.
I'd like to modify the script in two ways:
(1) Before deleting the original file, check that the converted file is greater than zero.
(2) If the converted file is zero (failed) then run an FFMPEG command to re-encode the original file using default values utilizing Intel Quick Sync hardware encoding, then delete the original as usual and go on to the next file in the list.
Here's what I have so far...
#ECHO OFF
cls
echo This script automatically converts MKV video files to MP4.
echo.
echo Changing directory to data drive (Z:).
echo.
Z:
echo Retrieving list of MKV files...
echo.
dir /b /s *.mkv > MKV-Files.txt
echo MKV list compiled.
echo.
echo Converting files to MP4...
echo.
FOR /F "delims=;" %%F in (MKV-Files.txt) DO (
echo Converting "%%F"
echo.
C:\FFMPEG\bin\ffmpeg.exe -y -i "%%F" -movflags faststart -codec copy "%%~dF% %~pF%%~nF.mp4"
echo.
echo Conversion successful.
echo.
echo Deleting "%%F"
echo.
del "%%F" /F
)
echo Job completed.
echo.
echo Exiting...
Thanks in advance for your ideas.

You can try this substitution:
ffmpeg.exe -y -i "%%F" -abort_on empty_output -movflags faststart -codec copy "%%~dF% %~pF%%~nF.mp4" || ffmpeg.exe -y -i "%%F" -movflags faststart -c:v h264_qsv -c:a copy "%%~dF% %~pF%%~nF.mp4"
You may want to disable subtitle or data tracks as MP4 has limited support for them. Add -dn and -sn for that.

Related

Need help to convert all "mp4" files to "gif" in a folder/directry with ffmpeg and .bat

I need some help.I try work automation to eliminate unnecessary time, I was looking for a way to convert video files to gif files.
So I learned how to make it using ".bat" through Googling, and want to make it a ".bat file" that automatically converts all mp4 files at one click because only one file is converted at a time.
it worked perfect for me. but I got a lot of vidoe files what i have to convert. I installed ffmpeg in my PC(#window)
this is what i find
#echo off
chcp 65001
cls
setlocal
echo 프레임 수치를 설정하세요
set /p fps=
ffmpeg.exe -i "%~1" -vf "fps=%fps%,scale=860:-1:flags=lanczos,palettegen" "%~n1.png"
ffmpeg.exe -i "%~1" -i "%~n1.png" -lavfi "fps=%fps%,scale=860:-1:flags=lanczos [x]; [x][1:v] paletteuse" "%~n1.gif"
del "%~n1.png"
goto :a
Thank for reading it.

How to set file name after merging video files (batch script, FFMPEG)

I use this bat script for converting .mp4(x264) files to .mp4(x265)
for %% in ("*.mp4") do ffmpeg -i "%%a" -c:v hevc "%dp0NewFolder\%%~na[HEVC].mp4"
So I'm trying to make another bat script for merging video files(concat).
for %%i in (*.mp4) do echo file '%%i'>> vlist.txt
ffmpeg -f concat -safe 0 -i vlist.txt -c copy %~dp0NewFolder\%%~na.mp4
Files to merge would be like
Vid_1.mp4,
Vid_2.mp4,
Vid_#.mp4
...
I want to keep the part before "_" in the new file name
What should I use instead of %%~na? To make it just Vid.mp4
Currently it creates %~na.mp4
From what I got you don't need a big scheme to create a output filename since we are talking about 1 filename only, or did I get something wrong?
for /f "delims=_" %%a in ('dir /b /a-d *.mp4') do set "NewVideoName=%%a"& goto :Next
:Next
ffmpeg -f concat -safe 0 -i vlist.txt -c copy "NewFolder\%NewVideoName%.mp4"

Windows CMD Batch Script FFmpeg

I have created a batch file (.bat) that uses FFmpeg to transcode various videos (with *.mov or *.mp4 file name extension) from an input folder to an output folder (with extension *.mkv) as batch process (Windows 10 environment).
File names (without extension) from the input folder should be copied to the newly created output file names (that have the new file extension *.mkv).
#echo off
set CMD=ffmpeg -c:v ffv1 -level 3 -g 1 -coder 1 -context 1 -pix_fmt + -slices 24 -slicecrc 1 -report -c:a pcm_s24le
FOR /R input_folder %%G IN (*.mov,*.mp4) DO (
echo %%G
call set outputfile=%%~nG%.mkv
call set inputfile=%%~nG%%~xG
echo %CMD% -y output_folder/%outputfile% -i %inputfile%
)
But this script does not work as expected, i.e. nothing happens.
Do you perhaps have an idea how to fix this?
Thanks in advance!
Here's an example showing my suggestions from the comments, with the addition of the file deletion as requested in the comments too. This assumes that ffmpeg returns an errorlevel of 0 upon success, (you don't want to delete them if the processing failed), and that there is an existing directory named output_folder, in the current working directory.
#Echo Off
SetLocal EnableExtensions
Set "CMD=ffmpeg.exe -c:v ffv1 -level 3 -g 1 -coder 1 -context 1 -pix_fmt +"
Set "CMD=%CMD% -slices 24 -slicecrc 1 -report -c:a pcm_s24le"
For /R "input_folder" %%G In (*.mov *.mp4) Do (
Echo %%G
%CMD% -y "output_folder\%%~nG.mkv" -i "%%G"
If Not ErrorLevel 1 Del /A /F "%%G"
)

Parallel processing with Pipe command

I'd like to parallel process the command that downloads a live stream.
So if it has 4 parts and the PARTS variable contains the number 4, it should open 4 new cmd windows and process the individual part.
After reading a lot about parallel processing I came to the following solution:
set /p URL=Enter video URL:
set /p NAME=Enter video name:
set /p PARTS=Enter Number of Parts:
for /l %%x in (1, 1, %PARTS%) do (
start cmd /C "C:\Program Files (x86)\Streamlink\bin\streamlink.exe" -O "%URL%/%%x" best | ffmpeg -y -i pipe:0 -c:v copy -c:a copy -absf aac_adtstoasc "%NAME%p%%x.mp4"
)
There seems to be an issue with the | command though since this script would open windows that close right after start and the output of the piped command ffmpeg -y -i pipe:0 -c:v copy -c:a copy -absf aac_adtstoasc "%NAME%p%%x.mp4 would show in the initial cmd window that executed the script.
How can I change it so the whole command gets executed in the new window?
To not let the pipe process the output of the start command, you need to escape it:
start "" cmd /C "C:\Program Files (x86)\Streamlink\bin\streamlink.exe" -O "%URL%/%%x" best ^| ffmpeg -y -i pipe:0 -c:v copy -c:a copy -absf aac_adtstoasc "%NAME%p%%x.mp4"
Since quotation is not modified this way, the used path and all variable parts still appear quoted to the calling cmd instance too, so no more additional escaping is required, unless these strings may contain quotation marks on their own, in which case I strongly recommend delayed expansion:
setlocal EnableDelayedExpansion
rem // some other code...
set /P URL="Enter video URL: "
set /P NAME="Enter video name: "
rem // some other code...
start "" cmd /C "C:\Program Files (x86)\Streamlink\bin\streamlink.exe" -O "!URL!/%%x" best ^| ffmpeg -y -i pipe:0 -c:v copy -c:a copy -absf aac_adtstoasc "!NAME!p%%x.mp4"
rem // some other code...
endlocal
The "" behind the start command should be stated to provide a window title; otherwise an error could occur as the first quoted item was taken as the title rather than as part of the command line.
The above line still could cause problems, since the cmd instance executing the actual commands receives the already expanded values rather than the variable. So you might even need to do this:
rem // Supposing delayed expansion is disabled in the hosting `cmd` instance:
start "" cmd /C /V "C:\Program Files (x86)\Streamlink\bin\streamlink.exe" -O "!URL!/%%x" best ^| ffmpeg -y -i pipe:0 -c:v copy -c:a copy -absf aac_adtstoasc "!NAME!p%%x.mp4"
setlocal EnableDelayedExpansion
rem // Supposing delayed expansion is enabled in the hosting `cmd` instance:
start "" cmd /C /V "C:\Program Files (x86)\Streamlink\bin\streamlink.exe" -O "^!URL^!/%%x" best ^| ffmpeg -y -i pipe:0 -c:v copy -c:a copy -absf aac_adtstoasc "^!NAME^!p%%x.mp4"
endlocal
Note that the pipe | creates two more cmd instances one for either side, implicitly.

Using FFmpeg to convert all images in a folder to mp4 or avi using a .bat file [Windows]

I'm trying to get all .png files in a folder to be converted into a video format in the same directory as the images. Now I can't understand how ffmpeg works, I just want something like this;
for /l %%k in (1,1,%images%) do (
ffmpeg.exe (I need help with the parameters here)
)
This is my very first help request ever and I'm not sure if I supplied enough information for this to be an easy answer. But at least TRYING to help me would be much appreciated. Thank you for reading!
#echo off
set /p framerate=Enter framerate:
for /r %%a in (*.png) do (
echo file '%%a' >> images.txt
)
ffmpeg.exe -r %framerate% -f concat -i images.txt -c:v libx264 -pix_fmt yuv420p video.mp4
del /q images.txt
Put this batch file AND ffmpeg.exe in the directory of all images
Run the batch file and all images in that the current folder will be converted into an mp4
The batch file will automatically close after it has completed

Resources