3

作为一名优秀的 Windows 系统管理员,我终于开始学习 PowerShell。话虽如此,我不知道我在做什么(惊喜,惊喜)。

我认为在远离生产环境的家里玩 PowerShell 对我来说是一次很好的学习体验。最近,我开始使用 FFMPEG 将我所有的 .mkv 文件转换为 .mp4,这样我就可以通过 Plex 为我的 PlayStation 3 提供更好的播放支持,并认为这将是一次很好的学习体验。

我一直在运行的命令如下:

ffmpeg -i OldVideoName.mkv -vcodec copy -acodec ac3 OldVideoName.mp4

我想要的是有一个运行一次的 PowerShell 脚本,扫描文件夹和所有子文件夹中的 .mkv 文件(Get-ChildItem ".*.mkv"),通过上述命令将它们转码为 .mp4,然后放置它们与具有相同命名方案的 .mkv 位于同一位置。

以 D:\Videos 作为目标目录运行脚本的示例:

D:\Videos\home_dvr\movies\video1.mkv --> D:\Videos\home_dvr\video1.mp4 D:\Videos\home_dvr\tv\video2.mkv --> D:\Videos\home_dvr\tv\video2 .mp4

你可以猜到,我这辈子都想不通。这是放弃前的最新尝试。

    $oldvid = Get-ChildItem .\*.mkv -Recurse
    $newvid = $oldvid.Name.split(‘.’)[0]; ForEach-Object {
            .\ffmpeg.exe -i $oldvid -y -vcodec copy -acodec ac3 $newvid".mp4”
    }

任何帮助,将不胜感激!

4

2 回答 2

10

尝试这个:

$oldvids = Get-ChildItem *.mkv -Recurse
foreach ($oldvid in $oldvids) {
    $newvid = [io.path]::ChangeExtension($oldvid.FullName, '.mp4')
    .\ffmpeg.exe -i $oldvid.FullName -y -vcodec copy -acodec ac3 $newvid
}

$oldvid 是一个 .NET FileInfo 对象,当它需要转换为字符串时,它可以只是文件名而不是整个路径。这不适用于不在当前目录中的文件。所以只需使用该FullName属性来获取完整路径。

于 2013-08-20T05:28:58.703 回答
5

似乎在当前版本的 powershell 中,行为发生了一些变化。Keith Hill 建议的答案不再起作用,它需要.FullName删除才能与 PS 5.1(内部版本 14393)一起使用。所以目前的答案是:

$oldvids = Get-ChildItem -Filter "*.mkv" -Recurse
foreach ($oldvid in $oldvids) {
    $newvid = [io.path]::ChangeExtension($oldvid, '.mp4')
    .\ffmpeg.exe -i $oldvid-y -map 0 -c:v copy -c:a ac3 $newvid
}

-c:v -c:a现在也优先于-vcodecand -acodec。如果您想保留所有曲目,而不仅仅是一个音频和一个视频曲目,-map 0则需要该标志。

于 2017-03-30T08:02:11.140 回答