#!/usr/bin/env ruby require 'websocket-eventmachine-client' require 'pp' require 'rmagick' include Magick IP = ARGV[0] FILE = ARGV[1] or raise "No filename given" EFFECT = ARGV[2] FRAMES = 125 FACTOR = 2 delay = 50 uri = "ws://#{IP}:80/ws" puts "Connecting to #{uri}..." gif = ImageList.new last_id = 255 last_frame_time = nil img = nil last_diff = nil EM.run do ws = WebSocket::EventMachine::Client.connect(uri: uri) ws.onopen do puts "Connected." puts "Waiting for delay..." if delay>0 ws.send "effect:#{EFFECT}" if EFFECT ws.send "monitor:1" end ws.onmessage do |msg, type| if type==:binary if delay > 0 delay -= 1 next end data = msg.unpack("C*") width = data.shift height = data.shift splitter = data.shift raise "Unexpected value #{splitter} at index 2" unless splitter==0xFF expected_length = width * height * 3 + 4 raise "Unexpected message length. Expected: #{expected_length}, was: #{data.count + 3}" unless data.count + 3==expected_length img = Image.new(width, height) gc = Draw.new print "." print "#{gif.length}" if gif.length%50==0 (0...height).each do |y| (0...width).each do |x| r, g, b = *data.shift(3) gc.fill("rgb(#{r}, #{g}, #{b})") gc.point(x, y) #img.pixel_color(x, y, Pixel.new(r, g, b, 255)) end end gc.draw(img) img.sample!(FACTOR) gif << img if gif.length >= FRAMES ws.close end else puts "-->#{msg}" exit end end ws.onerror do |error| puts "Error: #{error}" end ws.onclose do |msg, reason| puts "Disconnected." EventMachine.stop_event_loop end end puts puts "Generating gif..." gif.ticks_per_second = 100 gif.delay = 4 gif.write(FILE) puts puts