I like to run multiple instances of VLC, each with its own playlist, and be able to control them using the web interface and telnet. I then have some python scripts to simplify sending commands.
Powershell
# create a shortcut
function CreateVlcShortcut {
param (
[String]$shortcutName = "VLC Media Player",
[Int]$portOffset = 0
)
$HPORT = 8000 + $portOffset
$TPORT = 7000 + $portOffset
$shortcutPath = "C:\Program Files\VideoLAN\VLC\vlc.exe"
$shortcutArguments = "--http-port $HPORT --telnet-port $TPORT --telnet-password tree --http-password tree"
$WshShell = New-Object -COMObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("VLC $portOffset.lnk")
$Shortcut.TargetPath = $shortcutPath
$Shortcut.Arguments = $shortcutArguments
$Shortcut.Save()
}
# Example usage
#CreateVlcShortcut -portOffset 0
#CreateVlcShortcut -portOffset 20
# Create Multiple
# iterate over a range of numbers
function IterateOverRange {
param (
[Int]$start = 0,
[Int]$end = 30
)
for ($i = $start; $i -lt $end; $i++) {
CreateVlcShortcut -portOffset $i
}
}
IterateOverRange -start 0 -end 5
IterateOverRange -start 10 -end 15
IterateOverRange -start 20 -end 25
IterateOverRange -start 30 -end 35
CLI tools
At present I have no idea how to replace these on Windows without using cygwin and expect. I can, of course, run the Linux versions in WSL.
tvlc
This is a wrapper around expect.
#!/bin/bash
H="$1"
P="$2"
if [ -z "$H" -o -z "$P" ]; then
echo "tvlc host port cmd ..."
exit 1
fi
[ "$H" = "s" ] && H="snarf" # use this to create shortcuts
tvlc_expect "$H" "$P"
and tvlc_expect is
#!/usr/bin/expect
set timeout 5
set host "[lindex $argv 0]"
set tport "[lindex $argv 1]"
puts "tport '$tport'"
if { $tport == "" } {
set tport 0
}
set port "[expr 7000 + $tport]"
set password "tree"
spawn telnet $host $port
expect "Password:"
send "$password\r"
expect "Welcome, Master"
interact
tvlcmd
This uses python's socket module rather than using expect.
#!/usr/bin/env python3
import socket
from time import sleep
import sys
from threading import Thread
# shorthands
d = {
"s": "snarf"
}
def get_ports(ps):
xs = [ int(x) for x in ps.split(",") ]
for x in xs:
if x < 0 or x > 200:
raise ValueError(f"Port {x} out of range")
return set(xs)
def get_hosts(hs):
ys = [ (d[x] if x in d else x) for x in hs.split(",") ]
return set(ys)
args = sys.argv[1:]
try:
host, port, *cmds = args
ports = get_ports(port)
hosts = get_hosts(host)
except ValueError as e:
print(f"ValueError {e}")
print(f"{sys.argv[0]} <host> <tport> [<cmd>...]",file=sys.stderr)
exit(1)
cs = []
cmdi = iter(cmds)
for cmd in cmdi:
if cmd == "-f":
try:
fn = next(cmdi)
except StopIteration:
print(f"Missing filename for -f",file=sys.stderr)
exit(1)
with open(fn) as f:
lines = f.read().rstrip().splitlines()
cs.extend(lines)
else:
cs.append(cmd)
cmds = cs
def doit(s,host,port,cmds):
try:
s.connect((host,port))
except Exception:
print(f"# fail doit connect {host}:{port}",file=sys.stderr)
return
n = 0
while True:
n += 1
if n > 100:
print("doom",file=sys.stderr)
exit(1)
a = s.recv(1024)
if b"Password:" in a:
s.sendall(b"tree\n")
sleep(0.1)
b = s.recv(1024)
if b"aster" in b:
while not b">" in b:
b = s.recv(1024)
return docmds(s,cmds)
sleep(0.1)
def docmds(s,cmds):
for cmd in cmds:
cmd = cmd.replace("_"," ")
cmd += "\n"
s.sendall(cmd.encode())
oldtimeout = s.gettimeout()
s.settimeout(0.5)
sleep(0.1)
n = 0
while True:
try:
a = s.recv(1024)
except TimeoutError:
break
if a == b"":
break
try:
b = a.decode()
except Exception:
b = "".join( x for x in a if ord(x) < 128 and ord(x) >= 32 )
sys.stdout.write(b)
if "\n>" in b or b.startswith(">"):
break
print()
s.settimeout(oldtimeout)
sleep(0.1)
def doit1(host,port,cmds):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
doit(s,host,port,cmds)
except Exception as e:
print(f"Exception {e} sending to {host}:{port}")
def main():
for host in hosts:
for port in ports:
port += 7000
print(f"{host}:{port}")
Thread(target=doit1,args=(host,port,cmds)).start()
if __name__ == "__main__":
main()