Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add volumemeter example #344

Merged
merged 3 commits into from
Apr 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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