/ffmpeg-progess.py

https://bitbucket.org/GigaPatches/python-scripts · Python · 51 lines · 32 code · 5 blank · 14 comment · 9 complexity · 056a7a76d2a084d6ceb490ef302d79f4 MD5 · raw file

  1. #!/usr/bin/python
  2. '''
  3. Displays a progress bar for FFMPEG
  4. Usage:
  5. Pipe the output of an ffmpeg script into it (both stdout and stderr!)
  6. ffmpeg -i input.avi output.mp4 |& python ffmpeg-progress.py
  7. Known Issues:
  8. - Does not handle prompts from ffmpeg
  9. - No error reporting
  10. '''
  11. import os
  12. import sys
  13. import re
  14. import fcntl
  15. import select
  16. from progressbar import *
  17. widgets = ['Encoding: ', Percentage(), ' ', Bar(), ' ', ETA()]
  18. duration_re = re.compile(r'Duration: ([0-9:.]+)')
  19. time_re = re.compile('time=\s*([0-9:.]+) ')
  20. def parse_time(time):
  21. h, m, s = [float(x) for x in time.split(':')]
  22. return h * 3600 + m * 60 + s
  23. if __name__ == '__main__':
  24. duration = None
  25. pbar = ProgressBar(widgets=widgets, maxval=100).start()
  26. # ffmpeg does not flush
  27. fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL,
  28. fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
  29. while True:
  30. read = select.select([sys.stdin.fileno()], [], [])[0]
  31. if read:
  32. data = sys.stdin.read()
  33. if not data: break
  34. if duration is None:
  35. m = duration_re.search(data)
  36. if m:
  37. duration = parse_time(m.group(1))
  38. else:
  39. m = time_re.search(data)
  40. if m:
  41. time = parse_time(m.group(1))
  42. # ffmpeg sometimes goes over causing ProgressBar errors
  43. pbar.update(min((time / duration) * 100, 100))
  44. pbar.finish()