使用Web Audio API和createMediaElement方法,您可以使用类型化数组从<audio>
元素中的音频播放中获取频率数据,只要源URL是本地(不是流式传输),它就适用于大多数浏览器。请参阅Codepen:http://codepen.io/soulwire/pen/Dscga
实际代码:
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();
其中.visualizer
为空<div>
我正在使用Ionic / Angular开发一个用于广播电台的混合应用程序,而音频流是通过Icecast(http://dir.xiph.org/)并且我遇到了以下问题:本地mp3被分析并且可视化没有问题但是如果你使用流媒体URL,analyser.getByteFrequencyData在iOS Safari中全为零,但它可以正常播放。
所以回顾一下:
我知道在早期版本的Safari中有一个错误,其中createMediaElementSource()会失败,但如果仍然如此,那么它不会对本地文件起作用吗?
有什么想法吗?
答案 0 :(得分:0)
它只是没有按照Safari中的规范实现,它将返回一个零数组而不是流的频率。许多人已经观察到这种行为,例如http://isflashdeadyet.com/tests/web-audio-visualization/index-analyser.html和https://github.com/Okazari/Rythm.js/issues/7
根据https://browsersupport.io/AnalyserNode.prototype.getByteFrequencyData
在这里您会发现“在AnalyserNode上请求字节数据时,Safari似乎没有报告任何信号(值为128)”: http://fourthof5.com/audio-visualisation-with-the-web-audio-api
在此处测试演示以查看当前状态:http://fourthof5.com/assets/posts/audio-visualisation-with-the-web-audio-api/index.html
答案 1 :(得分:0)
仍然无法在Safari和iOS Chrome(使用Apple WebKit?)上使用。现在其他浏览器似乎还不错。音频播放正常,CORS正常-但Analyzer无法正常工作。
This fiddle(不是我的)很好地演示了该行为。后面的uri得到了分析,以前没有:
const url = useStream
? 'https://c2.radioboss.fm:18071/stream'
: 'https://twgljs.org/examples/sounds/DOCTOR%20VOX%20-%20Level%20Up.mp3';