[FFMPEG] Wie bekomme ich die Programm Ausgabe?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

[FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von Mijikai »

Ich würde gerne die Programm Aisgabe von FFMPEG einlesen.
Leider funktioniert es noch nicht :coderselixir:
Wo liegt das Problem?

Code: Alles auswählen

;PB v.5.62 x64 (Windows 7)

EnableExplicit

Procedure.i FFMPEG(Video.s,Audio.s,File.s)
  Protected Handle.i
  Protected Parameter.s
  If Video And Audio And File
    Parameter + "-i " + #DQUOTE$ + Video + #DQUOTE$
    Parameter + " -i " + #DQUOTE$ + Audio + #DQUOTE$
    Parameter + " -vcodec h264 "
    Parameter + #DQUOTE$ + File + #DQUOTE$
    Debug Parameter
    Handle = RunProgram("ffmpeg.exe",Parameter,#Null$,#PB_Program_Open|#PB_Program_Read|#PB_Program_Error)
    If Handle
      Debug Handle
      While ProgramRunning(Handle)
        If AvailableProgramOutput(Handle)
          Debug ReadProgramError(Handle,#PB_Program_Ascii)
          Debug ReadProgramString(Handle,#PB_Program_Ascii)
          Debug ReadProgramError(Handle,#PB_Program_Unicode)
          Debug ReadProgramString(Handle,#PB_Program_Unicode)
          Debug ReadProgramError(Handle,#PB_Program_UTF8)
          Debug ReadProgramString(Handle,#PB_Program_UTF8)
          Debug "LOOP"
        EndIf
      Wend  
      Debug "EXIT"
      Debug ProgramExitCode(Handle)
      CloseProgram(Handle)
    EndIf 
  EndIf
EndProcedure

FFMPEG("test.webm","test.weba","test.mp4")

End
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von NicTheQuick »

Gute Frage. Ich bekomme es auch nicht hin. ffmpeg scheint aber alles nach stderr zu schreiben. Dummerweise reagiert AvailableProgramOutput() nur auf stdout. Das ist wohl wieder mal ein Fall für eine nicht ganz durchdachte Purebasic-Bibliothek. /:->
Bild
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von Mijikai »

Bleibt wohl nur der Weg über WinApi oder den Output mit TCP abzufangen... :|
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von #NULL »

Ich bekomme unter Linux die Error-Ausgabe wenn außerhalb von AvailableProgramOutput(). Vielleicht meinte NicTheQuick das aber auch.

Code: Alles auswählen

      While ProgramRunning(Handle)
        Define err.s = ReadProgramError(Handle)
        If err
          Debug "ERR: " + err
        EndIf
        If AvailableProgramOutput(Handle)
            [...]
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von Kiffi »

NicTheQuick hat geschrieben:Gute Frage. Ich bekomme es auch nicht hin. ffmpeg scheint aber alles nach stderr zu schreiben. Dummerweise reagiert AvailableProgramOutput() nur auf stdout. Das ist wohl wieder mal ein Fall für eine nicht ganz durchdachte Purebasic-Bibliothek. /:->
dann einfach AvailableProgramOutput() entfernen und die zurückgegebenen Strings nur dann beachten, wenn sie nicht leer sind.

Code: Alles auswählen

;PB v.5.62 x64 (Windows 7)

EnableExplicit

Procedure.i FFMPEG(Video.s,Audio.s,File.s)
  Protected Handle.i
  Protected Parameter.s
  Protected RPE.s ; ReadProgramError
  Protected RPS.s ; ReadProgramString
  If Video And Audio And File
    Parameter + "-i " + #DQUOTE$ + Video + #DQUOTE$
    Parameter + " -i " + #DQUOTE$ + Audio + #DQUOTE$
    Parameter + " -vcodec h264 "
    Parameter + #DQUOTE$ + File + #DQUOTE$
    Debug Parameter
    Handle = RunProgram("ffmpeg.exe",Parameter,#Null$,#PB_Program_Open|#PB_Program_Read|#PB_Program_Error)
    If Handle
      Debug Handle
      While ProgramRunning(Handle)
        
        RPE = ReadProgramError(Handle)
        If RPE
          Debug "RPE: " + RPE
        EndIf
        
        RPS = ReadProgramString(Handle)
        If RPS
          Debug "RPS: " + RPS
        EndIf
        
      Wend  
      Debug "EXIT"
      Debug ProgramExitCode(Handle)
      CloseProgram(Handle)
    EndIf 
  EndIf
EndProcedure

FFMPEG("test.webm","test.weba","test.mp4")

End

Grüße ... Peter

Edit:
#NULL hat geschrieben:Ich bekomme unter Linux die Error-Ausgabe wenn außerhalb von AvailableProgramOutput().
oha, das habe ich jetzt nicht testen können.
Hygge
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von ccode_new »

Oh Kiffi du wars schneller. :mrgreen:

funktionierendes Beispiel (getestet unter Linux):

Code: Alles auswählen

EnableExplicit

Global param.s = "-i"

Global prog.i

Global retstr.s

prog = RunProgram("ffmpeg",param,"",#PB_Program_Open| #PB_Program_Error)

If prog
  Debug "ok"
  While ProgramRunning(prog)
    retstr = ReadProgramError(prog)
    If retstr <> ""
      Debug retstr
    EndIf  
  Wend 
EndIf

Debug "Exitcode " + ProgramExitCode(prog)

KillProgram(prog)

CloseProgram(prog)  
"ffmpeg" schreibt auf beiden Kanälen (stdout,stderr)

Code: Alles auswählen

EnableExplicit

Global param.s = "-h"

Global prog.i

Global retstr.s

prog = RunProgram("ffmpeg",param,"",#PB_Program_Open| #PB_Program_Read)

If prog
  Debug "ok"
  While ProgramRunning(prog)
    retstr = ReadProgramString(prog)
    If retstr <> ""
      Debug retstr
    EndIf  
  Wend 
EndIf

Debug "Exitcode " + ProgramExitCode(prog)

KillProgram(prog)

CloseProgram(prog)  
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von Mijikai »

Kiffi hat geschrieben: dann einfach AvailableProgramOutput() entfernen und die zurückgegebenen Strings nur dann beachten, wenn sie nicht leer sind.

Code: Alles auswählen

;PB v.5.62 x64 (Windows 7)

EnableExplicit

Procedure.i FFMPEG(Video.s,Audio.s,File.s)
  Protected Handle.i
  Protected Parameter.s
  Protected RPE.s ; ReadProgramError
  Protected RPS.s ; ReadProgramString
  If Video And Audio And File
    Parameter + "-i " + #DQUOTE$ + Video + #DQUOTE$
    Parameter + " -i " + #DQUOTE$ + Audio + #DQUOTE$
    Parameter + " -vcodec h264 "
    Parameter + #DQUOTE$ + File + #DQUOTE$
    Debug Parameter
    Handle = RunProgram("ffmpeg.exe",Parameter,#Null$,#PB_Program_Open|#PB_Program_Read|#PB_Program_Error)
    If Handle
      Debug Handle
      While ProgramRunning(Handle)
        
        RPE = ReadProgramError(Handle)
        If RPE
          Debug "RPE: " + RPE
        EndIf
        
        RPS = ReadProgramString(Handle)
        If RPS
          Debug "RPS: " + RPS
        EndIf
        
      Wend  
      Debug "EXIT"
      Debug ProgramExitCode(Handle)
      CloseProgram(Handle)
    EndIf 
  EndIf
EndProcedure

FFMPEG("test.webm","test.weba","test.mp4")

End
Bin auch auf Win7 x64 aber der Code tut leider auch nicht...
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von #NULL »

Was sagen denn die ersten beiden Ifs?
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von Mijikai »

Danke für die Vielen Beiträge :allright:
#NULL hat geschrieben:Was sagen denn die ersten beiden Ifs?
Was ist lf?

___________________________________________________________________

Hab jetzt mal ein Modul dafür geschrieben das zumindest mal grundlegend funktioniert.
Bin für jeden Verbesserungsvorschlag dankbar. :)

-> Vorallem bei ExitCode() ob das so richtig ist ?
(GetExitProcess oder GetExitThread?)

Code:

Code: Alles auswählen

DeclareModule PROCESS
  Declare.i Create(File.s,Parameter.s) 
  Declare.i Running(*Process)
  Declare.i DataAvailable(*Process)
  Declare.s DataRead(*Process)
  Declare.s File(*Process)
  Declare.s Parameter(*Process)
  Declare.i ExitCode(*Process)
  Declare.i Close(*Process)
EndDeclareModule

Module PROCESS
  
  EnableExplicit
  
  ;Module PROCESS
  ;By Mijikai
  ;Version: draft
  ;PB v.5.62 x64 (Win7)
  
  Structure PROCESS_STRUCT
    Exe.s
    Parameter.s
    PipeRead.i
    PipeWrite.i
    Security.SECURITY_ATTRIBUTES
    Startup.STARTUPINFO
    Info.PROCESS_INFORMATION
    BytesAvailable.i
  EndStructure
  
  Procedure.i Create(File.s,Parameter.s)
    Protected *Process.PROCESS_STRUCT
    *Process = AllocateStructure(PROCESS_STRUCT)
    If *Process  
      With *Process
        \Security\bInheritHandle = #True
        If CreatePipe_(@\PipeRead,@\PipeWrite,@\Security,#Null)
          \Startup\cb = SizeOf(STARTUPINFO)
          \Startup\dwFlags = #STARTF_USESTDHANDLES
          \Startup\hStdInput = \PipeRead
          \Startup\hStdOutput = \PipeWrite
          \Startup\hStdError = \PipeWrite
          If CreateProcess_(File,Parameter,@\Security,@\Security,#True,#Null,#Null,#Null,@\Startup,@\Info)
            ProcedureReturn *Process          
          EndIf
          CloseHandle_(\PipeRead)
          CloseHandle_(\PipeWrite)
        EndIf
      EndWith
      FreeStructure(*Process)
    EndIf 
  EndProcedure
  
  Procedure.i Running(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn Bool(WaitForSingleObject_(\Info\hProcess,10) <> #WAIT_TIMEOUT)
    EndWith  
  EndProcedure
  
  Procedure.i DataAvailable(*Process.PROCESS_STRUCT)
    With *Process
      PeekNamedPipe_(\PipeRead,#Null,#Null,#Null,@\BytesAvailable,#Null)
      ProcedureReturn \BytesAvailable 
    EndWith
  EndProcedure
  
  Procedure.s DataRead(*Process.PROCESS_STRUCT)
    Protected *Buffer
    Protected BufferSize.i
    Protected Result.s
    With *Process
      If \BytesAvailable > #Null
        *Buffer = AllocateMemory(\BytesAvailable)
        If *Buffer
          If ReadFile_(\PipeRead,*Buffer,\BytesAvailable,@BufferSize,#Null)
            If BufferSize
              Result = PeekS(*Buffer,BufferSize,#PB_Ascii)
            EndIf
          EndIf 
          FreeMemory(*Buffer)
        EndIf 
      EndIf
    EndWith
    ProcedureReturn Result
  EndProcedure
  
  Procedure.s File(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn \Exe
    EndWith
  EndProcedure
  
  Procedure.s Parameter(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn \Parameter  
    EndWith
  EndProcedure
  
  Procedure.i ExitCode(*Process.PROCESS_STRUCT)
    Protected Code.i
    With *Process
      GetExitCodeThread_(\Info\hThread,@Code)
      ProcedureReturn Code
    EndWith
  EndProcedure
  
  Procedure.i Close(*Process.PROCESS_STRUCT)
    With *Process
      CloseHandle_(\Info\hProcess)
      CloseHandle_(\Info\hThread)
      CloseHandle_(\PipeRead)
      CloseHandle_(\PipeWrite)
    EndWith
    FreeStructure(*Process)
  EndProcedure
    
EndModule

EnableExplicit

Global Handle.i

Procedure.s FFMPEG(Video.s,Audio.s,File.s)
  Video = " -i " + #DQUOTE$ + Video + #DQUOTE$
  Video + " -i " + #DQUOTE$ + Audio + #DQUOTE$
  Video + " -vcodec h264 " + #DQUOTE$ + File + #DQUOTE$
  ProcedureReturn Video
EndProcedure

DeleteFile("test.mp4")

Handle = PROCESS::Create("ffmpeg.exe",FFMPEG("test.webm","test.weba","test.mp4"))
If Handle
  Repeat
    If PROCESS::DataAvailable(Handle)
      Debug PROCESS::DataRead(Handle)
    EndIf 
  Until PROCESS::Running(Handle)
  Debug PROCESS::ExitCode(Handle);<- immer Null !?
  PROCESS::Close(Handle)
EndIf 

Repeat:Delay(100):ForEver
End
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: [FFMPEG] Wie bekomme ich die Programm Ausgabe?

Beitrag von #NULL »

Mijikai hat geschrieben:
#NULL hat geschrieben:Was sagen denn die ersten beiden Ifs?
Was ist lf?
Na die Ifs die nur ein EndIf haben aber kein Else mit Rückmeldung. Ich frage das nur weil ich zuerst rein gar keine Ausgabe hatte da es ffmpeg.exe bei mir unter Linux ja als solche nicht gibt :) und wollte wissen ob er überhaupt im jeweiligen If-Zweig ankommt.
my pb stuff..
Bild..jedenfalls war das mal so.
Antworten