1
0
mirror of https://github.com/musix-org/musix-oss synced 2025-06-17 01:16:00 +00:00

updated all commands and removed some weird files

This commit is contained in:
MatteZ02
2019-08-14 15:26:33 +03:00
parent 29b40867a3
commit 9d7e55b5ee
1058 changed files with 170671 additions and 70 deletions

28
node_modules/ytdl-core-discord/.eslintrc.js generated vendored Normal file
View File

@ -0,0 +1,28 @@
module.exports = {
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2017
},
"rules": {
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
};

7
node_modules/ytdl-core-discord/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,7 @@
language: node_js
node_js:
- 10
- 11
cache:
directories:
- node_modules

201
node_modules/ytdl-core-discord/LICENSE generated vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2019 Amish Shah
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

47
node_modules/ytdl-core-discord/README.md generated vendored Normal file
View File

@ -0,0 +1,47 @@
# ytdl-core-discord
[![Build Status](https://travis-ci.org/amishshah/ytdl-core-discord.svg?branch=master)](https://travis-ci.org/amishshah/ytdl-core-discord)
[![dependencies](https://david-dm.org/amishshah/ytdl-core-discord/status.svg)](https://david-dm.org/amishshah/ytdl-core-discord)
[![npm](https://img.shields.io/npm/dt/ytdl-core-discord.svg)](https://www.npmjs.com/package/ytdl-core-discord)
[![Patreon](https://img.shields.io/badge/donate-patreon-F96854.svg)](https://www.patreon.com/discordjs)
A [ytdl-core](https://github.com/fent/node-ytdl-core/) wrapper focused on efficiency for use in Discord music bots.
You can pass the exact same arguments as you would with the ytdl-core module, with the exception that
you must `await` the function call.
## What does it do?
For compatible videos, this module uses [prism-media](https://github.com/amishshah/prism-media)
to extract Opus audio from a stream without having to pipe it through FFmpeg first. This greatly
reduces the processing power required, making playback smoother and allowing you to play over
more connections simultaneously.
For videos where the required codec (webm + opus) isn't available, the module will fallback to
using FFmpeg to encode the stream in Opus. Many new videos on YouTube are available in this codec
so hopefully this isn't frequent.
Put simply, this module finds the most efficient way to extract a stream of Opus audio from a
YouTube video.
## Usage in Discord.js 11.4.x
```js
const ytdl = require('ytdl-core-discord');
async function play(connection, url) {
connection.playOpusStream(await ytdl(url));
}
```
## Usage in Discord.js 12.x
```js
const ytdl = require('ytdl-core-discord');
async function play(connection, url) {
connection.play(await ytdl(url), { type: 'opus' });
}
```
[![Patreon](https://c5.patreon.com/external/logo/become_a_patron_button.png)](https://www.patreon.com/discordjs)

42
node_modules/ytdl-core-discord/index.js generated vendored Normal file
View File

@ -0,0 +1,42 @@
const ytdl = require('ytdl-core');
const prism = require('prism-media');
function filter(format) {
return format.audioEncoding === 'opus' &&
format.container === 'webm' &&
format.audio_sample_rate == 48000;
}
module.exports = function download(url, options = {}) {
return new Promise((resolve, reject) => {
ytdl.getInfo(url, (err, info) => {
if (err) return reject(err);
// Prefer opus
const canDemux = info.formats.find(filter) && info.length_seconds != 0;
if (canDemux) Object.assign(options, { filter });
else if (info.length_seconds != 0) Object.assign(options, { filter: 'audioonly' });
const ytdlStream = ytdl.downloadFromInfo(info, options);
if (canDemux) {
const demuxer = new prism.opus.WebmDemuxer();
return resolve(ytdlStream.pipe(demuxer).on('end', () => demuxer.destroy()));
} else {
const transcoder = new prism.FFmpeg({
args: [
'-analyzeduration', '0',
'-loglevel', '0',
'-f', 's16le',
'-ar', '48000',
'-ac', '2',
],
});
const opus = new prism.opus.Encoder({ rate: 48000, channels: 2, frameSize: 960 });
const stream = ytdlStream.pipe(transcoder).pipe(opus);
stream.on('close', () => {
transcoder.destroy();
opus.destroy();
});
return resolve(stream);
}
});
});
};

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2019 Amish Shah
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,69 @@
[![Logo](https://hydrabolt.me/assets/prism-media-logo.svg)](https://hydrabolt.me/prism-media/)
<div align="center">
[![Build Status](https://travis-ci.org/amishshah/prism-media.svg?branch=master)](https://travis-ci.org/hydrabolt/prism-media)
[![dependencies](https://david-dm.org/amishshah/prism-media/status.svg)](https://david-dm.org/hydrabolt/prism-media)
[![npm](https://img.shields.io/npm/dt/prism-media.svg)](https://www.npmjs.com/package/prism-media)
[![Patreon](https://img.shields.io/badge/donate-patreon-F96854.svg)](https://www.patreon.com/discordjs)
</div>
## What is it?
An easy-to-use stream-based toolkit that you can use for media processing. All the features provided have predictable
abstractions and join together coherently.
```js
// This example will demux and decode an Opus-containing OGG file, and then write it to a file.
const prism = require('prism-media');
const fs = require('fs');
fs.createReadStream('./audio.ogg')
.pipe(new prism.opus.OggDemuxer())
.pipe(new prism.opus.Decoder({ rate: 48000, channels: 2, frameSize: 960 }))
.pipe(fs.createWriteStream('./audio.pcm'));
```
The example above can work with either a native or pure JavaScript Opus decoder - you don't need to worry about changing
your code for whichever you install.
- FFmpeg support (either through npm modules or a normal installation)
- Opus support (native or pure JavaScript)
- Demuxing for WebM/OGG files (no modules required!)
- Volume Altering (no modules required!)
## Dependencies
The following dependencies are all optional, and you should only install one from each category (the first listed in
each category is preferred)
- Opus
- [`node-opus`](https://github.com/Rantanen/node-opus) (native, ^0.3.1)
- [`opusscript`](https://github.com/abalabahaha/opusscript) (^0.0.6)
- FFmpeg
- [`ffmpeg-static`](http://npmjs.com/ffmpeg-binaries) (^2.4.0)
- [`ffmpeg-binaries`](http://npmjs.com/ffmpeg-binaries) (^4.0.0)
- `ffmpeg` from a [normal installation](https://www.ffmpeg.org/download.html)
## Useful Links
- [Documentation](https://hydrabolt.me/prism-media)
- [Examples](https://github.com/amishshah/prism-media/tree/master/examples)
- [Patreon](https://www.patreon.com/discordjs)
## License
> Copyright 2019 Amish Shah
>
> Licensed under the Apache License, Version 2.0 (the "License");
> you may not use this file except in compliance with the License.
> You may obtain a copy of the License at
>
> http://www.apache.org/licenses/LICENSE-2.0
>
> Unless required by applicable law or agreed to in writing, software
> distributed under the License is distributed on an "AS IS" BASIS,
> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> See the License for the specific language governing permissions and
> limitations under the License.

View File

@ -0,0 +1,91 @@
{
"_from": "prism-media@^1.0.1",
"_id": "prism-media@1.0.2",
"_inBundle": false,
"_integrity": "sha512-KCu3SlT1EtS0lvF74NGLSTzr5jrkRajE9n+S2jnUvvdiN5SpjsGj0/HgR1QK9+985Yv8cxjwZnpFRaj+SimDGA==",
"_location": "/ytdl-core-discord/prism-media",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "prism-media@^1.0.1",
"name": "prism-media",
"escapedName": "prism-media",
"rawSpec": "^1.0.1",
"saveSpec": null,
"fetchSpec": "^1.0.1"
},
"_requiredBy": [
"/ytdl-core-discord"
],
"_resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.0.2.tgz",
"_shasum": "1e0f097f67d799211177a50d5276fdd2ef1c7fd7",
"_spec": "prism-media@^1.0.1",
"_where": "C:\\Users\\matia\\Musix V2\\node_modules\\ytdl-core-discord",
"author": {
"name": "Amish Shah",
"email": "amishshah.2k@gmail.com"
},
"bugs": {
"url": "https://github.com/hydrabolt/prism-media/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Easy-to-use stream-based media transcoding",
"devDependencies": {
"docma": "^3.2.2",
"eslint": "^4.16.0",
"jest": "^22.1.4"
},
"files": [
"src/",
"typings/"
],
"homepage": "https://github.com/hydrabolt/prism-media#readme",
"jest": {
"testURL": "http://localhost/"
},
"keywords": [
"audio",
"media",
"ffmpeg",
"opus",
"pcm",
"webm",
"ogg"
],
"license": "Apache-2.0",
"main": "src/index.js",
"name": "prism-media",
"peerDependencies": {
"ffmpeg-binaries": "^4.0.0",
"ffmpeg-static": "^2.4.0",
"node-opus": "^0.3.1",
"opusscript": "^0.0.6"
},
"peerDependenciesMeta": {
"node-opus": {
"optional": true
},
"opusscript": {
"optional": true
},
"ffmpeg-static": {
"optional": true
},
"ffmpeg-binaries": {
"optional": true
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/hydrabolt/prism-media.git"
},
"scripts": {
"docs": "docma",
"lint": "eslint src",
"test": "yarn lint && jest"
},
"types": "typings/index.d.ts",
"version": "1.0.2"
}

View File

@ -0,0 +1,99 @@
const ChildProcess = require('child_process');
const { Duplex } = require('stream');
let FFMPEG_COMMAND = null;
/**
* An FFmpeg transform stream that provides an interface to FFmpeg.
* @memberof core
*/
class FFmpeg extends Duplex {
/**
* Creates a new FFmpeg transform stream
* @memberof core
* @param {Object} options Options you would pass to a regular Transform stream, plus an `args` option
* @param {Array<string>} options.args Arguments to pass to FFmpeg
* @example
* // By default, if you don't specify an input (`-i ...`) prism will assume you're piping a stream into it.
* const transcoder = new prism.FFmpeg({
* args: [
* '-analyzeduration', '0',
* '-loglevel', '0',
* '-f', 's16le',
* '-ar', '48000',
* '-ac', '2',
* ]
* });
* const s16le = mp3File.pipe(transcoder);
* const opus = s16le.pipe(new prism.opus.Encoder({ rate: 48000, channels: 2, frameSize: 960 }));
*/
constructor(options = {}) {
super();
this.process = createFFmpeg(options);
const EVENTS = {
readable: this._reader,
data: this._reader,
end: this._reader,
unpipe: this._reader,
finish: this._writer,
drain: this._writer,
};
this._readableState = this._reader._readableState;
this._writableState = this._writer._writableState;
this._copy(['write', 'end'], this._writer);
this._copy(['read', 'setEncoding', 'pipe', 'unpipe'], this._reader);
for (const method of ['on', 'once', 'removeListener', 'removeListeners', 'listeners']) {
this[method] = (ev, fn) => EVENTS[ev] ? EVENTS[ev][method](ev, fn) : Duplex.prototype[method].call(this, ev, fn);
}
const processError = error => this.emit('error', error);
this._reader.on('error', processError);
this._writer.on('error', processError);
}
get _reader() { return this.process.stdout; }
get _writer() { return this.process.stdin; }
_copy(methods, target) {
for (const method of methods) {
this[method] = target[method].bind(target);
}
}
_destroy(err, cb) {
super._destroy(err, cb);
this.once('error', () => {});
this.process.kill('SIGKILL');
}
}
module.exports = FFmpeg;
function createFFmpeg({ args = [] } = {}) {
if (!args.includes('-i')) args = ['-i', '-'].concat(args);
return ChildProcess.spawn(selectFFmpegCommand(), args.concat(['pipe:1']));
}
function selectFFmpegCommand() {
if (FFMPEG_COMMAND) return FFMPEG_COMMAND;
try {
FFMPEG_COMMAND = require('ffmpeg-static').path;
return FFMPEG_COMMAND;
} catch (e) {
try {
FFMPEG_COMMAND = require('ffmpeg-binaries');
process.emitWarning('ffmpeg-binaries is not maintained, please install ffmpeg or ffmpeg-static via npm instead.');
return FFMPEG_COMMAND;
} catch (err) {
for (const command of ['ffmpeg', 'avconv', './ffmpeg', './avconv']) {
if (!ChildProcess.spawnSync(command, ['-h']).error) {
FFMPEG_COMMAND = command;
return FFMPEG_COMMAND;
}
}
throw new Error('FFMPEG not found');
}
}
}

View File

@ -0,0 +1,129 @@
// Based on discord.js' old volume system
const { Transform } = require('stream');
/**
* Transforms a stream of PCM volume.
* @memberof core
* @extends TransformStream
*/
class VolumeTransformer extends Transform {
/**
* @memberof core
* @param {Object} options Any optional TransformStream options plus some extra:
* @param {string} options.type The type of transformer: s16le (signed 16-bit little-endian), s16be, s32le, s32be
* @param {number} [options.volume=1] The output volume of the stream
* @example
* // Half the volume of a signed 16-bit little-endian PCM stream
* input
* .pipe(new prism.VolumeTransformer({ type: 's16le', volume: 0.5 }))
* .pipe(writeStream);
*/
constructor(options = {}) {
super(options);
switch (options.type) {
case 's16le':
this._readInt = (buffer, index) => buffer.readInt16LE(index);
this._writeInt = (buffer, int, index) => buffer.writeInt16LE(int, index);
this._bits = 16;
break;
case 's16be':
this._readInt = (buffer, index) => buffer.readInt16BE(index);
this._writeInt = (buffer, int, index) => buffer.writeInt16BE(int, index);
this._bits = 16;
break;
case 's32le':
this._readInt = (buffer, index) => buffer.readInt32LE(index);
this._writeInt = (buffer, int, index) => buffer.writeInt32LE(int, index);
this._bits = 32;
break;
case 's32be':
this._readInt = (buffer, index) => buffer.readInt32BE(index);
this._writeInt = (buffer, int, index) => buffer.writeInt32BE(int, index);
this._bits = 32;
break;
default:
throw new Error('VolumeTransformer type should be one of s16le, s16be, s32le, s32be');
}
this._bytes = this._bits / 8;
this._extremum = Math.pow(2, this._bits - 1);
this.volume = typeof options.volume === 'undefined' ? 1 : options.volume;
this._chunk = Buffer.alloc(0);
}
_readInt(buffer, index) { return index; }
_writeInt(buffer, int, index) { return index; }
_transform(chunk, encoding, done) {
// If the volume is 1, act like a passthrough stream
if (this.volume === 1) {
this.push(chunk);
return done();
}
const { _bytes, _extremum } = this;
chunk = this._chunk = Buffer.concat([this._chunk, chunk]);
if (chunk.length < _bytes) return done();
const transformed = Buffer.allocUnsafe(chunk.length);
const complete = Math.floor(chunk.length / _bytes) * _bytes;
for (let i = 0; i < complete; i += _bytes) {
const int = Math.min(_extremum - 1, Math.max(-_extremum, Math.floor(this.volume * this._readInt(chunk, i))));
this._writeInt(transformed, int, i);
}
this._chunk = chunk.slice(complete);
this.push(transformed);
return done();
}
_destroy(err, cb) {
super._destroy(err, cb);
this._chunk = null;
}
/**
* Sets the volume relative to the input stream - i.e. 1 is normal, 0.5 is half, 2 is double.
* @param {number} volume The volume that you want to set
*/
setVolume(volume) {
this.volume = volume;
}
/**
* Sets the volume in decibels.
* @param {number} db The decibels
*/
setVolumeDecibels(db) {
this.setVolume(Math.pow(10, db / 20));
}
/**
* Sets the volume so that a perceived value of 0.5 is half the perceived volume etc.
* @param {number} value The value for the volume
*/
setVolumeLogarithmic(value) {
this.setVolume(Math.pow(value, 1.660964));
}
/**
* The current volume of the stream in decibels
* @readonly
* @type {number}
*/
get volumeDecibels() {
return Math.log10(this._volume) * 20;
}
/**
* The current volume of the stream from a logarithmic scale
* @readonly
* @type {number}
*/
get volumeLogarithmic() {
return Math.pow(this._volume, 1 / 1.660964);
}
}
module.exports = VolumeTransformer;

View File

@ -0,0 +1,199 @@
const { Transform } = require('stream');
/**
* Base class for WebmOpusDemuxer and WebmVorbisDemuxer.
* **You shouldn't directly instantiate this class, use the opus.WebmDemuxer and vorbis.WebmDemuxer
* implementations instead!**
* @memberof core
* @protected
* @extends TransformStream
*/
class WebmBaseDemuxer extends Transform {
/**
* Creates a new Webm demuxer.
* @private
* @memberof core
* @param {Object} [options] options that you would pass to a regular Transform stream.
*/
constructor(options = {}) {
super(Object.assign({ readableObjectMode: true }, options));
this._remainder = null;
this._length = 0;
this._count = 0;
this._skipUntil = null;
this._track = null;
this._incompleteTrack = {};
this._ebmlFound = false;
}
_transform(chunk, encoding, done) {
this._length += chunk.length;
if (this._remainder) {
chunk = Buffer.concat([this._remainder, chunk]);
this._remainder = null;
}
let offset = 0;
if (this._skipUntil && this._length > this._skipUntil) {
offset = this._skipUntil - this._count;
this._skipUntil = null;
} else if (this._skipUntil) {
this._count += chunk.length;
return done();
}
let result;
while (result !== TOO_SHORT) {
result = this._readTag(chunk, offset);
if (result === TOO_SHORT) break;
if (result._skipUntil) {
this._skipUntil = result._skipUntil;
break;
}
if (result.offset) offset = result.offset;
else break;
}
this._count += offset;
this._remainder = chunk.slice(offset);
return done();
}
/**
* Reads an EBML ID from a buffer.
* @private
* @param {Buffer} chunk the buffer to read from.
* @param {number} offset the offset in the buffer.
* @returns {Object|Symbol} contains an `id` property (buffer) and the new `offset` (number).
* Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
*/
_readEBMLId(chunk, offset) {
const idLength = vintLength(chunk, offset);
if (idLength === TOO_SHORT) return TOO_SHORT;
return {
id: chunk.slice(offset, offset + idLength),
offset: offset + idLength,
};
}
/**
* Reads a size variable-integer to calculate the length of the data of a tag.
* @private
* @param {Buffer} chunk the buffer to read from.
* @param {number} offset the offset in the buffer.
* @returns {Object|Symbol} contains property `offset` (number), `dataLength` (number) and `sizeLength` (number).
* Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
*/
_readTagDataSize(chunk, offset) {
const sizeLength = vintLength(chunk, offset);
if (sizeLength === TOO_SHORT) return TOO_SHORT;
const dataLength = expandVint(chunk, offset, offset + sizeLength);
return { offset: offset + sizeLength, dataLength, sizeLength };
}
/**
* Takes a buffer and attempts to read and process a tag.
* @private
* @param {Buffer} chunk the buffer to read from.
* @param {number} offset the offset in the buffer.
* @returns {Object|Symbol} contains the new `offset` (number) and optionally the `_skipUntil` property,
* indicating that the stream should ignore any data until a certain length is reached.
* Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
*/
_readTag(chunk, offset) {
const idData = this._readEBMLId(chunk, offset);
if (idData === TOO_SHORT) return TOO_SHORT;
const ebmlID = idData.id.toString('hex');
if (!this._ebmlFound) {
if (ebmlID === '1a45dfa3') this._ebmlFound = true;
else throw Error('Did not find the EBML tag at the start of the stream');
}
offset = idData.offset;
const sizeData = this._readTagDataSize(chunk, offset);
if (sizeData === TOO_SHORT) return TOO_SHORT;
const { dataLength } = sizeData;
offset = sizeData.offset;
// If this tag isn't useful, tell the stream to stop processing data until the tag ends
if (typeof TAGS[ebmlID] === 'undefined') {
if (chunk.length > offset + dataLength) {
return { offset: offset + dataLength };
}
return { offset, _skipUntil: this._count + offset + dataLength };
}
const tagHasChildren = TAGS[ebmlID];
if (tagHasChildren) {
return { offset };
}
if (offset + dataLength > chunk.length) return TOO_SHORT;
const data = chunk.slice(offset, offset + dataLength);
if (!this._track) {
if (ebmlID === 'ae') this._incompleteTrack = {};
if (ebmlID === 'd7') this._incompleteTrack.number = data[0];
if (ebmlID === '83') this._incompleteTrack.type = data[0];
if (this._incompleteTrack.type === 2 && typeof this._incompleteTrack.number !== 'undefined') {
this._track = this._incompleteTrack;
}
}
if (ebmlID === '63a2') {
this._checkHead(data);
} else if (ebmlID === 'a3') {
if (!this._track) throw Error('No audio track in this webm!');
if ((data[0] & 0xF) === this._track.number) {
this.push(data.slice(4));
}
}
return { offset: offset + dataLength };
}
}
/**
* A symbol that is returned by some functions that indicates the buffer it has been provided is not large enough
* to facilitate a request.
* @name WebmBaseDemuxer#TOO_SHORT
* @memberof core
* @private
* @type {Symbol}
*/
const TOO_SHORT = WebmBaseDemuxer.TOO_SHORT = Symbol('TOO_SHORT');
/**
* A map that takes a value of an EBML ID in hex string form, with the value being a boolean that indicates whether
* this tag has children.
* @name WebmBaseDemuxer#TAGS
* @memberof core
* @private
* @type {Object}
*/
const TAGS = WebmBaseDemuxer.TAGS = { // value is true if the element has children
'1a45dfa3': true, // EBML
'18538067': true, // Segment
'1f43b675': true, // Cluster
'1654ae6b': true, // Tracks
'ae': true, // TrackEntry
'd7': false, // TrackNumber
'83': false, // TrackType
'a3': false, // SimpleBlock
'63a2': false,
};
module.exports = WebmBaseDemuxer;
function vintLength(buffer, index) {
let i = 0;
for (; i < 8; i++) if ((1 << (7 - i)) & buffer[index]) break;
i++;
if (index + i > buffer.length) {
return TOO_SHORT;
}
return i;
}
function expandVint(buffer, start, end) {
const length = vintLength(buffer, start);
if (end > buffer.length || length === TOO_SHORT) return TOO_SHORT;
let mask = (1 << (8 - length)) - 1;
let value = buffer[start] & mask;
for (let i = start + 1; i < end; i++) {
value = (value << 8) + buffer[i];
}
return value;
}

View File

@ -0,0 +1,9 @@
/**
* Core features.
* **You shouldn't prefix imports from this namespace with `core`.**
* @namespace core
*/
module.exports = {
FFmpeg: require('./FFmpeg'),
VolumeTransformer: require('./VolumeTransformer'),
};

View File

@ -0,0 +1,5 @@
module.exports = {
opus: require('./opus'),
vorbis: require('./vorbis'),
...require('./core'),
};

View File

@ -0,0 +1,118 @@
const { Transform } = require('stream');
const OGG_PAGE_HEADER_SIZE = 26;
const STREAM_STRUCTURE_VERSION = 0;
const charCode = x => x.charCodeAt(0);
const OGGS_HEADER = Buffer.from([...'OggS'].map(charCode));
const OPUS_HEAD = Buffer.from([...'OpusHead'].map(charCode));
const OPUS_TAGS = Buffer.from([...'OpusTags'].map(charCode));
/**
* Demuxes an Ogg stream (containing Opus audio) to output an Opus stream.
* @extends {TransformStream}
* @memberof opus
*/
class OggDemuxer extends Transform {
/**
* Creates a new OggOpus demuxer.
* @param {Object} [options] options that you would pass to a regular Transform stream.
* @memberof opus
*/
constructor(options = {}) {
super(Object.assign({ readableObjectMode: true }, options));
this._remainder = null;
this._head = null;
this._bitstream = null;
}
_transform(chunk, encoding, done) {
if (this._remainder) {
chunk = Buffer.concat([this._remainder, chunk]);
this._remainder = null;
}
while (chunk) {
const result = this._readPage(chunk);
if (result) chunk = result;
else break;
}
this._remainder = chunk;
done();
}
/**
* Reads a page from a buffer
* @private
* @param {Buffer} chunk the chunk containing the page
* @returns {boolean|Buffer} if a buffer, it will be a slice of the excess data of the original, otherwise it will be
* false and would indicate that there is not enough data to go ahead with reading this page.
*/
_readPage(chunk) {
if (chunk.length < OGG_PAGE_HEADER_SIZE) {
return false;
}
if (!chunk.slice(0, 4).equals(OGGS_HEADER)) {
throw Error(`capture_pattern is not ${OGGS_HEADER}`);
}
if (chunk.readUInt8(4) !== STREAM_STRUCTURE_VERSION) {
throw Error(`stream_structure_version is not ${STREAM_STRUCTURE_VERSION}`);
}
if (chunk.length < 27) return false;
const pageSegments = chunk.readUInt8(26);
if (chunk.length < 27 + pageSegments) return false;
const table = chunk.slice(27, 27 + pageSegments);
const bitstream = chunk.readUInt32BE(14);
let sizes = [], totalSize = 0;
for (let i = 0; i < pageSegments;) {
let size = 0, x = 255;
while (x === 255) {
if (i >= table.length) return false;
x = table.readUInt8(i);
i++;
size += x;
}
sizes.push(size);
totalSize += size;
}
if (chunk.length < 27 + pageSegments + totalSize) return false;
let start = 27 + pageSegments;
for (const size of sizes) {
const segment = chunk.slice(start, start + size);
const header = segment.slice(0, 8);
if (this._head) {
if (header.equals(OPUS_TAGS)) this.emit('tags', segment);
else if (this._bitstream === bitstream) this.push(segment);
} else if (header.equals(OPUS_HEAD)) {
this.emit('head', segment);
this._head = segment;
this._bitstream = bitstream;
} else {
this.emit('unknownSegment', segment);
}
start += size;
}
return chunk.slice(start);
}
}
/**
* Emitted when the demuxer encounters the opus head.
* @event OggDemuxer#head
* @memberof opus
* @param {Buffer} segment a buffer containing the opus head data.
*/
/**
* Emitted when the demuxer encounters opus tags.
* @event OggDemuxer#tags
* @memberof opus
* @param {Buffer} segment a buffer containing the opus tags.
*/
module.exports = OggDemuxer;

View File

@ -0,0 +1,188 @@
// Partly based on https://github.com/Rantanen/node-opus/blob/master/lib/Encoder.js
const { Transform } = require('stream');
const loader = require('../util/loader');
const CTL = {
BITRATE: 4002,
FEC: 4012,
PLP: 4014,
};
const Opus = loader.require([
['node-opus', o => o.OpusEncoder],
['opusscript', o => o],
], {
fn: 'Encoder',
});
const charCode = x => x.charCodeAt(0);
const OPUS_HEAD = Buffer.from([...'OpusHead'].map(charCode));
const OPUS_TAGS = Buffer.from([...'OpusTags'].map(charCode));
// frame size = (channels * rate * frame_duration) / 1000
/**
* Takes a stream of Opus data and outputs a stream of PCM data, or the inverse.
* **You shouldn't directly instantiate this class, see opus.Encoder and opus.Decoder instead!**
* @memberof opus
* @extends TransformStream
* @protected
*/
class OpusStream extends Transform {
/**
* Creates a new Opus transformer.
* @private
* @memberof opus
* @param {Object} [options] options that you would pass to a regular Transform stream
*/
constructor(options = {}) {
if (!Opus.Encoder) {
throw Error('Could not find an Opus module! Please install node-opus or opusscript.');
}
super(Object.assign({ readableObjectMode: true }, options));
if (Opus.name === 'opusscript') {
options.application = Opus.Encoder.Application[options.application];
}
this.encoder = new Opus.Encoder(options.rate, options.channels, options.application);
this._options = options;
this._required = this._options.frameSize * this._options.channels * 2;
}
_encode(buffer) {
return this.encoder.encode(buffer, Opus.name !== 'node-opus' ? this._options.frameSize : null);
}
_decode(buffer) {
return this.encoder.decode(buffer, Opus.name !== 'node-opus' ? this._options.frameSize : null);
}
/**
* Returns the Opus module being used - `opusscript` or `node-opus`.
* @type {string}
* @readonly
* @example
* console.log(`Using Opus module ${prism.opus.Encoder.type}`);
*/
static get type() {
return Opus.name;
}
/**
* Sets the bitrate of the stream.
* @param {number} bitrate the bitrate to use use, e.g. 48000
* @public
*/
setBitrate(bitrate) {
(this.encoder.applyEncoderCTL || this.encoder.encoderCTL)
.apply(this.encoder, [CTL.BITRATE, Math.min(128e3, Math.max(16e3, bitrate))]);
}
/**
* Enables or disables forward error correction.
* @param {boolean} enabled whether or not to enable FEC.
* @public
*/
setFEC(enabled) {
(this.encoder.applyEncoderCTL || this.encoder.encoderCTL)
.apply(this.encoder, [CTL.FEC, enabled ? 1 : 0]);
}
/**
* Sets the expected packet loss over network transmission.
* @param {number} [percentage] a percentage (represented between 0 and 1)
*/
setPLP(percentage) {
(this.encoder.applyEncoderCTL || this.encoder.encoderCTL)
.apply(this.encoder, [CTL.FEC, Math.min(100, Math.max(0, percentage * 100))]);
}
_final(cb) {
if (Opus.name === 'opusscript' && this.encoder) this.encoder.delete();
cb();
}
}
/**
* An Opus encoder stream.
*
* Outputs opus packets in [object mode.](https://nodejs.org/api/stream.html#stream_object_mode)
* @extends opus.OpusStream
* @memberof opus
* @example
* const encoder = new prism.opus.Encoder({ frameSize: 960, channels: 2, rate: 48000 });
* pcmAudio.pipe(encoder);
* // encoder will now output Opus-encoded audio packets
*/
class Encoder extends OpusStream {
/**
* Creates a new Opus encoder stream.
* @memberof opus
* @param {Object} options options that you would pass to a regular OpusStream, plus a few more:
* @param {number} options.frameSize the frame size in bytes to use (e.g. 960 for stereo audio at 48KHz with a frame
* duration of 20ms)
* @param {number} options.channels the number of channels to use
* @param {number} options.rate the sampling rate in Hz
*/
constructor(options) {
super(options);
this._buffer = Buffer.alloc(0);
}
async _transform(chunk, encoding, done) {
this._buffer = Buffer.concat([this._buffer, chunk]);
let n = 0;
while (this._buffer.length >= this._required * (n + 1)) {
const buf = await this._encode(this._buffer.slice(n * this._required, (n + 1) * this._required));
this.push(buf);
n++;
}
if (n > 0) this._buffer = this._buffer.slice(n * this._required);
return done();
}
_destroy(err, cb) {
super._destroy(err, cb);
this._buffer = null;
}
}
/**
* An Opus decoder stream.
*
* Note that any stream you pipe into this must be in
* [object mode](https://nodejs.org/api/stream.html#stream_object_mode) and should output Opus packets.
* @extends opus.OpusStream
* @memberof opus
* @example
* const decoder = new prism.opus.Decoder({ frameSize: 960, channels: 2, rate: 48000 });
* input.pipe(decoder);
* // decoder will now output PCM audio
*/
class Decoder extends OpusStream {
_transform(chunk, encoding, done) {
const signature = chunk.slice(0, 8);
if (signature.equals(OPUS_HEAD)) {
this.emit('format', {
channels: this._options.channels,
sampleRate: this._options.rate,
bitDepth: 16,
float: false,
signed: true,
version: chunk.readUInt8(8),
preSkip: chunk.readUInt16LE(10),
gain: chunk.readUInt16LE(16),
});
return done();
}
if (signature.equals(OPUS_TAGS)) {
this.emit('tags', chunk);
return done();
}
this.push(this._decode(chunk));
return done();
}
}
module.exports = { Decoder, Encoder };

View File

@ -0,0 +1,24 @@
const WebmBaseDemuxer = require('../core/WebmBase');
const OPUS_HEAD = Buffer.from([...'OpusHead'].map(x => x.charCodeAt(0)));
/**
* Demuxes a Webm stream (containing Opus audio) to output an Opus stream.
* @extends core.WebmBaseDemuxer
* @memberof opus
* @example
* const fs = require('fs');
* const file = fs.createReadStream('./audio.webm');
* const demuxer = new prism.opus.WebmDemuxer();
* const opus = file.pipe(demuxer);
* // opus is now a ReadableStream in object mode outputting Opus packets
*/
class WebmDemuxer extends WebmBaseDemuxer {
_checkHead(data) {
if (!data.slice(0, 8).equals(OPUS_HEAD)) {
throw Error('Audio codec is not Opus!');
}
}
}
module.exports = WebmDemuxer;

View File

@ -0,0 +1,10 @@
/**
* Opus features
* @namespace opus
*/
module.exports = {
// Encoder and Decoder
...require('./Opus'),
OggDemuxer: require('./OggDemuxer'),
WebmDemuxer: require('./WebmDemuxer'),
};

View File

@ -0,0 +1,14 @@
exports.require = function loader(requireData, objMap = {}) {
for (const [name, reqFn] of requireData) {
try {
const dep = require(name);
const fn = reqFn ? reqFn(dep) : dep;
return {
[objMap.module || 'module']: dep,
[objMap.name || 'name']: name,
[objMap.fn || 'fn']: fn,
};
} catch (e) { }
}
return {};
};

View File

@ -0,0 +1,22 @@
const WebmBaseDemuxer = require('../core/WebmBase');
const VORBIS_HEAD = Buffer.from([...'vorbis'].map(x => x.charCodeAt(0)));
/**
* Demuxes a Webm stream (containing Vorbis audio) to output a Vorbis stream.
* @memberof vorbis
* @extends core.WebmBaseDemuxer
*/
class WebmDemuxer extends WebmBaseDemuxer {
_checkHead(data) {
if (data.readUInt8(0) !== 2 || !data.slice(4, 10).equals(VORBIS_HEAD)) {
throw Error('Audio codec is not Vorbis!');
}
this.push(data.slice(3, 3 + data.readUInt8(1)));
this.push(data.slice(3 + data.readUInt8(1), 3 + data.readUInt8(1) + data.readUInt8(2)));
this.push(data.slice(3 + data.readUInt8(1) + data.readUInt8(2)));
}
}
module.exports = WebmDemuxer;

View File

@ -0,0 +1,8 @@
/**
* Vorbis features
* @namespace vorbis
*/
module.exports = {
WebmDemuxer: require('./WebmDemuxer'),
};

View File

@ -0,0 +1,11 @@
import { ChildProcess } from 'child_process';
import { Duplex } from 'stream';
export interface FFmpegOptions {
args?: string[];
}
export default class FFmpegTransform extends Duplex {
public process: ChildProcess;
constructor(options?: FFmpegOptions);
}

View File

@ -0,0 +1,17 @@
import { Transform } from 'stream';
export interface VolumeOptions {
type: 's16le' | 's16be' | 's32le' | 's32be',
volume?: number
}
export default class VolumeTransformer {
public volume: number;
constructor(options: VolumeOptions);
public setVolume(volume: number): void;
public setVolumeDecibels(db: number): void;
public setVolumeLogarithmic(value: number): void;
public readonly volumeDecibels: number;
public readonly volumeLogarithmic: number;
}

View File

@ -0,0 +1,7 @@
import FFmpeg from './FFmpeg';
import VolumeTransformer from './VolumeTransformer';
export {
FFmpeg,
VolumeTransformer
}

View File

@ -0,0 +1,8 @@
export * from './core';
import opus from './opus';
import vorbis from './vorbis';
export {
opus,
vorbis
}

View File

@ -0,0 +1,3 @@
import { Transform } from 'stream';
export default class OggDemuxer extends Transform {}

View File

@ -0,0 +1,27 @@
import { Transform } from 'stream';
export interface OpusOptions {
frameSize: number,
channels: number,
rate: number
}
export class OpusStream extends Transform {
public encoder: any; // TODO: type opusscript/node-opus
constructor(options: OpusOptions);
public static readonly type: 'opusscript' | 'node-opus';
public setBitrate(bitrate: number): void;
public setFEC(enabled: boolean): void;
public setPLP(percentage: number): void;
}
export class Encoder extends OpusStream {}
export class Decoder extends OpusStream {}
declare let _default: {
Encoder: Encoder,
Decoder: Decoder,
}
export default _default;

View File

@ -0,0 +1,3 @@
import { Transform } from 'stream';
export default class WebmOpusTransform extends Transform {}

View File

@ -0,0 +1,10 @@
import { Encoder, Decoder } from './Opus';
import OggDemuxer from './OggDemuxer';
import WebmDemuxer from './WebmDemuxer';
export {
Encoder,
Decoder,
OggDemuxer,
WebmDemuxer
}

View File

@ -0,0 +1,3 @@
import { Transform } from 'stream';
export default class WebmVorbis extends Transform {}

View File

@ -0,0 +1,5 @@
import WebmDemuxer from './WebmDemuxer';
export {
WebmDemuxer
}

63
node_modules/ytdl-core-discord/package.json generated vendored Normal file
View File

@ -0,0 +1,63 @@
{
"_from": "ytdl-core-discord",
"_id": "ytdl-core-discord@1.0.3",
"_inBundle": false,
"_integrity": "sha512-/POaSbStmY+PMRnxz4mVN0Rw9Ktt3zs94j2bRX30vmtdMR1yCz9JbEmRY4ouXJK18k/FjdRs5Bnvinud2hbYGQ==",
"_location": "/ytdl-core-discord",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "ytdl-core-discord",
"name": "ytdl-core-discord",
"escapedName": "ytdl-core-discord",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/ytdl-core-discord/-/ytdl-core-discord-1.0.3.tgz",
"_shasum": "4dbe41d77507ee52fcf184b269e2cb9d7f2262aa",
"_spec": "ytdl-core-discord",
"_where": "C:\\Users\\matia\\Musix V2\\src",
"author": {
"name": "Amish Shah",
"email": "amishshah.2k@gmail.com"
},
"bugs": {
"url": "https://github.com/amishshah/ytdl-core-discord/issues"
},
"bundleDependencies": false,
"dependencies": {
"prism-media": "^1.0.1",
"ytdl-core": "^0.29.1"
},
"deprecated": false,
"description": "A ytdl-core wrapper focused on efficiency for use in Discord music bots",
"devDependencies": {
"eslint": "^5.14.0"
},
"homepage": "https://github.com/amishshah/ytdl-core-discord#readme",
"keywords": [
"discord",
"ytdl",
"youtube",
"audio",
"music",
"bot"
],
"license": "Apache-2.0",
"main": "index.js",
"name": "ytdl-core-discord",
"repository": {
"type": "git",
"url": "git+https://github.com/amishshah/ytdl-core-discord.git"
},
"scripts": {
"test": "eslint index.js"
},
"version": "1.0.3"
}