I've got these sentences of code that I use for video processing, the first one adds a watermark, the second creates a .ts file of the watermarked video and then adds an intro and outro to it but I found that it quickly fills disk space because of the .ts files being used, is there a way to achieve the same results without them? Either by deleting them right after using them or by using a different process altogether.
for %%I in ("C:\Users\Administrator\Desktop\work\*.mp4") do ffmpeg.exe
-y -i "%%I" -i white.png -filter_complex "[0:v]scale=iw:ih[v0];[1:v][v0]scale2ref=iw/6:ih/18[logo][0v];[0v][logo]overlay=W-w-3:H-h-1[v]"
-map "[v]" -map 0:a -codec:v libx264 -preset ultrafast -crf 23 -codec:a copy "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4"
for %%I in ("C:\Users\Administrator\Desktop\Complete-videos\*.mp4") do ffmpeg -y
-i %%I -c copy -vbsf h264_mp4toannexb -f mpegts -s 1280*720 %%I.ts && ffmpeg -y -i "concat:out1.ts|%%I.ts|out1.ts" -c:v libx264 -strict experimental -bsf:a aac_adtstoasc -ar 48000 -r 20 "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4
pause
This does it in one command, with no intermediate files.
for %%I in ("C:\Users\Administrator\Desktop\work\*.mp4") do ffmpeg.exe
-y -i "%%I" -i white.png -i out1.ts -filter_complex "[1:v][0:v]scale2ref=iw/6:ih/18[logo][0v];[0v][logo]overlay=W-w-3:H-h-1,scale=hd720,setsar=1[vl];[2:v][2:a][vl][0:a][2:v][2:a]concat=n=3:v=1:a=1[v][a]"
-map "[v]" -map "[a]" -r 20 -c:v libx264 -ar 48000 "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4"
pause
Notes: Depending on where out1.ts is, you may have to specify its full path during input. In the first command, in your 2nd step, the size option has no effect as you're copying streams. If resize is needed, insert scale=hd720 after the concat filter in my command. Add -strict experimental if your ffmpeg is older than Dec 2015 and you don't want to upgrade.
[totally untried suggestion since I have no idea what the ffmpeg line is doing]
I suggest you try this on a small file subset on a device with a restricted space like a ramdrive or a usb drive. USB drive may take a while. Coffee is good.
for %%I in ("C:\Users\Administrator\Desktop\work\*.mp4") do (
ffmpeg.exe -y -i "%%I" -i white.png -filter_complex "[0:v]scale=iw:ih[v0];[1:v][v0]scale2ref=iw/6:ih/18[logo][0v];[0v][logo]overlay=W-w-3:H-h-1[v]"
-map "[v]" -map 0:a -codec:v libx264 -preset ultrafast -crf 23 -codec:a copy "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4"
for %%Q in ("C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4") do ffmpeg -y
-i %%Q -c copy -vbsf h264_mp4toannexb -f mpegts -s 1280*720 %%Q.ts && ffmpeg -y -i "concat:out1.ts|%%I.ts|out1.ts" -c:v libx264 -strict experimental -bsf:a aac_adtstoasc -ar 48000 -r 20 "C:\Users\Administrator\Desktop\Complete-videos\%%~nQ.mp4
del *.ts
)
pause
This way, the first loop using %%I selects the file to be processed and apparently puts the processed file in another directory then immediately performs the second process on that file, controlled by %%Q using the name in %%~nI to select the single file created by the previous process.
Consequently, instead of processing 10 files each with its own .ts set, one is processed at a time and only one .ts set is created. I don't know whether the second process deletes the .ts files, but I've added a del to get rid of them on each cycle. I've also no idea whether the first process creates the .ts files, but I've made that assumption.
As the educationalists said about "new maths" - it's the idea that's important.
Related
I'm trying to
Using a single batch script to
Download an mp4 video using youtube-dl
Save the video's original title to a batch variable
Convert the video to webm with FFmpeg
I want to keep the original title, so it needs to read the title with youtube-dl, save it to a variable, and use that variable for FFmpeg input/output filename.
CMD Batch
1. Download Video
youtube-dl -f best "https://www.youtube.com/watch?v=TWNhqCHw0qc" -o "C:\Users\Matt\Downloads\%%(title)s.mp4" --merge-output-format mp4
2. Download Video using Loop
This is used to save the title to a variable %%a.
for /f "delims=" %%a in ('youtube-dl -f best "https://www.youtube.com/watch?v=TWNhqCHw0qc" -o #"C:\Users\Matt\Downloads\%%(title)s.mp4" --merge-output-format mp4') do (echo example)
3. Final Script
Download Video, Save Title, Convert with FFmpeg
Sorted
for /f "delims=" %%a in ('
youtube-dl
-f best "https://www.youtube.com/watch?v=TWNhqCHw0qc"
-o #"C:\Users\Matt\Downloads\%%(title)s.mp4"
--merge-output-format mp4
')
do (ffmpeg -y
-i "C:\Users\Matt\Downloads\%%a.mp4"
-c:v libvpx -b:v 1300K -crf 16 -pix_fmt yuv420p
-map 0:v:0? -sn
-c:a libvorbis -q:a 6 -ac 2 -map 0:a:0?
-f webm
"C:\Users\Matt\Downloads\%%a.webm"
)
Inline
for /f "delims=" %%a in ('youtube-dl -f best "https://www.youtube.com/watch?v=TWNhqCHw0qc" -o #"C:\Users\Matt\Downloads\%%(title)s.mp4" --merge-output-format mp4') do (ffmpeg -y -i "C:\Users\Matt\Downloads\%%a.mp4" -c:v libvpx -b:v 1300K -crf 16 -pix_fmt yuv420p -map 0:v:0? -sn -c:a libvorbis -q:a 6 -ac 2 -map 0:a:0? -f webm "C:\Users\Matt\Downloads\%%a.webm")
Error
Before the script can ever reach FFmpeg, youtube-dl fails to download the file. It says the file has already been downloaded, even when there is no file in the directory.
[download] #C#\Users\Matt\Downloads\Color Balloons.mp4 has already
been downloaded
I was able to create a script that works.
One of the problems was that youtube-dl wasn't working properly if located in C:\Program Files\, but works when located somewhere that doesn't require Administrator Privileges.
The --get-filename part requires an # symbol before the youtube-dl path.
youtube-dl gets filename from video and saves to var %%f
youtube-dl downloads the video to C:\Path\To\Downloads\
Merge output as mp4, so you can specify the extension for FFmpeg input
FFmpeg converts video to webm and uses %%f as input/output filename.
for /f "delims=" %%f in ('
#"C:\Users\Matt\Desktop\youtube-dl.exe"
--get-filename -o "%%(title)s"
"https://www.youtube.com/watch?v=TWNhqCHw0qc"
')
do ("C:\Users\Matt\Desktop\youtube-dl.exe"
-f best "https://www.youtube.com/watch?v=TWNhqCHw0qc"
-o "C:\Users\Matt\Downloads\%%f.mp4"
--merge-output-format mp4
&&
ffmpeg -y
-i "C:\Users\Matt\Downloads\%%f.mp4"
-c:v libvpx
-b:v 1300K -crf 16
-pix_fmt yuv420p
-map 0:v:0?
-sn
-c:a libvorbis
-q:a 6
-map 0:a:0?
-f webm
"C:\Users\Matt\Downloads\%%f.webm"
)
I have this batch script running perfectly on Windows:
C:\ffmpeg\bin\ffmpeg -i http://ipaddress/stream -deinterlace -c:v libx264 -pix_fmt yuv420p -s 960x540 -preset superfast -vb 1200k -maxrate 1200k -r 30 -g 60 -bufsize 8000k -c:a aac -b:a 64k -ar 44100 -ac 2 -f flv rtmp://ipaddress/live/
Sometimes ffmpeg crashes, how can I edit the batch script or what can i add to the batch file to restart the stream.
Thanks advance!
I don't know if the ffmpeg command can be restarted this way,
but I would limit the number of retries to avoid endless loops on fails:
#Echo off
Setlocal EnableDelayedExpansion
Set Retry=0
:loop
C:\ffmpeg\bin\ffmpeg.exe -i http://ipaddress/stream ^
-deinterlace -c:v libx264 -pix_fmt yuv420p -s 960x540 -preset superfast ^
-vb 1200k -maxrate 1200k -r 30 -g 60 -bufsize 8000k -c:a aac -b:a 64k ^
-ar 44100 -ac 2 -f flv rtmp://ipaddress/live/ ^
||(Set /A "Retry+=1"&if !Retry! leq 3 Goto :loop)
I'm converting webm to mp4 using FFmpeg.
My batch file is
cd "C:\Users\Matt\Desktop\" && for %f in (*.webm) do ffmpeg -y -i "C:\Users\Matt\Desktop\%~f" -vcodec libx264 -b:v 600K -pass 1 -acodec aac -b:a 128k "C:\Users\Matt\Desktop\%~nf.mp4" && ffmpeg -y -i "C:\Users\Matt\Desktop\" -vcodec libx264 -b:v 600K -pass 2 -acodec aac -b:a 128k "C:\Users\Matt\Desktop\%~nf.mp4"
It works for CRF and 1 Pass, but using 2 Pass it stops on the second pass and gives the error:
C:\Users\Matt\Desktop" -vcodec libx264 -b:v 600K -pass 2 -acodec aac -b:a 128k C:\Users\Matt\Desktop\video: Invalid argument
The first double quote is missing on the Path, and the filename "video 01.mp4" is cut off.
Your code could only work in cmd directly, in a batch you have to double the percent signs of the for variable.
There is no need for a one liner in a batch.
I hope this is more clear and works.
#Echo off
Pushd "C:\Users\Matt\Desktop\"
for %%f in (*.webm) do (
ffmpeg -y -i "%%~f" -vcodec libx264 -b:v 600K -pass 1 -acodec aac -b:a 128k -f mp4 NUL
ffmpeg -y -i "%%~nf_tmp.mp4" -vcodec libx264 -b:v 600K -pass 2 -acodec aac -b:a 128k "%%~nf.mp4"
)
PopD
Pause
Let's say I have 20 different online stream videos (playlist.m3u8) and I want every video to output to their own .avi files. How can I do that in single file, so I don't have to download and convert every single one separately?
I found a -map command online, but didn't get straight answer to this.
Will this be a working code?
ffmpeg -i 1playlist.m3u8 -vf scale=768:-1 -vcodec libx264 -crf 24 -acodec copy -map 0 1.avi \
-i 2playlist.m3u8 -vf scale=768:-1 -vcodec libx264 -crf 24 -acodec copy -map 1 2.avi \
-i 3playlist.m3u8 -vf scale=768:-1 -vcodec libx264 -crf 24 -acodec copy -map 2 3.avi
I'm using the following ffmpeg script to convert all .mp4 files in the folder to .webm.
for %%A IN (*.mp4) DO ffmpeg -i "%%A" -c:v libvpx -crf 4 -b:v 3M -c:a libvorbis "%%A.webm"
I am trying to make it go from "xxx.mp4" to "xxx.webm"
However when I run the script the file name goes from "xxx.mp4" to "xxx.mp4.webm"
Any suggestions are highly appreciated.
Use %%~nA.webm to select the name-part of the filename.
see for /? from the prompt or documentation.
To recursively convert in webm all the mp4 video files in nested folders, you can try this command:
find '~/Video/' -iname '*.mp4' -exec bash -c 'D=$(dirname "{}"); B=$(basename "{}"); mkdir "$D/webm/"; ffmpeg -i "{}" -c:v libvpx -crf 4 -b:v 3M -c:a libvorbis "$D/webm/${B%.*}.webm"' \;
It will create a folder named "webm" inside the one with mp4 video files and, inside the "webm" folder, it will save relative webm files, without keeping the old file extension in the name.