我有一个带有嵌入式soundcloud元素的小网页,我想制作一个频谱分析仪。到目前为止,我已经成功制作了一个只使用本地声音文件,但我无法弄清楚如何从嵌入式元素中获取音频数据。
有没有办法从嵌入元素中提取声音数据?
如果这不是一项简单的任务,那么能够分析当前正在浏览器中播放的声音,如果可能的话,同样令人满意。
提前致谢:)
代码(不是我真的写的,我从教程中找到了大部分内容)
HTML(嵌入式soundcloud标记)
<iframe id="em1" width="100%" height="450" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/144737157&auto_play=false&hide_related=false&visual=true"></iframe>
JS,我希望以某种方式将SoundCloudAudioSource附加到嵌入式标记或整个浏览器窗口。
var SoundCloudAudioSource = function(audioElement) {
var player = document.getElementById(audioElement);
var self = this;
var analyser;
var audioCtx = new (window.AudioContext || window.webkitAudioContext); // this is because it's not been standardised accross browsers yet.
analyser = audioCtx.createAnalyser();
analyser.fftSize = 256; // see - there is that 'fft' thing.
var source = audioCtx.createMediaElementSource(player); // this is where we hook up the <audio> element
source.connect(analyser);
analyser.connect(audioCtx.destination);
var sampleAudioStream = function() {
// This closure is where the magic happens. Because it gets called with setInterval below, it continuously samples the audio data
// and updates the streamData and volume properties. This the SoundCouldAudioSource function can be passed to a visualization routine and
// continue to give real-time data on the audio stream.
analyser.getByteFrequencyData(self.streamData);
// calculate an overall volume value
var total = 0;
for (var i = 0; i < 80; i++) { // get the volume from the first 80 bins, else it gets too loud with treble
total += self.streamData[i];
}
self.volume = total;
};
setInterval(sampleAudioStream, 20); //
// public properties and methods
this.volume = 0;
this.streamData = new Uint8Array(128); // This just means we will have 128 "bins" (always half the analyzer.fftsize value), each containing a number between 0 and 255.
this.playStream = function(streamUrl) {
// get the input stream from the audio element
player.setAttribute('src', streamUrl);
player.play();
}
};
答案 0 :(得分:1)
有没有办法从嵌入元素中提取声音数据?
没有
如果这不是一项简单的任务,那么能够分析当前正在浏览器中播放的声音,如果可能的话,同样令人满意。
这也是不可能的。
答案 1 :(得分:0)
感谢您的代码。
一个想法:
iframe src字段具有访问mp3文件的相关信息:
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/144737157&auto_play=false&hide_related=false&visual=true"
tracks-id:144737157
使用他们的SDK使用该信息:
SC.stream("/tracks/144737157",{autoLoad: true, onload: function(){ this.play(); }});
或直接: 您将被转发(302)到aws:
http://api.soundcloud.com/tracks/144737157/stream?client_id=201b55a1a16e7c0a122d112590b32e4a
答案 2 :(得分:0)
this.playStream = function(streamUrl) {
// get the input stream from the audio element
player.setAttribute('src', streamUrl);
player.play();
}
重点是你不能直接将streamUrl传递/使用到你自己的audioPlayer中。
因为实际上流网址不是您希望播放的歌曲的终点网址。当您向流网址发送http请求时,正在按需创建歌曲的实际音频(以mp3格式)。
之后,您将被重定向到作为物理路径的歌曲的端点URL,您可以使用通过发送http请求检索到的此端点URL来播放/分析它。关键是,音频的这个端点URL的到期时间是sth。喜欢10-15分钟。
为了达到我在这里所说的,你将不得不做一些与此类似的技巧: (不知道你将如何在JavaScript中执行此操作,但它会给你一个想法)
public void Run()
{
if (!string.IsNullOrEmpty(TrackUrl))
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(TrackUrl + ".json?client_id=YOUR_CLIENT_ID");
request.Method = "HEAD";
request.AllowReadStreamBuffering = true;
request.AllowAutoRedirect = true;
request.BeginGetResponse(new AsyncCallback(ReadWebRequestCallback), request);
}
}
private void ReadWebRequestCallback(IAsyncResult callbackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.EndGetResponse(callbackResult);
using (StreamReader httpwebStreamReader = new StreamReader(myResponse.GetResponseStream()))
{
this.AudioStreamEndPointUrl = myResponse.ResponseUri.AbsoluteUri;
this.SearchCompleted(this);
}
myResponse.Close();
}
AudioStreamEndPointUrl
是您的mp3音频将在接下来的15-20分钟内驻留的实际网址。请注意,每次要流式传输歌曲时,都必须重新请求端点URL。
最后,我建议您不要在互联网上传播您的API密钥;而是像CLIENT_ID一样输入。
答案 3 :(得分:0)
我认为JustGoscha的链接指向了正确的方向。 但是这个audio-visualization-with-web-audio-canvas-and-the-soundcloud-api链接应该满足您的需求。