Closed prodbyola closed 2 years ago
Try setting a fixed width and height on your image component? Either in js
or css
.
<canvas id='sketch' />
style {
#sketch {
width: 400px;
height: 400px;
}
}
}
Try setting a fixed width and height on your image component? Either in
js
orcss
.<canvas id='sketch' />
style { #sketch { width: 400px; height: 400px; } }
}
@jamesb93 thanks for the reply. I'm working with the example code on the homepage of this repo. HTML like
<div id="overview-container"></div>
<audio>
<source src="sample.mp3" type="audio/mpeg">
<source src="sample.ogg" type="audio/ogg">
</audio> ```
and in JS:
```js
import Peaks from 'peaks.js';
const options = {
zoomview: {
container: document.getElementById('zoomview-container')
},
overview: {
container: document.getElementById('overview-container')
},
mediaElement: document.querySelector('audio'),
dataUri: {
arraybuffer: 'sample.dat' // or json: 'sample.json'
}
};
Peaks.init(options, function(err, peaks) {
console.log(err, peaks) //
}); ```
So are you suggesting I manually add a canvas within the ***zoomview*** and ***overview*** containers? I just wanted to be clear about your response. Thank you!
The library includes a check that the container element width is non-zero, so I'm not sure why you're getting this error. Can you share a complete minimal example to help figure out what's happening?
So are you suggesting I manually add a canvas within the zoomview and overview containers?
There's no need to create your own canvas, Peaks.js will create those itself within your container div.
This is an example of mine (albeit in SvelteKit). It's a bit busy but it shows you the necessary js and HTML to get to something that works in a component.
<script>
import { onMount } from "svelte";
import Container from '$lib/components/Container.svelte';
import Button from '$lib/components/Button.svelte';
import { noext, cloudPrefix } from '$lib/utility/paths.js';
export let segments;
export let points;
export let title = "title";
export let caption = "";
export let file;
export let peaks;
export let id = "";
const noExtension = noext(file);
const lossless = cloudPrefix + noExtension + '.wav'
// Form path to lossless download
let Peaks, instance, overview, zoom, audio, controls, peaksControls;
let lastSelected = 0;
const convert = (time) => {
const date = new Date(time * 1000).toISOString().substr(11, 8)
return date.toString().substr(3);
}
onMount (async()=>{
const module = await import("peaks.js");
Peaks = module.default;
const options = {
containers: {
zoomview: zoom,
overview: overview
},
dataUri: {
arraybuffer: peaks
},
mediaElement: audio,
zoomWaveformColor: 'rgba(0, 30, 128, 0.61)',
overviewWaveformColor: 'rgba(0, 15, 100, 0.3)',
overviewHighlightColor: 'grey',
playheadColor: 'rgba(0, 0, 0, 1)',
playheadTextColor: '#aaa',
showPlayheadTime: false,
pointMarkerColor: '#FF0000',
axisGridlineColor: '#ccc',
axisLabelColor: '#aaa',
randomizeSegmentColor: true,
segments: segments,
points: points
}
instance = Peaks.init(options, (err, p) => {
if (err) {
console.log(err)
} else {
instance = p
instance.views.getView('overview').fitToContainer();
}
});
});
function clickHandler(segment, i) {
instance.player.seek(segment.startTime)
lastSelected = i
}
</script>
<Container id={id}>
<div class="horizontal">
<span id="title">{title}</span>
<span id="caption">{caption}</span>
</div>
<div class="vis">
<div id='waveform-overview' bind:this={overview} />
<div id='waveform-zoom' bind:this={zoom} />
</div>
<div class="peaks-controls" bind:this={peaksControls}>
<audio controls bind:this={audio}>
<source src={file} type="audio/mp3">
<track kind="captions">
</audio>
<div bind:this={controls} class="audio-controls">
<Button clickHandler={ () => instance.zoom.zoomIn() } text="+" />
<Button clickHandler={ () => instance.zoom.zoomOut() } text="-" />
</div>
</div>
{#if segments}
<ul class="segments">
<span id="timecodes">List of referenced time codes</span>
{#each segments as segment, i}
<div class:selected={ lastSelected === i } class='timecode' on:click={ () => clickHandler(segment, i) }>
<span id='time'>{convert(segment.startTime)} - {convert(segment.endTime)}</span>
<span id="label">{segment.labelText}</span>
</div>
{/each}
</ul>
{/if}
<div id='lossless'>
<a rel='external' id='lossless-link' href={lossless} download>
Download Lossless Version
</a>
</div>
</Container>
<style>
#waveform-overview {
height: 65px;
}
#lossless {
margin-top: 10px;
}
#lossless-link {
font-style: italic;
text-align: left;
color: rgb(96, 96, 96);
}
#lossless-link:hover {
background-color: var(--dark-blue);
color: white;
}
.audio-controls {
display: flex;
flex-direction: row;
}
#title {
text-align: left;
font-weight: bold;
}
.timecode {
display: flex;
flex-direction: row;
justify-content: space-between;
word-wrap: none;
border-top: 1px rgb(197, 197, 197) solid;
gap: 3%;
}
.timecode:hover {
background-color: rgb(240, 240, 240);
}
.timecode:active {
background-color: rgb(199, 199, 199);
}
#time {
white-space: nowrap;
}
#label {
color: grey;
text-align: right;
}
#caption{
font-style: italic;
min-width: max-content;
}
.horizontal {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 10%;
padding-bottom: 15px;
}
.vis {
padding-bottom: 5px;
display: flex;
flex-direction: column;
gap: 5px;
}
.peaks-controls {
display: flex;
justify-content: space-between;
padding-top: 3px;
align-items: center;
}
a {
color: black
}
a:hover {
background-color: inherit;
text-decoration: none;
}
.selected {
font-weight: bold;
}
.segments {
padding-top: 5px;
margin-top: 1em;
padding-left: 1em;
padding-right: 1em;
border-top: 1px rgb(197, 197, 197) solid;
}
</style>
@jamesb93 and @chrisn thanks for the help. It actually did work after I created the canvas manually!
Thanks, I'll close this. If anyone else finds this error, please re-open and we can investigate.
I just ran into this issue. Trying to render a simple example resulted in the error. Adding <canvas>
manually to the zoomview-container
and overview-container
fixed the issue.
Testing in Chrome Version 104.0.5112.101.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Peaks.js Demo Page</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>Test Audio</h1>
<div id="zoomview-container"><canvas></canvas></div>
<div id="overview-container"><canvas></canvas></div>
<audio>
<source src="sample.mp3" type="audio/mpeg">
<source src="sample.ogg" type='audio/ogg codecs="vorbis"'>
</audio>
</body>
<script src="index.js" type="module"></script>
</html>
index.js
import Peaks from 'peaks.js';
const audioContext = new AudioContext();
const options = {
zoomview: {
container: document.getElementById('zoomview-container')
},
overview: {
container: document.getElementById('overview-container')
},
mediaElement: document.querySelector('audio'),
webAudio: {
audioContext: audioContext,
scale: 128,
multiChannel: true
}
};
Peaks.init(options, function(err, peaks) {
// Do something when the waveform is displayed and ready
console.log("Ready to create!")
});
package.json
{
"name": "test-audio",
"version": "1.0.0",
"description": "Test Waveform App",
"source": "src/index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": {
"start": "parcel src/index.html -p 3000 --open",
"build:parcel": "parcel build ./src/index.html --public-url ./ --no-source-maps",
"build": "npm run clean && npm run build:parcel",
"clean": "rm -rf dist/*"
},
"keywords": [
"audio",
"webaudio"
],
"author": "Chris Morris",
"license": "MIT",
"devDependencies": {
"parcel": "^2.7.0"
},
"dependencies": {
"konva": "^8.3.11",
"peaks.js": "^2.0.5",
"waveform-data": "^4.3.0"
}
}
Thanks @ChrisMorrisDev, your example works fine for me (with an empty style.css file), using Chrome 104.0.5112.102. You shouldn't need to create a canvas element. Do your container divs have non-zero width and height at the time you call Peaks.init()
?
Ignore the above, removing the canvas elements causes the error. I'll investigate...
Peaks.init()
was only checking the container element width, so I have just changed it to also check the height. This means you will now get a more meaningful error message, provided you check the err
value in the callback as it won't appear as an uncaught exception.
The reason adding a canvas element inside the container works, is that the default height of a canvas element is 150, which forces the container to have non-zero height.
Thank you! Your code example helped identify what was happening.
Makes perfect sense. Thank you!
Hey,
I am having a hard time rendering the waveform in react project. Sometimes the same error pops up and sometimes nothing comes up only the blank space where waveform should render. I have attached the screenshot of the error.
Any advice/help?
Can you post a minimal code example somewhere to help find the cause of the issue? Also, have you seen this example of how to use with React?
As an aside, I notice the error is triggered from _onResize
. This isn't the best design: resizing of the container element may or may not be triggered by resizing the window.
I'm trying to use peak.js in my Vue 3 project and I followed the documentation to load waveform data from the server. I can confirm the data was loaded successfully as I can see the "peaks" logged in the Peaks.init() function. However, the waveform is not displayed. Instead, I get the error stated above.