/ffmpeg/webm-to-mp4.html

https://github.com/azorac/WebRTC-Experiment · HTML · 286 lines · 230 code · 49 blank · 7 comment · 0 complexity · af372b8c7d652ba765630899d873eb91 MD5 · raw file

  1. <!--
  2. > Muaz Khan - www.MuazKhan.com
  3. > MIT License - www.WebRTC-Experiment.com/licence
  4. > Documentation - github.com/muaz-khan/WebRTC-Experiment/tree/master/ffmpeg
  5. -->
  6. <!DOCTYPE html>
  7. <html lang="en">
  8. <head>
  9. <title>RecordRTC WebM to mp4 using ffmpeg-asm.js ® Muaz Khan</title>
  10. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  11. <meta charset="utf-8">
  12. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
  13. <link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
  14. <meta name="author" content="Muaz Khan">
  15. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  16. <link rel="stylesheet" href="https://www.webrtc-experiment.com/style.css">
  17. <style>
  18. video {
  19. vertical-align: bottom;
  20. width: 300px;
  21. }
  22. input {
  23. border: 1px solid #d9d9d9;
  24. border-radius: 1px;
  25. font-size: 2em;
  26. margin: .2em;
  27. width: 30%;
  28. }
  29. p, .inner { padding: 1em; }
  30. li {
  31. border-bottom: 1px solid rgb(189, 189, 189);
  32. border-left: 1px solid rgb(189, 189, 189);
  33. padding: .5em;
  34. }
  35. label {
  36. display: inline-block;
  37. width: 8em;
  38. }
  39. </style>
  40. <script>
  41. document.createElement('article');
  42. document.createElement('footer');
  43. </script>
  44. <!-- script used for audio/video/gif recording -->
  45. <script src="//www.webrtc-experiment.com/RecordRTC.js"> </script>
  46. </head>
  47. <body>
  48. <article>
  49. <header style="text-align: center;">
  50. <h1>
  51. <a href="https://www.webrtc-experiment.com/RecordRTC/">RecordRTC</a> WebM to mp4 using <a href="http://bgrins.github.io/videoconverter.js/">ffmpeg-asm.js</a>!
  52. </h1>
  53. <p>
  54. <a href="https://www.webrtc-experiment.com/">HOME</a>
  55. <span> &copy; </span>
  56. <a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a>
  57. .
  58. <a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a>
  59. .
  60. <a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a>
  61. .
  62. <a href="https://github.com/muaz-khan/WebRTC-Experiment/issues?state=open" target="_blank">Latest issues</a>
  63. .
  64. <a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">What's New?</a>
  65. </p>
  66. </header>
  67. <div class="github-stargazers"></div>
  68. <section class="experiment">
  69. <h2 class="header">Logs</h2>
  70. <ol id="logs-preview">
  71. <li>
  72. <a href="https://www.webrtc-experiment.com/RecordRTC/">RecordRTC</a> experiment converting WebM to mp4 inside the browser!
  73. </li>
  74. </ol>
  75. </section>
  76. <section class="experiment">
  77. <h2 class="header">Record Video and convert into "mp4" using <a href="https://googledrive.com/host/0B6GWd_dUUTT8OEtLRGdQb2pibDg/ffmpeg_asm.js" download="ffmpeg-asm.js">ffmpeg-asm.js</a>!</h2>
  78. <div class="inner">
  79. <video id="video-preview" controls></video>
  80. <button id="record-video">Record</button>
  81. <button id="stop-recording-video" disabled>Stop</button>
  82. </div>
  83. </section>
  84. <script>
  85. var recordVideo;
  86. var videoPreview = document.getElementById('video-preview');
  87. var inner = document.querySelector('.inner');
  88. var videoFile = !!navigator.mozGetUserMedia ? 'video.gif' : 'video.webm';
  89. document.querySelector('#record-video').onclick = function() {
  90. this.disabled = true;
  91. navigator.getUserMedia({
  92. video: true
  93. }, function(stream) {
  94. videoPreview.src = window.URL.createObjectURL(stream);
  95. videoPreview.play();
  96. recordVideo = RecordRTC(stream, {
  97. type: 'video'
  98. });
  99. recordVideo.startRecording();
  100. }, function(error) { throw error;});
  101. document.querySelector('#stop-recording-video').disabled = false;
  102. };
  103. document.querySelector('#stop-recording-video').onclick = function() {
  104. this.disabled = true;
  105. recordVideo.stopRecording(function(url) {
  106. videoPreview.src = url;
  107. videoPreview.download = videoFile;
  108. log('<a href="https://googledrive.com/host/0B6GWd_dUUTT8OEtLRGdQb2pibDg/ffmpeg_asm.js" download="ffmpeg-asm.js">ffmpeg-asm.js</a> file download started. It is about 18MB in size; please be patient!');
  109. convertStreams(recordVideo.getBlob());
  110. });
  111. };
  112. // var workerPath = location.href.replace(location.href.split('/').pop(), '') + 'ffmpeg_asm.js';
  113. var workerPath = 'https://googledrive.com/host/0B6GWd_dUUTT8OEtLRGdQb2pibDg/ffmpeg_asm.js';
  114. function processInWebWorker() {
  115. var blob = URL.createObjectURL(new Blob(['importScripts("' + workerPath + '");var now = Date.now;function print(text) {postMessage({"type" : "stdout","data" : text});};onmessage = function(event) {var message = event.data;if (message.type === "command") {var Module = {print: print,printErr: print,files: message.files || [],arguments: message.arguments || [],TOTAL_MEMORY: message.TOTAL_MEMORY || false};postMessage({"type" : "start","data" : Module.arguments.join(" ")});postMessage({"type" : "stdout","data" : "Received command: " +Module.arguments.join(" ") +((Module.TOTAL_MEMORY) ? ". Processing with " + Module.TOTAL_MEMORY + " bits." : "")});var time = now();var result = ffmpeg_run(Module);var totalTime = now() - time;postMessage({"type" : "stdout","data" : "Finished processing (took " + totalTime + "ms)"});postMessage({"type" : "done","data" : result,"time" : totalTime});}};postMessage({"type" : "ready"});'], {
  116. type: 'application/javascript'
  117. }));
  118. var worker = new Worker(blob);
  119. URL.revokeObjectURL(blob);
  120. return worker;
  121. }
  122. var worker;
  123. function convertStreams(videoBlob) {
  124. var aab;
  125. var buffersReady;
  126. var workerReady;
  127. var posted;
  128. var fileReader = new FileReader();
  129. fileReader.onload = function() {
  130. aab = this.result;
  131. postMessage();
  132. };
  133. fileReader.readAsArrayBuffer(videoBlob);
  134. if (!worker) {
  135. worker = processInWebWorker();
  136. }
  137. worker.onmessage = function(event) {
  138. var message = event.data;
  139. if (message.type == "ready") {
  140. log('<a href="https://googledrive.com/host/0B6GWd_dUUTT8OEtLRGdQb2pibDg/ffmpeg_asm.js" download="ffmpeg-asm.js">ffmpeg-asm.js</a> file has been loaded.');
  141. workerReady = true;
  142. if (buffersReady)
  143. postMessage();
  144. } else if (message.type == "stdout") {
  145. log(message.data);
  146. } else if (message.type == "start") {
  147. log('<a href="https://googledrive.com/host/0B6GWd_dUUTT8OEtLRGdQb2pibDg/ffmpeg_asm.js" download="ffmpeg-asm.js">ffmpeg-asm.js</a> file received ffmpeg command.');
  148. } else if (message.type == "done") {
  149. log(JSON.stringify(message));
  150. var result = message.data[0];
  151. log(JSON.stringify(result));
  152. var blob = new Blob([result.data], {
  153. type: 'video/mp4'
  154. });
  155. log(JSON.stringify(blob));
  156. PostBlob(blob);
  157. }
  158. };
  159. var postMessage = function() {
  160. posted = true;
  161. worker.postMessage({
  162. type: 'command',
  163. arguments: ['-i', videoFile, '-c:v', 'mpeg4', '-b:v', '64k', '-strict', 'experimental', 'output.mp4'],
  164. files: [
  165. {
  166. data: new Uint8Array(aab),
  167. name: videoFile
  168. }
  169. ]
  170. });
  171. };
  172. }
  173. function PostBlob(blob) {
  174. inner.appendChild(document.createElement('hr'));
  175. var h2 = document.createElement('h2');
  176. h2.innerHTML = '<a href="' + URL.createObjectURL(blob) + '" target="_blank" download="Converted Video.mp4">Download Converted mp4 and play in VLC player!</a>';
  177. inner.appendChild(h2);
  178. h2.tabIndex = 0;
  179. h2.focus();
  180. document.querySelector('#record-video').disabled = false;
  181. }
  182. var logsPreview = document.getElementById('logs-preview');
  183. function log(message) {
  184. var li = document.createElement('li');
  185. li.innerHTML = message;
  186. logsPreview.appendChild(li);
  187. li.tabIndex = 0;
  188. li.focus();
  189. }
  190. </script>
  191. <section class="experiment">
  192. <h2 class="header" id="feedback">Feedback</h2>
  193. <div>
  194. <textarea id="message" style="border: 1px solid rgb(189, 189, 189); height: 8em; margin: .2em; outline: none; resize: vertical; width: 98%;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>
  195. </div>
  196. <button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left: 1em;">Enter your email too; if you want "direct" reply!</small>
  197. </section>
  198. <section class="experiment">
  199. <h2 class="header">Using ffmpeg-asm.js...</h2>
  200. <ol>
  201. <li>
  202. WebM can be converted in mp4.
  203. </li>
  204. <li>
  205. WAV can be converted in ogg or mp3.
  206. </li>
  207. <li>
  208. WAV can be merged in mp4.
  209. </li>
  210. </ol>
  211. <p style="margin-top: 0;">
  212. If WAV or WebM is 5MB in size; ogg, mp3 or mp4 will be 700kb!
  213. </p>
  214. </section>
  215. <section class="experiment">
  216. <p style="margin-top: 0;">
  217. RecordRTC is MIT licensed on Github! <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RecordRTC" target="_blank">Documentation</a>
  218. </p>
  219. </section>
  220. <section class="experiment own-widgets latest-commits">
  221. <h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">Latest Updates</a></h2>
  222. <div id="github-commits"></div>
  223. </section>
  224. </article>
  225. <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/ffmpeg" class="fork-right"></a>
  226. <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RecordRTC" class="fork-left"></a>
  227. <footer>
  228. <p>
  229. <a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a>
  230. © <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
  231. <a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
  232. </p>
  233. </footer>
  234. <!-- commits.js is useless for you! -->
  235. <script src="https://www.webrtc-experiment.com/commits.js" async> </script>
  236. </body>
  237. </html>