detto.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // detto - cesco@ventuordici.org - 2020
  2. /* THE CHINOTTO-WARE LICENSE" (Revision 42):
  3. * cesco@ventuordici.org wrote this code.
  4. * As long as you retain this notice you can do whatever you want with this stuff.
  5. * I reserve the right to do the absolute minimum provided by law, up to and including absolutely nothing.
  6. * If we meet some day, and you think this stuff is worth it, you can buy me a chinotto in return.
  7. */
  8. var audioCtx;
  9. const canvas = document.querySelector('.visualizer');
  10. canvasCtx = canvas.getContext("2d");
  11. document.addEventListener('DOMContentLoaded', function() {
  12. if(window.location.hash) {
  13. document.getElementById('visualizer').style.display = 'none';
  14. document.getElementById('record_audio').style.display = 'none';
  15. document.getElementById('url').style.display = 'none';
  16. document.getElementById('stop_record').style.display = 'none';
  17. var downloadbutton = document.getElementById('download');
  18. if (downloadbutton) { downloadbutton.addEventListener('click', content_download, false); }
  19. } else {
  20. document.getElementById('player').style.display = 'none';
  21. document.getElementById('download').style.display = 'none';
  22. var recordbutton = document.getElementById('record_audio');
  23. if (recordbutton) {
  24. recordbutton.addEventListener('click', processa_audio, false);
  25. }
  26. var stopbutton = document.getElementById('stop_record');
  27. if (stopbutton) { stopbutton.addEventListener('click', stop_recorder, false); }
  28. }
  29. }, false);
  30. function processa_audio(){
  31. filename = "";
  32. fileext = ".webm";
  33. var constraints = { audio: true };
  34. var options = {
  35. audioBitsPerSecond : 64000,
  36. mimeType : 'audio/webm;codecs=opus'
  37. }
  38. audioCtx = new AudioContext();
  39. navigator.mediaDevices.getUserMedia(constraints).then(stream => {
  40. $('body').trigger('recording-start-ok')
  41. window.localStream = stream;
  42. const recorder = new MediaRecorder(stream, options);
  43. window.localRecorder = recorder;
  44. console.log("creato recorder " + recorder );
  45. visualize(stream);
  46. const chunks = [];
  47. recorder.ondataavailable = function(e) {
  48. // console.log("aggiungo chunk");
  49. chunks.push(e.data);
  50. }
  51. recorder.onstop = function(e) {
  52. console.log("stoppato recorder");
  53. const blob = new Blob(chunks, { type: 'audio/webm' });
  54. var reader = new FileReader();
  55. reader.onload = function(event) {
  56. console.log("reader loaded");
  57. var content = event.target.result;
  58. $('body').trigger('recording-stop-ready', content)
  59. }
  60. reader.readAsArrayBuffer(blob);
  61. }
  62. recorder.start(1000);
  63. }).catch(function onMicDenied(err) {
  64. console.log('ouch!', err)
  65. $('body').trigger('recording-start-fail', err)
  66. });
  67. }
  68. function stop_recorder(stream){
  69. console.log("stopping");
  70. localRecorder.stop();
  71. localStream.getAudioTracks()[0].stop();
  72. localStream.getTracks().forEach(track => track.stop());
  73. }
  74. function visualize(stream) {
  75. console.log("start visualize");
  76. if(!audioCtx) {
  77. audioCtx = new AudioContext();
  78. console.log("creating audioctx" + audioCtx);
  79. }
  80. const source = audioCtx.createMediaStreamSource(stream);
  81. const analyser = audioCtx.createAnalyser();
  82. console.log("created analyser" + analyser);
  83. analyser.fftSize = 2048;
  84. const bufferLength = analyser.frequencyBinCount;
  85. const dataArray = new Uint8Array(bufferLength);
  86. source.connect(analyser);
  87. draw()
  88. function draw() {
  89. // console.log("start draw");
  90. WIDTH = canvas.width
  91. HEIGHT = canvas.height;
  92. requestAnimationFrame(draw);
  93. analyser.getByteTimeDomainData(dataArray);
  94. canvasCtx.fillStyle = 'rgb(255, 255, 255)';
  95. canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
  96. canvasCtx.lineWidth = 2;
  97. canvasCtx.strokeStyle = 'rgb(150, 0, 0)';
  98. canvasCtx.beginPath();
  99. let sliceWidth = WIDTH * 1.0 / bufferLength;
  100. let x = 0;
  101. for(let i = 0; i < bufferLength; i++) {
  102. let v = dataArray[i] / 128.0;
  103. let y = v * HEIGHT/2;
  104. if(i === 0) {
  105. canvasCtx.moveTo(x, y);
  106. } else {
  107. canvasCtx.lineTo(x, y);
  108. }
  109. x += sliceWidth;
  110. }
  111. canvasCtx.lineTo(canvas.width, canvas.height/2);
  112. canvasCtx.stroke();
  113. }
  114. }