Using the web audio API and createMediaElement, you can use a typed array to get the frequency data from the sound in the <audio>
element, and it works in most browsers if the source URL is local (rather than streaming). See Codepen: http://codepen.io/soulwire/pen/Dscga
Actual code:
var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); var audioElement = new Audio('http://crossorigin.me/http://87.230.103.9:80/top100station.mp3'); // example stream audioElement.crossOrigin = 'anonymous'; audioElement.type = 'audio/mpeg'; var analyser = audioCtx.createAnalyser(); audioElement.addEventListener('canplay', function() { var audioSrc = audioCtx.createMediaElementSource(audioElement); // Bind our analyser to the media element source. audioSrc.connect(analyser); audioSrc.connect(audioCtx.destination); }); var frequencyData = new Uint8Array(20); var svgHeight = ($window.innerHeight / 2) - 20; var svgWidth = $window.innerWidth - 20; var barPadding = '2'; function createSvg(parent, height, width) { return d3.select(parent).append('svg').attr('height', height).attr('width', width); } var svg = createSvg('.visualizer', svgHeight, svgWidth); // Create our initial D3 chart. svg.selectAll('rect') .data(frequencyData) .enter() .append('rect') .attr('x', function (d, i) { return i * (svgWidth / frequencyData.length); }) .attr('width', svgWidth / frequencyData.length - barPadding); // Continuously loop and update chart with frequency data. function renderChart() { requestAnimationFrame(renderChart); // Copy frequency data to frequencyData array. analyser.getByteFrequencyData(frequencyData); console.log(frequencyData); // Update d3 chart with new data. svg.selectAll('rect') .data(frequencyData) .attr('y', function(d) { return svgHeight - d; }) .attr('height', function(d) { return d; }) .style('opacity', function(d) { return d / 255; }) .attr('fill', function() { return 'rgb(255, 255, 255)'; }); } // Run the loop renderChart();
Where .visualizer
is an empty <div>
I am developing a hybrid application for a radio station using Ionic / Angular, and the audio stream is through Icecast ( http://dir.xiph.org/ ), and I faced the following problem: local mp3 files are analyzed and visualized without problems, however, if you use the streaming url, analyser.getByteFrequencyData - all zeros in iOS Safari, but it works fine.
So, to repeat:

I know that there was a bug in earlier versions of Safari where createMediaElementSource () will fail, but if it doesn't matter, then it will not work in the local file?
Any ideas?
source share