Skip to content

Commit

Permalink
Merge pull request #344 from itslanguage/add-volumemeter-example
Browse files Browse the repository at this point in the history
Add volumemeter example
  • Loading branch information
joggienl authored Apr 17, 2019
2 parents c204fd9 + adbe05f commit 46de4bb
Show file tree
Hide file tree
Showing 22 changed files with 2,462 additions and 77 deletions.
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module.exports = {
root: true,
parser: 'babel-eslint',
extends: [
'airbnb-base',
Expand Down
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org).
- `recorder`
- Made it possible to load plugins.
- Added the Amplitude plugin.
- `examples`
- Add an example project to demonstrate the `AmplitudePlugin`.

### Changed

Expand Down Expand Up @@ -104,8 +106,7 @@ and this project adheres to [Semantic Versioning](http://semver.org).
- Improve README.md documentation.
- Changed the getUserAuth and getOAuth2Token to use the new API auth functions.


[Unreleased]: https://github.com/itslanguage/itslanguage-js/compare/v4.1.0...HEAD
[unreleased]: https://github.com/itslanguage/itslanguage-js/compare/v4.1.0...HEAD
[v4.1.0]: https://github.com/itslanguage/itslanguage-js/compare/v4.0.2...v4.1.0
[v4.0.2]: https://github.com/itslanguage/itslanguage-js/compare/v4.0.1...v4.0.2
[v4.0.1]: https://github.com/itslanguage/itslanguage-js/compare/v4.0.0...v4.0.1
Expand Down
20 changes: 20 additions & 0 deletions examples/react-recorder-volume-indicator/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"presets": [
[
"@babel/preset-env",
{
"spec": false,
"loose": true,
"useBuiltIns": "usage",
"corejs": 3
}
],
["@babel/preset-react", { "useBuiltIns": true }]
],

"plugins": [
"@babel/plugin-syntax-dynamic-import",
["@babel/plugin-proposal-class-properties", { "loose": true }],
["@babel/plugin-transform-runtime", { "helpers": true }]
]
}
3 changes: 3 additions & 0 deletions examples/react-recorder-volume-indicator/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
!.*
build/
node_modules/
23 changes: 23 additions & 0 deletions examples/react-recorder-volume-indicator/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
parser: 'babel-eslint',
extends: ['airbnb', 'plugin:prettier/recommended', 'prettier/react'],
plugins: ['react', 'react-hooks', 'jsx-a11y'],
env: {
jest: true,
browser: true,
node: true,
es6: true,
},
rules: {
'import/no-extraneous-dependencies': 0,
'react/jsx-filename-extension': 0,
'react/prefer-stateless-function': 0,
},
settings: {
'import/resolver': {
webpack: {
config: './webpack.config.js',
},
},
},
};
5 changes: 5 additions & 0 deletions examples/react-recorder-volume-indicator/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
build/
node_modules/
package-lock.json
yarn.lock
package.json
5 changes: 5 additions & 0 deletions examples/react-recorder-volume-indicator/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "all"
}
12 changes: 12 additions & 0 deletions examples/react-recorder-volume-indicator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Recorder volume indicator

Example project to show how to create volume indication on the `@itslanguage/recorder` package.

## Getting started, TL;DR

1. Clone the [itslanguage sdk](https://github.com/itslanguage/itslanguage-js.git) repository;
1. Navigate to the specific example in the examples directory;
1. Run `npm install` or `yarn install`;
1. Run `npm run start` or `yarn run start`;

The example should now be available via [http://localhost:3000](http://localhost:3000).
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.AmplitudeMeter {
margin: 2rem;
}

.AmplitudeMeter:hover circle:last-child {
fill: #eeeeee;
}

.AmplitudeMeter circle {
user-select: none;
transition: all 0.1s;
}

.AmplitudeMeter text {
user-select: none;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
createMediaStream,
createRecorder,
createAmplitudePlugin,
} from '../../../../../packages/recorder';
import './index.css';

class AmplitudeMeter extends React.Component {
state = {
currentVolume: 0,
};

componentWillMount() {
this.initializeRecorder();
}

componentWillUpdate(nextProps) {
const { enableMeter } = this.props;
if (nextProps.enableMeter !== enableMeter) {
if (nextProps.enableMeter) {
this.start();
} else {
this.stop();
}
}
}

componentWillUnmount() {
this.recorder.removeEventListener('amplitudelevels', this.updateVolume);
}

start = () => {
this.recorder.start();
};

stop = () => {
this.setState({ currentVolume: 0 }, () => {
this.recorder.stop();
});
};

updateVolume = ({ data }) => {
this.setState({ currentVolume: data.volume });
};

initializeRecorder = async () => {
const stream = await createMediaStream();
const recorderPlugins = [createAmplitudePlugin()];

this.recorder = createRecorder(stream, recorderPlugins);
this.recorder.addEventListener('amplitudelevels', this.updateVolume);
};

render() {
const { currentVolume } = this.state;
const volume = Math.min(
Math.max(parseInt(currentVolume * 30 * 64, 10), 16),
256,
);
const currentVolumeRounded = parseFloat(
Math.round(currentVolume * 100) / 100,
10,
).toFixed(2);

return (
<svg
className="AmplitudeMeter"
width="64px"
height="64px"
viewBox="0 0 536 716"
>
<circle cx="256" cy="256" r="256" fill="#dadada" />
<circle cx="256" cy="256" r={volume} fill="#e9573e" />
<text
x="50%"
y="100%"
textAnchor="middle"
stroke="#000000"
strokeWidth="2px"
fontSize="120px"
fontFamily="Fira Mono"
>
{currentVolumeRounded}
</text>
</svg>
);
}
}

AmplitudeMeter.propTypes = {
enableMeter: PropTypes.bool,
};

AmplitudeMeter.defaultProps = {
enableMeter: false,
};

export default AmplitudeMeter;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.App {
margin: 0 auto;
max-width: 960px;
}

.App .center {
text-align: center;
}

@media screen and (max-width: 976px) {
.App {
padding: 1rem;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react';
import AmplitudeMeter from '../AmplitudeMeter';
import Button from '../Button';

import './index.css';

class App extends React.Component {
state = {
enableMeter: false,
};

toggleMeter = () => {
this.setState(prevState => ({
enableMeter: !prevState.enableMeter,
}));
};

render() {
const { enableMeter } = this.state;
return (
<div className="App">
<div>
<h2>Volume indication example</h2>
<p>
Live demonstration of a recorder with <code>AmplitudePlugin</code>{' '}
enabled. If the <code>AmplitudePlugin</code> is enabled on the
recorder, the recorder will regulary emit an{' '}
<code>amplitude-level</code> event that has the current amplitude
level information. We can use that value to animate the circle.
Click on the "Enable meter" button to enable the recorder and show
the volume meter received from the recorder.
</p>
</div>
<div className="center">
<AmplitudeMeter enableMeter={enableMeter} />
<br />
<Button onClick={this.toggleMeter}>
{enableMeter ? 'Disable' : 'Enable'} meter
</Button>
</div>
<div>
<h3>About volume</h3>
<p>
The volume object that gets emitted by the recorder looks like
below.
</p>
<pre>
<code>
{`{
"averageVolumePerChannel": [0, 0],
"volumePerChannel": [0.12, 0.10],
"volume": 0.11
}`}
</code>
</pre>
<p>
This example output uses a recorder with 2 output channels (i.e.
stereo). The volume will always be a positive number between 0.0 and
1.0
</p>
</div>
</div>
);
}
}

export default App;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.Button {
background-color: #dadada;
border: none;
border-bottom: 2px solid #2d3a48;
border-right: 2px solid #2d3a48;
border-radius: 8px;
cursor: pointer;
padding: 0.5rem 1rem ;
}

.Button:hover {
background: #2d5b71;
}

.Button:focus {
outline: none;
}

.Button:active {
transform: scale(0.99);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';
import './index.css';

const Button = ({ children, onClick }) => (
<button type="button" onClick={onClick} className="Button">
{children}
</button>
);

Button.propTypes = {
children: PropTypes.node.isRequired,
onClick: PropTypes.func.isRequired,
};

export default Button;
28 changes: 28 additions & 0 deletions examples/react-recorder-volume-indicator/app/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
body {
background-color: #2db7dd;
color: #202020;
font-family: 'Fira Sans', sans-serif;
line-height: 1.4;
font-size: 16px;
font-weight: 300;
margin: 0;
padding: 0;
}

code {
background-color: #6ccde7;
color: #9b3a27;
font-family: 'Fira Mono', monospace;
font-weight: 400;
padding: 0 0.3rem;
}

pre {
background-color: #6ccde7;
padding: 1rem;
width: 100%;
}

p {
margin-top: 0;
}
7 changes: 7 additions & 0 deletions examples/react-recorder-volume-indicator/app/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import 'sanitize.css';
import './index.css';
import App from './components/App';

ReactDOM.render(<App />, document.getElementById('root'));
Binary file not shown.
22 changes: 22 additions & 0 deletions examples/react-recorder-volume-indicator/app/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="favicon.ico" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>React Volume Indicator App</title>

<link
href="https://fonts.googleapis.com/css?family=Fira+Mono:400|Fira+Sans:300,300i,500,500i,700,700i"
rel="stylesheet"
/>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="../dist/bundle.js"></script>
</body>
</html>
Loading

0 comments on commit 46de4bb

Please sign in to comment.