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

news2024/12/24 3:43:07

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.coloradmin.cn/o/1406496.html

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

相关文章

更改wpf原始默认按钮的样式

样式 代码 <Window x:Class"WpfApp4.Window1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008…

【linux】Debian挂起和休眠

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

详细分析Java中的list.foreach()和list.stream().foreach()

目录 前言1. 基本知识2. 差异之处2.1 执行顺序2.2 串行并行2.3 复杂数据处理2.4 CRUD集合2.5 迭代器 3. 总结4. 彩蛋 前言 典故来源于项目中使用了两种方式的foreach&#xff0c;后面尝试体验下有何区别&#xff01; 先看代码示例&#xff1a; 使用List的forEach&#xff1a…

风丘车辆热管理测试方案

车辆热管理是在能源危机出现、汽车排放法规日益严格以及人们对汽车舒适性要求更高的背景下应运而生的。将各个系统或部件如冷却系统、润滑系统和空调系统等集成一个有效的热管理系统&#xff1b;控制和优化车辆的热量传递过程&#xff0c;保证各关键部件和系统安全高效运行&…

麒麟系统—— openKylin 安装到虚拟机以及开放SSH通过工具连接

麒麟系统—— openKylin 安装到虚拟机以及开放SSH通过工具连接 1. 在VMware中安装openKylin麒麟系统步骤1&#xff1a;准备VMware环境步骤2&#xff1a;创建新的虚拟机步骤3&#xff1a;安装openKylin麒麟系统步骤4&#xff1a;调整分别率步骤5&#xff1a;安装SSH 2. 使用Open…

安卓自动缩放布局

AutoScalingLayout 适用于 Android 的自动缩放布局。 替换布局&#xff1a; 我们只需要替换根布局所需的自动缩放&#xff0c;子布局也将实现自动缩放。 原始布局AutoScalingLayout相对布局ASRelativeLayout线性布局ASLinearLayoutFrameLayout&#xff08;框架布局&#xff…

SpringCloud Bus动态刷新全局广播

文章目录 代码地址配置项目配置修改测试 SpringCloud Bus动态刷新定点通知 代码地址 地址:https://github.com/13thm/study_springcloud/tree/main/days11_%20Bus 配置项目 必须先具备良好的RabbitMQ环境先 演示广播效果&#xff0c;增加复杂度&#xff0c;再以3355为模板再…

Python基础第九篇(Python可视化的开发)

文章目录 一、json数据格式&#xff08;1&#xff09;.转换案例代码&#xff08;2&#xff09;.读出结果 二、pyecharts模块介绍三、pyecharts模块入门&#xff08;1&#xff09;.pyecharts模块安装&#xff08;2&#xff09;.pyecharts模块操作&#xff08;1&#xff09;.代码…

nvm安装与使用教程

目录 nvm是什么 nvm安装 配置环境变量 更换淘宝镜像 安装node.js版本 nvm list available 显示可下载版本的部分列表 nvm install 版本号 ​编辑 nvm ls 查看已经安装的版本 ​编辑 nvm use 版本号(切换想使用的版本号) nvm是什么 nvm是node.js version management的…

c++学习笔记-STL案例-机房预约系统6-老师模块

前言 衔接上一篇“c学习笔记-STL案例-机房预约系统5-学生模块”&#xff0c;本文主要设计老师模块&#xff0c;从&#xff0c;老师登录和注销、查看所有预约、审核预约三个方面进行分析和实现。 目录 9 教师模块 9.1 教师登录和注销 9.1.1 构造函数 9.1.2 教师子菜单 ​编…

java web mvc-07-Vaadin 入门介绍

拓展阅读 Spring Web MVC-00-重学 mvc mvc-01-Model-View-Controller 概览 web mvc-03-JFinal web mvc-04-Apache Wicket web mvc-05-JSF JavaServer Faces web mvc-06-play framework intro web mvc-07-Vaadin web mvc-08-Grails 开源 The jdbc pool for java.(java …

通信入门系列——复变函数

本节目录 一、复变函数 1、复数 2、复数的四则运算 二、复指数函数 三、欧拉公式本节内容 一、复变函数 1、复数 复数单位i&#xff0c;也就是满足i^2-1&#xff0c;将zxiy表示为复数z&#xff0c;x和y为任意的实数&#xff0c;称为复数z的实部和虚部。由复数zxiy对应的点(x,y…

LiveGBS流媒体平台GB/T28181常见问题-如何配置使用自己已有的redis服务替换redis版本升级redis版本

LiveGBS如何配置使用自己已有的redis服务替换redis版本升级redis版本 1、Redis服务2、如何切换REDIS?2.1、停止启动REDIS2.2、配置信令服务2.3、配置流媒体服务2.4、启动 3、搭建GB28181视频直播平台 1、Redis服务 在LivGBS中Redis作为数据交换、数据订阅、数据发布的高速缓存…

TensorRT英伟达官方示例解析(一)

系列文章目录 TensorRT英伟达官方示例解析&#xff08;一&#xff09; TensorRT英伟达官方示例解析&#xff08;二&#xff09; 文章目录 系列文章目录前言一、参考资料二、配置系统环境三、00-MNISTData四、01-SimpleDemo4.1 Makefile4.2 main.cpp4.3 main.py 总结 前言 一、…

上位机图像处理和嵌入式模块部署(自定义算法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 我们在使用opencv的时候&#xff0c;虽然大部分算法都不需要我们自己重头开始编写&#xff0c;但是总有一些关于我们自己产品的know-how&#xff0…

Redis--Bitmap有序集合的语法和使用场景举例

文章目录 前言Bitmap概述Bitmap命令介绍使用场景结尾 前言 Redis除了常见的五种数据类型之外&#xff0c;其实还有一些少见的数据结构&#xff0c;如Geo&#xff0c;HyperLogLog&#xff0c;Bitmap等。虽然它们少见&#xff0c;但是作用却不容小觑。本文将介绍Bitmap数据类型的…

c语言-柔性数组

文章目录 前言一、柔性数组的介绍1.1 柔性数组的定义 二、柔性数组的使用2.1 使用说明2.2 结构体中的成员只包含一个柔性数组成员2.3 结构体中的成员包含其他成员和一个柔性数组成员 三、模拟柔性数组总结 前言 本篇文章介绍c语言中的柔性数组。 一、柔性数组的介绍 1.1 柔性…

【动态规划】【字符串】【C++算法】940. 不同的子序列 II

作者推荐 【动态规划】【广度优先搜索】【状态压缩】847 访问所有节点的最短路径 本文涉及知识点 动态规划汇总 LeetCode940. 不同的子序列 II 给定一个字符串 s&#xff0c;计算 s 的 不同非空子序列 的个数。因为结果可能很大&#xff0c;所以返回答案需要对 10^9 7 取…

MySQL之数据库DDL

文章目录 MySQL数据库基本操作数据定义DDL对数据库的常用操作创建表修改表格式结构 MySQL数据库基本操作 首先我们先了解SQL的语言组成&#xff0c;他分为四个部分 数据定义语言&#xff08;DDL&#xff09;数据操纵语言&#xff08;DML&#xff09;数据控制语言&#xff08;…

网络安全---防御保护--子接口小实验

子接口小实验&#xff1a; 环境准备&#xff1a; 防火墙区域配置为trust&#xff1a; PC设置其ip为同一个网段&#xff1a; 此时尝试ping无法ping通的原因是没有打开防火墙允许ping&#xff0c;我们在图形化界面允许ping即可 最终结果&#xff1a; .com域名服务器&#xff1a; …