-
Notifications
You must be signed in to change notification settings - Fork 0
/
vlcclient.py
275 lines (216 loc) · 7.28 KB
/
vlcclient.py
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# coding: utf-8
"""
VLCClient
~~~~~~~~~
This module allows to control a VLC instance through a python interface.
You need to enable the telnet interface, e.g. start
VLC like this:
$ vlc --intf telnet --telnet-password admin
To start VLC with allowed remote admin:
$ vlc --intf telnet --telnet-password admin \
--lua-config "telnet={host='0.0.0.0:4212'}"
Replace --intf with --extraintf to start telnet and the regular GUI
More information about the telnet interface:
http://wiki.videolan.org/Documentation:Streaming_HowTo/VLM
:author: Michael Mayr <[email protected]>
:licence: MIT License
:version: 0.2.0
"""
from __future__ import print_function
import sys
import inspect
import telnetlib
DEFAULT_PORT = 4212
class VLCClient(object):
"""
Connection to a running VLC instance with telnet interface.
"""
def __init__(self, server, port=DEFAULT_PORT, password="admin", timeout=5):
self.server = server
self.port = port
self.password = password
self.timeout = timeout
self.telnet = None
self.server_version = None
self.server_version_tuple = ()
def connect(self):
"""
Connect to VLC and login
"""
assert self.telnet is None, "connect() called twice"
self.telnet = telnetlib.Telnet()
self.telnet.open(self.server, self.port, self.timeout)
# Parse version
result = self.telnet.expect([
r"VLC media player ([\d.]+)".encode("utf-8"),
])
self.server_version = result[1].group(1)
self.server_version_tuple = self.server_version.decode("utf-8").split('.')
# Login
self.telnet.read_until("Password: ".encode("utf-8"))
self.telnet.write(self.password.encode("utf-8"))
self.telnet.write("\n".encode("utf-8"))
# Password correct?
result = self.telnet.expect([
"Password: ".encode("utf-8"),
">".encode("utf-8")
])
if "Password".encode("utf-8") in result[2]:
raise WrongPasswordError()
def disconnect(self):
"""
Disconnect and close connection
"""
self.telnet.close()
self.telnet = None
def _send_command(self, line):
"""
Sends a command to VLC and returns the text reply.
This command may block.
"""
self.telnet.write((line + "\n").encode("utf-8"))
return self.telnet.read_until(">".encode("utf-8"))[1:-3]
def _require_version(self, command, version):
"""
Check if the server runs at least at a specific version
or raise an error.
"""
if isinstance(version, basestring):
version = version.split('.')
if version > self.server_version_tuple:
raise OldServerVersion(
"Command '{0} requires at least VLC {1}".format(
command, ".".join(version)
))
#
# Commands
#
def help(self):
"""Returns the full command reference"""
return self._send_command("help")
def status(self):
"""current playlist status"""
self._require_version("status", "2.0.0")
return self._send_command("status")
def info(self):
"""information about the current stream"""
return self._send_command("info")
def set_fullscreen(self, value):
"""set fullscreen on or off"""
assert type(value) is bool
return self._send_command("fullscreen {}".format("on" if value else "off"))
def raw(self, *args):
"""
Send a raw telnet command
"""
return self._send_command(" ".join(args))
#
# Playlist
#
def add(self, filename):
"""
Add a file to the playlist and play it.
This command always succeeds.
"""
return self._send_command('add {0}'.format(filename))
def enqueue(self, filename):
"""
Add a file to the playlist. This command always succeeds.
"""
return self._send_command("enqueue {0}".format(filename))
def seek(self, second):
"""
Jump to a position at the current stream if supported.
"""
return self._send_command("seek {0}".format(second))
def play(self):
"""Start/Continue the current stream"""
return self._send_command("play")
def pause(self):
"""Pause playing"""
return self._send_command("pause")
def stop(self):
"""Stop stream"""
return self._send_command("stop")
def rewind(self):
"""Rewind stream"""
return self._send_command("rewind")
def next(self):
"""Play next item in playlist"""
return self._send_command("next")
def prev(self):
"""Play previous item in playlist"""
return self._send_command("prev")
def clear(self):
"""Clear all items in playlist"""
return self._send_command("clear")
def playlist(self):
'''Gets the item in current playlist.'''
return self._send_command('playlist')
def is_playing(self):
return self._send_command('is_playing')
def get_title(self):
return self._send_command('get_title')
def get_length(self):
return self._send_command('get_length')
def get_time(self):
''' Seconds elapsed'''
return self._send_command('get_time')
def snapshot(self):
return self._send_command('snapshot')
#
# Volume
#
def volume(self, vol=None):
"""Get the current volume or set it"""
if vol:
return self._send_command("volume {0}".format(vol))
else:
return self._send_command("volume").strip()
def volup(self, steps=1):
"""Increase the volume"""
return self._send_command("volup {0}".format(steps))
def voldown(self, steps=1):
"""Decrease the volume"""
return self._send_command("voldown {0}".format(steps))
class WrongPasswordError(Exception):
"""Invalid password sent to the server."""
pass
class OldServerVersion(Exception):
"""VLC version is too old for the requested commmand."""
pass
def main():
"""
Run any commands via CLI interface
"""
try:
server = sys.argv[1]
if ':' in server:
server, port = server.split(':')
else:
port = DEFAULT_PORT
command_name = sys.argv[2]
except IndexError:
print("usage: vlcclient.py server[:port] command [argument]",
file=sys.stderr)
sys.exit(1)
vlc = VLCClient(server, int(port))
vlc.connect()
print("Connected to VLC {0}\n".format(vlc.server_version),
file=sys.stderr)
try:
command = getattr(vlc, command_name)
argspec = inspect.getargspec(command)
cli_args = sys.argv[3:]
cmd_args = argspec.args[1:]
if not argspec.varargs and len(cli_args) != len(cmd_args):
print("Error: {} requires {} arguments, but only got {}".format(
command_name, len(cmd_args), len(cli_args),
), file=sys.stderr)
exit(1)
result = command(*cli_args)
print(result)
except OldServerVersion as exc:
print("Error: {0}\n".format(exc), file=sys.stderr)
if __name__ == '__main__':
main()