mmp

The mini music player, an alternative to MPD

git clone https://git.8pit.net/mmp.git

 1(import [threading [*]]
 2    [playback.gstplayer [GstPlayer]]
 3    [playback.playlist [Playlist]])
 4(require [hy.contrib.walk [let]])
 5
 6(defclass Playback []
 7  (defn __init__ [self]
 8    (setv self._player (GstPlayer))
 9    (setv self._player-lock (RLock))
10    (setv self._playlist (Playlist))
11    (setv self._playlist-lock (RLock))
12
13    (.run self._player))
14
15  (defn state [self]
16    (let [state (with (self._player-lock)
17                      (.state self._player))]
18      (cond
19        [(= state "play") "play"]
20        [(= state "pause") "pause"]
21        [True "stop"])))
22
23  (defn time [self]
24    (with (self._player-lock)
25      (let [t (.time self._player)]
26        (if (= t (, 0 0))
27          None
28          (tuple (map (fn [x] (round x 3)) t))))))
29
30  (defn play [self &optional index]
31    (defn play-next []
32      (with (playlist self)
33        (let [song (.next playlist)]
34          (if (is None song)
35            False
36            (do
37              (.play-file self._player (. song path))
38              True)))))
39
40    (with (playlist self)
41      (when (not (is None index))
42        (.stop self)
43        (.nextup playlist index))
44      (.set_callback self._player play-next)
45      (with (self._player-lock)
46        (if (is None (.current playlist))
47          (play-next)
48          (.play self._player)))))
49
50  (defn pause [self]
51    (.clear_callback self._player)
52    (with (self._player-lock)
53      (.pause self._player)))
54
55  (defn stop [self]
56    (.clear_callback self._player)
57    (with (playlist self)
58      (.reset playlist))
59    (with (self._player-lock)
60      (.stop self._player)))
61
62  (defn next [self]
63    (with (playlist self)
64      (let [song (.next playlist)]
65        (if (is None song)
66          (.stop self)
67          (.play-file self._player (. song path)))
68        song)))
69
70  ;; TODO: Implement prev
71
72  (defn remove [self range]
73    (with (playlist self)
74      (let [song (.current playlist)]
75        (if (and (not (is None song))
76                 (in (. song position) range))
77            (let [s (.next self)]
78              (if (or (is None s)
79                      (= (. s position) (. song position)))
80                (.stop self)))))
81      (.remove playlist range)))
82
83  (defn __enter__ [self]
84    """Context manager for aquiring access to the underlying playlist.
85       All code executed in the context manager will be executed atomic
86       on the playlist object, i.e. the song won't be changed in between."""
87    (.acquire self._playlist-lock)
88    self._playlist)
89
90  (defn __exit__ [self type value traceback]
91    (.release self._playlist-lock)))