【发布时间】:2015-08-13 07:41:10
【问题描述】:
我必须使用 VB.NET 运行这个命令行:
"H:\videotest\test.vpy" - -y | "H:\Release\data\bin64\ffmpeg.exe" -hwaccel auto -y -i - -map 0:v:0 -c:v libx265 -crf 20.0 -preset 5 -x265-params level=0:profile= undefined:pmode:no-pme:pme:no-high-tier:ref=3:bframes=4:open-gop:keyint=250:min-keyint=25:b-adapt=2:bframe-bias=0: rc-lookahead=20:no-scenecut:b-pyramid:me=hex:subme=2:merange=57:temporal-mvp:weightp:no-weightb:max-merge=2:no-weightb:no-rect: no-amp:vbv-bufsize=0:vbv-maxrate=0:vbv-init=0.9:no-strict-cbr:qcomp=0.6:qstep=4:aq-mode=1:aq-strength=1.0:cutree:不提前跳过:min-cu-size=8:ctu=64:no-fast-cfb:ipratio=1.4:pbratio=1.3:cbqpoffs=0:crqpoffs=0:rd=3:psy-rd=0.3: psy-rdoq=1:no-b-intra:no-fast-intra:rdoq-level=1:no-tskip:no-tskip-fast:cu-lossless:tu-intra-depth=1:tu-inter- depth=1:strong-intra-smoothing:no-constrained-intra:nr-intra=0:nr-inter=0:qblur=0.5:cplxblur=20:signhide:sar=16 "H:\videotest\outputawdwd.mkv"
vspipe.exe 运行 test.vpy 脚本并对视频输入应用过滤器或调整其大小,然后将输出通过管道传输到 ffmpeg 进行编码。
如果我在 vspipe 中使用正常的 Process 声明,则会出现以下错误:
未知参数:|
从命令行脚本运行良好。我怀疑这意味着我必须在 vspipe 和 ffmpeg 之间手动进行管道传输。
是否可以手动将输出从一个进程传送到另一个进程?我必须手动操作吗?
这是我启动进程的函数:
executablepath = "H:\Project\VapourSynth\core64\vspipe.exe"
params = "H:\videotest\test.vpy" - -y | "H:\Release\data\bin64\ffmpeg.exe" -hwaccel auto -y -i - -map 0:v:0 -c:v libx265 -crf 20.0 -preset 5 -x265-params level=0:profile=undefined:pmode:no-pme:pme:no-high-tier:ref=3:bframes=4:open-gop:keyint=250:min-keyint=25:b-adapt=2:bframe-bias=0:rc-lookahead=20:no-scenecut:b-pyramid:me=hex:subme=2:merange=57:temporal-mvp:weightp:no-weightb:max-merge=2:no-weightb:no-rect:no-amp:vbv-bufsize=0:vbv-maxrate=0:vbv-init=0.9:no-strict-cbr:qcomp=0.6:qstep=4:aq-mode=1:aq-strength=1.0:cutree:no-early-skip:min-cu-size=8:ctu=64:no-fast-cfb:ipratio=1.4:pbratio=1.3:cbqpoffs=0:crqpoffs=0:rd=3:psy-rd=0.3:psy-rdoq=1:no-b-intra:no-fast-intra:rdoq-level=1:no-tskip:no-tskip-fast:cu-lossless:tu-intra-depth=1:tu-inter-depth=1:strong-intra-smoothing:no-constrained-intra:nr-intra=0:nr-inter=0:qblur=0.5:cplxblur=20:signhide:sar=16 "H:\videotest\outputawdwd.mkv"
Private Sub CreateJobProcess(ByVal Name, ByVal executablepath, ByVal params)
Try
If Not jobs_processes.ContainsKey(Name) Then
Dim Proc As New Process
Proc.StartInfo.UseShellExecute = False
Proc.StartInfo.CreateNoWindow = True
Proc.StartInfo.RedirectStandardError = True
Proc.StartInfo.FileName = "" & executablepath & ""
Proc.StartInfo.Arguments = params
'start process
Proc.Start()
'add new process to dictionary
jobs_processes.Add(Name, Proc)
'TEMP
My.Settings.giobbe -= 1
'start background workers for statistics
If Not ConversionStats.IsBusy Then
ConversionStats.WorkerSupportsCancellation = True
ConversionStats.RunWorkerAsync()
End If
If Not UpdateListJob.IsBusy Then
UpdateListJob.WorkerSupportsCancellation = True
UpdateListJob.RunWorkerAsync()
End If
End If
Catch ex As Exception
Me.Invoke(New MethodInvoker(Sub() Logbox.AppendText(Environment.NewLine & ">Program exception:" & Environment.NewLine & ex.Message & Environment.NewLine)))
MsgBox(ex.Message)
End Try
End Sub
更新:
这是我更改的块,该函数获取需要创建的作业的作业名称和参数,然后将过程保存在字典中。
Dim Proc As New Process
Proc.StartInfo.UseShellExecute = False
Proc.StartInfo.CreateNoWindow = True
Proc.StartInfo.RedirectStandardError = True
Proc.StartInfo.FileName = "cmd"
Proc.StartInfo.Arguments = params
'start process
Proc.Start()
'add new process to dictionary
jobs_processes.Add(Name, Proc)
'TEMP
My.Settings.giobbe -= 1
'start background workers for statistics
If Not ConversionStats.IsBusy Then
ConversionStats.WorkerSupportsCancellation = True
ConversionStats.RunWorkerAsync()
End If
If Not UpdateListJob.IsBusy Then
UpdateListJob.WorkerSupportsCancellation = True
UpdateListJob.RunWorkerAsync()
End If
然后我有一个后台工作程序( ConversionStats ),它从字典中的每个进程获取 stderr 并将它们打印到文本框中:
'take current selected process and set streamreader
Dim tmpproc As Process = jobs_processes(CurrentJob)
Dim ffmpeg_stats As StreamReader
Dim stdoutput As String = ""
'something that verify if the job is started
If statejob = 1 Then 'if job is working
'take stderr from ffmpeg
ffmpeg_stats = tmpproc.StandardError
stdoutput = ffmpeg_stats.ReadLine()
If stdoutput IsNot Nothing Then 'if ffmpeg stderr is not nothing
'IF FFMPEG IS RETURNING STATS
If stdoutput.Contains("frame=") Or stdoutput.Contains("size=") Then
所以这是我的代码... 但现在 cmd 使用流读取器获取标准错误导致获取字符串“无效句柄”。这是 cmd stderr 的错误还是流读取器有问题?
更新 2
我什至尝试启动一个干净的 cmd 进程,只声明参数,但结果只是带有主要信息的控制台。
Microsoft Windows [版本 6.3.9600] (c) 2013 年微软公司。 Tutti i diritti risrvati。
H:\Project\bin\Release>
这是要澄清的代码:
Dim Proc As New Process
Proc.StartInfo.FileName = "cmd"
Proc.StartInfo.Arguments = params
'start process
Proc.Start()
那么再次有人可以指导我如何将标准输出从一个进程 (vspipe.exe) 管道/重定向到另一个进程的标准输入 (ffmpeg.exe)?
【问题讨论】:
-
请将您用于执行该行的代码添加到您的问题中。
-
在命令窗口中输入它意味着操作系统正在处理参数,并且它知道如何管道。如果使用 shell 或 Process.Start 将其中的大部分作为 arg 传递给 vspipe,它可能不会知道
|是什么,这就是消息所说的。那么你如何“运行:从 VB 运行? -
ok 添加了我的 VB.Net 块。我使用简单的流程启动,所以我的问题是我该怎么做“|”在 VB.NET 中?
-
让操作系统来做。
StartInfo.FileName = "cmd"然后将executablepath添加到params,这样它看起来就像您在命令窗口中输入它的方式;StartInfo.Arguments = params然后启动进程 -
我想维护来自 ffmpeg 的 stderr,因为我需要为用户输出转换统计信息...有办法手动管道吗?
标签: vb.net ffmpeg pipeline video-encoding