How to read stdout in ffmpeg

Questions involving a Windows version of FFmpeg.
Post Reply
damorsoft
Posts: 4
Joined: Sat Feb 09, 2013 4:22 am

How to read stdout in ffmpeg

Post by damorsoft » Mon Feb 11, 2013 12:57 am

I am writing a GUI to run ffmpeg under windows.
How do I read the STDOUT of ffmpeg the code below works ffmpeg does its thing but show no progress thru standarderrror

Public Function FFdeMUX(ByVal MyApp As String, ByVal MyTail As String) As Integer
Dim myProcess As New Process()
myProcess.StartInfo.WorkingDirectory = Application.StartupPath
myProcess.StartInfo.FileName = MyApp
myProcess.StartInfo.Arguments = MyTail
myProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.CreateNoWindow = True
' myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.StartInfo.RedirectStandardInput = True
'myProcess.BeginErrorReadLine()
'myProcess.BeginOutputReadLine()
Try
myProcess.Start()
myProcess.PriorityClass = ProcessPriorityClass.Idle
While (myProcess.HasExited = False)
Dim S As String = myProcess.StandardError.ReadLine
If (Not String.IsNullOrEmpty(S)) Then
TextBox2.Text = S.ToString
End If
End While
ProcEC = myProcess.ExitCode
Catch ex As Exception
MsgBox(" Error(s) with RunFIinfo " & ex.Message)
ProcEC = 99
End Try
myProcess.Close()
Return ProcEC
End Function

rogerdpack
Posts: 1877
Joined: Fri Aug 05, 2011 9:56 pm

Re: How to read stdout in ffmpeg

Post by rogerdpack » Mon Feb 11, 2013 5:29 pm

I'm not sure what happens when you redirect stdout *and* stderr:

myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.StartInfo.RedirectStandardInput = True

where does it get redirected? Anyway this looks like the right track...

ramiro
Posts: 157
Joined: Tue May 10, 2011 12:56 am

Re: How to read stdout in ffmpeg

Post by ramiro » Mon Feb 11, 2013 6:34 pm

ffmpeg uses stderr to output any message (except when -h is used)
stdout is used as output for pipe

damorsoft
Posts: 4
Joined: Sat Feb 09, 2013 4:22 am

Re: How to read stdout in ffmpeg

Post by damorsoft » Tue Feb 19, 2013 5:32 pm

Well it turns out that you need the line..

Application.DoEvents()

Works fine now.. Would that be a blonde moment...

tolsen64
Posts: 3
Joined: Wed Feb 27, 2013 3:06 pm

Re: How to read stdout in ffmpeg

Post by tolsen64 » Wed Feb 27, 2013 3:31 pm

This is how I did it. I wrote a class that runs in a separate thread and raises events whenever a new line is output. My main window handles the event, which contains the line text and an ID number so I can differentiate between multiple instances of the class.

Code: Select all

Public Class ffmpeg

    Public Event StatusMsg(ByVal ID As Integer, ByVal StatusMsg As String)
    Public Event Started(ByVal ID As Integer)
    Public Event Finished(ByVal ID As Integer)

    Private _SourceFileName As String = ""
    Private _Passes As Integer = 1
    Private _VolAdj As String = ""
    Private _va As String = ""
    Private _VideoQuality As String = ""
    Private _OutputFolder As String = ""
    Private _ID As Integer = 0
    Private _ffmpeg As String = ""

    Public Sub New(ByVal ID As Integer, ByVal SourceFileName As String, ByVal Passes As Integer, ByVal VideoQuality As String, ByVal VolAdj As String, ByVal OutputFolder As String)
        _ID = ID
        _SourceFileName = SourceFileName
        _Passes = Passes
        _VolAdj = VolAdj
        _va = VolAdj
        _VideoQuality = VideoQuality
        _OutputFolder = OutputFolder
        If IntPtr.Size = 8 Then
            _ffmpeg = My.Application.Info.DirectoryPath & "\Externals\ffmpeg64.exe"
        Else
            _ffmpeg = My.Application.Info.DirectoryPath & "\Externals\ffmpeg32.exe"
        End If

        Threading.ThreadPool.QueueUserWorkItem(AddressOf Start)
    End Sub

    Private Sub Start()
        Dim fi As New IO.FileInfo(_SourceFileName)
        If fi.Extension.ToLower = ".vob" Then _SourceFileName = GetVOBString(fi)
        _VolAdj = CType(256 + (256 * (CType(_VolAdj, Integer) / 100)), String)
        If _OutputFolder = "" Then _OutputFolder = fi.DirectoryName
        Dim tmpMsg As String = ""
        For i = 1 To _Passes
            Using x As New Process
                With x.StartInfo
                    .CreateNoWindow = True
                    .UseShellExecute = False
                    .RedirectStandardError = True
                    .FileName = _ffmpeg
                    If _Passes = 1 Then
                        RaiseEvent StatusMsg(_ID, "Status=1 Pass")
                        .Arguments = " -i """ & _SourceFileName & """ -vcodec libxvid -qscale " & _VideoQuality & " -r 23.976 -g 240 -bf 2 -acodec libmp3lame -vol " & _VolAdj & " -ab 128k -ar 44100 -async 44100 -ac 2 -f avi -y """ & _OutputFolder & "\" & fi.Name.Replace(fi.Extension, "_p1va" & _va & "vq" & _VideoQuality & ".avi") & """"
                    Else
                        If i = 1 Then
                            RaiseEvent StatusMsg(_ID, "Status=Pass 1")
                            .Arguments = " -i """ & _SourceFileName & """ -vcodec libxvid -qscale " & _VideoQuality & " -r 23.976 -g 240 -bf 2 -acodec libmp3lame -vol " & _VolAdj & " -ab 128k -ar 44100 -async 44100 -ac 2 -pass 1 -an -f rawvideo -y NUL"
                        Else
                            RaiseEvent StatusMsg(_ID, "Status=Pass 2")
                            .Arguments = " -i """ & _SourceFileName & """ -vcodec libxvid -qscale " & _VideoQuality & " -r 23.976 -g 240 -bf 2 -acodec libmp3lame -vol " & _VolAdj & " -ab 128k -ar 44100 -async 44100 -ac 2 -pass 2 -f avi -y """ & _OutputFolder & "\" & fi.Name.Replace(fi.Extension, "_p2va" & _va & "vq" & _VideoQuality & ".avi") & """"
                        End If
                    End If
                    'Using sw As New IO.StreamWriter(My.Application.Info.DirectoryPath & "\ffmpegCmdLine.txt", True)
                    '    sw.WriteLine(.Arguments)
                    '    sw.Close()
                    'End Using
                End With
                x.Start()
                'RaiseEvent Started(_ID)
                'Using sw As New IO.StreamWriter(My.Application.Info.DirectoryPath & "\ffmpegStdErrorOutput.txt", True)
                Do Until x.StandardError.EndOfStream Or x.StandardError.Peek = 0
                    tmpMsg = x.StandardError.ReadLine
                    'Debug.WriteLine(tmpMsg)
                    'sw.WriteLine(tmpMsg)
                    RaiseEvent StatusMsg(_ID, tmpMsg)
                Loop
                'sw.Close()
                'End Using
                x.StandardError.Close()
                x.WaitForExit()
            End Using
        Next
        RaiseEvent Finished(_ID)
    End Sub

    Private Function GetVOBString(ByVal fi As IO.FileInfo) As String
        Dim tmpVobString As String = "concat:"
        Dim di As IO.DirectoryInfo = fi.Directory
        For Each f As IO.FileInfo In di.GetFiles(fi.Name.Substring(0, 7) & "*.vob", IO.SearchOption.TopDirectoryOnly)
            If Not f.Name.ToLower.EndsWith("_0.vob") Then tmpVobString &= f.FullName & "|"
        Next
        Return tmpVobString.TrimEnd("|")
    End Function

End Class

Post Reply
'