新闻详情

新闻详情

首页 / 资讯中心 / 详情

网页消息提醒音JS:从NotAllowedError到完整声音方案

发布时间:2026/9/25 7:37:15来源:尧图网络
网页消息提醒音JS:从NotAllowedError到完整声音方案
简介面向前端开发者的网页消息提醒音实现方案用于解决网页在实时通讯、社交网络、在线协作等场景中的新消息提示问题。资源包共3个文件包含1个mp3音频、1个jQuery脚本和1个HTML演示页面压缩包整体约181KB结构简洁可直接在浏览器中运行并查看效果。方案围绕HTML5 Audio API展开从Audio对象创建与play()调用到通过WebSocket的message等事件触发播放完整演示了消息提醒音的核心流程。同时涵盖多格式音频源MP3/OGG/WAV声明、loop循环播放、音量控制、预加载性能优化和静音选项并针对老版本IE等兼容性问题给出Flash后备或工具库替代思路。已有1128人学习下载适合希望快速上手网页提示音功能、并掌握跨浏览器音频处理细节的前端初中级开发者。1. 网页消息提醒音 JS一条 NotAllowedError 引出的完整声音方案做客服工作台的时候消息进来只有标题栏在闪没有声音用户多次反馈“消息来了不知道”。我找了一个网页消息提醒音 JS 方案接上去头一个版本就翻车本地点按钮声音正常部署上线后消息到了页面一声不吭控制台抛 NotAllowedError有的场景连报错都没有就是安静。反复排查之后我把这套声音模块沉淀了下来核心逻辑全部用原生 JavaScript 写不依赖第三方库重点解决三个问题浏览器自动播放策略下的声音解锁、消息触发时的高频节流、移动端兼容。适合正在做 IM、客服、订单通知、工单系统这类场景的前端开发者也适合后端顺手写页面时参考。2. 声音播放选型HTMLAudioElement 与 Web Audio API 的边界和取舍做提醒音之前先要回答一个问题声音从哪来。两种主流方案一种是用 HTMLAudioElement 直接播放音频文件另一种是用 Web Audio API 合成或者播放内存里的音频。选错方案的典型后果是开发到一半发现要加“多音效同时播放”然后从头重构。我的经验是选型不是“哪个更好”而是“能不能接受音频文件”。如果消息通知要放的是真人录的一段语音那只能走文件播放如果只是要“叮咚”一下那完全可以用 Web Audio 的振荡器合成资源体积为零路径问题也随之消失。真正的分水岭在于要不要做混音和调音色。2.1 HTMLAudioElement最直接的播放方式但要接受它是黑盒HTMLAudioElement 是最基础的网页声音播放方案不用额外引入任何工具浏览器原生支持。写法就是一个构造器加一个 play 方法const audio new Audio(assets/notice.mp3); audio.volume 0.6; audio.play();这段代码构建了一个音频实例把初始音量设置为 0.6然后触发播放。volume 的取值范围是 0 到 10 是静音1 是最大音量0.6 在绝大多数笔记本扬声器上已经足够清晰又不至于刺耳。play() 返回的是一个 Promise可以用 catch 拿到播放失败的具体原因后面避坑章节会详细说。我一般会把这个写法封装成可复用的函数避免在业务代码里到处 new Audio。常见做法是缓存同一个实例触发时把播放进度归零重新播let noticeAudio null; function playNotice() { if (!noticeAudio) { noticeAudio new Audio(assets/notice.mp3); noticeAudio.preload auto; } noticeAudio.currentTime 0; noticeAudio.play().catch((err) { console.warn(提醒音播放失败, err.name || err.message); }); }这段逻辑里有几个容易被忽略的细节。preload 设为 auto意思是页面初始化时就预加载音频文件不用等用户触发播放才开始下载能少几百毫秒延迟。currentTime 归零是为了处理“上一条消息的提醒音还没播完下一条又来了”的情况强制从头开始。catch 里打印 err.name 比只打印 message 更能快速判断是 NotAllowedError 还是 NotSupportedError。黑盒体现在哪你无法精确控制浏览器内部的音频管线不能对单段音频做变调不能把多个声音叠加后做混合输出。想要同时播两个音效HTMLAudioElement 需要维护两个实例而且两者互不知晓。如果提醒音的数量超过三种这套管理方式会变得笨重。2.2 Web Audio API用振荡器合成声音彻底摆脱音频文件Web Audio API 是另一条路不依赖任何音频文件直接用振荡器生成波形。即使是多音效叠加场景它也可以把一路声音接一路声音形成一个音频图控制力比 HTMLAudioElement 强一个量级。一个最简的合成提醒音如下const audioCtx new (window.AudioContext || window.webkitAudioContext)(); const now audioCtx.currentTime; const oscillator audioCtx.createOscillator(); const gainNode audioCtx.createGain(); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); oscillator.type sine; oscillator.frequency.setValueAtTime(880, now); gainNode.gain.setValueAtTime(0.0001, now); gainNode.gain.exponentialRampToValueAtTime(0.4, now 0.02); gainNode.gain.exponentialRampToValueAtTime(0.0001, now 0.4); oscillator.start(now); oscillator.stop(now 0.45);这段代码干了这么几件事创建一个波形为 sine 的振荡器频率设为 880Hz然后把振荡器接到一个增益节点再从这个增益节点接到音频输出。增益在 20 毫秒内从静音拉高到 0.4再在 0.4 秒内衰减回静音最终在 0.45 秒时停止振荡器。听感上就是很干净的一声“叮”开头没有爆音结尾没有突变。参数方面oscillator.type 决定音色sine 是正弦波声音柔和square 是方波声音硬适合做“错误”提示triangle 和 sawtooth 介于两者之间。frequency 决定音高880Hz 对应 A5适合做消息提醒如果要做“紧急”提示可以尝试 1318Hz也就是 E6穿透力更强。gain 的数值要控制在 0.6 以下超过 0.8 在自带扬声器上会破音。需要注意的是AudioContext 创建时机有讲究。Chrome 不允许在用户没有交互的情况下直接创建并播放必须在用户第一次点击或触摸的回调里去创建和恢复。这个点几乎每个刚接触 Web Audio 的人都会踩属于必考的自动播放策略问题。2.3 文件播放与合成一张对比表决定选型把两种方案放到同一张表里看边界会很清楚对比维度HTMLAudioElementWeb Audio 合成音Web Audio 播放文件资源依赖需要 mp3 / wav 文件完全无依赖需要音频文件初始加载成本有网络请求无网络请求有网络请求音色可控性弱只能用现成文件强可调波形和频率强可变速与调音多音效混播弱要管理多个实例强音频图可自由叠加强可并行播放实现复杂度低中中典型场景消息提示、按钮音效系统默认音、倒计时语音播报、复杂音效选型结论也直接给提醒音只有一两个产品对音色没有讲究直接用 HTMLAudioElement 播放 mp3开发和排错成本最低。提醒音超过三个而且要区分紧急、正常、成功等不同场景则建议用 Web Audio 合成把所有提示音集中到一个 SoundManager 里管理后文第 5 章会给出完整模块。这里额外提一个折中方案用 Web Audio 的 AudioBufferSourceNode 播放文件。它既能读取 mp3 文件又能对声音做变速和增益控制不过代码量会比 HTMLAudioElement 多不少适合音效数量多且需要精确控制的场景。我通常只在“需要播放真人语音片段”时才用它纯提示音直接用合成省事。3. 把提醒音接进业务触发时机、音效表和静音偏好选完播放方式接下来是把提醒音真正接进业务。这一层容易翻车的不在“怎么播放”而在“什么时候播放”。消息推送不是用户主动点击它发生在任意时刻而浏览器对“无交互状态下的自动发声”限制得很死。这一章先讲触发时机怎么节流再讲音效表怎么组织最后讲用户静音偏好的实现。3.1 触发时机不要让每次 play() 都直接执行新手最常见的写法是在 WebSocket onmessage 回调里直接调 audio.play()于是消息一多提醒音就像打地鼠一样叠在一起响。不但在体验上很糟糕密集播放还会触发浏览器的音频策略限制导致后面的播放静默失败。成熟的接法是加一个节流判断把“消息到达”和“实际发声”解耦let lastPlayTime 0; const MIN_INTERVAL 3000; function canPlayNotice() { const now Date.now(); if (now - lastPlayTime MIN_INTERVAL) { return false; } lastPlayTime now; return true; } function onNewMessage(message) { if (!canPlayNotice()) { renderMessage(message); return; } renderMessage(message); playSound(message.sound || notice); }这个节流窗口设为 3 秒含义是同一秒内推来 10 条消息也只响一次提示。Date.now() 记录的是毫秒时间戳lastPlayTime 一直在模块级保留直到页面刷新才重置。如果把 MIN_INTERVAL 改为 0相当于不节流不推荐。关键点在于节流判断放在业务回调的最前面而不是放进 SoundManager 内部。提醒音模块只负责“播放一声”是否播放是业务策略两个职责混在一起就很难复用。后面如果产品要求“3 秒内的第二条消息也响一声高亢音”只需要在这里加分支播放模块不需要改动。3.2 用音效表统一管理所有声音提醒音超过两个之后代码里直接 new Audio 就会变得越来越难维护。我在实际项目中会让所有声音配置收敛到一张表里用语义化字符串当 keyconst SOUND_TABLE { notice: { src: assets/notice.mp3, volume: 0.5, loop: false, timeout: 0, }, urgent: { src: assets/urgent.mp3, volume: 0.7, loop: true, timeout: 10000, }, success: { src: assets/success.wav, volume: 0.4, loop: false, timeout: 0, }, };这张表里的字段都是播放必需的参数。src 是音频文件路径可以是相对路径、绝对路径或 CDN 地址。volume 是初始音量类型是 0 到 1 的小数。loop 控制是否循环播放urgent 这种紧急提醒通常需要循环直到用户点开弹窗才停止。timeout 是循环播放的安全上限单位毫秒这里配套设计成即使产品忘记关闭循环10 秒后也会自动停避免页面一直被声音“缠住”。读取配置并播放的逻辑收敛成一个函数function playSound(name) { const config SOUND_TABLE[name]; if (!config) { throw new Error(不存在的音效标识: ${name}); } const audio new Audio(config.src); audio.volume config.volume; audio.loop config.loop; const playPromise audio.play(); if (playPromise) { playPromise.catch((err) { console.warn(音效 ${name} 播放失败, err.name || err.message); }); } if (config.loop config.timeout) { setTimeout(() { audio.pause(); audio.currentTime 0; }, config.timeout); } }这个函数的实现体现了几个取舍。每次调用都新建 Audio 实例好处是不同音效互不干扰代价是无法复用实例但单条消息的开销可以忽略。playPromise.catch 捕获的是 NotAllowedError 这类播放阻止错误日志里用 err.name 比 err.message 更容易定位类型。loop 和 timeout 的配合是关键开循环之前一定想好“什么时候停”。3.3 用户静音偏好存到 localStorage 并在入口拦截消息提醒音必须给用户一个关闭入口否则产品会被打低分。静音不只是把播放音量调成 0而是在播放入口就拦截避免创建无用的音频实例。const SOUND_SETTINGS_KEY sound_settings; function getSoundSettings() { try { return JSON.parse(localStorage.getItem(SOUND_SETTINGS_KEY)) || { muted: false }; } catch { return { muted: false }; } } function setMuted(muted) { const settings getSoundSettings(); settings.muted muted; localStorage.setItem(SOUND_SETTINGS_KEY, JSON.stringify(settings)); } function playSoundWithMute(name) { const settings getSoundSettings(); if (settings.muted) { return; } playSound(name); }getSoundSettings 里包了 try/catch因为用户在浏览器设置里关闭站点存储后访问 localStorage 会直接抛异常。返回值默认是 { muted: false }语义是“无设置就默认不静音”。setMuted 先读后写避免覆盖其他字段。playSoundWithMute 是业务里真正调用的入口静音时直接 return不创建音频实例也不触发任何网络请求。除了静音还有一个很常见的需求是“夜间免打扰”。判断逻辑放在静音判断之后const now new Date(); const hour now.getHours(); if (hour 22 || hour 8) { return; // 夜间静默 }这里有个工程要点夜间静默和用户静音是两套独立配置不要把它们并进同一个字段。用户静音是用户主动选择的偏好夜间静默是产品预设策略混在一起会导致“我明明开了静音半夜还在响”的误解。4. 提醒音避坑指南自动播放策略、延迟和移动端兼容这一章全部是踩坑记录每一条都有现象、原因和解决路径。我建议先自己回忆一遍是否遇到过同款问题再对照这里的工程解法。4.1 现象页面加载后立即调用 play()控制台抛 NotAllowedError很多人把 play() 写在页面初始化逻辑里比如登录成功后的轮询回调中结果是声音不响控制台报错NotAllowedError: play() failed because the user didnt interact with the document first。原因是 Chrome 的自动播放策略。它规定页面在没有用户手势点击、键盘输入、触摸之前不允许播放带声音的媒体。WebSocket 消息、定时器、接口回调都不算用户手势所以直接 play() 会被拒绝。解决方法是提前做一次“解锁”。常见做法是监听用户第一次点击在点击回调里初始化 AudioContext并恢复它的状态document.addEventListener(click, function unlock() { const ctx new (window.AudioContext || window.webkitAudioContext)(); if (ctx.state suspended) { ctx.resume(); } document.removeEventListener(click, unlock); }, { once: true });这段代码的关键是 { once: true }它让监听器执行一次后自动移除。unlock 函数里创建了 AudioContext如果是 suspended 状态则调用 resume()。经过这次解锁后续在 WebSocket 回调里调 play() 就不会被拦截。如果用的是 HTMLAudioElement也可以在同一回调里调用一次 audio.play() 然后立即 pause()达到类似效果。4.2 现象用户点击后第一次播放提醒音仍有几百毫秒延迟页面做了解锁用户也点了按钮但当第一条 WebSocket 消息到达时声音还是迟了半秒才响。原因是音频资源没有预加载。HTMLAudioElement 在 play() 被调用时才去加载文件网络耗时变成了延迟Web Audio 合成方案里AudioContext 在解锁时刚创建初始化需要时间。解决分两步。文件方案在页面初始化时就预加载const noticeAudio new Audio(assets/notice.mp3); noticeAudio.preload auto;并在首次点击的解锁回调里调用一次 noticeAudio.play().catch(() {})随后立即 pause()。这一步会把音频数据缓存到内存里后续真正播放时没有加载开销。合成方案则在首次点击回调里创建 AudioContextlet audioCtx; function initAudioContext() { if (!audioCtx) { audioCtx new (window.AudioContext || window.webkitAudioContext)(); } if (audioCtx.state suspended) { audioCtx.resume(); } return audioCtx; }首次点击时 initAudioContext() 被调用之后的播放逻辑都能直接拿到可用的上下文。4.3 现象移动端 Safari 完全不发声也没有报错Android Chrome 正常iOS Safari 里怎么都不响控制台看不到任何错误。我排查了半小时最后发现问题在两个叠加原因上。第一个原因是 iOS Safari 对 AudioContext 的状态要求更严它初始是 suspended必须由用户手势触发 resume()。这个通过 4.1 的解锁可以解决。第二个原因是 iOS 物理静音键处于静音状态时网页里所有音频都会被静音这个不是代码能绕过的需要在产品层面提示用户。解决时还要注意格式兼容iOS Safari 对 mp3 和 wav 支持良好对 ogg 几乎不支持所以音频资源优先提供 mp3不要只放一个 .ogg。还有一点iOS Safari 的 AudioContext 需要挂载到 window 上时使用 webkitAudioContext 前缀代码里要保留这个兼容路径。4.4 现象多条消息同时到达提醒音叠加成噪音订单系统高峰期一秒推进 5 条消息每条消息都触发一次 play()声音叠在一起变成一团噪音。原因是播放没有做互斥多个 Audio 实例同时发声。虽然第 3 章的节流能挡住一部分但节流窗口内的第二条消息依然会创建一个新的实例。解决方法是加“播放互斥”同一时间只保留一个提醒音实例let activeSound null; function playExclusive(name) { if (activeSound) { activeSound.pause(); activeSound.currentTime 0; activeSound null; } const audio new Audio(SOUND_TABLE[name].src); audio.play().catch(() {}); activeSound audio; audio.addEventListener(ended, () { if (activeSound audio) { activeSound null; } }); }这一段实现了一个“互斥播放”策略新的提醒音响起之前先暂停正在播放的旧声音并归零进度保证同一时间只有一个声音在响。ended 事件里做引用清理避免旧实例占用内存。节流和互斥可以共存节流管“是否允许响”互斥管“同时只能有一个在响”。4.5 现象开发环境一切正常部署线上后音频 404本地开发时音效一切正常一到测试环境就发现提醒音不响打开 Network 面板看到音频文件 404。原因是静态资源路径变了。开发时用 /assets/notice.mp3 能访问到文件线上部署可能把静态资源挂到了 /static 前缀或者 CDN 域名下面。解决方法是给所有音频资源的路径加一个可配置的前缀const ASSET_BASE window.SOUND_ASSET_BASE || ./assets; const SOUND_TABLE { notice: { src: ${ASSET_BASE}/notice.mp3, volume: 0.5 }, urgent: { src: ${ASSET_BASE}/urgent.mp3, volume: 0.7 }, };同时做一次预加载健康检查页面初始化时把所有音效文件都拉一遍失败的打日志function preloadAllSounds() { Object.values(SOUND_TABLE).forEach((config) { const audio new Audio(); audio.preload auto; audio.src config.src; audio.addEventListener(error, () { console.error(音效加载失败${config.src}); }); }); }preloadAllSounds 在页面初始化时调用它会触发浏览器下载所有音效文件但不播放。这样 404 问题能第一时间暴露在控制台而不是等到用户收到消息时才静默失败。5. 把提醒音封装成模块SoundManager 类与推送场景接入前面的代码是零散函数真正放到项目中应该收敛成一个类。我把选型、配置、节流、互斥、预加载、静音全部整合进 SoundManager业务层只调用一个 play(name) 方法复杂度全封装在内部。5.1 一个可直接复用的 SoundManager 类这个类是我在项目里用了半年以上的结构只抽掉了和业务相关的部分。它不依赖任何框架原生 JavaScript 即可运行class SoundManager { constructor(options {}) { this.assetBase options.assetBase || ./assets; this.soundTable options.soundTable || {}; this.minInterval options.minInterval || 3000; this.lastPlayTime 0; this.activeSound null; this.muted this.loadMuted(); this.audioCtx null; this.initUnlock(); } loadMuted() { try { const data localStorage.getItem(sound_settings); return data ? JSON.parse(data).muted : false; } catch { return false; } } initUnlock() { const unlock () { if (!this.audioCtx) { this.audioCtx new (window.AudioContext || window.webkitAudioContext)(); } if (this.audioCtx.state suspended) { this.audioCtx.resume(); } document.removeEventListener(click, unlock); }; document.addEventListener(click, unlock, { once: true }); } resolveSrc(src) { return src.startsWith(http) ? src : this.assetBase src; } play(name) { if (this.muted) return; if (Date.now() - this.lastPlayTime this.minInterval) return; const config this.soundTable[name]; if (!config) return; if (this.activeSound) { this.activeSound.pause(); this.activeSound.currentTime 0; this.activeSound null; } const audio new Audio(this.resolveSrc(config.src)); audio.volume config.volume ?? 0.5; audio.loop config.loop ?? false; audio.play().catch((err) { console.warn(SoundManager: ${name} 播放失败, err.name || err.message); }); this.activeSound audio; this.lastPlayTime Date.now(); audio.addEventListener(ended, () { if (this.activeSound audio) this.activeSound null; }); if (audio.loop config.timeout) { setTimeout(() { audio.pause(); audio.currentTime 0; }, config.timeout); } } setMuted(muted) { this.muted muted; localStorage.setItem(sound_settings, JSON.stringify({ muted })); } }这个类的设计原则是“配置驱动”。assetBase 解决资源路径可迁移性soundTable 收纳所有音效参数minInterval 控制最低播放间隔。play() 内部依次做静音判断、节流判断、互斥处理、播放和循环超时兜底。业务层永远不直接 new Audio()所有声音问题收敛到这一个入口。使用方式也很直接const manager new SoundManager({ assetBase: /static/sounds, minInterval: 3000, soundTable: { notice: { src: /notice.mp3, volume: 0.5 }, alert: { src: /alert.mp3, volume: 0.7, loop: true, timeout: 8000 }, }, }); manager.play(notice);5.2 参数规则说明SoundManager 的参数决定了它在不同项目里的边界行为下面这张表是实际调参时最常用的参考参数类型默认值含义建议assetBasestring./assets音频文件基础路径线上用全局变量覆盖soundTableobject{}音效配置表key 用语义化英文minIntervalnumber3000同一时间最小播放间隔3000-5000 毫秒volumenumber0.5播放音量0.3-0.6紧急音可到 0.7loopbooleanfalse是否循环播放紧急提醒才开timeoutnumber0循环播放安全上限配合 loop 使用单位毫秒调参时最容易忽略的是 timeout 和 loop 的配合。loop 为 true 但 timeout 为 0意味着循环永不停一旦产品忘记调 stop 方法页面就会一直响到用户关掉标签页。所有开启 loop 的音效都必须配套一个 timeout 兜底。还有一个参数细节audio.volume 不要直接写成 1。多数桌面浏览器的扬声器增益曲线在高音量区是压缩的音量超过 0.8 之后听感提升不明显反而容易破音。0.5 到 0.7 是提醒音的最优区间。5.3 接入 WebSocket 与 SSE 推送场景SoundManager 不关心消息从哪来它只暴露 play()。接入 WebSocket 或者 SSE 时回调里只需要做两件事渲染消息、决定播放哪个音效。socket.onmessage function (event) { const message JSON.parse(event.data); renderMessage(message); if (message.type order) { manager.play(alert); } else if (message.type chat) { manager.play(notice); } else { manager.play(success); } };这段代码里manager.play() 内部已经包含了静音、节流、互斥的判断。所以 WebSocket 回调里不需要重复写判断逻辑也不需要担心密集消息导致噪音。启动播放的时机依然要满足自动播放策略也就是说必须保证用户在此之前至少和页面发生了一次点击交互。SSE 场景写法几乎一样区别只在于使用的是 onmessage 还是 addEventListener(message)。我一般会加一个消息类型到音效的映射表避免在回调里写大量 if/elseconst SOUND_BY_MESSAGE_TYPE { order: alert, chat: notice, system: success, }; socket.onmessage function (event) { const message JSON.parse(event.data); renderMessage(message); const sound SOUND_BY_MESSAGE_TYPE[message.type]; if (sound) { manager.play(sound); } };6. 用频谱可视化验证提醒音给“没声音”一个确定的排查路径提醒音这个功能最折磨人的问题就是“听不到”的时候很难判断是没播放、没接通还是音量太小。靠耳朵听在嘈杂的办公室环境里根本没有说服力。所以我做提醒音模块时强制给自己加了一个可视化验证手段把 AudioContext 的输出接到 AnalyserNode 上画一根实时频谱条。const canvas document.getElementById(sound-meter); const meterCtx canvas.getContext(2d); const analyser manager.audioCtx.createAnalyser(); analyser.fftSize 256; manager.audioCtx.destination.connect(analyser); function drawMeter() { const dataArray new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(dataArray); const maxValue Math.max(...dataArray); meterCtx.clearRect(0, 0, canvas.width, canvas.height); meterCtx.fillStyle maxValue 100 ? #e74c3c : #27ae60; meterCtx.fillRect(0, 0, canvas.width * (maxValue / 255), 8); requestAnimationFrame(drawMeter); } drawMeter();这段代码的原理是把音频输出终端的信号分出一路到 AnalyserNode每一帧用 getByteFrequencyData 读取频域数据算出最大值后映射到画布上的一条横条。横条接近满格说明输出信号过强在 100 到 180 之间是正常的提醒音强度低于 30 基本就是没有声音信号出来。从那以后我每次写完提醒音模块都会强制走一遍三件事页面首帧用预加载检查控制台有没有 404第一次点击事件里确认 AudioContext 状态是 running播放时看频谱条有没有从 30 跳到 100 以上。这套流程帮我刷掉了太多“本地好用、上线无声”的问题。调试时也不要只盯着 Network 面板它能证明音频文件加载了但证明不了声音真的从扬声器出来了只有频谱可视化能证明。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

基于Claude Code与ffmpeg的video-use工具链:AI视频自动化生产实战 2026/9/25 8:01:37

基于Claude Code与ffmpeg的video-use工具链:AI视频自动化生产实战

1. 从"video-use"这个模糊标题说起:它到底想解决什么问题第一次看到"video-use"这个标题,加上项目正文和关键词都是空的,我脑子里第一反应是:这大概率是一个围绕"视频处理能力怎么被调用"的工程化项…

阅读更多 →
Atlas 300V Pro 24G上部署YOLOv5全流程:从ONNX转换到性能调优 2026/9/25 8:01:37

Atlas 300V Pro 24G上部署YOLOv5全流程:从ONNX转换到性能调优

最近在社区里看到不少人搜“atlas 300v 24g 是运算加速卡吗”,也有不少同学在问“atlas部署yolo”到底怎么搞。看来随着边缘AI项目变多,越来越多做视觉检测的朋友开始把目光放到昇腾Atlas这套硬件上。我这段时间刚好把一套YOLOv5的检测服务完整迁移到了A…

阅读更多 →
Dart2Wasm 构建与测试全指南:从源码编译、本地开发到基准测试与回归验证 2026/9/25 8:01:31

Dart2Wasm 构建与测试全指南:从源码编译、本地开发到基准测试与回归验证

编程语言编译器语言运行时标准库开发工具 【免费下载链接】sdk The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more. 项目地址: https://gitcode.com/gh_mirrors/sdk1/sdk 点击查看 免费下载 引言 Dart2Wasm 是 Dart SD…

阅读更多 →
Atlas 300V 24G是运算加速卡吗?昇腾NPU部署YOLO全流程实战 2026/9/25 8:01:11

Atlas 300V 24G是运算加速卡吗?昇腾NPU部署YOLO全流程实战

最近总有人在技术群里问“Atlas 300V 24G 是运算加速卡吗”,这个搜索热词一出来,我大概能猜到大家为什么会纠结。我第一次拿到这块卡的时候也愣了一下:它没有GPU那种粗壮的散热鳍片,没有显示输出接口,接口挡板上干干净…

阅读更多 →
CNAS/CMA体系下实验室投诉处理程序的闭环设计与实操指南 2026/9/25 8:01:04

CNAS/CMA体系下实验室投诉处理程序的闭环设计与实操指南

1. 投诉处理程序在CNAS/CMA体系中的真实定位做了这么多年实验室质量管理工作,我最深的感触是:很多实验室把投诉处理程序当成一个“应付评审用的必备文件”,编一套流程、配一张表格、应付完现场评审就束之高阁。等到真来了投诉,才发…

阅读更多 →
Linux开机启动脚本设置:rc.local、cron @reboot与systemd实战选型指南 2026/9/25 8:00:51

Linux开机启动脚本设置:rc.local、cron @reboot与systemd实战选型指南

1. 开机启动脚本:不是“配完就完事”,而是系统稳定性的第一道防线在Linux运维现场干了十多年,我见过太多因为开机启动配置翻车的案例:数据库服务没等MySQL初始化完就强行启动,结果主从同步直接断裂;监控脚本…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉