1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
import mpv
def _complexGraph(tracks):
graph = ""
for i, enabled in tracks.items():
graph += f"[aid{i}]volume={"1.0" if enabled else "0.0"}[a{i}];"
graph += "[a1][a2][a3][a4][a5][a6]amix=inputs=6:"
graph += "duration=longest:normalize=0[ao]"
return graph
def _simpleGraph():
return (
"[aid1]volume=1.0[a1];"
"[a1]amix=inputs=1:"
"duration=longest:normalize=1[ao]"
)
class Player:
VOCAL_TRACK = 1
GUITAR_TRACK = 2
BASS_TRACK = 3
PIANO_TRACK =4
DRUM_TRACK = 5
OTHER_TRACK = 6
def __init__(self):
self._player = mpv.MPV(ao="jack")
self._player.loop = "inf"
self._player.lavfi_complex = _simpleGraph()
self._playingStateCallback = self._dummyCallback
self._volumeCallback = self._dummyCallback
self._player.observe_property("pause", lambda name, value: self._playingStateCallback())
self._player.observe_property("volume", lambda name, value: self._volumeCallback())
self._player.observe_property("track-list/count", lambda name, value: self._updateGraph())
self._tracks = {
self.VOCAL_TRACK: True,
self.GUITAR_TRACK: True,
self.BASS_TRACK: True,
self.PIANO_TRACK: True,
self.DRUM_TRACK: True,
self.OTHER_TRACK: True
}
def __del__(self):
self._player.close()
def _dummyCallback(self):
pass
def _updateGraph(self):
if self.tracksSupported():
self._player.lavfi_complex = _complexGraph(self._tracks)
else:
self._player.lavfi_complex = _simpleGraph()
def play(self):
self._player.pause = False
def pause(self):
self._player.pause = True
def isPlaying(self):
return not self._player.pause
def setPlaybackRate(self, rate):
self._player.speed = rate
def getPlaybackRate(self):
return self._player.speed
def setPlaybackPosition(self, position):
self._player.percent_pos = position * 100
def getPlaybackPosition(self):
return float(self._player.percent_pos or 0.0) / 100.0
def setPlaybackVolume(self, volume):
self._player.volume = int(volume * 100)
def getPlaybackVolume(self):
return float(self._player.volume) / 100.0
def setCurrentSong(self, path):
self.pause()
self._player.play(str(path))
def setPlayingStateChangedCallback(self, callback):
self._playingStateCallback = callback
def setPlaybackVolumeChangedCallback(self, callback):
self._volumeCallback = callback
def tracksSupported(self):
return len(self._player.track_list) == 6
def trackEnabled(self, trackId):
return self._tracks[trackId]
def setTrackEnabled(self, trackId, enable):
self._tracks[trackId] = enable
self._updateGraph()
|