如何使用Powershell和其他转码/ ffmpeg批处理一系列视频文件



TL;博士

我在以下PowerShell脚本中做错了什么?它无法按预期工作。


我正在用照相机记录我在大学里的一些讲座。这很好用,尽管我必须将单个讲座分成三到四个部分,因为相机一次只能录制 29 分钟的视频。我知道这是一个与某些许可问题相关的常见问题,大多数相机根本没有正确的许可证来录制更长的视频。但它让我面临的问题是,在对文件进行一些后期处理后,我必须一起编辑文件。

使用相机,我最多可以生成四个大小约为 3.5 GB 的视频文件,这对于任何用途来说都是很大的,因为我们的 IT 部门不想托管这么多数据,因为我每周制作大约 22 GB 的视频材料,这是可以理解的。

前段时间,我在GitHub上遇到了Don Melton的一个非常有用的工具,称为"其他视频转码",用ruby编写,它允许我将文件压缩到合理的文件大小而不会造成任何视觉损失。此外,我裁剪视频以删除每帧中既不是黑板也不是我的教授站立的地方的部分,以便进一步减小文件大小,并通过剪掉大多数学生来保护隐私。

由于这些工具可以通过命令行访问,因此配置相对容易,并且不会花费额外的计算能力来渲染一个漂亮的 GUI,因此我可以在不到 10 分钟的时间内编辑其中一个 29 分钟的剪辑。

现在,我想通过编写一个 PowerShell 脚本来优化我的工作流程,该脚本仅获取要裁剪的内容和要处理的文件的参数,然后自行完成其余工作,这样我就可以启动脚本,然后在笔记本电脑呈现新文件时执行其他操作。

到目前为止,我有以下内容:

$video_path = Get-ChildItem .. -Directory | findstr "SoSe"
Get-ChildItem $video_path -name | findstr ".MP4" | Out-File temp.txt -Append 
Get-Content temp.txt | ForEach-Object {"file " + $_} >> .files.txt
Get-ChildItem $video_path |
Foreach-Object {
other-transcode --hevc --mp4 --target 3000 --crop 1920:780:0:0 $_.FullName
}
#other-transcode --hevc --mp4 --crop 1920:720:60:0 ..SoSe22_Theo1_videos_v14_RAW
ffmpeg -f concat -i files.txt -c copy merged.mp4
Remove-Item .temp.txt

但它并没有完全做到我期望做的事情。 这是我的文件系统:

sciebo/
└── SoSe22_Theo1_videos/
├── SoSe22_Theo1_videos_v16/
│   ├── SoSe22_Theo1_videos_v16_KOMPR/
│   │   ├── C0001.mp4
│   │   ├── C0002.mp4
│   │   ├── C0003.mp4
│   │   ├── C0004.mp4
│   │   ├── temp.txt
│   │   ├── files.txt
│   │   └── merged.mp4
│   └── SoSe22_Theo1_videos_v16_RAW/
│       ├── C0001.mp4
│       ├── C0002.mp4
│       ├── C0003.mp4
│       └── C0004.mp4
└── SoSe22_Theo1_videos_v17/
├── SoSe22_Theo1_videos_v17_KOMPR
└── SoSe22_Theo1_videos_v17_RAW/
├── C0006.mp4
├── C0007.mp4
├── C0008.mp4
└── C0009.mp4

其中第 16 讲已经处理,而第 17 讲尚未处理。我总是在以RAW结尾的文件夹中保存原始视频数据,在以KOMPR结尾的文件夹中保存编辑/压缩的输出文件。请注意,KOMPR文件夹中的视频文件是other-transcode工具的输出文件。

真正的工作发生在它所说的那一行

other-transcode --hevc --mp4 --target 3000 --crop 1920:780:0:0 $_.FullName

并在行中

ffmpeg -f concat -i files.txt -c copy merged.mp4

我将输出文件连接到最终版本中,我可以上传到我们的在线学习平台。 我的脚本有什么问题?最后,我想将--crop参数传递给我的脚本,但这不是主要问题。


有关转码脚本的一些信息,因此您不必查看文档:
作为最后一个参数,该工具采用要处理的视频文件的位置,无论是相对还是绝对文件路径。输出放置在调用脚本的文件夹中,因此如果我 cd 到其中一个KOMPR目录,然后调用

other-transcode --mp4 ../SoSe22_Theo1_videos_v16_RAW/C0001.mp4

将在KOMPR目录中创建一个新文件C0001.mp4,转码后的视频和旧音频将写入该新视频文件。

我会使用 Get-ChildItem 首先获取"SoSe*_RAW"文件夹并遍历这些.
在每次迭代中,检查它旁边是否有一个"SoSe*_KOMPR"文件夹,以及它是否已经有一个"合并.mp4文件".
如果是这种情况,则跳过处理该文件夹并继续下一个文件夹。

尝试

$allVideos = Get-ChildItem -Path 'X:sciebo' -Filter 'SoSe*_RAW' -Directory -Recurse | ForEach-Object {
$mergedPath = $_.FullName -replace '_[a-z]+$', '_KOMPR'
$mergedFile = Join-Path -Path $mergedPath -ChildPath 'merged.mp4'
if (Test-Path -Path $mergedFile -PathType Leaf) {
# already processed
continue  # skip this and proceed with the next folder
}
# convert each file in the folder
$mp4Files = Get-ChildItem -Path $_.FullName -Filter '*.mp4' -File | Sort-Object {[int]$_.BaseName.Substring(1)}
if (@($mp4Files).Count) {
# make sure there is a 'SoSe*_KOMPR' folder
if (!(Test-Path -Path $mergedPath -PathType Container)) {
$null = New-Item -Path $mergedPath -ItemType Directory
}
# convert the videos into the 'SoSe*_KOMPR'
$transcoded = [System.Collections.Generic.List[string]]::new()
foreach ($video in $mp4Files) {
# copy the file to the 'SoSe*_KOMPR' first and transcode there
$copy = $video | Copy-Item -Destination $mergedPath -PassThru
other-transcode --hevc --mp4 --target 3000 --crop 1920:780:0:0 $copy.FullName
# add a string for the files.txt
$transcoded.Add(('file {0}' -f $copy.FullName))
}
# create a files.txt file with all converted filenames in it
$fileList = Join-Path -Path $mergedPath -ChildPath 'files.txt'
$transcoded | Set-Content -Path $fileList
# then combine all the videos into merged.mp4
ffmpeg -f concat -i $fileList -c copy $mergedFile
}
}

最新更新