Compare commits

..

457 Commits
319 ... 628

Author SHA1 Message Date
paweldomas
a2b43843b7 Updates app.bundle.js 2015-08-24 12:00:40 +02:00
paweldomas
2f03a0a7fe Fixes broken last-N 2015-08-24 11:53:13 +02:00
paweldomas
4c2f0d3600 Removed duplicated code for adding video thumbnail's hover handler. 2015-08-24 11:53:12 +02:00
paweldomas
a8a0945d73 Moves method for selecting thumbnail's video element from videolayout to SmallVideo. Fixes issue with muted audio in IE after switching between thumbnails. 2015-08-24 11:53:11 +02:00
paweldomas
a7048fba06 Implements HTTP POST query for fetching app configuration. 2015-08-24 11:53:10 +02:00
Boris Grozev
7b35dd89bb Updates the external api docs. 2015-08-20 15:00:56 -05:00
Boris Grozev
3561204bb5 Allows to overwrite config and interfaceConfig options through the
external API.
2015-08-20 14:57:05 -05:00
ibauersachs
ee50d07dc3 Commit from translate.jitsi.org by user ibauersachs.: 172 of 173 strings translated (0 fuzzy). 2015-08-19 19:58:21 +00:00
ibauersachs
9ec4bc91fc Commit from translate.jitsi.org by user ibauersachs.: 173 of 173 strings translated (0 fuzzy). 2015-08-19 19:58:06 +00:00
Ingo Bauersachs
88071e5258 Add Slovenian (sl) 2015-08-19 21:54:00 +02:00
paweldomas
e79d476d89 Updates app.bundle.js 2015-08-19 18:27:09 +02:00
paweldomas
0fe4999beb Use fadeTo instead of fadeIn/fadeOut to avoid having display: none on large video which causes issues when Temasys plugin is used. 2015-08-19 18:23:18 +02:00
paweldomas
ae96b9f365 Fixes issue in IE where click events on local video thumbnail are captured by local audio object created by Temasys plugin on stream attach. 2015-08-19 18:23:08 +02:00
paweldomas
922d0bd512 New adapter.js for Temasys plugin. 2015-08-19 18:22:07 +02:00
paweldomas
9a7bc4ebab Fixes issue with returning from shared document view. Calls show() before fadeOut() on large video to avoid situation when we end up with black screen and are unable to select new video. Updates app.bundle.js. 2015-08-19 10:55:35 +02:00
damencho
2081757ba1 Enables stats in FF. 2015-08-18 16:42:47 -05:00
jitsi-pootle
e9c9fc5e69 New files added from translate.jitsi.org based on templates 2015-08-18 12:50:42 +00:00
paweldomas
562761196d Updates app.bundle.js 2015-08-18 13:27:29 +02:00
paweldomas
420514b921 Temasys adapter.js ver 0.12.0 with fix for setInterval included 2015-08-18 13:22:17 +02:00
paweldomas
eb63b24a9a Fixes fadeIn/fadeOut large video transitions in Safari. Enables animation on video resize when switching between camera and screen video. 2015-08-18 13:19:54 +02:00
paweldomas
c8bbded994 Removes accidentally committed debug message. 2015-08-18 13:19:44 +02:00
damencho
2a2702c13a Adds params for enabling fake devices on firefox. 2015-08-17 17:05:03 -05:00
Boris Grozev
5fc868ee96 Updates app.bundle.js. 2015-08-17 16:17:47 -05:00
Boris Grozev
502eab7278 Only update the "start muted" settings on precense from a moderator. 2015-08-17 16:17:15 -05:00
Boris Grozev
332aafbe20 Documents some of the XMPP events. Renames some of them. 2015-08-17 16:17:03 -05:00
Boris Grozev
d5258e6197 Remove a double variable declaration. 2015-08-17 16:17:01 -05:00
Boris Grozev
9cc9e6132c Add RTCBrowserType.isAndroid(). 2015-08-17 16:16:34 -05:00
hristoterezov
f60c1d9751 Removes the minimum width and height of the external API iframe in "film strip only" mode. 2015-08-17 13:46:26 -05:00
Boris Grozev
5d32318d93 Updates app.bundle.js. 2015-08-14 10:49:13 -05:00
Boris Grozev
fee8482bae Updates sdp-transform to 1.4.1. 2015-08-14 10:48:21 -05:00
paweldomas
f2b5cdbfb8 Updates app.bundle.js. 2015-08-14 17:06:50 +02:00
paweldomas
60afe2d202 Fixes issue with display name event not being fired on Safari/IE 2015-08-14 17:04:30 +02:00
paweldomas
18f03e296b Fixes broken input fields in Safari. 2015-08-14 17:03:58 +02:00
paweldomas
5cd9db1b6a Missing semicolon... 2015-08-14 17:02:19 +02:00
bgrozev
f83404a99e Merge pull request #341 from pstros/fix-comment
Change the comment to fix npm install
2015-08-13 16:00:56 -05:00
Devin Wilson
7c1ba9242b Change the comment to fix npm install 2015-08-13 08:31:50 -06:00
ibauersachs
bfcc587047 Commit from translate.jitsi.org by user ibauersachs.: 172 of 172 strings translated (0 fuzzy). 2015-08-13 07:35:17 +00:00
Boris Grozev
e90d8f5531 Updates app.bundle.js. 2015-08-12 21:54:15 +02:00
Boris Grozev
59033aab28 Adds what will hopefully be treated as a comment by all npm versions to package.json. 2015-08-12 21:52:49 +02:00
Boris Grozev
7f1eb617c3 Uses npm packeges for socket.io and jsSHA. 2015-08-12 21:50:42 +02:00
hristoterezov
fd7e8c9162 Merge pull request #338 from gerges/issue/toolbar-refactor
Refactors toolbar
2015-08-12 13:55:50 -05:00
Issac Gerges
51e886142b Ensure hangup button selector is specific enough to apply red color and custom size 2015-08-12 13:36:24 -05:00
Issac Gerges
dcc206b2b4 Update non-container toolbar items to be set to inline-block when shown 2015-08-12 13:06:55 -05:00
Issac Gerges
da75e17ff5 Merge remote-tracking branch 'origin/master' into issue/toolbar-refactor 2015-08-12 13:05:20 -05:00
paweldomas
8fea9b76ee Updates app.bundle.js 2015-08-12 14:23:43 +02:00
paweldomas
cb024be2d6 Fixes locking at WaitForPluginReady with Temasys plugin install detection. 2015-08-12 14:21:08 +02:00
paweldomas
4c4e99c51a Updates Temasys adapter.screenshare.js. Browser restart is no longer required after plugin install. 2015-08-12 14:20:51 +02:00
paweldomas
4b8bc398dd Fixes issue with black video when new stream element is inserted after the old one. 2015-08-12 14:20:44 +02:00
paweldomas
466e7dcc91 Fixes crash in LocalSSRCReplacement when null localDescription is passed. 2015-08-12 14:20:37 +02:00
Issac Gerges
de30ce0f5c Merge remote-tracking branch 'origin/master' into issue/toolbar-refactor 2015-08-11 13:30:08 -05:00
Issac Gerges
fc6f5717cb Refactor toolbar to add separators via css and remove unneeded containers 2015-08-11 13:24:53 -05:00
paweldomas
b680ecd2ff Renames getLargeVideoJid to getLargeVideoResource and updates app.bundle.js. 2015-08-11 13:12:55 +02:00
Boris Grozev
2bea2eec74 Updates app.bundle.js. 2015-08-10 16:54:51 -05:00
Boris Grozev
f52b1380ee Continues to separate JingleSessionPC. 2015-08-10 16:38:35 -05:00
Boris Grozev
baf720c553 Starts to abstract JingleSession. 2015-08-10 15:58:50 -05:00
Boris Grozev
deaff6af5b Executes a local (git-ignored) script on "make deploy". 2015-08-10 13:25:21 -05:00
Boris Grozev
6ca1e131af Renames JingleSession to JingleSessionPC. 2015-08-10 13:22:05 -05:00
Boris Grozev
57b9aeb38c Inlines a method for clarity/simplicity. 2015-08-10 13:14:12 -05:00
Boris Grozev
cc20a4d776 Removes an unused variable. 2015-08-10 13:02:39 -05:00
Boris Grozev
fd404b8465 Supports setting interfaceConfig options via URL params. Renames config.filmStripOnly to interfaceConfig.filmStripOnly. 2015-08-10 12:59:12 -05:00
damencho
cc29df6376 Adds params for enabling rec on entering the conference. 2015-08-07 10:31:48 -05:00
paweldomas
44136e8a55 Updates app.bundle.js. 2015-08-07 12:59:43 +02:00
paweldomas
fb875423a9 Fixes SSRC=1 issue. Renames VideoSSRCHack to LocalSSRCReplacement. 2015-08-07 12:58:12 +02:00
paweldomas
ab4c29eddc Fixes video mute in Firefox. Disables VideoSSRCHack for Firefox by default. 2015-08-07 12:58:03 +02:00
paweldomas
95e964a089 Fixes bugs in VideoSSRCHack. Additional log messages. 2015-08-07 12:57:56 +02:00
paweldomas
c288aa6e84 Fixes issue with toggling video mute in FF caused by the fact that it has no 'onended' callback handling implemented. 2015-08-07 12:57:48 +02:00
paweldomas
e5d03d1d11 Fixes GUM failure with the latest FF nightly plus cleanup. 2015-08-07 12:57:43 +02:00
hristoterezov
59147f059d Adds a parameter to API constructor that enables film strip only mode. 2015-08-06 19:01:21 -05:00
hristoterezov
7793d65a99 Renames config.minimized to config.filmStripOnly . 2015-08-06 18:59:51 -05:00
hristoterezov
b77791f4b2 Implements minimized mode - only the thumbnails are visible. 2015-08-06 18:34:40 -05:00
damencho
4092d67853 Updates use of recording states, add some information texts and notifications. 2015-08-05 22:18:45 -05:00
paweldomas
2ea6be9b2c Updates app.bundle.js. 2015-08-05 14:12:10 +02:00
paweldomas
74e7507a73 Re-uses SSRC of the first video stream created for any streams created in future. Does video mute and switching to the screen stream without 'source-add'/'source-remove' signaling. Moves video type signaling from Jingle to MUC presence. 2015-08-05 14:10:08 +02:00
bgrozev
9a31fa3d63 Fixes a bug reported by Pawel Domas. 2015-08-04 09:26:16 -05:00
Дамян Минков
fd44cfa7a0 Typo. 2015-08-03 17:18:32 -05:00
yanas
ab570d63fa Fixes this reference. 2015-08-03 14:08:42 -05:00
Boris Grozev
b4983b2566 Merge branch 'rename-mute-to-toggle' 2015-08-03 11:46:55 -05:00
bgrozev
fdb470d22f Merge pull request #330 from jitsi/remove-rtcp-mux-from-config
Removes the useBundle and useRtcpMux options from config.js. These are
2015-08-03 11:32:43 -05:00
bgrozev
c163a22415 Merge pull request #331 from jitsi/enable-noice-reduction
Re-enables video noise reduction (removes a workaround for M37).
2015-08-03 11:32:38 -05:00
bgrozev
1dea41d3d4 Merge pull request #328 from jitsi/verify-full-jid-for-jingle
Verify full (and not bare) JID of the Jingle sender, since everyone i…
2015-08-03 11:32:32 -05:00
yanas
9d321df49e Adds javadoc for previous commit. 2015-08-03 11:21:56 -05:00
yanas
d92d8e8299 Some additional error handling. 2015-08-03 11:00:16 -05:00
bgrozev
6b48bf0d84 Merge pull request #299 from marclaporte/patch-3
Minor rewording, fixing typos, and improving grammar
2015-08-03 10:48:36 -05:00
bgrozev
de82a8e32b Merge pull request #310 from marclaporte/patch-4
fix typo
2015-08-03 10:46:49 -05:00
bgrozev
fe4661078e Update a license mention in README.md 2015-08-03 10:40:20 -05:00
bgrozev
46554f75a2 Merge pull request #313 from marclaporte/patch-6
fix typo and minor rewording
2015-08-03 10:39:27 -05:00
Boris Grozev
dbd68d2daa Updates app.bundle.js. 2015-07-31 15:26:03 -05:00
Boris Grozev
67a52e6f72 Cleanup and formatting fixes in the UI module. 2015-07-31 14:45:40 -05:00
Boris Grozev
2c790f86ad More formatting fixes. 2015-07-31 14:28:23 -05:00
Boris Grozev
fd5a739f3c Minor formatting fixes, avoid using a global variable. 2015-07-31 14:25:48 -05:00
Boris Grozev
35e46a2cfa Fix a typo. 2015-07-31 14:23:48 -05:00
Boris Grozev
24f9a1c8d1 Abstract browser type checks. 2015-07-31 14:23:36 -05:00
Boris Grozev
71229bdba9 Minor formatting fixes. 2015-07-31 14:23:27 -05:00
Boris Grozev
84a8d00234 Renames functions for the sake of clarity. 2015-07-31 14:22:42 -05:00
Boris Grozev
ee95e99f57 Cleanup: removes an unused function. 2015-07-31 14:22:32 -05:00
Boris Grozev
be6d7af377 Cleanup: fixes to style, typos and documentation. 2015-07-31 14:22:20 -05:00
paweldomas
b8548757b4 Updates app.bundle.js 2015-07-31 15:51:45 +02:00
paweldomas
df932bb89f Fixes typo in variable name(and a crash on undefined). 2015-07-31 15:50:02 +02:00
paweldomas
50e67a0658 Prevents from duplicating existing SSRCs with 'source-add' in remote description. 2015-07-31 15:49:53 +02:00
damencho
3289f6f68e Updates nginx detection during configuration. 2015-07-30 14:59:31 -05:00
damencho
a701821698 Fixes updates on distributions that are missing openjdk 8. 2015-07-30 14:36:44 -05:00
bgrozev
5588bcd167 Updates another call to setMute(). 2015-07-30 14:24:44 -05:00
bgrozev
a7058747ac Updates a call to setMute(). 2015-07-30 10:51:50 -05:00
paweldomas
5017fed28e Updates app.bundle.js. 2015-07-30 14:23:33 +02:00
paweldomas
8469a282c1 Fixes inconsistent local video muted status. 2015-07-30 14:21:32 +02:00
paweldomas
2ffe178456 Fixes issue with missing avatar for Jigasi user. Fixes issue with avatar not being displayed when user has no video. Removed duplicated logic for checking video muted status(removed from LargeVideo which exists in SmallVideo). 2015-07-30 14:21:31 +02:00
paweldomas
349f196664 "wait for remote video" loop no longer exists so no need to set 'removed' flag on video. 2015-07-30 14:21:31 +02:00
paweldomas
f2bd76ac93 Fixes issue with video thumbnail not being removed for users without camera and mic. 2015-07-30 14:21:30 +02:00
hristoterezov
baee96734c Moves LargeVideo html dependancies in LargeVideo.js 2015-07-29 14:39:09 -05:00
Boris Grozev
4cac7ac97f Re-enables video noise reduction (removes a workaround for M37). 2015-07-29 11:28:58 -05:00
Boris Grozev
46a17948d0 Renames the external API commands from "mute{Audio,Video}" to "toggle{Audio,Video}" since what they do is "toggle". 2015-07-29 11:28:37 -05:00
Boris Grozev
79ac1e800f Verify full (and not bare) JID of the Jingle sender, since everyone in the MUC has the same bare JID. 2015-07-29 11:27:12 -05:00
Boris Grozev
b0c81985d4 Removes the useBundle and useRtcpMux options from config.js. These are
now fully supported by jitsi-videobridge and all browsers which we
support (and if we need to enable them conditionally because of browser
compatibility in the future, we should do it based on run-time browser
detection.)
2015-07-29 11:26:50 -05:00
damencho
f8b7d048b0 Updates meet default installation. Removes nginx dependency and adds openjdk-8 in order to activate multiplexing inside jvb and use its jetty to serve meet. Updates will not touch current configuration which will continue using nginx. 2015-07-27 16:07:22 -05:00
paweldomas
dc19620edc Updates app.bundle 2015-07-23 11:25:39 +02:00
paweldomas
4aa6fbc4b9 Switches to the last visible video correctly when current speaker leaves the conference. 2015-07-23 11:24:13 +02:00
hristoterezov
03902de511 Merge pull request #323 from pstros/remove-ui-refs-from-xmpp-upstream
Remove UI refs from xmpp and RTC
2015-07-22 18:19:15 -05:00
Devin Wilson
d44aed2c11 Remove duplicate handler 2015-07-22 13:38:28 -06:00
Devin Wilson
9bbf17e541 Remove UI references from RTC 2015-07-22 13:37:34 -06:00
Devin Wilson
156b218bfc Remove UI references from xmpp-related modules
Conflicts:
	modules/xmpp/JingleSession.js
	service/xmpp/XMPPEvents.js
2015-07-22 13:37:34 -06:00
hristoterezov
ca5a1001a1 Fixes issue with parsing "extrernal" hash parameter. 2015-07-22 13:26:07 -05:00
paweldomas
1010a56899 Updates app.bundle.js. 2015-07-22 14:00:34 +02:00
paweldomas
0902cbb164 Fixes problems with Temasys plugin support in Safari. 2015-07-22 13:58:51 +02:00
paweldomas
9b4ee7c0c5 Fixes video switching issue. 'oldSmallVideo' field is no longer used as it is might be overwritten before fadeOut 'complete' callback of #largeVideo is called(and we miss UI update on it). 2015-07-22 13:58:39 +02:00
Boris Grozev
2545441def Updates app.bundle.js 2015-07-21 17:11:29 -05:00
Boris Grozev
9206b470ef Re-orders a=ssrc lines before calling SRD (fixes SRD failures when rtx/FID groups are in use). 2015-07-21 16:56:48 -05:00
Boris Grozev
cb7ff545b6 Abstracts unified and plan B checks. 2015-07-21 16:56:48 -05:00
bgrozev
c149b22ac2 Updates the license in package.json 2015-07-21 13:57:31 -05:00
paweldomas
2d522f735e Updates app.bundle 2015-07-21 10:17:59 +02:00
paweldomas
bc935eb5dc Fixes broken video in FF 2015-07-21 10:16:18 +02:00
paweldomas
c3548eb866 Fixes issues with invalid avatars and problems with switching between videos. 2015-07-20 19:32:04 +02:00
hristoterezov
a66459e206 Changes the conference id for callstats API. 2015-07-17 14:45:30 -05:00
Devin Wilson
829d8dab16 Fix CallStats require and initialize API commands and keyboard shortcuts in init method 2015-07-17 09:57:59 -06:00
Boris Grozev
072905b7cd Updates app.bundle.js. 2015-07-15 17:31:09 -05:00
Boris Grozev
7e1c7d19d6 Advertises RFC4588 support for browsers that support it. 2015-07-15 16:47:36 -05:00
hristoterezov
a3886cc56c Focuses the enter display name field. 2015-07-15 13:31:39 -05:00
paweldomas
b22ddea71c Updates app.bundle 2015-07-15 14:55:30 +02:00
paweldomas
b5135c455e Updates strophe.js to 1.2.2 2015-07-15 14:45:08 +02:00
paweldomas
7776bc92a4 Undefined method... 2015-07-15 14:44:16 +02:00
paweldomas
420bbe136c Fixes call to undefined method(which fixes crash on lastN switch and when clicking contact on the contactlist). 2015-07-15 14:01:36 +02:00
paweldomas
2b103288c2 Removes old hack 2015-07-15 12:16:04 +02:00
paweldomas
17f245df5e Fixes local video thumbnail being replaced with an avatar when lastN enabled. 2015-07-15 12:14:34 +02:00
paweldomas
61f4674a28 Fixes direct access to 'src' attribute of 'video' element. 2015-07-15 12:12:07 +02:00
paweldomas
879fb9a590 Adds getters for peer video selectors and simplifies the code a little bit. 2015-07-15 12:11:58 +02:00
paweldomas
a1b0677442 Moves SSRC owner signaling from MUC presence to Jingle. 2015-07-14 15:35:13 +02:00
paweldomas
d74a356a40 Removes extra separator from the toolbar when desktopsharing is not available. 2015-07-14 15:09:55 +02:00
Boris Grozev
609029bc93 Updates app.bundle.js 2015-07-10 22:40:23 +02:00
Boris Grozev
f29fc0f8e7 Fix building on a case-sensitive file system. 2015-07-10 22:39:09 +02:00
Boris Grozev
d430074ed8 Remove a superfluous var declaration. 2015-07-10 22:38:27 +02:00
paweldomas
ae759fab5b Adds IE support through Temasys WebRTC plugin. 2015-07-10 11:57:20 +02:00
ibauersachs
cd6928d770 Commit from translate.jitsi.org by user ibauersachs.: 168 of 168 strings translated (0 fuzzy). 2015-07-09 21:47:06 +00:00
ibauersachs
94f2ace120 Commit from translate.jitsi.org by user ibauersachs.: 167 of 167 strings translated (0 fuzzy). 2015-07-09 21:42:09 +00:00
paweldomas
6ec7be09f2 Fixes issue with switching to the screen stream before conference starts(when we're still alone in the room). 2015-07-09 15:04:08 +02:00
paweldomas
5c136f1da6 Updates app.bundle.js 2015-07-06 12:50:43 +02:00
paweldomas
9268da65c2 Removes 'wait for remote video' hack 2015-07-06 12:24:59 +02:00
paweldomas
3fc6da1ed5 Fixes issue with invalid number of conference participants displayed on the contact list indicator. 2015-07-06 12:24:40 +02:00
Marc Laporte
c1226d8c07 fix typo and minor rewording 2015-07-04 18:21:27 -04:00
hristoterezov
62a731e244 Fixes typo in translation module interface. 2015-07-03 12:34:05 +03:00
hristoterezov
47b6355d66 Implements functionality that forces the user to enter display name. 2015-07-02 17:04:37 +03:00
hristoterezov
1e0bf42203 Removes unused methods from VideoLayout. 2015-07-01 11:14:21 +03:00
hristoterezov
6235ff163e Fixes audio mute. 2015-06-30 14:34:11 +03:00
hristoterezov
f11c3b94ed Moves some methods from avatar to videolayout. 2015-06-29 17:24:21 +03:00
Marc Laporte
dd8371f49c fix typo 2015-06-28 09:47:13 -04:00
hristoterezov
506312ac95 Integrates callstats.io API. 2015-06-26 15:32:40 +03:00
Damian Minkov
239f271caf Handles chat message timestamps according to XEP-0091 and updates app.bundle.js. 2015-06-23 16:28:46 +03:00
Zalmoxisus
7a54537bee Fixes chat messages timestamp according to XEP-0203. Fixes #305. 2015-06-23 16:14:06 +03:00
hristoterezov
6a492d96c2 Refactors VideoLayout.js. 2015-06-23 11:00:46 +03:00
paweldomas
38b180ad81 Adds scrollbar to the contact list. 2015-06-19 15:45:39 +02:00
Emil Ivov
c8c0c8b1ab Update README.md 2015-06-19 00:53:22 +02:00
Emil Ivov
2b692f5a0a Setting new distribution license 2015-06-18 22:36:31 +02:00
Emil Ivov
502aeca132 Adding original MIT license 2015-06-18 22:36:17 +02:00
George Politis
288fbff677 Update LICENSE 2015-06-18 19:07:32 +02:00
George Politis
bdca07be17 Updates app.bundle.js 2015-06-18 19:01:04 +02:00
George Politis
5f48e4cf9d Revert "Updates the license headers."
This reverts commit 93648f361b.
2015-06-18 18:59:41 +02:00
Emil Ivov
bff9648abc Update README.md 2015-06-18 18:57:58 +02:00
Emil Ivov
7874e09a7e Update README.md 2015-06-18 18:25:21 +02:00
George Politis
311df7ec7f Updates app.bundle.js 2015-06-18 16:27:36 +02:00
George Politis
93648f361b Updates the license headers. 2015-06-18 16:17:09 +02:00
Emil Ivov
8380a7bb9d Update LICENSE 2015-06-18 13:18:23 +02:00
paweldomas
a6c8d0787a Does not reload the page after Chrome desktop sharing extension is installed. 2015-06-17 10:11:30 +02:00
paweldomas
3f9b220ee9 The name of shared Etherpad document is now generated and advertised by Jicofo user. 2015-06-15 12:07:31 +02:00
hristoterezov
15db9ca7e4 Fixes issue with the download logs button. 2015-06-11 17:03:41 +03:00
Damian Minkov
224dff7481 Updates patch. 2015-06-11 11:56:08 +03:00
Damian Minkov
643b2024c0 Reloads wrong service on remove jitsi-meet-prosody. 2015-06-11 11:55:01 +03:00
George Politis
f378d43e31 Updates app.bundle.js. 2015-06-10 13:39:11 +02:00
George Politis
23f1dc174e Refactors simulcast support. 2015-06-10 13:35:05 +02:00
Marc Laporte
0c3802183d Minor rewording, fixing typos, and improving grammar 2015-06-03 12:52:52 -04:00
paweldomas
b038d276c9 Fixes problem with resetting focusedVideoInfo when participant leaves the room. Fixes error when display name is processed after participant has left. 2015-06-02 17:25:10 +02:00
Boris Grozev
797036e888 Updates app.bundle.js. 2015-06-02 16:09:53 +03:00
Boris Grozev
a426b65969 Advertises DTLS support in disco#info. 2015-06-02 16:09:40 +03:00
paweldomas
1d57cb9dae Fixes calls to updateLargeVideo, so that it is called with user resource jid. 2015-06-02 10:05:42 +02:00
Boris Grozev
be64bd883c Fail gracefully when not running in a git environment. 2015-06-01 18:06:37 +03:00
Damian Minkov
497c60375c Updates manual install instructions. 2015-06-01 15:01:31 +03:00
hristoterezov
7f616fc823 Changes start muted labels. 2015-06-01 10:11:12 +03:00
hristoterezov
8a4c341512 Implements default language config property and comments to config.js 2015-05-29 17:09:44 +03:00
bgrozev
c65343b2c5 Fix influxdb instructions. 2015-05-29 15:26:37 +03:00
hristoterezov
d0efa6a77b Adds French in available languages. 2015-05-29 09:46:49 +03:00
hristoterezov
01deadf078 Moves the sound notification code to be played when the participant joins / leaves the room instead of receiving add / remove stream event. 2015-05-28 14:34:40 +03:00
George Politis
6eaa3cd45d Updates app.bundle.js 2015-05-28 11:46:40 +02:00
gpolitis
b0d2a79873 Require FF 40 or above for a good experience. 2015-05-28 11:45:10 +02:00
gpolitis
d94f001f25 A recent JDK and Ant is required to compile JICOFO. 2015-05-27 20:56:10 +02:00
gpolitis
afb85e2fd9 These are Debian instructions really. 2015-05-27 20:49:26 +02:00
gpolitis
fffb5801c5 Makes some nginx directives optional. 2015-05-27 16:56:30 +02:00
gpolitis
d81cd20ee6 Removes otalk modules from the installation procedure. 2015-05-27 16:52:16 +02:00
gpolitis
3e7a9228bc No turn server is necessary with Jitsi Videobridge. 2015-05-27 16:22:16 +02:00
hristoterezov
835e199135 Fixes issue with not removed ssrcs after the participant left the room. 2015-05-27 11:47:06 +03:00
hristoterezov
1d660e1883 Removes join / leave notifications if the participant start audio muted. 2015-05-26 14:18:45 +03:00
hristoterezov
5746261961 Implements the functionality to update config.js parameters via the URL. 2015-05-25 17:42:59 +03:00
hristo
cbeae8eb30 Commit from translate.jitsi.org by user hristo.: 158 of 159 strings translated (0 fuzzy). 2015-05-25 13:12:58 +00:00
George Politis
95b2752d2a Updates libs/app.bundle.js 2015-05-21 10:32:55 +02:00
George Politis
e3da472e7a Adds special handling of recvonly remote streams. 2015-05-21 10:32:00 +02:00
George Politis
43f60ca336 Updates app.bundle.js 2015-05-20 16:27:39 +02:00
George Politis
118a61c416 Disables stats logging in FF. 2015-05-20 16:27:10 +02:00
George Politis
bf99a129bd Depend on sdp-interop@0.1.4 2015-05-20 16:20:31 +02:00
George Politis
fb6ad8cffd Updates app.bundle.js and restores latest sdp-interop. 2015-05-20 15:55:30 +02:00
hristoterezov
21fef57bc4 Adds config property that disables hiding of toolbar. 2015-05-20 15:10:09 +03:00
George Politis
777422c87d Update libs/app.bundle.js. 2015-05-20 14:03:43 +02:00
George Politis
ee6fd63c25 Depend on sdp-interop@0.1.3 2015-05-20 14:03:13 +02:00
George Politis
b9f00b71b2 Fixes conference disposal in FF. 2015-05-20 10:45:00 +02:00
hristoterezov
099e3340bc Implements start muted feature. 2015-05-19 18:03:01 +03:00
George Politis
172c2d3d71 Updates app.bundle.js. 2015-05-18 19:08:20 +02:00
George Politis
854c8e5f2f Removes obsolete/unused variable. 2015-05-18 19:07:56 +02:00
George Politis
b2cff193a9 Updates app.bundle.js. 2015-05-18 19:03:27 +02:00
George Politis
ad1772178d Notifies the focus about newly allocated channel SSRCs on add/remove source. 2015-05-18 19:00:12 +02:00
George Politis
0959b3d5b8 Updates app.bundle.js 2015-05-15 15:43:56 +02:00
George Politis
36f91f7f1e Disables RTP stats when running on FF. 2015-05-15 15:36:29 +02:00
George Politis
2c9d0606c3 Attempts to fix #258 2015-05-15 15:32:01 +02:00
George Politis
1ce22fb8c9 Depend on sdp-interop@0.1.2, sdp-transform@1.4.0 2015-05-15 13:08:04 +02:00
George Politis
e0cba855a6 Implements fault tolerant connect (closes #268). 2015-04-22 23:11:25 +02:00
paweldomas
8af3a65d37 Displays error dialog when BOSH connection fails. 2015-04-22 16:14:16 +02:00
hristoterezov
667f67376e Fixes the issue with black large video. 2015-04-22 15:53:01 +03:00
George Politis
ce7b6be024 Bumps app.bundle.js version. 2015-04-22 14:30:24 +02:00
George Politis
57cd2647f3 Fixes a JS error in the invite prompt when there's no room url. 2015-04-22 14:26:48 +02:00
hristoterezov
efcfe99707 Improves the notification that informs the user if started the conference audio/video muted. 2015-04-22 13:27:14 +03:00
hristoterezov
cc1ad1bc13 Implement the functionality that allows users to start the conversation muted. 2015-04-22 12:31:08 +03:00
Paweł Domas
29f06829e7 Merge pull request #272 from mkeesey/master
Fix stream end/start race condition
2015-04-16 07:54:23 +02:00
Mike Keesey
0fdf5e0102 Fix stream end/start race condition
We need to queue attempts to call modifySources to prevent errors in
setLocalDescription, et al. We need to let the asynchronous function
flow in modifySources finish before we kick off another set.
2015-04-15 08:46:27 -06:00
hristoterezov
5b7083f5f7 Fixes JS error when downloading logs. 2015-04-15 11:17:01 +03:00
Boris Grozev
adb1c572ed Rebuilds app.bundle.js. 2015-04-12 14:26:58 +02:00
Boris Grozev
5d17cd0bcc Merge branch 'dtmf' 2015-04-12 14:24:33 +02:00
Boris Grozev
134d89a3d6 Fix a problem with accessing peerconnection, use duration and pause in the API. 2015-04-12 14:23:54 +02:00
Boris Grozev
0efcbdcd37 Adds a MemberList module and (currently disabled) code to show the dialpad button. 2015-04-12 14:18:24 +02:00
hristoterezov
878713a15d Fixes typo for the user id node in the presence. 2015-04-09 16:57:32 +03:00
hristoterezov
e01713f6f8 Fixes remove video element functionality in UI to remove only the correct video instead of all. 2015-04-09 14:02:33 +03:00
paweldomas
b6155c04ad Modifies "authentication required" dialog. 2015-04-08 14:34:10 +02:00
Boris Grozev
8075d0a0fd Adds a (hidden) dialpad button to the toolbar. 2015-04-08 12:51:29 +02:00
Boris Grozev
029851fe3f Avoid unnecessary jquery calls. 2015-04-08 12:49:49 +02:00
Boris Grozev
886fb2ac43 Fix typos and rename event names for purposes of clarity. 2015-04-08 12:30:48 +02:00
Boris Grozev
99b1a51df0 Fix a typo. 2015-04-08 10:43:43 +02:00
Boris Grozev
795ec24246 Adds a module for sending DTMF tones. 2015-04-07 18:02:52 +02:00
Boris Grozev
ecf9c6fc6b Adds instructions for adding an icon (thanks @hristoterezov). 2015-04-07 17:38:30 +02:00
Boris Grozev
68bc819b89 Adds the dial pad icon. 2015-04-07 17:09:28 +02:00
George Politis
80c5779de9 Adds an SDP transform module. 2015-04-03 13:18:09 +02:00
paweldomas
d175dfdef7 Prevents from sending invalid presence packets, before MUC jid is defined. 2015-04-01 21:12:08 +02:00
hristo
93c13f5a11 Commit from translate.jitsi.org by user hristo.: 156 of 159 strings translated (0 fuzzy). 2015-04-01 13:13:01 +00:00
hristo
ff8b880948 Commit from translate.jitsi.org by user hristo.: 140 of 159 strings translated (0 fuzzy). 2015-04-01 12:39:44 +00:00
hristo
5b550c8a5b Commit from translate.jitsi.org by user hristo.: 113 of 159 strings translated (0 fuzzy). 2015-03-31 17:02:39 +00:00
hristo
ce7d3c5c81 Commit from translate.jitsi.org by user hristo.: 91 of 159 strings translated (0 fuzzy). 2015-03-31 15:10:41 +00:00
jitsi-pootle
c99350308c New files added from translate.jitsi.org based on templates 2015-03-31 11:35:10 +00:00
George Politis
e98c8ada6a Nukes the enableFirefoxSupport config param. 2015-03-31 13:02:59 +02:00
George Politis
ce8aa961ea Lowers FF requirement to v38. 2015-03-31 12:33:04 +02:00
paweldomas
fbd08ba3a6 Adds empty SSI templates to avoid 404. 2015-03-31 11:17:26 +02:00
Paweł Domas
61594cb877 Merge pull request #259 from jitsi/plugin_ssi_includes
Adds additional SSI include tags.
2015-03-31 08:38:01 +02:00
hristoterezov
520e655100 Fixes issue with video mute indicator. 2015-03-30 17:19:35 +03:00
paweldomas
58d1697b00 Adds additional SSI include tags. 2015-03-30 16:00:23 +02:00
hristoterezov
f902b99287 Adds documentation for the translation. 2015-03-30 16:11:16 +03:00
hristoterezov
d25a9b0e41 Fixes issue with desktop sharing when the user click Cancel on the popup window. 2015-03-27 16:23:48 +02:00
hristoterezov
0e0f7d7ccb Fixes issue with available devices icons 2015-03-27 15:56:17 +02:00
hristoterezov
58cc21d417 Changes the implementation to show availability of video and sound devices. 2015-03-27 11:36:39 +02:00
paweldomas
8ac44491d0 Fixes input field focus in call SIP number dialog. 2015-03-26 14:16:20 +01:00
Damian Minkov
a093b455b3 Fixes debian packaging checking wrong template. 2015-03-26 13:19:50 +02:00
George Politis
58494d45db Brings back goog-remb signaling. 2015-03-26 11:29:40 +01:00
paweldomas
f98621173f Fixes uid, email and displayName advertisement in MUC presence. 2015-03-25 12:39:22 +01:00
hristoterezov
dbcfc92dc4 Changes the implementation to allow users without audio and video to join the conferences. Fixes issue with switching off desktop sharing for audio only users. 2015-03-24 17:43:33 +02:00
ibauersachs
b9bd1d599b Commit from translate.jitsi.org by user ibauersachs.: 159 of 159 strings translated (0 fuzzy). 2015-03-24 15:35:05 +00:00
ibauersachs
99b0be91ed Commit from translate.jitsi.org by user ibauersachs.: 159 of 159 strings translated (0 fuzzy). 2015-03-24 13:50:48 +00:00
Ingo Bauersachs
f2ae29d8e4 Add Italian 2015-03-24 14:47:56 +01:00
jitsi-pootle
4c3d415a07 New files added from translate.jitsi.org based on templates 2015-03-24 13:21:29 +00:00
Ingo Bauersachs
7b65798758 Use SSL for the Jitsi homepage link 2015-03-24 10:36:27 +01:00
hristoterezov
c1c5a305c6 Removes the comment from the English translation json. 2015-03-24 11:17:51 +02:00
hristo
291211c029 Commit from translate.jitsi.org by user hristo.: 13 of 149 strings translated (0 fuzzy). 2015-03-23 16:40:26 +00:00
hristoterezov
a3a9e8d951 Adds comment about not changing or creating other language files manually. 2015-03-23 18:35:44 +02:00
hristoterezov
3a0ee11ccd Turns off the camera when video is muted on https connection. 2015-03-23 18:12:24 +02:00
George Politis
2568b07075 enables REMB signaling in the rembson room. 2015-03-23 10:17:02 +01:00
Boris Grozev
e5fa02a1d4 Automates bumping js file versions. Experimental, please revert Makefile
if it causes problems.
2015-03-21 20:04:12 -07:00
Damian Minkov
fb5550bc38 Fixes debian package watch file. 2015-03-21 16:48:53 +02:00
Damian Minkov
bc5565251c Removes some links when reconfiguring. 2015-03-21 14:18:11 +02:00
Damian Minkov
4f548ce748 Adds description to the patch. 2015-03-21 14:18:11 +02:00
Damian Minkov
0faeb450c0 Drops use of Pre-Depends. 2015-03-21 14:18:11 +02:00
George Politis
e12ffd7a24 Bumps app.bundle.js version. 2015-03-19 20:02:19 +01:00
George Politis
d4c78617a7 Updates app.bundle.js with fix from previous commit. 2015-03-19 19:30:18 +01:00
hristoterezov
db2296953d Merge pull request #233 from odotom/odotom-patch-2-2
Update RTC.js
2015-03-19 16:57:17 +02:00
paweldomas
cd19c0e9e3 Chrome no longer allows to trigger install from extension msg response callback, so we have to check if extension exists before user clicks "share desktop" button(on startup). Fixes jshint warnings. 2015-03-18 20:28:18 +01:00
hristoterezov
44e558e5a0 Fixes video mute when the user is alone in the room. 2015-03-18 18:41:41 +02:00
hristoterezov
0da2547360 Fixes the size of the desktop streaming video for remote peer. 2015-03-17 18:46:08 +02:00
paweldomas
f3274ea42e Fixes broken translation after i18next-client update to 1.8.0. 2015-03-17 09:25:26 +01:00
paweldomas
0848283f6d Fixes broken Shibboleth authentication. 2015-03-17 08:50:04 +01:00
paweldomas
6e99286bd0 Updates app.bundle.js. 2015-03-13 15:09:50 +01:00
paweldomas
588c2d9e4b XMPP authentication improvements. Makes it possible to authenticate during the conference. 2015-03-13 15:08:05 +01:00
paweldomas
7c201573fb No need to manually focus Prezi URL input. 2015-03-13 15:07:53 +01:00
paweldomas
581ffec5ed Fixes issues after jquery-impromptu update. 2015-03-13 15:07:43 +01:00
paweldomas
c296940fd4 Updates jquery-impromptu in order to fix issues with modal dialogs. 2015-03-13 15:07:31 +01:00
paweldomas
f48633fa1d Removes unused connection settings form. 2015-03-13 15:07:17 +01:00
George Politis
66a53c7dc0 Redirects to unsupported browser page for FF < 39. 2015-03-13 10:19:54 +01:00
bgrozev
09f53c6b21 Update influxdb.md 2015-03-13 10:01:16 +01:00
ibauersachs
b3a17040e5 Commit from translate.jitsi.org by user ibauersachs.: 11 of 149 strings translated (0 fuzzy). 2015-03-12 21:25:22 +00:00
ibauersachs
774a7b41e4 Commit from translate.jitsi.org by user ibauersachs.: 149 of 149 strings translated (0 fuzzy). 2015-03-12 21:24:32 +00:00
ibauersachs
062e671290 Commit from translate.jitsi.org by user ibauersachs.: 148 of 148 strings translated (0 fuzzy). 2015-03-12 20:47:21 +00:00
paweldomas
90d979b69d Makes it possible to display notification message above the toolbar. 2015-03-12 17:56:28 +01:00
George Politis
9d50084b98 Doesn't fail when removeStream is called on FF. 2015-03-12 17:00:40 +01:00
George Politis
e1d71a41f7 Adds FF in the list of supported browsers. Enables it by default. 2015-03-12 16:33:27 +01:00
George Politis
e781eb6423 Partially reverts "Fixes translation issues (deb68dd)" and restores sdp-interop changes. 2015-03-12 16:17:22 +01:00
hristo
15f4f03ba3 Commit from translate.jitsi.org by user hristo.: 11 of 149 strings translated (0 fuzzy). 2015-03-11 17:50:42 +00:00
hristoterezov
4f9b6f7180 Changes the format of email text in the language resource files. 2015-03-11 18:54:43 +02:00
hristoterezov
b36ec5fd01 Moves supported browser list from the email message to the JS 2015-03-11 10:53:39 +02:00
ibauersachs
ac95ea03fe Commit from translate.jitsi.org by user ibauersachs.: 148 of 148 strings translated (0 fuzzy). 2015-03-11 08:51:16 +00:00
hristoterezov
ae535fcb7d Replaces %0D%0A with \n in the email template text. 2015-03-11 10:29:21 +02:00
hristoterezov
957cc6afc1 Merge branch 'master' of github.com:jitsi/jitsi-meet 2015-03-10 17:25:44 +02:00
hristoterezov
16fdd59617 Adds turkish language. 2015-03-10 17:24:27 +02:00
George Politis
fabf8f42c6 Updates .gitignore. 2015-03-10 15:50:26 +01:00
ibauersachs
c98a56dc37 Commit from translate.jitsi.org by user ibauersachs.: 135 of 135 strings translated (0 fuzzy). 2015-03-10 10:10:08 +00:00
hristoterezov
deb68dd420 Fixes translation issues 2015-03-10 11:38:09 +02:00
Boris Grozev
0fd1a7fa08 Removes embedded html as per Ingo's suggestion. 2015-03-09 19:14:11 +01:00
Boris Grozev
c6ff8aa5dd Tries to improve readibility... 2015-03-09 18:44:42 +01:00
Boris Grozev
06f025e92a Fix formatting. 2015-03-09 18:29:47 +01:00
Boris Grozev
f14329f2cd Adds instructions to enable logging. 2015-03-09 18:27:56 +01:00
Boris Grozev
53e525597a Add .swp files to .gitignore. 2015-03-09 18:27:55 +01:00
George Politis
54b3cbcf94 Reverts config.js 2015-03-09 17:58:11 +01:00
George Politis
2852740e71 Updates the Makefile. It calls npm update before building the project. 2015-03-09 17:41:17 +01:00
George Politis
5322ba086b Reverts previous change of the Makefile. 2015-03-09 17:39:16 +01:00
hristoterezov
d2f95f3c81 Fixes some translation issues. 2015-03-09 17:50:13 +02:00
George Politis
3747251821 Adds dependency to specific commit for sdp-interop. 2015-03-09 16:21:53 +01:00
George Politis
159ba82167 Updates app.bundle.js with latest sdp-interop module that offers support for ssrc-groups. 2015-03-09 15:25:47 +01:00
George Politis
e34a8e6b60 Updates app.bundle.js with latest sdp-interop module. 2015-03-09 11:11:25 +01:00
jitsi-pootle
17a6e360a2 New files added from translate.jitsi.org based on templates 2015-03-09 08:16:17 +00:00
George Politis
b690f5d4a1 Updates app.bundle.js. 2015-03-05 20:25:50 +01:00
Damian Minkov
30f3168bf7 Adds watch file for the deb. 2015-03-05 19:23:55 +02:00
Damian Minkov
115f2e4663 Updates the patch for debian src package. 2015-03-05 19:23:29 +02:00
Damian Minkov
fa15a75928 Updates missing-source location. 2015-03-05 18:01:27 +02:00
Damian Minkov
4db75446f3 Do not edit /etc/nginx/nginx.conf file directly. 2015-03-05 17:52:05 +02:00
George Politis
d9f7b8b6cc Adds a comment about how FF handles the video.src attribute. 2015-03-05 11:26:44 +01:00
George Politis
05bbfda5bb Adds support for FF/multistream. 2015-03-04 21:33:06 +01:00
paweldomas
e465b3ed90 Removes unnecessary error dialog when desktop sharing is started before the conference. 2015-03-04 13:58:07 +01:00
hristoterezov
1825f47ef2 Adds translation support for placeholder attributes. 2015-03-04 12:59:52 +02:00
ibauersachs
169d613ac4 Commit from translate.jitsi.org by user ibauersachs.: 135 of 135 strings translated (0 fuzzy). 2015-03-04 09:37:19 +00:00
Ingo Bauersachs
3dac5eeff5 Fix punctuation spacing 2015-03-04 10:27:44 +01:00
hristoterezov
f79651f806 Merge branch 'translation' 2015-03-04 11:06:02 +02:00
hristoterezov
6048d0a325 Fixes the html attributes for translation options. 2015-02-27 20:05:32 +02:00
hristoterezov
6f12446c99 Fixes translation of plurals. 2015-02-27 19:58:05 +02:00
hristoterezov
af682f8727 Changes the configuration of translation module to retrieve the resources synchronous. Removes the default values. 2015-02-26 17:35:35 +02:00
paweldomas
9123923818 Displays reservation system error if one is returned by the focus. 2015-02-26 14:59:01 +01:00
Boris Grozev
aee7a8e1bd Fix a bug with stats accumulating. Fix a typo. 2015-02-26 10:12:06 +01:00
paweldomas
5b44edb3cc Handles graceful-shutdown focus error response. 2015-02-25 16:55:22 +01:00
Boris Grozev
806d4ea443 Filters some statistics from the logs. Increases the interval for logged statistics. 2015-02-25 11:38:04 +01:00
hristoterezov
1e35ca5e4d Removes the firefox issue link. 2015-02-25 12:06:32 +02:00
hristoterezov
d4f00d76ab Removes webrtcrequired.html. 2015-02-25 11:07:33 +02:00
hristoterezov
37282e63b3 Fixes the references with chromeonly page. 2015-02-24 18:24:39 +02:00
hristoterezov
4b218499ae Redesigns the supported browsers page. 2015-02-24 18:08:24 +02:00
hristoterezov
f16a1cdf44 Changes the implementation to store the language in local storage. Adds new languages. 2015-02-24 12:49:46 +02:00
hristoterezov
702f02568d Fixes issue with the buttons in the message handler. 2015-02-24 10:57:41 +02:00
paweldomas
b6808d87bc Updates app.bundle.js. 2015-02-23 16:15:42 +01:00
paweldomas
8042bd2aa6 Handles MUC destroyed event. 2015-02-23 16:13:38 +01:00
paweldomas
053b2d5af2 Fixes logout confirmation dialog. 2015-02-23 16:13:26 +01:00
Ingo Bauersachs
222164333b Fix some typos and punctuation spacing. 2015-02-23 13:35:16 +01:00
ibauersachs
db50810e4b Commit from translate.jitsi.org by user ibauersachs.: 130 of 130 strings translated (0 fuzzy). 2015-02-23 12:33:29 +00:00
hristo
720851dcb9 Commit from translate.jitsi.org by user hristo.: 3 of 130 strings translated (0 fuzzy). 2015-02-23 11:44:51 +00:00
jitsi-pootle
d7203b8b1a New files added from translate.jitsi.org based on templates 2015-02-23 11:42:53 +00:00
jitsi-pootle
204ca29ed7 New files added from translate.jitsi.org based on templates 2015-02-23 11:42:33 +00:00
hristoterezov
fdada53a4a Fixes issue with the recording. 2015-02-23 12:06:42 +02:00
hristoterezov
81eb3754a0 Fixes "focus not available" notifications. 2015-02-23 11:20:35 +02:00
hristoterezov
d260f1db61 Removes unused package.son files. 2015-02-20 18:21:58 +02:00
hristoterezov
74f078f166 Adds multi language support for message handlers. 2015-02-20 18:17:46 +02:00
paweldomas
e16cee4187 Delete old session ID and retry on 'session-invalid' response. Updates app.bundle.js. 2015-02-19 13:56:04 +01:00
paweldomas
a904e35c67 Adds auto-sign in feature and login/logout toolbar menu. 2015-02-19 13:49:51 +01:00
paweldomas
b87cd9f842 Moves Settings module out from the UI. 2015-02-19 13:49:41 +01:00
paweldomas
fed34e7671 Fixes PreziPlayer crash when invalid message is received. 2015-02-19 13:49:41 +01:00
George Politis
ed57f72117 Adds extra logging. 2015-02-19 13:27:44 +01:00
hristoterezov
4d39d4ccc3 Fixes issue with selected user resource jid variable. 2015-02-19 11:23:55 +02:00
hristoterezov
79cdd94833 Adds multi language support for notifications. 2015-02-13 18:28:35 +02:00
hristoterezov
e0645b41d3 Moves some function calls in UI service 2015-02-13 11:31:25 +02:00
hristoterezov
aa7f0c8a0b Merge branch 'master' of github.com:jitsi/jitsi-meet 2015-02-12 16:44:24 +02:00
hristoterezov
2362770cce Changes getUserMedia implementation to try lower resolution if the configured one is not supported. 2015-02-12 16:42:08 +02:00
Damian Minkov
8334036cf4 Moves admins definition as it seems on some distributions after latest lua updates, causes trouble for prosody. 2015-02-12 15:39:56 +02:00
Damian Minkov
eec513e9e3 Adds admins line after muc component. 2015-02-12 13:50:21 +02:00
hristoterezov
f2a7a43ba7 Fixes audio level performance issue on avatar. 2015-02-11 18:29:20 +02:00
Thomas Odorfer
9e6e23ce97 Update RTC.js
fix for screensharing screen ratio and local mirror effect - forgotten parameter videoType in RTC.js in jitsi-meet commit 6c4a5bd tag 340
2015-02-11 14:28:26 +01:00
hristoterezov
61bbbaf6eb Adds gitattributes file that marks the generated files as binary files. 2015-02-09 15:50:49 +02:00
hristoterezov
3519a6ec7b Fixes the generated file. 2015-02-09 15:03:23 +02:00
hristoterezov
d21f994eee Removes rtp stats option and adds options for disabling/enabling stats and audio levels. 2015-02-09 14:51:25 +02:00
hristoterezov
b32acf0dfb Fixes the multi language support for the debian package. 2015-02-09 12:24:11 +02:00
hristoterezov
71a56e13d9 Fixes some issues with the tests 2015-02-09 12:21:23 +02:00
hristoterezov
0f6d0a0439 Adds methods required by torture 2015-02-09 10:12:55 +02:00
hristoterezov
3032ea7684 Implements basic multi language support. 2015-02-06 17:46:50 +02:00
hristoterezov
04cfbafc33 Fixes issue with recording. 2015-02-06 15:43:40 +02:00
hristoterezov
57fcee676a Fixes issues with accessing modules not from APP object. 2015-02-06 14:54:19 +02:00
hristoterezov
2f5d090ca5 Merge pull request #227 from odotom/odotom-patch-1
Fixes typos.
2015-02-03 15:42:30 +02:00
bgrozev
8d796f328b Update README.md
Clarify that the detailed instructions are for a 'manual' installation.
2015-02-03 12:45:01 +02:00
hristoterezov
ffb1d6ea17 Generates app bundle file 2015-02-02 20:00:45 +02:00
hristoterezov
4447e5dac6 Merge pull request #229 from schleussinger/master
Corrected Scope - fixes runtime JS error and  Chrome Ext desktop sharing for me
2015-02-02 19:47:59 +02:00
schleussinger
dbed14db5e Fix correct Scope - this fixes JS error and Chrome Ext desktop sharing for me 2015-02-01 13:14:18 +01:00
Thomas Odorfer
254103e21f Update UI.js
fix typo UI.getCredentials
2015-01-31 22:14:53 +01:00
Thomas Odorfer
d0b39e1c97 Update app.js
app.js: fix getCredentials - return object instead of function reference
2015-01-31 22:11:02 +01:00
hristoterezov
4bb555e4b2 Fixes authentication issues. 2015-01-29 11:43:40 +02:00
hristoterezov
8d0ee3ded9 Updates generated file. 2015-01-29 11:27:02 +02:00
hristoterezov
98d1ca8505 Fixes authentication issues. 2015-01-29 11:09:09 +02:00
hristoterezov
e766bad4ce Merge branch 'master' of https://github.com/Zalmoxisus/jitsi-meet
Conflicts:
	libs/modules/RTC.bundle.js
	libs/modules/simulcast.bundle.js
2015-01-28 18:06:09 +02:00
hristoterezov
9eb2873cfa Removes the bundles for every module and add bundle for the whole application. 2015-01-28 16:35:22 +02:00
hristoterezov
c7e2331284 Removes document bind events between modules. 2015-01-27 14:03:26 +02:00
hristoterezov
02ca5e5732 Merge branch 'master' of github.com:jitsi/jitsi-meet 2015-01-27 11:56:43 +02:00
hristoterezov
bc2d72638b Add events for data chanel. 2015-01-27 11:56:22 +02:00
Zalmoxisus
40de181959 Fixes audio-only (when GUM fails) 2015-01-26 19:54:26 +02:00
bgrozev
70bc071cb8 Merge pull request #220 from Zalmoxisus/master
Fixes some typos that cause errors
2015-01-26 09:29:59 -06:00
Zalmoxisus
567ac23c2c Fixes some typos that cause errors 2015-01-26 16:24:26 +02:00
hristoterezov
af50bd5b94 Resolves some module dependancies by replaces them with events. 2015-01-24 16:28:02 +02:00
hristoterezov
899f0ee83d Removes UI dependancies in the xmpp module. 2015-01-23 17:36:17 +02:00
hristoterezov
29b3ea07e0 Removes util.js. Fixes prezi. 2015-01-23 14:01:44 +02:00
hristoterezov
c0a316c7df Creates keyboard shortcuts module. 2015-01-22 18:26:05 +02:00
hristoterezov
f624833f1f Merge branch 'master' of github.com:jitsi/jitsi-meet 2015-01-22 18:02:56 +02:00
hristoterezov
4c661ffca6 Removes nickname global variable. 2015-01-22 18:02:37 +02:00
Boris Grozev
0819f23049 Adds instructings for building. 2015-01-22 17:52:28 +02:00
Boris Grozev
1e9a463245 Fix a typo. 2015-01-22 17:39:40 +02:00
Boris Grozev
447d8f5677 Makes the default make target execute "deploy" and "clean". 2015-01-22 17:36:12 +02:00
fo
d2453b1f1f Changed capitalisation in require statements. 2015-01-22 16:56:23 +02:00
Boris Grozev
9460138cc3 Fix pako reference. 2015-01-21 17:35:23 +02:00
Boris Grozev
0063461858 Uses pako from npm. 2015-01-21 17:13:22 +02:00
hristoterezov
248d7a3173 Moves ssrc2jid global variable to the xmpp module. 2015-01-21 13:55:20 +02:00
hristoterezov
51277270fe Fixes issues with the recording. 2015-01-20 18:12:32 +02:00
hristoterezov
394738394d Fixes NPE when creating non anonymous room 2015-01-20 18:07:03 +02:00
hristoterezov
6c4a5bd2bc Removes some global variables. Fixes recording. 2015-01-20 17:56:00 +02:00
hristoterezov
6347730dc7 Fixes some issues related to xmpp module creation. 2015-01-19 18:54:41 +02:00
hristoterezov
3da8e39745 Merges app.js and generates bundles. 2015-01-19 12:03:14 +02:00
hristoterezov
f4acf97b00 Merge branch 'master' of github.com:jitsi/jitsi-meet
Conflicts:
	app.js
	libs/strophe/strophe.jingle.js
	modules/xmpp/moderator.js
	muc.js
2015-01-19 12:00:30 +02:00
hristoterezov
e4e66a03d7 Creates initial version of xmpp module. 2015-01-19 11:20:00 +02:00
paweldomas
ed78c0053c Makes it possible to append URL parameters after room name. Adds ?login=true to enforce authenticated domain when anonymous domain is used. This allows to get moderator permissions after room has been created. 2015-01-16 13:22:02 +01:00
paweldomas
398fd18b8e Advertises dtls/sctp support in capabilities. 2015-01-16 12:35:31 +01:00
paweldomas
d3003d4fcd Adjusts anonymous domain functionality to work with Jicofo. 2015-01-14 17:59:50 +01:00
hristoterezov
ee94eca733 Creates desktop sharing module. 2015-01-13 15:11:05 +02:00
hristoterezov
0696fb2c5a Fixes issue with video mute. 2015-01-13 11:33:45 +02:00
hristoterezov
e6fbb0934e Removes local streams from the connection object. 2015-01-12 15:23:29 +02:00
hristoterezov
faaf24d3c4 Creates simulcast module 2015-01-09 17:32:35 +02:00
hristoterezov
fcf785f32c Removes unused files. 2015-01-09 16:18:03 +02:00
hristoterezov
0508628871 Creates API module. 2015-01-09 15:39:32 +02:00
hristoterezov
27502d3fa8 Removes some dependancies from functions in app.js. 2015-01-09 14:19:48 +02:00
hristoterezov
1057ff36cd Moves some functions from app.js 2015-01-09 13:35:48 +02:00
paweldomas
8d5e50c0ca Moves 'callSipButtonClicked' method to Toolbar.js in order to fix 'sharedKey' undefined error. 2015-01-09 11:19:42 +01:00
hristoterezov
8db602c8bd Fixes make file 2015-01-09 11:49:45 +02:00
paweldomas
06494cf821 Fixes undefined 'messageHandler' error. 2015-01-09 08:56:30 +01:00
hristoterezov
0fe6a55700 Fixes issue with connection quality module name. 2015-01-08 14:33:06 +02:00
hristoterezov
e20274c2f7 Creates connection quality module. 2015-01-08 14:11:53 +02:00
paweldomas
b77106f61a Includes room secret in SIP gateway request if password is required to join the room. 2015-01-07 16:58:41 +01:00
hristoterezov
4d25b139cc Fixes some issues caused by the merge. 2015-01-07 17:47:48 +02:00
hristoterezov
6ce48a5b7b Merge branch 'master' of github.com:jitsi/jitsi-meet
Conflicts:
	app.js
	index.html
	libs/colibri/colibri.focus.js
	libs/modules/statistics.bundle.js
	moderator.js
	modules/UI/videolayout/VideoLayout.js
	muc.js
2015-01-07 17:14:10 +02:00
hristoterezov
69b0e2ad32 Creates UI module. 2015-01-07 16:54:03 +02:00
paweldomas
cd0c9393d8 Makes "authentication required" dialog persistent. Joins the room if someone else authenticates first and creates the conference for us. 2015-01-07 12:28:49 +01:00
paweldomas
2494444ca4 Fixes issue with remote video menu not displayed on role upgrade. 2015-01-07 12:28:40 +01:00
paweldomas
c76b78eb46 Improves SIP gateway auto configuration by getting feedback from the focus. 2015-01-05 16:45:45 +01:00
paweldomas
78fcc8b72c Sends SIP gateway requests through the focus component. 2015-01-05 16:45:45 +01:00
198 changed files with 57751 additions and 18731 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.bundle.js -text -diff

5
.gitignore vendored
View File

@@ -1 +1,6 @@
node_modules
*.swp
.idea/
*.iml
.*.tmp
deploy-local.sh

215
LICENSE
View File

@@ -1,21 +1,202 @@
The MIT License (MIT)
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Copyright (c) 2013 ESTOS GmbH
Copyright (c) 2013 BlueJimp SARL
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. Definitions.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,22 +1,27 @@
NPM = npm
BROWSERIFY = browserify
GLOBAL_FLAGS = -e
MODULE_DIR = modules
MODULE_SUBDIRS = $(wildcard $(MODULE_DIR)/*/)
MODULES = $(MODULE_SUBDIRS:$(MODULE_DIR)/%/=%)
GLOBAL_FLAGS = -x jquery -e
OUTPUT_DIR = .
DEPLOY_DIR = libs/modules
DEPLOY_DIR = libs
all:FLAGS = $(GLOBAL_FLAGS)
all:$(MODULES)
all: compile deploy clean
debug:FLAGS = -d $(GLOBAL_FLAGS)
debug:$(MODULES)
compile:FLAGS = $(GLOBAL_FLAGS)
compile: app
$(MODULES): *.js
$(BROWSERIFY) $(FLAGS) $(MODULE_DIR)/$@/$@.js -s $@ -o $(OUTPUT_DIR)/$@.bundle.js
debug: compile-debug deploy clean
compile-debug:FLAGS = -d $(GLOBAL_FLAGS)
compile-debug: app
app:
$(NPM) update && $(BROWSERIFY) $(FLAGS) app.js -s APP -o $(OUTPUT_DIR)/app.bundle.js
clean:
@rm -f $(OUTPUT_DIR)/*.bundle.js
rm -f $(OUTPUT_DIR)/*.bundle.js
deploy:
@mkdir -p $(DEPLOY_DIR) && cp $(OUTPUT_DIR)/*.bundle.js $(DEPLOY_DIR)
mkdir -p $(DEPLOY_DIR) && \
cp $(OUTPUT_DIR)/*.bundle.js $(DEPLOY_DIR) && \
./bump-js-versions.sh && \
([ ! -x deploy-local.sh ] || ./deploy-local.sh)

View File

@@ -1,6 +1,6 @@
Jitsi Meet - Secure, Simple and Scalable Video Conferences
====
Jitsi Meet is an open-source (MIT) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, scalable video conferences. You can see [Jitsi Meet in action](http://youtu.be/7vFUVClsNh0) here at the 482 session of the VoIP Users Conference.
Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, scalable video conferences. You can see [Jitsi Meet in action](http://youtu.be/7vFUVClsNh0) here at the session #482 of the VoIP Users Conference.
You can also try it out yourself at https://meet.jit.si .
@@ -10,15 +10,43 @@ Jitsi Meet allows for very efficient collaboration. It allows users to stream th
Installing Jitsi Meet is quite a simple experience. For Debian-based systems, we recommend following the [quick-install](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md) document, which uses the package system.
For other systems, or if you wish to install all components manually, see the [detailed installation instructions](https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md).
For other systems, or if you wish to install all components manually, see the [detailed manual installation instructions](https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md).
## Development tools
## Building the sources
Jitsi Meet uses [Browserify](http://browserify.org). If you want to make changes in the code you need to [install Browserify](http://browserify.org/#install). Browserify requires [nodejs](http://nodejs.org).
On Debian/Ubuntu systems, the required packages can be installed with:
```
sudo apt-get install npm
sudo npm install -g browserify
cd jitsi-meet
npm install
```
To build the Jitsi Meet application, just type
```
make
```
## Discuss
Please use the [Jitsi dev mailing list](http://lists.jitsi.org/pipermail/dev/) to discuss feature requests before opening an issue on github.
Please use the [Jitsi dev mailing list](http://lists.jitsi.org/pipermail/dev/) to discuss feature requests before opening an issue on Github.
## Acknowledgements
Jitsi Meet started out as a sample conferencing application using Jitsi Videobridge. It was originally developed by Philipp Hancke who then contributed it to the community where development continues with joint forces!
Jitsi Meet started out as a sample conferencing application using Jitsi Videobridge. It was originally developed by then ESTOS' developer Philipp Hancke who then contributed it to the community where development continues with joint forces!
## Miscellaneous
This project was originally contributed to the community under the MIT license and with the following notice:
The MIT License (MIT)
Copyright (c) 2013 ESTOS GmbH
Copyright (c) 2013 BlueJimp SARL
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,202 +0,0 @@
/**
* Implements API class that communicates with external api class
* and provides interface to access Jitsi Meet features by external
* applications that embed Jitsi Meet
*/
var APIConnector = (function () {
function APIConnector() { }
/**
* List of the available commands.
* @type {{
* displayName: inputDisplayNameHandler,
* muteAudio: toggleAudio,
* muteVideo: toggleVideo,
* filmStrip: toggleFilmStrip
* }}
*/
var commands =
{
displayName: VideoLayout.inputDisplayNameHandler,
muteAudio: toggleAudio,
muteVideo: toggleVideo,
toggleFilmStrip: BottomToolbar.toggleFilmStrip,
toggleChat: BottomToolbar.toggleChat,
toggleContactList: BottomToolbar.toggleContactList
};
/**
* Maps the supported events and their status
* (true it the event is enabled and false if it is disabled)
* @type {{
* incomingMessage: boolean,
* outgoingMessage: boolean,
* displayNameChange: boolean,
* participantJoined: boolean,
* participantLeft: boolean
* }}
*/
var events =
{
incomingMessage: false,
outgoingMessage:false,
displayNameChange: false,
participantJoined: false,
participantLeft: false
};
/**
* Check whether the API should be enabled or not.
* @returns {boolean}
*/
APIConnector.isEnabled = function () {
var hash = location.hash;
if(hash && hash.indexOf("external") > -1 && window.postMessage)
return true;
return false;
};
/**
* Initializes the APIConnector. Setups message event listeners that will
* receive information from external applications that embed Jitsi Meet.
* It also sends a message to the external application that APIConnector
* is initialized.
*/
APIConnector.init = function () {
if (window.addEventListener)
{
window.addEventListener('message',
APIConnector.processMessage, false);
}
else
{
window.attachEvent('onmessage', APIConnector.processMessage);
}
APIConnector.sendMessage({type: "system", loaded: true});
};
/**
* Sends message to the external application.
* @param object
*/
APIConnector.sendMessage = function (object) {
window.parent.postMessage(JSON.stringify(object), "*");
};
/**
* Processes a message event from the external application
* @param event the message event
*/
APIConnector.processMessage = function(event)
{
var message;
try {
message = JSON.parse(event.data);
} catch (e) {}
if(!message.type)
return;
switch (message.type)
{
case "command":
APIConnector.processCommand(message);
break;
case "event":
APIConnector.processEvent(message);
break;
default:
console.error("Unknown type of the message");
return;
}
};
/**
* Processes commands from external applicaiton.
* @param message the object with the command
*/
APIConnector.processCommand = function (message)
{
if(message.action != "execute")
{
console.error("Unknown action of the message");
return;
}
for(var key in message)
{
if(commands[key])
commands[key].apply(null, message[key]);
}
};
/**
* Processes events objects from external applications
* @param event the event
*/
APIConnector.processEvent = function (event) {
if(!event.action)
{
console.error("Event with no action is received.");
return;
}
switch(event.action)
{
case "add":
for(var i = 0; i < event.events.length; i++)
{
events[event.events[i]] = true;
}
break;
case "remove":
for(var i = 0; i < event.events.length; i++)
{
events[event.events[i]] = false;
}
break;
default:
console.error("Unknown action for event.");
}
};
/**
* Checks whether the event is enabled ot not.
* @param name the name of the event.
* @returns {*}
*/
APIConnector.isEventEnabled = function (name) {
return events[name];
};
/**
* Sends event object to the external application that has been subscribed
* for that event.
* @param name the name event
* @param object data associated with the event
*/
APIConnector.triggerEvent = function (name, object) {
APIConnector.sendMessage({
type: "event", action: "result", event: name, result: object});
};
/**
* Removes the listeners.
*/
APIConnector.dispose = function () {
if(window.removeEventListener)
{
window.removeEventListener("message",
APIConnector.processMessage, false);
}
else
{
window.detachEvent('onmessage', APIConnector.processMessage);
}
};
return APIConnector;
})();

1641
app.js

File diff suppressed because it is too large Load Diff

148
avatar.js
View File

@@ -1,148 +0,0 @@
var Avatar = (function(my) {
var users = {};
var activeSpeakerJid;
/**
* Sets the user's avatar in the settings menu(if local user), contact list
* and thumbnail
* @param jid jid of the user
* @param id email or userID to be used as a hash
*/
my.setUserAvatar = function(jid, id) {
if(id) {
if(users[jid] === id) {
return;
}
users[jid] = id;
}
var thumbUrl = getGravatarUrl(users[jid] || jid, 100);
var contactListUrl = getGravatarUrl(users[jid] || jid);
var resourceJid = Strophe.getResourceFromJid(jid);
var thumbnail = $('#participant_' + resourceJid);
var avatar = $('#avatar_' + resourceJid);
// set the avatar in the settings menu if it is local user and get the
// local video container
if(jid === connection.emuc.myroomjid) {
$('#avatar').get(0).src = thumbUrl;
thumbnail = $('#localVideoContainer');
}
// set the avatar in the contact list
var contact = $('#' + resourceJid + '>img');
if(contact && contact.length > 0) {
contact.get(0).src = contactListUrl;
}
// set the avatar in the thumbnail
if(avatar && avatar.length > 0) {
avatar[0].src = thumbUrl;
} else {
if (thumbnail && thumbnail.length > 0) {
avatar = document.createElement('img');
avatar.id = 'avatar_' + resourceJid;
avatar.className = 'userAvatar';
avatar.src = thumbUrl;
thumbnail.append(avatar);
}
}
//if the user is the current active speaker - update the active speaker
// avatar
if(jid === activeSpeakerJid) {
Avatar.updateActiveSpeakerAvatarSrc(jid);
}
};
/**
* Hides or shows the user's avatar
* @param jid jid of the user
* @param show whether we should show the avatar or not
* video because there is no dominant speaker and no focused speaker
*/
my.showUserAvatar = function(jid, show) {
if(users[jid]) {
var resourceJid = Strophe.getResourceFromJid(jid);
var video = $('#participant_' + resourceJid + '>video');
var avatar = $('#avatar_' + resourceJid);
if(jid === connection.emuc.myroomjid) {
video = $('#localVideoWrapper>video');
}
if(show === undefined || show === null) {
show = isUserMuted(jid);
}
//if the user is the currently focused, the dominant speaker or if
//there is no focused and no dominant speaker and the large video is
//currently shown
if (activeSpeakerJid === jid && VideoLayout.isLargeVideoOnTop()) {
setVisibility($("#largeVideo"), !show);
setVisibility($('#activeSpeaker'), show);
setVisibility(avatar, false);
setVisibility(video, false);
} else {
if (video && video.length > 0) {
setVisibility(video, !show);
setVisibility(avatar, show);
}
}
}
};
/**
* Updates the src of the active speaker avatar
* @param jid of the current active speaker
*/
my.updateActiveSpeakerAvatarSrc = function(jid) {
if(!jid) {
jid = connection.emuc.findJidFromResource(
VideoLayout.getLargeVideoState().userResourceJid);
}
var avatar = $("#activeSpeakerAvatar")[0];
var url = getGravatarUrl(users[jid],
interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE);
if(jid === activeSpeakerJid && avatar.src === url) {
return;
}
activeSpeakerJid = jid;
var isMuted = isUserMuted(jid);
if(jid && isMuted !== null) {
avatar.src = url;
setVisibility($("#largeVideo"), !isMuted);
Avatar.showUserAvatar(jid, isMuted);
}
};
function setVisibility(selector, show) {
if (selector && selector.length > 0) {
selector.css("visibility", show ? "visible" : "hidden");
}
}
function isUserMuted(jid) {
// XXX(gp) we may want to rename this method to something like
// isUserStreaming, for example.
if (jid && jid != connection.emuc.myroomjid) {
var resource = Strophe.getResourceFromJid(jid);
if (!VideoLayout.isInLastN(resource)) {
return true;
}
}
if (!RTC.remoteStreams[jid] || !RTC.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
return null;
}
return RTC.remoteStreams[jid][MediaStream.VIDEO_TYPE].muted;
}
function getGravatarUrl(id, size) {
if(id === connection.emuc.myroomjid || !id) {
id = SettingsMenu.getUID();
}
return 'https://www.gravatar.com/avatar/' +
MD5.hexdigest(id.trim().toLowerCase()) +
"?d=wavatar&size=" + (size || "30");
}
return my;
}(Avatar || {}));

34
bump-js-versions.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/sh
if ! which git > /dev/null 2>&1 ;then
echo "Cannot find git executable, not bumping js versions."
exit
fi
if ! git status > /dev/null 2>&1 ;then
echo "Not a git repository, not bumping js versions."
exit
fi
# This script finds all js files included from index.html which have been
# modified and bumps their version (the value of the "v" parameter used
# in index.html)
# contents of index.html at HEAD (excluding not-committed changes)
index=`git show HEAD:index.html`
# js files included from index.html. The sort needed for comm
jsfiles=.bump-js-versions-jsfiles.tmp
echo "$index" | grep '<script src=".*"' -o | sed -e 's/<script src="//' | sed -e 's/\?.*//' | tr -d \" | sort > $jsfiles
# modified files since the last commit
gitmodified=.bump-js-versions-gitmodified.tmp
git ls-files -m | sort > $gitmodified
for file in `comm -12 $jsfiles $gitmodified` ;do
old_version=`echo "$index" | grep "<script src=\"${file}?v=[0-9]*" -o | sed -e 's/.*v=//'| tr -d \"`
new_version=$((1+$old_version))
echo Bumping version of $file from $old_version to $new_version
sed -i.tmp -e "s%script src=\"${file}\?v=.*\"%script src=\"$file?v=$new_version\"%" index.html
done
rm -f $jsfiles $gitmodified index.html.tmp

343
chat.js
View File

@@ -1,343 +0,0 @@
/* global $, Util, connection, nickname:true, getVideoSize, getVideoPosition, showToolbar, processReplacements */
/**
* Chat related user interface.
*/
var Chat = (function (my) {
var notificationInterval = false;
var unreadMessages = 0;
/**
* Initializes chat related interface.
*/
my.init = function () {
var storedDisplayName = window.localStorage.displayname;
if (storedDisplayName) {
nickname = storedDisplayName;
Chat.setChatConversationMode(true);
}
$('#nickinput').keydown(function (event) {
if (event.keyCode === 13) {
event.preventDefault();
var val = Util.escapeHtml(this.value);
this.value = '';
if (!nickname) {
nickname = val;
window.localStorage.displayname = nickname;
connection.emuc.addDisplayNameToPresence(nickname);
connection.emuc.sendPresence();
Chat.setChatConversationMode(true);
return;
}
}
});
$('#usermsg').keydown(function (event) {
if (event.keyCode === 13) {
event.preventDefault();
var value = this.value;
$('#usermsg').val('').trigger('autosize.resize');
this.focus();
var command = new CommandsProcessor(value);
if(command.isCommand())
{
command.processCommand();
}
else
{
var message = Util.escapeHtml(value);
connection.emuc.sendMessage(message, nickname);
}
}
});
var onTextAreaResize = function () {
resizeChatConversation();
Chat.scrollChatToBottom();
};
$('#usermsg').autosize({callback: onTextAreaResize});
$("#chatspace").bind("shown",
function () {
unreadMessages = 0;
setVisualNotification(false);
});
addSmileys();
};
/**
* Appends the given message to the chat conversation.
*/
my.updateChatConversation = function (from, displayName, message) {
var divClassName = '';
if (connection.emuc.myroomjid === from) {
divClassName = "localuser";
}
else {
divClassName = "remoteuser";
if (!Chat.isVisible()) {
unreadMessages++;
Util.playSoundNotification('chatNotification');
setVisualNotification(true);
}
}
//replace links and smileys
var escMessage = message.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>'); //Strophe already escapes special symbols on sending, so we escape here only tags to avoid double &amp;
var escDisplayName = Util.escapeHtml(displayName);
message = processReplacements(escMessage);
var messageContainer =
'<div class="chatmessage">'+
'<img src="../images/chatArrow.svg" class="chatArrow">' +
'<div class="username ' + divClassName +'">' + escDisplayName + '</div>' +
'<div class="timestamp">' + getCurrentTime() + '</div>' +
'<div class="usermessage">' + message + '</div>' +
'</div>';
$('#chatconversation').append(messageContainer);
$('#chatconversation').animate(
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
};
/**
* Appends error message to the conversation
* @param errorMessage the received error message.
* @param originalText the original message.
*/
my.chatAddError = function(errorMessage, originalText)
{
errorMessage = Util.escapeHtml(errorMessage);
originalText = Util.escapeHtml(originalText);
$('#chatconversation').append('<div class="errorMessage"><b>Error: </b>'
+ 'Your message' + (originalText? (' \"'+ originalText + '\"') : "")
+ ' was not sent.' + (errorMessage? (' Reason: ' + errorMessage) : '')
+ '</div>');
$('#chatconversation').animate(
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
};
/**
* Sets the subject to the UI
* @param subject the subject
*/
my.chatSetSubject = function(subject)
{
if(subject)
subject = subject.trim();
$('#subject').html(linkify(Util.escapeHtml(subject)));
if(subject == "")
{
$("#subject").css({display: "none"});
}
else
{
$("#subject").css({display: "block"});
}
};
/**
* Sets the chat conversation mode.
*/
my.setChatConversationMode = function (isConversationMode) {
if (isConversationMode) {
$('#nickname').css({visibility: 'hidden'});
$('#chatconversation').css({visibility: 'visible'});
$('#usermsg').css({visibility: 'visible'});
$('#smileysarea').css({visibility: 'visible'});
$('#usermsg').focus();
}
};
/**
* Resizes the chat area.
*/
my.resizeChat = function () {
var chatSize = PanelToggler.getPanelSize();
$('#chatspace').width(chatSize[0]);
$('#chatspace').height(chatSize[1]);
resizeChatConversation();
};
/**
* Indicates if the chat is currently visible.
*/
my.isVisible = function () {
return $('#chatspace').is(":visible");
};
/**
* Shows and hides the window with the smileys
*/
my.toggleSmileys = function() {
var smileys = $('#smileysContainer');
if(!smileys.is(':visible')) {
smileys.show("slide", { direction: "down", duration: 300});
} else {
smileys.hide("slide", { direction: "down", duration: 300});
}
$('#usermsg').focus();
};
/**
* Scrolls chat to the bottom.
*/
my.scrollChatToBottom = function() {
setTimeout(function () {
$('#chatconversation').scrollTop(
$('#chatconversation')[0].scrollHeight);
}, 5);
};
/**
* Adds the smileys container to the chat
*/
function addSmileys() {
var smileysContainer = document.createElement('div');
smileysContainer.id = 'smileysContainer';
function addClickFunction(smiley, number) {
smiley.onclick = function addSmileyToMessage() {
var usermsg = $('#usermsg');
var message = usermsg.val();
message += smileys['smiley' + number];
usermsg.val(message);
usermsg.get(0).setSelectionRange(message.length, message.length);
Chat.toggleSmileys();
usermsg.focus();
};
}
for(var i = 1; i <= 21; i++) {
var smileyContainer = document.createElement('div');
smileyContainer.id = 'smiley' + i;
smileyContainer.className = 'smileyContainer';
var smiley = document.createElement('img');
smiley.src = 'images/smileys/smiley' + i + '.svg';
smiley.className = 'smiley';
addClickFunction(smiley, i);
smileyContainer.appendChild(smiley);
smileysContainer.appendChild(smileyContainer);
}
$("#chatspace").append(smileysContainer);
}
/**
* Resizes the chat conversation.
*/
function resizeChatConversation() {
var msgareaHeight = $('#usermsg').outerHeight();
var chatspace = $('#chatspace');
var width = chatspace.width();
var chat = $('#chatconversation');
var smileys = $('#smileysarea');
smileys.height(msgareaHeight);
$("#smileys").css('bottom', (msgareaHeight - 26) / 2);
$('#smileysContainer').css('bottom', msgareaHeight);
chat.width(width - 10);
chat.height(window.innerHeight - 15 - msgareaHeight);
}
/**
* Shows/hides a visual notification, indicating that a message has arrived.
*/
function setVisualNotification(show) {
var unreadMsgElement = document.getElementById('unreadMessages');
var unreadMsgBottomElement = document.getElementById('bottomUnreadMessages');
var glower = $('#chatButton');
var bottomGlower = $('#chatBottomButton');
if (unreadMessages) {
unreadMsgElement.innerHTML = unreadMessages.toString();
unreadMsgBottomElement.innerHTML = unreadMessages.toString();
ToolbarToggler.dockToolbar(true);
var chatButtonElement
= document.getElementById('chatButton').parentNode;
var leftIndent = (Util.getTextWidth(chatButtonElement) -
Util.getTextWidth(unreadMsgElement)) / 2;
var topIndent = (Util.getTextHeight(chatButtonElement) -
Util.getTextHeight(unreadMsgElement)) / 2 - 3;
unreadMsgElement.setAttribute(
'style',
'top:' + topIndent +
'; left:' + leftIndent + ';');
var chatBottomButtonElement
= document.getElementById('chatBottomButton').parentNode;
var bottomLeftIndent = (Util.getTextWidth(chatBottomButtonElement) -
Util.getTextWidth(unreadMsgBottomElement)) / 2;
var bottomTopIndent = (Util.getTextHeight(chatBottomButtonElement) -
Util.getTextHeight(unreadMsgBottomElement)) / 2 - 2;
unreadMsgBottomElement.setAttribute(
'style',
'top:' + bottomTopIndent +
'; left:' + bottomLeftIndent + ';');
if (!glower.hasClass('icon-chat-simple')) {
glower.removeClass('icon-chat');
glower.addClass('icon-chat-simple');
}
}
else {
unreadMsgElement.innerHTML = '';
unreadMsgBottomElement.innerHTML = '';
glower.removeClass('icon-chat-simple');
glower.addClass('icon-chat');
}
if (show && !notificationInterval) {
notificationInterval = window.setInterval(function () {
glower.toggleClass('active');
bottomGlower.toggleClass('active glowing');
}, 800);
}
else if (!show && notificationInterval) {
window.clearInterval(notificationInterval);
notificationInterval = false;
glower.removeClass('active');
bottomGlower.removeClass('glowing');
bottomGlower.addClass('active');
}
}
/**
* Returns the current time in the format it is shown to the user
* @returns {string}
*/
function getCurrentTime() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
if(hour.toString().length === 1) {
hour = '0'+hour;
}
if(minute.toString().length === 1) {
minute = '0'+minute;
}
if(second.toString().length === 1) {
second = '0'+second;
}
return hour+':'+minute+':'+second;
}
return my;
}(Chat || {}));

View File

@@ -1,20 +0,0 @@
<html>
<head>
<title>Jitsi Meet: Unsupported Browser</title>
<link rel="stylesheet" type="text/css" media="screen" href="css/chromeonly.css" />
</head>
<body>
<!-- wrap starts here -->
<div id="wrap">
<a href="http://google.com/chrome"><div id="left"></div></a>
<div id="middle"></div>
<div id="text">
<p>This application is currently only supported by <a href="http://google.com/chrome">Chrome</a>, <a href="http://www.chromium.org/">Chromium</a> and <a href="http://www.opera.com">Opera</a></p>
<p><a href="http://google.com/chrome">Download Chrome</a></p>
<p class="firefox">We are hoping that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=977864">multistream support</a> for Firefox would not be long so that we could all use this application with our favorite browser.</p>
</div>
<!-- wrap ends here -->
</div>
</body>
</html>

View File

@@ -1,98 +0,0 @@
/**
* Handles commands received via chat messages.
*/
var CommandsProcessor = (function()
{
/**
* Constructs new CommandProccessor instance from a message.
* @param message the message
* @constructor
*/
function CommandsPrototype(message)
{
/**
* Extracts the command from the message.
* @param message the received message
* @returns {string} the command
*/
function getCommand(message)
{
if(message)
{
for(var command in commands)
{
if(message.indexOf("/" + command) == 0)
return command;
}
}
return "";
};
var command = getCommand(message);
/**
* Returns the name of the command.
* @returns {String} the command
*/
this.getCommand = function()
{
return command;
}
var messageArgument = message.substr(command.length + 2);
/**
* Returns the arguments of the command.
* @returns {string}
*/
this.getArgument = function()
{
return messageArgument;
}
}
/**
* Checks whether this instance is valid command or not.
* @returns {boolean}
*/
CommandsPrototype.prototype.isCommand = function()
{
if(this.getCommand())
return true;
return false;
}
/**
* Processes the command.
*/
CommandsPrototype.prototype.processCommand = function()
{
if(!this.isCommand())
return;
commands[this.getCommand()](this.getArgument());
}
/**
* Processes the data for topic command.
* @param commandArguments the arguments of the topic command.
*/
var processTopic = function(commandArguments)
{
var topic = Util.escapeHtml(commandArguments);
connection.emuc.setSubject(topic);
}
/**
* List with supported commands. The keys are the names of the commands and
* the value is the function that processes the message.
* @type {{String: function}}
*/
var commands = {
"topic" : processTopic
};
return CommandsPrototype;
})();

View File

@@ -1,4 +1,5 @@
var config = {
// configLocation: './config.json', // see ./modules/HttpConfigFetch.js
hosts: {
domain: 'jitsi-meet.example.com',
//anonymousdomain: 'guest.example.com',
@@ -20,17 +21,24 @@ var config = {
chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension
desktopSharingSources: ['screen', 'window'],
minChromeExtVersion: '0.1', // Required version of Chrome extension
enableRtpStats: true, // Enables RTP stats processing
openSctp: true, // Toggle to enable/disable SCTP channels
disableStats: false,
disableAudioLevels: false,
channelLastN: -1, // The default value of the channel attribute last-n.
adaptiveLastN: false,
adaptiveSimulcast: false,
useRtcpMux: true,
useBundle: true,
enableRecording: false,
enableWelcomePage: true,
enableSimulcast: false,
enableFirefoxSupport: false, //firefox support is still experimental, only one-to-one conferences with chrome focus
// will work when simulcast, bundle, mux, lastN and SCTP are disabled.
logStats: false // Enable logging of PeerConnection stats via the focus
enableSimulcast: false, // blocks FF support
logStats: false, // Enable logging of PeerConnection stats via the focus
// requireDisplayName: true,//Forces the participants that doesn't have display name to enter it when they enter the room.
// startAudioMuted: 10, //every participant after the Nth will start audio muted
// startVideoMuted: 10, //every participant after the Nth will start video muted
// defaultLanguage: "en",
// To enable sending statistics to callstats.io you should provide Applicaiton ID and Secret.
// callStatsID: "",//Application ID for callstats.io API
// callStatsSecret: ""//Secret for callstats.io API
/*noticeMessage: 'Service update is scheduled for 16th March 2015. ' +
'During that time service will not be available. ' +
'Apologise for inconvenience.'*/
};

View File

@@ -1,127 +0,0 @@
var ConnectionQuality = (function () {
/**
* Constructs new ConnectionQuality object
* @constructor
*/
function ConnectionQuality() {
}
/**
* local stats
* @type {{}}
*/
var stats = {};
/**
* remote stats
* @type {{}}
*/
var remoteStats = {};
/**
* Interval for sending statistics to other participants
* @type {null}
*/
var sendIntervalId = null;
/**
* Updates the local statistics
* @param data new statistics
*/
ConnectionQuality.updateLocalStats = function (data) {
stats = data;
VideoLayout.updateLocalConnectionStats(100 - stats.packetLoss.total,stats);
if(sendIntervalId == null)
{
startSendingStats();
}
};
/**
* Start statistics sending.
*/
function startSendingStats() {
sendStats();
sendIntervalId = setInterval(sendStats, 10000);
}
/**
* Sends statistics to other participants
*/
function sendStats() {
connection.emuc.addConnectionInfoToPresence(convertToMUCStats(stats));
connection.emuc.sendPresence();
}
/**
* Converts statistics to format for sending through XMPP
* @param stats the statistics
* @returns {{bitrate_donwload: *, bitrate_uplpoad: *, packetLoss_total: *, packetLoss_download: *, packetLoss_upload: *}}
*/
function convertToMUCStats(stats) {
return {
"bitrate_download": stats.bitrate.download,
"bitrate_upload": stats.bitrate.upload,
"packetLoss_total": stats.packetLoss.total,
"packetLoss_download": stats.packetLoss.download,
"packetLoss_upload": stats.packetLoss.upload
};
}
/**
* Converts statitistics to format used by VideoLayout
* @param stats
* @returns {{bitrate: {download: *, upload: *}, packetLoss: {total: *, download: *, upload: *}}}
*/
function parseMUCStats(stats) {
return {
bitrate: {
download: stats.bitrate_download,
upload: stats.bitrate_upload
},
packetLoss: {
total: stats.packetLoss_total,
download: stats.packetLoss_download,
upload: stats.packetLoss_upload
}
};
}
/**
* Updates remote statistics
* @param jid the jid associated with the statistics
* @param data the statistics
*/
ConnectionQuality.updateRemoteStats = function (jid, data) {
if(data == null || data.packetLoss_total == null)
{
VideoLayout.updateConnectionStats(jid, null, null);
return;
}
remoteStats[jid] = parseMUCStats(data);
VideoLayout.updateConnectionStats(jid, 100 - data.packetLoss_total,remoteStats[jid]);
};
/**
* Stops statistics sending.
*/
ConnectionQuality.stopSendingStats = function () {
clearInterval(sendIntervalId);
sendIntervalId = null;
//notify UI about stopping statistics gathering
VideoLayout.onStatsStop();
};
/**
* Returns the local statistics.
*/
ConnectionQuality.getStats = function () {
return stats;
}
return ConnectionQuality;
})();

View File

@@ -1,186 +0,0 @@
/**
* Contact list.
*/
var ContactList = (function (my) {
var numberOfContacts = 0;
var notificationInterval;
/**
* Indicates if the chat is currently visible.
*
* @return <tt>true</tt> if the chat is currently visible, <tt>false</tt> -
* otherwise
*/
my.isVisible = function () {
return $('#contactlist').is(":visible");
};
/**
* Adds a contact for the given peerJid if such doesn't yet exist.
*
* @param peerJid the peerJid corresponding to the contact
* @param id the user's email or userId used to get the user's avatar
*/
my.ensureAddContact = function(peerJid, id) {
var resourceJid = Strophe.getResourceFromJid(peerJid);
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
if (!contact || contact.length <= 0)
ContactList.addContact(peerJid,id);
};
/**
* Adds a contact for the given peer jid.
*
* @param peerJid the jid of the contact to add
* @param id the email or userId of the user
*/
my.addContact = function(peerJid, id) {
var resourceJid = Strophe.getResourceFromJid(peerJid);
var contactlist = $('#contactlist>ul');
var newContact = document.createElement('li');
// XXX(gp) contact click event handling is now in videolayout.js. Is the
// following statement (newContact.id = resourceJid) still relevant?
newContact.id = resourceJid;
newContact.className = "clickable";
newContact.onclick = function(event) {
if(event.currentTarget.className === "clickable") {
$(ContactList).trigger('contactclicked', [peerJid]);
}
};
newContact.appendChild(createAvatar(id));
newContact.appendChild(createDisplayNameParagraph("Participant"));
var clElement = contactlist.get(0);
if (resourceJid === Strophe.getResourceFromJid(connection.emuc.myroomjid)
&& $('#contactlist>ul .title')[0].nextSibling.nextSibling)
{
clElement.insertBefore(newContact,
$('#contactlist>ul .title')[0].nextSibling.nextSibling);
}
else {
clElement.appendChild(newContact);
}
updateNumberOfParticipants(1);
};
/**
* Removes a contact for the given peer jid.
*
* @param peerJid the peerJid corresponding to the contact to remove
*/
my.removeContact = function(peerJid) {
var resourceJid = Strophe.getResourceFromJid(peerJid);
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
if (contact && contact.length > 0) {
var contactlist = $('#contactlist>ul');
contactlist.get(0).removeChild(contact.get(0));
updateNumberOfParticipants(-1);
}
};
my.setVisualNotification = function(show, stopGlowingIn) {
var glower = $('#contactListButton');
function stopGlowing() {
window.clearInterval(notificationInterval);
notificationInterval = false;
glower.removeClass('glowing');
if(!ContactList.isVisible()) {
glower.removeClass('active');
}
}
if (show && !notificationInterval) {
notificationInterval = window.setInterval(function () {
glower.toggleClass('active glowing');
}, 800);
}
else if (!show && notificationInterval) {
stopGlowing();
}
if(stopGlowingIn) {
setTimeout(stopGlowing, stopGlowingIn);
}
};
/**
* Updates the number of participants in the contact list button and sets
* the glow
* @param delta indicates whether a new user has joined (1) or someone has
* left(-1)
*/
function updateNumberOfParticipants(delta) {
//when the user is alone we don't show the number of participants
if(numberOfContacts === 0) {
$("#numberOfParticipants").text('');
numberOfContacts += delta;
} else if(numberOfContacts !== 0 && !ContactList.isVisible()) {
ContactList.setVisualNotification(true);
numberOfContacts += delta;
$("#numberOfParticipants").text(numberOfContacts);
}
}
/**
* Creates the avatar element.
*
* @return the newly created avatar element
*/
function createAvatar(id) {
var avatar = document.createElement('img');
avatar.className = "icon-avatar avatar";
avatar.src = "https://www.gravatar.com/avatar/" + id + "?d=wavatar&size=30";
return avatar;
}
/**
* Creates the display name paragraph.
*
* @param displayName the display name to set
*/
function createDisplayNameParagraph(displayName) {
var p = document.createElement('p');
p.innerText = displayName;
return p;
}
/**
* Indicates that the display name has changed.
*/
$(document).bind( 'displaynamechanged',
function (event, peerJid, displayName) {
if (peerJid === 'localVideoContainer')
peerJid = connection.emuc.myroomjid;
var resourceJid = Strophe.getResourceFromJid(peerJid);
var contactName = $('#contactlist #' + resourceJid + '>p');
if (contactName && displayName && displayName.length > 0)
contactName.html(displayName);
});
my.setClickable = function(resourceJid, isClickable) {
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
if(isClickable) {
contact.addClass('clickable');
} else {
contact.removeClass('clickable');
}
};
return my;
}(ContactList || {}));

View File

@@ -1,54 +0,0 @@
body {
width:100%;
height:100%;
background-color: white;
color: #424242;
font-family:'YanoneKaffeesatzLight',Verdana,Tahoma,Arial;
margin:0;
padding:0;
}
#wrap{
display: block;
position: absolute;
width:900px;
height: 262px;
overflow:hidden;
text-align: center;
margin: auto;
top: 0; left: 0; bottom: 0; right: 0;
}
#left{
display:inline-block;
background-image:url(../images/chromelogo.png);
background-repeat:no-repeat;
width:246px;
height:262px;
float: left;
}
.firefox{
font-size: 11pt;
color: #c8c8c8;
}
#middle{
display:inline-block;
background-image:url(../images/chromepointer.png);
background-repeat:no-repeat;
width:53px;
height:262px;
float: left;
}
#text{
display:inline-block;
font-size: 18pt;
width: 560px;
vertical-align:middle;
padding-top: 30px;
}
a {
color: #087dba;
text-decoration:none;
}

View File

@@ -3,12 +3,27 @@
cursor: default;
}
#contactlist>ul {
margin: 0px;
padding: 0px;
#contactlist>div.title {
text-align: left;
padding: 7px 10px;
margin: 2px;
color: #00ccff;
font-size: 11pt;
border-bottom: 1px solid #676767;
}
#contactlist>ul>li {
#contactlist>ul#contacts {
position: absolute;
top: 31px;
bottom: 0px;
width: 100%;
margin: 0px;
padding: 0px;
overflow-y: scroll;
overflow-x: hidden;
}
#contacts>li {
list-style-type: none;
text-align: left;
color: #FFF;
@@ -17,18 +32,12 @@
margin: 2px;
}
#contactlist>ul>li>p {
#contacts>li>p {
display: inline-block;
vertical-align: middle;
margin: 0px;
}
#contactlist>ul>li.title {
color: #00ccff;
font-size: 11pt;
border-bottom: 1px solid #676767;
}
.avatar {
padding: 0px;
margin-right: 10px;

View File

@@ -119,4 +119,8 @@
.icon-settings:before {
content: "\e61b";
}
}
.icon-dialPad:before {
content: "\e61c";
}

View File

@@ -99,5 +99,7 @@
width: 90px;
height: 16px;
padding-top: 4px;
padding-left: 10px;
padding-right: 10px;
margin: 15px auto 0px auto;
}

61
css/login_menu.css Normal file
View File

@@ -0,0 +1,61 @@
/*Initialize*/
ul.loginmenu {
display:none;
position: absolute;
margin: 0;
padding: 5px;
padding-bottom: 7px;
top: 45px;
left: -5px;
background-color: rgba(0,0,0,0.9);
border: 1px solid rgba(256, 256, 256, 0.2);
border-radius:8px;
}
ul.loginmenu li {
list-style-type: none;
padding: 7px;
}
ul.loginmenu li.identity {
color: #fff;
font-size: 11pt;
cursor: default;
}
ul.loginmenu:after {
content: url('../images/dropdownPointer.png');
display: block;
position: absolute;
top: -7px;
left: 18px;
}
li a.authButton{
background-color: #06a5df;
padding-top: 3px;
padding-bottom: 3px;
padding-left: 29px;
padding-right: 29px;
border-radius: 4px;
color: #fff;
font-size: 11pt;
cursor: pointer;
}
span.authentication:hover ul.loginmenu, ul.loginmenu:hover {
display:block !important;
}
a.disabled {
color: gray !important;
pointer-events: none;
}
.loginmenuPadding {
width: 50px;
height: 30px;
position: absolute;
top: -30px;
left: 0px;
}

View File

@@ -29,10 +29,6 @@ html, body{
z-index: 5;
}
#settings {
display:none;
}
#nowebrtc {
display:none;
}
@@ -42,17 +38,30 @@ html, body{
position: relative;
}
#toolbar a.button::after {
content: '';
display: inline-block;
position: absolute;
left: 40px;
width: 1px;
height: 20px;
background: #373737;
}
#toolbar a.button:last-child::after {
content: none;
}
.button {
display: inline-block;
position: relative;
color: #FFFFFF;
top: 0px;
padding: 10px 0px;
top: 0;
padding: 10px 0;
width: 38px;
cursor: pointer;
font-size: 11pt;
text-align: center;
text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.6);
text-shadow: 0 1px 0 rgba(255,255,255,.3), 0 -1px 0 rgba(0,0,0,.6);
z-index: 1;
}
@@ -65,13 +74,13 @@ html, body{
cursor: pointer;
}
#chatButton, #chatBottomButton, #contactListButton, #numberOfParticipants {
#toolbar_button_chat, #chatBottomButton, #contactListButton, #numberOfParticipants {
-webkit-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
}
/*#ffde00*/
#chatButton.active, #contactListButton.glowing, #chatBottomButton.glowing {
#toolbar_button_chat.active, #contactListButton.glowing, #chatBottomButton.glowing {
-webkit-text-shadow: -1px 0 10px #00ccff,
0 1px 10px #00ccff,
1px 0 10px #00ccff,
@@ -86,6 +95,11 @@ html, body{
0 -1px 10px #00ccff;
}
#toolbar_button_hangup {
color: #ff0000;
font-size: 1.4em;
}
#numberOfParticipants {
position: absolute;
top: 0px;
@@ -104,13 +118,13 @@ html, body{
color: #00ccff;
}
#recordButton {
#toolbar_button_record {
-webkit-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
}
/*#ffde00*/
#recordButton.active {
#toolbar_button_record.active {
-webkit-text-shadow: -1px 0 10px #00ccff,
0 1px 10px #00ccff,
1px 0 10px #00ccff,
@@ -159,6 +173,8 @@ a.bottomToolbarButton:hover {
}
input[type='text'], input[type='password'], textarea {
-webkit-user-select: text;
user-select: text;
display: inline-block;
font-size: 14px;
padding: 5px;

View File

@@ -26,4 +26,9 @@
button.jqidefaultbutton #inviteLinkRef {
color: #2c8ad2;
}
#inviteLinkRef {
-webkit-user-select: text;
user-select: text;
}

11
css/notice.css Normal file
View File

@@ -0,0 +1,11 @@
#notice {
position: relative;
z-index: 3;
margin-top: 6px;
}
#noticeText {
background-color: #000000;
color: white;
padding: 3px;
border-radius: 5px;
}

View File

@@ -3,7 +3,7 @@
color: #00ccff;
}
#settingsmenu input {
#settingsmenu input, select {
margin-top: 10px;
margin-left: 10%;
width: 80%;
@@ -27,8 +27,8 @@
}
#settingsmenu button {
width: 36%;
left: 32%;
width: 45%;
left: 26%;
padding: 0;
margin-top: 10px;
}
@@ -43,3 +43,26 @@
#settingsmenu .icon-settings {
padding: 34px;
}
#languages_selectbox{
height: 40px;
}
#startMutedOptions {
padding-left: 10%;
text-indent: -10%;
}
#startAudioMuted {
width: 13px !important;
}
#startVideoMuted {
width: 13px !important;
}
.startMutedLabel {
width: 94%;
float: left;
}

118
css/unsupported_browser.css Normal file
View File

@@ -0,0 +1,118 @@
body {
width:100%;
height:100%;
background-color: white;
color: #424242;
font-family:Helvetica,'YanoneKaffeesatzLight',Verdana,Tahoma,Arial;
font-size: 28px;
margin:0;
padding:0;
}
#wrap{
display: block;
position: absolute;
width:900px;
height: 365px;
overflow:hidden;
text-align: center;
margin: auto;
top: 0; left: 0; bottom: 0; right: 0;
}
.firefox{
font-size: 11pt;
color: #c8c8c8;
width: 468px;
text-align: center;
margin: 30px auto 0px auto;
padding-left: 15px;
}
#text{
display:inline-block;
font-size: 28px;
width: 568px;
vertical-align:middle;
padding-top: 25px;
}
a {
color: #087dba;
text-decoration:none;
}
.browser {
width: 138px;
height: 163px;
margin-top: 5px;
background-color: #e8e8e8;
border: 1px solid #cfcfcf;
border-radius: 10px;
}
.browser_wrapper
{
width: 138px;
height: 188px;
vertical-align: middle;
color: #929391;
font-size: 20px;
float: left;
margin-left: 15px;
}
.supported_browsers
{
margin: 0px auto 0px auto;
width: 660px;
}
.clear
{
clear: both;
}
.button
{
background-color: #62c82a;
border: 1px solid #3c8117;
border-radius: 10px;
color: #FFFFFF;
font-size: 12px;
text-align: center;
width: 115px;
height: 26px;
padding-top: 13px;
margin: 15px auto 0px auto;
}
.logo
{
margin: 20px auto 0px auto;
}
#chrome_logo
{
width: 78px;
height: 78px;
background-image: url('/images/chrome.png');
}
#chromium_logo
{
width: 77px;
height: 79px;
background-image: url('/images/chromium.png');
}
#firefox-nightly_logo
{
width: 73px;
height: 79px;
background-image: url('/images/firefox-nightly.png');
}
#opera_logo
{
width: 73px;
height: 78px;
background-image: url('/images/opera.png');
}

View File

@@ -60,28 +60,31 @@
}
#remoteVideos .videocontainer:hover {
-webkit-box-shadow: inset 0 0 10px #FFFFFF, 0 0 10px #FFFFFF;
box-shadow: inset 0 0 10px #FFFFFF, 0 0 10px #FFFFFF;
border: 2px solid #FFFFFF;
}
#remoteVideos .videocontainer.videoContainerFocused {
-webkit-box-shadow: inset 0 0 28px #006d91;
box-shadow: inset 0 0 28px #006d91;
border: 2px solid #006d91;
}
#remoteVideos .videocontainer.videoContainerFocused:hover {
-webkit-box-shadow: inset 0 0 5px #FFFFFF, 0 0 10px #FFFFFF, inset 0 0 60px #006d91;
box-shadow: inset 0 0 5px #FFFFFF, 0 0 10px #FFFFFF, inset 0 0 60px #006d91;
border: 2px solid #FFFFFF;
}
#localVideoWrapper {
display:inline-block;
-webkit-mask-box-image: url(../images/videomask.svg);
border-radius:0px !important;
border-radius:4px !important;
border: 0px !important;
}
#remoteVideos .videocontainer>video {
/* With TemasysWebRTC plugin <object/> element is used
instead of <video/> */
#remoteVideos .videocontainer>video,
#remoteVideos .videocontainer>object {
border-radius:4px;
}
@@ -92,17 +95,20 @@
-o-transform: scale(-1, 1);
}
#localVideoWrapper>video {
border-radius:0px !important;
#localVideoWrapper>video,
#localVideoWrapper>object {
border-radius:4px !important;
}
#largeVideo,
#largeVideoWrapper,
#largeVideoContainer {
overflow: hidden;
text-align: center;
}
#largeVideo
#largeVideo,
#largeVideoWrapper
{
object-fit: cover;
}
@@ -110,8 +116,13 @@
#presentation,
#etherpad,
#localVideoWrapper>video,
#localVideoWrapper>object,
#localVideoWrapper,
.videocontainer>video {
#largeVideoWrapper,
#largeVideoWrapper>video,
#largeVideoWrapper>object,
.videocontainer>video,
.videocontainer>object {
position: absolute;
left: 0;
top: 0;
@@ -129,7 +140,7 @@
z-index: 0;
}
#etherpadButton {
#toolbar_button_etherpad {
display: none;
}
@@ -363,7 +374,7 @@
margin-right: 40%;
text-align: center;
background: linear-gradient(to bottom, rgba(255,255,255,.85) , rgba(255,255,255,.35));
-webkit-box-shadow: 0 0 2px #000000, 0 0 10px #000000;
box-shadow: 0 0 2px #000000, 0 0 10px #000000;
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
display: none;
@@ -415,3 +426,54 @@
left: 35px;
border-radius: 200px;
}
.noMic {
position: absolute;
border-radius: 8px;
z-index: 1;
width: 100%;
height: 100%;
background-image: url("../images/noMic.png");
background-color: #000;
background-repeat: no-repeat;
background-position: center;
}
.noVideo {
position: absolute;
border-radius: 8px;
z-index: 1;
width: 100%;
height: 100%;
background-image: url("../images/noVideo.png");
background-color: #000;
background-repeat: no-repeat;
background-position: center;
}
.videoMessageFilter {
-webkit-filter: grayscale(.5) opacity(0.8);
filter: grayscale(.5) opacity(0.8);
}
.videoProblemFilter {
-webkit-filter: blur(10px) grayscale(.5) opacity(0.8);
filter: blur(10px) grayscale(.5) opacity(0.8);
}
#videoConnectionMessage {
display: none;
position: absolute;
width: 100%;
top:50%;
z-index: 10000;
font-weight: 600;
font-size: 14px;
text-align: center;
color: #FFF;
opacity: .80;
text-shadow: 0px 0px 1px rgba(0,0,0,0.3),
0px 1px 1px rgba(0,0,0,0.3),
1px 0px 1px rgba(0,0,0,0.3),
0px 0px 1px rgba(0,0,0,0.3);
}

14
debian/control vendored
View File

@@ -10,26 +10,26 @@ Homepage: https://jitsi.org/meet
Package: jitsi-meet
Architecture: all
Pre-Depends: jitsi-videobridge
Depends: ${misc:Depends}, nginx, jitsi-meet-prosody, libjs-strophe (>= 1.1.3),
libjs-jquery, libjs-jquery-ui
Depends: ${misc:Depends}, jitsi-videobridge, jitsi-meet-prosody, libjs-strophe (>= 1.1.3),
libjs-jquery, libjs-jquery-ui, openjdk-8-jre-headless | nginx
Description: WebRTC JavaScript video conferences
Jitsi Meet is a WebRTC JavaScript application that uses Jitsi
Videobridge to provide high quality, scalable video conferences.
.
It is a web interface to Jitsi Videobridge for audio and video
forwarding and relaying, configured to work with nginx
forwarding and relaying, configured to work with jetty instance
running embedded into Jitsi Videobridge
Package: jitsi-meet-prosody
Architecture: all
Pre-Depends: openssl, prosody | prosody-trunk, jitsi-videobridge
Depends: ${misc:Depends}, jicofo
Depends: ${misc:Depends}, openssl, prosody | prosody-trunk, jitsi-videobridge, jicofo
Description: Prosody configuration for Jitsi Meet
Jitsi Meet is a WebRTC JavaScript application that uses Jitsi
Videobridge to provide high quality, scalable video conferences.
.
It is a web interface to Jitsi Videobridge for audio and video
forwarding and relaying, configured to work with nginx
forwarding and relaying, configured to work with jetty instance
running embedded into Jitsi Videobridge
.
This package contains configuration for Prosody to be used with
Jitsi Meet.

View File

@@ -28,6 +28,15 @@ case "$1" in
# loading debconf
. /usr/share/debconf/confmodule
# detect dpkg-reconfigure, just delete old links
db_get jitsi-meet-prosody/jvb-hostname
JVB_HOSTNAME_OLD=$RET
if [ -n "$RET" ] && [ ! "$JVB_HOSTNAME_OLD" = "$JVB_HOSTNAME" ] ; then
rm -f /etc/prosody/conf.d/$JVB_HOSTNAME_OLD.cfg.lua
rm -f /etc/prosody/certs/$JVB_HOSTNAME_OLD.key
rm -f /etc/prosody/certs/$JVB_HOSTNAME_OLD.crt
fi
# stores the hostname so we will reuse it later, like in purge
db_set jitsi-meet-prosody/jvb-hostname $JVB_HOSTNAME
@@ -62,7 +71,7 @@ case "$1" in
if [ -f $PROSODY_HOST_CONFIG ] && ! grep -q "VirtualHost \"auth.$JVB_HOSTNAME\"" $PROSODY_HOST_CONFIG; then
echo -e "\nVirtualHost \"auth.$JVB_HOSTNAME\"" >> $PROSODY_HOST_CONFIG
echo -e " authentication = \"internal_plain\"\n" >> $PROSODY_HOST_CONFIG
echo -e "admins = { \"$JICOFO_AUTH_USER@auth.$JVB_HOSTNAME\" }\n" >> $PROSODY_HOST_CONFIG
sed -i "s/Component \"conference.$JVB_HOSTNAME\" \"muc\"/Component \"conference.$JVB_HOSTNAME\" \"muc\"\nadmins = { \"$JICOFO_AUTH_USER@auth.$JVB_HOSTNAME\" }\n/g" $PROSODY_HOST_CONFIG
echo -e "Component \"focus.$JVB_HOSTNAME\"" >> $PROSODY_HOST_CONFIG
echo -e " component_secret=\"$JICOFO_SECRET\"\n" >> $PROSODY_HOST_CONFIG
PROSODY_CREATE_JICOFO_USER="true"

View File

@@ -25,7 +25,7 @@ set -e
case "$1" in
remove)
if [ -x "/etc/init.d/prosody" ]; then
invoke-rc.d nginx reload
invoke-rc.d prosody reload
fi
;;

View File

@@ -1,5 +1,4 @@
Template: jitsi-meet-prosody/jvb-hostname
Type: string
Default: ${default-key}
_Description: The hostname of the current installation:
The value for the hostname that is set in Jitsi Videobridge installation.

View File

@@ -7,4 +7,5 @@ service /usr/share/jitsi-meet/
css /usr/share/jitsi-meet/
sounds /usr/share/jitsi-meet/
fonts /usr/share/jitsi-meet/
images /usr/share/jitsi-meet/
images /usr/share/jitsi-meet/
lang /usr/share/jitsi-meet/

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# postinst script for jitsi-meet
#
# see: dh_installdeb(1)
@@ -20,63 +20,159 @@ set -e
case "$1" in
configure)
. /etc/jitsi/videobridge/config
JVB_ETC_CONFIG="/etc/jitsi/videobridge/config"
JVB_CONFIG="/usr/share/jitsi-videobridge/.sip-communicator/sip-communicator.properties"
. $JVB_ETC_CONFIG
# loading debconf
. /usr/share/debconf/confmodule
# detect dpkg-reconfigure
RECONFIGURING="false"
db_get jitsi-meet/jvb-hostname
JVB_HOSTNAME_OLD=$RET
if [ -n "$RET" ] && [ ! "$JVB_HOSTNAME_OLD" = "$JVB_HOSTNAME" ] ; then
RECONFIGURING="true"
rm -f /etc/jitsi/meet/$JVB_HOSTNAME_OLD-config.js
fi
JVB_SERVE="false"
db_get jitsi-meet/jvb-serve
if [ -n "$RET" ] && [ "$RET" = "true" ] ; then
JVB_SERVE="true"
fi
# stores the hostname so we will reuse it later, like in purge
db_set jitsi-meet/jvb-hostname $JVB_HOSTNAME
# nginx conf
if [ ! -f /etc/nginx/sites-available/$JVB_HOSTNAME.conf ]; then
cp /usr/share/doc/jitsi-meet/jitsi-meet.example /etc/nginx/sites-available/$JVB_HOSTNAME.conf
if [ ! -f /etc/nginx/sites-enabled/$JVB_HOSTNAME.conf ]; then
ln -s /etc/nginx/sites-available/$JVB_HOSTNAME.conf /etc/nginx/sites-enabled/$JVB_HOSTNAME.conf
fi
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" /etc/nginx/sites-available/$JVB_HOSTNAME.conf
fi
if grep "# server_names_hash_bucket_size 64" /etc/nginx/nginx.conf > /dev/null; then
sed -i "s/#\ server_names_hash_bucket_size\ 64/\ server_names_hash_bucket_size\ 64/" /etc/nginx/nginx.conf
NGINX_INSTALL_CHECK="$(dpkg-query -W -f '${PackageSpec}:${Status}\n' nginx 2>&1 | grep -v "ok installed" || :)"
if [ -z "${NGINX_INSTALL_CHECK}" ]; then
FORCE_NGINX="true"
fi
# SSL for nginx
db_get jitsi-meet/cert-choice
CERT_CHOICE="$RET"
if [ "$CERT_CHOICE" = 'A certificate is available and the files are uploaded on the server' ]; then
db_set jitsi-meet/cert-path-key "/etc/ssl/$JVB_HOSTNAME.key"
db_input critical jitsi-meet/cert-path-key || true
db_go
db_get jitsi-meet/cert-path-key
CERT_KEY="$RET"
db_set jitsi-meet/cert-path-crt "/etc/ssl/$JVB_HOSTNAME.crt"
db_input critical jitsi-meet/cert-path-crt || true
db_go
db_get jitsi-meet/cert-path-crt
CERT_CRT="$RET"
# replace self-signed certificate paths with user provided ones
CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g')
CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g')
sed -i "s/ssl_certificate_key\ \/var\/lib\/prosody\/.*key/ssl_certificate_key\ $CERT_KEY_ESC/g" \
/etc/nginx/sites-available/$JVB_HOSTNAME.conf
CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g')
CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g')
sed -i "s/ssl_certificate\ \/var\/lib\/prosody\/.*crt/ssl_certificate\ $CERT_CRT_ESC/g" \
/etc/nginx/sites-available/$JVB_HOSTNAME.conf
fi
UPLOADED_CERT_CHOICE="A certificate is available and the files are uploaded on the server"
# jitsi meet
JITSI_MEET_CONFIG="/etc/jitsi/meet/$JVB_HOSTNAME-config.js"
if [ ! -f $JITSI_MEET_CONFIG ]; then
if [ ! -f $JITSI_MEET_CONFIG ] ; then
cp /usr/share/doc/jitsi-meet/config.js $JITSI_MEET_CONFIG
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $JITSI_MEET_CONFIG
fi
# this is new install let's configure jvb to serve meet
if [[ -z $FORCE_NGINX && ( -z $JVB_HOSTNAME_OLD || "$JVB_SERVE" = "true" ) ]] ; then
# this is a reconfigure, lets just delete old links
if [ "$RECONFIGURING" = "true" ] ; then
rm -f $JVB_CONFIG
fi
# configure jvb
echo "AUTHBIND=yes" >> $JVB_ETC_CONFIG
sed -i "s/JVB_OPTS=.*/JVB_OPTS=--apis=rest,xmpp/g" $JVB_ETC_CONFIG
echo "org.jitsi.videobridge.rest.jetty.host=::" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.port=443" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.ProxyServlet.hostHeader=$JVB_HOSTNAME" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.ProxyServlet.pathSpec=/http-bind" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.ProxyServlet.proxyTo=http://localhost:5280/http-bind" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.ResourceHandler.resourceBase=/usr/share/jitsi-meet" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.ResourceHandler.alias./config.js=/etc/jitsi/meet/$JVB_HOSTNAME-config.js" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.RewriteHandler.regex=^/([a-zA-Z0-9]+)$" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.RewriteHandler.replacement=/" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.tls.port=443" >> $JVB_CONFIG
echo "org.jitsi.videobridge.TCP_HARVESTER_PORT=443" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.sslContextFactory.keyStorePath=/etc/jitsi/videobridge/$JVB_HOSTNAME.jks" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.sslContextFactory.keyStorePassword=changeit" >> $JVB_CONFIG
# configure authbind to allow jvb to bind to privileged ports
OWNER=$(stat -c '%U' /usr/share/jitsi-videobridge)
GROUP=$(stat -c '%G' /usr/share/jitsi-videobridge)
JVB_UID="`id -u $OWNER`"
if [ ! -f "/etc/authbind/byuid/$JVB_UID" ] ; then
if [ ! -d "/etc/authbind/byuid" ] ; then
mkdir -p /etc/authbind/byuid
chmod 755 /etc/authbind
chmod 755 /etc/authbind/byuid
fi
echo '::,443' >/etc/authbind/byuid/$JVB_UID
chown $OWNER:$GROUP /etc/authbind/byuid/$JVB_UID
chmod 700 /etc/authbind/byuid/$JVB_UID
fi
if [ "$CERT_CHOICE" = "$UPLOADED_CERT_CHOICE" ] ; then
# create jks from uploaded certs
openssl pkcs12 -export \
-in /etc/ssl/$JVB_HOSTNAME.crt \
-inkey /etc/ssl/$JVB_HOSTNAME.key \
-passout pass:changeit > /etc/jitsi/videobridge/$JVB_HOSTNAME.p12
keytool -importkeystore \
-srckeystore /etc/jitsi/videobridge/$JVB_HOSTNAME.p12 \
-destkeystore /etc/jitsi/videobridge/$JVB_HOSTNAME.jks \
-srcstoretype pkcs12 \
-noprompt -storepass changeit -srcstorepass changeit
else
# create jks from self-signed certs
openssl pkcs12 -export \
-in /var/lib/prosody/$JVB_HOSTNAME.crt \
-inkey /var/lib/prosody/$JVB_HOSTNAME.key \
-passout pass:changeit > /etc/jitsi/videobridge/$JVB_HOSTNAME.p12
keytool -importkeystore \
-srckeystore /etc/jitsi/videobridge/$JVB_HOSTNAME.p12 \
-destkeystore /etc/jitsi/videobridge/$JVB_HOSTNAME.jks \
-srcstoretype pkcs12 \
-noprompt -storepass changeit -srcstorepass changeit
fi
db_set jitsi-meet/jvb-serve "true"
invoke-rc.d jitsi-videobridge restart
elif [[ "$FORCE_NGINX" = "true" || ( -n $JVB_HOSTNAME_OLD && "$JVB_SERVE" = "false" ) ]] ; then
# this is a reconfigure, lets just delete old links
if [ "$RECONFIGURING" = "true" ] ; then
rm -f /etc/nginx/sites-enabled/$JVB_HOSTNAME_OLD.conf
rm -f /etc/jitsi/meet/$JVB_HOSTNAME_OLD-config.js
fi
# nginx conf
if [ ! -f /etc/nginx/sites-available/$JVB_HOSTNAME.conf ] ; then
cp /usr/share/doc/jitsi-meet/jitsi-meet.example /etc/nginx/sites-available/$JVB_HOSTNAME.conf
if [ ! -f /etc/nginx/sites-enabled/$JVB_HOSTNAME.conf ] ; then
ln -s /etc/nginx/sites-available/$JVB_HOSTNAME.conf /etc/nginx/sites-enabled/$JVB_HOSTNAME.conf
fi
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" /etc/nginx/sites-available/$JVB_HOSTNAME.conf
fi
if [ "$CERT_CHOICE" = "$UPLOADED_CERT_CHOICE" ] ; then
db_set jitsi-meet/cert-path-key "/etc/ssl/$JVB_HOSTNAME.key"
db_input critical jitsi-meet/cert-path-key || true
db_go
db_get jitsi-meet/cert-path-key
CERT_KEY="$RET"
db_set jitsi-meet/cert-path-crt "/etc/ssl/$JVB_HOSTNAME.crt"
db_input critical jitsi-meet/cert-path-crt || true
db_go
db_get jitsi-meet/cert-path-crt
CERT_CRT="$RET"
# replace self-signed certificate paths with user provided ones
CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g')
CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g')
sed -i "s/ssl_certificate_key\ \/var\/lib\/prosody\/.*key/ssl_certificate_key\ $CERT_KEY_ESC/g" \
/etc/nginx/sites-available/$JVB_HOSTNAME.conf
CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g')
CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g')
sed -i "s/ssl_certificate\ \/var\/lib\/prosody\/.*crt/ssl_certificate\ $CERT_CRT_ESC/g" \
/etc/nginx/sites-available/$JVB_HOSTNAME.conf
fi
invoke-rc.d nginx reload
fi
# and we're done with debconf
db_stop
invoke-rc.d nginx reload
;;
abort-upgrade|abort-remove|abort-deconfigure)

View File

@@ -10,20 +10,23 @@ _Description: SSL certificate for the Jitsi Meet instance
Template: jitsi-meet/cert-path-key
Type: string
Default: ${default-key}
_Description: Full local server path to the SSL key file:
The full path to the SSL key file on the server.
If it has not been uploaded, now is a good time to do so.
Template: jitsi-meet/cert-path-crt
Type: string
Default: ${default-crt}
_Description: Full local server path to the SSL certificate file:
The full path to the SSL certificate file on the server.
If you haven't uploaded it, now is a good time to upload it in another console.
Template: jitsi-meet/jvb-hostname
Type: string
Default: ${default-key}
_Description: The hostname of the current installation:
The value for the hostname that is set in Jitsi Videobridge installation.
Template: jitsi-meet/jvb-serve
Type: boolean
Default: false
_Description: for internal use
for internal use.

View File

@@ -1,22 +1,22 @@
Description: Update the used js files for jquery to generic ones, to be able to use local system installed version (through symlinks).
Index: jitsi-meet/index.html
===================================================================
--- jitsi-meet.orig/index.html
+++ jitsi-meet/index.html
@@ -9,7 +9,7 @@
<meta itemprop="name" content="Jitsi Meet"/>
@@ -10,14 +10,14 @@
<meta itemprop="description" content="Join a WebRTC video conference powered by the Jitsi Videobridge"/>
<meta itemprop="image" content="/images/jitsilogo.png"/>
<script src="https://api.callstats.io/static/callstats.min.js"></script>
- <script src="libs/jquery-2.1.1.min.js"></script>
+ <script src="libs/jquery.min.js"></script>
<script src="config.js?v=5"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="simulcast.js?v=5"></script><!-- simulcast handling -->
<script src="libs/strophe/strophe.jingle.adapter.js?v=2"></script><!-- strophe.jingle bundles -->
@@ -24,7 +24,7 @@
<script src="libs/strophe/strophe.util.js"></script>
<script src="libs/colibri/colibri.focus.js?v=10"></script><!-- colibri focus implementation -->
<script src="libs/colibri/colibri.session.js?v=1"></script>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/1.5.0/sha.js"></script>
<script src="config.js?v=11"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="libs/strophe/strophe.min.js?v=2"></script>
<script src="libs/strophe/strophe.disco.min.js?v=1"></script>
<script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>
- <script src="libs/jquery-ui.js"></script>
+ <script src="libs/jquery-ui.min.js"></script>
<script src="libs/rayo.js?v=1"></script>
<script src="libs/tooltip.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/toastr.js?v=1"></script><!-- notifications lib -->

View File

@@ -1,7 +1,3 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
@@ -74,7 +70,6 @@ msgid ""
"uploaded it, now is a good time to upload it in another console."
msgstr ""
#. Type: string
#. Description
#: ../jitsi-meet.templates:4001
@@ -87,3 +82,17 @@ msgstr ""
msgid ""
"The value for the hostname that is set in Jitsi Videobridge installation."
msgstr ""
#. Type: string
#. Description
#: ../jitsi-meet.templates:5001
msgid "for internal use"
msgstr ""
#. Type: string
#. Description
#: ../jitsi-meet.templates:5001
msgid ""
"Jitsi Videobridge installation can use its internal jetty to serve static meet pages."
msgstr ""

12
debian/rules vendored
View File

@@ -1,10 +1,4 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
@@ -19,7 +13,7 @@ override_dh_install:
dh_installdirs
dh_install -X/config.js
yui-compressor -o debian/jitsi-meet/usr/share/jitsi-meet/libs/strophe/strophe.caps.jsonly.min.js \
debian/patches/missing-source/libs/strophe/strophe.caps.jsonly.js
debian/missing-source/libs/strophe/strophe.caps.jsonly.js
yui-compressor -o debian/jitsi-meet/usr/share/jitsi-meet/libs/strophe/strophe.disco.min.js \
debian/patches/missing-source/libs/strophe/sha1.js \
debian/patches/missing-source/libs/strophe/strophe.disco.js
debian/missing-source/libs/strophe/sha1.js \
debian/missing-source/libs/strophe/strophe.disco.js

2
debian/watch vendored Normal file
View File

@@ -0,0 +1,2 @@
version=3
opts="uversionmangle=s/^/1.0./" https://github.com/jitsi/jitsi-meet/releases/ /jitsi/jitsi-meet/archive/(\S+)\.tar\.gz

View File

@@ -1,317 +0,0 @@
/* global $, alert, changeLocalVideo, chrome, config, connection, getConferenceHandler, getUserMediaWithConstraints, VideoLayout */
/**
* Indicates that desktop stream is currently in use(for toggle purpose).
* @type {boolean}
*/
var isUsingScreenStream = false;
/**
* Indicates that switch stream operation is in progress and prevent from triggering new events.
* @type {boolean}
*/
var switchInProgress = false;
/**
* Method used to get screen sharing stream.
*
* @type {function (stream_callback, failure_callback}
*/
var obtainDesktopStream = null;
/**
* Flag used to cache desktop sharing enabled state. Do not use directly as it can be <tt>null</tt>.
* @type {null|boolean}
*/
var _desktopSharingEnabled = null;
/**
* Method obtains desktop stream from WebRTC 'screen' source.
* Flag 'chrome://flags/#enable-usermedia-screen-capture' must be enabled.
*/
function obtainWebRTCScreen(streamCallback, failCallback) {
RTC.getUserMediaWithConstraints(
['screen'],
streamCallback,
failCallback
);
}
/**
* Constructs inline install URL for Chrome desktop streaming extension.
* The 'chromeExtensionId' must be defined in config.js.
* @returns {string}
*/
function getWebStoreInstallUrl()
{
return "https://chrome.google.com/webstore/detail/" + config.chromeExtensionId;
}
/**
* Checks whether extension update is required.
* @param minVersion minimal required version
* @param extVersion current extension version
* @returns {boolean}
*/
function isUpdateRequired(minVersion, extVersion)
{
try
{
var s1 = minVersion.split('.');
var s2 = extVersion.split('.');
var len = Math.max(s1.length, s2.length);
for (var i = 0; i < len; i++)
{
var n1 = 0,
n2 = 0;
if (i < s1.length)
n1 = parseInt(s1[i]);
if (i < s2.length)
n2 = parseInt(s2[i]);
if (isNaN(n1) || isNaN(n2))
{
return true;
}
else if (n1 !== n2)
{
return n1 > n2;
}
}
// will happen if boths version has identical numbers in
// their components (even if one of them is longer, has more components)
return false;
}
catch (e)
{
console.error("Failed to parse extension version", e);
messageHandler.showError('Error',
'Error when trying to detect desktopsharing extension.');
return true;
}
}
function checkExtInstalled(isInstalledCallback) {
if (!chrome.runtime) {
// No API, so no extension for sure
isInstalledCallback(false);
return;
}
chrome.runtime.sendMessage(
config.chromeExtensionId,
{ getVersion: true },
function (response) {
if (!response || !response.version) {
// Communication failure - assume that no endpoint exists
console.warn("Extension not installed?: " + chrome.runtime.lastError);
isInstalledCallback(false);
} else {
// Check installed extension version
var extVersion = response.version;
console.log('Extension version is: ' + extVersion);
var updateRequired = isUpdateRequired(config.minChromeExtVersion, extVersion);
if (updateRequired) {
alert(
'Jitsi Desktop Streamer requires update. ' +
'Changes will take effect after next Chrome restart.');
}
isInstalledCallback(!updateRequired);
}
}
);
}
function doGetStreamFromExtension(streamCallback, failCallback) {
// Sends 'getStream' msg to the extension. Extension id must be defined in the config.
chrome.runtime.sendMessage(
config.chromeExtensionId,
{ getStream: true, sources: config.desktopSharingSources },
function (response) {
if (!response) {
failCallback(chrome.runtime.lastError);
return;
}
console.log("Response from extension: " + response);
if (response.streamId) {
RTC.getUserMediaWithConstraints(
['desktop'],
function (stream) {
streamCallback(stream);
},
failCallback,
null, null, null,
response.streamId);
} else {
failCallback("Extension failed to get the stream");
}
}
);
}
/**
* Asks Chrome extension to call chooseDesktopMedia and gets chrome 'desktop' stream for returned stream token.
*/
function obtainScreenFromExtension(streamCallback, failCallback) {
checkExtInstalled(
function (isInstalled) {
if (isInstalled) {
doGetStreamFromExtension(streamCallback, failCallback);
} else {
chrome.webstore.install(
getWebStoreInstallUrl(),
function (arg) {
console.log("Extension installed successfully", arg);
// We need to reload the page in order to get the access to chrome.runtime
window.location.reload(false);
},
function (arg) {
console.log("Failed to install the extension", arg);
failCallback(arg);
messageHandler.showError('Error',
'Failed to install desktop sharing extension');
}
);
}
}
);
}
/**
* @returns {boolean} <tt>true</tt> if desktop sharing feature is available and enabled.
*/
function isDesktopSharingEnabled() {
if (_desktopSharingEnabled === null) {
if (obtainDesktopStream === obtainScreenFromExtension) {
// Parse chrome version
var userAgent = navigator.userAgent.toLowerCase();
// We can assume that user agent is chrome, because it's enforced when 'ext' streaming method is set
var ver = parseInt(userAgent.match(/chrome\/(\d+)\./)[1], 10);
console.log("Chrome version" + userAgent, ver);
_desktopSharingEnabled = ver >= 34;
} else {
_desktopSharingEnabled = obtainDesktopStream === obtainWebRTCScreen;
}
}
return _desktopSharingEnabled;
}
function showDesktopSharingButton() {
if (isDesktopSharingEnabled()) {
$('#desktopsharing').css({display: "inline"});
} else {
$('#desktopsharing').css({display: "none"});
}
}
/**
* Call this method to toggle desktop sharing feature.
* @param method pass "ext" to use chrome extension for desktop capture(chrome extension required),
* pass "webrtc" to use WebRTC "screen" desktop source('chrome://flags/#enable-usermedia-screen-capture'
* must be enabled), pass any other string or nothing in order to disable this feature completely.
*/
function setDesktopSharing(method) {
// Check if we are running chrome
if (!navigator.webkitGetUserMedia) {
obtainDesktopStream = null;
console.info("Desktop sharing disabled");
} else if (method == "ext") {
obtainDesktopStream = obtainScreenFromExtension;
console.info("Using Chrome extension for desktop sharing");
} else if (method == "webrtc") {
obtainDesktopStream = obtainWebRTCScreen;
console.info("Using Chrome WebRTC for desktop sharing");
}
// Reset enabled cache
_desktopSharingEnabled = null;
showDesktopSharingButton();
}
/**
* Initializes <link rel=chrome-webstore-item /> with extension id set in config.js to support inline installs.
* Host site must be selected as main website of published extension.
*/
function initInlineInstalls()
{
$("link[rel=chrome-webstore-item]").attr("href", getWebStoreInstallUrl());
}
function getSwitchStreamFailed(error) {
console.error("Failed to obtain the stream to switch to", error);
switchInProgress = false;
}
function streamSwitchDone() {
//window.setTimeout(
// function () {
switchInProgress = false;
Toolbar.changeDesktopSharingButtonState(isUsingScreenStream);
// }, 100
//);
}
function newStreamCreated(stream) {
var oldStream = connection.jingle.localVideo;
connection.jingle.localVideo = stream;
VideoLayout.changeLocalVideo(stream, !isUsingScreenStream);
var conferenceHandler = getConferenceHandler();
if (conferenceHandler) {
// FIXME: will block switchInProgress on true value in case of exception
conferenceHandler.switchStreams(stream, oldStream, streamSwitchDone);
} else {
// We are done immediately
console.error("No conference handler");
messageHandler.showError('Error',
'Unable to switch video stream.');
streamSwitchDone();
}
}
/*
* Toggles screen sharing.
*/
function toggleScreenSharing() {
if (switchInProgress || !obtainDesktopStream) {
console.warn("Switch in progress or no method defined");
return;
}
switchInProgress = true;
if (!isUsingScreenStream)
{
// Switch to desktop stream
obtainDesktopStream(
function (stream) {
// We now use screen stream
isUsingScreenStream = true;
// Hook 'ended' event to restore camera when screen stream stops
stream.addEventListener('ended',
function (e) {
if (!switchInProgress && isUsingScreenStream) {
toggleScreenSharing();
}
}
);
newStreamCreated(stream);
},
getSwitchStreamFailed);
} else {
// Disable screen stream
RTC.getUserMediaWithConstraints(
['video'],
function (stream) {
// We are now using camera stream
isUsingScreenStream = false;
newStreamCreated(stream);
},
getSwitchStreamFailed, config.resolution || '360'
);
}
}

12
doc/adding-an-icon.md Normal file
View File

@@ -0,0 +1,12 @@
### Adding an icon to the font file (e.g. for the floating menu)
1. Go to https://icomoon.io/app/
2. Go to "Manage Projects" from the menu on the top left.
3. Use "Import project" and select <code>fonts/selection.json</code> from Jitsi Meet.
4. Import icons (e.g. svg files) using the "import items" button.
5. Go to "generate font" and make sure the identifiers for the new icons are correct.
6. Download the result in a zip file using the "download" button.
7. Copy <code>selection.json</code> and <code>fonts/jitsi.*</code> from the zip file to <code>fonts/</code> in Jitsi Meet
8. Copy the class for the new icon from <code>style.css</code> in the zip file to <code>css/font.css</code> in Jitsi Meet (do *not* copy the whole file)
Sample commit: https://github.com/jitsi/jitsi-meet/commit/68bc819b89aec12364fcf07b81efa83a1900eed6

View File

@@ -29,6 +29,13 @@ constructor.
```
If you don't specify room the user will enter in new conference with random room name.
You can overwrite options set in config.js and interface_config.js. For example, to enable the film-strip-only interface mode and disable simulcast, you can use:
```javascript
var configOverwrite = {enableSimulcast: false};
var interfaceConfigOverwrite = {filmStripOnly: true};
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, true, configOverwrite, interfaceConfigOverwrite);
```
Controlling embedded Jitsi Meet Conference
=========
@@ -49,13 +56,13 @@ the new display name to be set
```
api.executeCommand('displayName', ['New Nickname']);
```
* **muteAudio** - mutes / unmutes the audio for the local participant. No arguments are required.
* **toggleAudio** - mutes / unmutes the audio for the local participant. No arguments are required.
```
api.executeCommand('muteAudio', [])
api.executeCommand('toggleAudio', [])
```
* **muteVideo** - mutes / unmutes the video for the local participant. No arguments are required.
* **toggleVideo** - mutes / unmutes the video for the local participant. No arguments are required.
```
api.executeCommand('muteVideo', [])
api.executeCommand('toggleVideo', [])
```
* **toggleFilmStrip** - hides / shows the film strip. No arguments are required.
```
@@ -78,7 +85,7 @@ The ```commands``` parameter is object with keys the names of the commands and v
commands.
```
api.executeCommands({displayName: ['nickname'], muteAudio: []});
api.executeCommands({displayName: ['nickname'], toggleAudio: []});
```
You can add event listeners to the embedded Jitsi Meet using ```addEventListener``` method.
@@ -166,4 +173,4 @@ You can remove the embedded Jitsi Meet Conference with the following code:
api.dispose()
```
It is a good practice to remove the conference before the page is unloaded.
It is a good practice to remove the conference before the page is unloaded.

View File

@@ -16,6 +16,7 @@ VirtualHost "jitmeet.example.com"
}
Component "conference.jitmeet.example.com" "muc"
admins = { "focusUser@auth.jitmeet.example.com" }
Component "jitsi-videobridge.jitmeet.example.com"
component_secret = "jitmeetSecret"
@@ -23,7 +24,5 @@ Component "jitsi-videobridge.jitmeet.example.com"
VirtualHost "auth.jitmeet.example.com"
authentication = "internal_plain"
admins = { "focusUser@auth.jitmeet.example.com" }
Component "focus.jitmeet.example.com"
component_secret = "focusSecret"

View File

@@ -1,3 +1,5 @@
server_names_hash_bucket_size 64;
server {
listen 80;
server_name jitsi-meet.example.com;
@@ -17,7 +19,7 @@ server {
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
}
location ~ ^/([a-zA-Z0-9]+)$ {
location ~ ^/([a-zA-Z0-9=\?]+)$ {
rewrite ^/(.*)$ / break;
}

View File

@@ -6,7 +6,7 @@ server {
root /srv/jitsi.example.com;
index index.html;
location ~ ^/([a-zA-Z0-9]+)$ {
location ~ ^/([a-zA-Z0-9=\?]+)$ {
rewrite ^/(.*)$ / break;
}

29
doc/influxdb.md Normal file
View File

@@ -0,0 +1,29 @@
# Overview
Jitsi Meet supports logging to an [InfluxDB](http://influxdb.com/) database.
# Configuration
The following needs to be done to enable this functionality.
## Install InfluxDB
The details are outside the scope of the document, see http://influxdb.com/download/ .
## Create an InfluxDB database
Use the InfluxDB admin interface (running on port 8083) and create a database. In this example we name it <code>jitsi_database</code>
## Enable logging for Jitsi Videobridge
Add the following properties to <code>/usr/share/jitsi-videobridge/.sip-communicator/sip-communicator.properties</code>.
- org.jitsi.videobridge.log.INFLUX_DB_ENABLED=true
- org.jitsi.videobridge.log.INFLUX_URL_BASE=http://influxdb.example.com:8086
- org.jitsi.videobridge.log.INFLUX_DATABASE=jitsi_database
- org.jitsi.videobridge.log.INFLUX_USER=user
- org.jitsi.videobridge.log.INFLUX_PASS=pass
## Enable logging for Jicofo
Add the same properties as above to <code>/usr/share/jicofo/.sip-communicator/sip-communicator.properties</code>.
## Enable logging for Jitsi Meet itself
Change "logStats" to "true" in <code>/etc/jitsi/meet/you-domain.config.js</code> or the <code>config.js</code> file used in your installation.
# User interface
You can explore the database using the [Jiloin](https://github.com/jitsi/jiloin) web interface.

View File

@@ -1,39 +1,21 @@
# Server Installation for Jitsi Meet
This describes configuring a server `jitsi.example.com`. You will need to
This describes configuring a server `jitsi.example.com` running Debian or a Debian Derivative. You will need to
change references to that to match your host, and generate some passwords for
`YOURSECRET1`, `YOURSECRET2`, `YOURSECRET3` and `YOURSECRET4`.
There are also some complete [example config files](https://github.com/jitsi/jitsi-meet/tree/master/doc/example-config-files/) available, mentioned in each section.
## Install prosody and otalk modules
## Install prosody
```sh
apt-get install lsb-release
echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list
wget --no-check-certificate https://prosody.im/files/prosody-debian-packages.key -O- | sudo apt-key add -
apt-get update
apt-get install prosody-trunk
apt-get install git lua-zlib lua-sec-prosody lua-dbi-sqlite3 liblua5.1-bitop-dev liblua5.1-bitop0
git clone https://github.com/andyet/otalk-server.git
cd otalk-server
cp -r mod* /usr/lib/prosody/modules
apt-get install prosody
```
## Configure prosody
Modify the config file in `/etc/prosody/prosody.cfg.lua` (see also the example config file):
Add config file in `/etc/prosody/conf.avail/jitsi.example.com.cfg.lua` :
- add your domain virtual host section:
- modules to enable/add: compression, bosh, smacks, carbons, mam, lastactivity, offline, pubsub, adhoc, websocket, http_altconnect
- comment out: `c2s_require_encryption = true`, and `s2s_secure_auth = false`
- change `authentication = "internal_hashed"`
- add this:
```
daemonize = true
cross_domain_bosh = true;
storage = {archive2 = "sql2"}
sql = { driver = "SQLite3", database = "prosody.sqlite" }
default_archive_policy = "roster"
```
- configure your domain by editing the example.com virtual host section section:
```
VirtualHost "jitsi.example.com"
authentication = "anonymous"
@@ -41,15 +23,15 @@ VirtualHost "jitsi.example.com"
key = "/var/lib/prosody/jitsi.example.com.key";
certificate = "/var/lib/prosody/jitsi.example.com.crt";
}
modules_enabled = {
"bosh";
"pubsub";
}
```
- add domain with authentication for conference focus user:
```
VirtualHost "auth.jitsi.example.com"
authentication = "internal_plain"
ssl = {
key = "/var/lib/prosody/jitsi.example.com.key";
certificate = "/var/lib/prosody/jitsi.example.com.crt";
}
```
- add focus user to server admins:
```
@@ -64,6 +46,11 @@ Component "focus.jitsi.example.com"
component_secret = "YOURSECRET2"
```
Add link for the added configuration
```sh
ln -s /etc/prosody/conf.avail/jitsi.example.com.cfg.lua /etc/prosody/conf.d/jitsi.example.com.cfg.lua
```
Generate certs for the domain:
```sh
prosodyctl cert generate jitsi.example.com
@@ -84,39 +71,28 @@ prosodyctl restart
apt-get install nginx
```
Add nginx config for domain in `/etc/nginx/nginx.conf`:
```
tcp_nopush on;
types_hash_max_size 2048;
server_names_hash_bucket_size 64;
```
Add a new file `jitsi.example.com` in `/etc/nginx/sites-available` (see also the example config file):
```
server_names_hash_bucket_size 64;
server {
listen 80;
server_name jitsi.example.com;
# set the root
root /srv/jitsi.example.com;
index index.html;
location ~ ^/([a-zA-Z0-9]+)$ {
location ~ ^/([a-zA-Z0-9=\?]+)$ {
rewrite ^/(.*)$ / break;
}
location / {
ssi on;
}
# BOSH
location /http-bind {
proxy_pass http://localhost:5280/http-bind;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
}
# xmpp websockets
location /xmpp-websocket {
proxy_pass http://localhost:5280;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
tcp_nodelay on;
}
}
```
@@ -126,12 +102,6 @@ cd /etc/nginx/sites-enabled
ln -s ../sites-available/jitsi.example.com jitsi.example.com
```
## Fix firewall if needed
```sh
ufw allow 80
ufw allow 5222
```
## Install Jitsi Videobridge
```sh
wget https://download.jitsi.org/jitsi-videobridge/linux/jitsi-videobridge-linux-{arch-buildnum}.zip
@@ -143,6 +113,8 @@ Install JRE if missing:
apt-get install default-jre
```
_NOTE: When installing on older Debian releases keep in mind that you need JRE >= 1.7._
In the user home that will be starting Jitsi Videobridge create `.sip-communicator` folder and add the file `sip-communicator.properties` with one line in it:
```
org.jitsi.impl.neomedia.transform.srtp.SRTPCryptoContext.checkReplay=false
@@ -157,7 +129,15 @@ Or autostart it by adding the line in `/etc/rc.local`:
/bin/bash /root/jitsi-videobridge-linux-{arch-buildnum}/jvb.sh --host=localhost --domain=jitsi.example.com --port=5347 --secret=YOURSECRET1 </dev/null >> /var/log/jvb.log 2>&1
```
## Install Jitsi Conference Focus(jicofo)
## Install Jitsi Conference Focus (jicofo)
Install JDK and Ant if missing:
```
apt-get install default-jdk ant
```
_NOTE: When installing on older Debian releases keep in mind that you need JDK >= 1.7._
Clone source from Github repo:
```sh
git clone https://github.com/jitsi/jicofo.git
@@ -170,7 +150,7 @@ ant dist.{os-name}
Run jicofo:
```sh
cd dist/{os-name}'
./jicofo.sh --domain=jitsi.exmaple.com --secret=YOURSECRET2 --user_domain=auth.jitsi.example.com --user_name=focus --user_password=YOURSECRET3
./jicofo.sh --domain=jitsi.example.com --secret=YOURSECRET2 --user_domain=auth.jitsi.example.com --user_name=focus --user_password=YOURSECRET3
```
## Deploy Jitsi Meet
@@ -202,54 +182,6 @@ Restart nginx to get the new configuration:
invoke-rc.d nginx restart
```
## Install [Turn server](https://github.com/andyet/otalk-server/tree/master/restund)
```sh
apt-get install make gcc
wget http://creytiv.com/pub/re-0.4.7.tar.gz
tar zxvf re-0.4.7.tar.gz
ln -s re-0.4.7 re
cd re-0.4.7
sudo make install PREFIX=/usr
cd ..
wget http://creytiv.com/pub/restund-0.4.2.tar.gz
wget https://raw.github.com/andyet/otalk-server/master/restund/restund-auth.patch
tar zxvf restund-0.4.2.tar.gz
cd restund-0.4.2/
patch -p1 < ../restund-auth.patch
sudo make install PREFIX=/usr
cp debian/restund.init /etc/init.d/restund
chmod +x /etc/init.d/restund
cd /etc
wget https://raw.github.com/andyet/otalk-server/master/restund/restund.conf
```
Configure addresses and ports as desired, and the password to be configured in prosody:
```
realm jitsi.example.com
# share this with your prosody server
auth_shared YOURSECRET4
# modules
module_path /usr/lib/restund/modules
turn_relay_addr [turn ip address]
```
Configure prosody to use it in `/etc/prosody/prosody.cfg.lua`. Add to your virtual host:
```
turncredentials_secret = "YOURSECRET4";
turncredentials = {
{ type = "turn", host = "turn.address.ip.configured", port = 3478, transport = "tcp" }
}
```
Add turncredentials module in the "modules_enabled" section
Reload prosody if needed
```
prosodyctl restart
```
## Running behind NAT
In case of videobridge being installed on a machine behind NAT, add the following extra lines to the file `~/.sip-communicator/sip-communicator.properties` (in the home of user running the videobridge):
```
@@ -288,4 +220,4 @@ enableRecording: true
Restart jitsi-videobridge and start a new conference (making sure that the page
is reloaded with the new config.js) -- the organizer of the conference should
now have a "recoriding" button in the floating menu, near the "mute" button.
now have a "recording" button in the floating menu, near the "mute" button.

View File

@@ -1,6 +1,6 @@
# Jitsi Meet quick install
This documents decribes the needed steps for quick Jitsi Meet installation on a Debian based GNU/Linux system.
This document describes the required steps for a quick Jitsi Meet installation on a Debian based GNU/Linux system.
N.B.: All commands are supposed to be run by root. If you are logged in as a regular user with sudo rights, please prepend ___sudo___ to each of the commands.
@@ -24,13 +24,13 @@ apt-get update
apt-get -y install jitsi-meet
```
During the installation you'll be asked to enter the hostname of the Jitsi Meet instance. If you have a FQDN hostname for the instance already set ip in DNS, enter it there. If you don't have a resolvable hostname, you can enter the IP address of the machine (if it is static or doesn't change).
During the installation, you will be asked to enter the hostname of the Jitsi Meet instance. If you have a FQDN hostname for the instance already set up in DNS, enter it there. If you don't have a resolvable hostname, you can enter the IP address of the machine (if it is static or doesn't change).
This hostname (or IP address) will be used for virtualhost configuration inside the Jitsi Meet and also you and your correspondents will be using it to access the web conferences.
This hostname (or IP address) will be used for virtualhost configuration inside the Jitsi Meet and also, you and your correspondents will be using it to access the web conferences.
### Open a conference
Launch a web broswer (Chrome, Chromium or latest Opera) and enter in the URL bar the hostname (or IP address) you used in the previous step.
Launch a web browser (Chrome, Chromium or latest Opera) and enter in the URL bar the hostname (or IP address) you used in the previous step.
Confirm that you trust the self-signed certificate of the newly installed Jitsi Meet.
@@ -50,7 +50,7 @@ wget https://download.jitsi.org/jigasi_1.0-1_amd64.deb
dpkg -i jigasi_1.0-1_amd64.deb
```
During the installation you'll be asked to enter your SIP account and password. This account will be used to invite the other SIP participants.
During the installation, you will be asked to enter your SIP account and password. This account will be used to invite the other SIP participants.
### Reload Jitsi Meet
@@ -58,19 +58,17 @@ Launch again a browser with the Jitsi Meet URL and you'll see a telephone icon o
Enjoy!
## Deinstall
## Uninstall
```sh
apt-get purge jigasi jitsi-meet jicofo jitsi-videobridge
```
Somethimes the following packages will fail to uninstall properly:
Sometimes the following packages will fail to uninstall properly:
- jigasi
- jitsi-videobridge
When this happens, just run the deinstall command a second time and it should be ok.
When this happens, just run the uninstall command a second time and it should be ok.
The reason for failure is that not allways the daemons are stopped right away, there is a timeout before the actual stop. And if the unistall script goes on before the services' stop, there is an error.
The second run of the deinstall command fixes this, as by then the jigasi or jvb daemons are already stopped.
The reason for failure is that sometimes, the uninstall script is faster than the process that stops the daemons. The second run of the uninstall command fixes this, as by then the jigasi or jvb daemons are already stopped.

View File

@@ -1,17 +0,0 @@
/* global Strophe */
Strophe.addConnectionPlugin('logger', {
// logs raw stanzas and makes them available for download as JSON
connection: null,
log: [],
init: function (conn) {
this.connection = conn;
this.connection.rawInput = this.log_incoming.bind(this);
this.connection.rawOutput = this.log_outgoing.bind(this);
},
log_incoming: function (stanza) {
this.log.push([new Date().getTime(), 'incoming', stanza]);
},
log_outgoing: function (stanza) {
this.log.push([new Date().getTime(), 'outgoing', stanza]);
},
});

View File

@@ -1,206 +0,0 @@
/* global $, config, connection, dockToolbar, Moderator, Prezi,
setLargeVideoVisible, ToolbarToggler, Util, VideoLayout */
var Etherpad = (function (my) {
var etherpadName = null;
var etherpadIFrame = null;
var domain = null;
var options = "?showControls=true&showChat=false&showLineNumbers=true&useMonospaceFont=false";
/**
* Initializes the etherpad.
*/
my.init = function (name) {
if (config.etherpad_base && !etherpadName) {
domain = config.etherpad_base;
if (!name) {
// In case we're the focus we generate the name.
etherpadName = Math.random().toString(36).substring(7) +
'_' + (new Date().getTime()).toString();
shareEtherpad();
}
else
etherpadName = name;
enableEtherpadButton();
}
};
/**
* Opens/hides the Etherpad.
*/
my.toggleEtherpad = function (isPresentation) {
if (!etherpadIFrame)
createIFrame();
var largeVideo = null;
if (Prezi.isPresentationVisible())
largeVideo = $('#presentation>iframe');
else
largeVideo = $('#largeVideo');
if ($('#etherpad>iframe').css('visibility') === 'hidden') {
$('#activeSpeaker').css('visibility', 'hidden');
largeVideo.fadeOut(300, function () {
if (Prezi.isPresentationVisible()) {
largeVideo.css({opacity: '0'});
} else {
VideoLayout.setLargeVideoVisible(false);
}
});
$('#etherpad>iframe').fadeIn(300, function () {
document.body.style.background = '#eeeeee';
$('#etherpad>iframe').css({visibility: 'visible'});
$('#etherpad').css({zIndex: 2});
});
}
else if ($('#etherpad>iframe')) {
$('#etherpad>iframe').fadeOut(300, function () {
$('#etherpad>iframe').css({visibility: 'hidden'});
$('#etherpad').css({zIndex: 0});
document.body.style.background = 'black';
});
if (!isPresentation) {
$('#largeVideo').fadeIn(300, function () {
VideoLayout.setLargeVideoVisible(true);
});
}
}
resize();
};
my.isVisible = function() {
var etherpadIframe = $('#etherpad>iframe');
return etherpadIframe && etherpadIframe.is(':visible');
};
/**
* Resizes the etherpad.
*/
function resize() {
if ($('#etherpad>iframe').length) {
var remoteVideos = $('#remoteVideos');
var availableHeight
= window.innerHeight - remoteVideos.outerHeight();
var availableWidth = Util.getAvailableVideoWidth();
$('#etherpad>iframe').width(availableWidth);
$('#etherpad>iframe').height(availableHeight);
}
}
/**
* Shares the Etherpad name with other participants.
*/
function shareEtherpad() {
connection.emuc.addEtherpadToPresence(etherpadName);
connection.emuc.sendPresence();
}
/**
* Creates the Etherpad button and adds it to the toolbar.
*/
function enableEtherpadButton() {
if (!$('#etherpadButton').is(":visible"))
$('#etherpadButton').css({display: 'inline-block'});
}
/**
* Creates the IFrame for the etherpad.
*/
function createIFrame() {
etherpadIFrame = document.createElement('iframe');
etherpadIFrame.src = domain + etherpadName + options;
etherpadIFrame.frameBorder = 0;
etherpadIFrame.scrolling = "no";
etherpadIFrame.width = $('#largeVideoContainer').width() || 640;
etherpadIFrame.height = $('#largeVideoContainer').height() || 480;
etherpadIFrame.setAttribute('style', 'visibility: hidden;');
document.getElementById('etherpad').appendChild(etherpadIFrame);
etherpadIFrame.onload = function() {
document.domain = document.domain;
bubbleIframeMouseMove(etherpadIFrame);
setTimeout(function() {
//the iframes inside of the etherpad are not yet loaded when the etherpad iframe is loaded
var outer = etherpadIFrame.contentDocument.getElementsByName("ace_outer")[0];
bubbleIframeMouseMove(outer);
var inner = outer.contentDocument.getElementsByName("ace_inner")[0];
bubbleIframeMouseMove(inner);
}, 2000);
};
}
function bubbleIframeMouseMove(iframe){
var existingOnMouseMove = iframe.contentWindow.onmousemove;
iframe.contentWindow.onmousemove = function(e){
if(existingOnMouseMove) existingOnMouseMove(e);
var evt = document.createEvent("MouseEvents");
var boundingClientRect = iframe.getBoundingClientRect();
evt.initMouseEvent(
"mousemove",
true, // bubbles
false, // not cancelable
window,
e.detail,
e.screenX,
e.screenY,
e.clientX + boundingClientRect.left,
e.clientY + boundingClientRect.top,
e.ctrlKey,
e.altKey,
e.shiftKey,
e.metaKey,
e.button,
null // no related element
);
iframe.dispatchEvent(evt);
};
}
/**
* On Etherpad added to muc.
*/
$(document).bind('etherpadadded.muc', function (event, jid, etherpadName) {
console.log("Etherpad added", etherpadName);
if (config.etherpad_base && !Moderator.isModerator()) {
Etherpad.init(etherpadName);
}
});
/**
* On focus changed event.
*/
// FIXME: there is no such event as 'focusechanged.muc'
$(document).bind('focusechanged.muc', function (event, focus) {
console.log("Focus changed");
if (config.etherpad_base)
shareEtherpad();
});
/**
* On video selected event.
*/
$(document).bind('video.selected', function (event, isPresentation) {
if (!config.etherpad_base)
return;
if (etherpadIFrame && etherpadIFrame.style.visibility !== 'hidden')
Etherpad.toggleEtherpad(isPresentation);
});
/**
* Resizes the etherpad, when the window is resized.
*/
$(window).resize(function () {
resize();
});
return my;
}(Etherpad || {}));

View File

@@ -23,17 +23,21 @@ var JitsiMeetExternalAPI = (function()
* @param width width of the iframe
* @param height height of the iframe
* @param parent_node the node that will contain the iframe
* @param filmStripOnly if the value is true only the small videos will be
* visible.
* @constructor
*/
function JitsiMeetExternalAPI(domain, room_name, width, height, parent_node)
{
function JitsiMeetExternalAPI(domain, room_name, width, height, parentNode,
configOverwrite, interfaceConfigOverwrite) {
if((!width || width < MIN_WIDTH) && !filmStripOnly)
width = MIN_WIDTH;
if((!height || height < MIN_HEIGHT) && !filmStripOnly)
height = MIN_HEIGHT;
this.parentNode = null;
if(parent_node)
{
this.parentNode = parent_node;
}
else
{
if (parentNode) {
this.parentNode = parentNode;
} else {
var scriptTag = document.scripts[document.scripts.length - 1];
this.parentNode = scriptTag.parentNode;
}
@@ -41,17 +45,35 @@ var JitsiMeetExternalAPI = (function()
this.iframeHolder =
this.parentNode.appendChild(document.createElement("div"));
this.iframeHolder.id = "jitsiConference" + JitsiMeetExternalAPI.id;
if(width < MIN_WIDTH)
width = MIN_WIDTH;
if(height < MIN_HEIGHT)
height = MIN_HEIGHT;
this.iframeHolder.style.width = width + "px";
this.iframeHolder.style.height = height + "px";
if(width)
this.iframeHolder.style.width = width + "px";
if(height)
this.iframeHolder.style.height = height + "px";
this.frameName = "jitsiConferenceFrame" + JitsiMeetExternalAPI.id;
this.url = "//" + domain + "/";
if(room_name)
this.url += room_name;
this.url += "#external";
this.url += "#external=true";
var key;
if (configOverwrite) {
for (key in configOverwrite) {
if (!configOverwrite.hasOwnProperty(key) ||
typeof key !== 'string')
continue;
this.url += "&config." + key + "=" + configOverwrite[key];
}
}
if (interfaceConfigOverwrite) {
for (key in interfaceConfigOverwrite) {
if (!interfaceConfigOverwrite.hasOwnProperty(key) ||
typeof key !== 'string')
continue;
this.url += "&interfaceConfig." + key + "=" + interfaceConfigOverwrite[key];
}
}
JitsiMeetExternalAPI.id++;
this.frame = document.createElement("iframe");
@@ -80,15 +102,12 @@ var JitsiMeetExternalAPI = (function()
* Sends the passed object to Jitsi Meet
* @param object the object to be sent
*/
JitsiMeetExternalAPI.prototype.sendMessage = function(object)
{
if(this.frameLoaded)
{
JitsiMeetExternalAPI.prototype.sendMessage = function(object) {
if (this.frameLoaded) {
this.frame.contentWindow.postMessage(
JSON.stringify(object), this.frame.src);
}
else
{
else {
this.initialCommands.push(object);
}
@@ -98,8 +117,8 @@ var JitsiMeetExternalAPI = (function()
* Executes command. The available commands are:
* displayName - sets the display name of the local participant to the value
* passed in the arguments array.
* muteAudio - mutes / unmutes audio with no arguments
* muteVideo - mutes / unmutes video with no arguments
* toggleAudio - mutes / unmutes audio with no arguments
* toggleVideo - mutes / unmutes video with no arguments
* filmStrip - hides / shows the film strip with no arguments
* If the command doesn't require any arguments the parameter should be set
* to empty array or it may be omitted.
@@ -107,10 +126,9 @@ var JitsiMeetExternalAPI = (function()
* @param arguments array of arguments
*/
JitsiMeetExternalAPI.prototype.executeCommand = function(name,
argumentsList)
{
argumentsList) {
var argumentsArray = argumentsList;
if(!argumentsArray)
if (!argumentsArray)
argumentsArray = [];
var object = {type: "command", action: "execute"};
object[name] = argumentsArray;
@@ -121,8 +139,8 @@ var JitsiMeetExternalAPI = (function()
* Executes commands. The available commands are:
* displayName - sets the display name of the local participant to the value
* passed in the arguments array.
* muteAudio - mutes / unmutes audio with no arguments
* muteVideo - mutes / unmutes video with no arguments
* toggleAudio - mutes / unmutes audio with no arguments
* toggleVideo - mutes / unmutes video with no arguments
* filmStrip - hides / shows the film strip with no arguments
* @param object the object with commands to be executed. The keys of the
* object are the commands that will be executed and the values are the
@@ -135,8 +153,8 @@ var JitsiMeetExternalAPI = (function()
};
/**
* Adds event listeners to Meet Jitsi. The object key should be the name of the
* event and value - the listener.
* Adds event listeners to Meet Jitsi. The object key should be the name of
* the event and value - the listener.
* Currently we support the following
* events:
* incomingMessage - receives event notifications about incoming
@@ -170,8 +188,7 @@ var JitsiMeetExternalAPI = (function()
* @param object
*/
JitsiMeetExternalAPI.prototype.addEventListeners
= function (object)
{
= function (object) {
var message = {type: "event", action: "add", events: []};
for(var i in object)
@@ -217,8 +234,7 @@ var JitsiMeetExternalAPI = (function()
* @param listener the listener
*/
JitsiMeetExternalAPI.prototype.addEventListener
= function (event, listener)
{
= function (event, listener) {
var message = {type: "event", action: "add", events: [event]};
this.eventHandlers[event] = listener;
@@ -230,8 +246,7 @@ var JitsiMeetExternalAPI = (function()
* @param event the name of the event.
*/
JitsiMeetExternalAPI.prototype.removeEventListener
= function (event)
{
= function (event) {
if(!this.eventHandlers[event])
{
console.error("The event " + event + " is not registered.");
@@ -247,8 +262,7 @@ var JitsiMeetExternalAPI = (function()
* @param events array with the names of the events.
*/
JitsiMeetExternalAPI.prototype.removeEventListeners
= function (events)
{
= function (events) {
var eventsArray = [];
for(var i = 0; i < events.length; i++)
{
@@ -274,8 +288,7 @@ var JitsiMeetExternalAPI = (function()
* Processes message events sent from Jitsi Meet
* @param event the event
*/
JitsiMeetExternalAPI.prototype.processMessage = function(event)
{
JitsiMeetExternalAPI.prototype.processMessage = function(event) {
var message;
try {
message = JSON.parse(event.data);
@@ -285,18 +298,15 @@ var JitsiMeetExternalAPI = (function()
console.error("Message without type is received.");
return;
}
switch (message.type)
{
switch (message.type) {
case "system":
if(message.loaded)
{
if(message.loaded) {
this.onFrameLoaded();
}
break;
case "event":
if(message.action != "result" ||
!message.event || !this.eventHandlers[message.event])
{
!message.event || !this.eventHandlers[message.event]) {
console.warn("The received event cannot be parsed.");
return;
}
@@ -306,8 +316,6 @@ var JitsiMeetExternalAPI = (function()
console.error("Unknown message type.");
return;
}
};
/**
@@ -316,8 +324,7 @@ var JitsiMeetExternalAPI = (function()
*/
JitsiMeetExternalAPI.prototype.onFrameLoaded = function () {
this.frameLoaded = true;
for (var i = 0; i < this.initialCommands.length; i++)
{
for (var i = 0; i < this.initialCommands.length; i++) {
this.sendMessage(this.initialCommands[i]);
}
this.initialCommands = null;
@@ -331,13 +338,11 @@ var JitsiMeetExternalAPI = (function()
this.eventListener = function (event) {
self.processMessage(event);
};
if (window.addEventListener)
{
if (window.addEventListener) {
window.addEventListener('message',
this.eventListener, false);
}
else
{
else {
window.attachEvent('onmessage', this.eventListener);
}
};
@@ -346,13 +351,11 @@ var JitsiMeetExternalAPI = (function()
* Removes the listeners and removes the Jitsi Meet frame.
*/
JitsiMeetExternalAPI.prototype.dispose = function () {
if (window.removeEventListener)
{
if (window.removeEventListener) {
window.removeEventListener('message',
this.eventListener, false);
}
else
{
else {
window.detachEvent('onmessage',
this.eventListener);
}

Binary file not shown.

View File

@@ -35,4 +35,5 @@
<glyph unicode="&#xe619;" d="M46.993 961.7c461.234 0 553.793 0 1015.024 0 35.919 0 53.356-25.959 53.356-57.959-0.581-303.259-0.325-606.488-0.449-909.809 0-43.984-13.203-57.058-57.703-57.058-443.072-0.126-556.453-0.126-999.553 0-44.534 0-57.799 13.009-57.799 57.058-0.098 303.257 0.485 608.072-0.093 911.329-0.034 26.21 11.301 53.761 47.217 56.439zM311.405 450.298c0-119.045-0.072-172.168 0.057-291.249 0.036-50.043 11.208-61.050 62.12-61.050 233.352 0 137.075 0 370.522 0 47.075 0 59.249 11.982 59.249 58.095 0.126 239.111 0.126 346.338 0 585.389 0 48.138-10.687 58.991-57.768 58.991-235.323 0.101-140.844 0.101-376.157 0-47.044 0-57.93-11.043-57.966-58.89-0.129-119.109-0.057-172.209-0.057-291.287zM153.944 838.566c-74.929-0.062-66.687 5.958-66.845-66.685-0.201-63.95-7.054-63.534 62.528-63.372 72.999 0.194 67.201-3.764 67.302 67.554 0 67.722 4.087 62.595-62.985 62.502zM963.644 838.566c-71.159-0.034-65.56 6.185-65.751-65.364-0.129-67.302-4.508-64.693 64.528-64.693 73.089 0 65.299-2.031 65.299 66.238-0.003 68.646 6.956 63.911-64.076 63.818zM216.828 122.408c0.359 73.094 4.639 66.914-67.358 67.17-68.104 0.191-62.569 2.763-62.407-63.31 0.129-73.476-6.954-66.52 67.074-66.649 66.042-0.065 63.142-6.056 62.691 62.789zM1027.718 124.4c0.134 68.334 6.443 65.304-63.297 65.178-70.132-0.132-66.656 5.793-66.527-65.304 0.129-70.645-4.384-64.721 63.756-64.657 71.995 0.132 66.202-6.698 66.068 64.783zM1027.718 342.077c0 70.55 7.219 66.842-67.485 66.522-0.898 0-1.873 0-2.838 0-59.375 0-59.375 0-59.375-58.023 0-77.922-6.443-69.936 69.293-70.196 66.076-0.387 60.539-3.091 60.405 61.697zM151.307 489.873c68.295-0.163 65.815-5.568 65.624 62.982-0.194 71.128 4.895 64.917-66.014 65.010-69.905 0.101-63.813 4.704-63.885-63.978-0.062-67.431-5.7-64.463 64.275-64.014zM961.263 489.873c72.511-0.258 66.589-4.603 66.455 64.494 0 68.558 6.185 63.537-64.267 63.498-70.196-0.028-65.686 6.053-65.498-65.493 0.132-62.5 0.067-62.5 63.31-62.5zM150.399 280.38c71.004 0 66.659-6.567 66.466 64.528-0.163 63.694-0.036 63.501-65.013 63.756-70.805 0.258-64.822 2.673-64.822-63.756 0.036-69.167-5.919-64.788 63.369-64.528z" horiz-adv-x="1115" />
<glyph unicode="&#xe61a;" d="M3.881 146.835h220.26v-210.835h-220.26v210.835zM308.817 350.143h220.27v-414.143h-220.27v414.143zM613.764 553.412h220.268v-617.412h-220.268v617.412zM918.685 756.715h220.265v-820.715h-220.265v820.715zM1223.629 960h220.263v-1024h-220.263v1024z" horiz-adv-x="1444" />
<glyph unicode="&#xe61b;" d="M526.071 234.749c-28.637-30.869-56.465-60.861-84.282-90.859-51.578-55.636-103.047-111.376-154.842-166.832-7.606-8.135-15.958-16.1-25.317-22.012-28.075-17.708-58.31-18.090-88.472-6.492-59.84 23.028-80.004 90.727-59.734 139.234 5.413 12.95 13.721 23.601 23.709 33.173 70.256 67.351 140.506 134.717 210.76 202.077 15.638 14.993 31.264 29.995 47.364 45.45-9.302 9.529-18.386 18.833-27.451 28.137-12.122 12.442-13.234 20.28-5.067 35.498 4.735 8.816 4.789 8.878-2.627 16.198-20.012 19.72-40.168 39.198-63.498 55.188-27.167 18.624-57.161 24.233-89.083 19.849-53.402-7.328-91.609-38.372-121.413-81.046-12.774-18.299-15.365-40.313-17.517-61.875-3.23-32.245-2.415-64.479 2.209-96.597 1.654-11.515-3.863-16.539-13.835-11.175-8.306 4.448-16.095 11.048-22.115 18.353-15.574 18.89-22.223 42.042-27.474 65.395-12.955 57.652-8.86 114.49 12.191 169.495 32.345 84.537 79.743 159.571 145.953 221.932 13.659 12.857 176.841 180.564 202.944 207.021 7.493 7.599 14.895 7.635 22.393 0.028 43.009-43.641 85.985-87.316 128.927-131.029 8.117-8.267 8.019-15.097-0.222-23.49-26.339-26.834-52.726-53.627-79.106-80.419-6.244-6.334-97.34-82.437-73.027-128.816 22.693-25.090 46.196-49.449 69.575-73.904 1.189-1.238 4.686-1.386 6.523-0.632 3.63 1.499 6.848 3.997 10.248 6.066 9.745 5.94 19.545 4.918 27.812-3.083 11.755-11.381 23.405-22.858 35.392-34.59 4.807 4.575 9.939 9.41 15.027 14.294 27.128 26.039 54.272 52.071 81.351 78.146 16.413 15.778 18.652 28.418 11.038 49.658-10.473 29.221-14.356 59.677-13.85 90.624 1.017 61.045 20.438 115.334 61.003 161.416 32.825 37.286 72.054 64.311 121.643 74.325 35.227 7.101 69.139 4.513 100.663-14.026 6.365-3.752 11.908-9.007 17.455-14.005 3.491-3.125 3.153-6.236-0.565-9.98-42.503-42.885-84.772-86.013-127.154-129.035-12.442-12.638-12.356-23.167 0.196-35.914 40.344-40.978 80.597-82.050 120.936-123.052 10.076-10.233 19.537-10.021 29.504 0.134 43.195 44.077 86.449 88.090 129.706 132.118 1.21 1.233 2.572 2.322 5.135 4.624 5.491-5.893 11.895-10.924 15.961-17.406 19.452-30.944 22.608-64.83 17.073-100.25-14.253-91.080-97.188-175.638-197.712-190.123-39.977-5.764-79.372-2.562-118.067 9.031-5.898 1.775-11.541 4.629-17.538 5.829-12.47 2.474-23.872-0.366-32.74-9.877-30.921-33.168-61.674-66.484-92.474-99.758-0.73-0.805-1.349-1.718-0.181-1.099 8.992-10.006 17.354-20.662 27.061-29.94 81.064-77.54 164.91-151.986 250.882-224.063 9.936-8.347 10.274-15.695 1.040-25.1-42.338-43.068-84.689-86.111-127.059-129.154-9.413-9.575-16.846-9.152-25.291 1.295-76.686 94.78-156.8 186.609-239.707 276.002-1.334 1.453-2.562 3.029-4.257 5.042z" horiz-adv-x="1105" />
<glyph unicode="&#xe61c;" d="M74.418 881.299h239.304v-228.491h-239.304v228.491zM393.455 881.299h239.304v-228.491h-239.304v228.491zM712.494 881.299h239.263v-228.491h-239.263v228.491zM74.418 562.265h239.304v-228.555h-239.304v228.555zM393.455 562.265h239.304v-228.555h-239.304v228.555zM712.494 562.265h239.263v-228.555h-239.263v228.555zM74.418 243.166h239.304v-228.465h-239.304v228.465zM393.455 243.166h239.304v-228.465h-239.304v228.465zM712.494 243.166h239.263v-228.465h-239.263v228.465z" horiz-adv-x="1026" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,59 @@
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M74.418 78.701h239.304v228.491h-239.304v-228.491z",
"M393.455 78.701h239.304v228.491h-239.304v-228.491z",
"M712.494 78.701h239.263v228.491h-239.263v-228.491z",
"M74.418 397.735h239.304v228.555h-239.304v-228.555z",
"M393.455 397.735h239.304v228.555h-239.304v-228.555z",
"M712.494 397.735h239.263v228.555h-239.263v-228.555z",
"M74.418 716.834h239.304v228.465h-239.304v-228.465z",
"M393.455 716.834h239.304v228.465h-239.304v-228.465z",
"M712.494 716.834h239.263v228.465h-239.263v-228.465z"
],
"attrs": [
{},
{},
{},
{},
{},
{},
{},
{},
{}
],
"isMulticolor": false,
"width": 1026,
"grid": 0,
"tags": [
"dailPad"
]
},
"attrs": [
{},
{},
{},
{},
{},
{},
{},
{},
{}
],
"properties": {
"order": 29,
"id": 0,
"prevSize": 32,
"code": 58908,
"name": "dialPad"
},
"setIdx": 0,
"setId": 2,
"iconIdx": 0
},
{
"icon": {
"paths": [
@@ -31,7 +84,8 @@
"code": 58907,
"name": "settings"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 0
},
{
@@ -74,7 +128,8 @@
"name": "webCam",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 1
},
{
@@ -144,7 +199,8 @@
"name": "connection",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 2
},
{
@@ -168,7 +224,8 @@
"name": "filmstrip",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 3
},
{
@@ -194,7 +251,8 @@
"name": "reload",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 4
},
{
@@ -218,7 +276,8 @@
"name": "hangup",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 5
},
{
@@ -242,7 +301,8 @@
"name": "contactList",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 6
},
{
@@ -267,7 +327,8 @@
"name": "avatar",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 7
},
{
@@ -292,7 +353,8 @@
"name": "callRetro",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 8
},
{
@@ -317,7 +379,8 @@
"name": "callModern",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 9
},
{
@@ -343,7 +406,8 @@
"name": "recDisable",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 10
},
{
@@ -370,7 +434,8 @@
"name": "recEnable",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 11
},
{
@@ -395,7 +460,8 @@
"name": "kick1",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 12
},
{
@@ -421,7 +487,8 @@
"name": "kick",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 13
},
{
@@ -447,7 +514,8 @@
"name": "share-desktop",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 14
},
{
@@ -471,7 +539,8 @@
"name": "chat-simple",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 15
},
{
@@ -497,7 +566,8 @@
"name": "full-screen",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 16
},
{
@@ -523,7 +593,8 @@
"name": "exit-full-screen",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 17
},
{
@@ -552,7 +623,8 @@
"name": "prezi",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 18
},
{
@@ -595,7 +667,8 @@
"name": "addNew-V5",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 19
},
{
@@ -621,7 +694,8 @@
"name": "chat",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 20
},
{
@@ -648,7 +722,8 @@
"name": "presentation",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 21
},
{
@@ -672,7 +747,8 @@
"name": "security",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 22
},
{
@@ -697,7 +773,8 @@
"name": "share-doc",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 23
},
{
@@ -721,7 +798,8 @@
"name": "security-locked",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 24
},
{
@@ -746,7 +824,8 @@
"name": "camera-disabled",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 25
},
{
@@ -772,7 +851,8 @@
"name": "mic-disabled",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 26
},
{
@@ -797,7 +877,8 @@
"name": "microphone",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 27
}
],

BIN
images/chrome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/chromium.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
images/dropdownPointer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

BIN
images/firefox-nightly.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
images/firefox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
images/noMic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
images/noVideo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
images/opera.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -9,83 +9,42 @@
<meta itemprop="name" content="Jitsi Meet"/>
<meta itemprop="description" content="Join a WebRTC video conference powered by the Jitsi Videobridge"/>
<meta itemprop="image" content="/images/jitsilogo.png"/>
<script src="https://api.callstats.io/static/callstats.min.js"></script>
<script src="libs/jquery-2.1.1.min.js"></script>
<script src="config.js?v=5"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="simulcast.js?v=8"></script><!-- simulcast handling -->
<script src="libs/strophe/strophe.jingle.adapter.js?v=4"></script><!-- strophe.jingle bundles -->
<script src="libs/strophe/strophe.min.js?v=1"></script>
<script src="config.js?v=12"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="libs/strophe/strophe.min.js?v=2"></script>
<script src="libs/strophe/strophe.disco.min.js?v=1"></script>
<script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>
<script src="libs/strophe/strophe.jingle.js?v=2"></script>
<script src="libs/strophe/strophe.jingle.sdp.js?v=4"></script>
<script src="libs/strophe/strophe.jingle.session.js?v=4"></script>
<script src="libs/strophe/strophe.util.js"></script>
<script src="libs/jquery-ui.js"></script>
<script src="libs/rayo.js?v=1"></script>
<script src="libs/tooltip.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/pako.bundle.js?v=1"></script><!-- zlib deflate -->
<script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
<script src="interface_config.js?v=5"></script>
<script src="muc.js?v=17"></script><!-- simple MUC library -->
<script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
<script src="desktopsharing.js?v=3"></script><!-- desktop sharing -->
<script src="app.js?v=23"></script><!-- application logic -->
<script src="commands.js?v=1"></script><!-- application logic -->
<script src="chat.js?v=15"></script><!-- chat logic -->
<script src="contact_list.js?v=8"></script><!-- contact list logic -->
<script src="side_panel_toggler.js?v=1"></script>
<script src="util.js?v=7"></script><!-- utility functions -->
<script src="etherpad.js?v=10"></script><!-- etherpad plugin -->
<script src="prezi.js?v=7"></script><!-- prezi plugin -->
<script src="smileys.js?v=3"></script><!-- smiley images -->
<script src="replacement.js?v=7"></script><!-- link and smiley replacement -->
<script src="moderatemuc.js?v=4"></script><!-- moderator plugin -->
<script src="libs/app.bundle.js?v=130"></script>
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
<script src="videolayout.js?v=32"></script><!-- video ui -->
<script src="connectionquality.js?v=1"></script>
<script src="toolbar.js?v=7"></script><!-- toolbar ui -->
<script src="toolbar_toggler.js?v=2"></script>
<script src="canvas_util.js?v=1"></script><!-- canvas drawing utils -->
<script src="audio_levels.js?v=4"></script><!-- audio levels plugin -->
<script src="media_stream.js?v=2"></script><!-- media stream -->
<script src="bottom_toolbar.js?v=6"></script><!-- media stream -->
<script src="moderator.js?v=2"></script><!-- media stream -->
<script src="roomname_generator.js?v=1"></script><!-- generator for random room names -->
<script src="keyboard_shortcut.js?v=3"></script>
<script src="recording.js?v=1"></script>
<script src="tracking.js?v=1"></script><!-- tracking -->
<script src="jitsipopover.js?v=3"></script>
<script src="message_handler.js?v=2"></script>
<script src="api_connector.js?v=2"></script>
<script src="settings_menu.js?v=1"></script>
<script src="service/RTC/RTCBrowserType.js?v=1"></script>
<script src="service/RTC/StreamEventTypes.js?v=1"></script>
<script src="service/RTC/MediaStreamTypes.js?v=1"></script>
<script src="libs/modules/statistics.bundle.js?v=2"></script>
<script src="libs/modules/RTC.bundle.js?v=2"></script>
<script src="avatar.js?v=4"></script><!-- avatars -->
<link rel="stylesheet" href="css/font.css?v=6"/>
<link rel="stylesheet" href="css/font.css?v=7"/>
<link rel="stylesheet" href="css/toastr.css?v=1">
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=30"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=16" id="videolayout_default"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=31"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=20" id="videolayout_default"/>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
<link rel="stylesheet" href="css/modaldialog.css?v=3">
<link rel="stylesheet" href="css/notice.css?v=1">
<link rel="stylesheet" href="css/popup_menu.css?v=4">
<link rel="stylesheet" href="css/login_menu.css?v=1">
<link rel="stylesheet" href="css/popover.css?v=2">
<link rel="stylesheet" href="css/jitsi_popover.css?v=2">
<link rel="stylesheet" href="css/contact_list.css?v=4">
<link rel="stylesheet" href="css/chat.css?v=5">
<link rel="stylesheet" href="css/welcome_page.css?v=2">
<link rel="stylesheet" href="css/settingsmenu.css?v=1">
<link rel="stylesheet" href="css/settingsmenu.css?v=2">
<!--
Link used for inline installation of chrome desktop streaming extension,
is updated automatically from the code with the value defined in config.js -->
<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/diibjkoicjeejcmhdnailmkgecihlobk">
<script src="libs/jquery-impromptu.js"></script>
<script src="libs/jquery-impromptu.js?v=2"></script>
<script src="libs/jquery.autosize.js"></script>
<script src="libs/prezi_player.js?v=2"></script>
<!--#include virtual="plugin.head.html" -->
</head>
<body>
<div id="welcome_page">
@@ -96,184 +55,116 @@
<a target="_new">
<div class="watermark rightwatermark"></div>
</a>
<a class="poweredby" href="http://jitsi.org" target="_new" >powered by jitsi.org</a>
<a class="poweredby" href="http://jitsi.org" target="_new" ><span data-i18n="poweredby"></span> jitsi.org</a>
<div id="enter_room_container">
<div id="enter_room_form" >
<div id="domain_name"></div>
<div id="enter_room">
<input id="enter_room_field" type="text" autofocus placeholder="Enter room name" />
<input id="enter_room_field" type="text" autofocus data-i18n="[placeholder]welcomepage.roomname" placeholder="Enter room name" />
<div class="icon-reload" id="reload_roomname"></div>
<input id="enter_room_button" type="button" value="GO" />
<input id="enter_room_button" type="button" data-i18n="[value]welcomepage.go" value="GO" />
</div>
</div>
</div>
<div id="brand_header"></div>
<input type='checkbox' name='checkbox' id="disable_welcome"/>
<label for="disable_welcome" class="disable_welcome_position">Don't show this page next time I enter</label>
<div id="header_text"></div>
<label for="disable_welcome" class="disable_welcome_position" data-i18n="welcomepage.disable"></label>
<div id="header_text">
<!--#include virtual="plugin.header.text.html" -->
</div>
</div>
<div id="welcome_page_main">
<div id="features">
<div class="feature_row">
<div class="feature_holder">
<div class="feature_icon">Simple to use</div>
<div class="feature_description">
No downloads required. <span name="appName"></span> works directly within your browser. Simply share your conference URL with others to get started.
<div class="feature_icon" data-i18n="welcomepage.feature1.title" ></div>
<div class="feature_description" data-i18n="welcomepage.feature1.content" data-i18n-options='{ "postProcess": "resolveAppName" }'>
</div>
</div>
<div class="feature_holder">
<div class="feature_icon">Low bandwidth</div>
<div class="feature_description">
Multi-party video conferences work with as little as 128Kbps. Screen-sharing and audio-only conferences are possible with far less.
<div class="feature_icon" data-i18n="welcomepage.feature2.title" ></div>
<div class="feature_description" data-i18n="welcomepage.feature2.content">
</div>
</div>
<div class="feature_holder">
<div class="feature_icon">Open source</div>
<div class="feature_description">
<span name="appName"></span> is licensed under MIT. You are free to download, use, modify, and share them as per these licenses.
<div class="feature_icon" data-i18n="welcomepage.feature3.title" ></div>
<div class="feature_description" data-i18n="welcomepage.feature3.content" data-i18n-options='{ "postProcess": "resolveAppName" }'>
</div>
</div>
<div class="feature_holder">
<div class="feature_icon">Unlimited users</div>
<div class="feature_description">
There are no artificial restrictions on the number of users or conference participants. Server power and bandwidth are the only limiting factors.
<div class="feature_icon" data-i18n="welcomepage.feature4.title" ></div>
<div class="feature_description" data-i18n="welcomepage.feature4.content">
</div>
</div>
</div>
<div class="feature_row">
<div class="feature_holder">
<div class="feature_icon">Screen sharing</div>
<div class="feature_description">
It's easy to share your screen with others. <span name="appName"></span> is ideal for on-line presentations, lectures, and tech support sessions.
</div>
<div class="feature_icon" data-i18n="welcomepage.feature5.title" ></div>
<div class="feature_description" data-i18n="welcomepage.feature5.content" data-i18n-options='{ "postProcess": "resolveAppName" }'>
</div>
</div>
<div class="feature_holder">
<div class="feature_icon">Secure rooms</div>
<div class="feature_description">
Need some privacy? <span name="appName"></span> conference rooms can be secured with a password in order to exclude unwanted guests and prevent interruptions.
</div>
<div class="feature_icon" data-i18n="welcomepage.feature6.title" ></div>
<div class="feature_description" data-i18n="welcomepage.feature6.content" data-i18n-options='{ "postProcess": "resolveAppName" }'>
</div>
</div>
<div class="feature_holder">
<div class="feature_icon">Shared notes</div>
<div class="feature_description">
<span name="appName"></span> features Etherpad, a real-time collaborative text editor that's great for meeting minutes, writing articles, and more.
</div>
<div class="feature_icon" data-i18n="welcomepage.feature7.title" ></div>
<div class="feature_description" data-i18n="welcomepage.feature7.content" data-i18n-options='{ "postProcess": "resolveAppName" }'></div>
</div>
<div class="feature_holder">
<div class="feature_icon">Usage statistics</div>
<div class="feature_description">
Learn about your users through easy integration with Piwik, Google Analytics, and other usage monitoring and statistics systems.
</div>
<div class="feature_icon" data-i18n="welcomepage.feature8.title" ></div>
<div class="feature_description" data-i18n="welcomepage.feature8.content"></div>
</div>
</div>
</div>
</div>
<!--#include virtual="plugin.welcomepage.footer.html" -->
</div>
<div id="videoconference_page">
<div style="position: relative;" id="header_container">
<div id="header">
<div id="notice" class="notice" style="display: none">
<span id="noticeText" class="noticeText"></span>
</div>
<span id="toolbar">
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="mutePopover" content="Mute / Unmute" onclick='toggleAudio();'>
<i id="mute" class="icon-microphone"></i>
<span id="authentication" class="authentication" style="display: none">
<a class="button icon-avatar" id="toolbar_button_authentication" data-i18n="[content]toolbar.authenticate"></a>
<ul class="loginmenu">
<span class="loginmenuPadding"></span>
<li id="toolbar_auth_identity" class="identity"></li>
<li id="toolbar_button_login">
<a class="authButton" data-i18n="toolbar.login"></a>
</li>
<li id="toolbar_button_logout">
<a class="authButton" data-i18n="toolbar.logout"></a>
</li>
</ul>
</span>
<a class="button icon-microphone" id="toolbar_button_mute" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="mutePopover" data-i18n="[content]toolbar.mute" content="Mute / Unmute"></a>
<a class="button icon-camera" id="toolbar_button_camera" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="toggleVideoPopover" data-i18n="[content]toolbar.videomute" content="Start / stop camera"></a>
<a class="button icon-recEnable" id="toolbar_button_record" data-container="body" data-toggle="popover" data-placement="bottom" data-i18n="[content]toolbar.record" content="Record" style="display: none"></a>
<a class="button icon-security" id="toolbar_button_security" data-container="body" data-toggle="popover" data-placement="bottom" data-i18n="[content]toolbar.lock" content="Lock / unlock room"></a>
<a class="button icon-link" id="toolbar_button_link" data-container="body" data-toggle="popover" data-placement="bottom" data-i18n="[content]toolbar.invite" content="Invite others"></a>
<a class="button icon-chat" id="toolbar_button_chat" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="bottom" data-i18n="[content]toolbar.chat" content="Open / close chat">
<span id="unreadMessages"></span>
</a>
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="toggleVideoPopover" content="Start / stop camera" onclick='toggleVideo();'>
<i id="video" class="icon-camera"></i>
</a>
<span id="authentication" style="display: none">
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Authenticate" onclick='authenticateClicked();'>
<i id="authButton" class="icon-avatar"></i>
</a>
</span>
<span id="recording" style="display: none">
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Record" onclick='toggleRecording();'>
<i id="recordButton" class="icon-recEnable"></i>
</a>
</span>
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Lock / unlock room" onclick="Toolbar.openLockDialog();">
<i id="lockIcon" class="icon-security"></i>
</a>
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Invite others" onclick="Toolbar.openLinkDialog();">
<i class="icon-link"></i>
</a>
<div class="header_button_separator"></div>
<span class="toolbar_span">
<a class="button" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="bottom" content="Open / close chat" onclick='BottomToolbar.toggleChat();'>
<i id="chatButton" class="icon-chat">
<span id="unreadMessages"></span>
</i>
</a>
</span>
<span id="prezi_button">
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Share Prezi" onclick='Prezi.openPreziDialog();'>
<i class="icon-prezi"></i>
</a>
</span>
<span id="etherpadButton">
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Shared document" onclick='Etherpad.toggleEtherpad(0);'>
<i class="icon-share-doc"></i>
</a>
</span>
<div class="header_button_separator"></div>
<span id="desktopsharing" style="display: none">
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Share screen" onclick="toggleScreenSharing();">
<i class="icon-share-desktop"></i>
</a>
</span>
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Enter / Exit Full Screen" onclick='buttonClick("#fullScreen", "icon-full-screen icon-exit-full-screen");Toolbar.toggleFullScreen();'>
<i id="fullScreen" class="icon-full-screen"></i>
</a>
<span id="sipCallButton" style="display: none">
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Call SIP number" onclick='callSipButtonClicked();'>
<i class="icon-telephone"></i></a>
</span>
<div class="header_button_separator"></div>
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Settings" onclick='PanelToggler.toggleSettingsMenu();'>
<i id="settingsButton" class="icon-settings"></i>
</a>
<div class="header_button_separator"></div>
<span id="hangup">
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Hang Up" onclick='hangup();'>
<i class="icon-hangup" style="color:#ff0000;font-size: 1.4em;"></i>
</a>
</span>
<a class="button icon-prezi" id="toolbar_button_prezi" data-container="body" data-toggle="popover" data-placement="bottom" data-i18n="[content]toolbar.prezi" content="Share Prezi"></a>
<a class="button icon-share-doc" id="toolbar_button_etherpad" data-container="body" data-toggle="popover" data-placement="bottom" content="Shared document" data-i18n="[content]toolbar.etherpad"></a>
<a class="button icon-share-desktop" id="toolbar_button_desktopsharing" data-container="body" data-toggle="popover" data-placement="bottom" content="Share screen" data-i18n="[content]toolbar.sharescreen" style="display: none"></a>
<a class="button icon-full-screen" id="toolbar_button_fullScreen" data-container="body" data-toggle="popover" data-placement="bottom" content="Enter / Exit Full Screen" data-i18n="[content]toolbar.fullscreen"></a>
<a class="button icon-telephone" id="toolbar_button_sip" data-container="body" data-toggle="popover" data-placement="bottom" content="Call SIP number" data-i18n="[content]toolbar.sip" style="display: none"></a>
<a class="button icon-dialpad" id="toolbar_button_dialpad" data-container="body" data-toggle="popover" data-placement="bottom" content="Open dialpad" data-i18n="[content]toolbar.dialpad" style="display: none"></a>
<a class="button icon-settings" id="toolbar_button_settings" data-container="body" data-toggle="popover" data-placement="bottom" content="Settings" data-i18n="[content]toolbar.Settings"></a>
<a class="button icon-hangup" id="toolbar_button_hangup" data-container="body" data-toggle="popover" data-placement="bottom" content="Hang Up" data-i18n="[content]toolbar.hangup"></a>
</span>
</div>
<div id="subject"></div>
</div>
<div id="settings">
<h1>Connection Settings</h1>
<form id="loginInfo">
<label>JID: <input id="jid" type="text" name="jid" placeholder="me@example.com"/></label>
<label>Password: <input id="password" type="password" name="password" placeholder="secret"/></label>
<label>BOSH URL: <input id="boshURL" type="text" name="boshURL" placeholder="/http-bind"/></label>
<input id="connect" type="submit" value="Connect" />
</form>
</div>
<div id="reloadPresentation"><a onclick='Prezi.reloadPresentation();'><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
<div id="videospace" onmousemove="ToolbarToggler.showToolbar();">
<div id="largeVideoContainer" class="videocontainer">
<div id="presentation"></div>
<div id="etherpad"></div>
<a target="_new"><div class="watermark leftwatermark"></div></a>
<a target="_new"><div class="watermark rightwatermark"></div></a>
<a class="poweredby" href="http://jitsi.org" target="_new" >powered by jitsi.org</a>
<div id="activeSpeaker">
<img id="activeSpeakerAvatar" src=""/>
<canvas id="activeSpeakerAudioLevel"></canvas>
</div>
<video id="largeVideo" autoplay oncontextmenu="return false;"></video>
</div>
<div id="reloadPresentation"><a id="reloadPresentationLink"><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
<div id="videospace">
<div id="remoteVideos">
<span id="localVideoContainer" class="videocontainer">
<span id="localNick" class="nick"></span>
@@ -282,18 +173,13 @@
</span>
<audio id="localAudio" autoplay oncontextmenu="return false;" muted></audio>
<span class="focusindicator"></span>
<!--<div class="connectionindicator">
<span class="connection connection_empty"><i class="icon-connection"></i></span>
<span class="connection connection_full"><i class="icon-connection"></i></span>
</div>-->
</span>
<audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
<audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>
</div>
<span id="bottomToolbar">
<span class="bottomToolbar_span">
<a class="bottomToolbarButton" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="top" content="Open / close chat" onclick='BottomToolbar.toggleChat();'>
<a class="bottomToolbarButton" id="bottom_toolbar_chat" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="top" data-i18n="[content]bottomtoolbar.chat" content="Open / close chat">
<i id="chatBottomButton" class="icon-chat-simple">
<span id="bottomUnreadMessages"></span>
</i>
@@ -301,7 +187,7 @@
</span>
<div class="bottom_button_separator"></div>
<span class="bottomToolbar_span">
<a class="bottomToolbarButton" data-container="body" data-toggle="popover" data-placement="top" id="contactlistpopover" content="Open / close contact list" onclick='BottomToolbar.toggleContactList();'>
<a class="bottomToolbarButton" id="bottom_toolbar_contact_list" data-container="body" data-toggle="popover" data-placement="top" id="contactlistpopover" data-i18n="[content]bottomtoolbar.contactlist" content="Open / close contact list">
<i id="contactListButton" class="icon-contactList">
<span id="numberOfParticipants"></span>
</i>
@@ -309,7 +195,7 @@
</span>
<div class="bottom_button_separator"></div>
<span class="bottomToolbar_span">
<a class="bottomToolbarButton" data-container="body" data-toggle="popover" shortcut="filmstripPopover" data-placement="top" content="Show / hide film strip" onclick='BottomToolbar.toggleFilmStrip()'>
<a class="bottomToolbarButton" id="bottom_toolbar_film_strip" data-container="body" data-toggle="popover" shortcut="filmstripPopover" data-placement="top" data-i18n="[content]bottomtoolbar.filmstrip" content="Show / hide film strip">
<i id="filmStripButton" class="icon-filmstrip"></i>
</a>
</span>
@@ -317,36 +203,47 @@
</div>
<div id="chatspace" class="right-panel">
<div id="nickname">
Enter a nickname in the box below
<span data-i18n="chat.nickname.title"></span>
<form>
<input type='text' id="nickinput" placeholder='Choose a nickname' autofocus>
<input type='text' id="nickinput" data-i18n="[placeholder]chat.nickname.popover" autofocus>
</form>
</div>
<!--div><i class="fa fa-comments">&nbsp;</i><span class='nick'></span>:&nbsp;<span class='chattext'></span></div-->
<div id="chatconversation"></div>
<audio id="chatNotification" src="sounds/incomingMessage.wav" preload="auto"></audio>
<textarea id="usermsg" placeholder='Enter text...' autofocus></textarea>
<textarea id="usermsg" data-i18n="[placeholder]chat.messagebox" autofocus></textarea>
<div id="smileysarea">
<div id="smileys" onclick="Chat.toggleSmileys()">
<div id="smileys" id="toggle_smileys">
<img src="images/smile.svg"/>
</div>
</div>
</div>
<div id="contactlist" class="right-panel">
<ul>
<li class="title"><i class="icon-contact-list"></i> CONTACT LIST</li>
</ul>
<div class="title">
<i class="icon-contactList"><span data-i18n="contactlist"></span></i>
</div>
<ul id="contacts"></ul>
</div>
<div id="settingsmenu" class="right-panel">
<div class="icon-settings"> SETTINGS</div>
<div class="icon-settings" data-i18n="settings.title"></div>
<img id="avatar" src="https://www.gravatar.com/avatar/87291c37c25be69a072a4514931b1749?d=wavatar&size=30"/>
<div class="arrow-up"></div>
<input type="text" id="setDisplayName" placeholder="Name">
<input type="text" id="setDisplayName" data-i18n="[placeholder]settings.name" placeholder="Name">
<input type="text" id="setEmail" placeholder="E-Mail">
<button onclick="SettingsMenu.update()" id="updateSettings">Update</button>
<div id = "startMutedOptions">
<label class = "startMutedLabel">
<input type="checkbox" id="startAudioMuted">
<span data-i18n="settings.startAudioMuted"></span>
</label>
<label class = "startMutedLabel">
<input type="checkbox" id="startVideoMuted">
<span data-i18n="settings.startVideoMuted"></span>
</label>
</div>
<button id="updateSettings" data-i18n="settings.update"></button>
</div>
<a id="downloadlog" onclick='dump(event.target);' data-container="body" data-toggle="popover" data-placement="right" data-content="Download logs" ><i class="fa fa-cloud-download"></i></a>
<a id="downloadlog" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[data-content]downloadlogs" ><i class="fa fa-cloud-download"></i></a>
</div>
</body>
</html>

View File

@@ -5,15 +5,19 @@ var interfaceConfig = {
INITIAL_TOOLBAR_TIMEOUT: 20000,
TOOLBAR_TIMEOUT: 4000,
DEFAULT_REMOTE_DISPLAY_NAME: "Fellow Jitster",
DEFAULT_DOMINANT_SPEAKER_DISPLAY_NAME: "Speaker",
DEFAULT_DOMINANT_SPEAKER_DISPLAY_NAME: "speaker",
DEFAULT_LOCAL_DISPLAY_NAME: "me",
SHOW_JITSI_WATERMARK: true,
JITSI_WATERMARK_LINK: "http://jitsi.org",
JITSI_WATERMARK_LINK: "https://jitsi.org",
SHOW_BRAND_WATERMARK: false,
BRAND_WATERMARK_LINK: "",
SHOW_POWERED_BY: false,
GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
APP_NAME: "Jitsi Meet",
INVITATION_POWERED_BY: true,
ACTIVE_SPEAKER_AVATAR_SIZE: 100
ACTIVE_SPEAKER_AVATAR_SIZE: 100,
/**
* Whether to only show the filmstrip (and hide the toolbar).
*/
filmStripOnly: false
};

View File

@@ -1,79 +0,0 @@
var KeyboardShortcut = (function(my) {
//maps keycode to character, id of popover for given function and function
var shortcuts = {
67: {
character: "C",
id: "toggleChatPopover",
function: BottomToolbar.toggleChat
},
70: {
character: "F",
id: "filmstripPopover",
function: BottomToolbar.toggleFilmStrip
},
77: {
character: "M",
id: "mutePopover",
function: toggleAudio
},
84: {
character: "T",
function: function() {
if(!isAudioMuted()) {
toggleAudio();
}
}
},
86: {
character: "V",
id: "toggleVideoPopover",
function: toggleVideo
}
};
window.onkeyup = function(e) {
var keycode = e.which;
if(!($(":focus").is("input[type=text]") || $(":focus").is("input[type=password]") || $(":focus").is("textarea"))) {
if (typeof shortcuts[keycode] === "object") {
shortcuts[keycode].function();
} else if (keycode >= "0".charCodeAt(0) && keycode <= "9".charCodeAt(0)) {
var remoteVideos = $(".videocontainer:not(#mixedstream)"),
videoWanted = keycode - "0".charCodeAt(0) + 1;
if (remoteVideos.length > videoWanted) {
remoteVideos[videoWanted].click();
}
}
//esc while the smileys are visible hides them
} else if (keycode === 27 && $('#smileysContainer').is(':visible')) {
Chat.toggleSmileys();
}
};
window.onkeydown = function(e) {
if(!($(":focus").is("input[type=text]") || $(":focus").is("input[type=password]") || $(":focus").is("textarea"))) {
if(e.which === "T".charCodeAt(0)) {
if(isAudioMuted()) {
toggleAudio();
}
}
}
};
/**
*
* @param id indicates the popover associated with the shortcut
* @returns {string} the keyboard shortcut used for the id given
*/
my.getShortcut = function(id) {
for(var keycode in shortcuts) {
if(shortcuts.hasOwnProperty(keycode)) {
if (shortcuts[keycode].id === id) {
return " (" + shortcuts[keycode].character + ")";
}
}
}
return "";
};
return my;
}(KeyboardShortcut || {}))

57
lang/Translation.md Normal file
View File

@@ -0,0 +1,57 @@
Jitsi Meet Translation
==========================
Jitsi Meet uses [i18next](http://i18next.com) library for translation.
i18next uses separate json files for each language.
Translating Jitsi Meet
======================
The translation of Jitsi Meet is integrated with Pootle. You can translate Jitsi Meet via our Pootle user interface on
[http://translate.jitsi.org](http://translate.jitsi.org).
**WARNING: Please don't create or edit manually the language files! Please use our Pootle user interface!**
Development
===========
If you want to add new functionality for Jitsi Meet and you have texts that need to be translated please use our translation module.
It is located in modules/translation. You must add key and value in main.json file in English for each translatable text.
Than you can use the key to get the translated text for the current language.
**WARNING: Please don't change the other language files except main.json! They must be updated and translated via our Pootle user interface!**
You can add translatable text in the HTML:
* **via attribute on HTML element** - add **data-i18n** attribute with value the key of the translatable text.
```
<span data-i18n="dialog.OK">OK</span>
```
You can also use APP.translation.generateTranslationHTML(key, options) to get this HTML code as Javascript string.
```
APP.translation.generateTranslationHTML("dialog.OK") // returns <span data-i18n="dialog.OK">OK</span>
```
The value in the options parameter will be added in data-i18n-options attribute of the element.
**Note:** If you dynamically add HTML elements don't forget to call APP.translation.translateElement(jquery_selector) to translate the text initially.
* **via Javascript string** - call APP.translation.translateString(key, options). You can use that method to get the translated string in Javascript and then attach it in the HTML.
```
APP.translation.translateString("dialog.OK") // returns the value for the key of the current language file. "OK" for example.
```
For the available values of ``options`` parameter for the above methods of translation module see [i18next documentation](http://i18next.com/pages/doc_features).
**Note:** It is useful to add attributes in the HTML for persistent HTML elements because when the language is changed the text will be automatically translated.
Otherwise you should call ``APP.translation.translateString`` and manually change the text every time the language is changed.

7
lang/languages-bg.json Normal file
View File

@@ -0,0 +1,7 @@
{
"en": "Английски",
"bg": "Български",
"de": "Немски",
"tr": "Турски",
"it": "Италиански"
}

9
lang/languages-de.json Normal file
View File

@@ -0,0 +1,9 @@
{
"en": "Englisch",
"bg": "Bulgarisch",
"de": "Deutsch",
"tr": "Türkisch",
"it": "Italienisch",
"fr": "Französisch",
"sl": "Slowenisch"
}

7
lang/languages-fr.json Normal file
View File

@@ -0,0 +1,7 @@
{
"en": "Anglais",
"bg": "Bulgare",
"de": "Allemand",
"tr": "Turc",
"it": "Italien"
}

7
lang/languages-it.json Normal file
View File

@@ -0,0 +1,7 @@
{
"en": "Inglese",
"bg": "Bulgaro",
"de": "Tedesco",
"tr": "Turco",
"it": "Italiano"
}

9
lang/languages-sl.json Normal file
View File

@@ -0,0 +1,9 @@
{
"en": "Angleščina",
"bg": "Bolgarščina",
"de": "Nemščina",
"tr": "Turščina",
"it": "Italjanščina",
"fr": "Francoščina",
"sl": ""
}

5
lang/languages-tr.json Normal file
View File

@@ -0,0 +1,5 @@
{
"en": "İngilizce",
"bg": "Bulgarca",
"de": "Almanca"
}

9
lang/languages.json Normal file
View File

@@ -0,0 +1,9 @@
{
"en": "English",
"bg": "Bulgarian",
"de": "German",
"tr": "Turkish",
"it": "Italian",
"fr": "French",
"sl": "Slovenian"
}

224
lang/main-bg.json Normal file
View File

@@ -0,0 +1,224 @@
{
"contactlist": "СПИСЪК С КОНТАКТИ",
"connectionsettings": "Настройки на връзката",
"poweredby": "powered by",
"downloadlogs": "Изтегли логовете",
"roomUrlDefaultMsg": "Конференцията се създава...",
"participant": "Участник",
"me": "аз",
"speaker": "Говорител",
"defaultNickname": "например __name__",
"defaultPreziLink": "например __url__",
"welcomepage": {
"go": "Влез",
"roomname": "Въведете име на стаята",
"disable": "Не показвай страницата следващия път",
"feature1": {
"title": "Лесен за употреба",
"content": "Не е необходимо да сваляте нищо. _app_ работи директно във вашия браузър. Просто споделете адреса на вашата конференция с другите за да започнете."
},
"feature2": {
"title": "",
"content": "Видео конференциите могат да работят с по-малко от 128Kbps, а аудио конференциите и конференциите с споделен екран дори с по-малко."
},
"feature3": {
"title": "Отворен код",
"content": "__app__ е лицензиран под MIT лиценз. Можете свободно да го изтеглите, използвате, променяте и споделяте според тези лицензи."
},
"feature4": {
"title": "Неограничен брой потребители",
"content": "Няма изкуствени ограничения за броя на потребителите или участниците в конференция. Единствените ограничения са мощността на вашия сървър и качеството на интернет връзката му."
},
"feature5": {
"title": "Споделяне на екрана",
"content": "Лесно е да споделите екрана си с другите. __app__ е идеален за онлайн презентации, лекции и техническа подръжка."
},
"feature6": {
"title": "Сигурни стаи",
"content": "Нуждаете се от уединение? _app__ конферентните стай могат да бъдат защитени от парола за да се препазите от нежелани гости или прекъсвания."
},
"feature7": {
"title": "Споделени бележки",
"content": "__app__ използва Etherpad, с който можете да редактирате текст в реално време заедно."
},
"feature8": {
"title": "Статистики за използване",
"content": "Научете повече за своите потребители като интегрирате лесно Piwik, Google Analytics и други статистики за изполването."
}
},
"toolbar": {
"mute": "Включи / Изключи микрофона",
"videomute": "Спри / пусни камерата",
"authenticate": "",
"record": "Запис",
"lock": "Заключи / отключи стаята",
"invite": "Поканване на други",
"chat": "",
"prezi": "Сподели Prezi",
"etherpad": "Споделяне на документ",
"sharescreen": "Споделяне на екрана",
"fullscreen": "Влез / Излез от Пълен екран",
"sip": "Обади се на SIP номер",
"Settings": "Настройки",
"hangup": "Затвори",
"login": "Влез",
"logout": ""
},
"bottomtoolbar": {
"chat": "Отвори / затвори чат",
"filmstrip": "Покажи / скрий лентата с видеа",
"contactlist": "Отвори / затвори контакт листа"
},
"chat": {
"nickname": {
"title": "Въведете име в полето",
"popover": "Избор на име"
},
"messagebox": "Въведете текст..."
},
"settings": {
"title": "НАСТРОЙКИ",
"update": "Актуализиране",
"name": "Име"
},
"videothumbnail": {
"editnickname": "Натиснете за да<br/>промените името",
"moderator": "Създателя на<br/>конференцията",
"videomute": "Учасника е спрял<br/>камерата си.",
"mute": "Учасника е с изключен микрофон",
"kick": "Изгони",
"muted": "Изключен микрофон",
"domute": "Изключи микрофона"
},
"connectionindicator": {
"bitrate": "",
"packetloss": "Загуба на пакети:",
"resolution": "Резолюция:",
"less": "Скрий",
"more": "Покажи",
"address": "Адрес:",
"remoteport": "Отдалечен порт:",
"remoteport_plural": "Отдалечени портове:",
"localport": "Локален порт:",
"localport_plural": "Локални портове:",
"localaddress": "Локален адрес:",
"localaddress_plural": "Локални адреси:",
"remoteaddress": "Отдалечен адрес:",
"remoteaddress_plural": "Отдалечени адреси:",
"transport": "Транспорт:",
"bandwidth": "",
"na": "Върнете се тук за информацията относно вашата връзка, когато започне конференцията"
},
"notify": {
"disconnected": "връзката е прекъсната",
"moderator": "Придобихте права на модератор!",
"connected": "свързан",
"somebody": "Някой",
"me": "Аз",
"focus": "Конферентен фокус",
"focusFail": "__component__ не е на раположения - следващ опит след __ms__ секунди",
"grantedTo": "Даване на роля модератор на __to__!",
"grantedToUnknown": "Даване на роля модератор на $t(somebody)!"
},
"dialog": {
"kickMessage": "Бяхте изгонен от срещата!",
"popupError": "Вашия браузър блокира попъп прозорците от този сайт. Моля позволете попъп прозорците от настройките на браузъра и опитайте пак.",
"passwordError": "Тази конференция е защитена с парола. Само създателя и може да промени паролата.",
"passwordError2": "Тази конференция не е защитена с парола. Само създателя и може да сложи парола.",
"joinError": "Не можете да се присъедините към конференцията. Може би имате проблем с конфигурацията на сифурността. Моля обърнете се към администратора на услугата.",
"connectError": "Опа! Нещо се обърка и не успяхме да се свържем с конференцията.",
"connecting": "",
"error": "",
"detectext": "Възникна грешка при опит да бъде намерено разширението за споделяне на екран.",
"failtoinstall": "Неуспешна инсталация на разширението за споделяне на екрана.",
"failedpermissions": "Неуспешен опит за получаване на права за използване на микрофон и/или камера.",
"bridgeUnavailable": "Jitsi Videobridge не е наличен. Моля опитайте пак!",
"lockTitle": "Неуспешно заключване",
"lockMessage": "Неуспешно заключване на конференцията.",
"warning": "Внимание",
"passwordNotSupported": "В момента не поддържаме стаи с пароли.",
"sorry": "Съжаляваме",
"internalError": "Вътрешна грешка [setRemoteDescription]",
"unableToSwitch": "Неуспешен опит за смяна на видеото.",
"SLDFailure": "Опа! Нещо се обърка и не успяхме да спрем микрофона! (SLD Failure)",
"SRDFailure": "Опа! Нещо се обърка и не успяхме да спрем камерата! (SRD Failure)",
"oops": "Опа!",
"defaultError": "Възникна грешка",
"passwordRequired": "Изисква се парола",
"Ok": "ОК",
"removePreziTitle": "Премахни Prezi",
"removePreziMsg": "Сигурни ли сте, че искате да премахнете Prezi?",
"sharePreziTitle": "Сподели Prezi",
"sharePreziMsg": "Друг участник вече е споделил Prezi. Тази конференция позволява само да се споделя само едно Prezi.",
"Remove": "Премахване",
"Stop": "Спиране",
"AuthMsg": "Нужна е идентификация, за да създадете стая:<br/><b>__room__</b></br> Може да се идентифицирате, за да създадете стая или да изчакате някой друг да го направи.",
"Authenticate": "Идентификация",
"Cancel": "Отказ",
"retry": "Повторен опит",
"logoutTitle": "Изход",
"logoutQuestion": "Сигурни ли сте, че искате да излезете и да прекъснете конференцията?",
"sessTerminated": "Сесията е прекъсната.",
"hungUp": "Вие затворихте обаждането.",
"joinAgain": "Песъединете се отново",
"Share": "Споделяне",
"preziLinkError": "Моля въведете правилен Prezi линк.",
"Save": "Запазване",
"recordingToken": "Въведете код за достъп за запис на конференцията",
"Dial": "Набиране",
"sipMsg": "Въведете SIP номер",
"passwordCheck": "Сигурни ли сте, че искате да махнете паролата?",
"passwordMsg": "Въведете парола, за да заключите стаята",
"Invite": "Покани",
"shareLink": "Сподели този линк с всеки, който искаш да поканиш",
"settings1": "Конфигурирай конференцията",
"settings2": "Участниците се присъединиха с изключен микрофон.",
"settings3": "Изисквай имена<br/><br/>Въведете парола за да заключите стаята:",
"yourPassword": "вашата парола",
"Back": "Назад",
"serviceUnavailable": "Услугата не е налична",
"gracefulShutdown": "Услугата временно не е достъпна поради профилактика. Моля опитайте по-късно.",
"Yes": "Да",
"reservationError": "Грешка в системата за резервации",
"reservationErrorMsg": "Грешка номер: __code__, съобщение: __msg__",
"password": "парола",
"userPassword": "потребителска парола",
"token": "код за достъп"
},
"email": {
"sharedKey": [
"Тази конференция е защитена с парола. Моля използвайте следния код за да се присъедините:",
"",
"",
"__sharedKey__",
"",
""
],
"subject": "Покана за __appName__ (__conferenceName__)",
"body": [
"Здравей, Бих искал да те поканя в една __appName__ конференция, която създадох.",
"",
"",
"Кликни на следния линк за да се присъединиш в конференцията.",
"",
"",
"__sharedKeyText__",
"__appName__ поддържа __supportedBrowsers__, така че трябва да използваш един от тези браузъри.",
"",
"",
"Ще се видим след секунда!"
],
"and": "и"
},
"connection": {
"ERROR": "Грешка",
"CONNECTING": "Свързване",
"CONNFAIL": "Връзката е неуспешна",
"AUTHENTICATING": "Идентификация",
"AUTHFAIL": "Неуспешна идентификация",
"CONNECTED": "Свързан",
"DISCONNECTED": "Изключен",
"DISCONNECTING": "Прекъсване на връзката",
"ATTACHED": "Прикрепен"
}
}

243
lang/main-de.json Normal file
View File

@@ -0,0 +1,243 @@
{
"contactlist": "Kontaktliste",
"connectionsettings": "Verbindungseinstellungen",
"poweredby": "Betrieben von",
"downloadlogs": "Log herunterladen",
"roomUrlDefaultMsg": "Die Konferenz wird erstellt...",
"participant": "Teilnehmer",
"me": "ich",
"speaker": "Sprecher",
"defaultNickname": "Bsp.: __name__",
"defaultPreziLink": "Bsp.: __url__",
"welcomepage": {
"go": "Los",
"roomname": "Raumnamen eingeben",
"disable": "Diese Seite beim nächsten Betreten nicht mehr anzeigen",
"feature1": {
"title": "Einfach zu benutzen",
"content": "Kein Download nötig. __app__ läuft direkt im Browser. Einfach die Konferenzadresse teilen und los geht's."
},
"feature2": {
"title": "Niedrige Bandbreite",
"content": "Videokonferenzen mit mehreren Teilnehmen mit weniger als 128Kpbs. Bildschirmfreigaben und Telefonkonferenzen kommen sogar mit noch weniger Bandbreite aus."
},
"feature3": {
"title": "Open Source",
"content": "__app__ steht unter der MIT Lizenz. __app__ kann gemäss der Lizenz heruntergeladen, verwendet, verändert und weitergegeben werden."
},
"feature4": {
"title": "Unbegrenzte Anzahl Benutzer",
"content": "Es gibt keine künstliche Beschränkung der Anzahl der Benutzer oder Konferenzteilnehmer. Die Leistung des Servers und die Bandbreite sind die einzigen limitierenden Faktoren."
},
"feature5": {
"title": "Bildschirmfreigabe",
"content": "Es ist ganz einfach den Bildschirm zu teilen. __app__ ist ideal für Online-Präsentationen, Vorlesungen und Fernwartungsanfragen."
},
"feature6": {
"title": "Sichere Konferenzen",
"content": "Privatsphäre gewünscht? __app__ Konferenzen können mit einem Passwort geschützt werden um ungebetene Gäste fernzuhalten und Unterbrechungen zu vermeiden."
},
"feature7": {
"title": "Freigegebene Notizen",
"content": "__app__ verwendent Etherpad, ein Editor zur kollaborativen Bearbeitung von Texten."
},
"feature8": {
"title": "Benutzungsstatistiken",
"content": "Die Verwendung kann durch die Integration mit Piwik, Google Analytics und anderen Überwachungs- und Statistikprogrammen protokolliert werden."
}
},
"toolbar": {
"mute": "Stummschaltung aktivieren / deaktivieren",
"videomute": "Kamera starten / stoppen",
"authenticate": "Anmelden",
"record": "Aufnehmen",
"lock": "Raum schützen / Schutz aufheben",
"invite": "Andere einladen",
"chat": "Chat öffnen / schliessen",
"prezi": "Prezi freigeben",
"etherpad": "Geteiltes Dokument",
"sharescreen": "Bildschirm freigeben",
"fullscreen": "Vollbildmodus aktivieren / deaktivieren",
"sip": "SIP Nummer anrufen",
"Settings": "Einstellungen",
"hangup": "Auflegen",
"login": "Anmelden",
"logout": "Abmelden",
"dialpad": "Tastenblock anzeigen"
},
"bottomtoolbar": {
"chat": "Chat öffnen / schliessen",
"filmstrip": "Videovorschauen anzeigen / verstecken",
"contactlist": "Kontaktliste öffnen / schliessen"
},
"chat": {
"nickname": {
"title": "Nickname im Eingabefeld eingeben",
"popover": "Einen Namen auswählen"
},
"messagebox": "Text eingeben..."
},
"settings": {
"title": "Einstellungen",
"update": "Aktualisieren",
"name": "Name",
"startAudioMuted": "Stumm beitreten",
"startVideoMuted": "Ohne Video beitreten"
},
"videothumbnail": {
"editnickname": "Klicken um den Anzeigenamen zu bearbeiten",
"moderator": "Besitzer dieser Konferenz",
"videomute": "Teilnehmer hat die Kamera pausiert.",
"mute": "Teilnehmer ist stumm geschaltet",
"kick": "Hinauswerfen",
"muted": "Stummgeschaltet",
"domute": "Stummschalten"
},
"connectionindicator": {
"bitrate": "Bitrate:",
"packetloss": "Paketverlust:",
"resolution": "Auflösung:",
"less": "Weniger anzeigen",
"more": "Mehr anzeigen",
"address": "Adresse:",
"remoteport": "Entfernter Port:",
"remoteport_plural": "Entfernte Ports:",
"localport": "Lokaler Port:",
"localport_plural": "Lokale Ports:",
"localaddress": "Lokale Adresse:",
"localaddress_plural": "Lokale Adressen:",
"remoteaddress": "Entfernte Adresse:",
"remoteaddress_plural": "Entfernte Adressen:",
"transport": "Protokoll:",
"bandwidth": "Geschätzte Bandbreite:",
"na": "Verbindungsdaten erneut anzeigen wenn die Konferenz begonnen hat"
},
"notify": {
"disconnected": "getrennt",
"moderator": "Moderatorenrechte vergeben",
"connected": "verbunden",
"somebody": "Jemand",
"me": "Ich",
"focus": "Konferenz-Organisator",
"focusFail": "__component__ ist im Moment nicht verfügbar - wiederholen in __ms__ Sekunden",
"grantedTo": "Moderatorenrechte an __to__ vergeben.",
"grantedToUnknown": "Moderatorenrechte an $t(somebody) vergeben.",
"muted": "Der Konferenz wurde stumm beigetreten.",
"mutedTitle": "Stummschaltung aktiv."
},
"dialog": {
"kickMessage": "Oh! Sie wurden aus der Konferenz ausgeschlossen.",
"popupError": "Ihr Browser blockiert Popups von dieser Webseite. Bitte erlauben Sie Popups in den Sicherheitseinstellungen und versuchen Sie es erneut.",
"passwordError": "Diese Konferenz ist mit einem Paswort geschützt. Nur der Besitzer der Konferenz kann ein Passwort vergeben.",
"passwordError2": "Diese Konferenzt ist nicht mit einem Passwort geschützt. Nur der Besitzer der Konferenz kann ein Passwort vergeben.",
"joinError": "Oh! Der Konferenz konnte nicht beigetreten werden. Diese könnte ein Problem mit den Sicherheitseinstellungen sein. Bitte kontaktieren Sie den Administrator des Dienstes.",
"connectError": "Oh! Es hat etwas nicht geklappt und der Konferenz konnte nicht beigetreten werden.",
"connectErrorWithMsg": "Oh! Es hat etwas nicht geklappt und der Konferenz konnte nicht beigetreten werden: __msg__",
"connecting": "Verbindung wird hergestellt",
"error": "Fehler",
"detectext": "Fehler bei der Erkennung der Bildschirmfreigabeerweiterung.",
"failtoinstall": "Die Bildschirmfreigabeerweiterung konnte nicht installiert werden.",
"failedpermissions": "Die Zugriffsberechtigungen auf das Mikrofon und/oder die Kamera konnte nicht eingeholt werden.",
"bridgeUnavailable": "Die Jitsi Videobridge ist momentan nicht erreichbar. Bitte versuchen Sie es später noch einmal.",
"lockTitle": "Sperren fehlgeschlagen",
"lockMessage": "Die Konferenz konnte nicht gesperrt werden.",
"warning": "Warnung",
"passwordNotSupported": "Passwörter für Räume werden nicht unterstützt.",
"sorry": "Entschuldigung",
"internalError": "Interner Anwendungsfehler [setRemoteDescription]",
"unableToSwitch": "Der Videodatenstrom kann nicht gewechselt werden.",
"SLDFailure": "Oh! Die Stummschaltung konnte nicht aktiviert werden. (SLD Fehler)",
"SRDFailure": "Oh! Das Video konnte nicht gestoppt werden. (SRD Fehler)",
"oops": "Oh!",
"defaultError": "Es ist ein Fehler aufgetreten",
"passwordRequired": "Passwort erforderlich",
"Ok": "OK",
"removePreziTitle": "Prezi entfernen",
"removePreziMsg": "Sind Sie sich sicher dass sie Prezi entfernen möchten?",
"sharePreziTitle": "Ein Prezi teilen",
"sharePreziMsg": "Ein anderer Teilnehmer teilt bereits ein Prezi. Diese Konferenz kann nur eine Prezi auf einmal anzeigen.",
"Remove": "Entfernen",
"WaitingForHost": "Warten auf den Organisator...",
"WaitForHostMsg": "Die Konferenz <b>__room__</b> hat noch nicht begonnen. Wenn Sie der Organisator sind, melden Sie sich bitte an. Anderenfalls warten Sie bitte bis der Organisator beigetreten ist.",
"IamHost": "Ich bin der Organisator",
"Cancel": "Abbrechen",
"retry": "Wiederholen",
"logoutTitle": "Abmelden",
"logoutQuestion": "Sind Sie sicher dass Sie sich abmelden und die Konferenz verlassen möchten?",
"sessTerminated": "Sitzung beendet",
"hungUp": "Anruf beendet",
"joinAgain": "Erneut beitreten",
"Share": "Teilen",
"preziLinkError": "Bitte einen gültigen Prezi-Link angeben.",
"Save": "Speichern",
"recordingToken": "Aufnahme-Token eingeben",
"Dial": "Wählen",
"sipMsg": "Geben Sie eine SIP Nummer ein",
"passwordCheck": "Sind Sie sicher dass Sie das Passwort entfernen möchten?",
"passwordMsg": "Passwort setzen um den Raum zu schützen",
"Invite": "Einladen",
"shareLink": "Teilen Sie diesen Link mit jedem den Sie einladen möchten",
"settings1": "Konferenz einrichten",
"settings2": "Teilnehmer treten stummgeschaltet bei",
"settings3": "Nickname erforderlich<br/><br/>Setzen Sie ein Passwort um den Raum zu schützen:",
"yourPassword": "Ihr Passwort",
"Back": "Zurück",
"serviceUnavailable": "Dienst nicht verfügbar",
"gracefulShutdown": "Der Dienst steht momentan wegen Wartungsarbeiten nicht zur Verfügung. Bitte versuchen Sie es später noch einmal.",
"Yes": "Ja",
"reservationError": "Fehler im Reservationssystem",
"reservationErrorMsg": "Fehler, Nummer: __code__, Nachricht: __msg__",
"password": "Passwort",
"userPassword": "Benutzerpasswort",
"token": "Token",
"displayNameRequired": "Geben Sie Ihren Anzeigenamen ein:"
},
"email": {
"sharedKey": [
"Diese Konferenz ist Passwortgeschützt. Bitte verwenden Sie diese PIN zum Beitreten:",
"",
"",
"__sharedKey__",
"",
""
],
"subject": "Einladung zu einer __appName__ (__conferenceName__)",
"body": [
"Hallo!",
"",
"",
"Ich möchte dich zu einer eben erstellten __appName__-Konferenz einladen.",
"",
"",
"Bitte klicke auf den folgenden Link um der Konferenz ebenfalls beizutreten:",
"",
"",
"__roomUrl__",
"",
"",
"__sharedKeyText__",
" Bitte beachte, dass __appName__ momentan nur mit einem der Browser __supportedBrowsers__ verwendet werden kann.",
"",
"",
"Bis gleich!"
],
"and": "und"
},
"connection": {
"ERROR": "Fehler",
"CONNECTING": "Verbindung wird hergestellt",
"RECONNECTING": "Es ist ein Netzwerkproblem aufgetreten. Verbinde...",
"CONNFAIL": "Verbindungsaufbau gescheitert",
"AUTHENTICATING": "Anmeldung läuft",
"AUTHFAIL": "Authentifizierung fehlgeschlagen",
"CONNECTED": "Verbunden",
"DISCONNECTED": "Getrennt",
"DISCONNECTING": "Verbindung wird getrennt",
"ATTACHED": "Angehängt"
},
"recording": {
"toaster": "Wird aufgezeichnet",
"pending": "Die Aufzeichnung wird gestartet sobald ein weiterer Teilnehmer beitritt",
"on": "Aufzeichnung wurde gestartet"
}
}

227
lang/main-fr.json Normal file
View File

@@ -0,0 +1,227 @@
{
"contactlist": "Liste de contacts",
"connectionsettings": "Paramètres de connexion",
"poweredby": "propulsé par",
"downloadlogs": "Téléchargement des logs",
"roomUrlDefaultMsg": "Votre conférence est en cours de création...",
"participant": "Participant",
"me": "moi",
"speaker": "Haut-parleur",
"defaultNickname": "ex: __name__",
"defaultPreziLink": "e.g. __url__",
"welcomepage": {
"go": "Créer",
"roomname": "Saisissez un nom de salle",
"disable": "Ne pas afficher cette page lors de ma prochaine visite",
"feature1": {
"title": "Simple à utiliser",
"content": "Aucun téléchargement requis. __app__ s'utilise directement depuis votre navigateur. Partager simplement l'URL de votre conférence avec les autres pour commencer."
},
"feature2": {
"title": "Faible bande passante",
"content": "Les vidéo conférences à plusieurs participants nécessitent moins de 128 kbps. Le partage d'écran et les conférences avec seulement de l'audio sont possibles avec beaucoup moins de débit."
},
"feature3": {
"title": "Open source",
"content": "__app__ est sous licence MIT. Vous êtes libre de le télécharger, l'utiliser, le modifier et le partager sous cette licence."
},
"feature4": {
"title": "Nombre d'utilisateurs illimité",
"content": "Il n'y a pas de restrictions artificielles concernant le nombre d'utilisateurs ou de participants à une conférence. La puissance du serveur et la bande passante sont les seuls facteurs limitants."
},
"feature5": {
"title": "Partage d'écan",
"content": "C'est facile de partager votre écran avec d'autres personnes. __app__ est idéal pour les présentations en ligne, les cours, et les sessions de support technique."
},
"feature6": {
"title": "Salles sécurisées",
"content": "Besoin de confidentialité? Les salles de conférence __app__ peuvent être sécurisées par un mot de passe pour exclure des invités non désirées, et prévenir des interruptions. "
},
"feature7": {
"title": "Notes partagées",
"content": "__app__ propose Etherpad, un éditeur de texte collaboratif en temps réel qui est parfait pour les procès-verbaux, l'édition d'articles et plus encore."
},
"feature8": {
"title": "Statistiques d'utilisation",
"content": "Connaissez mieux vos utilisateurs avec une intégration facile de Piwik, Google Analytics et d'autres systèmes de statistiques et supervision d'utilisation."
}
},
"toolbar": {
"mute": "Muet / Actif",
"videomute": "Démarrer / Arrêter la caméra",
"authenticate": "",
"record": "Enregistrer",
"lock": "Verrouiller / déverrouiller la salle",
"invite": "Inviter des participants",
"chat": "",
"prezi": "Partager une présentation Prezi",
"etherpad": "Partager un document",
"sharescreen": "Partager mon écran",
"fullscreen": "Activer / Désactiver le plein écran",
"sip": "Appeler un numéro SIP",
"Settings": "Paramètres",
"hangup": "Raccrocher",
"login": "Connexion",
"logout": ""
},
"bottomtoolbar": {
"chat": "Ouvrir / fermer le chat",
"filmstrip": "Montrer / cacher ma vidéo miniature",
"contactlist": "Ouvrir / fermer ma liste de contacts"
},
"chat": {
"nickname": {
"title": "Saisissez un pseudonyme dans le champ ci-dessous",
"popover": "Choisissez un pseudonyme"
},
"messagebox": "Saisissez votre texte..."
},
"settings": {
"title": "PARAMÈTRES",
"update": "Mise à jour",
"name": "Nom"
},
"videothumbnail": {
"editnickname": "Cliquez pour modifier<br/>votre nom",
"moderator": "Le propriétaire de<br/>cette conférence",
"videomute": "Un participant a<br/>arrêté sa caméra.",
"mute": "Un participant a coupé son micro",
"kick": "Exclure",
"muted": "Coupé",
"domute": "Couper le son"
},
"connectionindicator": {
"bitrate": "Débit",
"packetloss": "Perte de paquets:",
"resolution": "Résolution:",
"less": "Cacher le détail",
"more": "Montrer le détail",
"address": "Adresse:",
"remoteport": "Port distant:",
"remoteport_plural": "Ports distants:",
"localport": "Port local:",
"localport_plural": "Ports locaux:",
"localaddress": "Adresse locale:",
"localaddress_plural": "Adresses locales:",
"remoteaddress": "Adresse distante:",
"remoteaddress_plural": "Adresses distantes:",
"transport": "Transport:",
"bandwidth": "Bande passante estimée:",
"na": "Revenez ici pour afficher les informations de connexion une fois la conférence démarrée"
},
"notify": {
"disconnected": "Déconnecté",
"moderator": "Droits modérateur accordés!",
"connected": "Connecté",
"somebody": "Quelqu'un",
"me": "Moi",
"focus": "",
"focusFail": "__component__ n'est pas disponible - réessayez dans __ms__ sec",
"grantedTo": "Droits modérateur accordés à __to__!",
"grantedToUnknown": "Droits modérateur accordés à $t(somebody)!"
},
"dialog": {
"kickMessage": "Oups! Vous avez été renvoyé de la réunion!",
"popupError": "Votre navigateur bloque les popups pour ce site. Activez les popups pour ce site dans vos paramètres de sécurité et réessayez.",
"passwordError": "Cette conversation est protégée par un mot de passe. Seul le propriétaire de cette conférence peut paramétrer un mot de passe.",
"passwordError2": "Cette conversation n'est pas protégée par un mot de passe. Seul le propriétaire de cette conférence peut paramétrer un mot de passe.",
"joinError": "Oups! La conférence ne peut être rejointe. Il y a peut-être un souci avec les paramètres de sécurité. Contactez l'administrateur.",
"connectError": "Oups! Un problème est survenu et la connexion à la conférence est impossible.",
"connecting": "",
"error": "",
"detectext": "Une erreur est survenue pendant la détection de l'extension de partage d'écran.",
"failtoinstall": "Échec de l'installation de l'extension de partage d'écran",
"failedpermissions": "Échec d'obtention des permissions pour utiliser le micro et/ou la caméra local(e)",
"bridgeUnavailable": "Le pont de visioconférence Jitsi est indisponible pour le moment. Réessayez plus tard!",
"lockTitle": "Échec du verrouillage",
"lockMessage": "Impossible de verrouiller la conférence.",
"warning": "Avertissement",
"passwordNotSupported": "Les mots de passe de conférence ne sont pas supportés.",
"sorry": "Désolé",
"internalError": "Une erreur interne de l'application est survenue [setRemoteDescription]",
"unableToSwitch": "Impossible de passer le flux vidéo.",
"SLDFailure": "Oups! Un problème est survenu et le micro n'a pas été coupé! (Échec SLD)",
"SRDFailure": "Oups! Un problème est survenu et la caméra n'a pas été coupée! (Échec SRD)",
"oops": "Oups!",
"defaultError": "Une erreur est survenue",
"passwordRequired": "Mot de passe requis",
"Ok": "Ok",
"removePreziTitle": "Supprimer la présentation Prezi",
"removePreziMsg": "Voulez-vous vraiment supprimer votre présentation Prezi?",
"sharePreziTitle": "Partager une présentation Prezi",
"sharePreziMsg": "Un autre participant partage déjà une présentation Prezi. Cette conférence autorise une seule présentation Prezi à la fois.",
"Remove": "Supprimer",
"Stop": "Arrêter",
"AuthMsg": "L'authentification est requise pour créer la conférence:<br/><b>__room__ </b></br> Vous pouvez vous authentifier pour créer la conférence ou attendre que quelqu'un le fasse pour vous.",
"Authenticate": "Authentifiez-vous",
"Cancel": "Annuler",
"retry": "Réessayer",
"logoutTitle": "Déconnexion",
"logoutQuestion": "Voulez-vous vraiment vous déconnecter et arrêter la conférence?",
"sessTerminated": "Session terminée",
"hungUp": "Vous avez raccroché et quitté la conférence",
"joinAgain": "Rejoignez à nouveau la conférence",
"Share": "Partager",
"preziLinkError": "Fournissez s'il vous plaît un lien prezi fonctionnel.",
"Save": "Sauvegarder",
"recordingToken": "Saisissez un jeton d'enregistrement",
"Dial": "Composer",
"sipMsg": "Saisissez un numéro SIP",
"passwordCheck": "Voulez-vous vraiment supprimer votre mot de passe?",
"passwordMsg": "Saisissez un mot de passe pour verrouiller la conférence",
"Invite": "Inviter",
"shareLink": "Partagez ce lien avec toutes les personnes que vous voulez inviter",
"settings1": "Configurez votre conférence",
"settings2": "Les participants rejoignent la conférence en étant muets.",
"settings3": "Pseudonymes requis<br/><br/>Saisissez un mot de passe pour verrouiller la conférence:",
"yourPassword": "Votre mot de passe",
"Back": "Retour",
"serviceUnavailable": "Service indisponible",
"gracefulShutdown": "Le service est actuellement en maintenance. Réessayez plus tard.",
"Yes": "Oui",
"reservationError": "Erreur du système de réservation",
"reservationErrorMsg": "Code d'erreur: __code__, message: __msg__",
"password": "mot de passe",
"userPassword": "mot de passe utilisateur",
"token": "jeton"
},
"email": {
"sharedKey": [
"Cette conférence est protégée par un mot de passe. Utilisez le code suivant pour la rejoindre:",
"",
"",
"__sharedKey__",
"",
""
],
"subject": "Invitation à la conférence __appName__ : __conferenceName__",
"body": [
"Bonjour, je vous invite à la conférence __appName__ que je viens de créer.",
"",
"",
"Cliquez sur le lien suivant pour rejoindre la conférence.",
"",
"",
"__roomUrl__",
"",
"",
"__sharedKeyText__",
" Notez que __appName__ est actuellement seulement supporté par __supportedBrowsers__, vous devez donc utiliser un de ces navigateurs.",
"",
"",
"À tout de suite dans la conférence!"
],
"and": "et"
},
"connection": {
"ERROR": "Erreur",
"CONNECTING": "Connexion en cours...",
"CONNFAIL": "Échec de la Connexion",
"AUTHENTICATING": "Authentification en cours...",
"AUTHFAIL": "Échec de l'authentification",
"CONNECTED": "Connecté",
"DISCONNECTED": "Déconnecté",
"DISCONNECTING": "Déconnexion en cours...",
"ATTACHED": "Attachée"
}
}

227
lang/main-it.json Normal file
View File

@@ -0,0 +1,227 @@
{
"contactlist": "LISTA CONTATTI",
"connectionsettings": "Impostazioni Connessione",
"poweredby": "powered by",
"downloadlogs": "Scarica logs",
"roomUrlDefaultMsg": "La tua conferenza sta per essere creata...",
"participant": "Partecipante",
"me": "io",
"speaker": "Relatore",
"defaultNickname": "es. __nome__",
"defaultPreziLink": "es. __url__",
"welcomepage": {
"go": "VAI",
"roomname": "Inserisci Nome Stanza",
"disable": "Non visualizzare questa pagina la prossima volta",
"feature1": {
"title": "Semplice da usare",
"content": "Nessun download richiesto. __app__ funziona direttamente nel tuo browser. Condividi semplicemente l'URL della tua conferenza con altri per iniziare."
},
"feature2": {
"title": "Poca banda",
"content": "Conferenze video multi utente funzionano con appena 128Kbps. La condivisione dello schermo ed conferenze solo audio sono possibili con molto meno."
},
"feature3": {
"title": "Open source",
"content": "__app__ è sotto licenza MIT. Sei libero di scaricarla, usarla, modificarla e condividerla con la medesima licenza."
},
"feature4": {
"title": "Utenti illimitati",
"content": "Non ci sono restrizioni sul numero di utenti per una conferenza. La potenza del server e la banda a disposizione sono gli unici fattori limitanti."
},
"feature5": {
"title": "Condivisione Schermo",
"content": "é facile condividere il tuo schermo con altri. __app__ è l'ideale per presentazioni online, letture, e sessioni di supporto tecnico."
},
"feature6": {
"title": "Stanze sicure",
"content": "Hai bisogno di più privacy? Le conferenze di __app__ possono essere rese sicure con una password per escludere ospiti non desiderati e prevenire interruzioni."
},
"feature7": {
"title": "Note condivise",
"content": "__app__ utilizza Etherpad, un editor di testo real-time e collaborativo che è ottimo per meeting, scrivere articoli e tanto altro."
},
"feature8": {
"title": "Statistiche di utilizzo",
"content": "Impara come i tuoi utenti lo utilizzano con la facile integrazione con PiWik, Google Analytics, e altri sistemi di statistica e monitor dell'utilizzo."
}
},
"toolbar": {
"mute": "Microfono Attiva / Disattiva",
"videomute": "Abilita / Disabilita video",
"authenticate": "",
"record": "Registra",
"lock": "Blocca / Sblocca Stanza",
"invite": "Invita altri",
"chat": "",
"prezi": "Condividi con Prezi",
"etherpad": "Documento condiviso",
"sharescreen": "Condividi schermo",
"fullscreen": "Entra / Esci da schermo intero",
"sip": "Chiama numero SIP",
"Settings": "Impostazioni",
"hangup": "Termina",
"login": "Login",
"logout": ""
},
"bottomtoolbar": {
"chat": "Apri / Chiudi chat",
"filmstrip": "Mostra / Nascondi miniature",
"contactlist": "Apri / Chiudi la lista contatti"
},
"chat": {
"nickname": {
"title": "Scegli un nickname nel box qui sotto",
"popover": "Scegli un nickname"
},
"messagebox": "Inserisci testo..."
},
"settings": {
"title": "IMPOSTAZIONI",
"update": "Aggiorna",
"name": "Nome"
},
"videothumbnail": {
"editnickname": "Clicca per modificare il tuo<br/>nome visualizzato",
"moderator": "Il proprietario<br/>della conferenza",
"videomute": "Il partecipante ha<br/>fermato il video.",
"mute": "Il partecipante è in muto",
"kick": "Espelli",
"muted": "Audio disattivato",
"domute": "Disattiva audio"
},
"connectionindicator": {
"bitrate": "Bitrate:",
"packetloss": "Perdita pacchetti:",
"resolution": "Risoluzione:",
"less": "Mostra meno",
"more": "Mostra di più",
"address": "Indirizzo:",
"remoteport": "Porta remota:",
"remoteport_plural": "Porte remote:",
"localport": "Porta locale:",
"localport_plural": "Porte locali:",
"localaddress": "Indirizzo locale:",
"localaddress_plural": "Indirizzi locali:",
"remoteaddress": "Indirizzo remoto:",
"remoteaddress_plural": "Indirizzi remoti:",
"transport": "Trasporto:",
"bandwidth": "Banda stimata:",
"na": "Ritorna qui per informazioni sulla connessione una volta che la conferenza inizia"
},
"notify": {
"disconnected": "disconnesso",
"moderator": "Impostati i permessi di moderatore!",
"connected": "connesso",
"somebody": "Qualcuno",
"me": "io",
"focus": "Focus su conferenza",
"focusFail": "__component__ non disponibile - riprova in __ms__ sec",
"grantedTo": "Permessi di moderatore garantiti a __to__!",
"grantedToUnknown": "Permessi di moderatore garantiti a $t(somebody)!"
},
"dialog": {
"kickMessage": "Accidenti! Sei stato espulso dalla conferenza !",
"popupError": "Il tuo browser sta bloccando le finestre popup da questo sito. Abilita i popup tra le impostazioni di sicurezza del tuo browser e riprova.",
"passwordError": "Questa conversazione è protetta da una password. Solo il proprietario della conferenza può impostare una password.",
"passwordError2": "Questa conversazione non è al momento protetta da una password. Solo il proprietario può impostare la password.",
"joinError": "Oops! Non puoi entrare nella conferenza. Ci deve essere qualche problema con la configurazione di sicurezza. Contattare l'amministratore di sistema.",
"connectError": "Oops! Qualcosa è andato storto e non ti puoi collegare alla conferenza.",
"connecting": "",
"error": "",
"detectext": "Errore durante il rilevamento dell'estensione per il desktopsharing.",
"failtoinstall": "Impossibile installare l'estensione per il desktop sharing",
"failedpermissions": "Impossibile ottenere i permessi per usare il microfono e/o il video locale.",
"bridgeUnavailable": "Il Videobridge non è al momento disponibile. Si prega di riprovare più tardi!",
"lockTitle": "Blocco fallito",
"lockMessage": "Impossibile bloccare la conferenza.",
"warning": "Attenzione",
"passwordNotSupported": "Le password sulla stanza non sono al momento supportate.",
"sorry": "Spiacente",
"internalError": "Errore interno dell'applicazione [setRemoteDescription]",
"unableToSwitch": "Impossibile cambiare lo stream video.",
"SLDFailure": "Oops! Qualcosa è andato storto e non è possibile silenziare il microfono! (Errore SLD)",
"SRDFailure": "Oops! Qualcosa è andato storto e non è possibile fermare il video! (Errore SRD)",
"oops": "Oops!",
"defaultError": "C'è stato qualche tipo di errore",
"passwordRequired": "Richiesta password ",
"Ok": "Ok",
"removePreziTitle": "Rimuovi Prezi",
"removePreziMsg": "Sei sicuro di voler rimuovere il tuo Prezi?",
"sharePreziTitle": "Condividi un Prezi",
"sharePreziMsg": "Un altro partecipante sta già condividendo un Prezi. Questa conferenza permette un solo Prezi alla volta.",
"Remove": "Rimuovi",
"Stop": "Ferma",
"AuthMsg": "Autenticazione richiesta per creare la stanza:<br/><b>__room__ </b></br> Puoi autenticarti per creare la stanza o aspettare che qualcun altro lo faccia per te.",
"Authenticate": "Autenticazione",
"Cancel": "Annulla",
"retry": "Riprova",
"logoutTitle": "Logout",
"logoutQuestion": "Vuoi disconnetterti e interrompere la conferenza ?",
"sessTerminated": "Sessione Terminata",
"hungUp": "Hai terminato la conversazione",
"joinAgain": "Entra ancora",
"Share": "Condividi",
"preziLinkError": "Fornire un link Prezi esatto.",
"Save": "Salva",
"recordingToken": "Inserire token di registrazione",
"Dial": "Componi",
"sipMsg": "Inserire numero SIP",
"passwordCheck": "Confermi la rimozione della password?",
"passwordMsg": "Imposta una password per bloccare la stanza",
"Invite": "Invita",
"shareLink": "Condividi questo link con tutte le persone che vuoi invitare",
"settings1": "Configura la tua conferenza",
"settings2": "Partecipanti connessi in muto",
"settings3": "Richiedi nicknames<br/><br/>Imposta una password per bloccare la tua stanza:",
"yourPassword": "la tua password",
"Back": "Indietro",
"serviceUnavailable": "Servizio non disponibile",
"gracefulShutdown": "Il nostro servizio è al momento spento per manutenzione. Si prega di riprovare più tardi.",
"Yes": "Sì",
"reservationError": "Errore di sistema in prenotazione",
"reservationErrorMsg": "Codice di errore: __code__, messaggio: __msg__",
"password": "password",
"userPassword": "password utente",
"token": "token"
},
"email": {
"sharedKey": [
"Questa conferenza è protetta da password. Utilizzare il seguente PIN alla connessione:",
"",
"",
"__sharedKey__",
"",
""
],
"subject": "Invito su __appName__ (__conferenceName__)",
"body": [
"Ciao, Vorrei invitarti alla conferenza che ho appena creato su __appName__ .",
"",
"",
"Cliccare sul seguente link per entrare nella conferenza.",
"",
"",
"__roomUrl__",
"",
"",
"__sharedKeyText__",
"NOTA: __appName__ è al momento supportato da questi browsers: __supportedBrowsers__, è necessario utilizzare uno di questi programmi per poter entrare.",
"",
"",
"Ci sentiamo tra un secondo!"
],
"and": "e"
},
"connection": {
"ERROR": "Errore",
"CONNECTING": "Connessione",
"CONNFAIL": "Connessione non riuscita",
"AUTHENTICATING": "Autenticazione",
"AUTHFAIL": "Autenticazione fallita",
"CONNECTED": "Connesso",
"DISCONNECTED": "Disconnesso",
"DISCONNECTING": "Disconnessione in corso",
"ATTACHED": "Collegato"
}
}

249
lang/main-sl.json Normal file
View File

@@ -0,0 +1,249 @@
{
"contactlist": "STIKI",
"connectionsettings": "Nastavitve povezave",
"poweredby": "poganja",
"downloadlogs": "Shrani zapis",
"roomUrlDefaultMsg": "Ustvarjanje vaše konference ...",
"participant": "Udeleženec",
"me": "jaz",
"speaker": "Govornik",
"defaultNickname": "npr. __name__",
"defaultPreziLink": "npr. __url__",
"welcomepage": {
"go": "POJDI",
"roomname": "Vpišite ime sobe",
"disable": "Prihodnjič ne prikaži te strani",
"feature1": {
"title": "Enostavna uporaba",
"content": "Nič ni treba namestiti. __app__ deluje direktno v vašem brskalniku. Enostavno sporočite ostalim udeležencem URL svoje konference in začnite."
},
"feature2": {
"title": "Ozka pasovna širina",
"content": "Video konferenca z več udeleženci s samo 128Kbps. Deljenje zaslona in samo avdio konference so možne že z veliko nižjo pasovno širino."
},
"feature3": {
"title": "Odprta koda",
"content": "__app__ je objavljen po licenci MIT. Pod pogoji te licence lahko prosto snamete, uporabljate, spreminjate in delite."
},
"feature4": {
"title": "Neomejeno število uporabnikov",
"content": "Nobene umetne omejitve števila uporabnikov ali udeležencev konference. Zmogljivost strežnika in pasovna širina sta edini omejitvi."
},
"feature5": {
"title": "Skupna raba zaslona",
"content": "Skupna raba zaslona z drugimi je zelo enostavna. __app__ je idealna rešitev za spletne predstavitve, predavanja in tehnično podporo."
},
"feature6": {
"title": "Varne sobe",
"content": "Rabite zasebnost? Konferenčne sobe __app__ so lahko zaklenjene z geslom, da preprečite dostop neželenim gostom ter prekinitve."
},
"feature7": {
"title": "Skupna raba zapiskov",
"content": "__app__ vsebuje Etherpad, realnočasovni skupinski urejevalnik besedil, ki je idealen za pisanje zapisnikov sestankov, člankov in še mnogo drugega."
},
"feature8": {
"title": "Statistika uporabe",
"content": "Spoznajte svoje uporabnike z enostavno integracijo v Piwik, Google Analytics ter druge sisteme za nadzor uporabe in statistiko."
}
},
"toolbar": {
"mute": "Utišaj / Povrni glasnost",
"videomute": "Zaženi / Ustavi kamero",
"authenticate": "Overi",
"record": "Snemaj",
"lock": "Zakleni / Odkleni sobo",
"invite": "Povabite ostale",
"chat": "Odpri / zapri klepetalnico",
"prezi": "Skupna raba Prezi",
"etherpad": "Dokument v skupni rabi",
"sharescreen": "Zaslon v souporabi",
"fullscreen": "Vklopi / Izklopi celozaslonski način",
"sip": "Pokliči številko SIP",
"Settings": "Nastavitve",
"hangup": "Odloži",
"login": "Prijava",
"logout": "Odjava",
"dialpad": "Pokaži številčnico"
},
"bottomtoolbar": {
"chat": "Odpri / zapri klepetalnico",
"filmstrip": "Pokaži / Skrij filmski trak",
"contactlist": "Odpri / Zapri stike"
},
"chat": {
"nickname": {
"title": "Vpišite vzdevek v spodnje polje",
"popover": "Izberite vzdevek"
},
"messagebox": "Vnesite besedilo ..."
},
"settings": {
"title": "NASTAVITVE",
"update": "Posodobi",
"name": "Ime",
"startAudioMuted": "začni brez zvoka",
"startVideoMuted": "začni brez slike"
},
"videothumbnail": {
"editnickname": "Kliknite, da spremenite<br/>svoje ime",
"moderator": "Lastnik<br/>konference",
"videomute": "Udeleženec je<br/>izključil kamero.",
"mute": "Udeleženec je utišan",
"kick": "Izženi",
"muted": "Utišan",
"domute": "Utišaj"
},
"connectionindicator": {
"bitrate": "Bitna hitrost:",
"packetloss": "Izgubljeni paketi:",
"resolution": "Ločljivost:",
"less": "Pokaži manj",
"more": "Pokaži več",
"address": "Naslov:",
"remoteport_plural_5": "Oddaljena vrata:",
"remoteport": "Oddaljena vrata:",
"remoteport_plural_2": "Oddaljena vrata:",
"remoteport_plural_3": "Oddaljena vrata:",
"localport_plural_5": "Krajevna vrata:",
"localport": "Krajevna vrata:",
"localport_plural_2": "Krajevna vrata:",
"localport_plural_3": "Krajevna vrata:",
"localaddress_plural_5": "Krajevni naslov:",
"localaddress": "Krajevna naslova:",
"localaddress_plural_2": "Krajevni naslovi:",
"localaddress_plural_3": "Krajevni naslov:",
"remoteaddress_plural_5": "Oddaljeni naslov:",
"remoteaddress": "Oddaljena naslova:",
"remoteaddress_plural_2": "Oddaljeni naslovi:",
"remoteaddress_plural_3": "Oddaljeni naslovi:",
"transport": "Prenos:",
"bandwidth": "Ocenjena pasovna širina:",
"na": "Ko se konferenca začne se vrnite sem za informacije o povezavi"
},
"notify": {
"disconnected": "odklopjeno",
"moderator": "Dodeljene moderatorske pravice!",
"connected": "povezano",
"somebody": "Nekdo",
"me": "Jaz",
"focus": "Fokus na konferenco",
"focusFail": "__component__ ni na razpolago - ponovni poskus čez __ms__ sec",
"grantedTo": "Moderatorske pravice dodeljene uporabniku __to__!",
"grantedToUnknown": "Moderatorske pravice dodeljene uporabniku $t(somebody)!",
"muted": "Pogovor ste začeli utišano.",
"mutedTitle": "Utišani ste!"
},
"dialog": {
"kickMessage": "Ojej! Izgnali so vas iz srečanja!",
"popupError": "Vaš brskalnik ne dovoli pojavnih oken iz te spletne strani. Omogočite prosim pojavna okna v varnostnih nastavitvah svojega brskalnika in ponovno poskusite.",
"passwordError": "Ta pogovor je zaščiten z geslom. Samo lastnik konference lahko nastavi geslo.",
"passwordError2": "Ta pogovor ni zaščiten z geslom. Samo lastnik konference lahko nastavi geslo.",
"joinError": "Ups! Ni se bilo mogoče pridružiti konferenci. Mogoče je kakšna težava z varnostnimi nastavitvami. Pišite prosim administratorju storitve.",
"connectError": "Ups! Nekaj je narobe in se ni bilo mogoče povezati s konferenco.",
"connectErrorWithMsg": "Ups! Nekaj je narobe in se ni bilo mogoče povezati s konferenco: __msg__",
"connecting": "Povezovanje",
"error": "Napaka",
"detectext": "Napaka pri zaznavanju razširitve za skupno uporabo namizja.",
"failtoinstall": "Razširitve za skupno uporabo namizja ni bilo mogoče namestiti",
"failedpermissions": "Ni bilo mogoče pridobiti dovoljenja za uporabo lokalnega mikrofona ali kamere.",
"bridgeUnavailable": "Jitsi Videobridge trenutno ni na razpolago. Prosim poskusite kasneje!",
"lockTitle": "Zaklepanje ni uspelo",
"lockMessage": "Konference ni bilo mogoče zakleniti.",
"warning": "Opozorilo",
"passwordNotSupported": "Trenutno ni mogoče zakleniti sobe z geslom.",
"sorry": "Oprostite",
"internalError": "Notranja napaka [setRemoteDescription]",
"unableToSwitch": "Ni mogoče preklopiti video pretoka.",
"SLDFailure": "Ups! Nekaj je narobe in zvoka se ne da utišati! (Napaka SLD)",
"SRDFailure": "Ups! Nekaj je narobe in slike ni mogoče ustaviti! (Napaka SRD)",
"oops": "Ups!",
"defaultError": "Prišlo je do neke napake",
"passwordRequired": "Potrebno je geslo",
"Ok": "V redu",
"removePreziTitle": "Odstrani Prezi",
"removePreziMsg": "Ali res želite odstraniti Prezi?",
"sharePreziTitle": "Dajte Prezi v skupno rabo",
"sharePreziMsg": "Drug uporabnik je že dal Prezi v skupno rabo. Ta konferenca podpira samo en Prezi naenkrat.",
"Remove": "Odstrani",
"WaitingForHost": "Čakanje na gostitelja ...",
"WaitForHostMsg": "Ta konferenca <b>__room__ </b> se še ni začela. V primeru, da ste vi gostitelj se prosim overite. Drugače počakajte prosim na prihod gostitelja.",
"IamHost": "Jaz sem gostitelj",
"Cancel": "Prekliči",
"retry": "Poskusi ponovno",
"logoutTitle": "Odjava",
"logoutQuestion": "Ali se res želite odjaviti in prekiniti konferenco?",
"sessTerminated": "Seja je končana",
"hungUp": "Prekinili ste klic",
"joinAgain": "Ponovno se pridruži",
"Share": "Souporaba",
"preziLinkError": "Prosim, pravilno vpišite povezavo Prezi.",
"Save": "Shrani",
"recordingToken": "Vnesite žeton za registracijo",
"Dial": "Pokliči",
"sipMsg": "Vnesite številko SIP",
"passwordCheck": "Ali res želite odstraniti geslo?",
"passwordMsg": "Nastavite geslo za zaklepanje sobe",
"Invite": "Povabi",
"shareLink": "To povezavo pošljite vsem, ki jih želite povabiti",
"settings1": "Nastavite svojo konferenco",
"settings2": "Utišaj udeležence ob pristopu",
"settings3": "Zahtevaj vzdevke<br/><br/>Nastavi geslo za zaklep sobe:",
"yourPassword": "vaše geslo",
"Back": "Nazaj",
"serviceUnavailable": "Storitev ni na voljo",
"gracefulShutdown": "Storitev trenutno ni na voljo zaradi vzdrževanja. Poskusite ponovno kasneje.",
"Yes": "Da",
"reservationError": "Napaka v sistemu rezervacije",
"reservationErrorMsg": "Koda napake: __code__, sporočilo: __msg__",
"password": "geslo",
"userPassword": "uporabniško geslo",
"token": "žeton",
"displayNameRequired": "Vpišite svoje ime:"
},
"email": {
"sharedKey": [
"Ta konferenca je zaklenjena z geslom. Uporabite sledeči PIN ko se pridružite:",
"",
"",
"__sharedKey__",
"",
""
],
"subject": "Povabilo na __appName__ (__conferenceName__)",
"body": [
"Pozdravljeni,",
"želim vas povabiti na ravnokar pripravljeno konferenco __appName__.",
"",
"",
"Prosim, kliknite na sledečo povezavo, da se pridružite konferenci.",
"",
"",
"__roomUrl__",
"",
"",
"__sharedKeyText__",
" Opomba: __appName__ trenutno nudi podporo samo za __supportedBrowsers__, uporabiti morate enega izmed teh brskalnikov.",
"",
"",
"Se slišimo čez trenutek!"
],
"and": "in"
},
"connection": {
"ERROR": "Napaka",
"CONNECTING": "Povezovanje",
"RECONNECTING": "Prišlo je do omrežne napake. Ponovni poskus ...",
"CONNFAIL": "Povezovanje je spodletelo",
"AUTHENTICATING": "Overjanje",
"AUTHFAIL": "Overitev je spodletela",
"CONNECTED": "Povezano",
"DISCONNECTED": "Ni povezave",
"DISCONNECTING": "Prekinjanje povezave",
"ATTACHED": "Priključeno"
},
"recording": {
"toaster": "Trenutno poteka snemanje!",
"pending": "Snemanje se bo začelo takoj, ko se bo pridružil drugi udeleženec",
"on": "Snemanje se je začelo"
}
}

173
lang/main-tr.json Normal file
View File

@@ -0,0 +1,173 @@
{
"contactlist": "KİŞİ LİSTESİ",
"connectionsettings": "Bağlantı Ayarları",
"poweredby": "Gücünün kaynağı",
"downloadlogs": "Günlükleri indir",
"welcomepage": {
"go": "GİT",
"roomname": "Oda adı girin",
"disable": "Sonraki girişimde bu sayfayı gösterme",
"feature1": {
"title": "Kullanımı kolay",
"content": "İndirmeye gerek yok. __app__ tarayıcınızda doğrudan çalışır. Başlamak için görüşme bağlantısını URL diğerleri ile paylaşın."
},
"feature2": {
"title": "Düşük bant genişliği ihtiyacı",
"content": "Ekran paylaşımı ve sadece ses ile çok katılımcılı video görüşmeleri, 128Kbps bağlantı ile mümkündür."
},
"feature3": {
"title": "Açık kaynak kodlu",
"content": "__app__ MIT ile lisanslanmıştır. Bu lisansa uygun olarak indirmek, kullanmak, değiştirmek ve paylaşmakta özgürsün."
},
"feature4": {
"title": "Sınırsız sayıda kullanıcı",
"content": "Kullanıcılar veya konferans katılımcılarının sayısında hiçbir yapay kısıtlama yoktur. Sadece sunucun güç ve bant genişliği, sınırlayıcı unsurdur."
},
"feature5": {
"title": "Ekran paylaşımı",
"content": "Diğerlerinle ekranınızı kolayca paylaşın. __app__ çevrimiçi sunumlar, dersler ve teknik destek oturumları için idealdir."
},
"feature6": {
"title": "Güvenli odalar",
"content": "Biraz gizliliğe ihtiyacınız var? __app__ görüşme odaları, istemeyen misafirleri uzak tutmak ve kesinleri önlemek için bir parola ile güvence altına alınabilir."
},
"feature7": {
"title": "Paylaşımlı notlar",
"content": "__app__ Etherpad içerir, gerçek zamanlı bir ortak çalışma metin düzenleyicisidir. Görüşme tutanakları, makale yazımı ve daha fazlası için biçilmiş kaftandır."
},
"feature8": {
"title": "Kullanım istatistikleri",
"content": "Piwik, Google Analytics ve diğer kullanım izleme ve istatistik sistemleri ile kolay tümleştirmeyle kullanıcılar hakkında bilgi edinin."
}
},
"toolbar": {
"mute": "Sessiz / Sesli",
"videomute": "Kamera başlat / durdur",
"authenticate": "",
"record": "Kaydet",
"lock": "Odayı kilitle / kilit aç",
"invite": "Arkadaşlarını davet et",
"chat": "",
"prezi": "Prezi paylaş",
"etherpad": "Paylaşımlı belge",
"sharescreen": "Ekran paylaş",
"fullscreen": "Tam Ekrana Gir / Çık",
"sip": "SIP numara ara",
"Settings": "Ayarlar",
"hangup": "Kapat",
"login": "Oturum aç",
"logout": ""
},
"bottomtoolbar": {
"chat": "Sohbeti aç / kapa",
"filmstrip": "Kişi listesi aç / kapa",
"contactlist": "Film şeridini göster / gizle"
},
"chat": {
"nickname": {
"title": "Aşağıdaki kutuya bir takma ad girin",
"popover": "Bir takma ad seçin"
},
"messagebox": "Metin girin..."
},
"settings": {
"title": "AYARLAR",
"update": "Güncelle",
"name": "Ad"
},
"videothumbnail": {
"editnickname": "Görünür adınızı değiştirmek<br/>için tıkla",
"moderator": "Bu görüşmenin<br/>sahibi",
"videomute": "Katılımcı<br/>kamera durdurdu.",
"mute": "Katılımcı sessiz",
"kick": "Kovuldu",
"muted": "Sessiz",
"domute": "Sustur"
},
"connectionindicator": {
"bitrate": "Bit hızı:",
"packetloss": "Paket kaybı:",
"resolution": "Çözünürlük:",
"less": "Daha az göster",
"more": "Daha fazla göster",
"address": "Adres:",
"remoteport": "Uzak port:Uzak portlar:",
"localport": "Yerel port:Yerel portlar:",
"localaddress": "Yerel adres:Yerel adresler:",
"remoteaddress": "Uzak adres:Uzak adresler:",
"transport": "Transport:",
"bandwidth": "Tahmini bant genişliği:",
"na": "Görüşme başladıktan sonra bağlantı bilgileri için buraya gel"
},
"notify": {
"disconnected": "bağlantı kesildi",
"moderator": "Görüşme yöneticisi hakları verildi!",
"connected": "bağlandı",
"somebody": "Birisi",
"me": "Bana",
"focus": "Görüşme odağı",
"focusFail": "__component__ uygun değil - __ms__ saniye içinde tekrar deneyin",
"grantedTo": "__to__, görüşme yöneticisi hakları verildi!",
"grantedToUnknown": "$t(somebody), görüşme yöneticisi hakları verildi!"
},
"dialog": {
"kickMessage": "Ahhh! Görüşmeden, kavuldun!",
"popupError": "Tarayıcınız bu siteden açılır pencereleri engelliyor. Lütfen, tarayıcınızın güvenlik ayarlarında pop-up etkinleştirin ve tekrar deneyin.",
"passwordError": "Bu görüşme şu anda bir parola ile korunmaktadır. Sadece görüşmenin sahibi bir parola ayarlayabilir.",
"passwordError2": "Bu görüşme şu anda bir parola ile korunmamaktadır. Sadece görüşmenin sahibi bir parola ayarlayabilir.",
"joinError": "Amanin boo! Görüşmeye katılamadık. Güvenlik yapılandırması ile ilgili bir sorun olabilir. Hizmet yöneticisi ile bağlantı kurun.",
"connectError": "Amanin boo! Birşeyler ters gitti ve görüşmeye bağlanamadık.",
"error": "Hata",
"detectext": "Ekran paylaşımı eklentisi tespit edilirken hata.",
"failtoinstall": "Masaüstü paylaşım eklentisi yüklenemedi",
"failedpermissions": "Yerel mikrofon ve/veya kamerayı kullanmak için izinler alınamadı.",
"bridgeUnavailable": "Jitsi Videobridge şu anda kullanılamıyor. Daha sonra tekrar deneyiniz!",
"lockTitle": "Kilitlenemedi",
"lockMessage": "Görüşme kilitlenemedi.",
"warning": "Uyarı",
"passwordNotSupported": "Oda parolaları şu anda desteklenmemekte.",
"sorry": "Üzgünüz",
"internalError": "İç uygulama hatası [setRemoteDescription]",
"unableToSwitch": "Video akışıılamıyor.",
"SLDFailure": "Amanin boo! Birşeyler ters gitti ve sessize alamadık! (SLD Başarısız)",
"SRDFailure": "Amanin boo! Birşeyler ters gitti ve videoyu durduramadık! (SRD Başarısız)",
"oops": "Amanin boo!",
"defaultError": "Bir tür hata var",
"passwordRequired": "Parola gerekli",
"Ok": "Tamam",
"removePreziTitle": "Prezi kaldır",
"removePreziMsg": "Prezi kaldırmak istediğinizden emin misiniz?",
"sharePreziTitle": "Bir Prezi paylaşın",
"sharePreziMsg": "Diğer katılımcı hala bir Prezi paylaşıyor.Bu görüşme aynı zamanda sadece bir Prezi izin verir.",
"Remove": "Kaldır",
"Stop": "Durdur",
"AuthMsg": "Oda oluşturmak için kimlik doğrulama gerekli:<br/><b>__room__ </b></br> Oda oluşturmak için ya kimlik doğrulamalı ya da bunu yapması için bir başkasını beklemelisiniz.",
"Authenticate": "Kimlik doğrula",
"Cancel": "İptal",
"logoutTitle": "Oturum kapat",
"logoutQuestion": "Oturumu ve görüşmeyi sonlandırmak istediğinizden emin misiniz?",
"sessTerminated": "Oturum sonlandırıldı",
"hungUp": "Görüşmeyi bitirdiniz",
"joinAgain": "Yeniden katıl",
"Share": "Paylaş",
"preziLinkError": "Lütfen doğru prezi bağlantısı verin.",
"Save": "Kaydet",
"recordingToken": "Kayıt jetonu girin",
"Dial": "Ara",
"sipMsg": "SIP numarası gir",
"passwordCheck": "Parolanızı kaldırmak istediğinizden emin misiniz?",
"passwordMsg": "Odanızı kilitlemek için bir parola koyun",
"Invite": "Davet et",
"shareLink": "Davet etmek istediğiniz herkesle bu bağlantıyı paylaşın",
"settings1": "Görüşmenizi yapılandır",
"settings2": "Katılımcılar sessiz katılsın",
"settings3": "Takma adlar gerekli<br/><br/>Odanızı kitlemek için bir parola ayarlayın:",
"yourPassword": "parolanız",
"Back": "Geri",
"serviceUnavailable": "Hizmet kullanım dışı",
"gracefulShutdown": "Hizmetimiz bakıp için durduruldu. Daha sonra tekrar deneyiniz.",
"Yes": "Evet",
"reservationError": "Rezervasyon sistemi hatası",
"reservationErrorMsg": "Hata kodu: __code__, mesaj: __msg__"
}
}

250
lang/main.json Normal file
View File

@@ -0,0 +1,250 @@
{
"contactlist": "CONTACT LIST",
"connectionsettings": "Connection Settings",
"poweredby": "powered by",
"downloadlogs": "Download logs",
"roomUrlDefaultMsg": "Your conference is currently being created...",
"participant": "Participant",
"me": "me",
"speaker": "Speaker",
"defaultNickname": "ex. __name__",
"defaultPreziLink": "e.g. __url__",
"welcomepage":{
"go": "GO",
"roomname": "Enter room name",
"disable": "Don't show this page next time I enter",
"feature1": {
"title": "Simple to use",
"content": "No downloads required. __app__ works directly within your browser. Simply share your conference URL with others to get started."
},
"feature2": {
"title": "Low bandwidth",
"content": "Multi-party video conferences work with as little as 128Kbps. Screen-sharing and audio-only conferences are possible with far less."
},
"feature3": {
"title": "Open source",
"content": "__app__ is licensed under MIT. You are free to download, use, modify, and share them as per these licenses."
},
"feature4": {
"title": "Unlimited users",
"content": "There are no artificial restrictions on the number of users or conference participants. Server power and bandwidth are the only limiting factors."
},
"feature5": {
"title": "Screen sharing",
"content": "It's easy to share your screen with others. __app__ is ideal for on-line presentations, lectures, and tech support sessions."
},
"feature6": {
"title": "Secure rooms",
"content": "Need some privacy? __app__ conference rooms can be secured with a password in order to exclude unwanted guests and prevent interruptions."
},
"feature7": {
"title": "Shared notes",
"content": "__app__ features Etherpad, a real-time collaborative text editor that's great for meeting minutes, writing articles, and more."
},
"feature8": {
"title": "Usage statistics",
"content": "Learn about your users through easy integration with Piwik, Google Analytics, and other usage monitoring and statistics systems."
}
},
"toolbar": {
"mute": "Mute / Unmute",
"videomute": "Start / stop camera",
"authenticate": "Authenticate",
"record": "Record",
"lock": "Lock / unlock room",
"invite": "Invite others",
"chat": "Open / close chat",
"prezi": "Share Prezi",
"etherpad": "Shared document",
"sharescreen": "Share screen",
"fullscreen": "Enter / Exit Full Screen",
"sip": "Call SIP number",
"Settings": "Settings",
"hangup": "Hang Up",
"login": "Login",
"logout": "Logout",
"dialpad": "Show dialpad"
},
"bottomtoolbar": {
"chat": "Open / close chat",
"filmstrip": "Show / hide film strip",
"contactlist": "Open / close contact list"
},
"chat":{
"nickname": {
"title": "Enter a nickname in the box below",
"popover": "Choose a nickname"
},
"messagebox": "Enter text..."
},
"settings":
{
"title": "SETTINGS",
"update": "Update",
"name": "Name",
"startAudioMuted": "start without audio",
"startVideoMuted": "start without video"
},
"videothumbnail":
{
"editnickname": "Click to edit your<br/>display name",
"moderator": "The owner of<br/>this conference",
"videomute": "Participant has<br/>stopped the camera.",
"mute": "Participant is muted",
"kick": "Kick out",
"muted": "Muted",
"domute": "Mute"
},
"connectionindicator":
{
"bitrate": "Bitrate:",
"packetloss": "Packet loss:",
"resolution": "Resolution:",
"less": "Show less",
"more": "Show more",
"address": "Address:",
"remoteport_plural": "Remote ports:",
"localport_plural": "Local ports:",
"remoteport": "Remote port:",
"localport": "Local port:",
"localaddress": "Local address:",
"localaddress_plural": "Local addresses:",
"remoteaddress": "Remote address:",
"remoteaddress_plural": "Remote addresses:",
"transport": "Transport:",
"bandwidth": "Estimated bandwidth:",
"na": "Come back here for connection information once the conference starts"
},
"notify": {
"disconnected": "disconnected",
"moderator": "Moderator rights granted!",
"connected": "connected",
"somebody": "Somebody",
"me": "Me",
"focus": "Conference focus",
"focusFail": "__component__ not available - retry in __ms__ sec",
"grantedTo": "Moderator rights granted to __to__!",
"grantedToUnknown": "Moderator rights granted to $t(somebody)!",
"muted": "You have started the conversation muted.",
"mutedTitle": "You're muted!"
},
"dialog": {
"kickMessage": "Ouch! You have been kicked out of the meet!",
"popupError": "Your browser is blocking popup windows from this site. Please enable popups in your browser security settings and try again.",
"passwordError": "This conversation is currently protected by a password. Only the owner of the conference could set a password.",
"passwordError2": "This conversation isn't currently protected by a password. Only the owner of the conference could set a password.",
"joinError": "Oops! We couldn't join the conference. There might be some problem with security configuration. Please contact service administrator.",
"connectError": "Oops! Something went wrong and we couldn't connect to the conference.",
"connectErrorWithMsg": "Oops! Something went wrong and we couldn't connect to the conference: __msg__",
"connecting": "Connecting",
"error": "Error",
"detectext": "Error when trying to detect desktopsharing extension.",
"failtoinstall": "Failed to install desktop sharing extension",
"failedpermissions": "Failed to obtain permissions to use the local microphone and/or camera.",
"bridgeUnavailable": "Jitsi Videobridge is currently unavailable. Please try again later!",
"lockTitle": "Lock failed",
"lockMessage": "Failed to lock conference.",
"warning": "Warning",
"passwordNotSupported": "Room passwords are currently not supported.",
"sorry": "Sorry",
"internalError": "Internal application error [setRemoteDescription]",
"unableToSwitch": "Unable to switch video stream.",
"SLDFailure": "Oops! Something went wrong and we failed to mute! (SLD Failure)",
"SRDFailure": "Oops! Something went wrong and we failed to stop video! (SRD Failure)",
"oops": "Oops!",
"defaultError": "There was some kind of error",
"passwordRequired": "Password required",
"Ok": "Ok",
"removePreziTitle": "Remove Prezi",
"removePreziMsg": "Are you sure you would like to remove your Prezi?",
"sharePreziTitle": "Share a Prezi",
"sharePreziMsg": "Another participant is already sharing a Prezi.This conference allows only one Prezi at a time.",
"Remove": "Remove",
"WaitingForHost": "Waiting for the host ...",
"WaitForHostMsg": "The conference <b>__room__ </b> has not yet started. If you are the host then please authenticate. Otherwise, please wait for the host to arrive.",
"IamHost": "I am the host",
"Cancel": "Cancel",
"retry": "Retry",
"logoutTitle" : "Logout",
"logoutQuestion" : "Are you sure you want to logout and stop the conference?",
"sessTerminated": "Session Terminated",
"hungUp": "You hung up the call",
"joinAgain": "Join again",
"Share": "Share",
"preziLinkError": "Please provide a correct prezi link.",
"Save": "Save",
"recordingToken": "Enter recording token",
"Dial": "Dial",
"sipMsg": "Enter SIP number",
"passwordCheck": "Are you sure you would like to remove your password?",
"Remove": "Remove",
"passwordMsg": "Set a password to lock your room",
"Invite": "Invite",
"shareLink": "Share this link with everyone you want to invite",
"settings1": "Configure your conference",
"settings2": "Participants join muted",
"settings3": "Require nicknames<br/><br/>Set a password to lock your room:",
"yourPassword": "your password",
"Back": "Back",
"serviceUnavailable": "Service unavailable",
"gracefulShutdown": "Our service is currently down for maintenance. Please try again later.",
"Yes": "Yes",
"reservationError": "Reservation system error",
"reservationErrorMsg": "Error code: __code__, message: __msg__",
"password": "password",
"userPassword": "user password",
"token": "token",
"displayNameRequired": "Please enter your display name:"
},
"email":
{
"sharedKey": [
"This conference is password protected. Please use the following pin when joining:",
"",
"",
"__sharedKey__",
"",
""],
"subject": "Invitation to a __appName__ (__conferenceName__)",
"body": [
"Hey there, I%27d like to invite you to a __appName__ conference I%27ve just set up.",
"",
"",
"Please click on the following link in order to join the conference.",
"",
"",
"__roomUrl__",
"",
"",
"__sharedKeyText__",
" Note that __appName__ is currently only supported by __supportedBrowsers__, so you need to be using one of these browsers.",
"",
"",
"Talk to you in a sec!"
],
"and": "and"
},
"connection":
{
"ERROR": "Error",
"CONNECTING": "Connecting",
"RECONNECTING": "A network problem occurred. Reconnecting...",
"CONNFAIL": "Connection failed",
"AUTHENTICATING": "Authenticating",
"AUTHFAIL": "Authentication failed",
"CONNECTED": "Connected",
"DISCONNECTED": "Disconnected",
"DISCONNECTING": "Disconnecting",
"ATTACHED": "Attached",
"FETCH_SESSION_ID": "Obtaining session-id...",
"GOT_SESSION_ID": "Obtaining session-id... Done",
"GET_SESSION_ID_ERROR": "Get session-id error: "
},
"recording":
{
"toaster": "Currently recording!",
"pending": "Your recording will start as soon as another participant joins",
"on": "Recording has been started"
}
}

38644
libs/app.bundle.js Normal file

File diff suppressed because it is too large Load Diff

1273
libs/jquery-impromptu.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,94 +0,0 @@
/* jshint -W117 */
Strophe.addConnectionPlugin('rayo',
{
RAYO_XMLNS: 'urn:xmpp:rayo:1',
connection: null,
init: function (conn)
{
this.connection = conn;
if (this.connection.disco)
{
this.connection.disco.addFeature('urn:xmpp:rayo:client:1');
}
this.connection.addHandler(
this.onRayo.bind(this), this.RAYO_XMLNS, 'iq', 'set', null, null);
},
onRayo: function (iq)
{
console.info("Rayo IQ", iq);
},
dial: function (to, from, roomName)
{
var self = this;
var req = $iq(
{
type: 'set',
to: config.hosts.call_control
}
);
req.c('dial',
{
xmlns: this.RAYO_XMLNS,
to: to,
from: from
});
req.c('header',
{
name: 'JvbRoomName',
value: roomName
});
this.connection.sendIQ(
req,
function (result)
{
console.info('Dial result ', result);
var resource = $(result).find('ref').attr('uri');
this.call_resource = resource.substr('xmpp:'.length);
console.info(
"Received call resource: " + this.call_resource);
},
function (error)
{
console.info('Dial error ', error);
}
);
},
hang_up: function ()
{
if (!this.call_resource)
{
console.warn("No call in progress");
return;
}
var self = this;
var req = $iq(
{
type: 'set',
to: this.call_resource
}
);
req.c('hangup',
{
xmlns: this.RAYO_XMLNS
});
this.connection.sendIQ(
req,
function (result)
{
console.info('Hangup result ', result);
self.call_resource = null;
},
function (error)
{
console.info('Hangup error ', error);
self.call_resource = null;
}
);
}
}
);

View File

@@ -1,264 +0,0 @@
function TraceablePeerConnection(ice_config, constraints) {
var self = this;
var RTCPeerconnection = navigator.mozGetUserMedia ? mozRTCPeerConnection : webkitRTCPeerConnection;
this.peerconnection = new RTCPeerconnection(ice_config, constraints);
this.updateLog = [];
this.stats = {};
this.statsinterval = null;
this.maxstats = 0; // limit to 300 values, i.e. 5 minutes; set to 0 to disable
// override as desired
this.trace = function (what, info) {
//console.warn('WTRACE', what, info);
self.updateLog.push({
time: new Date(),
type: what,
value: info || ""
});
};
this.onicecandidate = null;
this.peerconnection.onicecandidate = function (event) {
self.trace('onicecandidate', JSON.stringify(event.candidate, null, ' '));
if (self.onicecandidate !== null) {
self.onicecandidate(event);
}
};
this.onaddstream = null;
this.peerconnection.onaddstream = function (event) {
self.trace('onaddstream', event.stream.id);
if (self.onaddstream !== null) {
self.onaddstream(event);
}
};
this.onremovestream = null;
this.peerconnection.onremovestream = function (event) {
self.trace('onremovestream', event.stream.id);
if (self.onremovestream !== null) {
self.onremovestream(event);
}
};
this.onsignalingstatechange = null;
this.peerconnection.onsignalingstatechange = function (event) {
self.trace('onsignalingstatechange', self.signalingState);
if (self.onsignalingstatechange !== null) {
self.onsignalingstatechange(event);
}
};
this.oniceconnectionstatechange = null;
this.peerconnection.oniceconnectionstatechange = function (event) {
self.trace('oniceconnectionstatechange', self.iceConnectionState);
if (self.oniceconnectionstatechange !== null) {
self.oniceconnectionstatechange(event);
}
};
this.onnegotiationneeded = null;
this.peerconnection.onnegotiationneeded = function (event) {
self.trace('onnegotiationneeded');
if (self.onnegotiationneeded !== null) {
self.onnegotiationneeded(event);
}
};
self.ondatachannel = null;
this.peerconnection.ondatachannel = function (event) {
self.trace('ondatachannel', event);
if (self.ondatachannel !== null) {
self.ondatachannel(event);
}
};
if (!navigator.mozGetUserMedia && this.maxstats) {
this.statsinterval = window.setInterval(function() {
self.peerconnection.getStats(function(stats) {
var results = stats.result();
for (var i = 0; i < results.length; ++i) {
//console.log(results[i].type, results[i].id, results[i].names())
var now = new Date();
results[i].names().forEach(function (name) {
var id = results[i].id + '-' + name;
if (!self.stats[id]) {
self.stats[id] = {
startTime: now,
endTime: now,
values: [],
times: []
};
}
self.stats[id].values.push(results[i].stat(name));
self.stats[id].times.push(now.getTime());
if (self.stats[id].values.length > self.maxstats) {
self.stats[id].values.shift();
self.stats[id].times.shift();
}
self.stats[id].endTime = now;
});
}
});
}, 1000);
}
};
dumpSDP = function(description) {
return 'type: ' + description.type + '\r\n' + description.sdp;
}
if (TraceablePeerConnection.prototype.__defineGetter__ !== undefined) {
TraceablePeerConnection.prototype.__defineGetter__('signalingState', function() { return this.peerconnection.signalingState; });
TraceablePeerConnection.prototype.__defineGetter__('iceConnectionState', function() { return this.peerconnection.iceConnectionState; });
TraceablePeerConnection.prototype.__defineGetter__('localDescription', function() {
var publicLocalDescription = simulcast.reverseTransformLocalDescription(this.peerconnection.localDescription);
return publicLocalDescription;
});
TraceablePeerConnection.prototype.__defineGetter__('remoteDescription', function() {
var publicRemoteDescription = simulcast.reverseTransformRemoteDescription(this.peerconnection.remoteDescription);
return publicRemoteDescription;
});
}
TraceablePeerConnection.prototype.addStream = function (stream) {
this.trace('addStream', stream.id);
simulcast.resetSender();
try
{
this.peerconnection.addStream(stream);
}
catch (e)
{
console.error(e);
return;
}
};
TraceablePeerConnection.prototype.removeStream = function (stream, stopStreams) {
this.trace('removeStream', stream.id);
simulcast.resetSender();
if(stopStreams) {
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
stream.getVideoTracks().forEach(function (track) {
track.stop();
});
}
this.peerconnection.removeStream(stream);
};
TraceablePeerConnection.prototype.createDataChannel = function (label, opts) {
this.trace('createDataChannel', label, opts);
return this.peerconnection.createDataChannel(label, opts);
};
TraceablePeerConnection.prototype.setLocalDescription = function (description, successCallback, failureCallback) {
var self = this;
description = simulcast.transformLocalDescription(description);
this.trace('setLocalDescription', dumpSDP(description));
this.peerconnection.setLocalDescription(description,
function () {
self.trace('setLocalDescriptionOnSuccess');
successCallback();
},
function (err) {
self.trace('setLocalDescriptionOnFailure', err);
failureCallback(err);
}
);
/*
if (this.statsinterval === null && this.maxstats > 0) {
// start gathering stats
}
*/
};
TraceablePeerConnection.prototype.setRemoteDescription = function (description, successCallback, failureCallback) {
var self = this;
description = simulcast.transformRemoteDescription(description);
this.trace('setRemoteDescription', dumpSDP(description));
this.peerconnection.setRemoteDescription(description,
function () {
self.trace('setRemoteDescriptionOnSuccess');
successCallback();
},
function (err) {
self.trace('setRemoteDescriptionOnFailure', err);
failureCallback(err);
}
);
/*
if (this.statsinterval === null && this.maxstats > 0) {
// start gathering stats
}
*/
};
TraceablePeerConnection.prototype.close = function () {
this.trace('stop');
if (this.statsinterval !== null) {
window.clearInterval(this.statsinterval);
this.statsinterval = null;
}
this.peerconnection.close();
};
TraceablePeerConnection.prototype.createOffer = function (successCallback, failureCallback, constraints) {
var self = this;
this.trace('createOffer', JSON.stringify(constraints, null, ' '));
this.peerconnection.createOffer(
function (offer) {
self.trace('createOfferOnSuccess', dumpSDP(offer));
successCallback(offer);
},
function(err) {
self.trace('createOfferOnFailure', err);
failureCallback(err);
},
constraints
);
};
TraceablePeerConnection.prototype.createAnswer = function (successCallback, failureCallback, constraints) {
var self = this;
this.trace('createAnswer', JSON.stringify(constraints, null, ' '));
this.peerconnection.createAnswer(
function (answer) {
answer = simulcast.transformAnswer(answer);
self.trace('createAnswerOnSuccess', dumpSDP(answer));
successCallback(answer);
},
function(err) {
self.trace('createAnswerOnFailure', err);
failureCallback(err);
},
constraints
);
};
TraceablePeerConnection.prototype.addIceCandidate = function (candidate, successCallback, failureCallback) {
var self = this;
this.trace('addIceCandidate', JSON.stringify(candidate, null, ' '));
this.peerconnection.addIceCandidate(candidate);
/* maybe later
this.peerconnection.addIceCandidate(candidate,
function () {
self.trace('addIceCandidateOnSuccess');
successCallback();
},
function (err) {
self.trace('addIceCandidateOnFailure', err);
failureCallback(err);
}
);
*/
};
TraceablePeerConnection.prototype.getStats = function(callback, errback) {
if (navigator.mozGetUserMedia) {
// ignore for now...
if(!errback)
errback = function () {
}
this.peerconnection.getStats(null,callback,errback);
} else {
this.peerconnection.getStats(callback);
}
};

View File

@@ -1,306 +0,0 @@
/* jshint -W117 */
Strophe.addConnectionPlugin('jingle', {
connection: null,
sessions: {},
jid2session: {},
ice_config: {iceServers: []},
pc_constraints: {},
media_constraints: {
mandatory: {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true
}
// MozDontOfferDataChannel: true when this is firefox
},
localAudio: null,
localVideo: null,
init: function (conn) {
this.connection = conn;
if (this.connection.disco) {
// http://xmpp.org/extensions/xep-0167.html#support
// http://xmpp.org/extensions/xep-0176.html#support
this.connection.disco.addFeature('urn:xmpp:jingle:1');
this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:1');
this.connection.disco.addFeature('urn:xmpp:jingle:transports:ice-udp:1');
this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:audio');
this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:video');
// this is dealt with by SDP O/A so we don't need to annouce this
//this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:rtcp-fb:0'); // XEP-0293
//this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:rtp-hdrext:0'); // XEP-0294
if (config.useRtcpMux) {
this.connection.disco.addFeature('urn:ietf:rfc:5761'); // rtcp-mux
}
if (config.useBundle) {
this.connection.disco.addFeature('urn:ietf:rfc:5888'); // a=group, e.g. bundle
}
//this.connection.disco.addFeature('urn:ietf:rfc:5576'); // a=ssrc
}
this.connection.addHandler(this.onJingle.bind(this), 'urn:xmpp:jingle:1', 'iq', 'set', null, null);
},
onJingle: function (iq) {
var sid = $(iq).find('jingle').attr('sid');
var action = $(iq).find('jingle').attr('action');
var fromJid = iq.getAttribute('from');
// send ack first
var ack = $iq({type: 'result',
to: fromJid,
id: iq.getAttribute('id')
});
console.log('on jingle ' + action + ' from ' + fromJid, iq);
var sess = this.sessions[sid];
if ('session-initiate' != action) {
if (sess === null) {
ack.type = 'error';
ack.c('error', {type: 'cancel'})
.c('item-not-found', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up()
.c('unknown-session', {xmlns: 'urn:xmpp:jingle:errors:1'});
this.connection.send(ack);
return true;
}
// compare from to sess.peerjid (bare jid comparison for later compat with message-mode)
// local jid is not checked
if (Strophe.getBareJidFromJid(fromJid) != Strophe.getBareJidFromJid(sess.peerjid)) {
console.warn('jid mismatch for session id', sid, fromJid, sess.peerjid);
ack.type = 'error';
ack.c('error', {type: 'cancel'})
.c('item-not-found', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up()
.c('unknown-session', {xmlns: 'urn:xmpp:jingle:errors:1'});
this.connection.send(ack);
return true;
}
} else if (sess !== undefined) {
// existing session with same session id
// this might be out-of-order if the sess.peerjid is the same as from
ack.type = 'error';
ack.c('error', {type: 'cancel'})
.c('service-unavailable', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up();
console.warn('duplicate session id', sid);
this.connection.send(ack);
return true;
}
// FIXME: check for a defined action
this.connection.send(ack);
// see http://xmpp.org/extensions/xep-0166.html#concepts-session
switch (action) {
case 'session-initiate':
sess = new JingleSession($(iq).attr('to'), $(iq).find('jingle').attr('sid'), this.connection);
// configure session
//in firefox we have only one stream object
if (this.localAudio != this.localVideo) {
sess.localStreams.push(this.localAudio);
}
if (this.localVideo) {
sess.localStreams.push(this.localVideo);
}
sess.media_constraints = this.media_constraints;
sess.pc_constraints = this.pc_constraints;
sess.ice_config = this.ice_config;
sess.initiate(fromJid, false);
// FIXME: setRemoteDescription should only be done when this call is to be accepted
sess.setRemoteDescription($(iq).find('>jingle'), 'offer');
this.sessions[sess.sid] = sess;
this.jid2session[sess.peerjid] = sess;
// the callback should either
// .sendAnswer and .accept
// or .sendTerminate -- not necessarily synchronus
$(document).trigger('callincoming.jingle', [sess.sid]);
break;
case 'session-accept':
sess.setRemoteDescription($(iq).find('>jingle'), 'answer');
sess.accept();
$(document).trigger('callaccepted.jingle', [sess.sid]);
break;
case 'session-terminate':
// If this is not the focus sending the terminate, we have
// nothing more to do here.
if (Object.keys(this.sessions).length < 1
|| !(this.sessions[Object.keys(this.sessions)[0]]
instanceof JingleSession))
{
break;
}
console.log('terminating...', sess.sid);
sess.terminate();
this.terminate(sess.sid);
if ($(iq).find('>jingle>reason').length) {
$(document).trigger('callterminated.jingle', [
sess.sid,
sess.peerjid,
$(iq).find('>jingle>reason>:first')[0].tagName,
$(iq).find('>jingle>reason>text').text()
]);
} else {
$(document).trigger('callterminated.jingle',
[sess.sid, sess.peerjid]);
}
break;
case 'transport-info':
sess.addIceCandidate($(iq).find('>jingle>content'));
break;
case 'session-info':
var affected;
if ($(iq).find('>jingle>ringing[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
$(document).trigger('ringing.jingle', [sess.sid]);
} else if ($(iq).find('>jingle>mute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
affected = $(iq).find('>jingle>mute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').attr('name');
$(document).trigger('mute.jingle', [sess.sid, affected]);
} else if ($(iq).find('>jingle>unmute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
affected = $(iq).find('>jingle>unmute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').attr('name');
$(document).trigger('unmute.jingle', [sess.sid, affected]);
}
break;
case 'addsource': // FIXME: proprietary, un-jingleish
case 'source-add': // FIXME: proprietary
sess.addSource($(iq).find('>jingle>content'), fromJid);
break;
case 'removesource': // FIXME: proprietary, un-jingleish
case 'source-remove': // FIXME: proprietary
sess.removeSource($(iq).find('>jingle>content'), fromJid);
break;
default:
console.warn('jingle action not implemented', action);
break;
}
return true;
},
initiate: function (peerjid, myjid) { // initiate a new jinglesession to peerjid
var sess = new JingleSession(myjid || this.connection.jid,
Math.random().toString(36).substr(2, 12), // random string
this.connection);
// configure session
//in firefox we have only one stream
if (this.localAudio != this.localVideo) {
sess.localStreams.push(this.localAudio);
}
if (this.localVideo) {
sess.localStreams.push(this.localVideo);
}
sess.media_constraints = this.media_constraints;
sess.pc_constraints = this.pc_constraints;
sess.ice_config = this.ice_config;
sess.initiate(peerjid, true);
this.sessions[sess.sid] = sess;
this.jid2session[sess.peerjid] = sess;
sess.sendOffer();
return sess;
},
terminate: function (sid, reason, text) { // terminate by sessionid (or all sessions)
if (sid === null || sid === undefined) {
for (sid in this.sessions) {
if (this.sessions[sid].state != 'ended') {
this.sessions[sid].sendTerminate(reason || (!this.sessions[sid].active()) ? 'cancel' : null, text);
this.sessions[sid].terminate();
}
delete this.jid2session[this.sessions[sid].peerjid];
delete this.sessions[sid];
}
} else if (this.sessions.hasOwnProperty(sid)) {
if (this.sessions[sid].state != 'ended') {
this.sessions[sid].sendTerminate(reason || (!this.sessions[sid].active()) ? 'cancel' : null, text);
this.sessions[sid].terminate();
}
delete this.jid2session[this.sessions[sid].peerjid];
delete this.sessions[sid];
}
},
// Used to terminate a session when an unavailable presence is received.
terminateByJid: function (jid) {
if (this.jid2session.hasOwnProperty(jid)) {
var sess = this.jid2session[jid];
if (sess) {
sess.terminate();
console.log('peer went away silently', jid);
delete this.sessions[sess.sid];
delete this.jid2session[jid];
$(document).trigger('callterminated.jingle',
[sess.sid, jid], 'gone');
}
}
},
terminateRemoteByJid: function (jid, reason) {
if (this.jid2session.hasOwnProperty(jid)) {
var sess = this.jid2session[jid];
if (sess) {
sess.sendTerminate(reason || (!sess.active()) ? 'kick' : null);
sess.terminate();
console.log('terminate peer with jid', sess.sid, jid);
delete this.sessions[sess.sid];
delete this.jid2session[jid];
$(document).trigger('callterminated.jingle',
[sess.sid, jid, 'kicked']);
}
}
},
getStunAndTurnCredentials: function () {
// get stun and turn configuration from server via xep-0215
// uses time-limited credentials as described in
// http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00
//
// see https://code.google.com/p/prosody-modules/source/browse/mod_turncredentials/mod_turncredentials.lua
// for a prosody module which implements this
//
// currently, this doesn't work with updateIce and therefore credentials with a long
// validity have to be fetched before creating the peerconnection
// TODO: implement refresh via updateIce as described in
// https://code.google.com/p/webrtc/issues/detail?id=1650
var self = this;
this.connection.sendIQ(
$iq({type: 'get', to: this.connection.domain})
.c('services', {xmlns: 'urn:xmpp:extdisco:1'}).c('service', {host: 'turn.' + this.connection.domain}),
function (res) {
var iceservers = [];
$(res).find('>services>service').each(function (idx, el) {
el = $(el);
var dict = {};
var type = el.attr('type');
switch (type) {
case 'stun':
dict.url = 'stun:' + el.attr('host');
if (el.attr('port')) {
dict.url += ':' + el.attr('port');
}
iceservers.push(dict);
break;
case 'turn':
case 'turns':
dict.url = type + ':';
if (el.attr('username')) { // https://code.google.com/p/webrtc/issues/detail?id=1508
if (navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) && parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10) < 28) {
dict.url += el.attr('username') + '@';
} else {
dict.username = el.attr('username'); // only works in M28
}
}
dict.url += el.attr('host');
if (el.attr('port') && el.attr('port') != '3478') {
dict.url += ':' + el.attr('port');
}
if (el.attr('transport') && el.attr('transport') != 'udp') {
dict.url += '?transport=' + el.attr('transport');
}
if (el.attr('password')) {
dict.credential = el.attr('password');
}
iceservers.push(dict);
break;
}
});
self.ice_config.iceServers = iceservers;
},
function (err) {
console.warn('getting turn credentials failed', err);
console.warn('is mod_turncredentials or similar installed?');
}
);
// implement push?
}
});

File diff suppressed because one or more lines are too long

View File

@@ -1,41 +0,0 @@
/**
* Strophe logger implementation. Logs from level WARN and above.
*/
Strophe.log = function (level, msg) {
switch(level) {
case Strophe.LogLevel.WARN:
console.warn("Strophe: "+msg);
break;
case Strophe.LogLevel.ERROR:
case Strophe.LogLevel.FATAL:
console.error("Strophe: "+msg);
break;
}
};
Strophe.getStatusString = function(status)
{
switch (status)
{
case Strophe.Status.ERROR:
return "ERROR";
case Strophe.Status.CONNECTING:
return "CONNECTING";
case Strophe.Status.CONNFAIL:
return "CONNFAIL";
case Strophe.Status.AUTHENTICATING:
return "AUTHENTICATING";
case Strophe.Status.AUTHFAIL:
return "AUTHFAIL";
case Strophe.Status.CONNECTED:
return "CONNECTED";
case Strophe.Status.DISCONNECTED:
return "DISCONNECTED";
case Strophe.Status.DISCONNECTING:
return "DISCONNECTING";
case Strophe.Status.ATTACHED:
return "ATTACHED";
default:
return "unknown";
}
};

View File

@@ -1,32 +0,0 @@
/**
* Provides a wrapper class for the MediaStream.
*
* TODO : Add here the src from the video element and other related properties
* and get rid of some of the mappings that we use throughout the UI.
*/
var MediaStream = (function() {
/**
* Creates a MediaStream object for the given data, session id and ssrc.
*
* @param data the data object from which we obtain the stream,
* the peerjid, etc.
* @param sid the session id
* @param ssrc the ssrc corresponding to this MediaStream
*
* @constructor
*/
function MediaStreamProto(data, sid, ssrc) {
this.stream = data.stream;
this.peerjid = data.peerjid;
this.ssrc = ssrc;
this.session = connection.jingle.sessions[sid];
this.type = (this.stream.getVideoTracks().length > 0)
? MediaStream.VIDEO_TYPE : MediaStream.AUDIO_TYPE;
this.muted = false;
}
return MediaStreamProto;
})();
MediaStream.VIDEO_TYPE = 'Video';
MediaStream.AUDIO_TYPE = 'Audio';

View File

@@ -1,152 +0,0 @@
var messageHandler = (function(my) {
/**
* Shows a message to the user.
*
* @param titleString the title of the message
* @param messageString the text of the message
*/
my.openMessageDialog = function(titleString, messageString) {
$.prompt(messageString,
{
title: titleString,
persistent: false
}
);
};
/**
* Shows a message to the user with two buttons: first is given as a parameter and the second is Cancel.
*
* @param titleString the title of the message
* @param msgString the text of the message
* @param persistent boolean value which determines whether the message is persistent or not
* @param leftButton the fist button's text
* @param submitFunction function to be called on submit
* @param loadedFunction function to be called after the prompt is fully loaded
* @param closeFunction function to be called after the prompt is closed
*/
my.openTwoButtonDialog = function(titleString, msgString, persistent, leftButton,
submitFunction, loadedFunction, closeFunction) {
var buttons = {};
buttons[leftButton] = true;
buttons.Cancel = false;
$.prompt(msgString, {
title: titleString,
persistent: false,
buttons: buttons,
defaultButton: 1,
loaded: loadedFunction,
submit: submitFunction,
close: closeFunction
});
};
/**
* Shows a message to the user with two buttons: first is given as a parameter and the second is Cancel.
*
* @param titleString the title of the message
* @param msgString the text of the message
* @param persistent boolean value which determines whether the message is persistent or not
* @param buttons object with the buttons. The keys must be the name of the button and value is the value
* that will be passed to submitFunction
* @param submitFunction function to be called on submit
* @param loadedFunction function to be called after the prompt is fully loaded
*/
my.openDialog = function(titleString, msgString, persistent, buttons, submitFunction, loadedFunction) {
$.prompt(msgString, {
title: titleString,
persistent: false,
buttons: buttons,
defaultButton: 1,
loaded: loadedFunction,
submit: submitFunction
});
};
/**
* Shows a dialog with different states to the user.
*
* @param statesObject object containing all the states of the dialog
* @param loadedFunction function to be called after the prompt is fully loaded
* @param stateChangedFunction function to be called when the state of the dialog is changed
*/
my.openDialogWithStates = function(statesObject, loadedFunction, stateChangedFunction) {
var myPrompt = $.prompt(statesObject);
myPrompt.on('impromptu:loaded', loadedFunction);
myPrompt.on('impromptu:statechanged', stateChangedFunction);
};
/**
* Opens new popup window for given <tt>url</tt> centered over current
* window.
*
* @param url the URL to be displayed in the popup window
* @param w the width of the popup window
* @param h the height of the popup window
* @param onPopupClosed optional callback function called when popup window
* has been closed.
*
* @returns popup window object if opened successfully or undefined
* in case we failed to open it(popup blocked)
*/
my.openCenteredPopup = function (url, w, h, onPopupClosed) {
var l = window.screenX + (window.innerWidth / 2) - (w / 2);
var t = window.screenY + (window.innerHeight / 2) - (h / 2);
var popup = window.open(
url, '_blank',
'top=' + t + ', left=' + l + ', width=' + w + ', height=' + h + '');
if (popup && onPopupClosed) {
var pollTimer = window.setInterval(function () {
if (popup.closed !== false) {
window.clearInterval(pollTimer);
onPopupClosed();
}
}, 200);
}
return popup;
};
/**
* Shows a dialog prompting the user to send an error report.
*
* @param titleString the title of the message
* @param msgString the text of the message
* @param error the error that is being reported
*/
my.openReportDialog = function(titleString, msgString, error) {
my.openMessageDialog(titleString, msgString);
console.log(error);
//FIXME send the error to the server
};
/**
* Shows an error dialog to the user.
* @param title the title of the message
* @param message the text of the messafe
*/
my.showError = function(title, message) {
if(!(title || message)) {
title = title || "Oops!";
message = message || "There was some kind of error";
}
messageHandler.openMessageDialog(title, message);
};
my.notify = function(displayName, cls, message) {
toastr.info(
'<span class="nickname">' +
displayName +
'</span><br>' +
'<span class=' + cls + '>' +
message +
'</span>');
};
return my;
}(messageHandler || {}));

View File

@@ -1,60 +0,0 @@
/* global $, $iq, config, connection, focusMucJid, forceMuted, messageHandler,
setAudioMuted, Strophe, toggleAudio */
/**
* Moderate connection plugin.
*/
Strophe.addConnectionPlugin('moderate', {
connection: null,
init: function (conn) {
this.connection = conn;
this.connection.addHandler(this.onMute.bind(this),
'http://jitsi.org/jitmeet/audio',
'iq',
'set',
null,
null);
},
setMute: function (jid, mute) {
console.info("set mute", mute);
var iqToFocus = $iq({to: focusMucJid, type: 'set'})
.c('mute', {
xmlns: 'http://jitsi.org/jitmeet/audio',
jid: jid
})
.t(mute.toString())
.up();
this.connection.sendIQ(
iqToFocus,
function (result) {
console.log('set mute', result);
},
function (error) {
console.log('set mute error', error);
// FIXME: this causes an exception
//messageHandler.openReportDialog(null, 'Failed to mute ' +
// $("#participant_" + jid).find(".displayname").text() ||
//"participant" + '.', error);
});
},
onMute: function (iq) {
var from = iq.getAttribute('from');
if (from !== focusMucJid) {
console.warn("Ignored mute from non focus peer");
return false;
}
var mute = $(iq).find('mute');
if (mute.length) {
var doMuteAudio = mute.text() === "true";
setAudioMuted(doMuteAudio);
forceMuted = doMuteAudio;
}
return true;
},
eject: function (jid) {
// We're not the focus, so can't terminate
//connection.jingle.terminateRemoteByJid(jid, 'kick');
connection.emuc.kick(jid);
}
});

View File

@@ -1,236 +0,0 @@
/* global $, $iq, config, connection, Etherpad, hangUp, messageHandler,
roomName, sessionTerminated, Strophe, Toolbar, Util, VideoLayout */
/**
* Contains logic responsible for enabling/disabling functionality available
* only to moderator users.
*/
var Moderator = (function (my) {
var focusUserJid;
var getNextTimeout = Util.createExpBackoffTimer(1000);
var getNextErrorTimeout = Util.createExpBackoffTimer(1000);
// External authentication stuff
var externalAuthEnabled = false;
my.isModerator = function () {
return connection.emuc.isModerator();
};
my.isPeerModerator = function (peerJid) {
return connection.emuc.getMemberRole(peerJid) === 'moderator';
};
my.isExternalAuthEnabled = function () {
return externalAuthEnabled;
};
my.onModeratorStatusChanged = function (isModerator) {
Toolbar.showSipCallButton(isModerator);
Toolbar.showRecordingButton(
isModerator); //&&
// FIXME:
// Recording visible if
// there are at least 2(+ 1 focus) participants
//Object.keys(connection.emuc.members).length >= 3);
if (isModerator && config.etherpad_base) {
Etherpad.init();
}
};
my.init = function () {
$(document).bind(
'local.role.changed.muc',
function (event, jid, info, pres) {
Moderator.onModeratorStatusChanged(Moderator.isModerator());
}
);
$(document).bind(
'left.muc',
function (event, jid) {
console.info("Someone left is it focus ? " + jid);
var resource = Strophe.getResourceFromJid(jid);
if (resource === 'focus' && !sessionTerminated) {
console.info(
"Focus has left the room - leaving conference");
//hangUp();
// We'd rather reload to have everything re-initialized
// FIXME: show some message before reload
location.reload();
}
}
);
};
my.setFocusUserJid = function (focusJid) {
if (!focusUserJid) {
focusUserJid = focusJid;
console.info("Focus jid set to: " + focusUserJid);
}
};
my.getFocusUserJid = function () {
return focusUserJid;
};
my.getFocusComponent = function () {
// Get focus component address
var focusComponent = config.hosts.focus;
// If not specified use default: 'focus.domain'
if (!focusComponent) {
focusComponent = 'focus.' + config.hosts.domain;
}
return focusComponent;
};
my.createConferenceIq = function () {
// Generate create conference IQ
var elem = $iq({to: Moderator.getFocusComponent(), type: 'set'});
elem.c('conference', {
xmlns: 'http://jitsi.org/protocol/focus',
room: roomName
});
if (config.hosts.bridge !== undefined)
{
elem.c(
'property',
{ name: 'bridge', value: config.hosts.bridge})
.up();
}
if (config.channelLastN !== undefined)
{
elem.c(
'property',
{ name: 'channelLastN', value: config.channelLastN})
.up();
}
if (config.adaptiveLastN !== undefined)
{
elem.c(
'property',
{ name: 'adaptiveLastN', value: config.adaptiveLastN})
.up();
}
if (config.adaptiveSimulcast !== undefined)
{
elem.c(
'property',
{ name: 'adaptiveSimulcast', value: config.adaptiveSimulcast})
.up();
}
if (config.openSctp !== undefined)
{
elem.c(
'property',
{ name: 'openSctp', value: config.openSctp})
.up();
}
if (config.enableFirefoxSupport !== undefined)
{
elem.c(
'property',
{ name: 'enableFirefoxHacks', value: config.enableFirefoxSupport})
.up();
}
elem.up();
return elem;
};
my.parseConfigOptions = function (resultIq) {
Moderator.setFocusUserJid(
$(resultIq).find('conference').attr('focusjid'));
var extAuthParam
= $(resultIq).find('>conference>property[name=\'externalAuth\']');
if (extAuthParam.length) {
externalAuthEnabled = extAuthParam.attr('value') === 'true';
}
console.info("External authentication enabled: " + externalAuthEnabled);
};
// FIXME: we need to show the fact that we're waiting for the focus
// to the user(or that focus is not available)
my.allocateConferenceFocus = function (roomName, callback) {
// Try to use focus user JID from the config
Moderator.setFocusUserJid(config.focusUserJid);
// Send create conference IQ
var iq = Moderator.createConferenceIq();
connection.sendIQ(
iq,
function (result) {
if ('true' === $(result).find('conference').attr('ready')) {
// Reset both timers
getNextTimeout(true);
getNextErrorTimeout(true);
// Setup config options
Moderator.parseConfigOptions(result);
// Exec callback
callback();
} else {
var waitMs = getNextTimeout();
console.info("Waiting for the focus... " + waitMs);
// Reset error timeout
getNextErrorTimeout(true);
window.setTimeout(
function () {
Moderator.allocateConferenceFocus(
roomName, callback);
}, waitMs);
}
},
function (error) {
// Not authorized to create new room
if ($(error).find('>error>not-authorized').length) {
console.warn("Unauthorized to start the conference");
$(document).trigger('auth_required.moderator');
return;
}
var waitMs = getNextErrorTimeout();
console.error("Focus error, retry after " + waitMs, error);
// Show message
messageHandler.notify(
'Conference focus', 'disconnected',
Moderator.getFocusComponent() +
' not available - retry in ' + (waitMs / 1000) + ' sec');
// Reset response timeout
getNextTimeout(true);
window.setTimeout(
function () {
Moderator.allocateConferenceFocus(roomName, callback);
}, waitMs);
}
);
};
my.getAuthUrl = function (urlCallback) {
var iq = $iq({to: Moderator.getFocusComponent(), type: 'get'});
iq.c('auth-url', {
xmlns: 'http://jitsi.org/protocol/focus',
room: roomName
});
connection.sendIQ(
iq,
function (result) {
var url = $(result).find('auth-url').attr('url');
if (url) {
console.info("Got auth url: " + url);
urlCallback(url);
} else {
console.error(
"Failed to get auth url fro mthe focus", result);
}
},
function (error) {
console.error("Get auth url error", error);
}
);
};
return my;
}(Moderator || {}));

219
modules/API/API.js Normal file
View File

@@ -0,0 +1,219 @@
/* global APP */
/**
* Implements API class that communicates with external api class
* and provides interface to access Jitsi Meet features by external
* applications that embed Jitsi Meet
*/
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
/**
* List of the available commands.
* @type {{
* displayName: inputDisplayNameHandler,
* toggleAudio: toggleAudio,
* toggleVideo: toggleVideo,
* toggleFilmStrip: toggleFilmStrip,
* toggleChat: toggleChat,
* toggleContactList: toggleContactList
* }}
*/
var commands = {};
function initCommands() {
commands = {
displayName: APP.UI.inputDisplayNameHandler,
toggleAudio: APP.UI.toggleAudio,
toggleVideo: APP.UI.toggleVideo,
toggleFilmStrip: APP.UI.toggleFilmStrip,
toggleChat: APP.UI.toggleChat,
toggleContactList: APP.UI.toggleContactList
};
}
/**
* Maps the supported events and their status
* (true it the event is enabled and false if it is disabled)
* @type {{
* incomingMessage: boolean,
* outgoingMessage: boolean,
* displayNameChange: boolean,
* participantJoined: boolean,
* participantLeft: boolean
* }}
*/
var events = {
incomingMessage: false,
outgoingMessage:false,
displayNameChange: false,
participantJoined: false,
participantLeft: false
};
var displayName = {};
/**
* Processes commands from external application.
* @param message the object with the command
*/
function processCommand(message) {
if (message.action != "execute") {
console.error("Unknown action of the message");
return;
}
for (var key in message) {
if(commands[key])
commands[key].apply(null, message[key]);
}
}
/**
* Processes events objects from external applications
* @param event the event
*/
function processEvent(event) {
if (!event.action) {
console.error("Event with no action is received.");
return;
}
var i = 0;
switch(event.action) {
case "add":
for (; i < event.events.length; i++) {
events[event.events[i]] = true;
}
break;
case "remove":
for (; i < event.events.length; i++) {
events[event.events[i]] = false;
}
break;
default:
console.error("Unknown action for event.");
}
}
/**
* Sends message to the external application.
* @param object
*/
function sendMessage(object) {
window.parent.postMessage(JSON.stringify(object), "*");
}
/**
* Processes a message event from the external application
* @param event the message event
*/
function processMessage(event) {
var message;
try {
message = JSON.parse(event.data);
} catch (e) {}
if(!message.type)
return;
switch (message.type) {
case "command":
processCommand(message);
break;
case "event":
processEvent(message);
break;
default:
console.error("Unknown type of the message");
return;
}
}
function setupListeners() {
APP.xmpp.addListener(XMPPEvents.MUC_MEMBER_JOINED, function (from) {
API.triggerEvent("participantJoined", {jid: from});
});
APP.xmpp.addListener(XMPPEvents.MESSAGE_RECEIVED, function (from, nick, txt, myjid, stamp) {
if (from != myjid)
API.triggerEvent("incomingMessage",
{"from": from, "nick": nick, "message": txt, "stamp": stamp});
});
APP.xmpp.addListener(XMPPEvents.MUC_MEMBER_LEFT, function (jid) {
API.triggerEvent("participantLeft", {jid: jid});
});
APP.xmpp.addListener(XMPPEvents.DISPLAY_NAME_CHANGED, function (jid, newDisplayName) {
var name = displayName[jid];
if(!name || name != newDisplayName) {
API.triggerEvent("displayNameChange", {jid: jid, displayname: newDisplayName});
displayName[jid] = newDisplayName;
}
});
APP.xmpp.addListener(XMPPEvents.SENDING_CHAT_MESSAGE, function (body) {
APP.API.triggerEvent("outgoingMessage", {"message": body});
});
}
var API = {
/**
* Check whether the API should be enabled or not.
* @returns {boolean}
*/
isEnabled: function () {
var hash = location.hash;
if (hash && hash.indexOf("external") > -1 && window.postMessage)
return true;
return false;
},
/**
* Initializes the APIConnector. Setups message event listeners that will
* receive information from external applications that embed Jitsi Meet.
* It also sends a message to the external application that APIConnector
* is initialized.
*/
init: function () {
initCommands();
if (window.addEventListener) {
window.addEventListener('message',
processMessage, false);
}
else {
window.attachEvent('onmessage', processMessage);
}
sendMessage({type: "system", loaded: true});
setupListeners();
},
/**
* Checks whether the event is enabled ot not.
* @param name the name of the event.
* @returns {*}
*/
isEventEnabled: function (name) {
return events[name];
},
/**
* Sends event object to the external application that has been subscribed
* for that event.
* @param name the name event
* @param object data associated with the event
*/
triggerEvent: function (name, object) {
if(this.isEnabled() && this.isEventEnabled(name))
sendMessage({
type: "event", action: "result", event: name, result: object});
},
/**
* Removes the listeners.
*/
dispose: function () {
if(window.removeEventListener) {
window.removeEventListener("message",
processMessage, false);
}
else {
window.detachEvent('onmessage', processMessage);
}
}
};
module.exports = API;

Some files were not shown because too many files have changed in this diff Show More