Created
March 8, 2012 15:44
-
-
Save pyro2927/2001583 to your computer and use it in GitHub Desktop.
threaded ruby script to run VLC sync
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# setup static variables | |
MOVIE_FOLDER = "/Volumes/DroboFS/tdb103170485/2/Public/Movies/" | |
#help output | |
# +----[ Remote control commands ] | |
# | | |
# | add XYZ . . . . . . . . . . . . add XYZ to playlist | |
# | enqueue XYZ . . . . . . . . . queue XYZ to playlist | |
# | playlist . . . . . show items currently in playlist | |
# | play . . . . . . . . . . . . . . . . . . play stream | |
# | stop . . . . . . . . . . . . . . . . . . stop stream | |
# | next . . . . . . . . . . . . . . next playlist item | |
# | prev . . . . . . . . . . . . previous playlist item | |
# | goto . . . . . . . . . . . . . . goto item at index | |
# | repeat [on|off] . . . . toggle playlist item repeat | |
# | loop [on|off] . . . . . . . . . toggle playlist loop | |
# | random [on|off] . . . . . . . toggle random jumping | |
# | clear . . . . . . . . . . . . . . clear the playlist | |
# | status . . . . . . . . . . . current playlist status | |
# | title [X] . . . . . . set/get title in current item | |
# | title_n . . . . . . . . next title in current item | |
# | title_p . . . . . . previous title in current item | |
# | chapter [X] . . . . set/get chapter in current item | |
# | chapter_n . . . . . . next chapter in current item | |
# | chapter_p . . . . previous chapter in current item | |
# | | |
# | seek X . . . seek in seconds, for instance `seek 12' | |
# | pause . . . . . . . . . . . . . . . . toggle pause | |
# | fastforward . . . . . . . . . set to maximum rate | |
# | rewind . . . . . . . . . . . . set to minimum rate | |
# | faster . . . . . . . . . . faster playing of stream | |
# | slower . . . . . . . . . . slower playing of stream | |
# | normal . . . . . . . . . . normal playing of stream | |
# | frame. . . . . . . . . . play frame by frame | |
# | f [on|off] . . . . . . . . . . . . toggle fullscreen | |
# | info . . . . . information about the current stream | |
# | stats . . . . . . . . show statistical information | |
# | get_time . . seconds elapsed since stream's beginning | |
# | is_playing . . . . 1 if a stream plays, 0 otherwise | |
# | get_title . . . . . the title of the current stream | |
# | get_length . . . . the length of the current stream | |
# | | |
# | volume [X] . . . . . . . . . . set/get audio volume | |
# | volup [X] . . . . . . . raise audio volume X steps | |
# | voldown [X] . . . . . . lower audio volume X steps | |
# | adev [X] . . . . . . . . . . . set/get audio device | |
# | achan [X]. . . . . . . . . . set/get audio channels | |
# | atrack [X] . . . . . . . . . . . set/get audio track | |
# | vtrack [X] . . . . . . . . . . . set/get video track | |
# | vratio [X] . . . . . . . set/get video aspect ratio | |
# | vcrop [X] . . . . . . . . . . . set/get video crop | |
# | vzoom [X] . . . . . . . . . . . set/get video zoom | |
# | snapshot . . . . . . . . . . . . take video snapshot | |
# | strack [X] . . . . . . . . . set/get subtitles track | |
# | key [hotkey name] . . . . . . simulate hotkey press | |
# | menu . . [on|off|up|down|left|right|select] use menu | |
# | | |
# | help . . . . . . . . . . . . . . . this help message | |
# | longhelp . . . . . . . . . . . a longer help message | |
# | logout . . . . . . . exit (if in socket connection) | |
# | quit . . . . . . . . . . . . . . . . . . . quit vlc | |
# | | |
# +----[ end of help ] | |
# start script | |
require 'socket' | |
require 'timeout' | |
server = TCPServer.open(2300) | |
# Setup our clients | |
$clientArray = Array.new | |
def sendCommand(command, clientHash) | |
# %x[echo #{command} | nc #{clientHash[:ip]} #{clientHash[:port]}] | |
puts "Running command '#{command}' on client #{clientHash[:ip]}" | |
clientHash[:socket].puts(command) | |
readSocket(clientHash[:socket]) | |
end | |
def sendAllCommand(command) | |
# puts "Running command '#{command}' on all clients" | |
$clientArray.each do |clientHash| | |
sendCommand(command, clientHash) | |
end | |
end | |
def readSocket(socket) | |
begin | |
#don't let this stall us | |
begin | |
timeout (1) do | |
line = socket.gets | |
puts line.chomp | |
end | |
rescue | |
return | |
end | |
end while true | |
end | |
#authenticate against the luarc | |
def auth(clientHash) | |
puts "Authenticating" | |
socket = clientHash[:socket] | |
#readSocket(socket) | |
#put in our admin password | |
socket.puts "admin" | |
readSocket(socket) | |
puts "Done authenticating" | |
end | |
loop { # Servers run forever | |
Thread.start(server.accept) do |client| | |
#loop over commands from the client | |
loop { | |
line = client.gets | |
line.chomp! | |
args = line.split(" ") | |
case args[0] | |
# help text | |
when "help" | |
client.puts "To start, open VLC and select VLC > Add Interface > Telnet'\nThen run 'register 4212' here to register your client for syncronized playback" | |
client.puts "** Commands **" | |
client.puts "* register <port> (registers a vlc oldrc port with this server)" | |
client.puts "* unregister (unregisters all ports from the client's IP)" | |
client.puts "* seek <number_in_seconds>" | |
client.puts "* pause (toggles pause on/off)" | |
client.puts "* startover (starts film over)" | |
client.puts "* list (list all movies on main server)" | |
when "list" | |
client.puts %x[ls #{MOVIE_FOLDER}] | |
#list clients by ip | |
when "clients" | |
$clientArray.each do |clientHash| | |
client.puts "* #{clientHash[:ip]}" | |
end | |
# register this client | |
when "register" | |
if args[1].nil? | |
client.puts "Missing VLC port number" | |
else | |
#get our IP address | |
port, ip = Socket.unpack_sockaddr_in(client.getpeername) | |
client.puts "Registering client with IP: #{ip}" | |
vlcSocket = TCPSocket.open(ip, args[1]) | |
$clientArray.push({:ip => ip, :port => args[1], :socket => vlcSocket }) | |
auth($clientArray.last) | |
end | |
#remove this client | |
when "unregister" | |
#get our IP address | |
port, ip = Socket.unpack_sockaddr_in(client.getpeername) | |
$clientArray.delete_if {|hash| hash[:ip] == ip } | |
client.puts "Client removed, #{ $clientArray.length } remaining clients" | |
when "play" | |
client.puts "Playing clients..." | |
$clientArray.each do |clientHash| | |
is_playing = sendCommand("is_playing",clientHash) | |
if is_playing != 1 | |
sendCommand("play",clientHash) | |
client.puts "Client #{clientHash[:ip]} now playing" | |
else | |
client.puts "Client #{clientHash[:ip]} already playing" | |
end | |
end | |
when "pause" | |
client.puts "Toggling pause on clients..." | |
sendAllCommand("pause") | |
when "seek" | |
if args[1].nil? | |
client.puts "Need seek time" | |
else | |
sendAllCommand("seek #{args[1]}") | |
end | |
when "startover" | |
client.puts "Starting everyone over" | |
sendAllCommand("stop") | |
sendAllCommand("play") | |
sendAllCommand("seek 0") | |
else | |
client.puts "Command (#{command})not understood" | |
end | |
} | |
end | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment