--- /dev/null
+<!DOCTYPE html>
+<html dir="ltr" lang="en-US">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta name="viewport" content="width=device-width,initial-scale=1">
+ <style>
+ html, body {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: 100%;
+ max-height: 100%;
+ background-color: #000;
+ overflow: hidden;
+ }
+ </style>
+</head>
+<body>
+
+
+<input type="button" value="Skip" onclick="javscript:Client.skip()"/>
+<input type="button" value="Play" onclick="javscript:Client.play()"/>
+<input type="button" value="Pause" onclick="javscript:Client.pause()"/>
+<input type="button" value="Chan +" onclick="javscript:Client.chan_next()"/>
+<input type="button" value="Chan -" onclick="javscript:Client.chan_prev()"/>
+
+
+<script type="text/javascript" src="client.js"></script>
+<script>
+(()=>{
+ Client.connect(()=>{});
+})();
+</script>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html dir="ltr" lang="en-US">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta name="viewport" content="width=device-width,initial-scale=1">
+ <style>
+ html, body {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: 100%;
+ max-height: 100%;
+ background-color: #000;
+ overflow: hidden;
+ }
+ </style>
+</head>
+<body>
+<video id="Video" width="100%" height="100%" src="" autoplay muted playsinline>
+</video>
+
+<script>
+const updatePlayer = (data)=>{
+ console.log(data["curr"]);
+ console.log(data["curr"]["duration"])
+ const duration = data["curr"]["duration"];
+ const elapsed = data["time"]
+ if (elapsed > 0 && elapsed < duration)
+ {
+ Video.src = data["curr"]["path"] + "#t=" + Math.floor(elapsed);
+ }
+};
+
+const Cmd = {
+ play: (data)=>{
+ console.log(data);
+ updatePlayer(data);
+ }
+};
+
+const connect = ()=>{
+ let ws = new WebSocket(
+ "ws://" + window.location.host + ":3000");
+
+ ws.onmessage = (event)=>{
+ const msg = JSON.parse(event.data);
+ Cmd[msg.cmd](msg);
+ };
+
+ ws.onclose = (event)=>{
+ connect();
+ };
+};
+
+Video.addEventListener("ended", updatePlayer);
+document.addEventListener("visibilitychange", updatePlayer);
+
+(()=>{ connect(); })();
+</script>
+
+</body></html>
["Movies", "Shorts", "Shows"])
]
player = ATV::Player.new(db, channels)
-server = ATV::Server.new(player)
-server.start
+ATV::Server.start(player)
+#server = ATV::Server.new(player)
+#server.start
@items = selectors.map do |sel|
files.select {|f| f["path"].start_with? sel }
end.flatten.shuffle
+ @time = @items[@index]["duration"] - 10
end
def update(playing)
@time += 1 if playing
item = @items[@index]
if @time >= item["duration"] then
- next()
+ next_vid()
pp @items[@index]
true
else
end
end
- def next()
- @time = 0
+ def next_vid()
@index += 1
if @index >= @items.length
@index = 0
end
+ @time = 0
+ @time = @items[@index]["duration"] - 10
+ end
+
+ def state()
+ next_index = ((@index+1) >= @items.length ? 0 : (@index+1))
+ {
+ "time" => @time,
+ "curr" => @items[@index],
+ "next" => @items[next_index]
+ }
end
end
end
@channels.each do |c|
updated ||= c.update(@playing)
end
+# puts updated
+ updated
end
def play()
@channel = @channels.length - 1
end
end
+
+ def state()
+ @channels[@channel].state
+ end
end
end
require 'iodine'
module ATV
- class Server
+ module Server
APP = Proc.new do |env|
if env['rack.upgrade?'.freeze] == :websocket
- env['rack.upgrade'.freeze] = ATV
+ env['rack.upgrade'.freeze] = ATV::Server
[0,{}, []] # It's possible to set cookies for the response.
end
end
- def initialize(player)
- @player = player
- end
-
- def start()
+ def start(player)
+ @@player = player
Iodine.listen(service: :http, handler: APP)
Iodine.run_every(1000) do
- @player.update
+ if player.update
+ publish(@@player.state.merge({"cmd" => "play"}))
+ end
end
+ Iodine.threads = 1
Iodine.start
end
+
+ def publish(obj)
+ puts JSON.dump(obj)
+ Iodine.publish(:atv, JSON.dump(obj))
+ end
+
+ def on_open(client)
+ puts "connect: #{client}"
+ client.subscribe :atv
+ publish(@@player.state.merge({"cmd" => "play"}))
+ end
+
+ def on_close(client)
+ puts "disconnect: #{client}"
+ end
+
+ def on_message(client, cmd)
+ cmd = JSON.parse(cmd)
+ Cmds[cmd["cmd"]].call(cmd["data"])
+ end
+
+ def send(client, data)
+ client.write JSON.dump(data)
+ end
+
+# Cmds = {
+# "skip" => lambda do |data|
+# cfg = $channels[$channel]
+# cfg[:play][:start_time] = secs_since_midnight()
+# cfg[:play][:curr] = cfg[:play][:next]
+# cfg[:play][:next] = next_show($channel)
+# update_program()
+# end,
+#
+# "play" => lambda do |data|
+# pp data
+# end,
+#
+# "pause" => lambda do |data|
+# pp data
+# end,
+#
+# "chan_prev" => lambda do |data|
+# $channel -= 1
+# if $channel < 0
+# $channel = $channels.length - 1
+# end
+# puts $channel
+# update_program()
+# end,
+#
+# "chan_next" => lambda do |data|
+# $channel += 1
+# if $channel >= $channels.length
+# $channel = 0
+# end
+# puts $channel
+# update_program()
+# end,
+# }
+
+ extend self
end
end