用于按顺序获取音频曲目列表时间戳的 Powershell 脚本



我是Powershell的菜鸟。我试图制作一个带有时间戳的音轨列表。
我需要的代码是读取包含mp3位置的文本文件的代码,程序将获取时间戳,例如:
考虑一个文件.txt带有以下文本:

C:\文件夹\歌曲1.mp3
C:\文件夹\歌曲1.mp3
C:\文件夹\歌曲1.mp3

程序应按时间戳打印以下内容.txt 如:
00:00:00 - 00:02:30 - 歌曲 1.mp3 00:02:30 - 00:04:32 - 歌曲 2.mp3 00:04:32 - 00:07:30 - 歌曲 3.mp3


我尝试了以下代码

$path = 'C:SanalGambitmp3'
Get-ChildItem $path -Filter *.mp3 -name | Foreach-Object {
$shell = New-Object -COMObject Shell.Application
$shellfolder = $shell.Namespace($path)
$shellfile = $shellfolder.ParseName($_)
write-host  $shellfolder.GetDetailsOf($shellfile, 27) $_;
}

它只是给出了每个mp3文件的结束时间,而无需按顺序添加它们。 有人可以帮我创建一个满足我需求的程序吗?

你离:)很近

$path = 'C:SanalGambitmp3'
Get-ChildItem $path -Filter *.mp3 -name | Foreach-Object `
-Begin {
[timespan]$startTime = [timespan]::Zero
[timespan]$fullTime = [timespan]::Zero
$shell = New-Object -COMObject Shell.Application
$shellfolder = $shell.Namespace($path)
} `
-Process {
$shellfile = $shellfolder.ParseName($_)
$startTime = $fullTime
$fullTime += $shellfolder.GetDetailsOf($shellfile, 27)
"$startTime - $fullTime - $_"
}

Begin块中声明$shell$shellfolder更加优化,因为它们不是在每个文件上定义的(这是无用的)。

除非您明确希望在控制台上显示它,否则应避免Write-Host因为它会占用管道,因此如果要将结果存储在文件中,则文件将为空。 有了"$startTime - $fullTime - $_"如果没有管道,它将输出,如果有管道,则传递给管道。

您可以在Process| Out-File myResult.txt块的右大括号 (}) 之后添加以将其存储在文件中,或者| Tee-Object myResult.txt如果您希望同时显示和保存它。

编辑:

如果要从仅包含文件夹的列表中获取它:

Get-Content list.txt |
ForEach {
$path = $_
Get-ChildItem -LiteralPath $path -Filter *.mp3 -Name | Foreach-Object `
-Begin {
[timespan]$startTime = [timespan]::Zero
[timespan]$fullTime = [timespan]::Zero
$shell = New-Object -COMObject Shell.Application
$shellfolder = $shell.Namespace($path)
} `
-Process {
$shellfile = $shellfolder.ParseName($_)
$startTime = $fullTime
$duration = $shellfolder.GetDetailsOf($shellfile, 27)
$fullTime += $duration
#"$startTime - $fullTime - $path$_"
[PSCustomObject]@{
Path=$path;
FileName=$_;
Duration=$duration;
StartTime=$startTime;
EndTime=$fullTime
}
}
}

正如@iRon所建议的,我已经"$startTime - $fullTime - $path$_"注释并返回了一个PSCustomObject,如果您更喜欢第一种方法,可以将其删除(在这种情况下,不要忘记注释掉上一行)

为每个文件夹重置时间戳,如果您希望有一个整体时间戳,请移动行

[timespan]$startTime = [timespan]::Zero
[timespan]$fullTime = [timespan]::Zero

并将它们放在脚本的开头(Get-Content ...以上),就像在第二次编辑中一样。

第二次编辑:

如果您想从包含文件夹和文件的列表中获取它:

[timespan]$startTime = [timespan]::Zero
[timespan]$fullTime = [timespan]::Zero
Get-Content list.txt |
ForEach {
$path = $_
$file = ""
if ($_ -match ".mp3$")
{
$path = $_.SubString(0, $_.LastIndexOf(''))
$file = $_.SubString($_.LastIndexOf('') + 1)
}
Get-ChildItem -LiteralPath "$path$file" -Filter *.mp3 -Name | Foreach-Object `
-Begin {
$shell = New-Object -COMObject Shell.Application
$shellfolder = $shell.Namespace($path)
} `
-Process {
$shellfile = $shellfolder.ParseName($_)
$startTime = $fullTime
$duration = $shellfolder.GetDetailsOf($shellfile, 27)
$fullTime += $duration
#"$startTime - $fullTime - $path$_"
[PSCustomObject]@{
Path=$path;
FileName=$_;
Duration=$duration;
StartTime=$startTime;
EndTime=$fullTime
}
}
}

在这种情况下,似乎只有整体时间戳是合适的。

与其使用Write-Host(将结果输出到显示器,通常应避免),不如在管道中放置一个字符串(或[pscustomobject]),这可以很容易地排序:

Get-ChildItem $path -Filter *.mp3 -name | Foreach-Object {
...
"$($shellfolder.GetDetailsOf($shellfile, 27)) $_"
} | Sort-Object

最新更新