recording+playback+sending works correctly

This commit is contained in:
or-else
2022-03-16 16:19:09 -07:00
parent afea2aeec0
commit d0c4251eda
8 changed files with 112 additions and 79 deletions
+14 -11
View File
@@ -2650,9 +2650,14 @@ ul.tabbar li.active > a {
border-radius: 1.5rem; border-radius: 1.5rem;
} }
.audio canvas.visualiser { .audio canvas {
width: 12rem; width: 14rem;
height: 2.6rem; height: 2.6rem;
margin-right: 2rem;
}
.audio canvas.playback {
margin-right: 0;
} }
.audio .duration { .audio .duration {
@@ -2665,8 +2670,8 @@ ul.tabbar li.active > a {
} }
.audio-player .material-icons.large { .audio-player .material-icons.large {
font-size: 2.5rem; font-size: 2.4rem;
color: #009688; color: #667575;
} }
.audio-player .material-icons.disabled { .audio-player .material-icons.disabled {
@@ -2674,16 +2679,16 @@ ul.tabbar li.active > a {
cursor: default; cursor: default;
} }
.audio-player .visualiser { .audio-player .playback {
width: 12rem; width: 14rem;
height: 2.6rem; height: 2.6rem;
} }
.audio-player canvas.visualiser { .audio-player canvas.playback {
display: block; display: block;
} }
.audio-player div.visualiser { .audio-player div.playback {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -2692,9 +2697,7 @@ ul.tabbar li.active > a {
} }
.audio-player .timer { .audio-player .timer {
font-size: small; font-size: smaller;
float: right;
padding-right: 7.4rem;
color: #666; color: #666;
} }
+1 -1
View File
File diff suppressed because one or more lines are too long
+16 -15
View File
@@ -12,13 +12,10 @@ const CANVAS_UPSCALING = 2.0;
const LINE_WIDTH = 3 * CANVAS_UPSCALING; const LINE_WIDTH = 3 * CANVAS_UPSCALING;
// Spacing between two visualization bars. // Spacing between two visualization bars.
const SPACING = 2 * CANVAS_UPSCALING; const SPACING = 2 * CANVAS_UPSCALING;
// Color of histogram bars (base color #009688). // Color of histogram bars.
const BAR_COLOR = '#85c7c5'; const BAR_COLOR = '#bbb';
const BAR_COLOR_DARK = '#559695'; const BAR_COLOR_DARK = '#888';
const THUMB_COLOR = '#246867'; const THUMB_COLOR = '#666';
// Background color
const BKG_COLOR = '#fff';
// Minimum number of amplitude bars to draw. // Minimum number of amplitude bars to draw.
const MIN_PREVIEW_LENGTH = 16; const MIN_PREVIEW_LENGTH = 16;
@@ -36,6 +33,7 @@ export default class AudioPlayer extends React.PureComponent {
playing: false, playing: false,
currentTime: '0:00', currentTime: '0:00',
duration: this.props.duration > 0 ? secondsToTime(this.props.duration / 1000) : '-:--', duration: this.props.duration > 0 ? secondsToTime(this.props.duration / 1000) : '-:--',
longMin: this.props.duration >= 600000,
preview: preview preview: preview
}; };
@@ -91,10 +89,12 @@ export default class AudioPlayer extends React.PureComponent {
initAudio() { initAudio() {
this.audioPlayer = new Audio(this.props.src); this.audioPlayer = new Audio(this.props.src);
this.audioPlayer.oncanplay = _ => this.setState({canPlay: true}); this.audioPlayer.oncanplay = _ => this.setState({canPlay: true});
this.audioPlayer.ontimeupdate = _ => this.setState({currentTime: secondsToTime(this.audioPlayer.currentTime)}); this.audioPlayer.ontimeupdate = _ => this.setState({
currentTime: secondsToTime(this.audioPlayer.currentTime, this.state.longMin)
});
this.audioPlayer.onended = _ => { this.audioPlayer.onended = _ => {
this.audioPlayer.currentTime = 0; this.audioPlayer.currentTime = 0;
this.setState({playing: false, currentTime: secondsToTime(0)}) this.setState({playing: false, currentTime: secondsToTime(0, this.state.longMin)})
} }
} }
@@ -220,7 +220,7 @@ export default class AudioPlayer extends React.PureComponent {
const rect = e.target.getBoundingClientRect(); const rect = e.target.getBoundingClientRect();
const offset = (e.clientX - rect.left) / this.effectiveWidth * CANVAS_UPSCALING; const offset = (e.clientX - rect.left) / this.effectiveWidth * CANVAS_UPSCALING;
this.audioPlayer.currentTime = this.props.duration * offset / 1000; this.audioPlayer.currentTime = this.props.duration * offset / 1000;
this.setState({currentTime: secondsToTime(this.audioPlayer.currentTime)}); this.setState({currentTime: secondsToTime(this.audioPlayer.currentTime, this.state.longMin)});
if (!this.state.playing && this.state.preview) { if (!this.state.playing && this.state.preview) {
this.visualize(); this.visualize();
} }
@@ -232,14 +232,15 @@ export default class AudioPlayer extends React.PureComponent {
(this.props.short ? '' : ' large') + (this.props.short ? '' : ' large') +
(this.state.canPlay ? '' : ' disabled'); (this.state.canPlay ? '' : ' disabled');
const play = (<a href="#" onClick={this.handlePlay} title="Play"> const play = (<a href="#" onClick={this.handlePlay} title="Play">
<i className={playClass}>{this.state.playing ? 'pause_circle' : 'play_circle'}</i> <i className={playClass}>{this.state.playing ? 'pause_circle' :
(this.state.canPlay ? 'play_circle' : 'not_interested')}</i>
</a>); </a>);
return (<div className="audio-player">{this.props.short ? return (<div className="audio-player">{this.props.short ?
<> <>
<div> <div>
{this.state.preview ? {this.state.preview ?
<canvas className="visualiser" ref={this.canvasRef} onClick={this.handleSeek} /> : <canvas className="playback" ref={this.canvasRef} onClick={this.handleSeek} /> :
<div className="visualiser"> - </div> <div className="playback"> - </div>
} }
</div> </div>
{play} {play}
@@ -249,8 +250,8 @@ export default class AudioPlayer extends React.PureComponent {
{play} {play}
<div> <div>
{this.state.preview ? {this.state.preview ?
<canvas className="visualiser" ref={this.canvasRef} onClick={this.handleSeek} /> : <canvas className="playback" ref={this.canvasRef} onClick={this.handleSeek} /> :
<div className="visualiser"> <div className="playback">
<FormattedMessage <FormattedMessage
id="preview_unavailable" defaultMessage="unavailable" description="Message shown when media preview is not available" /> id="preview_unavailable" defaultMessage="unavailable" description="Message shown when media preview is not available" />
</div> </div>
+39 -21
View File
@@ -9,24 +9,26 @@ import { secondsToTime } from '../lib/strformat';
// FFT resolution. // FFT resolution.
const BUFFER_SIZE = 256; const BUFFER_SIZE = 256;
// Make canvas bigger than the element size to reduce blurring.
const CANVAS_UPSCALING = 2.0;
// Thickness of a visualization bar. // Thickness of a visualization bar.
const LINE_WIDTH = 4; const LINE_WIDTH = 3 * CANVAS_UPSCALING;
// Spacing between two visualization bars. // Spacing between two visualization bars.
const SPACING = 2; const SPACING = 2 * CANVAS_UPSCALING;
// Duration represented by one visualization bar. // Duration represented by one visualization bar.
const MILLIS_PER_BAR = 100; const MILLIS_PER_BAR = 100;
// Color of histogram bars // Color of histogram bars
const BAR_COLOR = '#8fbed6'; const BAR_COLOR = '#bbb';
// Scaling for visualization bars. // Vertical scaling for visualization bars.
const BAR_SCALE = 64.0; const BAR_SCALE = 64.0;
// Background color
const BKG_COLOR = '#eeeeee';
// Minimum duration of a recording in milliseconds. // Minimum duration of a recording in milliseconds.
const MIN_DURATION = 200; const MIN_DURATION = 200;
// Maximum duration of a recording in milliseconds (10 min). // Maximum duration of a recording in milliseconds (10 min).
const MAX_DURATION = 600000; const MAX_DURATION = 600000;
// Number of bars in preview. // Number of bars in preview.
const VISUALIZATION_BARS = 96; const VISUALIZATION_BARS = 96;
// Maximum number of samples per bar.
const MAX_SAMPLES_PER_BAR = 10;
export default class AudioRecorder extends React.PureComponent { export default class AudioRecorder extends React.PureComponent {
constructor(props) { constructor(props) {
@@ -44,6 +46,7 @@ export default class AudioRecorder extends React.PureComponent {
this.visualize = this.visualize.bind(this); this.visualize = this.visualize.bind(this);
this.initMediaRecording = this.initMediaRecording.bind(this); this.initMediaRecording = this.initMediaRecording.bind(this);
this.initCanvas = this.initCanvas.bind(this);
this.getRecording = this.getRecording.bind(this); this.getRecording = this.getRecording.bind(this);
this.cleanUp = this.cleanUp.bind(this); this.cleanUp = this.cleanUp.bind(this);
@@ -59,11 +62,6 @@ export default class AudioRecorder extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
this.canvasContext = this.canvasRef.current.getContext('2d');
this.canvasContext.lineCap = 'round';
// To reduce line blurring.
this.canvasContext.translate(0.5, 0.5);
this.stream = null; this.stream = null;
this.mediaRecorder = null; this.mediaRecorder = null;
this.audioContext = null; this.audioContext = null;
@@ -82,13 +80,16 @@ export default class AudioRecorder extends React.PureComponent {
// Draw amplitude of sound. // Draw amplitude of sound.
visualize() { visualize() {
this.initCanvas();
const pcmData = new Uint8Array(this.analyser.frequencyBinCount); const pcmData = new Uint8Array(this.analyser.frequencyBinCount);
const width = this.canvasRef.current.width; const width = this.canvasWidth;
const height = this.canvasRef.current.height; const height = this.canvasHeight;
// Number of bars.
const viewLength = (width / (LINE_WIDTH + SPACING)) | 0; const viewLength = (width / (LINE_WIDTH + SPACING)) | 0;
// Duration of audio which fits onto the screen.
const viewDuration = MILLIS_PER_BAR * viewLength; const viewDuration = MILLIS_PER_BAR * viewLength;
this.canvasContext.fillStyle = BKG_COLOR;
this.canvasContext.lineWidth = LINE_WIDTH; this.canvasContext.lineWidth = LINE_WIDTH;
this.canvasContext.strokeStyle = BAR_COLOR; this.canvasContext.strokeStyle = BAR_COLOR;
@@ -144,7 +145,7 @@ export default class AudioRecorder extends React.PureComponent {
} }
// Clear canvas. // Clear canvas.
this.canvasContext.fillRect(0, 0, width, height); this.canvasContext.clearRect(0, 0, width, height);
// Draw amplitude bars. // Draw amplitude bars.
this.canvasContext.beginPath(); this.canvasContext.beginPath();
@@ -202,6 +203,18 @@ export default class AudioRecorder extends React.PureComponent {
} }
} }
initCanvas() {
this.canvasRef.current.width = this.canvasRef.current.offsetWidth * CANVAS_UPSCALING;
this.canvasRef.current.height = this.canvasRef.current.offsetHeight * CANVAS_UPSCALING;
this.canvasContext = this.canvasRef.current.getContext('2d');
this.canvasContext.lineCap = 'round';
// To reduce line blurring.
this.canvasContext.translate(0.5, 0.5);
this.canvasWidth = this.canvasRef.current.width;
this.canvasHeight = this.canvasRef.current.height;
}
initMediaRecording(stream) { initMediaRecording(stream) {
this.stream = stream; this.stream = stream;
this.mediaRecorder = new MediaRecorder(stream); this.mediaRecorder = new MediaRecorder(stream);
@@ -260,16 +273,21 @@ export default class AudioRecorder extends React.PureComponent {
const data = audio.getChannelData(0); const data = audio.getChannelData(0);
// Number of amplitude bars in preview. // Number of amplitude bars in preview.
const viewLength = Math.min(data.length, VISUALIZATION_BARS); const viewLength = Math.min(data.length, VISUALIZATION_BARS);
// The number of samples in each bar. Limit the number of samples to something reasonable, no need to process all. // The number of samples in each bar.
const spb = Math.min(100, (data.length / viewLength) | 0); const totalSPB = (data.length / viewLength) | 0;
// Distance between samples: we are going to take just a fracton of samples.
const samplingRate = Math.max(1, (totalSPB / MAX_SAMPLES_PER_BAR) | 0);
let buffer = []; let buffer = [];
let max = -1; let max = -1;
for (let i = 0; i < viewLength; i++) { for (let i = 0; i < viewLength; i++) {
let amplitude = 0; let amplitude = 0;
for (let j = 0; j < spb; j++) { let count = 0;
amplitude += data[spb * i + j] ** 2; for (let j = 0; j < totalSPB; j += samplingRate) {
amplitude += data[totalSPB * i + j] ** 2;
count ++;
} }
const val = Math.sqrt(amplitude / spb); const val = Math.sqrt(amplitude / count);
buffer.push(val); buffer.push(val);
max = Math.max(max, val); max = Math.max(max, val);
} }
@@ -293,7 +311,7 @@ export default class AudioRecorder extends React.PureComponent {
<i className="material-icons">delete_outline</i> <i className="material-icons">delete_outline</i>
</a> </a>
{this.state.recording ? {this.state.recording ?
<canvas className="visualiser" ref={this.canvasRef} /> <canvas ref={this.canvasRef} />
: :
<AudioPlayer <AudioPlayer
src={this.state.blobUrl} src={this.state.blobUrl}
+39 -28
View File
@@ -9681,10 +9681,9 @@ __webpack_require__.r(__webpack_exports__);
const CANVAS_UPSCALING = 2.0; const CANVAS_UPSCALING = 2.0;
const LINE_WIDTH = 3 * CANVAS_UPSCALING; const LINE_WIDTH = 3 * CANVAS_UPSCALING;
const SPACING = 2 * CANVAS_UPSCALING; const SPACING = 2 * CANVAS_UPSCALING;
const BAR_COLOR = '#85c7c5'; const BAR_COLOR = '#bbb';
const BAR_COLOR_DARK = '#559695'; const BAR_COLOR_DARK = '#888';
const THUMB_COLOR = '#246867'; const THUMB_COLOR = '#666';
const BKG_COLOR = '#fff';
const MIN_PREVIEW_LENGTH = 16; const MIN_PREVIEW_LENGTH = 16;
class AudioPlayer extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { class AudioPlayer extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
constructor(props) { constructor(props) {
@@ -9700,6 +9699,7 @@ class AudioPlayer extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComp
playing: false, playing: false,
currentTime: '0:00', currentTime: '0:00',
duration: this.props.duration > 0 ? (0,_lib_strformat__WEBPACK_IMPORTED_MODULE_2__.secondsToTime)(this.props.duration / 1000) : '-:--', duration: this.props.duration > 0 ? (0,_lib_strformat__WEBPACK_IMPORTED_MODULE_2__.secondsToTime)(this.props.duration / 1000) : '-:--',
longMin: this.props.duration >= 600000,
preview: preview preview: preview
}; };
this.initAudio = this.initAudio.bind(this); this.initAudio = this.initAudio.bind(this);
@@ -9760,14 +9760,14 @@ class AudioPlayer extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComp
}); });
this.audioPlayer.ontimeupdate = _ => this.setState({ this.audioPlayer.ontimeupdate = _ => this.setState({
currentTime: (0,_lib_strformat__WEBPACK_IMPORTED_MODULE_2__.secondsToTime)(this.audioPlayer.currentTime) currentTime: (0,_lib_strformat__WEBPACK_IMPORTED_MODULE_2__.secondsToTime)(this.audioPlayer.currentTime, this.state.longMin)
}); });
this.audioPlayer.onended = _ => { this.audioPlayer.onended = _ => {
this.audioPlayer.currentTime = 0; this.audioPlayer.currentTime = 0;
this.setState({ this.setState({
playing: false, playing: false,
currentTime: (0,_lib_strformat__WEBPACK_IMPORTED_MODULE_2__.secondsToTime)(0) currentTime: (0,_lib_strformat__WEBPACK_IMPORTED_MODULE_2__.secondsToTime)(0, this.state.longMin)
}); });
}; };
} }
@@ -9894,7 +9894,7 @@ class AudioPlayer extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComp
const offset = (e.clientX - rect.left) / this.effectiveWidth * CANVAS_UPSCALING; const offset = (e.clientX - rect.left) / this.effectiveWidth * CANVAS_UPSCALING;
this.audioPlayer.currentTime = this.props.duration * offset / 1000; this.audioPlayer.currentTime = this.props.duration * offset / 1000;
this.setState({ this.setState({
currentTime: (0,_lib_strformat__WEBPACK_IMPORTED_MODULE_2__.secondsToTime)(this.audioPlayer.currentTime) currentTime: (0,_lib_strformat__WEBPACK_IMPORTED_MODULE_2__.secondsToTime)(this.audioPlayer.currentTime, this.state.longMin)
}); });
if (!this.state.playing && this.state.preview) { if (!this.state.playing && this.state.preview) {
@@ -9911,21 +9911,21 @@ class AudioPlayer extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComp
title: "Play" title: "Play"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: playClass className: playClass
}, this.state.playing ? 'pause_circle' : 'play_circle')); }, this.state.playing ? 'pause_circle' : this.state.canPlay ? 'play_circle' : 'not_interested'));
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "audio-player" className: "audio-player"
}, this.props.short ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null, this.state.preview ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("canvas", { }, this.props.short ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null, this.state.preview ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("canvas", {
className: "visualiser", className: "playback",
ref: this.canvasRef, ref: this.canvasRef,
onClick: this.handleSeek onClick: this.handleSeek
}) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "visualiser" className: "playback"
}, " - ")), play) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, play, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null, this.state.preview ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("canvas", { }, " - ")), play) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, play, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null, this.state.preview ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("canvas", {
className: "visualiser", className: "playback",
ref: this.canvasRef, ref: this.canvasRef,
onClick: this.handleSeek onClick: this.handleSeek
}) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "visualiser" className: "playback"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
id: "preview_unavailable", id: "preview_unavailable",
defaultMessage: [{ defaultMessage: [{
@@ -9962,15 +9962,16 @@ __webpack_require__.r(__webpack_exports__);
const BUFFER_SIZE = 256; const BUFFER_SIZE = 256;
const LINE_WIDTH = 4; const CANVAS_UPSCALING = 2.0;
const SPACING = 2; const LINE_WIDTH = 3 * CANVAS_UPSCALING;
const SPACING = 2 * CANVAS_UPSCALING;
const MILLIS_PER_BAR = 100; const MILLIS_PER_BAR = 100;
const BAR_COLOR = '#8fbed6'; const BAR_COLOR = '#bbb';
const BAR_SCALE = 64.0; const BAR_SCALE = 64.0;
const BKG_COLOR = '#eeeeee';
const MIN_DURATION = 200; const MIN_DURATION = 200;
const MAX_DURATION = 600000; const MAX_DURATION = 600000;
const VISUALIZATION_BARS = 96; const VISUALIZATION_BARS = 96;
const MAX_SAMPLES_PER_BAR = 10;
class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
constructor(props) { constructor(props) {
super(props); super(props);
@@ -9985,6 +9986,7 @@ class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
}; };
this.visualize = this.visualize.bind(this); this.visualize = this.visualize.bind(this);
this.initMediaRecording = this.initMediaRecording.bind(this); this.initMediaRecording = this.initMediaRecording.bind(this);
this.initCanvas = this.initCanvas.bind(this);
this.getRecording = this.getRecording.bind(this); this.getRecording = this.getRecording.bind(this);
this.cleanUp = this.cleanUp.bind(this); this.cleanUp = this.cleanUp.bind(this);
this.handleResume = this.handleResume.bind(this); this.handleResume = this.handleResume.bind(this);
@@ -9998,9 +10000,6 @@ class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
} }
componentDidMount() { componentDidMount() {
this.canvasContext = this.canvasRef.current.getContext('2d');
this.canvasContext.lineCap = 'round';
this.canvasContext.translate(0.5, 0.5);
this.stream = null; this.stream = null;
this.mediaRecorder = null; this.mediaRecorder = null;
this.audioContext = null; this.audioContext = null;
@@ -10019,12 +10018,12 @@ class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
} }
visualize() { visualize() {
this.initCanvas();
const pcmData = new Uint8Array(this.analyser.frequencyBinCount); const pcmData = new Uint8Array(this.analyser.frequencyBinCount);
const width = this.canvasRef.current.width; const width = this.canvasWidth;
const height = this.canvasRef.current.height; const height = this.canvasHeight;
const viewLength = width / (LINE_WIDTH + SPACING) | 0; const viewLength = width / (LINE_WIDTH + SPACING) | 0;
const viewDuration = MILLIS_PER_BAR * viewLength; const viewDuration = MILLIS_PER_BAR * viewLength;
this.canvasContext.fillStyle = BKG_COLOR;
this.canvasContext.lineWidth = LINE_WIDTH; this.canvasContext.lineWidth = LINE_WIDTH;
this.canvasContext.strokeStyle = BAR_COLOR; this.canvasContext.strokeStyle = BAR_COLOR;
let prevBarCount = 0; let prevBarCount = 0;
@@ -10076,7 +10075,7 @@ class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
} }
} }
this.canvasContext.fillRect(0, 0, width, height); this.canvasContext.clearRect(0, 0, width, height);
this.canvasContext.beginPath(); this.canvasContext.beginPath();
for (let i = 0; i < this.viewBuffer.length; i++) { for (let i = 0; i < this.viewBuffer.length; i++) {
@@ -10142,6 +10141,16 @@ class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
} }
} }
initCanvas() {
this.canvasRef.current.width = this.canvasRef.current.offsetWidth * CANVAS_UPSCALING;
this.canvasRef.current.height = this.canvasRef.current.offsetHeight * CANVAS_UPSCALING;
this.canvasContext = this.canvasRef.current.getContext('2d');
this.canvasContext.lineCap = 'round';
this.canvasContext.translate(0.5, 0.5);
this.canvasWidth = this.canvasRef.current.width;
this.canvasHeight = this.canvasRef.current.height;
}
initMediaRecording(stream) { initMediaRecording(stream) {
this.stream = stream; this.stream = stream;
this.mediaRecorder = new MediaRecorder(stream); this.mediaRecorder = new MediaRecorder(stream);
@@ -10198,18 +10207,21 @@ class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
createPreview(audio) { createPreview(audio) {
const data = audio.getChannelData(0); const data = audio.getChannelData(0);
const viewLength = Math.min(data.length, VISUALIZATION_BARS); const viewLength = Math.min(data.length, VISUALIZATION_BARS);
const spb = Math.min(100, data.length / viewLength | 0); const totalSPB = data.length / viewLength | 0;
const samplingRate = Math.max(1, totalSPB / MAX_SAMPLES_PER_BAR | 0);
let buffer = []; let buffer = [];
let max = -1; let max = -1;
for (let i = 0; i < viewLength; i++) { for (let i = 0; i < viewLength; i++) {
let amplitude = 0; let amplitude = 0;
let count = 0;
for (let j = 0; j < spb; j++) { for (let j = 0; j < totalSPB; j += samplingRate) {
amplitude += data[spb * i + j] ** 2; amplitude += data[totalSPB * i + j] ** 2;
count++;
} }
const val = Math.sqrt(amplitude / spb); const val = Math.sqrt(amplitude / count);
buffer.push(val); buffer.push(val);
max = Math.max(max, val); max = Math.max(max, val);
} }
@@ -10237,7 +10249,6 @@ class AudioRecorder extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons" className: "material-icons"
}, "delete_outline")), this.state.recording ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("canvas", { }, "delete_outline")), this.state.recording ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("canvas", {
className: "visualiser",
ref: this.canvasRef ref: this.canvasRef
}) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_audio_player_jsx__WEBPACK_IMPORTED_MODULE_1__["default"], { }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_audio_player_jsx__WEBPACK_IMPORTED_MODULE_1__["default"], {
src: this.state.blobUrl, src: this.state.blobUrl,
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long