Skip to content

Commit

Permalink
Initial commit | Created waveform visualizer in electron
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaBragg committed Jun 18, 2021
0 parents commit 776445d
Show file tree
Hide file tree
Showing 14 changed files with 6,282 additions and 0 deletions.
89 changes: 89 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock
.DS_Store

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# Webpack
.webpack/

# Electron-Forge
out/
90 changes: 90 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"name": "volumonitor",
"productName": "volumonitor",
"version": "1.0.0",
"description": "My Electron application description",
"main": ".webpack/main",
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
"lint": "echo \"No linting configured\""
},
"keywords": [],
"author": {
"name": "Joshua Bragg",
"email": "[email protected]"
},
"license": "MIT",
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"name": "volumonitor"
}
},
{
"name": "@electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "@electron-forge/maker-deb",
"config": {}
},
{
"name": "@electron-forge/maker-rpm",
"config": {}
}
],
"plugins": [
[
"@electron-forge/plugin-webpack",
{
"mainConfig": "./webpack.main.config.js",
"renderer": {
"config": "./webpack.renderer.config.js",
"entryPoints": [
{
"html": "./src/index.html",
"js": "./src/index.tsx",
"name": "main_window"
}
]
}
}
]
]
}
},
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.57",
"@electron-forge/maker-deb": "^6.0.0-beta.57",
"@electron-forge/maker-rpm": "^6.0.0-beta.57",
"@electron-forge/maker-squirrel": "^6.0.0-beta.57",
"@electron-forge/maker-zip": "^6.0.0-beta.57",
"@electron-forge/plugin-webpack": "6.0.0-beta.57",
"@marshallofsound/webpack-asset-relocator-loader": "^0.5.0",
"css-loader": "^5.0.0",
"electron": "13.1.2",
"fork-ts-checker-webpack-plugin": "^6.2.10",
"node-loader": "^2.0.0",
"sass": "^1.35.1",
"sass-loader": "^12.1.0",
"style-loader": "^2.0.0",
"ts-loader": "^9.2.3",
"typescript": "^4.3.4"
},
"dependencies": {
"@types/react": "^17.0.11",
"@types/react-dom": "^17.0.8",
"electron-squirrel-startup": "^1.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
}
14 changes: 14 additions & 0 deletions src/App.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.app {
display: flex;
align-items: center;
width: 100%;
height: 200px;

div {
display: inline-block;
vertical-align: middle;
width: 1px;

background-color: red;
}
}
54 changes: 54 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { useEffect, useState } from 'react';
import './App.scss';

function App(): JSX.Element {
const [analyser, setAnalyser] = useState<AnalyserNode | null>(null);
const [freqData, setFreqData] = useState<Uint8Array>(new Uint8Array());

useEffect(() => {
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then((mediaStream: MediaStream) => {
const audioContext = new AudioContext();

const audioStream = audioContext.createMediaStreamSource(mediaStream);
const analyser = audioContext.createAnalyser();

audioStream.connect(analyser);

setAnalyser(analyser);
})
.catch((err) => {
console.error(err);
})
}, []);

useEffect(() => {
if (analyser) {
setInterval(() => {
const dataArray = new Uint8Array(analyser.frequencyBinCount);

analyser.getByteTimeDomainData(dataArray);

setFreqData(dataArray);
}, 5);
}
}, [analyser]);

const getFreqVisualization = (dataArray: Uint8Array): JSX.Element[] => {
const out: JSX.Element[] = [];

dataArray.forEach((data, i) => out.push(<div key={i} style={{ height: 2 * (data - 127) }}></div>));

return out;
}

return (
<div className="app">
{
getFreqVisualization(freqData)
}
</div>
);
}

export default App;
13 changes: 13 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<title>VoluMonitor</title>
</head>

<body>
<div id="root"></div>
</body>

</html>
10 changes: 10 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
46 changes: 46 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const { app, BrowserWindow } = require('electron');
const path = require('path');

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) { // eslint-disable-line global-require
app.quit();
}

const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
});

// and load the index.html of the app.
mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);

// Open the DevTools.
mainWindow.webContents.openDevTools();
};

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.
31 changes: 31 additions & 0 deletions src/renderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* This file will automatically be loaded by webpack and run in the "renderer" context.
* To learn more about the differences between the "main" and the "renderer" context in
* Electron, visit:
*
* https://electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes
*
* By default, Node.js integration in this file is disabled. When enabling Node.js integration
* in a renderer process, please be aware of potential security implications. You can read
* more about security risks here:
*
* https://electronjs.org/docs/tutorial/security
*
* To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration`
* flag:
*
* ```
* // Create the browser window.
* mainWindow = new BrowserWindow({
* width: 800,
* height: 600,
* webPreferences: {
* nodeIntegration: true
* }
* });
* ```
*/

import './index.css';

console.log('👋 This message is being logged by "renderer.js", included via webpack');
25 changes: 25 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": [
"src"
]
}
14 changes: 14 additions & 0 deletions webpack.main.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
/**
* This is the main entry point for your application, it's the first file
* that runs in the main process.
*/
entry: './src/main.js',
// Put your normal webpack config below here
module: {
rules: require('./webpack.rules'),
},
resolve: {
extensions: ['.js', '.ts', '.jsx', '.tsx', '.css', '.scss']
},
};
Loading

0 comments on commit 776445d

Please sign in to comment.