Skip to content

Instantly share code, notes, and snippets.

@apeckham
Last active November 28, 2024 02:41
Show Gist options
  • Save apeckham/2db891e45d0649eda10748c9d22be4ca to your computer and use it in GitHub Desktop.
Save apeckham/2db891e45d0649eda10748c9d22be4ca to your computer and use it in GitHub Desktop.
custom appsmith component for wavesurfer audio player
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap');
/* Waveform container styling */
#root {
background-color: #f9f9f9;
}
body {
font-family: 'Montserrat', sans-serif;
}
/* Button styling */
button {
background-color: #4F4A85;
color: white;
border: none;
font-family: 'Montserrat';
border-radius: 5px;
padding: 10px 20px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: background-color 0.3s ease, transform 0.2s ease;
}
button:active {
transform: translateY(1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
<div style="padding: 10px;">
<div id="root" style="margin-bottom: 5px;"></div>
<div style="display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px;">
<!-- Left Section: Start/Stop Buttons -->
<div style="display: flex; gap: 5px;">
<button id="startButton">Start</button>
<button id="stopButton">Stop</button>
</div>
<!-- Right Section: Playback Controls -->
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 10px;">
<label for="speedControl" style="white-space: nowrap;"><span id="speedValue">1.0x</span></label>
<input id="speedControl" type="range" min="0.5" max="2" step="0.1" value="1" style="min-width: 100px;">
<div style="white-space: nowrap;">
<span id="currentTime" style="font-family: monospace;">0:00</span> /
<span id="totalTime" style="font-family: monospace;">0:00</span>
</div>
</div>
</div>
</div>
import WaveSurfer from 'https://cdn.jsdelivr.net/npm/wavesurfer.js@7/dist/wavesurfer.esm.js';
let wavesurfer;
appsmith.onReady(() => {
// Function to initialize WaveSurfer
const initializeWaveSurfer = (url) => {
if (wavesurfer) {
wavesurfer.destroy();
}
wavesurfer = WaveSurfer.create({
container: '#root',
waveColor: '#4F4A85',
progressColor: '#383351',
url: url,
});
// Update total duration when the file is ready
wavesurfer.on('ready', () => {
const totalDuration = wavesurfer.getDuration();
document.getElementById('totalTime').textContent = formatTime(totalDuration);
});
// Update current playback time during playback
wavesurfer.on('audioprocess', () => {
const currentTime = wavesurfer.getCurrentTime();
document.getElementById('currentTime').textContent = formatTime(currentTime);
});
// Reset time when playback finishes
wavesurfer.on('finish', () => {
document.getElementById('currentTime').textContent = formatTime(0);
});
// Add button event listeners
document.getElementById('startButton').addEventListener('click', () => {
wavesurfer.play();
});
document.getElementById('stopButton').addEventListener('click', () => {
wavesurfer.pause();
});
// Playback speed control
document.getElementById('speedControl').addEventListener('input', (event) => {
const speed = parseFloat(event.target.value);
wavesurfer.setPlaybackRate(speed);
document.getElementById('speedValue').textContent = `${speed.toFixed(1)}x`;
});
};
// Utility to format time in MM:SS
const formatTime = (seconds) => {
const minutes = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${minutes}:${secs.toString().padStart(2, '0')}`;
};
// Listen for model changes and initialize WaveSurfer when the URL is available
appsmith.onModelChange((newModel) => {
if (newModel.url) {
console.log("Initializing WaveSurfer with URL:", newModel.url);
initializeWaveSurfer(newModel.url);
} else {
console.log("URL not available yet. Waiting for next model update...");
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment