not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

750 lines
28 KiB

  1. define(["activity/recordrtc", "sugar-web/activity/activity", "sugar-web/datastore", "activity/gif-recorder"], function (recordRTC, activity, datastore, gifRecorder) {
  2. function displayAlertMessage(message) {
  3. var div = document.createElement("p");
  4. div.innerHTML = message;
  5. div.style.color = "#f00";
  6. div.style.position = "fixed";
  7. div.style.top = "0px";
  8. div.style.width = "auto";
  9. div.style.padding = "4px";
  10. div.style.fontSize = "42px";
  11. div.style.background = "#fff";
  12. document.body.appendChild(div);
  13. div.style.left = document.body.clientWidth / 2 - (div.getBoundingClientRect().width / 2) + "px";
  14. setTimeout(function () {
  15. div.parentNode.removeChild(div);
  16. }, 3000);
  17. }
  18. var captureHelper = {
  19. ids: [],
  20. by: "by",
  21. popupMode: false,
  22. width: 320,
  23. height: 240,
  24. displayLoading: function () {
  25. var loading = document.getElementById("loading");
  26. loading.style.top = parseInt(5 * document.body.clientHeight / 100) + "px";
  27. loading.style.left = parseInt(5 * document.body.clientWidth / 100) + "px";
  28. loading.style.width = parseInt(90 * document.body.clientWidth / 100) + "px";
  29. loading.style.padding = "10px";
  30. loading.style.display = "block";
  31. },
  32. hideLoading: function () {
  33. var loading = document.getElementById("loading");
  34. loading.style.display = "none";
  35. },
  36. displayAllData: function (datas) {
  37. var t = this;
  38. for (var i = 0; i < datas.length; i++) {
  39. t.displayData(datas[i]);
  40. }
  41. },
  42. forgeAndInsertData: function (data) {
  43. var t = this;
  44. this.insertData(data, function (error, metadata) {
  45. var data = null;
  46. var datas = datastore.find();
  47. var found = false;
  48. for (i = 0; i < datas.length; i++) {
  49. if (datas[i].objectId == metadata) {
  50. found = true;
  51. data = datas[i];
  52. break;
  53. }
  54. }
  55. if (!found) {
  56. displayAlertMessage("No more space<br/><div style='text-align: center;'><img src='icons/emblem-warning.svg'></div>");
  57. return;
  58. }
  59. t.ids.push(metadata);
  60. activity.getDatastoreObject().setDataAsText(JSON.stringify({ids: t.ids}));
  61. activity.getDatastoreObject().save(function (error) {
  62. });
  63. var dsObject = new datastore.DatastoreObject(data.objectId);
  64. dsObject.loadAsText(function(err, meta, text) {
  65. data.text = text;
  66. captureHelper.displayData(data, true);
  67. });
  68. });
  69. },
  70. deleteRecord: function(record,metadata){
  71. var t = this;
  72. record.parentNode.removeChild(record);
  73. t.ids.splice(t.ids.indexOf(metadata),1);
  74. activity.getDatastoreObject().setDataAsText(JSON.stringify({ids: t.ids}));
  75. activity.getDatastoreObject().save(function (error) {
  76. });
  77. },
  78. generateAudioPopup: function (fullData, originalAudio, metadata) {
  79. var audio = document.createElement("audio");
  80. audio.src = fullData.data;
  81. audio.style.padding = "0px";
  82. audio.style.zIndex = "98";
  83. audio.setAttribute("controls", "");
  84. audio.style.width = "100%";
  85. audio.style.height = "100px";
  86. audio.style.paddingBottom = "100px";
  87. return this.generatePopup(fullData, audio, originalAudio, metadata);
  88. },
  89. generateVideoPopup: function (fullData, originalVideo, metadata) {
  90. var video = document.createElement("video");
  91. video.src = fullData.data;
  92. video.style.padding = "0px";
  93. video.style.zIndex = "98";
  94. video.setAttribute("controls", "");
  95. video.style.width = "100%";
  96. video.style.maxHeight = (90 * document.body.clientHeight / 100) + "px";
  97. video.style.maxWidth = (90 * document.body.clientWidth / 100) + "px";
  98. video.style.paddingBottom = "100px";
  99. return this.generatePopup(fullData, video, originalVideo, metadata);
  100. },
  101. generateImagePopup: function (fullData, originalImage, metadata, record) {
  102. var img = document.createElement("img");
  103. //img.src = fullData.data;
  104. img.style.backgroundImage = "url('" + fullData.data + "')";
  105. img.style.backgroundRepeat = "no-repeat";
  106. img.style.backgroundPosition = "center center";
  107. img.style.padding = "0px";
  108. img.style.zIndex = "98";
  109. img.style.margin = "auto";
  110. img.style.display = "block";
  111. img.style.maxHeight = (90 * document.body.clientHeight / 100) + "px";
  112. img.style.maxWidth = (90 * document.body.clientWidth / 100) + "px";
  113. img.style.backgroundSize = "contain";
  114. img.setAttribute('height', img.style.maxHeight);
  115. img.setAttribute('width', img.style.maxWidth);
  116. return this.generatePopup(fullData, img, originalImage, metadata, record);
  117. },
  118. generatePopup: function (fullData, innerElement, originalImage, metadata, record) {
  119. var t = this;
  120. if(typeof(record)=='undefined'){
  121. record = originalImage;
  122. }
  123. var div = document.createElement("div");
  124. div.style.position = "fixed";
  125. div.style.background = "#000";
  126. div.style.zIndex = "97";
  127. div.style.minHeight = "42px";
  128. div.style.top = parseInt(5 * document.body.clientHeight / 100) + "px";
  129. div.style.left = parseInt(5 * document.body.clientWidth / 100) + "px";
  130. div.style.width = parseInt(90 * document.body.clientWidth / 100) + "px";
  131. var title = document.createElement("span");
  132. title.style.zIndex = "98";
  133. title.style.padding = "5px";
  134. title.style.position = "absolute";
  135. title.innerHTML = metadata.title;
  136. title.style.background = "#000";
  137. title.style.color = "#fff";
  138. title.style.fontSize = "26px";
  139. div.appendChild(title);
  140. div.appendChild(innerElement);
  141. var closeButton = document.createElement("button");
  142. closeButton.style.position = "absolute";
  143. closeButton.style.zIndex = "99";
  144. closeButton.style.borderRadius = "0px";
  145. closeButton.style.float = "right";
  146. closeButton.style.backgroundImage = "url(icons/close.svg)";
  147. closeButton.style.backgroundRepeat = "no-repeat";
  148. closeButton.style.backgroundPosition = "center center";
  149. closeButton.style.width = "42px";
  150. closeButton.style.height = "42px";
  151. closeButton.style.top = "0px";
  152. closeButton.style.right = "0px";
  153. closeButton.addEventListener("click", function () {
  154. div.parentNode.removeChild(div);
  155. t.popupMode = false;
  156. });
  157. div.appendChild(closeButton);
  158. var removeButton = document.createElement("button");
  159. removeButton.style.display = 'inline-block';
  160. removeButton.style.float = "left";
  161. removeButton.style.position = "absolute";
  162. removeButton.zIndex = "99";
  163. removeButton.className = "delbtn";
  164. removeButton.style.background = "url('icons/delete.svg')";
  165. removeButton.onclick = function(e){
  166. t.deleteRecord(record, metadata);
  167. div.parentNode.removeChild(div);
  168. t.popupMode = false;
  169. };
  170. div.appendChild(removeButton);
  171. return div;
  172. },
  173. displayImage: function (fullData, first, metadata) {
  174. var t = this;
  175. var div = document.createElement("div");
  176. div.style.border = "1px solid #000";
  177. div.style.marginLeft = "5px";
  178. div.style.marginTop = "5px";
  179. div.style.width = this.width + "px";
  180. div.style.height = this.height + "px";
  181. div.style.display = 'inline-block';
  182. var img = document.createElement("div");
  183. img.style.display = "inline-block"
  184. img.style.border = "1px solid #000";
  185. img.zIndex = "98";
  186. img.style.position = "absolute";
  187. img.style.width = this.width + "px";
  188. img.style.height = this.height + "px";
  189. //img.src = fullData.data;
  190. img.style.backgroundImage = "url('" + fullData.data + "')";
  191. img.style.backgroundRepeat = "no-repeat";
  192. img.style.backgroundPosition = "center";
  193. div.appendChild(img);
  194. var videoIndicator = document.createElement("img");
  195. videoIndicator.style.display = 'inline-block';
  196. videoIndicator.style.float = "left";
  197. videoIndicator.style.position = "absolute";
  198. videoIndicator.zIndex = "99";
  199. videoIndicator.style.width = this.width + "px";
  200. videoIndicator.style.height = this.height + "px";
  201. videoIndicator.src = "icons/photo.svg";
  202. div.appendChild(videoIndicator);
  203. if (first && this.records.childNodes && this.records.childNodes.length > 0) {
  204. this.records.insertBefore(div, this.records.firstChild)
  205. } else {
  206. this.records.appendChild(div);
  207. }
  208. div.addEventListener("click", function () {
  209. if (t.popupMode) {
  210. return;
  211. }
  212. t.popupMode = true;
  213. var popupDiv = t.generateImagePopup(fullData, img, metadata, div);
  214. document.body.appendChild(popupDiv);
  215. });
  216. },
  217. displayVideo: function (fullData, first, metadata) {
  218. var t = this;
  219. var div = document.createElement("div");
  220. div.style.border = "1px solid #000";
  221. div.style.marginLeft = "5px";
  222. div.style.marginTop = "5px";
  223. div.style.width = this.width + "px";
  224. div.style.height = this.height + "px";
  225. div.style.display = 'inline-block';
  226. var video = document.createElement("video");
  227. video.style.width = this.width + "px";
  228. video.style.height = this.height + "px";
  229. video.style.float = "left";
  230. video.zIndex = "98";
  231. video.style.position = "absolute";
  232. video.src = fullData.data;
  233. video.style.display = 'inline-block';
  234. div.appendChild(video);
  235. var videoIndicator = document.createElement("img");
  236. videoIndicator.style.display = 'inline-block';
  237. videoIndicator.style.float = "left";
  238. videoIndicator.style.position = "absolute";
  239. videoIndicator.zIndex = "99";
  240. videoIndicator.style.width = this.width + "px";
  241. videoIndicator.style.height = this.height + "px";
  242. videoIndicator.src = "icons/video.svg";
  243. div.appendChild(videoIndicator);
  244. if (first && this.records.childNodes && this.records.childNodes.length > 0) {
  245. this.records.insertBefore(div, this.records.firstChild)
  246. } else {
  247. this.records.appendChild(div);
  248. }
  249. div.addEventListener("click", function () {
  250. if (t.popupMode) {
  251. return;
  252. }
  253. t.popupMode = true;
  254. var popupDiv = t.generateVideoPopup(fullData, div, metadata);
  255. document.body.appendChild(popupDiv);
  256. });
  257. },
  258. displayAudio: function (fullData, first, metadata) {
  259. var t = this;
  260. var div = document.createElement("div");
  261. div.style.border = "1px solid #000";
  262. div.style.marginLeft = "5px";
  263. div.style.display = 'inline-block';
  264. div.style.marginTop = "5px";
  265. div.style.width = this.width + "px";
  266. div.style.height = this.height + "px";
  267. div.style.background = "#000";
  268. var img = document.createElement("img");
  269. img.src = "icons/audio.svg";
  270. img.style.width = this.width + "px";
  271. img.style.height = this.height + "px";
  272. img.style.display = 'inline-block';
  273. div.appendChild(img);
  274. if (first && this.records.childNodes && this.records.childNodes.length > 0) {
  275. this.records.insertBefore(div, this.records.firstChild)
  276. } else {
  277. this.records.appendChild(div);
  278. }
  279. div.addEventListener("click", function () {
  280. if (t.popupMode) {
  281. return;
  282. }
  283. t.popupMode = true;
  284. var popupDiv = t.generateAudioPopup(fullData, div, metadata);
  285. document.body.appendChild(popupDiv);
  286. });
  287. },
  288. displayData: function (data, first) {
  289. var objectId = data.objectId;
  290. var fullData = {id: objectId, data: data.text};
  291. if (data.metadata.mimetype.indexOf("audio") === 0) {
  292. this.displayAudio(fullData, first, data.metadata);
  293. }
  294. if (data.metadata.mimetype.indexOf("video") === 0) {
  295. this.displayVideo(fullData, first, data.metadata);
  296. }
  297. if (data.metadata.mimetype.indexOf("image") === 0) {
  298. this.displayImage(fullData, first, data.metadata);
  299. }
  300. },
  301. getData: function (ids, callback) {
  302. var allData = datastore.find();
  303. var toload = [];
  304. var medias = [];
  305. for (var i = 0; i < allData.length; i++) {
  306. var d = allData[i];
  307. if (!d.metadata || !d.metadata.mimetype || ids.indexOf(d.objectId) < 0) {
  308. continue;
  309. }
  310. var mimetype = d.metadata.mimetype;
  311. if (mimetype.indexOf("audio") !== 0 && mimetype.indexOf("video") !== 0 && mimetype.indexOf("image") !== 0) {
  312. continue;
  313. }
  314. toload.push(d.objectId);
  315. }
  316. var remain = toload.length;
  317. for (var i = 0 ; i < toload.length ; i++) {
  318. var dsObject = new datastore.DatastoreObject(toload[i]);
  319. dsObject.loadAsText(function(err, metadata, text) {
  320. medias.push({metadata: metadata, text: text});
  321. if (callback && --remain == 0) {
  322. callback(medias.reverse());
  323. }
  324. });
  325. }
  326. },
  327. helper: undefined,
  328. getMimetypeWithData: function (data) {
  329. return data.split(";")[0].split(":")[1];
  330. },
  331. insertData: function (inputData, callback) {
  332. var mimetype = this.getMimetypeWithData(inputData);
  333. var type = mimetype.split("/")[0];
  334. var metadata = {
  335. mimetype: mimetype,
  336. title: type.charAt(0).toUpperCase() + type.slice(1) + " " + captureHelper.by + " " + captureHelper.buddy_name.charAt(0).toUpperCase() + captureHelper.buddy_name.slice(1),
  337. activity: "org.olpcfrance.MediaViewerActivity",
  338. timestamp: new Date().getTime(),
  339. creation_time: new Date().getTime(),
  340. file_size: 0
  341. };
  342. datastore.create(metadata, callback, inputData);
  343. },
  344. isCordova: function () {
  345. if (window.cordova || window.PhoneGap) {
  346. return true;
  347. } else {
  348. return false;
  349. }
  350. },
  351. init: function () {
  352. var t = this;
  353. var itemNumber = document.body.clientWidth / 160;
  354. this.width = document.body.clientWidth / itemNumber - 10;
  355. this.height = 240 * this.width / 320;
  356. this.records = document.getElementById("records");
  357. if (this.isCordova()) {
  358. this.helper = cordovaHelper;
  359. } else {
  360. this.helper = html5Helper;
  361. this.helper.timerStart = document.getElementById("timer-start");
  362. this.helper.timerEnd = document.getElementById("timer-end");
  363. this.loadingStop = document.getElementById("loading-stop");
  364. this.loadingStop.addEventListener("click", function () {
  365. if (html5Helper.currentRecording && html5Helper.currentRecording.maxTime) {
  366. html5Helper.currentRecording.time = html5Helper.currentRecording.maxTime;
  367. }
  368. });
  369. }
  370. this.helper.init();
  371. }
  372. };
  373. var html5Helper = {
  374. recording: false,
  375. currentRecording: {},
  376. recordAudio: function () {
  377. if (this.recording) {
  378. return;
  379. }
  380. this.recording = true;
  381. var t = this;
  382. document.getElementById("loading-stop").style.display = "block";
  383. t.timerStart.style.display = "inline-block";
  384. t.timerEnd.style.display = "inline-block";
  385. document.getElementById("loading-progress").style.display = "inline-block";
  386. captureHelper.displayLoading();
  387. try {
  388. navigator.mediaDevices.getUserMedia({audio: true}).then(function (mediaStream) {
  389. var recordRTC = RecordRTC(mediaStream, {
  390. type: 'audio'
  391. });
  392. recordRTC.startRecording();
  393. var maxTime = 5;
  394. t.currentRecording.time = 0;
  395. var p = document.getElementById("loading-progress");
  396. t.currentRecording.maxTime = maxTime;
  397. p.setAttribute("max", maxTime.toString());
  398. t.timerEnd.innerHTML = maxTime.toString() + "s";
  399. t.timerStart.innerHTML = "0s";
  400. t.currentRecording.interval = setInterval(function () {
  401. t.currentRecording.time++;
  402. p = document.getElementById("loading-progress");
  403. p.value = t.currentRecording.time;
  404. if (t.currentRecording.time <= maxTime) {
  405. t.timerStart.innerHTML = t.currentRecording.time + "s";
  406. }
  407. if (t.currentRecording.time > t.currentRecording.maxTime) {
  408. t.timerStart.innerHTML = "";
  409. t.timerEnd.innerHTML = "";
  410. document.getElementById("loading-progress").value = 0;
  411. clearInterval(t.currentRecording.interval);
  412. recordRTC.stopRecording(function () {
  413. recordRTC.getDataURL(function (dataURL) {
  414. setTimeout(function () {
  415. captureHelper.forgeAndInsertData(dataURL);
  416. if (mediaStream.stop) mediaStream.stop();
  417. t.recording = false;
  418. captureHelper.hideLoading();
  419. }, 500);
  420. }, false);
  421. });
  422. }
  423. }, 1000);
  424. }).catch(function (error) {
  425. t.recording = false;
  426. captureHelper.hideLoading();
  427. });
  428. } catch (e) {
  429. t.recording = false;
  430. captureHelper.hideLoading();
  431. }
  432. },
  433. recordVideo: function () {
  434. if (this.recording) {
  435. return;
  436. }
  437. this.recording = true;
  438. var t = this;
  439. document.getElementById("loading-stop").style.display = "block";
  440. t.timerStart.style.display = "inline-block";
  441. t.timerEnd.style.display = "inline-block";
  442. document.getElementById("loading-progress").style.display = "inline-block";
  443. captureHelper.displayLoading();
  444. try {
  445. navigator.mediaDevices.getUserMedia({video: true}).then(function (mediaStream) {
  446. var recordRTC = RecordRTC(mediaStream, {
  447. type: 'video',
  448. frameRate: 80,
  449. quality: 0
  450. });
  451. document.querySelector('#vidDisplay').srcObject = mediaStream;
  452. recordRTC.startRecording();
  453. var maxTime = 5;
  454. t.currentRecording.time = 0;
  455. var p = document.getElementById("loading-progress");
  456. t.currentRecording.maxTime = maxTime;
  457. t.timerEnd.innerHTML = maxTime.toString() + "s";
  458. p.setAttribute("max", maxTime.toString());
  459. t.timerStart.innerHTML = "0s";
  460. t.currentRecording.interval = setInterval(function () {
  461. t.currentRecording.time++;
  462. p = document.getElementById("loading-progress");
  463. p.value = t.currentRecording.time;
  464. if (t.currentRecording.time <= maxTime) {
  465. t.timerStart.innerHTML = t.currentRecording.time + "s";
  466. }
  467. if (t.currentRecording.time > t.currentRecording.maxTime) {
  468. t.timerStart.innerHTML = "";
  469. t.timerEnd.innerHTML = "";
  470. document.getElementById("loading-progress").value = 0;
  471. clearInterval(t.currentRecording.interval);
  472. recordRTC.stopRecording(function () {
  473. recordRTC.getDataURL(function (dataURL) {
  474. setTimeout(function () {
  475. captureHelper.forgeAndInsertData(dataURL);
  476. if (mediaStream.stop) mediaStream.stop();
  477. t.recording = false;
  478. captureHelper.hideLoading();
  479. }, 500);
  480. }, false);
  481. });
  482. }
  483. }, 1000);
  484. }).catch(function (error) {
  485. t.recording = false;
  486. captureHelper.hideLoading();
  487. });
  488. } catch (e) {
  489. t.recording = false;
  490. captureHelper.hideLoading();
  491. }
  492. },
  493. takePicture: function () {
  494. if (this.recording) {
  495. return;
  496. }
  497. this.recording = true;
  498. var t = this;
  499. t.timerStart.style.display = "none";
  500. t.timerEnd.style.display = "none";
  501. document.getElementById("loading-stop").style.display = "none";
  502. document.getElementById("loading-progress").style.display = "none";
  503. var video = document.createElement("video");
  504. try {
  505. captureHelper.displayLoading();
  506. navigator.mediaDevices.getUserMedia({video: true}).then(function (mediaStream) {
  507. document.querySelector('#vidDisplay').srcObject = mediaStream;
  508. setTimeout(function () {
  509. var canvas = document.createElement("canvas");
  510. var width = captureHelper.width;
  511. var height = captureHelper.height;
  512. canvas.width = width;
  513. canvas.height = height;
  514. canvas.getContext('2d').drawImage(document.querySelector('#vidDisplay'), 0, 0, width, height);
  515. var imgSrc = canvas.toDataURL("image/png");
  516. captureHelper.forgeAndInsertData(imgSrc);
  517. if (mediaStream.stop) mediaStream.stop();
  518. t.recording = false;
  519. captureHelper.hideLoading();
  520. }, 2700);
  521. }).catch(function (error) {
  522. t.recording = false;
  523. captureHelper.hideLoading();
  524. });
  525. } catch (e) {
  526. t.recording = false;
  527. captureHelper.hideLoading();
  528. }
  529. },
  530. init: function () {
  531. }
  532. };
  533. var cordovaHelper = {
  534. cordovaLoaded: false,
  535. fileSystem: null,
  536. takePicture: function () {
  537. var captureSuccess = function (imageData) {
  538. var data = "data:image/jpeg;base64," + imageData;
  539. captureHelper.forgeAndInsertData(data);
  540. }
  541. // capture error callback
  542. var captureError = function (error) {
  543. };
  544. // start image capture
  545. navigator.camera.getPicture(captureSuccess, captureError, {
  546. quality: 50,
  547. targetWidth: 640,
  548. targetHeight: 480,
  549. destinationType: Camera.DestinationType.DATA_URL,
  550. sourceType: Camera.PictureSourceType.CAMERA
  551. });
  552. },
  553. recordAudio: function () {
  554. var captureSuccess = function (mediaFiles) {
  555. var i, path, len;
  556. for (i = 0, len = mediaFiles.length; i < len; i += 1) {
  557. path = mediaFiles[i].fullPath;
  558. if (path.indexOf("file:/") == -1) {
  559. path = "file:/" + path;
  560. }
  561. path = path.replace("file:/", "file:///");
  562. window.resolveLocalFileSystemURI(path, function (entry) {
  563. entry.file(function (file) {
  564. if (file.size / 1000000 > 2) {
  565. displayAlertMessage("File is too big");
  566. return;
  567. }
  568. var reader = new FileReader();
  569. reader.onloadend = function (evt) {
  570. captureHelper.forgeAndInsertData(evt.target.result);
  571. };
  572. reader.readAsDataURL(file);
  573. }, function (err) {
  574. })
  575. }, function (err) {
  576. });
  577. }
  578. };
  579. // capture error callback
  580. var captureError = function (error) {
  581. };
  582. // start image capture
  583. try {
  584. navigator.device.capture.captureAudio(captureSuccess, captureError, {
  585. limit: 1
  586. });
  587. } catch(err)
  588. {
  589. }
  590. },
  591. recordVideo: function () {
  592. var captureSuccess = function (mediaFiles) {
  593. var i, path, len;
  594. for (i = 0, len = mediaFiles.length; i < len; i += 1) {
  595. path = mediaFiles[i].fullPath;
  596. if (path.indexOf("file:/") == -1) {
  597. path = "file:/" + path;
  598. }
  599. path = path.replace("file:/", "file:///");
  600. window.resolveLocalFileSystemURI(path, function (entry) {
  601. entry.file(function (file) {
  602. if (file.size / 1000000 > 2) {
  603. displayAlertMessage("File is too big");
  604. return;
  605. }
  606. var reader = new FileReader();
  607. reader.onloadend = function (evt) {
  608. captureHelper.forgeAndInsertData(evt.target.result);
  609. };
  610. reader.readAsDataURL(file);
  611. }, function (err) {
  612. })
  613. }, function (err) {
  614. });
  615. }
  616. };
  617. // capture error callback
  618. var captureError = function (error) {
  619. };
  620. // start image capture
  621. try {
  622. navigator.device.capture.captureVideo(captureSuccess, captureError, {
  623. limit: 1,
  624. quality: 0,
  625. duration: 15,
  626. width: captureHelper.width,
  627. height: captureHelper.height
  628. });
  629. } catch(err)
  630. {
  631. }
  632. },
  633. onDeviceReady: function () {
  634. var t = captureHelper.helper;
  635. t.cordovaLoaded = true;
  636. },
  637. init: function () {
  638. document.addEventListener("deviceready", this.onDeviceReady, false);
  639. }
  640. };
  641. return captureHelper;
  642. });