freeswitch.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. <html>
  2. <head>
  3. <meta http-equiv="Pragma" content="no-cache">
  4. <meta http-equiv="Expires" content="-1">
  5. <meta http-equiv="cache-control" content="no-store">
  6. <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
  7. <script language="javascript" content-type="text/javascript" src="swfobject.js"></script>
  8. <script language="javascript" content-type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
  9. <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.3/jquery-ui.min.js" ></script>
  10. <script language="javascript" type="text/javascript" src="jquery.query-2.1.7.js"></script>
  11. <script language="javascript" type="text/javascript" src="jquery.tmpl.js"></script>
  12. <script language="javascript" content-type="text/javascript">
  13. var flashvars = {
  14. rtmp_url: 'rtmp://my.ip.address.here/phone'
  15. };
  16. var params = {
  17. allowScriptAccess: 'always'
  18. };
  19. function makeCall(number, account, options) {
  20. $("#flash")[0].makeCall(number, account, options);
  21. }
  22. function sendDTMF(digit, duration) {
  23. $("#flash")[0].sendDTMF(digit, duration);
  24. }
  25. function onDisplayUpdate(uuid, name, number) {
  26. var elm = $("#call_" + uuid);
  27. elm.children(".callerid_name").text(name);
  28. elm.children(".callerid_number").text(number);
  29. elm.data("name", name);
  30. elm.data("number", number);
  31. if (uuid == $("#incoming_call").data("uuid")) {
  32. $("#incoming_name").text(name);
  33. $("#incoming_number").text(number);
  34. }
  35. }
  36. function hangup(uuid) {
  37. $("#flash")[0].hangup(uuid);
  38. }
  39. function answer(uuid) {
  40. $("#flash")[0].answer(uuid);
  41. }
  42. function attach(uuid) {
  43. $("#flash")[0].attach(uuid);
  44. }
  45. function transfer(uuid, dest) {
  46. $("#flash")[0].transfer(uuid, dest);
  47. }
  48. function ui_transfer(uuid) {
  49. $("#transfer").data("uuid", uuid);
  50. $("#transfer").dialog('open');
  51. }
  52. function three_way(uuid1, uuid2) {
  53. $("#flash")[0].three_way(uuid1, uuid2);
  54. }
  55. function do_three_way(uuid) {
  56. var a = $(".active_call").data("uuid");
  57. if (a != "") {
  58. three_way(a, uuid);
  59. }
  60. }
  61. function do_join(uuid) {
  62. var a = $(".active_call").data("uuid");
  63. if (a != "") {
  64. join(a, uuid);
  65. }
  66. }
  67. function join(uuid1, uuid2) {
  68. $("#flash")[0].join(uuid1, uuid2);
  69. }
  70. function onCallState(uuid, state) {
  71. $("#call_"+uuid).children('.call_state').text(state);
  72. }
  73. function onIncomingCall(uuid, name, number, account, evt) {
  74. if (name == "") {
  75. name = "Unknown Name";
  76. }
  77. if (number == "") {
  78. number = "Unknown Number";
  79. }
  80. add_call(uuid, name, number);
  81. $("#incoming_call").data("uuid", uuid);
  82. $("#incoming_name").text(name);
  83. $("#incoming_number").text(number);
  84. $("#incoming_account").text(account);
  85. $("#incoming_call").dialog('open');
  86. }
  87. function onDisconnected() {
  88. $("#status").text("Disconnected");
  89. $("#sessionid").text("");
  90. setTimeout(function() {
  91. $("#status").text("Connecting...");
  92. $("#flash")[0].connect();
  93. }, 5000);
  94. }
  95. function onMakeCall(uuid, number, account) {
  96. add_call(uuid, "", number, account);
  97. }
  98. function onHangup(uuid, cause) {
  99. if ($("#incoming_call").data("uuid") == uuid) {
  100. $("#incoming_call").dialog('close');
  101. }
  102. $("#call_" + uuid).children(".hangupcause").text(cause);
  103. setTimeout(function() {
  104. remove_call(uuid);
  105. }, 1000);
  106. }
  107. function onDebug(message) {
  108. $("#log").append(message + "<br/>");
  109. }
  110. function onAttach(uuid) {
  111. $(".active_call").removeClass('active_call');
  112. if (uuid == "") {
  113. $("a", "#controls").button("option", "disabled", true);
  114. } else {
  115. $("a", "#controls").button("option", "disabled", false);
  116. $("#call_" + uuid).addClass('active_call');
  117. }
  118. }
  119. function checkMic() {
  120. try {
  121. if ($("#flash")[0].isMuted()) {
  122. $("#no_mic").show();
  123. $("#input_source").hide();
  124. return false;
  125. } else {
  126. $("#no_mic").hide();
  127. $("#input_source").show();
  128. return true;
  129. }
  130. } catch(err) {
  131. return false;
  132. }
  133. }
  134. function onConnected(sessionid) {
  135. $("#sessionid").text(sessionid);
  136. $(".call", "#call_container").remove();
  137. $(".account", "#account_container").remove();
  138. $("#status").text("Connected");
  139. if (!checkMic()) {
  140. $("#security").dialog('open');
  141. }
  142. }
  143. function login(user,pass) {
  144. $("#flash")[0].login(user,pass);
  145. }
  146. function logout(account) {
  147. $("#flash")[0].logout(account);
  148. }
  149. function onLogin(status, user, domain) {
  150. if (status != "success") {
  151. softAlert("Authentication failed!", "onAuth");
  152. } else {
  153. //$("#status").html("Connected as <span class='user'>" + user + "</span>@<span class='domain'>" + domain + "</span>");
  154. var u = user + '@' + domain;
  155. $("#flash")[0].register(u, $.query.get('code'));
  156. add_account(user, domain);
  157. }
  158. }
  159. function onLogout(user,domain) {
  160. remove_account(user, domain);
  161. }
  162. function onInit() {
  163. var mics = eval($("#flash")[0].micList());
  164. var sources = $("#input_source");
  165. var current_mic = $("#flash")[0].getMic();
  166. sources.children().remove();
  167. $("#status").text("Connecting...");
  168. for (i = 0; i < mics.length; i++) {
  169. var a = (i == current_mic) ? "selected" : "";
  170. sources.append("<option value='"+ i + "' " + a + " >" + mics[i] + "</option");
  171. }
  172. }
  173. function onEvent(data) {
  174. onDebug("Got event: " + data);
  175. }
  176. function softAlert(message,title) {
  177. $("#message_text").text(message);
  178. $("#message").dialog('option', 'title', title);
  179. $("#message").dialog('open');
  180. }
  181. function get_uuid(object) {
  182. return object.parent(".call").data("uuid");
  183. }
  184. function add_call(uuid, name, number, account) {
  185. var c = [ {uuid: uuid, name: name, number: number, account: account } ];
  186. var elm = $("#call_template").tmpl(c);
  187. elm.data("uuid", uuid);
  188. elm.data("name", name);
  189. elm.data("number", number);
  190. elm.data("account", account);
  191. elm.appendTo("#call_container");
  192. }
  193. function remove_call(uuid) {
  194. var c = $('#call_'+ uuid);
  195. c.fadeOut("slow", function() { c.remove() } );
  196. }
  197. function get_user(object) {
  198. return object.parent(".account").data("user");
  199. }
  200. function add_account(suser, domain) {
  201. var u = suser + "@" + domain;
  202. var sid = u.replace("@", "_").replace(/\./g, "_");
  203. var c = [ { id: sid, user: u} ];
  204. var elm = $("#account_template").tmpl(c);
  205. elm.data("user", u);
  206. elm.appendTo("#account_container");
  207. $("a", "#account_" + sid).button();
  208. }
  209. function remove_account(suser,domain) {
  210. var u = suser + "_" + domain;
  211. var sid = u.replace(/\./g, "_")
  212. var c = $('#account_'+ sid);
  213. c.fadeOut("slow", function() { c.remove() } );
  214. }
  215. function showSecurity() {
  216. $("#security").dialog('open');
  217. }
  218. function newcall(account) {
  219. $("#callout").data('account', account);
  220. $("#callout").dialog('open');
  221. }
  222. $(document).ready(function() {
  223. swfobject.embedSWF("freeswitch.swf", "flash", "250", "150", "9.0.0", "expressInstall.swf", flashvars, params, []);
  224. if (swfobject.ua.ie) {
  225. $("#flash").css("top", "-500px");
  226. $("#flash").css("left", "-500px");
  227. } else {
  228. $("#flash").css("visibility", "hidden");
  229. }
  230. $("#incoming_call").dialog({
  231. autoOpen: false,
  232. resizable: false,
  233. buttons: {
  234. "Answer": function() {
  235. answer($(this).data("uuid"));
  236. $(this).dialog("close");
  237. },
  238. "Decline": function() {
  239. hangup($(this).data("uuid"));
  240. $(this).dialog("close");
  241. }
  242. }});
  243. $("#callout").dialog({
  244. autoOpen: false,
  245. resizable: false,
  246. width: 600,
  247. buttons: {
  248. "Call": function() {
  249. makeCall($("#number").val(), $(this).data('account'), []);
  250. $(this).dialog("close");
  251. },
  252. "Cancel": function() {
  253. $(this).dialog("close"); }
  254. }
  255. });
  256. $("#message").dialog({
  257. autoOpen: false,
  258. resizable: false,
  259. buttons: {
  260. "Ok": function() {
  261. $(this).dialog("close");
  262. }
  263. }});
  264. $("#controls").dialog({
  265. title: "Keypad",
  266. autoOpen: false,
  267. resizable: false,
  268. width: 200,
  269. height: 220
  270. });
  271. $("#auth").dialog({
  272. modal: true,
  273. autoOpen: false,
  274. resizable: false,
  275. buttons: {
  276. "Ok": function() {
  277. login($("#username").val(), $("#password").val());
  278. $("#password").val('');
  279. $(this).dialog('close');
  280. },
  281. "Cancel": function() {
  282. $(this).dialog('close');
  283. }
  284. }
  285. });
  286. $("#transfer").dialog({
  287. autoOpen: false,
  288. resizable: false,
  289. width: 600,
  290. buttons: {
  291. "Ok": function() {
  292. transfer($(this).data("uuid"), $("#transfer_number").val());
  293. $(this).dialog('close');
  294. },
  295. "Cancel": function() {
  296. $(this).dialog('close');
  297. }
  298. }
  299. });
  300. $("#security").dialog({
  301. autoOpen: false,
  302. modal: true,
  303. resizable: false,
  304. buttons: {
  305. "Ok": function() {
  306. $(this).dialog("close");
  307. }
  308. },
  309. minWidth: 300,
  310. minHeight: 170,
  311. drag: function () {
  312. var flash = $("#flash");
  313. var fake_flash = $("#fake_flash");
  314. var offset = fake_flash.offset();
  315. flash.css("left", offset.left);
  316. flash.css("top", offset.top + 20);
  317. },
  318. open: function () {
  319. var flash = $("#flash");
  320. var fake_flash = $("#fake_flash");
  321. var offset = fake_flash.offset();
  322. fake_flash.css("width", flash.width())
  323. fake_flash.css("height", flash.height() + 20)
  324. flash.css("left", offset.left);
  325. flash.css("top", offset.top + 20);
  326. flash.css("visibility", "visible");
  327. flash.css("z-index", $("#security").parent(".ui-dialog").css("z-index") + 1);
  328. flash[0].showPrivacy();
  329. },
  330. close: function() {
  331. var flash = $("#flash");
  332. flash.css("visibility", "hidden");
  333. flash.css("left", 0);
  334. flash.css("top", 0);
  335. flash.css("z-index", "auto");
  336. checkMic();
  337. }
  338. });
  339. $("a", "#controls").button({ disabled: true });
  340. $("a", "#call_container").button();
  341. $("a", "#guest_account").button();
  342. });
  343. function testevent() {
  344. var evt = {
  345. test1: "hello",
  346. test2: "hallo",
  347. test3: "allo"
  348. };
  349. $("#flash")[0].sendevent(evt);
  350. }
  351. </script>
  352. <style type="text/css">
  353. .dtmfrow {
  354. min-width: 50px;
  355. width: 20px;
  356. height: 20px;
  357. text-align: center;
  358. vertical-align: center;
  359. }
  360. #call_container {
  361. float: right;
  362. }
  363. #account_container {
  364. float: left;
  365. }
  366. .call {
  367. border: 1px solid #181469;
  368. width: 400px;
  369. height: 120px;
  370. }
  371. .account, #guest_account {
  372. border: 1px solid #181469;
  373. height: 100px;
  374. width: 300px;
  375. padding-left: 20px;
  376. }
  377. #call_add {
  378. width: 400px;
  379. text-align: right;
  380. }
  381. .active_call {
  382. background-color: #DBF2C2;
  383. }
  384. .three_way {
  385. background-color: #C0DAF2;
  386. }
  387. #controls {
  388. float: left;
  389. }
  390. #flash {
  391. float: left;
  392. visibility: hidden;
  393. position: absolute;
  394. top: 0;
  395. left: 0;
  396. }
  397. #log {
  398. font-size: 13px;
  399. }
  400. #header {
  401. background-color: #003366;
  402. color: white;
  403. height: 30px;
  404. width: 100%;
  405. padding-top: 10px;
  406. padding-left: 5px;
  407. }
  408. #input_source_container {
  409. }
  410. #status {
  411. }
  412. #sessionid {
  413. margin-left: 20px;
  414. }
  415. #header a, #header a:visited, #header a:hover {
  416. color: #white;
  417. text-decoration: underline;
  418. }
  419. #no_mic {
  420. float: right;
  421. padding-right: 10px;
  422. display: none;
  423. }
  424. #input_source {
  425. float: right;
  426. padding-right: 10px;
  427. }
  428. </style>
  429. <script id="call_template" type="text/html">
  430. <div class="call" id="call_{{= uuid}}">
  431. <p class="callerid">
  432. Account: {{= account}}<br/>
  433. <span class="callerid_name">{{= name}}</span> <span class="callerid_number">{{= number}}</span>
  434. </p>
  435. Call state: <span class="call_state"></span> <span class="hangupcause"></span><br/>
  436. <a href="#" onClick="attach(get_uuid($(this)))">Switch</a>
  437. <a href="#" onClick="hangup(get_uuid($(this)))">Hangup</a>
  438. <a href="#" onClick="do_three_way(get_uuid($(this)))">3-way</a>
  439. <a href="#" onClick="do_join(get_uuid($(this)))">Join</a>
  440. <a href="#" onClick="ui_transfer(get_uuid($(this)))">Transfer</a>
  441. </div>
  442. </script>
  443. <script id="account_template" type="text/html">
  444. <div class="account" id="account_{{= id}}">
  445. <p>User: {{= user}}</p>
  446. <a href="#" onClick="logout(get_user($(this)))">Logout</a>
  447. <a href="#" onClick="newcall(get_user($(this)));">+ New Call</a>
  448. </div>
  449. </script>
  450. </head>
  451. <body>
  452. <!-- Dialogs -->
  453. <div id="incoming_call" title="Incoming call">
  454. Account: <span id="incoming_account"></span><br/>
  455. <h3><span id="incoming_name"></span></h3>
  456. <h3><span id="incoming_number"></span></h3>
  457. </div>
  458. <div id="callout" title="Call out">
  459. <input type="text" id="number" value="sip:888@conference.freeswitch.org" size="58" />
  460. </div>
  461. <div id="message">
  462. <span id="message_text"></span>
  463. </div>
  464. <div id="transfer" title="Transfer call">
  465. <input type="text" id="transfer_number" value="sip:888@conference.freeswitch.org" size="58" />
  466. </div>
  467. <div id="security" title="Permissions required">
  468. You must accept to use your microphone on this site in order to be able to make phone calls
  469. <div id="fake_flash" width="300" height="170"></div>
  470. </div>
  471. <div id="auth" title="Login">
  472. Username: <input type="text" name="username" value="" id="username" />
  473. Password: <input type="password" name="password" value="" id="password" />
  474. </div>
  475. <!-- End Dialogs -->
  476. <div id="header">
  477. <span id="status">Waiting for flash...</span>
  478. <span id="sessionid"></span>
  479. <span id="no_mic">
  480. <img src="warning-icon.png" width="21" height="20" />
  481. <a href="#" onClick="showSecurity();">Microphone not allowed</a>
  482. </span>
  483. <select id="input_source" onChange="$('#flash')[0].setMic($(this).val())" >
  484. </select>
  485. </div>
  486. <div id="flash">
  487. <h1>Alternative content</h1>
  488. <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
  489. </div>
  490. <div id="call_container">
  491. <div id="call_add" class="button">
  492. <a href="#" onClick="attach('');">Hold</a>
  493. </div>
  494. </div>
  495. <div>
  496. <a href="#" onClick="showSecurity();">Privacy</a>
  497. <a href="#" onClick="$('#log').html('')" >Clear log</a>
  498. <a href="#" onClick="$('#controls').dialog('open');">Show Keypad</a>
  499. <a href="#" onClick="$('#auth').dialog('open');">Login</a>
  500. </div>
  501. <div id="controls" class="button">
  502. <table cols=3 border=0>
  503. <tr>
  504. <td class="dtmfrow"><a href="#" onClick="sendDTMF('1', 2000)">1</a></td>
  505. <td class="dtmfrow"><a href="#" onClick="sendDTMF('2', 2000)">2</a></td>
  506. <td class="dtmfrow"><a href="#" onClick="sendDTMF('3', 2000)">3</a></td>
  507. </tr>
  508. <tr>
  509. <td class="dtmfrow"><a href="#" onClick="sendDTMF('4', 2000)">4</a></td>
  510. <td class="dtmfrow"><a href="#" onClick="sendDTMF('5', 2000)">5</a></td>
  511. <td class="dtmfrow"><a href="#" onClick="sendDTMF('6', 2000)">6</a></td>
  512. </tr>
  513. <tr>
  514. <td class="dtmfrow"><a href="#" onClick="sendDTMF('7', 2000)">7</a></td>
  515. <td class="dtmfrow"><a href="#" onClick="sendDTMF('8', 2000)">8</a></td>
  516. <td class="dtmfrow"><a href="#" onClick="sendDTMF('9', 2000)">9</a></td>
  517. </tr>
  518. <tr>
  519. <td class="dtmfrow"><a href="#" onClick="sendDTMF('*', 2000)">*</a></td>
  520. <td class="dtmfrow"><a href="#" onClick="sendDTMF('0', 2000)">0</a></td>
  521. <td class="dtmfrow"><a href="#" onClick="sendDTMF('#', 2000)">#</a></td>
  522. </tr>
  523. </table>
  524. <div id="#input_device">
  525. </div>
  526. </div>
  527. <div id="account_container">
  528. <div class="guest_account" id="guest_account">
  529. <p>Guest account</p>
  530. <a href="#" onClick="newcall('');">+ New Call</a>
  531. </div>
  532. </div>
  533. <div id="log">
  534. </div>
  535. </body>
  536. </html>