Browse files

first commit of the videochat example for chrome

  • Loading branch information...
1 parent ed96a70 commit c59e45e39583c1b9f5af96c769477d693bafe929 @rdeioris rdeioris committed Aug 17, 2012
Showing with 241 additions and 0 deletions.
  1. +130 −0 examples/chromevideochat/videochat.html
  2. +111 −0 examples/chromevideochat/videochat.rb
View
130 examples/chromevideochat/videochat.html
@@ -0,0 +1,130 @@
+<html>
+
+ <head>
+ <script type="text/javascript">
+
+
+var ctx;
+var ws_data;
+var ws_control;
+var output;
+var my_id;
+
+
+function update_video() {
+ ctx.drawImage(output, 0, 0, 320, 240);
+ image = ctx.getImageData(0, 0, 320, 240);
+ b64jpeg = canvas.toDataURL("image/jpeg", 0.4);
+ ws_data.send(my_id+','+b64jpeg);
+}
+
+function blastbeat_data(id, cookie) {
+ ws_data = new WebSocket("ws://192.168.173.5:8080/data/"+cookie);
+ ws_data.onopen = function() {
+
+ canvas = document.getElementById('output_canvas');
+ ctx = canvas.getContext('2d');
+
+ setInterval(update_video, 100);
+
+ ws_data.send('start');
+
+ ws_data.onmessage = function(e) {
+ frame = e.data;
+ var comma = frame.indexOf(',');
+ if (comma == -1) return;
+ frame_id = frame.substr(0, comma);
+ user_frame = document.getElementById('user_'+frame_id);
+ if (user_frame) {
+ user_frame.src = frame.substr(comma+1);
+ }
+ }
+ }
+
+ ws_data.onclose = function(e) {
+ alert('data socket closed');
+ }
+
+ ws_data.onerror = function(e) {
+ alert('error on data socket');
+ }
+}
+
+function ping_control() {
+ join = {'command':'ping'};
+ jm = JSON.stringify(join);
+ ws_control.send(jm);
+}
+
+function blastbeat_control() {
+ ws_control = new WebSocket("ws://192.168.173.5:8080/control");
+ ws_control.onopen = function() {
+
+ join = {'command':'join', 'username':'foobar'};
+ jm = JSON.stringify(join);
+ ws_control.send(jm);
+
+ setInterval(ping_control, 30*1000);
+
+ ws_control.onmessage = function(e) {
+ jm = JSON.parse(e.data);
+ if (jm['command'] == 'welcome') {
+ for(user_id in jm['users']) {
+ user_video = document.createElement('img');
+ user_video.id = 'user_' +jm['users'][user_id];
+ document.body.appendChild(user_video);
+ }
+ my_id = jm['id'];
+ blastbeat_data(jm['id'], jm['cookie']);
+ }
+ else if (jm['command'] == 'newuser') {
+ if (jm['id'] != my_id) {
+ user_video = document.createElement('img');
+ user_video.id = 'user_' + jm['id'];
+ document.body.appendChild(user_video);
+ }
+ }
+ else if (jm['command'] == 'byeuser') {
+ user_video = document.getElementById('user_'+jm['id']);
+ if (user_video) {
+ document.body.removeChild(user_video);
+ }
+ }
+ else if (jm['command'] == 'text') {
+ alert(jm['text']);
+ }
+ }
+
+ ws_control.onclose = function(e) {
+ alert('control socket closed');
+ }
+ }
+
+ ws_control.onerror = function(e) {
+ alert('error on control socket');
+ }
+}
+
+function webcam_ok(stream) {
+ output = document.getElementById('output');
+ var source = window.webkitURL.createObjectURL(stream);
+ output.src = source;
+ blastbeat_control();
+}
+
+function webcam_no() {
+ alert('no access to the webcam');
+}
+
+navigator.webkitGetUserMedia({video: true, audio: true}, webcam_ok, webcam_no);
+
+ </script>
+
+ </head>
+
+ <body>
+ <video width="320" height="240" id="output" autoplay></video>
+ <canvas width="320" height="240" style="visibility:hidden;position:absolute;top:0px;left:0px;" id="output_canvas"></canvas>
+ </body>
+
+</html>
View
111 examples/chromevideochat/videochat.rb
@@ -0,0 +1,111 @@
+require 'blastbeat'
+require 'json'
+
+# CONFIGURE HERE
+blastbeat = BlastBeat::Node.new('tcp://192.168.173.5:5000', 'FOOBAR1')
+
+# the global hash of sessions
+$sessions = {}
+# the global hash of cookies
+$cookies = {}
+# a global integer for assigning an id to each user
+$users_id = 0
+# send a gratuitous pong (a trick for letting BlastBeat knowing about us as soon as possibile)
+blastbeat.send('', 'pong')
+
+# this class maps to a session/thread
+class BlastBeatSession
+
+ attr_reader :id, :cookie
+
+ def manage_command(body)
+ j = JSON.parse(body)
+ case j['command']
+ when 'text'
+ @blastbeat.send(@sid, 'videochat:websocket', body)
+ when 'join'
+ @blastbeat.send(@sid, 'join', 'videochat')
+ $users_id+=1
+ @id = $users_id
+ @cookie = rand(36**8).to_s(36)
+ $cookies[@cookie] = self
+ users = []
+ for session_id in $sessions.keys
+ next if session_id == @sid
+ users << $sessions[session_id].id
+ end
+ welcome = {'command' => 'welcome', 'id' => @id, 'cookie' => @cookie, 'users' => users }
+ @blastbeat.send(@sid, 'websocket', JSON.generate(welcome))
+ newuser = {'command' => 'newuser', 'id' => @id}
+ @blastbeat.send(@sid, 'videochat:websocket', JSON.generate(newuser))
+ end
+ end
+
+ def run(msg_type, msg_body)
+ # if the message is 'uwsgi' the session just started
+ if msg_type == 'uwsgi'
+ # parse the request (pretty useless here)
+ environ = @blastbeat.uwsgi(msg_body)
+ if environ['PATH_INFO'] == '/control'
+ @type = 'control'
+ elsif environ['PATH_INFO'][0,6] == '/data/'
+ cookie = environ['PATH_INFO'][6, environ['PATH_INFO'].length]
+ if not $cookies.has_key?(cookie)
+ @blastbeat.send(@sid, 'end')
+ $sessions.delete(@sid)
+ return
+ end
+ @type = 'data'
+ end
+ elsif msg_type == 'websocket'
+ # start piping frames
+ if @type == 'data' and msg_body == 'start'
+ @blastbeat.send(@sid, 'join', 'videoframes')
+ @blastbeat.send(@sid, 'noecho', 'videoframes')
+ @blastbeat.send(@sid, 'pipe', 'videoframes:websocket')
+ # a control message
+ # {'command':'text', 'body':'hello'}
+ elsif @type == 'control'
+ manage_command(msg_body)
+ end
+ end
+ end
+
+ def initialize(blastbeat, sid)
+ @blastbeat = blastbeat
+ @sid = sid
+ @type = nil
+ @cookie = nil
+ @id = nil
+ end
+end
+
+# main loop
+while true
+ # dequeue BlastBeat messages
+ sid,msg_type,msg_body = blastbeat.recv
+ # respond to ping
+ if msg_type == 'ping'
+ blastbeat.send(sid, 'pong')
+ next
+ end
+ # respond to end
+ if msg_type == 'end'
+ next unless $sessions.has_key?(sid)
+ byeuser = {'command' => 'byeuser', 'id' => $sessions[sid].id }
+ for user_sid in $sessions.keys
+ blastbeat.send(user_sid, 'websocket', JSON.generate(byeuser))
+ end
+ $cookies.delete( $sessions[sid].cookie )
+ $sessions.delete(sid)
+ next
+ end
+
+ # create a new session if not available
+ if not $sessions.has_key?(sid)
+ $sessions[sid] = BlastBeatSession.new(blastbeat, sid)
+ end
+
+ $sessions[sid].run(msg_type,msg_body)
+
+end

0 comments on commit c59e45e

Please sign in to comment.