├── .gitignore
├── LICENSE
├── README.md
├── example.html
├── example.js
├── gulpfile.js
├── index.js
├── package.json
└── waveform.png
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | npm-debug.log
3 | dist/
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2015-present Christian Nilsson
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-waveform
2 |
3 | > Generates waveform using Web Audio API.
4 |
5 |
6 |
7 |
8 |
9 |
10 | ## Install
11 |
12 | ```sh
13 | npm install react-waveform
14 | ```
15 |
16 |
17 | ## Props
18 |
19 | * **buffer** AudioBuffer
20 | * **width** Number
21 | * **height** Number
22 | * **zoom** Number
23 | * **color** String
24 | * **onDone** Function
25 |
26 |
27 | ## Example
28 |
29 | ```javascript
30 | var React = require('react');
31 | var Waveform = require('react-waveform');
32 |
33 | var request = new XMLHttpRequest();
34 | request.open('GET', 'HardaTider-Har&nu.mp3', true);
35 | request.responseType = 'arraybuffer';
36 |
37 | request.addEventListener('load', function () {
38 | var context = new (window.AudioContext || window.webkitAudioContext)();
39 |
40 | context.decodeAudioData(request.response, function (buffer) {
41 | React.render(
42 | ,
43 | document.getElementById('waveform')
44 | );
45 | });
46 | });
47 |
48 | request.send();
49 | ```
50 |
51 |
52 | ## License
53 |
54 | MIT
55 |
--------------------------------------------------------------------------------
/example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/example.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Waveform = require('./index');
3 |
4 | var request = new XMLHttpRequest();
5 | request.open('GET', 'HardaTider-Har&nu.mp3', true);
6 | request.responseType = 'arraybuffer';
7 |
8 | request.addEventListener('load', function () {
9 | var context = new (window.AudioContext || window.webkitAudioContext)();
10 |
11 | context.decodeAudioData(request.response, function (buffer) {
12 | React.render(
13 | ,
14 | document.getElementById('waveform')
15 | );
16 | });
17 | });
18 |
19 | request.send();
20 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('gulp-browserify');
3 | var concat = require('gulp-concat');
4 |
5 | var paths = {
6 | example: 'example.html',
7 | main: 'example.js',
8 | js: ['index.js', 'example.js'],
9 | dist: 'dist/'
10 | };
11 |
12 | gulp.task('copyexample', function () {
13 | return gulp.src(paths.example)
14 | .pipe(gulp.dest(paths.dist));
15 | });
16 |
17 | gulp.task('browserify', function () {
18 | return gulp.src(paths.main)
19 | .pipe(browserify({ transform: 'reactify', debug: true }))
20 | .pipe(concat('main.js'))
21 | .pipe(gulp.dest(paths.dist));
22 | });
23 |
24 | gulp.task('watch', function () {
25 | gulp.watch(paths.example, ['copyexample']);
26 | gulp.watch(paths.js, ['browserify']);
27 | });
28 |
29 | gulp.task('default', ['browserify', 'copyexample']);
30 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | module.exports = React.createClass({
4 | displayName: 'Waveform',
5 |
6 | getDefaultProps: function () {
7 | return {
8 | buffer: null,
9 | width: 500,
10 | height: 100,
11 | zoom: 1,
12 | color: 'black',
13 | onDone: null
14 | };
15 | },
16 |
17 | propTypes: {
18 | buffer: React.PropTypes.object.isRequired,
19 | width: React.PropTypes.number,
20 | height: React.PropTypes.number,
21 | zoom: React.PropTypes.number,
22 | color: React.PropTypes.string,
23 | onDone: React.PropTypes.func
24 | },
25 |
26 | componentDidMount: function () {
27 | var width = this.props.width * this.props.zoom;
28 | var middle = this.props.height / 2;
29 |
30 | var channelData = this.props.buffer.getChannelData(0);
31 | var step = Math.ceil(channelData.length / width);
32 |
33 | var ctx = this.refs.canvas.getDOMNode().getContext('2d');
34 | ctx.fillStyle = this.props.color;
35 | this.draw(width, step, middle, channelData, ctx);
36 |
37 | if (this.props.onDone) { this.props.onDone(); }
38 | },
39 |
40 | draw: function (width, step, middle, data, ctx) {
41 | for (var i = 0; i < width; i += 1) {
42 | var min = 1.0;
43 | var max = -1.0;
44 |
45 | for (var j = 0; j < step; j += 1) {
46 | var datum = data[(i * step) + j];
47 |
48 | if (datum < min) {
49 | min = datum;
50 | } else if (datum > max) {
51 | max = datum;
52 | }
53 |
54 | ctx.fillRect(i, (1 + min) * middle, 1, Math.max(1, (max - min) * middle));
55 | }
56 | }
57 | },
58 |
59 | render: function () {
60 | return (
61 |
65 | );
66 | }
67 | });
68 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-waveform",
3 | "version": "0.1.1",
4 | "description": "Generates waveform using Web Audio API.",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/klambycom/react-waveform.git"
12 | },
13 | "keywords": [
14 | "react",
15 | "waveform",
16 | "audio"
17 | ],
18 | "author": "Christian Nilsson (http://klamby.com/)",
19 | "license": "MIT",
20 | "devDependencies": {
21 | "gulp": "^3.8.11",
22 | "gulp-browserify": "^0.5.1",
23 | "gulp-concat": "^2.4.3",
24 | "reactify": "^1.0.0"
25 | },
26 | "dependencies": {
27 | "react": "^0.12.2"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/waveform.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klambycom/react-waveform/5168350976b0806096a279f6e2d5db8fe167ce93/waveform.png
--------------------------------------------------------------------------------