В powershell есть ли способ передачи данных по каналу, пока командлет еще работает? - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь заставить инструмент youtube-dl написать индикатор выполнения при загрузке видео. Кажется, что проблема, которую я имею, вызвана тем, что данные, которые я передаю, не передаются до тех пор, пока загрузчик не завершит работу. Есть ли способ заставить данные отправлять через канал по новой строке?

Чтобы воссоздать:

Я написал функцию для фильтрации вывода youtube-dl так строки прогресса загрузки будут отправляться на индикатор выполнения, а остальные передаются на выход. Индикатор выполнения отображается в конце только на мгновение, и ни один из следующих шагов, которые должны выполняться, не выполняется.

Function Write-ProgressBar
{
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]$InputString,
        [Parameter(Mandatory=$true)][string]$Type
    )

    $regex = "\[download\] *(\d{0,3}[.]{0,1}\d{0,3})% of ([0-9.\/BGKMTbikst]+)* at *([0-9.\/BGKMTbikst]+)* *ETA (\d*:\d*).*?" 
    $IsDownloadProgress = $InputString -match $regex

    if ($IsDownloadProgress)
    {
        $Size = $Matches[2]
        $Speed = $Matches[3]
        $ETA = $Matches[4]
        $PercentComplete = $Matches[1]

        $SecondsLeft = $(([int]$ETA.split(':')[0]*60)+[int]$ETA.split(':')[1])

        Write-Progress -Activity "Downloading $Type" -Status "Downloading $Size file at $Speed" -SecondsRemaining $SecondsLeft -PercentComplete $PercentComplete
    } else {
        Write-Output $InputString
    }
}

youtube-dl.exe -o "C:\users\public\videos\%(title)s.%(ext)s" https://www.youtube.com/watch?v=dQw4w9WgXcQ -f bestaudio -i -x | Write-ProgressBar -Type "Audio"

Write-ProgressBar создает ожидаемый индикатор выполнения при использовании внутри al oop:

for ($i = 0; $i -le 100; $i++) {
    "[download]  $i% of 58.26MiB at  1.04MiB/s ETA 00:$(100-$i)" | Write-ProgressBar -Type "test"
    Start-Sleep -Milliseconds 50
}

Но когда выход из того же l oop отправляется в канал из функции, индикатор выполнения появляется только на мгновение, когда функция возвращает:

Function test-pipe
{
    for ($i = 0; $i -le 100; $i++) {
        Write-Output "[download]  $i% of 58.26MiB at  1.04MiB/s ETA 00:$(100-$i)"
        Start-Sleep -Milliseconds 50
    }
}

test-pipe | Write-ProgressBar -Type "test"
...