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

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

Test cases for playing/pausing/stopping jobs

  • Property mode set to 100644
File size: 3.6 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
24    @property
25    def is_playing(self):
26        with self.lock:
27            if self._dryrun:
28                playing = self.isAlive() and not self.is_done
29            else:
30                playing = self.isAlive() and \
31                          not self.is_done and \
32                          self.player is not None and \
33                          self.player.poll() is None
34        return playing
35
36    @property
37    def is_paused(self):
38        with self.lock:
39            paused = self.is_playing and self._paused
40        return paused
41
42    @property
43    def is_done(self):
44        return self._done
45
46    @property
47    def callback(self):
48        return self._callback
49    @callback.setter
50    def callback(self, val):
51        with self.lock:
52            self._callback = val
53
54    def run(self):
55        if self.fh is None:
56            raise ValueError, "file handler is None"
57       
58        self.mplayer_play()
59        self._done = True
60        with self.lock:
61            if self.callback:
62                self.callback()
63
64    def mplayer_play(self):
65        if not self.isAlive():
66            return
67       
68        logger.info("playing file '%s'" % self.fh.name)
69        self._paused = False
70
71        if self._dryrun:
72            step = 0.01
73            while self._dryrun_time > 0:
74                time.sleep(step)
75                self._dryrun_time -= step
76                while self.is_paused:
77                    time.sleep(0.01)
78            return
79       
80        # open mplayer
81        with self.lock:
82            self.player = subprocess.Popen(
83                "/usr/bin/mplayer -really-quiet -slave %s" % self.fh.name,
84                shell=True,
85                stdin=subprocess.PIPE,
86                stderr=subprocess.PIPE,
87                stdout=subprocess.PIPE)
88
89        # wait for mplayer to finish
90        while True:
91            with self.lock:
92                playing = self.is_playing
93            if not playing:
94                break
95            time.sleep(0.1)
96
97        logger.info("mplayer finished with code %d" % self.player.returncode)
98       
99        # get output from mplayer and log it
100        with self.lock:
101            stderr = self.player.stderr.read()
102            stdout = self.player.stdout.read()
103           
104        if stderr.strip() != "":
105            logger.error(stderr)
106        if stdout.strip() != "":
107            logger.debug(stdout)
108
109    def mplayer_pause(self):
110        with self.lock:
111            if self.is_playing:
112                if not self._dryrun:
113                    self.player.stdin.write("pause\n")
114                self._paused = not(self._paused)
115                logger.info("paused: %s", self.is_paused)
116            else:
117                logger.warning("trying to pause non-playing job")
118               
119    def mplayer_stop(self):
120        with self.lock:
121            if self.is_playing:
122                if not self._dryrun:
123                    self.player.stdin.write("quit\n")
124                else:
125                    self._dryrun_time = 0.0
126                logger.info("stopped")
127            else:
128                logger.warning("trying to stop non-playing job")
Note: See TracBrowser for help on using the repository browser.