图片来源:Chrome插件-云音乐听歌风起云涌,你还不知道它的名字。这时候只能打开手机听歌、认歌,不过通过浏览器插件解决这个问题更简单。无需繁琐地取出手机,也不会因为要拿出来而打扰他人,也不会因为环境噪音而难以识别。如果你恰好有这个需求,不妨试试云音乐出品的Chrome浏览器插件“云音乐听歌”,也可以直接收红心。也可以到插件官网预览实际运行效果。背景目前,Chrome商店中的听歌、识别音乐插件大部分是国外生产的,国内产品很少,对国内音乐的支持很差。现在云音乐有了这个能力,我们希望能覆盖到这个功能的每一个角落,传递音乐的美好力量。同时,目前市面上的大部分插件仍然是基于manifestv2实现的(相比manifestv3,安全性、性能和隐私性更差)。通常的做法是直接录制音频到服务器,通过服务器进行指纹提取,会增加服务器的计算压力,增加网络传输。那么有没有什么办法可以使用manifestv3协议实现功能,同时把提取音频指纹的计算放在前端呢?Chrome浏览器插件的新协议本文的重点不在于如何实现浏览器插件本身。如果对插件本身的开发不了解,可以参考谷歌官方的开发文档。特别是manifestv2(MV2)即将被废弃,2022年逐渐不接受更新,2023年逐渐无法运行。本文所有内容基于manifestv3,更安全,更好性能,并且在隐私方面更强。(MV3)用于实施。协议的升级也会对函数的实现带来一些变化,因为MV3更加安全的限制,一些基于MV2的灵活实现(例如:远程代码执行,不安全的方法如eval,newFunction(...)可以使用)将不起作用。而这会给听歌识别歌曲的插件带来一些实现上的困难。MV3协议对插件实现的核心影响:原来的BackgroundPage被ServiceWorker取代,意味着WebAPI等操作不能再在BackgroundPage上进行。不再支持远程代码托管,无法动态加载代码,这意味着需要将可执行代码直接打包到插件中。内容安全策略调整不再支持直接执行不安全代码。WASM初始化相关函数不能直接运行。实现听歌识别音乐听歌识别音乐的技术已经比较成熟。总体思路是通过音频数字采样提取音频指纹,最终与数据库中的指纹进行匹配。具有最高特征值的歌曲被认为是被识别的歌曲。.浏览器插件中的音频提取使用插件在网页中录制音频和视频其实非常简单。您只需要chrome.tabCaptureAPI来录制网页本身的音频。HASH规则与数据库数据一致。可以对获得的流进行音频转录和采样。一般有3种处理方法:createScriptProcessor:这种方法对于音频处理是最简单的,但是这种方法在W3C标准中已经被标记为废弃。不推荐使用MediaRecorder:借助媒体API也可以完成音频转录,但是没有办法做的很细。AudioWorkletNode:用于替代createScriptProcessor进行音频处理。可以解决同步线程处理对主线程造成的压力。同时,它可以对音频信号进行比特位处理。这里,音频采样也选择这种方法。基于AudioWorkletNode的音频采样和采样时长控制方法:模块注册,这里的模块加载是通过文件加载的方法,PitchProcessor.js对应根目录下的文件:constaudio_ctx=newwindow.AudioContext({sampleRate:8000,});awaitaudio_ctx.audioWorklet.addModule("PitchProcessor.js");创建一个AudioWorkletNode,主要用于接收WebAudio线程通过port.message传回的数据信息,从而可以在主线程进行数据处理:classPitchNodeextendsAudioWorkletNode{//处理PitchProcessor抛出的未捕获异常.onprocessorerror(err){console.log(`AudioWorkletProcessor.process()发生错误:${err}`);}初始化(回调){this.callback=回调;this.port.onmessage=(event)=>this.onmessage(event.data);}onmessage(event){if(event.type==='getData'){if(this.callback){这个。回调(事件。结果);}}}}constnode=newPitchNode(audio_ctx,"PitchProcessor");processAudioWorkletProcessor.process,即PitchProcessor.js文件内容:process(inputs,outputs){constinputChannels=inputs[0];常量输入样本=i输入通道[0];如果(this.samples.length<48000){this.samples=concatFloat32Array(this.samples,inputSamples);}else{this.port.postMessage({type:'getData',result:this.samples});this.samples=newFloat32Array(0);}returntrue;}取第一个输入通道的第一个通道采集数字信号,采集到满足定义长度后通知(比如这里是48000)到主线程进行信号识别和处理基于process方法,可以做很多有趣的尝试,比如最基本的白噪声生成。音频指纹提取提取音频信号后,下一步就是对信号数据进行指纹提取。我们提取的其实是一段二进制数据,需要进行傅里叶变换,转换成频域信息进行特征表示。具体的指纹提取逻辑是一套有规律且复杂的算法。传统的指纹提取方法:1)基于频带能量的音频指纹;2)基于地标的音频指纹;3)基于神经网络的音频指纹,对算法感兴趣的可以阅读相关论文,例如:AHighlyRobustAudioFingerprintingSystem。整个运算有一定的性能要求,基于WebAssembly的运算可以获得更好的CPU性能。现在C++/C/Rust有比较方便的编译成WebAssembly字节码的方式,这里不再展开。接下来,当您尝试在插件场景中初始化WASM模块时,您很可能会遇到以下异常:RefusedtocompileorinstantiateWebAssemblymodulebecause'wasm-eval'isnotanallowedsourceofscriptinthefollowingContentSecurityPolicydirective:"script-src'self''unsafe-inline''unsafe-eval'...这是因为使用WebAssembly时需要遵循严格的CSP定义。对于ChromeMV2,可以添加"content_security_policy":“script-src'self''unsafe-eval';”来声明。在MV3中,由于更严格的隐私和安全限制,不再允许这种简单粗暴的执行方式。在MV3中,对于插件页面的脚本-CSP定义中的srcobject-srcworker-src只允许取值:selfnonelocalhost,即无法定义unsafe-eval等属性,所以直接在插件页面简单运行wasm已经不可行.好像已经走到尽头了?总有更多的方法n个问题。仔细阅读了文档,发现文档中有这样的描述:CSPmodificationsforsandboxhavenosuchnewrestrictions。——Ch??rome插件开发文档是说这种安全限制在沙盒模式下是没有的。插件本身可以定义一个沙箱页面。这个页面虽然不能访问web/chromeAPI,但是可以运行一些所谓的“不安全”方法,比如eval、newFunction、WebAssembly.instantiate等。因此,可以使用沙盒页面加载运行WASM模块,将计算结果返回给主页面,整个指纹采集流程就变成了,如下图:沙盒页面可以在主页面加载iFrame的方式是利用iFrame的contentWindow和主窗口进行数据通信。数据流程如下图所示:基本的音频提取和指纹提取过程到这里就完成了,剩下的就是数据库中的指纹特征。匹配。特征与提取的音频指纹匹配后,下一步就是在指纹库中进行音频检索。指纹库可以用一个哈希表来实现,每一项代表同一个指纹对应的音乐ID和该音乐出现的时间,构建指纹库。从数据库中访问提取的指纹以获得匹配的歌曲。当然,这只是一个基本的过程。每个公司具体的算法优化方法还是有很大差异的。除了版权原因,算法直接关系到各个公司的匹配效率和准确性。这里插件的实现还是采用效率优先的方式。写在最后,以上大致描述了基于WebAssembly和MV3实现听歌识别歌曲插件的大致流程。虽然该插件灵活易用,但谷歌也意识到该插件带来的一些安全、隐私等问题,因此进行了大规模迁移。MV3协议具有更多的隐私性和安全性,但也限制了很多功能的实现。2023年以后,会有大量的插件无法继续使用。关于听歌认歌插件的功能,目前已经完成的功能包括音频识别、红心歌单收藏等,未来还会继续扩展功能。希望这个小功能可以帮到你。参考https://developer.mozilla.org/en-US/https://developer.chrome.com/docs/apps/https://www.w3.org/TR/webaudio/#widl-AudioContext-createScriptProcessor-ScriptProcessorNode-unsigned-long-bufferSize-unsigned-long-numberOfInputChannels-unsigned-long-numberOfOutputChannelshttps://developer.mozilla.org/zh-CN/docs/WebAssembly/C_to_wasmhttp://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=152C085A95A4B5EF1E83E9EECC283931?doi=10.1.1.103.2175&rep=rep1&type=pdf本文由网易云音乐技术团队发布。未经授权禁止任何形式的转载。我们常年招聘各种技术岗位。如果你要跳槽,又恰好喜欢云音乐,那就加入我们吧grp.music-fe(at)corp.netease.com!
