You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
3.1 KiB

  1. # Copyright 2015 Adafruit Industries.
  2. # Author: Tony DiCola
  3. # License: GNU GPLv2, see LICENSE.txt
  4. import os
  5. import subprocess
  6. import time
  7. class OMXPlayer:
  8. def __init__(self, config):
  9. """Create an instance of a video player that runs omxplayer in the
  10. background.
  11. """
  12. self._process = None
  13. self._load_config(config)
  14. def _load_config(self, config):
  15. self._extensions = config.get('omxplayer', 'extensions') \
  16. .translate(str.maketrans('', '', ' \t\r\n.')) \
  17. .split(',')
  18. self._extra_args = config.get('omxplayer', 'extra_args').split()
  19. self._sound = config.get('omxplayer', 'sound').lower()
  20. assert self._sound in ('hdmi', 'local', 'both'), 'Unknown omxplayer sound configuration value: {0} Expected hdmi, local, or both.'.format(self._sound)
  21. def supported_extensions(self):
  22. """Return list of supported file extensions."""
  23. return self._extensions
  24. def play(self, movie, loop=False, vol=0):
  25. """Play the provided movied file, optionally looping it repeatedly."""
  26. self.stop(3) # Up to 3 second delay to let the old player stop.
  27. # Assemble list of arguments.
  28. args = ['omxplayer']
  29. args.extend(['-o', self._sound]) # Add sound arguments.
  30. args.extend(self._extra_args) # Add extra arguments from config.
  31. if vol is not 0:
  32. args.extend(['--vol', str(vol)])
  33. if loop:
  34. args.append('--loop') # Add loop parameter if necessary.
  35. args.append(movie) # Add movie file path.
  36. # Run omxplayer process and direct standard output to /dev/null.
  37. self._process = subprocess.Popen(args,
  38. stdout=open(os.devnull, 'wb'),
  39. close_fds=True)
  40. def is_playing(self):
  41. """Return true if the video player is running, false otherwise."""
  42. if self._process is None:
  43. return False
  44. self._process.poll()
  45. return self._process.returncode is None
  46. def stop(self, block_timeout_sec=None):
  47. """Stop the video player. block_timeout_sec is how many seconds to
  48. block waiting for the player to stop before moving on.
  49. """
  50. # Stop the player if it's running.
  51. if self._process is not None and self._process.returncode is None:
  52. # There are a couple processes used by omxplayer, so kill both
  53. # with a pkill command.
  54. subprocess.call(['pkill', '-9', 'omxplayer'])
  55. # If a blocking timeout was specified, wait up to that amount of time
  56. # for the process to stop.
  57. start = time.time()
  58. while self._process is not None and self._process.returncode is None:
  59. if (time.time() - start) >= block_timeout_sec:
  60. break
  61. time.sleep(0)
  62. # Let the process be garbage collected.
  63. self._process = None
  64. def create_player(config):
  65. """Create new video player based on omxplayer."""
  66. return OMXPlayer(config)