VideoHelp Forum
+ Reply to Thread
Results 1 to 12 of 12
Thread
  1. The following code runs OK from a Windows command prompt:

    Code:
    ffprobe -select_streams v -i output.mpg -show_entries "frame=pkt_pts_time,pkt_duration_time,interlaced_frame" -pretty -print_format json -of json > output.mpg.json
    but I don't know Python or ffprobe well enough to get this Python script to work:

    Code:
    import os, sys, subprocess, shlex, re
    from subprocess import call
    
    def probe_file(filename):
    
        cmnd = ['ffprobe.exe','-select_streams v', '-i output.mpg',' -show_entries, "frame=pkt_pts_time','pkt_duration_time','interlaced_frame'",'-pretty',' -print_format json',-of json > output.mpg.json]
    
        p = subprocess.Popen(cmnd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
        out, err =  p.communicate()
    #    print ("==========output==========")
    
    #    print (out)
    
        if err:
            print ("========= error ========")
            print (err)
    
    probe_file('test_pattern_709.mp4')
    Any help is appreciated.

    Thank you.
    Quote Quote  
  2. I am PLEABS
    Join Date
    Apr 2018
    Location
    Earth
    Search Comp PM
    Its pretty long time since i use FFMPEG stuff with python so forgive me if i make some mistake
    but pretty sure that cmnd var can be written directly by using single quotes to wrap the whole command
    Code:
    cmnd = 'ffprobe -select_streams v -i output.mpg -show_entries "frame=pkt_pts_time,pkt_duration_time,interlaced_frame" -pretty -print_format json -of json > output.mpg.json'
    Quote Quote  
  3. I'll give that a try, thanks.
    Last edited by chris319; 25th Jun 2019 at 15:13.
    Quote Quote  
  4. I got it to run without error but I'm not seeing the output I expect. It's not printing the format like it does when run as a batch file.

    Code:
    #!/usr/bin/python
    import os, sys, subprocess, shlex, re
    from subprocess import call
    
    cmnd = ''
    err = 0
    
    def probe_file(filename):
    
      cmnd = 'ffprobe -select_streams v -i output.mpg -show_entries "frame=pkt_pts_time,pkt_duration_time,interlaced_frame" -pretty -print_format json -of json > output.mpg.json'
    
    
      p = subprocess.Popen(cmnd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      #print (filename)
      
    #  out, err =  p.communicate()
      out =  p.communicate()
    
      print ("==========output==========")
    
      print (out)
    
    if err:
            print ("========= error ========")
            print (err)
    
    probe_file('test_pattern_709.mp4')
    Quote Quote  
  5. I ried this and it worked, for windows:
    Code:
    import subprocess
    import os
    
    def probe_file(ffprobe, filename):
        cmnd = [ffprobe , '-i', filename, '-show_entries' ,  'frame=pkt_pts_time,pkt_duration_time,interlaced_frame']  #'-print_format',  'json',  '-of',  'json'
        basename = os.path.basename(filename)
        with open(f'{basename}.txt', 'w') as log:
            p = subprocess.Popen(cmnd, stdout=log, stderr=subprocess.PIPE) #, shell = True #to not show pop up cmd window
            print(filename)
            out, err =  p.communicate()
            if out:  #if you redirect output to text file , there is no output here, out is None
                print("==========output==========")
                print(out.decode('utf-8'))
            if err:
                print("========= error ========")
                print(err.decode('utf-8'))
            
    ffprobe = r'C:\path_to_ffprobe\ffprobe.exe'  #not having ffprobe in PATH
    input = r'C:\path_to_file\videofile.mp4'
    
    probe_file(ffprobe, input)
    for linux:
    Code:
    import subprocess
    import os
    
    def probe_file(filename):
        cmnd = ['ffprobe' ,  '-show_entries' ,  'frame=pkt_pts_time,pkt_duration_time,interlaced_frame',  filename]  #'-print_format',  'json',  '-of',  'json'
        basename = os.path.basename(filename)
        with open(f'{basename}.txt', 'w') as log:
            p = subprocess.Popen(cmnd, stdout=log, stderr=subprocess.PIPE) 
            print(filename)
            out, err =  p.communicate()
            if err:
                print("========= error ========")
                print(err.decode('utf-8'))
    
    input = /home/path_to_file/videofile.mp4'
    probe_file(input)
    linux has input file at the end

    you can also pass a directory for storing logs, so you can redirect it to other disk etc.
    Last edited by _Al_; 26th Jun 2019 at 23:59.
    Quote Quote  
  6. I am PLEABS
    Join Date
    Apr 2018
    Location
    Earth
    Search Comp PM
    Code:
    import os
    import subprocess
    from pathlib import Path
    
    ffprobe = Path(r"\ffprobe.exe")
    
    
    def probe_file(_file):
        print("\non progress please wait...")
        cmnd = '"{0}" -hide_banner -select_streams v -i {1} -show_entries "frame=pkt_pts_time,pkt_duration_time,interlaced_frame" -pretty -print_format json -of json'.format(ffprobe, _file)
    
        a = subprocess.run(cmnd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
        b = a.returncode
    
        if b == 0:
            print("=========output=========")
            c = open(Path(r"\output.mpg.json"), "w")
            c.write(a.stdout)
        else:
            print("\n=========error!=========")
            print(a.stderr)
    
    
    print("Enter your File path...")
    probe_file(Path(input()))
    edit: because of your question i have a good time by making this
    Last edited by Ant_G; 28th Jun 2019 at 02:49. Reason: improove the code
    Quote Quote  
  7. Thanks, Al - it works! Except it is printing the output as one big error message so I swapped the order of "out" and "err" on line 10:

    Code:
    import subprocess
    import os
    
    def probe_file(ffprobe, filename):
        cmnd = [ffprobe , '-i', filename, '-show_entries' ,  'frame=pkt_pts_time,pkt_duration_time,interlaced_frame']  #'-print_format',  'json',  '-of',  'json'
        basename = os.path.basename(filename)
        with open(f'{basename}.txt', 'w') as log:
            p = subprocess.Popen(cmnd, stdout=log, stderr=subprocess.PIPE) #, shell = True #to not show pop up cmd window
            print(filename)
            err, out =  p.communicate() # <- swapped order of "out" and "err"
            if out:  #if you redirect output to text file , there is no output here, out is None
                print("==========output==========")
                print(out.decode('utf-8'))
            if err:
                print("========= error ========")
                print(err.decode('utf-8'))
    
    ffprobe = r'ffprobe.exe'  #not having ffprobe in PATH
    input = r'test_pattern_709.mp4' #C:\path_to_file\videofile.mp4'
    
    probe_file(ffprobe, input)
    Last edited by chris319; 27th Jun 2019 at 03:45.
    Quote Quote  
  8. Originally Posted by chris319 View Post
    it is printing the output as one big error message so I swapped the order of "out" and "err" on line 10:

    Code:
            err, out =  p.communicate() 
          
    probe_file(ffprobe, input)
    it will work but it is a booby trap sort of, if it is swapped like that, you call out as err and err as out. It is quite normal that information is in stderr, so I'd leave it as err, except change comments to info, for example:
    Code:
            out, err =  p.communicate()
            if err:
                print("========= info ========")
                print(err.decode('utf-8'))
    so this way it is clear that ffprobe puts info into stderr
    Quote Quote  
  9. That's weird, but I've changed it as you have it.
    Quote Quote  
  10. not sure what you mean, in your last example you have: err, out = p.communicate(), where it might rather be: out, err= p.communicate()
    from manual: communicate() returns a tuple: (stdoutdata, stderrdata)
    Quote Quote  
  11. Here is the complete program, per your suggestion:

    Code:
    import subprocess
    import os
    
    def probe_file(ffprobe, filename):
        cmnd = [ffprobe , '-i', filename, '-show_entries' ,  'frame=pkt_pts_time,pkt_duration_time,interlaced_frame']  #'-print_format',  'json',  '-of',  'json'
        basename = os.path.basename(filename)
        with open(f'{basename}.txt', 'w') as log:
            p = subprocess.Popen(cmnd, stdout=log, stderr=subprocess.PIPE) #, shell = True #to not show pop up cmd window
                #print(filename)
            out,err =  p.communicate()
            if out:  #if you redirect output to text file , there is no output here, out is None
                print("==========output==========")
                print(out.decode('utf-8'))
            if err:
                print("========= info ========")
                print(err.decode('utf-8'))
    
    ffprobe = r'ffprobe.exe'  #not having ffprobe in PATH
    input = r'test_pattern_709.mp4' #C:\path_to_file\videofile.mp4'
    
    probe_file(ffprobe, input)
    Quote Quote  
  12. oh, ok, weird in a sense that info is in stderr. It helps to think of it something like two band channel. Out and err are just labels and devoleper channels whatever into whatever channel. Thanks to that, ffprobe can do a thing you want and still prints its own log. Or you can take out those labels and just use indexing, first item in that tuple has index 0, second 1:
    Code:
            p = subprocess.Popen(cmnd, stdout=log, stderr=subprocess.PIPE)
            results = p.communicate()
            if results[1]:
                print("========= info ========")
                print(results[1].decode('utf-8'))
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!