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

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

Remove lag times from job test cases and put them in the actual player.

  • 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        self.mplayer_play()
64        self._done = True
65        with self.lock:
66            if self.callback:
67                self.callback()
68
69    def mplayer_play(self):
70        if not self.isAlive():
71            return
72       
73        logger.info("playing file '%s'" % self.fh.name)
74        self._paused = False
75
76        if self._dryrun:
77            step = 0.01
78            while self._dryrun_time > 0:
79                time.sleep(step)
80                self._dryrun_time -= step
81                while self.is_paused:
82                    time.sleep(0.01)
83            return
84       
85        # open mplayer
86        with self.lock:
87            self.player = subprocess.Popen(
88                "/usr/bin/mplayer -really-quiet -slave %s" % self.fh.name,
89                shell=True,
90                stdin=subprocess.PIPE,
91                stderr=subprocess.PIPE,
92                stdout=subprocess.PIPE)
93
94        # wait for mplayer to finish
95        while True:
96            with self.lock:
97                playing = self.is_playing
98            if not playing:
99                break
100            time.sleep(0.1)
101
102        logger.info("mplayer finished with code %d" % self.player.returncode)
103       
104        # get output from mplayer and log it
105        with self.lock:
106            stderr = self.player.stderr.read()
107            stdout = self.player.stdout.read()
108           
109        if stderr.strip() != "":
110            logger.error(stderr)
111        if stdout.strip() != "":
112            logger.debug(stdout)
113
114    def mplayer_pause(self):
115        with self.lock:
116            if self.is_playing:
117                if not self._dryrun:
118                    self.player.stdin.write("pause\n")
119                self._paused = not(self._paused)
120                logger.info("paused: %s", self.is_paused)
121            else:
122                logger.warning("trying to pause non-playing job")
123        time.sleep(self._lag)
124               
125    def mplayer_stop(self):
126        with self.lock:
127            if self.is_playing:
128                if not self._dryrun:
129                    self.player.stdin.write("quit\n")
130                else:
131                    self._dryrun_time = 0.0
132                logger.info("stopped")
133            else:
134                logger.warning("trying to stop non-playing job")
135        time.sleep(self._lag)
Note: See TracBrowser for help on using the repository browser.