问题
So, I want to create a Powershell or Batch file (whichever works best for the task), that I can paste in a folder and after executing it, will start to use FFmpeg to encode all videos
The part that works (in .bat):
for %%a in ("*.mkv") do(
ffmpeg -i "%%a" -c:v libx265 -c:a copy -x265-params crf=25 "%%a [encoded].mkv"
pause)
This works, but in some folders, I already have [encoded] files. I'd like for the script to skip these files. I asked in reddit and received the following script:
for %%a in ("*.mkv") do (
if not exist "%%a [encoded].mkv" ffmpeg -i "%%a" -c:v libx265 -c:a copy -x265-params crf=25 "%%a [encoded].mkv"
pause)
I tried the script, but every file got encoded, even if it had the [encoded] in it. After I pointed that out, they told me that I should probably switch to PowerShell and gave a link to a StackOverflow question:
You probably need to switch to PowerShell Find files which does not contains selected string Then do a foreach in what is returned to execute the ffmpeg command on it.
but I don't know how to code in PowerShell (never used it before) Would a .bat file even work? If yes, how could I write it? And if a PowerShell script would be the better option, how would I code it?
Any help and answers are appreciated.
回答1:
In PowerShell, you can use the following (you can paste this code as-is into a PowerShell console window):
Get-ChildItem *.mkv | where BaseName -notlike '*`[encoded]' | foreach {
ffmpeg -i $_ -c:v libx265 -c:a copy -x265-params crf=25 "$($_.BaseName) [encoded].mkv"
pause
}
Get-ChildItem *.mkv
uses the Get-ChildItem to get information about all files with extension (.mkv
) in the current directory (you could add-File
to explicitly rule out directories, but directory names with extensions are are).where BaseName -notlike '*`[encoded]'
uses the Where-Object cmdlet (whose built-in alias iswhere
) to weed out files whose base name (the name without the filename extensions) already ends in[encoded]
. Note the`
before the opening[
in order to use it verbatim, because[
has special meaning in PowerShell's wildcard expressions, which the -like / -notlike operator operates on.foreach { ... }
uses the ForEach-Object cmdlet (whose built-in alias isforeach
) to invokeffmpeg
for each file of interest:Inside the script block (
{ ... }
), the automatic $_ variable refers to the pipeline (|
) input object at hand, which in this case is a System.IO.FileInfo instance representing an input file."$($_.BaseName) [encoded].mkv"
uses an expandable string (string interpolation) to derive the output file name via the input file's base name ($_.BaseName
).
回答2:
%%a
already is the full filename (including [encoded]
), so your if
can't work.
I suggest another approach:
for %%a in ("*.mkv") do (
echo %%a|findstr /iel "[encoded].mkv" >nul || ffmpeg -i "%%a" -c:v libx265 -c:a copy -x265-params crf=25 "%%~na [encoded].mkv"
pause
)
(I didn't check if the ffmpeg
syntax is ok - I trust you there)
来源:https://stackoverflow.com/questions/64082434/how-to-create-a-powershell-script-or-windows-bat-file-for-ffmpeg