├── LICENSE ├── README.md ├── index.html ├── index.js └── record-server-example ├── .gitignore ├── README.md ├── package.json ├── public └── index.html └── server.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Bryan Jennings 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Record Audio 2 | 3 | A simple audio recording function. 4 | 5 | ### How to use 6 | 7 | The following code will record audio for 3 seconds, then play back the audio that it recorded. 8 | 9 | ```javascript 10 | (async () => { 11 | const recorder = await recordAudio(); 12 | recorder.start(); 13 | await sleep(3000); 14 | const audio = await recorder.stop(); 15 | audio.play(); 16 | })(); 17 | ``` 18 | 19 | ### Instructions for running example 20 | 21 | Make sure your browser is up to date. 22 | 23 | Clone the repo, then open index.html, then press action button and start talking. You will be recorded for 3 seconds, then your recording will be played back. 24 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Record Audio Test 5 | 6 | 7 |

Audio Recording Test

8 |

Talk for 3 seconds, then you will hear your recording played back

9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const recordAudio = () => 2 | new Promise(async resolve => { 3 | const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); 4 | const mediaRecorder = new MediaRecorder(stream); 5 | const audioChunks = []; 6 | 7 | mediaRecorder.addEventListener("dataavailable", event => { 8 | audioChunks.push(event.data); 9 | }); 10 | 11 | const start = () => mediaRecorder.start(); 12 | 13 | const stop = () => 14 | new Promise(resolve => { 15 | mediaRecorder.addEventListener("stop", () => { 16 | const audioBlob = new Blob(audioChunks, { type: "audio/mpeg" }); 17 | const audioUrl = URL.createObjectURL(audioBlob); 18 | const audio = new Audio(audioUrl); 19 | const play = () => audio.play(); 20 | stream.getTracks().forEach((track) => track.stop()); 21 | resolve({ audioBlob, audioUrl, play }); 22 | }); 23 | 24 | mediaRecorder.stop(); 25 | }); 26 | 27 | resolve({ start, stop }); 28 | }); 29 | 30 | const sleep = time => new Promise(resolve => setTimeout(resolve, time)); 31 | 32 | const handleAction = async () => { 33 | const recorder = await recordAudio(); 34 | const actionButton = document.getElementById("action"); 35 | actionButton.disabled = true; 36 | recorder.start(); 37 | await sleep(3000); 38 | const audio = await recorder.stop(); 39 | audio.play(); 40 | await sleep(3000); 41 | actionButton.disabled = false; 42 | }; 43 | -------------------------------------------------------------------------------- /record-server-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn.lock 3 | public/messages/* 4 | -------------------------------------------------------------------------------- /record-server-example/README.md: -------------------------------------------------------------------------------- 1 | # Record Server Example 2 | 3 | This is a simple example of how to record audio and save audio to a Node server. 4 | 5 | ## Getting started 6 | 7 | npm install or yarn install. 8 | ``` 9 | npm install 10 | ``` 11 | 12 | Run the server. 13 | ``` 14 | node server.js 15 | ``` 16 | 17 | Go to http://localhost:3545 18 | -------------------------------------------------------------------------------- /record-server-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "record-example", 3 | "version": "0.0.1", 4 | "description": "Records and saves audio to the server", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "keywords": [ 11 | "record", 12 | "audio" 13 | ], 14 | "author": "Bryan Jennings", 15 | "license": "MIT", 16 | "dependencies": { 17 | "express": "^4.17.1", 18 | "uuid": "^3.3.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /record-server-example/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Record and save audio 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

Saved messages

20 |
21 | 22 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /record-server-example/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const fs = require('fs'); 3 | const { promisify } = require('util'); 4 | const { v4 } = require('uuid'); 5 | 6 | const writeFile = promisify(fs.writeFile); 7 | const readdir = promisify(fs.readdir); 8 | 9 | // make sure messages folder exists 10 | const messageFolder = './public/messages/'; 11 | if (!fs.existsSync(messageFolder)) { 12 | fs.mkdirSync(messageFolder); 13 | } 14 | 15 | const app = express(); 16 | 17 | app.use(express.static('public')); 18 | app.use(express.json({limit: '2.0mb', extended: true})); 19 | 20 | app.get('/messages', (req, res) => { 21 | readdir(messageFolder) 22 | .then(messageFilenames => { 23 | res.status(200).json({ messageFilenames }); 24 | }) 25 | .catch(err => { 26 | console.log('Error reading message directory', err); 27 | res.sendStatus(500); 28 | }); 29 | }); 30 | 31 | app.post('/messages', (req, res) => { 32 | if (!req.body.message) { 33 | return res.status(400).json({ error: 'No req.body.message' }); 34 | } 35 | const messageId = v4(); 36 | writeFile(messageFolder + messageId, req.body.message, 'base64') 37 | .then(() => { 38 | res.status(201).json({ message: 'Saved message' }); 39 | }) 40 | .catch(err => { 41 | console.log('Error writing message to file', err); 42 | res.sendStatus(500); 43 | }); 44 | }); 45 | 46 | const PORT = process.env.PORT || 3545; 47 | app.listen(PORT, () => { 48 | console.log(`Listening on port ${PORT}`); 49 | }); 50 | --------------------------------------------------------------------------------