Page 1 of 1

ffmpeg and stdout

Posted: Fri Dec 01, 2017 8:54 am
by Rjevsky
Hello everybody! I want to receive data on the ffmpeg coding process. It is known that the output of data occurs stderr.
But i getting big problem!

Code: Select all

  Procedure RoutineCoding(str$)   
    Protected prog, Output.s
   prog = RunProgram("ffmpeg.exe",str$ , "", #PB_Program_Open | #PB_Program_Error )
   While ProgramRunning(prog)
     Debug"err: "+ ReadProgramError(prog, #PB_Ascii)
    Wend
  EndProcedure  
  RoutineCoding(" -i 1.avi -c:v libx265 -an -x265-params crf=25 -y OUT.mov")
If the stops end in CRLF, everything works fine and I get the data. But if the line ends with CR then the data is not output immediately and I need to wait for CRLF to get this data. And this is the most important data for me! how can I get the selected data right away?


Image

Re: ffmpeg and stdout

Posted: Mon Dec 04, 2017 7:25 am
by Rjevsky
Hi! I was looking for a solution to my problem and realized that this is a bug. But I did not lose hope and found an option in ffmpeg -progress which can transfer the data I need to post requests or write to a text file. I wrote two working examples and can not decide which method is preferable.

Code: Select all

Procedure Server(param)
  InitNetwork()
  CreateNetworkServer(10, 1111)
  Protected Buffersize = 16
  Protected SEvent,Result,ClientID,msg$
  Protected *Buffer = AllocateMemory(Buffersize)
  Protected d.i = 0
  Debug "Started server"
  Repeat
    SEvent = NetworkServerEvent()
    Delay(100)
    Select SEvent
      Case #PB_NetworkEvent_Connect
        Debug "A new client has connected! " + Str(EventClient())
      Case #PB_NetworkEvent_Data
        Repeat
          ClientID = EventClient()
          Result = ReceiveNetworkData(ClientID, *Buffer, Buffersize)       
          If Result           
            msg$ = msg$+PeekS(*Buffer, Result,#PB_Ascii)        
          Else
            Debug "Just did a non-blocking read of 0 bytes."
          EndIf
        Until Result <> Buffersize  
        Debug "client: " + msg$ + " from " + Str(ClientID)
        msg$ =""        
      Case #PB_NetworkEvent_Disconnect
        Debug Str(EventClient()) + " disconnected."
    EndSelect
  ForEver
EndProcedure


Procedure RoutineCoding(str$) 
  Protected prog, Output.s, out.s
OpenFile(0, "1.txt",#PB_File_SharedWrite)
prog = RunProgram("ffmpeg.exe",str$ + " -progress http://127.0.0.1:1111/", "",  #PB_Program_Open | #PB_Program_Wait)
Delay(200)
  EndProcedure  
CreateThread (@Server(),1)
RoutineCoding("-i 1.m2v -c:v libx265 -an -x265-params crf=20 -y OUT.mov")

Code: Select all

Procedure RoutineCoding(str$) 
  Protected prog, Output.s, out.s
OpenFile(0, "1.txt",#PB_File_SharedWrite)
   prog = RunProgram("ffmpeg.exe",str$ + " -progress 1.txt", "",  #PB_Program_Open )
   While ProgramRunning(prog)
     Output = ReadString(0)
       If Output
       Debug Output
       If Left(Output,9)="progress=":FileSeek(0,0):TruncateFile(0):EndIf
       EndIf
  Wend
  CloseFile(0)
  EndProcedure  

RoutineCoding("-i 1.avi -c:v libx265 -an -x265-params crf=25 -y OUT.mov")

Re: ffmpeg and stdout

Posted: Mon Dec 04, 2017 11:36 am
by Bitblazer
Tbh. i still dont see why you think the output is a bug/mistake. If you consider the meaning and implementation of CR vs. CR + LF in computers, ffmpeg outputs the text correctly.
See CR the section about computers.

Basically CR = "move cursor to left" while CR+LF means "move to left and feed up the paper by one line" (old mechanical typewriter behaviour). Might be weird nowadays, but this is old stuff dating back to mechanical typewriters.

The "typewriter" association isnt perfect because a CR here implies to also blank the line to the right margin. In a mechanical typewriter overwriting the same line would create a mess ;) Anyway - i dont see any bug here for ffmpeg, they just implemented the control codes pretty literally. Just implement a line buffer and trigger for CR to find the next line. Then check if you got a LF char as first char and treat those two cases (yes LF exists/no LF char). Basic ASCII control codes are quite old.

Re: ffmpeg and stdout

Posted: Mon Dec 04, 2017 11:45 am
by Rjevsky
Purebasic dont return string in #PB_Program_Error until it is received #crlf
FFMPEG returned #crlf already at the end of the encoding, so I can not monitor the encoding process (see the picture)
here's a description of a similar problem

Re: ffmpeg and stdout

Posted: Mon Dec 04, 2017 4:14 pm
by kenmo
Yes, I wish we had more control over a Program's Error output, like we do its standard output:

ReadProgramString -> ReadProgramError
AvailableProgramOutput -> ???
ReadProgramData -> ???

Re: ffmpeg and stdout

Posted: Mon Dec 04, 2017 5:50 pm
by Rjevsky
Ffmpeg dont use standart output, only stderr

Re: ffmpeg and stdout

Posted: Mon Dec 04, 2017 11:26 pm
by Bitblazer
For further explanation - ffmpeg can be used as a classic *nix commandline tool with piping and to achieve that old classic usage it takes STDIN for input and writes output data to STDOUT. So they basically use STDERR even for standard info like verbose audio info about the input data.
  • write a wrapper around ffmpeg which changes this behaviour and call the wrapper
    add the same STDERR functions to PB like STDOUT has - as requested in a previous posting from kenmo in this thread
    use the network server functions of ffpmpeg instead
But its really more of a feature/wishlist topic and not a bug imho

Re: ffmpeg and stdout

Posted: Tue Dec 05, 2017 8:09 am
by Rjevsky
Im windows user and i make stdread program on AutoIt for ffmpeg. Autoit work great and I did not have any problems!

Re: ffmpeg and stdout

Posted: Tue Dec 05, 2017 1:42 pm
by oreopa
Nothing to add here, but I ran into this same "problem" with ffmpeg a while back. Glad to know it wasn't only me :)