Permalink
Browse files

first commit of the videochat example for chrome

  • Loading branch information...
Roberto De Ioris
Roberto De Ioris committed Aug 17, 2012
1 parent ed96a70 commit c59e45e39583c1b9f5af96c769477d693bafe929
Showing with 241 additions and 0 deletions.
  1. +130 −0 examples/chromevideochat/videochat.html
  2. +111 −0 examples/chromevideochat/videochat.rb
@@ -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>
@@ -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.