使用WebAPI获取【系统媒体】(页面背景音乐)MediaStream(媒体流)+显示频谱+【控制音量/快进】(.net FrameWork MVC)
使用WebAPI获取系统媒体(页面背景音乐)MediaStream(媒体流)+显示频谱+控制音量
1、页面布局添加audio标签
//controls 控制界面中是否显示audio控件 <audio id="playaudio1" src="" controls></audio>@*系统音乐*@
2、自定义设计界面--通过自定义点击界面音乐实现类似于音乐播放器的功能(图示说明)
可参考另一博客:呼叫台功能页面布局【canvas绘制音频频谱图】【绘制音量控制滑块】 (示例使用.net framework mvc) - じ逐梦 - 博客园 (cnblogs.com)
播放效果如图:
3、成功播放后js编写代码获取媒体的MediaStream(媒体流)
Web Audio API 的运用 - Web API 接口参考 | MDN (mozilla.org)
AudioContext.createMediaElementSource() - Web API 接口参考 | MDN (mozilla.org)
AudioContext
接口的 createMediaElementSource()
方法用于创建一个新的 MediaElementAudioSourceNode
对象,输入某个存在的 HTML <audio>
or <video>
元素,对应的音频即可被播放或者修改。
由 <audio>
元素,通过使用 createMediaElementSource()
方法,创建一个音源
3-1、通过AudioContext上下文获取()创建上下文 (有了上下文可以干好多事)
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();
利用HTML5 Web Audio API给网页JS交互增加声音 « 张鑫旭-鑫空间-鑫生活 (zhangxinxu.com)
3-2、获取auido元素 //通过auido标签获取该媒体音源--创建一个接口用来关联HTMLMediaElement 这可以用来播放和处理来自video或audio元素的音频
(注意track和stream_dest要声明为全局变量否则会有最下方解决问题的第一个问题出现)
AudioContext
接口的 createMediaElementSource()
方法用于创建一个新的 MediaElementAudioSourceNode
对象,输入某个存在的 HTML <audio>
or <video>
元素,对应的音频即可被播放或者修改。
//获取audio标签 var audioElement = document.querySelector('audio#playaudio'); //通过auido标签获取该媒体音源--创建一个接口用来关联HTMLMediaElement 这可以用来播放和处理来自video或audio元素的音频 const track = audioContext.createMediaElementSource(audioElement);
3-3、获取本地媒体的MediaStream
(注意track和stream_dest要声明为全局变量否则会有最下方解决问题的第一个问题出现)
AudioContext.createMediaStreamDestination() - Web API 接口参考 | MDN (mozilla.org)
AudioContext
接口的 createMediaStreamDestination()
方法用于创建一个新的对象,该对象关联着表示音频流的一个 WebRTC (en-US) MediaStream
,音频流可以存储在本地文件或者被发送到另外一台计算机。
AudioContext
的 destination
属性返回一个 AudioDestinationNode
,表示 context 中所有音频的最终目标节点,一般是音频渲染设备,比如扬声器。
//获取本地audio的MediaStream var stream_dest = audioContext.createMediaStreamDestination();
3-4、建立连接(暂时没搞懂原因) 需要将我们的音频图从音频源/输入节点连接到目的地
track.connect(stream_dest);
3-5、成功获取MedisStream --stream_dest即为所需
stream_dest数据如图:
提取stream_dest中的stream即为媒体的MedisStream 数据如图:stream_dest.stream
4、本地测试获取到的MediaStream
页面可添加一个测试audio标签用来表示输出,将获取到的MediaStream通过srcObject属性测试
//获取测试audio var playaudio1 = document.querySelector('audio#playaudio1');//设置赋值 playaudio1.srcObject = stream_dest.stream;
成功效果:(左边为输入-右边为输出(MediaStream数据正确通过赋值后会有其效果))
5、获取到了MediaStream就可传进WebRTC
实现呼叫台博客的功能(调第三方的api的推流技术,通过切换音乐实现音箱播放相应音乐)
调用第三方接口实现呼叫台功能+麦克风数据数据并展示频谱 -WebRTC - じ逐梦 - 博客园 (cnblogs.com)
6、以上完整代码:
functin getSysMediaStream{ //创建AudioContext上下文 const AudioContext = window.AudioContext || window.webkitAudioContext; const audioContext = new AudioContext(); //获取audio标签 var audioElement = document.querySelector('audio#playaudio');
//标黄这两步需要做一个逻辑判断处理-最下方解决问题的第一个有详细说明
//通过auido标签获取该媒体音源--创建一个接口用来关联HTMLMediaElement 这可以用来播放和处理来自video或audio元素的音频 const track = audioContext.createMediaElementSource(audioElement); //获取本地audio的MediaStream音频 var stream_dest = audioContext.createMediaStreamDestination(); track.connect(stream_dest); //获取测试audio var playaudio1 = document.querySelector('audio#playaudio1'); //设置赋值 playaudio1.srcObject = stream_dest.stream;
//显示频谱
initAudioData(stream_dest.stream)
}
二、显示频谱:
将生成的MediaStream放入生成频谱方法中实现显示频谱(频谱详细显示可参考另一博客麦克风采集信息显示频谱方式)
调用第三方接口实现呼叫台功能+麦克风数据数据并展示频谱 -WebRTC - じ逐梦 - 博客园 (cnblogs.com)

// 音频数据处理 function initAudioData(stream) { console.error("1"); console.error(stream); //localStream = stream; // 创建音频上下文 audioCtx = new (window.AudioContext || window.webkitAudioContext)(); // 创建音频源 -将声音输入这个对象 source = audioCtx.createMediaStreamSource(stream); // 创建音频分析节点 analyser = audioCtx.createAnalyser(); // fftSize决定了能够获取到的音频数据的数量 analyser.fftSize = 4096; // 音频源连接至analyser source.connect(analyser); // analyserNode再连接至扬声器播放--本人不需要暂时注释掉了 analyser.connect(audioCtx.destination); // 简单用定时器来绘制波形图,该文档使用requestAnimationFrame来以屏幕刷新的评率来反复执行绘制函数 //animateFrame = setInterval(drawWaver, 60); //开始绘制频谱图 var canvas = document.getElementById('canvas'), cwidth = canvas.width, cheight = canvas.height - 2, meterWidth = 10,//能量条的宽度 gap = 2,//能量条的间距 meterNum = 800 / (10 + 2);//计算当前画布上能画多少条 var ctx = canvas.getContext('2d'); var capHeight = 2,//冒头的高度 capStyle = '#fff',//冒头的颜色 capYPositionArray = [];//将上一面各个冒头的位置保存到这个数组1e9fff //定义一个渐变样式用于画图 var gradient = ctx.createLinearGradient(0, 0, 0, 300); //gradient.addColorStop(1, '#0f0'); //gradient.addColorStop(0.5, '#ff0'); //gradient.addColorStop(0, '#f00'); gradient.addColorStop(1, '#1e9fff');//低音颜色 gradient.addColorStop(0.5, '#70bbf2');//中音颜色 gradient.addColorStop(0, '#1e9fff');//高音颜色 //绘制频谱图 function drawSpectrum() { var array = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(array); var step = Math.round(array.length / meterNum);//计算从analyser中的采样步长 //清理画布 ctx.clearRect(0, 0, cwidth, cheight); //对信源数组进行抽样遍历,画出每个频谱条 for (var i = 0; i < meterNum; i++) { var value = array[i * step]; //取样作为y轴的值 //绘制缓慢降落的冒头 if (capYPositionArray.length < Math.round(meterNum)) { capYPositionArray.push(value);//初始化保存冒头位置的数组,将第一个画面位置保存 } ctx.fillStyle = capStyle; //1.开始绘制冒头 if (value < capYPositionArray[i]) { //使用前一次数据 ctx.fillRect(i * 12, cheight - (--capYPositionArray[i]), meterWidth, capHeight); } else { //否则,直接使用当前数据并记录 ctx.fillRect(i * 12, cheight - value, meterWidth, capHeight); capYPositionArray[i] = value; } //2.开始绘制频谱条 ctx.fillStyle = gradient; ctx.fillRect(i * 12/*频谱条的宽度+条间距*/, cheight - value + capHeight, meterWidth, cheight); } //用requestAnimationFrame来以屏幕刷新的评率来反复执行绘制函数 requestAnimationFrame(drawSpectrum); } //用requestAnimationFrame来以屏幕刷新的评率来反复执行绘制函数 requestAnimationFrame(drawSpectrum); }
三.控制音量
就是控制audio的音量
参考另一博客中绘制音量滑块代码--在滑动系统声音滑块的触发事件中调用下面控制音量的方法
呼叫台功能页面布局【canvas绘制音频频谱图】【绘制音量控制滑块】 (示例使用.net framework mvc) - じ逐梦 - 博客园 (cnblogs.com)
(6条消息) 解决audio控制播放音量_weixin_33831196的博客-CSDN博客
//系统音乐音量控制 参数是int值 1-100 function ctrsys(s) { //根据audio的id获取元素 const playaudio = document.querySelector('audio#playaudio'); //设置音量 0-1 1表示音量最大 playaudio.volume = s/100; }
9、根据自己编辑滑块滑动控制进度
参考另一博客:在播放进度条滑块滑动事件和进度条点击事件中调用该方法
(6条消息) js-audio对象-音频倍速播放、定位播放_sunxiaolinlinx的博客-CSDN博客
//系统音乐快进 参数是int值 单位:秒 function sspeed(p) { const playaudio = document.querySelector('audio#playaudio'); playaudio.currentTime = p; }
10、音乐播放结束根据当前模式(单曲循环、顺序播放、随机播放)继续播放
(6条消息) video 标签 监听播放、暂停、结束等事件_爱吃烧鸭蛋的叶安的博客-CSDN博客_video标签 捕捉播放结束
问题解决:
1、通过采用先获取audio元素,然后获取其媒体信息(获取MediaStream),当媒体暂停重新播放出现错误
问题解决:
经翻译可以看出HTMLMediaElement之前已经连接到一个不同的MediaElementSourceNode。
所以修改之前代码,需要将上面的(track和stream_dest要声明为全局变量并且加上逻辑判断,页面没有刷新情况下只会在第一次给其赋值
修改代码为:
两个变量设为全局:
//元素音源 let track = null; //创建一个新的对象,该对象关联着表示音频流的一个 WebRTC (en-US) MediaStream let stream_dest = null;
获取元素的MediaStream方法添加逻辑判断--添加作用原因就是页面在不刷新情况下不会重复生成新的【关联音频流stream_dest的对象】和【音源track】
此处的audioCtx就是上面详细代码中的audioContext上下文

//获取系统媒体stream function getSysStream() { //获取音源 将音源放入audioContext中 // 获取界面auido标签 const audioElement = document.querySelector('audio'); if (track == null) { //通过使用 createMediaElementSource() 方法,创建了一个音源 track = audioCtx.createMediaElementSource(audioElement); stream_dest = audioCtx.createMediaStreamDestination(); } track.connect(stream_dest); sysStream = stream_dest.stream;//获取系统声音stream }
上面控制台提示的错误实现解决
本文来自博客园,作者:じ逐梦,转载请注明原文链接:https://www.cnblogs.com/ZhuMeng-Chao/p/16956095.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现