From 8b2d2a3b34a17c739efaaab14717e844a4d4e3a3 Mon Sep 17 00:00:00 2001 From: Sravanth C <54331348+chebro@users.noreply.github.com> Date: Wed, 20 Jan 2021 01:12:29 +0530 Subject: [PATCH 1/2] Add dockerfile --- Dockerfile | 11 +++++ README.md | 59 ++++++++++++++---------- bin/merge.js | 9 ++-- package-lock.json | 113 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- 5 files changed, 165 insertions(+), 30 deletions(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..273c22b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM node:lts-alpine3.12 + +RUN mkdir -p /usr/src/bot +WORKDIR /usr/src/bot + +COPY package.json /usr/src/bot +RUN npm install + +COPY . /usr/src/bot +CMD ["node", "index.js"] + diff --git a/README.md b/README.md index f2fb488..6a529c4 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,9 @@ _Recording voice calls without prior consent violates privacy. Do not use this b - [Installation and Usage](#installation-and-usage) - - [Setting Up the Local Environment](#setting-up-the-local-environment) - - [Running the Script](#running-the-script) + - [Run Locally](#run-locally) + - [Run as Docker Container](#run-as-docker-container) + - [Bot Commands](#bot-commands) - [Managing the Output](#managing-the-output) - [Merge Recording](#merge-recording) - [Convert the Merged File to MP3](#convert-the-merged-file-to-mp3) @@ -23,11 +24,7 @@ Clone the repository : git clone https://github.com/chebro/discord-voice-recorder/ ``` -Run `npm i` to download necessary `node_modules`. Then, head over to the [FFmpeg.org](https://ffmpeg.org/download.html), and download executables for your OS; If you're on Windows, double-check if the FFmpeg bin is on your path. - -### Setting Up the Local Environment - -To run this script locally, [create a discord bot](https://discordpy.readthedocs.io/en/latest/discord.html) first. Invite the bot to your server, then: +[Create a discord bot](https://discordpy.readthedocs.io/en/latest/discord.html). Invite the bot to your server, then: 1. Create a `config.json` file and a `recordings` folder at the root folder. 2. Paste the bot token (from [developer window](https://discord.com/developers/applications)) and any bot prefix into `config.json`, like so: @@ -39,50 +36,62 @@ To run this script locally, [create a discord bot](https://discordpy.readthedocs } ``` -### Running the Script +You can run the bot in any one of the following two ways. -Run `npm start`, the bot should be online. +### Running the Script Locally -#### Start Recording +Run `npm i` to download necessary `node_modules`, then run `npm start`, the bot should be online. + +### Run as a Docker Container + +1. Build the docker image ``` -enter +docker build -t dvr . ``` -**Note:** You should hear a 'drop' sound after running this. If you don't, there's a problem with your FFmpeg installation. - -#### Stop Recording +2. Bind `/recordings` directory on host to container and start the container with a custom name. ``` -exit +docker run \ + --name \ + --mount type=bind,source="$(pwd)"/recordings,target=/usr/src/bot/recordings \ + dvr ``` +The bot should be online. + +3. To stop the container, run `docker stop `, you can restart it using `docker start `. + +### Bot Commands + +1. Start Recording : `enter ` + +2. Stop Recording : `exit` + ## Managing the Output -The audio will be recorded in [PCM format](https://en.wikipedia.org/wiki/Pulse-code_modulation) and saved to the `/recordings` directory. - -_To work with PCM audio, you could use software such as [Audacity](https://www.audacityteam.org/). To import the audio into Audacity, open File > Import Raw Data... and then select your audio file. You should select Signed 16-bit PCM as the encoding, a Little-endian byte order, 2 Channels (Stereo) and a sample rate of 48000Hz._ +The output for each piece of audio stream is written to a unique file in [PCM format](https://en.wikipedia.org/wiki/Pulse-code_modulation) (48000 Hz, signed 16-bit little-endian, 2 channel [stereo]) and saved to the `/recordings` directory. ### Merge Recording -The output for each piece of audio stream is written to a unique file. To merge all output files, run: +To merge all output files to `/recordings/merge.pcm`, run: ``` -node ./bin/merge.js +node /bin/merge.js ``` -This creates a `merge.pcm` in the `/recordings` directory. - -**Note:** Do not forget to empty your `recordings` folder after each session. Running `./bin/merge.js` otherwise, will dump large merge files. +**Note:** Empty your `recordings` folder (and remove `merge.pcm`) after each session. Running `./bin/merge.js` otherwise, will dump large merge files. ### Convert the Merged File to MP3 -As mentioned in issue [#3](https://github.com/chebro/discord-voice-recorder/issues/3), to convert pcm to mp3, run: +Head over to [FFmpeg.org](https://ffmpeg.org/download.html), and download executables for your OS; If you're on Windows, double-check if the FFmpeg bin is on your path. As discussed in issue [#3](https://github.com/chebro/discord-voice-recorder/issues/3), to convert pcm to mp3, run: ``` -ffmpeg -f s16le -ar 44.1k -ac 2 -i merge.pcm output.mp3 +ffmpeg -f s16le -ar 48000 -ac 2 -i merge.pcm output.mp3 ``` ## Thanks Special thanks to [@eslachance](https://github.com/eslachance) for the [gist](https://gist.github.com/eslachance/fb70fc036183b7974d3b9191601846ba). It is what inspired me to make this repo. + diff --git a/bin/merge.js b/bin/merge.js index a2aea56..d84c395 100644 --- a/bin/merge.js +++ b/bin/merge.js @@ -1,8 +1,8 @@ var fs = require('fs'), - chunks = fs.readdirSync('../recordings'), + chunks = fs.readdirSync(__dirname + '/../recordings'), inputStream, currentfile, - outputStream = fs.createWriteStream('../recordings/merge.pcm'); + outputStream = fs.createWriteStream(__dirname + '/../recordings/merge.pcm'); chunks.sort((a, b) => { return a - b; }); @@ -12,7 +12,7 @@ function appendFiles() { return; } - currentfile = '../recordings/' + chunks.shift(); + currentfile = `${__dirname}/../recordings/` + chunks.shift(); inputStream = fs.createReadStream(currentfile); inputStream.pipe(outputStream, { end: false }); @@ -23,4 +23,5 @@ function appendFiles() { }); } -appendFiles(); \ No newline at end of file +appendFiles(); + diff --git a/package-lock.json b/package-lock.json index 1f5e774..5236fe7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,17 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@derhuerst/http-basic": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.1.tgz", + "integrity": "sha512-Rmn7qQQulw2sxJ8qGfZ7OuqMWuhz8V+L5xnYKMF5cXVcYqmgWqlVEAme90pF7Ya8OVhxVxLmhh0rI2k6t7ITWw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, "@discordjs/collection": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", @@ -45,6 +56,11 @@ "node-addon-api": "^2.0.0" } }, + "@types/node": { + "version": "10.17.51", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.51.tgz", + "integrity": "sha512-KANw+MkL626tq90l++hGelbl67irOJzGhUJk6a1Bt8QHOeh9tztJx+L0AqttraWKinmZn7Qi5lJZJzx45Gq0dg==" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -58,6 +74,24 @@ "event-target-shim": "^5.0.0" } }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + } + } + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -96,6 +130,16 @@ "concat-map": "0.0.1" } }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -119,6 +163,17 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -172,11 +227,27 @@ "ws": "^7.3.1" } }, + "env-paths": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==" + }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, + "ffmpeg-static": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-4.2.7.tgz", + "integrity": "sha512-SGnOr2d+k0/9toRIv9t5/hN/DMYbm5XMtG0wVwGM1tEyXJAD6dbcWOEvfHq4LOySm9uykKL6LMC4eVPeteUnbQ==", + "requires": { + "@derhuerst/http-basic": "^8.2.0", + "env-paths": "^2.2.0", + "https-proxy-agent": "^5.0.0", + "progress": "^2.0.3" + } + }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -223,6 +294,33 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -427,6 +525,11 @@ "os-tmpdir": "^1.0.0" } }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=" + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -442,6 +545,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -566,6 +674,11 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index b80a618..6e9580c 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "@discordjs/opus": "^0.3.2", - "discord.js": "^12.3.1" + "discord.js": "^12.3.1", + "ffmpeg-static": "^4.2.7" } } From 0e8cc4355db99ac27d892209a6b1fd4105bb3988 Mon Sep 17 00:00:00 2001 From: Sravanth C <54331348+chebro@users.noreply.github.com> Date: Wed, 20 Jan 2021 01:19:47 +0530 Subject: [PATCH 2/2] UPdate readme --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6a529c4..7947c46 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,9 @@ Clone the repository : git clone https://github.com/chebro/discord-voice-recorder/ ``` -[Create a discord bot](https://discordpy.readthedocs.io/en/latest/discord.html). Invite the bot to your server, then: +[Make a discord bot](https://discordpy.readthedocs.io/en/latest/discord.html) if you don't have one already and invite the bot to your server, then: -1. Create a `config.json` file and a `recordings` folder at the root folder. +1. Create `config.json` file and a `/recordings` directory at the root folder. 2. Paste the bot token (from [developer window](https://discord.com/developers/applications)) and any bot prefix into `config.json`, like so: ```yaml @@ -36,21 +36,21 @@ git clone https://github.com/chebro/discord-voice-recorder/ } ``` -You can run the bot in any one of the following two ways. +You can now run the script in one of the following two ways: -### Running the Script Locally +### Run Locally Run `npm i` to download necessary `node_modules`, then run `npm start`, the bot should be online. ### Run as a Docker Container -1. Build the docker image +1. Build the docker image: ``` docker build -t dvr . ``` -2. Bind `/recordings` directory on host to container and start the container with a custom name. +2. Bind `/recordings` directory on host to container and start the container with a custom name: ``` docker run \