probe-static.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #!/usr/bin/env python3
  2. import os, sys, subprocess, pathlib, logging, pprint
  3. # Static config
  4. DEBUG = False
  5. lang_undef = 'und'
  6. ffprobe_exec = 'ffprobe'
  7. # Env config
  8. if 'DEBUG' in os.environ:
  9. DEBUG = bool(os.environ['DEBUG'])
  10. if 'EXEC' in os.environ:
  11. ffprobe_exec = pathlib.Path(os.environ['EXEC'])
  12. # CLI config
  13. if len(sys.argv) < 2:
  14. print(f"Usage: {sys.argv[0]} input_file", file=sys.stderr)
  15. sys.exit(-1)
  16. # Logging
  17. if DEBUG:
  18. logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
  19. else:
  20. logging.basicConfig(stream=sys.stderr, level=logging.WARN)
  21. logger = logging.getLogger(__name__)
  22. # Parse to array of dicts of stream data
  23. def ffprobe(path):
  24. streams = {}
  25. # ffprobe
  26. args = [ ffprobe_exec, '-hide_banner', '-show_streams', path ]
  27. logger.debug(f"ffprobe command: {args}")
  28. probe = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  29. logger.debug(f"ffprobe result: {probe}")
  30. data = probe.stdout.decode('utf-8')
  31. if probe.returncode != 0:
  32. logger.error(f"ffprobe error ({probe.returncode}): {probe.stderr.decode('utf-8')}")
  33. logger.debug(f"ffprobe stdout: {data}")
  34. sys.exit(probe.returncode)
  35. # Process streams
  36. stream = None
  37. for line in data.splitlines():
  38. if line == "[STREAM]":
  39. logger.debug('Stream start')
  40. stream = {}
  41. elif line == "[/STREAM]":
  42. logger.debug('Stream end')
  43. i = len(streams)
  44. try:
  45. i = int(stream['index'])
  46. except ValueError:
  47. pass
  48. if i in streams:
  49. logger.error(f"Inconsistent stream index: {i}")
  50. logger.debug(f"Streams: {steams}\nNext stream: {stream}")
  51. continue
  52. streams[i] = stream
  53. steam = None
  54. elif stream is not None:
  55. logger.debug(f"\tStream data: {line}")
  56. try:
  57. (key, val) = line.split('=', 1)
  58. except ValueError:
  59. logger.error(f"Skipping unexpected stream data: {line}")
  60. continue
  61. stream[key] = val
  62. # Return the set of all parsed streams
  63. return streams
  64. # Execute
  65. streams = ffprobe(sys.argv[1])
  66. if len(sys.argv) == 2:
  67. pprint.pp(streams)
  68. else:
  69. for (i, stream) in streams.items():
  70. for key in sys.argv[2:]:
  71. if key in stream:
  72. print(f"{i}: {key}={stream[key]}")
  73. else:
  74. print(f"{i}: {key}=")