Показать полную графическую версию : Запуск FFprobe на Powershell
Uragan66
18-11-2019, 13:30
Добрый день всем!
Пытаюсь посредством FFProbe получить информацию о потоках iptv от провайдера.
Хочу это сделать скриптом PS, но запуская таким кодом:
$soft = 'ffprobe.exe'
Get-Content .\log\Test-streams.ini `
| ForEach {Start-Process -FilePath $soft -ArgumentList "-hide_banner -show_streams -timeout 500000 $_ -report" -NoNewWindow -Wait}
получаю n-е количество логов, а не один, как хотелось бы.
Хотя это исправляется легко путём объединения логов. Вопрос в другом, при запуске ffprobe с ключом -report не воспринимаются кириллические символы в ответе сервера. В итоге в логах, где есть русские названия, получаются кракозябры.
Дальнейшая смена кодировки ничего не даёт.
Подскажите, пожалуйста, есть ли способ запуска ffprobe на PS, чтобы нормальный лог/логи были на выходе ?
P.S. И попутный, пока нерешенный вопрос: есть ли способ запуска ffprobe на PS или CMD в многопоточном или лучше асинхронном режиме ?
DJ Mogarych
18-11-2019, 22:07
Хотя это исправляется легко путём объединения логов »
Можно get-content .\log\ffprobe-*.log
кириллические символы в ответе сервера »
Может быть, поможет экспорт в какой-нибудь другой формат, типа xml, там вроде UTF8 по умолчанию. Примеры в статье:
https://www.bugcodemaster.com/article/use-ffprobe-obtain-information-video-files
Uragan66
18-11-2019, 22:33
DJ Mogarych, спасибо, посмотрю по ссылке. Пока решилось всё "костылём" с CMD.
Можно get-content .\log\ffprobe-*.log »
да, так и объединяю...
*****************
Сейчас больше интересует вопрос многопоточного или ассинхронного запуска FFprobe. Возможно ли это на ps или cmd ?
А то слишком долго FFprobe работает, к примеру, с 225 ссылками.
DJ Mogarych
19-11-2019, 09:07
Как вариант - поделить 225 ссылок на части и запускать ffprobe для каждой части отдельно.
Uragan66
20-11-2019, 19:31
Как вариант - поделить 225 ссылок на части »
DJ Mogarych, думал я так сделать, но не могу понять как несколько потоков ffprobe запустить одним кодом.
Пробовал так:
Get-Content .\log\Test-streams.ini `
| ForEach {Start-Job -ScriptBlock {
& ffprobe.exe -timeout 6000000 -hide_banner -select_streams v:1 -print_format json=compact=1 -show_entries format=filename -show_programs -show_entries program=service_name -of default=noprint_wrappers=1:nokey=0 $_ >>out.json
}}
Вывода никакого нет, да и ffprobe вроде вообще не запускается.
Знаю, что результаты фоновых заданий Start-Job можно получить командлетом Receive-Job, но как правильно код составить и, главное, заставить ffprobe работать, пока не могу сообразить.
DJ Mogarych
20-11-2019, 22:16
Можно сделать 4 задачи в стандартном планировщике задач.
Uragan66
08-12-2019, 12:48
Добрый день всем!
Цитата DJ Mogarych:
Можно сделать 4 задачи в стандартном планировщике задач. »
DJ Mogarych, ну это немного не то, не каждый умеет использовать планировщик, а скрипт планируется для нескольких пользователей, да и не совсем удобно это...
Нашел интересный скрипт многопоточного запуска пинга - https://xaegr.wordpress.com/2011/07/12/threadping/
Попробовал его переделать под свою задачу:
Param (
[string[]]$unc = 'http://109.248.67.1:4044',
[string[]]$prt = ':1234',
[string[]]$Address = $(1..20 | %{"$unc/udp/239.195.1.$_$prt"}),
[int]$Threads = 3
)
write-host "Distributing addresses around jobs"
$JobAddresses = @{}
$CurJob = 0
$CurAddress = 0
while ($CurAddress -lt $Address.count)
{
$JobAddresses[$CurJob] += @($Address[$CurAddress])
$CurAddress++
if ($CurJob -eq $Threads -1)
{
$CurJob = 0
}
else
{
$CurJob++
}
}
$Jobs = @()
foreach ($n in 0 .. ($Threads-1))
{
Write-host "Starting job $n, for addresses $($JobAddresses[$n])"
$Jobs += Start-Job -ArgumentList "ffprobe.exe -timeout 6000000 -hide_banner -select_streams v:1 -print_format json=compact=1 -show_entries format=filename -show_programs -show_entries program=service_name -of default=noprint_wrappers=1:nokey=0 $JobAddresses[$n] >>out.json" -ScriptBlock {
cmd /c
}
}
write-host "Waiting for jobs"
$ReceivedJobs = 0
while ($ReceivedJobs -le $Jobs.Count)
{
foreach ($CompletedJob in ($Jobs | where {$_.State -eq "Completed"}))
{
Receive-Job $CompletedJob | select status, address, roundtriptime
$ReceivedJobs ++
sleep 1
}
}
Remove-Job $Jobs
write-host "Done."Но последний блок кода (вывод) никак не получается... Да и ffprobe не знаю как точно запустить с помощью Start-Job
Может кто сможет помочь с этим скриптом, буду очень благодарен.
DJ Mogarych
09-12-2019, 09:14
Истина где-то здесь: https://www.google.com/search?q=ffmpeg+several+instances+simultaneously
Uragan66
09-12-2019, 23:57
DJ Mogarych, спасибо большое, просмотрел несколько ссылок, но так и не смог что-либо применить к своему коду.
Но решение всё же найдено. На social.technet.microsoft.com предложили такой код (за что большая благодарность Vector BCO ) :
$i = 0
foreach ($OL in @(1..255)){ # 1 foreach вместо 2х и тем более 3х
Start-Job -Name ffprobe -ArgumentList $OL -ScriptBlock {
$OL = $args[0]
$URI = "http://79.105.135.20:5055/udp/239.28.0.$OL`:2020
$soft = 'C:\full\path\to your program\ffprobe.exe' # Полный путь, или можно пробовать играться с переменной $Path. Для начала я бы не заморачивался со вторым
$utf8 = [System.Text.Encoding]::GetEncoding(65001)
cmd /c $utf8.GetString($utf8.GetBytes("$soft -timeout 6000000 -hide_banner -select_streams v:1 -print_format json=compact=1 -show_entries format=filename -show_programs -show_entries program=service_name -of default=noprint_wrappers=1:nokey=0 $URI >> C:\temp\out_$OL.json")) # И снова полный путь
}
# Если запустить 255 потоков, то производительность сильно просядет (скорее всего)
# По этому мое предложение запускать по 5 задач, ждать их выполнения, после чего запускать следующие 5 задач. При желании можете увеличить до 10 или 15
if (($i -ge 5) -or ($OL -eq 255){
Get-Job ffprobe | Wait-Job -Timeout 300
Get-Job ffprobe | Receive-Job
Get-Job ffprobe | Remove-Job -Force
$i = 0
} else {$i++}
}Пришлось немного повозиться с жесткой привязкой путей, но всё получилось, как было нужно.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.