├── .gitignore ├── main.js ├── package-lock.json ├── package.json └── test.wav /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node 2 | 3 | ### Node ### 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (https://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # TypeScript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | # parcel-bundler cache (https://parceljs.org/) 64 | .cache 65 | 66 | # next.js build output 67 | .next 68 | 69 | # nuxt.js build output 70 | .nuxt 71 | 72 | # vuepress build output 73 | .vuepress/dist 74 | 75 | # Serverless directories 76 | .serverless 77 | 78 | 79 | # End of https://www.gitignore.io/api/node 80 | 81 | /output.wav 82 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const _ = require("lodash"); 3 | const Aimastering = require('aimastering'); 4 | const program = require('commander'); 5 | const srs = require('secure-random-string'); 6 | 7 | // parse command line arguments 8 | program 9 | .option('-i, --input ', 'Input audio file path') 10 | .option('-o, --output ', 'Output audio file path') 11 | .parse(process.argv); 12 | if (program.input.length === 0) { 13 | program.help(); 14 | } 15 | 16 | // Call API with promise interface 17 | const callApiDeferred = async function (api, method) { 18 | const apiArgments = Array.prototype.slice.call(arguments, 2); 19 | 20 | return new Promise((resolve, reject) => { 21 | const callback = (error, data, response) => { 22 | if (error) { 23 | reject(error, response); 24 | } else { 25 | resolve(data, response); 26 | } 27 | }; 28 | const args = _.flatten([ 29 | apiArgments, 30 | callback 31 | ]); 32 | 33 | method.apply(api, args); 34 | }); 35 | }; 36 | 37 | const sleep = async function (ms) { 38 | return new Promise((resolve) => { 39 | setTimeout(resolve, ms); 40 | }); 41 | }; 42 | 43 | const main = async function () { 44 | // configure API client 45 | const client = Aimastering.ApiClient.instance; 46 | const bearer = client.authentications['bearer']; 47 | // bearer.apiKey = process.env.AIMASTERING_ACCESS_TOKEN; 48 | 49 | // API key must be 'guest_' + [arbitrary string] 50 | // Unless the API key is leaked, the data will not be visible to others. 51 | bearer.apiKey = 'guest_' + srs({length: 32}) 52 | 53 | // create api 54 | const audioApi = new Aimastering.AudioApi(client); 55 | const masteringApi = new Aimastering.MasteringApi(client); 56 | 57 | // upload input audio 58 | const inputAudioData = fs.createReadStream(program.input); 59 | const inputAudio = await callApiDeferred(audioApi, audioApi.createAudio, { 60 | 'file': inputAudioData, 61 | }); 62 | console.error(inputAudio); 63 | 64 | // start mastering 65 | let mastering = await callApiDeferred(masteringApi, masteringApi.createMastering, inputAudio.id, { 66 | 'mode': 'default', 67 | }); 68 | console.error(mastering); 69 | 70 | // wait for the mastering completion 71 | while (mastering.status === 'waiting' || mastering.status === 'processing') { 72 | mastering = await callApiDeferred(masteringApi, masteringApi.getMastering, mastering.id); 73 | console.error('waiting for the mastering completion progression: ' 74 | + (100 * mastering.progression).toFixed() + '%'); 75 | await sleep(5000); 76 | } 77 | 78 | // download output audio 79 | const outputAudioData = await callApiDeferred(audioApi, audioApi.downloadAudio, mastering.output_audio_id); 80 | fs.writeFileSync(program.output, outputAudioData); 81 | 82 | console.error('the output file was written to ' + program.output); 83 | }; 84 | 85 | main(); 86 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tutorial-node", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "aimastering": { 8 | "version": "1.1.0", 9 | "resolved": "https://registry.npmjs.org/aimastering/-/aimastering-1.1.0.tgz", 10 | "integrity": "sha512-cxHG3nGu5E3wUDLJ8veQXSby0yVV0ZkapYrC44HC+LPmqTxbB/58w+b/uQ3i/EJQqr8JS6kVhZ6nqOUbuuJBhw==", 11 | "requires": { 12 | "superagent": "3.5.2" 13 | } 14 | }, 15 | "asynckit": { 16 | "version": "0.4.0", 17 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 18 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 19 | }, 20 | "call-bind": { 21 | "version": "1.0.2", 22 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 23 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 24 | "requires": { 25 | "function-bind": "^1.1.1", 26 | "get-intrinsic": "^1.0.2" 27 | } 28 | }, 29 | "combined-stream": { 30 | "version": "1.0.8", 31 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 32 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 33 | "requires": { 34 | "delayed-stream": "~1.0.0" 35 | } 36 | }, 37 | "commander": { 38 | "version": "2.17.1", 39 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", 40 | "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" 41 | }, 42 | "component-emitter": { 43 | "version": "1.3.0", 44 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 45 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" 46 | }, 47 | "cookiejar": { 48 | "version": "2.1.2", 49 | "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", 50 | "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" 51 | }, 52 | "core-util-is": { 53 | "version": "1.0.2", 54 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 55 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 56 | }, 57 | "debug": { 58 | "version": "2.6.9", 59 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 60 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 61 | "requires": { 62 | "ms": "2.0.0" 63 | } 64 | }, 65 | "delayed-stream": { 66 | "version": "1.0.0", 67 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 68 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 69 | }, 70 | "extend": { 71 | "version": "3.0.2", 72 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 73 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 74 | }, 75 | "form-data": { 76 | "version": "2.5.1", 77 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", 78 | "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", 79 | "requires": { 80 | "asynckit": "^0.4.0", 81 | "combined-stream": "^1.0.6", 82 | "mime-types": "^2.1.12" 83 | } 84 | }, 85 | "formidable": { 86 | "version": "1.2.2", 87 | "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", 88 | "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==" 89 | }, 90 | "function-bind": { 91 | "version": "1.1.1", 92 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 93 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 94 | }, 95 | "get-intrinsic": { 96 | "version": "1.1.1", 97 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", 98 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", 99 | "requires": { 100 | "function-bind": "^1.1.1", 101 | "has": "^1.0.3", 102 | "has-symbols": "^1.0.1" 103 | } 104 | }, 105 | "has": { 106 | "version": "1.0.3", 107 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 108 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 109 | "requires": { 110 | "function-bind": "^1.1.1" 111 | } 112 | }, 113 | "has-symbols": { 114 | "version": "1.0.2", 115 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", 116 | "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" 117 | }, 118 | "inherits": { 119 | "version": "2.0.4", 120 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 121 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 122 | }, 123 | "isarray": { 124 | "version": "1.0.0", 125 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 126 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 127 | }, 128 | "lodash": { 129 | "version": "4.17.21", 130 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 131 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 132 | }, 133 | "methods": { 134 | "version": "1.1.2", 135 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 136 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 137 | }, 138 | "mime": { 139 | "version": "1.6.0", 140 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 141 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 142 | }, 143 | "mime-db": { 144 | "version": "1.49.0", 145 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", 146 | "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" 147 | }, 148 | "mime-types": { 149 | "version": "2.1.32", 150 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", 151 | "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", 152 | "requires": { 153 | "mime-db": "1.49.0" 154 | } 155 | }, 156 | "ms": { 157 | "version": "2.0.0", 158 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 159 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 160 | }, 161 | "object-inspect": { 162 | "version": "1.11.0", 163 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", 164 | "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" 165 | }, 166 | "process-nextick-args": { 167 | "version": "2.0.1", 168 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 169 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 170 | }, 171 | "qs": { 172 | "version": "6.10.1", 173 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", 174 | "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", 175 | "requires": { 176 | "side-channel": "^1.0.4" 177 | } 178 | }, 179 | "readable-stream": { 180 | "version": "2.3.7", 181 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 182 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 183 | "requires": { 184 | "core-util-is": "~1.0.0", 185 | "inherits": "~2.0.3", 186 | "isarray": "~1.0.0", 187 | "process-nextick-args": "~2.0.0", 188 | "safe-buffer": "~5.1.1", 189 | "string_decoder": "~1.1.1", 190 | "util-deprecate": "~1.0.1" 191 | } 192 | }, 193 | "safe-buffer": { 194 | "version": "5.1.2", 195 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 196 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 197 | }, 198 | "secure-random-string": { 199 | "version": "1.1.3", 200 | "resolved": "https://registry.npmjs.org/secure-random-string/-/secure-random-string-1.1.3.tgz", 201 | "integrity": "sha512-298HxkJJp5mjpPhxDsN26S/2JmMaUIrQ4PxDI/F4fXKRBTOKendQ5i6JCkc+a8F8koLh0vdfwSCw8+RJkY7N6A==" 202 | }, 203 | "side-channel": { 204 | "version": "1.0.4", 205 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 206 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 207 | "requires": { 208 | "call-bind": "^1.0.0", 209 | "get-intrinsic": "^1.0.2", 210 | "object-inspect": "^1.9.0" 211 | } 212 | }, 213 | "string_decoder": { 214 | "version": "1.1.1", 215 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 216 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 217 | "requires": { 218 | "safe-buffer": "~5.1.0" 219 | } 220 | }, 221 | "superagent": { 222 | "version": "3.5.2", 223 | "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.5.2.tgz", 224 | "integrity": "sha1-M2GjlxVnUEw1EGOr6q4PqiPb8/g=", 225 | "requires": { 226 | "component-emitter": "^1.2.0", 227 | "cookiejar": "^2.0.6", 228 | "debug": "^2.2.0", 229 | "extend": "^3.0.0", 230 | "form-data": "^2.1.1", 231 | "formidable": "^1.1.1", 232 | "methods": "^1.1.1", 233 | "mime": "^1.3.4", 234 | "qs": "^6.1.0", 235 | "readable-stream": "^2.0.5" 236 | } 237 | }, 238 | "util-deprecate": { 239 | "version": "1.0.2", 240 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 241 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tutorial-node", 3 | "version": "1.0.0", 4 | "description": "AI Mastering API tutorial written in node.js.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/ai-mastering/tutorialnode.git" 12 | }, 13 | "author": "AI Mastering", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/ai-mastering/tutorialnode/issues" 17 | }, 18 | "homepage": "https://github.com/ai-mastering/tutorialnode#readme", 19 | "dependencies": { 20 | "aimastering": "^1.1.0", 21 | "commander": "^2.17.1", 22 | "lodash": "^4.17.21", 23 | "secure-random-string": "^1.1.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ai-mastering/tutorial-node/59203470890f651e2176e8ce0d067fbf6172ad76/test.wav --------------------------------------------------------------------------------