source: server/lib/gutenbach/server/player.py @ a9eb577e

no-cups
Last change on this file since a9eb577e was a9eb577e, checked in by Jessica B. Hamrick <jhamrick@…>, 12 years ago

Add logging configuration option

  • Property mode set to 100644
File size: 3.8 KB
Line 
1import logging
2import threading
3import subprocess
4import time
5
6# initialize logger
7logger = logging.getLogger(__name__)
8
9class Player(threading.Thread):
10
11    def __init__(self, fh, *args, **kwargs):
12        self.lock = threading.RLock()
13
14        with self.lock:
15            super(Player, self).__init__(*args, **kwargs)
16            self.fh = fh
17            self.player = None
18            self._callback = None
19            self._paused = False
20            self._done = False
21            self._dryrun = False
22            self._dryrun_time = 0.5
23            self._lag = 0.01
24
25    @property
26    def is_playing(self):
27        with self.lock:
28            if self._dryrun:
29                playing = self.isAlive() and not self.is_done
30            else:
31                playing = self.isAlive() and \
32                          not self.is_done and \
33                          self.player is not None and \
34                          self.player.poll() is None
35        return playing
36
37    @property
38    def is_paused(self):
39        with self.lock:
40            paused = self.is_playing and self._paused
41        return paused
42
43    @property
44    def is_done(self):
45        return self._done
46
47    @property
48    def callback(self):
49        return self._callback
50    @callback.setter
51    def callback(self, val):
52        with self.lock:
53            self._callback = val
54
55    def start(self):
56        super(Player, self).start()
57        time.sleep(self._lag)
58
59    def run(self):
60        if self.fh is None:
61            raise ValueError, "file handler is None"
62       
63        logger.info("playing file '%s'" % self.fh.name)
64
65        with self.lock:
66            self._paused = False
67            self._done = False
68
69        command = ["mplayer", "-really-quiet", "-slave", self.fh.name]
70        logger.info("running '%s'", " ".join(command))
71
72        if self._dryrun:
73            step = 0.01
74            while self._dryrun_time > 0:
75                time.sleep(step)
76                self._dryrun_time -= step
77                while self.is_paused:
78                    time.sleep(0.01)
79
80        else:
81            with self.lock:
82                self.player = subprocess.Popen(
83                    command,
84                    stdin=subprocess.PIPE,
85                    stderr=subprocess.PIPE,
86                    stdout=subprocess.PIPE)
87
88            # wait for mplayer to finish
89            while True:
90                with self.lock:
91                    playing = self.is_playing
92                if not playing:
93                    break
94                time.sleep(0.1)
95
96            logger.info("mplayer finished with code %d" % self.player.returncode)
97       
98            # get output from mplayer and log it
99            with self.lock:
100                stderr = self.player.stderr.read()
101                stdout = self.player.stdout.read()
102           
103            if stderr.strip() != "":
104                logger.error(stderr)
105            if stdout.strip() != "":
106                logger.debug(stdout)
107
108        with self.lock:
109            if self.callback:
110                self.callback()
111            self._done = True
112
113    def mplayer_pause(self):
114        with self.lock:
115            if self.is_playing:
116                if not self._dryrun:
117                    self.player.stdin.write("pause\n")
118                self._paused = not(self._paused)
119                logger.info("paused: %s", self.is_paused)
120            else:
121                logger.warning("trying to pause non-playing job")
122        time.sleep(self._lag)
123               
124    def mplayer_stop(self):
125        with self.lock:
126            if self.is_playing:
127                if not self._dryrun:
128                    self.player.stdin.write("quit\n")
129                else:
130                    self._dryrun_time = 0.0
131                logger.info("stopped")
132            else:
133                logger.warning("trying to stop non-playing job")
134        self.join()
Note: See TracBrowser for help on using the repository browser.