Strange problem with FFMPEG's stdout

Windows specific forum
criobot
User
User
Posts: 10
Joined: Sat Dec 27, 2008 9:42 pm
Location: Bulgaria
Contact:

Strange problem with FFMPEG's stdout

Post by criobot »

I'm not sure if the problem is with PB's Process library or within FFMPEG itself. I am using the latest FFMPEG build. And it behaves very strange even with these simple parameters from the code below. It returns only exit code 1 and no output, but if I change the parameters to "-h", it behaves normally and outputs all the help with exit code 0. ReadProgramString does not read any program output, nor does ReadProgramData. My goal is to keep track on the conversion process through the console output, but no success so far... :(

Code: Select all

asdf = RunProgram("ffmpeg.exe", "-i test.mp4", "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Hide|#PB_Program_Error)
If IsProgram(asdf)
  While ProgramRunning(asdf)
    If AvailableProgramOutput(asdf)
      Debug ReadProgramString(asdf)
    EndIf
  Wend
  Debug ProgramExitCode(asdf)
  CloseProgram(asdf)
EndIf
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Strange problem with FFMPEG's stdout

Post by ricardo »

This coide (that i found somewhere) works with FFMPEG

Code: Select all

ProcedureDLL.s GetProgramResult(Command.s) 
  
  proc.PROCESS_INFORMATION ;Process info filled by CreateProcessA 
  ret.l ;long variable For get the Return value of the 
  start.MySTARTUPINFO ;StartUp Info passed To the CreateProceeeA 
  sa.SECURITY_ATTRIBUTES ;Security Attributes passeed To the 
  hReadPipe.l ;Read Pipe handle created by CreatePipe 
  hWritePipe.l ;Write Pite handle created by CreatePipe 
  lngBytesread.l ;Amount of byte Read from the Read Pipe handle 
  strBuff.s=Space(256) ;String buffer reading the Pipe 
  
  ;Consts For functions 
  #NORMAL_PRIORITY_CLASS = $20 
  #STARTF_USESTDHANDLES = $100 
  #STARTF_USESHOWWINDOW = $1 
  
  ;Create the Pipe 
  sa\nLength =SizeOf(SECURITY_ATTRIBUTES) ;Len(sa) 
  sa\bInheritHandle = 1 
  sa\lpSecurityDescriptor = 0 
  ret = CreatePipe_(@hReadPipe, @hWritePipe, @sa, 0) 
  If ret = 0 
    ;If an error occur during the Pipe creation exit 
    MessageRequester("info", "CreatePipe failed. Error: ",0) 
    End 
  EndIf 
  
  
  start\cb = SizeOf(MySTARTUPINFO) 
  start\dwFlags = #STARTF_USESHOWWINDOW | #STARTF_USESTDHANDLES 
  
  ;set the StdOutput And the StdError output To the same Write Pipe handle 
  start\hStdOutput = hWritePipe 
  start\hStdError = hWritePipe 
  
  ;Execute the command 
  ret = CreateProcess_(0, Command, sa, sa, 1, #NORMAL_PRIORITY_CLASS, 0, 0, @start, @proc) 
  
  If ret <> 1 
    retour.s="" 
  Else 
    
    ;Now We can ... must close the hWritePipe 
    ret = CloseHandle_(hWritePipe) 
    
    mOutputs.s = "" 
    
    ;Read the ReadPipe handle 
    While ret<>0 
      ret = ReadFile_(hReadPipe, strBuff, 255, @lngBytesread, 0) 
      If lngBytesread>0 
        mLine$ = Left(strBuff, lngBytesread)
        ;Debug mLine$
        ParseaData(mLine$)
        mOutputs = mOutputs + mLine$ 
      EndIf 
    Wend 
    
    ;Close the opened handles 
    ret = CloseHandle_(proc\hProcess) 
    ret = CloseHandle_(proc\hThread) 
    ret = CloseHandle_(hReadPipe) 
    ;ret=CloseHandle_(hWritePipe) 
    
    retour.s=mOutputs 
    
  EndIf 
  
  ProcedureReturn mOutputs ;ConformationAsciiEtenduVersAscii(mOutputs) 
EndProcedure 

bCommandLine$ = "FFmpeg -y -i abc.mp3 abc.flac"
  Datos$ = GetProgramResult(bCommandLine$)

ARGENTINA WORLD CHAMPION
DarkPlayer
Enthusiast
Enthusiast
Posts: 107
Joined: Thu May 06, 2010 11:36 pm

Re: Strange problem with FFMPEG's stdout

Post by DarkPlayer »

I think your problem is that FFMPEG can't find your input file.
Depeding on your compiler settings, the working directory might be C:\Program Files\Purebasic, if you start your program within the IDE. Just try an absolut path for the input file.
The reason why you can't see an error in the program output is that critical errors are written to STDERR and you are just collecting the output from STDOUT. You also have to use ReadProgramError() to collect all output messages from FFMPEG.
NY152
User
User
Posts: 29
Joined: Sun May 14, 2006 12:33 am

Re: Strange problem with FFMPEG's stdout

Post by NY152 »

i have a little question:

ParseaData is not function ! Where is this function ?
.:NY152:.
Bitblazer
Enthusiast
Enthusiast
Posts: 761
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Strange problem with FFMPEG's stdout

Post by Bitblazer »

read this
NY152
User
User
Posts: 29
Joined: Sun May 14, 2006 12:33 am

Re: Strange problem with FFMPEG's stdout

Post by NY152 »

Thank you but this code does not work with the little test I made

I tested with a simple command

With the program and parameter : C:\Windows\System32\where.exe notepad

The program must return the notepad path, this is not the case, the output is empty.
.:NY152:.
Bitblazer
Enthusiast
Enthusiast
Posts: 761
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Strange problem with FFMPEG's stdout

Post by Bitblazer »

Just read what i linked to. ffmpeg is using STDOUT and STDERR in a non-standard way due to the way how ffmpeg is often used as a piping tool in *nix environments (for example 'cat inputfile.bin | ffmpeg -parameters >newvideo.mpg'). So they decided to use STDOUT for the output video stream and use STDERR for regular "STDOUT" output to achieve this kind of common usage in the *nix world work. That's why using other Programs to test your PB use with FFMPEG is a bit pointless. The code from ricardo assigns STDIN and STDERR into one pipe to work, i personally wouldn't do that as it makes it impossible to distinguish between STDIN and STDERR.
NY152
User
User
Posts: 29
Joined: Sun May 14, 2006 12:33 am

Re: Strange problem with FFMPEG's stdout

Post by NY152 »

Whether in STDOUT or STDERR, I do not have the result, it's empty ...
.:NY152:.
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Strange problem with FFMPEG's stdout

Post by ricardo »

For the records, add this to your FFMPEG command: -progress pipe:2

and you will be able to read as stdout.
ARGENTINA WORLD CHAMPION
User avatar
jacdelad
Addict
Addict
Posts: 1991
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Strange problem with FFMPEG's stdout

Post by jacdelad »

Six years later...

...why not. I just had the same problem and simply gave up (my program waits until ffmpeg is done). Thanks ricardo, I'll try.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Strange problem with FFMPEG's stdout

Post by ricardo »

In fact in FFMPEG tou can use also this at the end of the command to redirect both outputs (st and err) to the same output


-f null NUL 2>&1

Like in:

FFMPEG -i input.mp3 -f null NUL 2>&1
ARGENTINA WORLD CHAMPION
User avatar
Piero
Addict
Addict
Posts: 863
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Strange problem with FFMPEG's stdout

Post by Piero »

No logged infos on stdout (warnings/errors still on stderr):

Code: Select all

ffmpeg -v 24 -i in.mp4 out.mp3
Log only progress every 1.5 seconds, also overwriting output file without "interactive" asking:

Code: Select all

ffmpeg -v 24 -stats_period 1.5 -progress pipe:1 -i in.mp4 -y out.mp3
Set to non-interactive mode (-nostdin) and use stdout only for warnings/errors:

Code: Select all

ffmpeg -nostdin -v 24 -i in.mp4 out.mp3 2>&1
Log file info (just ignore the "no output file" error):

Code: Select all

ffmpeg -hide_banner -i file.mp4 2>&1
User avatar
Piero
Addict
Addict
Posts: 863
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Time duration with ffmpeg

Post by Piero »

To get duration without error messages:

Code: Select all

ffmpeg -nostdin -hide_banner -nostats -i file.mp4 -f null -c copy - 2>&1
Edit/Note: ffmpeg 7 "Duration: " seems to be reliable enough for a simple completion % check using the "-progress" output
User avatar
Piero
Addict
Addict
Posts: 863
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

ffmpeg monitor

Post by Piero »

Code: Select all

; ffmpeg monitor "early prototype"

EnableExplicit
Define dur$,pro$,md,mp 

Enumeration
   #Duration
   #Out_time
   #Speed
   #ProgressBarFF = 0
   ;#ProgressBarFiles
EndEnumeration

Macro regexp(a,b)
   CreateRegularExpression(a,b,
      #PB_RegularExpression_MultiLine|#PB_RegularExpression_AnyNewLine)
EndMacro

regexp(#Duration, "^\s*Duration: \K[^.]+")
regexp(#Out_time, "^out_time=\K[^.]+")
regexp(#Speed, "^speed=\s*\K[^x]+") ; has space after "="!?

Procedure.s reg(r,s.s)
   Dim Result$(0)
   ExtractRegularExpression(r,s,Result$())
   ProcedureReturn Result$(0)
EndProcedure

; ProgressBarGadget(#ProgressBarFF, x, y, Width, Height, 0, 1); initialize

; Simulated file info log (stdout) from:
; ffmpeg -nostdin -hide_banner -nostats -i in.mp4 -f null -c copy - 2>&1
dur$=~"...\n  Duration: 01:00:00.96, start: 0.000000, bitrate: 415 kb\n..."

md=ParseDate("%hh:%ii:%ss",reg(#Duration,dur$)) ; media time duration
; SetGadgetAttribute(#ProgressBarFF, #PB_ProgressBar_Maximum, md); set max

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PROGRESS PROCESSING:

; Simulated progress log (stdout) from (-y = overwrite):
; ffmpeg -v 24 -nostdin -stats_period 1.0 -progress pipe:1 -i in.mp4 -y out.mp3
pro$=~"...\nout_time=00:20:00.912086\n...\nspeed= 10x\nprogress=Continue"

mp=ParseDate("%hh:%ii:%ss",reg(#Out_time,pro$)) ; media time processed

; Remaining time:
Debug "ETA: " + FormatDate("%hh:%ii:%ss",((md-mp)/Val(reg(#Speed,pro$)))); 0?
; Percent completed:
Debug "" + Int(Round(1/(md/mp)*100,#PB_Round_Down)) + "%"
; Update ProgressBar:
; SetGadgetState (#ProgressBarFF,mp)
tj1010
Enthusiast
Enthusiast
Posts: 716
Joined: Mon Feb 25, 2013 5:51 pm

Re: Strange problem with FFMPEG's stdout

Post by tj1010 »

I ran in to the stderr problem a while back. I do a lot of transcoding and upscaling work with libx264 and mkv and acc(no hwaccel for best quality). I never thought to just read it back through named pipes..

FYI

Code: Select all

-vf scale=3840x2560:flags=lanczos
is the absolute best 16:9 4k upscale; better than Topaz AI filters even

Code: Select all

-c:a aac -b:a 128k -ac 2
for auto stereo channel transcode; aac supported by most blueray players. It will auto-separate 7.1 and 5.1 to stereo using dolby and dts metadata

Code: Select all

-map 0:a?
all audio from source

Code: Select all

-map 0:s?
all subs from source

Code: Select all

-vf nlmeans="1.0:7:5:3:3"
most optimal denoise

Code: Select all

-protocol_whitelist https,tls,tcp,file
m3u8/HLS/every-video-stream-on-the-internet as source to single out-file

Code: Select all

-listen 1 -i <> -c:v libx264 -crf 21 -preset veryfast -c:a aac -b:a 128k -ac 2 -f hls -hls_time 4 -hls_playlist_type event stream.m3u8
FFMPEG also has a built in HLS server via RTMP. HLS is basically what every in-browser video and audio stream on the net is using; including YouTube, Netflix, Hulu, and Amazon. It also supports RTSP and about thirty other protocols. HTML5>Video tag supports m3u8

If you care about quality never use a hwaccel even with the slowest encode and CBR, and .mkv you can embed all sub in the video file and it works on any player that supports .mkv, which is most.. I don't think ffmpeg has audio normalization(removing loudness difference between audio tracks).

If you do want to use -hwaccel auto

Code: Select all

-c:v h264_amf -usage quality -cq 18
AMD(works through directX API on Windows)

Code: Select all

-c:v x264_nvenc -preset p7 -cq 18
Nvidia

Code: Select all

-c:v x264_qsv -preset veryslow -global_quality 18 
Intel
Post Reply