talking_stick 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Changes.md +5 -0
- data/Guardfile +44 -0
- data/README.md +59 -24
- data/app/assets/images/talking_stick/line-spinner.svg +1 -0
- data/app/assets/images/talking_stick/loading.gif +0 -0
- data/app/assets/javascripts/talking_stick/talking_stick.js.erb +272 -0
- data/app/assets/javascripts/talking_stick/talking_stick/partner.js +89 -28
- data/app/assets/javascripts/talking_stick/talking_stick/rails_signaling.js +24 -6
- data/app/assets/stylesheets/talking_stick/application.css +55 -0
- data/app/controllers/talking_stick/application_controller.rb +6 -0
- data/app/controllers/talking_stick/participants_controller.rb +1 -1
- data/app/controllers/talking_stick/rooms_controller.rb +4 -1
- data/app/models/talking_stick/participant.rb +2 -1
- data/app/models/talking_stick/room.rb +17 -0
- data/app/models/talking_stick/signal.rb +2 -0
- data/app/views/talking_stick/rooms/_form.html.erb +12 -9
- data/app/views/talking_stick/rooms/edit.html.erb +5 -4
- data/app/views/talking_stick/rooms/index.html.erb +29 -22
- data/app/views/talking_stick/rooms/new.html.erb +5 -3
- data/app/views/talking_stick/rooms/show.html.erb +92 -19
- data/config/locales/en.yml +15 -0
- data/config/locales/it.yml +14 -0
- data/db/migrate/20150722200822_add_slug_to_talking_stick_rooms.rb +11 -0
- data/lib/generators/talking_stick/views/USAGE +18 -0
- data/lib/generators/talking_stick/views/views_generator.rb +18 -0
- data/lib/talking_stick/version.rb +1 -1
- data/spec/dummy/app/assets/javascripts/application.js +1 -0
- data/spec/dummy/app/assets/stylesheets/application.css +1 -0
- data/spec/models/talking_stick/participant_spec.rb +1 -1
- data/spec/models/talking_stick/room_spec.rb +32 -2
- data/talking_stick.gemspec +2 -0
- metadata +42 -5
- data/app/assets/javascripts/talking_stick/talking_stick.js +0 -141
- data/app/views/layouts/talking_stick/application.html.erb +0 -14
@@ -1,22 +1,48 @@
|
|
1
|
-
|
1
|
+
<% content_for(:title) { "#{@room.name} Group Conversation" } %>
|
2
|
+
<div class="container-fluid" role="main" id="room" data-room-name="<%= @room.name %>">
|
3
|
+
<div class="row">
|
4
|
+
<div class="col-xs-3">
|
5
|
+
<div class="row">
|
6
|
+
<div class="col-xs-12">
|
7
|
+
<div id="localvideo-container"></div>
|
8
|
+
</div>
|
9
|
+
<div class="col-xs-12">
|
10
|
+
<span class="navbar-brand"><%= @room.name %></span>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
<div class="col-xs-9">
|
15
|
+
<div id="partnervideos"></div>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</div>
|
2
19
|
|
3
|
-
<
|
4
|
-
<
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
<
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
<
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
<%= link_to '
|
20
|
+
<div class="modal fade" role="dialog" id="video-preview">
|
21
|
+
<div class="modal-dialog">
|
22
|
+
<div class="modal-content">
|
23
|
+
<div class="modal-header">
|
24
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
25
|
+
<h3 class="modal-title"><%= t(:joining_room) %> "<%= @room.name %>"</h3>
|
26
|
+
</div>
|
27
|
+
<div class="modal-body">
|
28
|
+
<video id="localvideo" poster="<%= image_path 'talking_stick/line-spinner.svg' %>" autoplay=true></video>
|
29
|
+
<p id="preview_instructions"><%= t(:video_grant_access) %></p>
|
30
|
+
</div>
|
31
|
+
<div class="modal-footer">
|
32
|
+
<button id="connect" type="button" class="btn btn-default btn-primary" data-dismiss="modal" disabled>Join</button>
|
33
|
+
<%= link_to "Exit", :back, class: 'btn btn-default' %>
|
34
|
+
</div>
|
35
|
+
</div><!-- /.modal-content -->
|
36
|
+
</div><!-- /.modal-dialog -->
|
37
|
+
</div><!-- /.modal -->
|
17
38
|
|
18
39
|
<script type="text/javascript">
|
19
40
|
$(document).ready(function() {
|
41
|
+
$('#sim').click(sim);
|
42
|
+
// Attempt to keep the modal from scrolling vertically
|
43
|
+
// 300px is the approximate height of the modal, minus the video
|
44
|
+
$('#video-preview').find('video').height($(window).height() - 300);
|
45
|
+
$('#video-preview').modal({backdrop: 'static', keyboard: false, show: true});
|
20
46
|
var myGuid = TalkingStick.generateGUID();
|
21
47
|
// Use the least-common-denominator, Rails API, for WebRTC setup
|
22
48
|
var options = {
|
@@ -27,14 +53,61 @@ $(document).ready(function() {
|
|
27
53
|
|
28
54
|
var options = {
|
29
55
|
guid: myGuid,
|
30
|
-
localVideo: $('#localvideo'),
|
31
56
|
roomUrl: '<%= room_path %>',
|
32
57
|
signalingEngine: signalingEngine,
|
33
|
-
logLevel: '
|
58
|
+
logLevel: 'trace',
|
34
59
|
};
|
35
60
|
TalkingStick.init(options);
|
36
61
|
|
37
|
-
$('#connect').click(
|
38
|
-
|
62
|
+
$('#connect').click(startSession);
|
63
|
+
$(window).on('talking_stick.local_media_setup', function() {
|
64
|
+
$('#preview_instructions').html('<%= t(:video_intro) %>');
|
65
|
+
$('form#connect input[name="join"]').attr('disabled', false);
|
66
|
+
});
|
39
67
|
});
|
68
|
+
|
69
|
+
function startSession() {
|
70
|
+
$('#localvideo').detach().appendTo('#localvideo-container');
|
71
|
+
$('#localvideo').height('auto');
|
72
|
+
// Gotta restart and re-mute the video after moving it
|
73
|
+
$('#localvideo')[0].play();
|
74
|
+
TalkingStick.connect();
|
75
|
+
};
|
76
|
+
|
77
|
+
function resizeVideos() {
|
78
|
+
var videoCollection = $('#partnervideos video');
|
79
|
+
var numVideos = videoCollection.length;
|
80
|
+
var square = Math.sqrt(numVideos);
|
81
|
+
if (!isInt(square)) {
|
82
|
+
// Round up to the next square
|
83
|
+
square = parseInt(square) + 1;
|
84
|
+
}
|
85
|
+
console.log(square);
|
86
|
+
videoCollection.css('width', (100/square) + "%");
|
87
|
+
};
|
88
|
+
|
89
|
+
function cleanupPartner() {
|
90
|
+
resizeVideos();
|
91
|
+
}
|
92
|
+
|
93
|
+
function sim() {
|
94
|
+
var el = $(document.createElement('video'));
|
95
|
+
el.attr('poster', "<%= image_path 'talking_stick/line-spinner.svg' %>");
|
96
|
+
$('#partnervideos').append(el);
|
97
|
+
TalkingStick.localVideo = $('#localvideo');
|
98
|
+
TalkingStick.trigger('partner.media', el);
|
99
|
+
}
|
100
|
+
|
101
|
+
function isInt(value){
|
102
|
+
if((parseFloat(value) == parseInt(value)) && !isNaN(value)){
|
103
|
+
return true;
|
104
|
+
} else {
|
105
|
+
return false;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
$(window).on('talking_stick.partner.media', resizeVideos);
|
110
|
+
$(window).on('talking_stick.partner.cleanup', cleanupPartner);
|
111
|
+
$(window).resize(resizeVideos);
|
112
|
+
|
40
113
|
</script>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
en:
|
2
|
+
camera: camera
|
3
|
+
destroy: Destroy
|
4
|
+
edit: Edit
|
5
|
+
join: Join
|
6
|
+
last_used: Last Used
|
7
|
+
last_used_never: Never
|
8
|
+
listing_rooms: Listing Rooms
|
9
|
+
microphone: microphone
|
10
|
+
name: Name
|
11
|
+
new_room: New Room
|
12
|
+
show: Show
|
13
|
+
your_name: Your name
|
14
|
+
video_grant_access: To join this conversation you'll need to grant access to the camera and microphone.
|
15
|
+
video_intro: Put on pants (optional), check your hair (required), and press "Join" when you're ready to start!
|
@@ -0,0 +1,14 @@
|
|
1
|
+
it:
|
2
|
+
camera: fotocamera
|
3
|
+
destroy: Distruggere
|
4
|
+
edit: Modifica
|
5
|
+
join: Unirsi
|
6
|
+
last_used: Ultimo Uso
|
7
|
+
listing_rooms: Lista Camere
|
8
|
+
microphone: microfono
|
9
|
+
name: Nome
|
10
|
+
new_room: Creo Camere
|
11
|
+
show: Mostrare
|
12
|
+
your_name: Il tuo nome
|
13
|
+
video_grant_access: Per partecipare a questa conversazione è necessario concedere l'accesso alla videocamera e al microfono.
|
14
|
+
video_intro: Indossare pantaloni (opzionale), controlla i tuoi capelli (richiesto), e premere "Unirsi" quando si è pronti per iniziare!
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class AddSlugToTalkingStickRooms < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
add_column :talking_stick_rooms, :slug, :string
|
4
|
+
# Add slugs to the existing rooms
|
5
|
+
TalkingStick::Room.all.map &:save
|
6
|
+
end
|
7
|
+
|
8
|
+
def down
|
9
|
+
remove_column :talking_stick_rooms, :slug
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Description:
|
2
|
+
Creates default participant and room views available for customization
|
3
|
+
|
4
|
+
Run:
|
5
|
+
rails generate talking_stick:views
|
6
|
+
|
7
|
+
This will create the following default views:
|
8
|
+
app/views/talking_stick/participants/_form.html.erb
|
9
|
+
app/views/talking_stick/participants/edit.html.erb
|
10
|
+
app/views/talking_stick/participants/index.html.erb
|
11
|
+
app/views/talking_stick/participants/new.html.erb
|
12
|
+
app/views/talking_stick/participants/show.html.erb
|
13
|
+
|
14
|
+
app/views/talking_stick/rooms/_form.html.erb
|
15
|
+
app/views/talking_stick/rooms/edit.html.erb
|
16
|
+
app/views/talking_stick/rooms/index.html.erb
|
17
|
+
app/views/talking_stick/rooms/new.html.erb
|
18
|
+
app/views/talking_stick/rooms/show.html.erb
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class TalkingStick::ViewsGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path('../../../../../app/views/talking_stick', __FILE__)
|
3
|
+
|
4
|
+
def generate_participant_views
|
5
|
+
directory "participants", "#{paste_path}/participants"
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_room_views
|
9
|
+
directory "rooms", "#{paste_path}/rooms"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def paste_path
|
15
|
+
'app/views/talking_stick'
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -1,7 +1,37 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
module TalkingStick
|
4
4
|
RSpec.describe Room, type: :model do
|
5
|
-
|
5
|
+
describe "#validation" do
|
6
|
+
subject { described_class.new(name: "Test") }
|
7
|
+
|
8
|
+
it "automatically sluggifys the room name" do
|
9
|
+
expect {
|
10
|
+
subject.valid?
|
11
|
+
}.to change{ subject.slug }.from(nil).to("test")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "allows the slug to be set by manually" do
|
15
|
+
subject.slug = "dont_touch"
|
16
|
+
expect {
|
17
|
+
subject.valid?
|
18
|
+
}.to_not change{ subject.slug }.from("dont_touch")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".find_or_create" do
|
23
|
+
it "uses a room if it already exists" do
|
24
|
+
existing = described_class.create(name: "Test")
|
25
|
+
|
26
|
+
expect(described_class.find_or_create(slug: "test")).to eq existing
|
27
|
+
expect(described_class.count).to eq 1
|
28
|
+
end
|
29
|
+
|
30
|
+
it "creates a room if the slug doesn't exist" do
|
31
|
+
expect {
|
32
|
+
described_class.find_or_create(slug: "Test")
|
33
|
+
}.to change(described_class, :count).by(1)
|
34
|
+
end
|
35
|
+
end
|
6
36
|
end
|
7
37
|
end
|
data/talking_stick.gemspec
CHANGED
@@ -21,6 +21,8 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_dependency 'jquery-rails', '~> 4.0'
|
22
22
|
|
23
23
|
s.add_development_dependency 'sqlite3'
|
24
|
+
s.add_development_dependency 'guard'
|
25
|
+
s.add_development_dependency 'guard-rspec'
|
24
26
|
s.add_development_dependency 'rspec-rails'
|
25
27
|
s.add_development_dependency 'capybara'
|
26
28
|
s.add_development_dependency 'factory_girl_rails'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: talking_stick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Klang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rspec-rails
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -104,13 +132,17 @@ extra_rdoc_files: []
|
|
104
132
|
files:
|
105
133
|
- ".gitignore"
|
106
134
|
- ".rspec"
|
135
|
+
- Changes.md
|
107
136
|
- Gemfile
|
137
|
+
- Guardfile
|
108
138
|
- LICENSE.md
|
109
139
|
- README.md
|
110
140
|
- Rakefile
|
111
141
|
- app/assets/images/talking_stick/.keep
|
142
|
+
- app/assets/images/talking_stick/line-spinner.svg
|
143
|
+
- app/assets/images/talking_stick/loading.gif
|
112
144
|
- app/assets/javascripts/talking_stick/application.js
|
113
|
-
- app/assets/javascripts/talking_stick/talking_stick.js
|
145
|
+
- app/assets/javascripts/talking_stick/talking_stick.js.erb
|
114
146
|
- app/assets/javascripts/talking_stick/talking_stick/partner.js
|
115
147
|
- app/assets/javascripts/talking_stick/talking_stick/rails_signaling.js
|
116
148
|
- app/assets/stylesheets/talking_stick/application.css
|
@@ -121,7 +153,6 @@ files:
|
|
121
153
|
- app/models/talking_stick/participant.rb
|
122
154
|
- app/models/talking_stick/room.rb
|
123
155
|
- app/models/talking_stick/signal.rb
|
124
|
-
- app/views/layouts/talking_stick/application.html.erb
|
125
156
|
- app/views/talking_stick/participants/_form.html.erb
|
126
157
|
- app/views/talking_stick/participants/edit.html.erb
|
127
158
|
- app/views/talking_stick/participants/index.html.erb
|
@@ -133,10 +164,15 @@ files:
|
|
133
164
|
- app/views/talking_stick/rooms/new.html.erb
|
134
165
|
- app/views/talking_stick/rooms/show.html.erb
|
135
166
|
- bin/rails
|
167
|
+
- config/locales/en.yml
|
168
|
+
- config/locales/it.yml
|
136
169
|
- config/routes.rb
|
137
170
|
- db/migrate/20150510181337_create_talking_stick_rooms.rb
|
138
171
|
- db/migrate/20150510182258_create_talking_stick_participants.rb
|
139
172
|
- db/migrate/20150511005922_create_talking_stick_signals.rb
|
173
|
+
- db/migrate/20150722200822_add_slug_to_talking_stick_rooms.rb
|
174
|
+
- lib/generators/talking_stick/views/USAGE
|
175
|
+
- lib/generators/talking_stick/views/views_generator.rb
|
140
176
|
- lib/talking_stick.rb
|
141
177
|
- lib/talking_stick/engine.rb
|
142
178
|
- lib/talking_stick/version.rb
|
@@ -207,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
243
|
version: '0'
|
208
244
|
requirements: []
|
209
245
|
rubyforge_project:
|
210
|
-
rubygems_version: 2.
|
246
|
+
rubygems_version: 2.2.2
|
211
247
|
signing_key:
|
212
248
|
specification_version: 4
|
213
249
|
summary: Easy group-based video conversations for Rails with WebRTC
|
@@ -256,3 +292,4 @@ test_files:
|
|
256
292
|
- spec/models/talking_stick/participant_spec.rb
|
257
293
|
- spec/models/talking_stick/room_spec.rb
|
258
294
|
- spec/spec_helper.rb
|
295
|
+
has_rdoc:
|
@@ -1,141 +0,0 @@
|
|
1
|
-
var TalkingStick = (function(self) {
|
2
|
-
self.guid = undefined;
|
3
|
-
self.myStream = undefined;
|
4
|
-
self.joinedAt = undefined;
|
5
|
-
self._options = {
|
6
|
-
media: { audio: true, video: true },
|
7
|
-
localVideo: undefined, // Set this to the DOM element where video should be rendered
|
8
|
-
logLevel: 'error',
|
9
|
-
};
|
10
|
-
|
11
|
-
self.logLevels = [
|
12
|
-
'trace',
|
13
|
-
'debug',
|
14
|
-
'notice',
|
15
|
-
'warning',
|
16
|
-
'error',
|
17
|
-
];
|
18
|
-
|
19
|
-
self.init = function(options) {
|
20
|
-
$.extend(self._options, options);
|
21
|
-
|
22
|
-
self.logLevelIdx = self.logLevels.indexOf(self._options.logLevel);
|
23
|
-
self.partners = {};
|
24
|
-
self.guid = self._options.guid || self.generateGUID();
|
25
|
-
self.signalingEngine = self._options.signalingEngine;
|
26
|
-
self.setupLocalVideo();
|
27
|
-
self.log('notice', 'TalkingStick initialized.');
|
28
|
-
};
|
29
|
-
|
30
|
-
self.log = function() {
|
31
|
-
var level = arguments[0];
|
32
|
-
var levelIdx = self.logLevels.indexOf(level);
|
33
|
-
if (levelIdx >= self.logLevelIdx) {
|
34
|
-
var args = Array.prototype.slice.call(arguments, 1);
|
35
|
-
args.unshift('[' + level + ']');
|
36
|
-
switch(levelIdx) {
|
37
|
-
case 4:
|
38
|
-
console.error.apply(console, args);
|
39
|
-
break;
|
40
|
-
case 3:
|
41
|
-
console.warn.apply(console, args);
|
42
|
-
break;
|
43
|
-
default:
|
44
|
-
console.log.apply(console, args);
|
45
|
-
break;
|
46
|
-
}
|
47
|
-
}
|
48
|
-
}
|
49
|
-
|
50
|
-
self.setupLocalVideo = function() {
|
51
|
-
var localVideo = $(self._options.localVideo);
|
52
|
-
|
53
|
-
self.prepareVideoElement(localVideo);
|
54
|
-
|
55
|
-
self.log('debug', 'Requesting user consent to access to input devices');
|
56
|
-
navigator.getUserMedia(self._options.media, function(stream) {
|
57
|
-
self.log('debug', 'User has granted access to input devices');
|
58
|
-
self.myStream = stream;
|
59
|
-
|
60
|
-
// The JS API requires the raw DOM element, not a jQuery wrapper
|
61
|
-
attachMediaStream(localVideo[0], stream);
|
62
|
-
}, self.errorCallback);
|
63
|
-
};
|
64
|
-
|
65
|
-
self.connect = function() {
|
66
|
-
// Tell the server we're ready to start contacting the other participants
|
67
|
-
var data = {
|
68
|
-
participant: {
|
69
|
-
guid: self.guid,
|
70
|
-
}
|
71
|
-
}
|
72
|
-
$.post(self._options.roomUrl + '/participants.json', data)
|
73
|
-
.success(function(data) {
|
74
|
-
self.log('notice', 'TalkingStick connected to the room.');
|
75
|
-
self.joinedAt = new Date(data.joined_at);
|
76
|
-
self.signalingEngine.connected();
|
77
|
-
})
|
78
|
-
.fail(function() { self.ajaxErrorLog('Error joining the room', arguments) });
|
79
|
-
};
|
80
|
-
|
81
|
-
|
82
|
-
self.errorCallback = function(error) {
|
83
|
-
self.log('error', error);
|
84
|
-
};
|
85
|
-
|
86
|
-
/*
|
87
|
-
* participant.guid
|
88
|
-
* participant.joined_at
|
89
|
-
*/
|
90
|
-
self.addPartner = function(participant) {
|
91
|
-
self.log('debug', 'Adding new partner to this conversation', participant);
|
92
|
-
var partnerVideo = document.createElement('video');
|
93
|
-
self.prepareVideoElement(partnerVideo);
|
94
|
-
$('#partnerVideos').append(partnerVideo);
|
95
|
-
var options = {
|
96
|
-
videoElement: partnerVideo,
|
97
|
-
signalingEngine: self.signalingEngine,
|
98
|
-
}
|
99
|
-
|
100
|
-
partner = new TalkingStick.Partner(participant, options);
|
101
|
-
self.partners[participant.guid] = partner;
|
102
|
-
|
103
|
-
partner.connect(self.myStream);
|
104
|
-
|
105
|
-
if (partner.joinedAt < TalkingStick.joinedAt) {
|
106
|
-
self.log('trace', 'Sending Offer to', partner.guid);
|
107
|
-
// Send Offers to partners who joined before us.
|
108
|
-
// Expect partners who join after us to send us Offers.
|
109
|
-
partner.sendOffer();
|
110
|
-
}
|
111
|
-
|
112
|
-
return partner;
|
113
|
-
};
|
114
|
-
|
115
|
-
self.prepareVideoElement = function(el) {
|
116
|
-
el = $(el);
|
117
|
-
|
118
|
-
// Ensure video streams play as soon as they are attached
|
119
|
-
el.attr('autoplay', true);
|
120
|
-
|
121
|
-
// Prevent local audio feedback
|
122
|
-
el.attr('muted', true);
|
123
|
-
};
|
124
|
-
|
125
|
-
self.generateGUID = function () {
|
126
|
-
function s4() {
|
127
|
-
return Math.floor((1 + Math.random()) * 0x10000)
|
128
|
-
.toString(16)
|
129
|
-
.substring(1);
|
130
|
-
}
|
131
|
-
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
132
|
-
s4() + '-' + s4() + s4() + s4();
|
133
|
-
};
|
134
|
-
|
135
|
-
self.ajaxErrorLog = function(message, ajaxFailArgs) {
|
136
|
-
// ajaxFailArgs: 0: jqXHR; 1: textStatus; 2: errorThrown
|
137
|
-
self.log('error', message + ':', ajaxFailArgs[2]);
|
138
|
-
}
|
139
|
-
|
140
|
-
return self;
|
141
|
-
}(TalkingStick || {}));
|