《WebKit 技术内幕》学习之十一(3):多媒体

3 音频

3.1 音频元素

        说完视频之后,接下来就是HTML5中对音频的支持情况。音频支持不仅指对声音的播放,还包括对音频的编辑和合成,以及对乐器数字接口(MIDI)等的支持,下面逐次介绍并分析它们。

3.1.1 HTML5 Audio元素

        说到音频,最简单当然也是最直接想到的就是音频播放,在HTML5中使用“audio”元素来表示。同视频类似,HTML5标准中也定义了三种格式,它们是Ogg、MP3和Wav。到目前为止,笔者所了解的浏览器对音频格式的支持如表11-2所示。

                        表11-2 主流浏览器对HTML5中三个音频格式的支持

        与视频格式类似,考虑到浏览器对HTML5的“audio”支持程度不同,格式也不尽相同,所以Web开发者同样可以提供三种格式的文件,采用如实例代码11-4所示的代码以获得最好的用户体验效果。

示例代码11-4 使用“audio”元素的HTML5代码片段

    <audio controls="controls"><source src="audio.mp3" type="audio/mpeg"><source src=" audio.wav" type="audio/wav"><source src=" audio.ogg" type="audio/ogg">Your browser does not support the audio tag.</audio>

因为视频内容通常包含音频数据,所以不仅仅是“audio”元素才会使用音频播放,但是二者在工作原理上是类似的。同时,音频的字幕同视频是一样的,“track”元素也可以用在“audio”元素的字幕中,用来显示字幕。

3.1.2 基础设施

        音频的支持方面还是从输入和输出两个方面着手。对于输入,同视频类似,WebKit使用资源加载器先加载音频文件,之后是建立音频元素、管线化引擎相关的类,如MediaPlayer类、HTMLAudioElement和WebMediaPlayer类等。同视频不一样的是,视频的输出是GPU中的纹理对象,而音频需要输出到声卡,所以需要打开声卡设备。因为Chromium的沙箱模型机制,所以只能靠Browser进程来打开和关闭声卡设备,图11-14描述了多进程中如何将音频从Renderer进程传输到Browser进程,以及WebKit和Chromium中相应的基础设施。

                        图11-14 WebKit和Chromium支持Audio的基础设施

首先是Renderer进程这一部分,也就是右侧部分,从上往下依次介绍如下。

  • WebKit::WebAudioSourceProvider 和WebKit::WebAudioSourceProviderClient :最上面两个类是WebKit的Chromium移植接口类,根据名字读者已经猜测出来了,前者提供音频原数据,也就是音频文件中的数据,这里采用“拉”的方式,也就是在ResourceLoader加载数据之后,当且仅当渲染引擎需要新的数据的时候,主动从加载后的数据中拉出数据来进行解码。“provideInput”函数由Chromium实现,由WebKit引擎调用。WebKit::WebAudioSourceProviderClient提供了“setFormat”函数,用于让Chromium的媒体播放器设置频道数量、采样率等信息。WebAudioSourceProviderImpl是WebKit::Web-AudioSourceProvider的实现类。
  • AudioRendererImpI :该类就是音频渲染器的实现,并使用类AudioRenderSink将音频解码的结果输出到音频设备。
  • AudioRendererSink :一个抽象类,用于表示一个音频终端点,能够接收解码后的音频信息,典型的一个例子就是音频设备。
  • AudioRendererMixer :渲染器中的调音类。
  • AudioOutputDevice :音频的输出设备,当然只是一个桥接层,因为实际的调用请求是通过下面两个类传送给Browser进程的。
  • AudioOutputIPCImpI和AudioMessageFiIter :前者将数据和指令通过IPC发送给Browser进程,而后者当然就是执行消息发送机制的类。

然后是Browser进程这一部分,也就是左侧部分,自下而上依次介绍如下。

  • AudioRendererHost :Browser进程端同Renderer进程通信并有调度管理输出视频流的功能,对于每个输出流,有相应的AudioOutputStream对象对应,并且通过AudioOutputController类来处理和优化输出。
  • AudioOutputControIIer :该类控制一个AudioOutputStream对象并提供数据给该对象,提供play、pause、stop等功能,因为它控制着音频的输出结果。
  • AudioOutputStream 和AudioOutputProxy :音频的输出流类和其子类。AudioOutputProxy是一个使用优化算法的类,它仅在Start()和Stop()函数之间打开音频设备,其他情况下音频设备都是关闭的。AudioOutputProxy使用AudioOutputDispatcher打开和关闭实际的物理音频设备。
  • AudioOutputDispatcher 和AudioOutputDispatcherImpI :控制音频设备的接口类和实际实现类。

        经过上面对类的解释,相信读者有了一个大致的思路:当WebKit和Chromium需要输出解码后的音频数据时,通过从右侧自上向下、左侧自下向上的过程,然后使用共享内存的方式将解码后的数据输出到实际的物理设备中。

3.2 Web Audio

        Audio元素能够用来播放各种格式的音频,但是,HTML5还拥有更强大的能力来处理声音,这就是Web Audio。该规范提供了高层次的JavaScript接口,用来处理和合成声音。整个思路就是提供一张图,该图中的每个节点称为AudioNode,这些节点构成处理的整个过程,虽然实际的处理是使用C/C++来完成的,但是Web Audio也提供了一些接口来让Web前端开发者使用JavaScript代码来调用C/C++的实现。WebAudio对于很多Web应用很有帮助,例如游戏,它能够帮助开发者设计和实时合成出各种音效。

        根据W3C的Web Audio规范的定义,整个处理过程可以看成一个拓扑图,该图有一个或多个输入源,称为Source节点。中间的所有点都可以看成各种处理过程,它们组成复杂的网。图中有一个最终节点称为“Destination”,它可以表示实际的音频设备,每个图只能有一个该类型的节点。上述图中的所有节点都是工作在一个上下文中,称为AudioContext,如图11-15所示。

                图11-15 使用WebAudio技术的音频图

        对于Source1节点,它没有输入节点,只有输出节点。对于中间的这些节点,它们既包含输入节点也包含输出节点,而对于Destination节点,它只有输入节点,没有输出节点。上述图中的其他节点都是可以任意定义的,这些节点每一个都可以代表一种处理算法,开发者可以根据需要设置不同的节点以处理出不同效果的音频输出。

        中间这些节点有很多类型,它们的作用也不一样,这些节点的实现通常由C或者C++代码来完成以达到高性能,当然这里提供的接口都是JavaScript接口。

        Web Audio的绝大多数处理都是在WebKit中完成的,而不需要Chromium过多地参与,除了输入源和输出结果到实际设备,其他同前面的多媒体数据源是一致的,不再赘述,下面描述图11-15中的结构是如何被WebKit支持的。

        图11-16的上半部分主要是支持规范中的标准接口,例如AudioBufferSourceNode、AudioContext、DestinationNode和OscillatorNode等类,它们对应图11-15中规范定义的接口,还有众多的类这里并没有绘制出。下面重点关注的是OsicllatorNode类,它需要对音频数据进行大量计算,包括向量的加法、乘法等。同时该节点类需要使用PeriodicWave来计算周期性波形,这里面需要使用到FFT(快速傅立叶变换)算法,因为音频的及时性,网页对性能有非常高的要求。对于Chromium移植,不同平台采用不同的加速算法,在Windows和Linux上使用FFmpeg中的高性能算法,在Android上使用OpenMax DL提供的接口来加速,而在Mac上又是不同的算法。

                                图11-16 WebKit支持WebAudio的一些重要基础设施

        Web Audio对于Web领域来说很重要,一个重要的应用场景就是游戏,因为游戏中进场需要合成音效或者变换出不同的音效结果,笔者很乐意看到它在HTML5中发展得越来越好,推动游戏等应用领域的发展。

3.3 MIDI和Web MIDI

        MIDI是一个通信标准,它是电子乐器之间,以及电子乐器与电脑之间的统一交流协议,用以确定电脑音乐程序、合成器和其他电子音响设备互相交换信息与控制信号的方法。同其他的声音格式不同,MIDI不是记录采样信息,而是记录乐器的演奏指令。现在,在Web中支持MIDI变成了一个非常热门的话题。

        音频也可以以MIDI格式来存储,但是该格式并不是HTML5的标准,所以浏览器并没有内置地支持它们。为了能让MIDI格式的音乐播放出来,可以使用JavaScript代码,这就是MIDI.js。它使用上面提到的WebAudio技术和Audio元素来实现音乐的播放,在Chromium中效果非常不错。

        但是这也只能做到播放MIDI格式的音频文件,能否在JavaScript中利用代码来控制MIDI输入和输出设备呢?也就是能够读入MIDI的输入信息,由JavaScript代码将其信息处理成MIDI格式的指令并传送到输出设备,这就是现在兴起的Web MIDI技术。目前的规范定义了一系列接口来接收和发送MIDI指令,但是该技术本身并不提供语义上的控制,而只是负责传输这些指令,所以渲染引擎其实并不知道这些指令的实际含义,这是跟Web Audio非常不一样的地方。

        根据上面的描述,Web MIDI规范中定义了输入和输出的MIDI设备,如MIDIInput和MIDIOutput,通过MIDIAccess接口返回到所有枚举的输入和输出设备。MIDIInput主要包含一个接收指令的函数,叫onMessage,而MIDIOutput包含一个发送指令的函数,叫send,而发送的数据指令就是MIDIEvent,该指令包含一个时间戳和数据。MIDI规范也是草案阶段,所以支持它的浏览器很少,在2013年6月,Google渲染在Chromium的开发者版本中加入了Web MIDI的支持,这是一个非常大的进展,虽然只是处于起步阶段。

        WebKit和Chromium对于Web MIDI的支持主要包括三个部分,第一是加入JavaScript的绑定,这个技术前面已经介绍过了;第二是将对MIDI接口的支持从Renderer进程桥接到Browser进程;第三是Chromium的具体实现,如图11-17所示。

                                        图11-17 Chromium中的MIDI实现类们

3.4 Web Speech

        HTML5对声音方面的支持绝不仅仅是上面介绍的这么多,现在还有一项非常重要的应用,那就是语音识别技术(Speech-to-Text)和合成语音技术(Text-to-Speech),它们已经被广泛地应用在很多领域。简单来说,就是从语音识别出文本文字和从文本文字生成声音资源。

        HTML5中的“Web Speech API”是由Google公司发起的规范,其目的是将语音识别和合成语音技术提供给JavaScript接口,这样Web前端开发者可以在网页中使用它们。所以,这一规范主要包括两个接口:SpeechRecognition和SpeechSynthesis,分别标识上述两种功能。

        自然而然地,W3C定义了两个主要的接口,分别对应识别和合成技术,接口定义比较清晰简单,例如对于SpeechRecognition,当调用start()函数时就开始语音识别,而后面的事件句柄则是让开发者知道识别的状态,当识别完成之后,可以通过监听“onresult”来获取识别的结果。

                       图11-18 W3C Speech API草案定义的主要接口

        而对于SpeechSynthesis接口,规范定义的主要是speak()方法,该方法的参数SpeechSynthesisUtterance非常重要。该参数包含了输入的文本,并能提供各种合成过程中的状态,实际输出结果可以通过调用getVoices()函数来获得语音结果。

        遗憾的是,目前Chromium中对该规范的实现依赖于Google API(也就是网络服务接口),这也意味着用户不能离线使用这些功能,因为语音的识别是需要服务器端提供的能力。同时还有一个问题,如果开发者希望自己在Chromium中编译一个浏览器或者其他应用,可是这些功能是受限的,开发者必须向Google申请一个称为“API Keys”的密钥文件,也就是必须获得使用这些Google API的授权。在未来,笔者希望能够有不依赖于服务的语音识别和合成语音技术的出现。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/643629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第36天 |435. 无重叠区间 763.划分字母区间 56. 合并区间

目录 435. 无重叠区间 &#x1f4a1;解题思路 &#x1f4bb;实现代码 763.划分字母区间 &#x1f4a1;解题思路 &#x1f4bb;实现代码 56. 合并区间 &#x1f4a1;解题思路 &#x1f4bb;实现代码 435. 无重叠区间 题目链接&#xff1a;435. 无重叠区间 给定一个…

一文讲透Redis的LRU与LFU算法实现

深入解析Redis的LRU与LFU算法实现 一、前言 Redis是一款基于内存的高性能NoSQL数据库&#xff0c;数据都缓存在内存里&#xff0c; 这使得Redis可以每秒轻松地处理数万的读写请求。 相对于磁盘的容量&#xff0c;内存的空间一般都是有限的&#xff0c;为了避免Redis耗尽宿主…

【Go面试向】Go程序的执行顺序

【Go】Go程序的执行顺序 大家好 我是寸铁&#x1f44a; 总结了一篇Go程序的执行顺序的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; Go程序内容 go程序通常包含: 包、常量、变量、init()、main()等元素 下面从这几个方面分别去梳理&#xff01; 包的执行顺序 程序中的包 …

Linux系统常用命令行指令

Linux系统是一种常用于开源项目开发的生产环境&#xff0c;因其免费、开源、安全、稳定的特点被广泛应用于手机、平板电脑、路由器、电视和电子游戏机等嵌入式系统中&#xff0c;能够更加简便地让用户知道系统是怎样工作的。前几日我安装好了Red Hat Enterprise Linux 9.0&…

Linux的常见指令和基本操作演绎【复习篇章一】

文章目录 前言下载安装 XShellXShell 下的复制粘贴热键操作01.ls指令tree 02.cd指令03.touch指令04.mkdir指令&#xff08;重要&#xff09;&#xff1a;05.rmdir指令 && rm 指令&#xff08;重要&#xff09;06.组合07.man指令&#xff08;重要&#xff09;&#xff1…

《WebKit 技术内幕》学习之十一(4):多媒体

4 WebRTC 4.1 历史 相信读者都有过使用Tencent QQ或者FaceTime进行视频通话的经历&#xff0c;这样的应用场景相当典型和流行&#xff0c;但是基本上来说它们都是每个公司推出的私有产品&#xff0c;而且通信等协议也都是保密的&#xff0c;这使得一种产品的用户基本上不可能…

【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用

系列文章目录 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part1 案例复现 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part2 自有数据集构建 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用 在一个人体姿态估计的任务中&#xff0c;需要用深度学习模型…

天天酷跑-C语言搭建童年游戏(easyx)

游戏索引 游戏名称&#xff1a;天天酷跑 游戏介绍&#xff1a; 本游戏是在B站博主<程序员Rock>的视频指导下完成 想学的更详细的小伙伴可以移步到<程序员Rock>视频 【程序员Rock】C语言项目&#xff1a;手写天天酷跑丨大一课程设计首选项目&#xff0c;手把手带你用…

【linux】Debian挂起和休眠

一、挂起和休眠 在Debian桌面系统中&#xff0c;挂起和休眠是两种不同的状态&#xff0c;它们之间有一些区别。 挂起&#xff08;Suspend&#xff09;是将当前系统的状态保存到RAM&#xff08;内存&#xff09;中&#xff0c;然后关闭所有硬件设备&#xff0c;除了RAM之外。在…

如何用H5+CSS+JS写一个简单的招聘网站

大家好&#xff0c;我是猿码叔叔&#xff0c;一个 Java 语言开发者。应网友要求&#xff0c;写一个简单的招聘页面。由于技术原因&#xff0c;页面相对简单&#xff0c;朋友们可以选择性的阅读&#xff0c;如果对您有帮助&#xff0c;也可直接拿去使用&#xff0c;因为接下来除…

数据分析的理念、流程、方法、工具(下)

四、用户分群 1、用户分群 用户分群是精细化运营的基础要求&#xff0c;也是数据分析的最基础方式。对用户进行分群&#xff0c;能帮助我们了解每个细分群体用户的变化情况&#xff0c;进而了解用户的整体现状及发展趋势。同时&#xff0c;由于运营资源本身有限&#xff0c;不…

技术变革下职业危机

方向一&#xff1a;技术变革 1.人工智能&#xff08;AI&#xff09;&#xff1a;AI技术的快速发展正在改变各个行业。AI在医疗诊断、金融分析、客户服务以及物流管理等方面都有广泛应用&#xff0c;提高了效率和准确性。但同时也引发了一些道德和道德问题&#xff0c;比如隐私…

玩法与画面全面升级,艾尔莎H311-PRO和你玩转《如龙8:无尽财富》

作为经典的日系开放式世界游戏系列&#xff0c;《如龙》至今已经推出了有十多部作品&#xff0c;它凭借着经典的日式RPG玩法吸引了不少忠实粉丝。早在2022年9月的时候&#xff0c;世嘉就已经公布了最新的正统续作《如龙8》&#xff0c;而在经历了一年半的等待以后&#xff0c;我…

jvs-rules(规则引擎)1.23功能更新说明,新增SQL变量、数据源等

规则引擎更新功能 新增: 1、新增SQL变量&#xff1a; SQL变量通常指的是在执行SQL查询时使用的动态变量。这些变量允许在查询中注入或更改某些值&#xff0c;以便根据不同的条件或输入执行不同的查询。 1.1 新增自定义SQL语言进行数据查询&#xff1b; 用户可以使用自定义的…

强化学习12——策略梯度算法学习

Q-learning、DQN算法是基于价值的算法&#xff0c;通过学习值函数、根据值函数导出策略&#xff1b;而基于策略的算法&#xff0c;是直接显示地学习目标策略&#xff0c;策略梯度算法就是基于策略的算法。 策略梯度介绍 将策略描述为带有参数 θ \theta θ 的连续函数&#…

Pycharm运行提示(运行‘Python测试(00.py内)‘(u)

为什么有时候我在pycharm中运行代码会出现图片中的问题&#xff1f; 我们该如何改过来&#xff1f; 很简单 点击文件-设置 点击Python集成工具&#xff0c;在默认测试运行程序里修改为Unittest即可 再次运行代码就会显示正常的运行 你的pycharm可能是英文 如何英文变中文&…

鸿蒙APP的应用场景

鸿蒙APP可以用于多种场合和设备类型&#xff0c;这是鸿蒙系统的分布式能力和多终端适配的优势。以下是一些鸿蒙APP的应用场景&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.智能手机和平板电脑&am…

开源:两个免费的年会抽奖项目

前言 年会抽奖项目平常基本不用&#xff0c;只有到年终才会排上用场。开发的时长也不会给太久&#xff0c;而且也只是自家公司内部使用的&#xff0c;所以不需要部署&#xff0c;数据库后端甚至都可以省略&#xff1b;然后我就找了个开源的 符合我要求的年会抽奖项目进行二次开…

CSS 图片遮罩学习小节

概念&#xff1a;-webkit-mask-image是一项用于制作镂空图形和图形遮罩效果的CSS样式属性。 -webkit-mask-image 的值既可以是渐变色也可以是图片地址。 -webkit-mask-image 的起源很早&#xff0c;但兼容性不好&#xff0c;因此用途并不广泛。 效果如下&#xff1a; 底图&…

Spring Security 6 学习-1

什么是 Spring Security Spring Security文档 Spring Security中文文档 Spring Security 是 Spring 家族中的安全型开发框架&#xff0c;主要解决三大方面问题&#xff1a;认证&#xff08;你是谁&#xff09;、授权&#xff08;你能干什么&#xff09;、常见攻击保护&#xff…