diff --git a/src/components/messages/AudioPlayer.vue b/src/components/messages/AudioPlayer.vue
index cf7472c..f0194b3 100644
--- a/src/components/messages/AudioPlayer.vue
+++ b/src/components/messages/AudioPlayer.vue
@@ -6,15 +6,22 @@
{{ currentTime }} / {{ totalTime }}
+
+
+
\ No newline at end of file
diff --git a/src/plugins/utils.js b/src/plugins/utils.js
index 56368b3..bdc8646 100644
--- a/src/plugins/utils.js
+++ b/src/plugins/utils.js
@@ -424,6 +424,9 @@ class Util {
promise
.then((response) => {
messageContent.url = response.content_uri;
+ return (msgtype == 'm.audio' ? this.generateWaveform(fileContents, messageContent) : true);
+ })
+ .then(() => {
return this.sendMessage(matrixClient, roomId, "m.room.message", messageContent)
})
.then(result => {
@@ -478,6 +481,9 @@ class Util {
return reject(response.error);
}
encryptedFile.url = response.content_uri;
+ return (msgtype == 'm.audio' ? this.generateWaveform(fileContents, messageContent) : true);
+ })
+ .then(() => {
return this.sendMessage(matrixClient, roomId, "m.room.message", messageContent)
})
.then(result => {
@@ -495,6 +501,51 @@ class Util {
return uploadPromise;
}
+ generateWaveform(data, messageContent) {
+ if (!(window.AudioContext || window.webkitAudioContext)) {
+ return; // No support
+ }
+ const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+ if (audioCtx) {
+ return audioCtx.decodeAudioData(data)
+ .then((audioBuffer) => {
+ const rawData = audioBuffer.getChannelData(0); // TODO - currently using only 1 channel
+ const samples = 1000; // Number of samples
+ const blockSize = Math.floor(rawData.length / samples);
+ let filteredData = [];
+ for (let i = 0; i < samples; i++) {
+ let blockStart = blockSize * i; // the location of the first sample in the block
+ let sum = 0;
+ for (let j = 0; j < blockSize; j++) {
+ sum = sum + Math.abs(rawData[blockStart + j]) // find the sum of all the samples in the block
+ }
+ filteredData.push(sum / blockSize); // divide the sum by the block size to get the average
+ }
+
+ // Normalize
+ const multiplier = Math.pow(Math.max(...filteredData), -1);
+ filteredData = filteredData.map(n => n * multiplier);
+
+ // Integerize
+ filteredData = filteredData.map(n => parseInt((n * 255).toFixed()));
+
+
+ // Generate SVG of waveform
+ let svg = `";
+
+ messageContent.format = "org.matrix.custom.html";
+ messageContent.formatted_body = svg;
+ })
+ }
+ }
+
/**
* Return what "mode" to use for the given room.
*