本人在传统的语音通信公司做过手机和IP电话上的语音软件开发,也在移动互联网公司做过APP上的语音软件开发。现在带实时语音通信功能的APP有好多,主流的有微信语音、QQ电话、钉钉等,当然也包括我开发过的那款APP(那款APP在实时通信APP排名中一直靠前)。既然都做语音软件开发,那肯定有很多共同的地方,比如需要相同的语音专业知识,都有语音前处理、编解码、传输等。通过自己的观察,也有一些不同的地方。我们今天主要聊聊这些不同点。
1,在传统语音通信公司都是在具体硬件上开发音频软件。有了硬件就要有相应的驱动,在Linux/Android上就是ALSA相关的驱动软件开发。对于前处理、编解码、传输等模块,既可以在底层做也可以在偏上面的层次做,这取决于软件架构。我曾经在Linux平台上硬件一样软件需求一样的情况下由于软件架构不一样开发过两套语音方案。一套方案是驱动在kernel space做,前处理、编解码、传输等在user space做。另一套方案是驱动和前处理、编解码、传输等全部在kernel space做。之所以要做两套方案是因为第一套方案的性能不够好,尤其表现在one way delay上。
在移动互联网公司做APP上的语音软件都是在上层做开发。驱动等对开发人员是黑盒子,开发人员要做的有前处理、编解码、传输等,用好系统提供的API就可以了。以Android为例,对做APP来说用好media framework里提供的audio相关的(AudioRecord/AudioTrack等)API 就可以了。
2,上面说过在传统语音通信公司里都是在具体硬件上开发软件,一些音频相关的参数就只有一套,在这个硬件上调好了就可以了。而在APP上做语音软件开发,不针对具体的硬件。但是一些音频参数要依赖于硬件,不同的硬件上参数不一样,一个手机上调的效果很好的参数到另一个是手机上可能效果就很糟糕,所以在APP上做音频软件开发一个很重要的工作就是硬件适配。在不同的机型上用不同的参数,最起码也要把主流的机型适配好,一些用户量大的APP要适配上百款甚至几百款机型。以回声消除为例,它的一个很重要的参数就是从speaker(远端)出来到mic(近端)进去的时延,不同的机型时延不一样,这主要因为两点:1)硬件不一样,2)做APP都是在上层做,它要从底层拿到远端和近端的PCM数据,不同的手机底层实现不一样,时延也会不一样。开发时就要把尽可能多的机型上的时延得到保存起来,用户使用时根据不同的机型给出不同的时延值。
3,在传统通信公司开发语音软件,如果做有线产品,codec一般选用ITU-T的G系列(G711/G722/G726/G729等),如果做无线产品,codec一般选用3GPP的AMR系列(AMR-NB/AMR-WB等)。在APP上做语音软件开发,codec更多的会选用互联网阵营里提出来的iLBC/OPUS等。现在做语音通信,基本上形成了两大阵营,即以ITU-T/3GPP为代表的传统阵营和互联网阵营,在codec上都有各自的演进策略。传统阵营会演进到EVS(支持语音和音乐,最高48K采样),互联网阵营会演进到OPUS(支持语音和音乐,最高96K采样)。中国移动已要求移动终端17年底可选支持EVS,18年中必须支持EVS,传统阵营要求这么快演进也是被形势所逼。前几天微信语音功能进行了更新,可以像系统电话那样来接听微信语音电话,又要革电话的命了,以前革了短信的命。个人觉得互联网公司在语音codec上选择iLBC/OPUS还有一个原因是因为他们的语音方案多基于开源的来做,比如webRTC,而这些codec是开源方案里天然支持的,互联网又要求快,他们必然会选择这些已经调试适配好的codec。
4,在传统通信公司开发语音软件,一定要严格遵守各种协议(主要有3GPP/ITU-T/RFC的),不能有自己私有的协议,因为要过互通性测试。运营商在采购通信设备时一般会采购多家设备商的(采购多家设备商的设备有多方面原因,其中之一就是不想让一家设备商一家独大形成垄断从而受制于他),通信终端更是多种多样,大家必须遵守相同的协议才能互通,所以一定要严格遵守各种协议。
在移动互联网公司开发APP上的语音软件,客户端(前台)是自己开发维护,服务器(后台)也是自己开发维护,即所有都是自己开发维护,不存在跟其他厂家的产品互通。这样就会用很多私有协议。我开发过的那款APP就用了好多私有协议,有的是自己提出来的,有的是对已有公开协议的改造。这些协议如果有文档还好,如果没文档在看代码时就会特别累。
5,传统通信网络通常会划分为终端、接入网、核心网等不同的网元,如下图:
作为语音通信,终端会把采集到的语音编码后打包经过attached的接入网设备核心网设备到对方attached的接入网设备再到对方终端播放出来。一般接入网设备和核心网设备只会透传语音数据不会修改语音数据。
在APP上开发语音软件,一般采用client-server机制,如下图。
Client A 与Client B进行语音通信,A把语音数据发给B。A先把语音数据发给server的PORT A,server会把PORT A的数据路由到PORT B,再由PORT B把语音数据发给Client B。为了保证语音质量,一般会做两次补偿,先在server的PORT A上根据丢包率等做一次补偿,尽可能复原出Client A发出的语音数据。再在Client B上做补偿,尽可能复原出PORT B发出的语音数据。也就是说server会对客户端发过来的语音数据做修改的,而不是透传的。
6,在传统通信公司做语音软件开发,一定要过运营商的入网认证,包括各种场景下的语音质量(MOS值)、one-way-delay、round-trip-delay等指标。这些指标一定要过,不然拿不到入网证,拿不到入网证也就不能卖产品了。这些指标通常都是拿仪器测是否通过,要想过运营商的指标,公司一般都会有音频实验室,里面放着运营商指定的各种仪器,来模拟指定的各种场景。自己公司实验室里指标测过了才有信心拿到运营商指定的实验室去测。过认证是一个很痛苦的过程,因为这些都是系统性的问题,解决起来都是不容易的,有可能某个指标花了很长时间解决都不达标。话说回来,解决这些系统性问题的过程也是自己能力提高的过程,整个指标一遍做下来,能力会有一个大的提高。
在移动互联网公司做APP上的语音软件开发,不会有入网认证,任何时候都可以发布产品。一般公司也不会建音频实验室,因为建一个音频实验室花费较大(像腾X这样的巨头是有的,它做的很专业,它的两款APP产品这么大的用户量要求它必须做的很专业,做的不专业音质不好会把产品口碑做差的,而且这点花费对它来说不算什么)。各种场景下的语音质量等指标没有一个确切的数据。用户下载了APP用后觉得语音质量好就会继续用,觉得语音质量不好的话就会卸掉不会再用了。
-A
备份全库
-B
备某一个数据库下的所有表
-R, --routines
备份存储过程和函数数据
--triggers
备份触发器数据
--master-data={1|2}
告诉你备份后时刻的binlog位置
如果等于1,则将其打印为CHANGE MASTER命令; 如果等于2,那么该命令将以注释符号为前缀。
--single-transaction
对innodb引擎进行热备
-F, --flush-logs
刷新binlog日志
-x, --lock-all-tables
锁定所有数据库的所有表。这是通过在整个转储期间采用全局读锁来实现的。
-l, --lock-tables
锁定所有表以供读取
-d
仅表结构
-t
仅数据
--compact
减少无用数据输出(调试)
一个完整的备份语句:
innodb引擎的备份命令如下:
mysqldump -A -R --triggers --master-data=2 --single-transaction |gzip >/opt/all_$(date +%F).sql.gz
适合多引擎混合(例如:myisam与innodb混合)的备份命令如下:
mysqldump -A -R --triggers --master-data=2 |gzip >/opt/all_$(date +%F).sql.gz
1.3.3 -A 参数
备份全库,备份语句
mysqldump -uroot -p123 -A > /backup/full.sql
1.3.4 -B 参数
备某一个数据库下的所有表
增加建库(create)及“use库”的语句,可以直接接多个库名,同时备份多个库* -B 库1 库2
mysqldump -uroot -p123 -B world > /backup/worldb.sql
备份语句:
create database if not 存在
use db1
drop table
create table
insert into
不加-B备份数据库时,只是备份数据库下的所有表,不会创建数据库
只能备份单独的数据库(一般用于备份单表时使用)
mysqldump -uroot -p123 world > /backup/world.sql
备份单表
mysqldump -uroot -p123 world city > /backup/world_city.sql
对于单表备份的粒度,再恢复数据库数据时速度最快。
备份多个表
mysqldump 库1 表1 表2 表3 >库1.sql
mysqldump 库2 表1 表2 表3 >库2.sql
分库备份:for循环
mysqldump -www.dfgjyl.cn/ uroot -p'mysql123' -B mysql ...
mysqldump www.chushiyl.cn -uroot -p'mysql123' -B mysql_utf8 ...
mysqldump http://feishenbo.cn/ -uroot -p'mysql123' -B mysql ...
......
分库备份
for name in `mysql -e "show databases;"|sed 1d`
do
mysqldump -uroot -p'mysql123' -B $name
done
1.3.5 --master-data={1|2}参数
告诉你备份后时刻的binlog位置
2为注释 1为非注释,要执行的(主从复制)
[root@db02 logs]# sed -n '22p' /opt/t.sql
CHANGE MASTER TO MASTER_LOG_FILE='clsn-bin.000005', MASTER_LOG_POS=344;
[root@db02 logs]# mysqldump -B --master-data=2 clsn >/opt/t.sql
以上就是我基于做过的公司观察到的一些不同点,有可能有遗漏,后面想到了再补上。也有可能其他移动互联网公司做法有不同的地方,欢迎大家补充
今天是2018年的第一天,祝大家新年快乐!希望自己在18年多出精品,自己知道不可能高产,差不多一个月两篇原创的节奏。平时工作很忙,周末有私事,包括带小孩参加各种培训班,好多都是周末在小孩上课时我写出来的。
1,在传统语音通信公司都是在具体硬件上开发音频软件。有了硬件就要有相应的驱动,在Linux/Android上就是ALSA相关的驱动软件开发。对于前处理、编解码、传输等模块,既可以在底层做也可以在偏上面的层次做,这取决于软件架构。我曾经在Linux平台上硬件一样软件需求一样的情况下由于软件架构不一样开发过两套语音方案。一套方案是驱动在kernel space做,前处理、编解码、传输等在user space做。另一套方案是驱动和前处理、编解码、传输等全部在kernel space做。之所以要做两套方案是因为第一套方案的性能不够好,尤其表现在one way delay上。
在移动互联网公司做APP上的语音软件都是在上层做开发。驱动等对开发人员是黑盒子,开发人员要做的有前处理、编解码、传输等,用好系统提供的API就可以了。以Android为例,对做APP来说用好media framework里提供的audio相关的(AudioRecord/AudioTrack等)API 就可以了。
2,上面说过在传统语音通信公司里都是在具体硬件上开发软件,一些音频相关的参数就只有一套,在这个硬件上调好了就可以了。而在APP上做语音软件开发,不针对具体的硬件。但是一些音频参数要依赖于硬件,不同的硬件上参数不一样,一个手机上调的效果很好的参数到另一个是手机上可能效果就很糟糕,所以在APP上做音频软件开发一个很重要的工作就是硬件适配。在不同的机型上用不同的参数,最起码也要把主流的机型适配好,一些用户量大的APP要适配上百款甚至几百款机型。以回声消除为例,它的一个很重要的参数就是从speaker(远端)出来到mic(近端)进去的时延,不同的机型时延不一样,这主要因为两点:1)硬件不一样,2)做APP都是在上层做,它要从底层拿到远端和近端的PCM数据,不同的手机底层实现不一样,时延也会不一样。开发时就要把尽可能多的机型上的时延得到保存起来,用户使用时根据不同的机型给出不同的时延值。
3,在传统通信公司开发语音软件,如果做有线产品,codec一般选用ITU-T的G系列(G711/G722/G726/G729等),如果做无线产品,codec一般选用3GPP的AMR系列(AMR-NB/AMR-WB等)。在APP上做语音软件开发,codec更多的会选用互联网阵营里提出来的iLBC/OPUS等。现在做语音通信,基本上形成了两大阵营,即以ITU-T/3GPP为代表的传统阵营和互联网阵营,在codec上都有各自的演进策略。传统阵营会演进到EVS(支持语音和音乐,最高48K采样),互联网阵营会演进到OPUS(支持语音和音乐,最高96K采样)。中国移动已要求移动终端17年底可选支持EVS,18年中必须支持EVS,传统阵营要求这么快演进也是被形势所逼。前几天微信语音功能进行了更新,可以像系统电话那样来接听微信语音电话,又要革电话的命了,以前革了短信的命。个人觉得互联网公司在语音codec上选择iLBC/OPUS还有一个原因是因为他们的语音方案多基于开源的来做,比如webRTC,而这些codec是开源方案里天然支持的,互联网又要求快,他们必然会选择这些已经调试适配好的codec。
4,在传统通信公司开发语音软件,一定要严格遵守各种协议(主要有3GPP/ITU-T/RFC的),不能有自己私有的协议,因为要过互通性测试。运营商在采购通信设备时一般会采购多家设备商的(采购多家设备商的设备有多方面原因,其中之一就是不想让一家设备商一家独大形成垄断从而受制于他),通信终端更是多种多样,大家必须遵守相同的协议才能互通,所以一定要严格遵守各种协议。
在移动互联网公司开发APP上的语音软件,客户端(前台)是自己开发维护,服务器(后台)也是自己开发维护,即所有都是自己开发维护,不存在跟其他厂家的产品互通。这样就会用很多私有协议。我开发过的那款APP就用了好多私有协议,有的是自己提出来的,有的是对已有公开协议的改造。这些协议如果有文档还好,如果没文档在看代码时就会特别累。
5,传统通信网络通常会划分为终端、接入网、核心网等不同的网元,如下图:
作为语音通信,终端会把采集到的语音编码后打包经过attached的接入网设备核心网设备到对方attached的接入网设备再到对方终端播放出来。一般接入网设备和核心网设备只会透传语音数据不会修改语音数据。
在APP上开发语音软件,一般采用client-server机制,如下图。
Client A 与Client B进行语音通信,A把语音数据发给B。A先把语音数据发给server的PORT A,server会把PORT A的数据路由到PORT B,再由PORT B把语音数据发给Client B。为了保证语音质量,一般会做两次补偿,先在server的PORT A上根据丢包率等做一次补偿,尽可能复原出Client A发出的语音数据。再在Client B上做补偿,尽可能复原出PORT B发出的语音数据。也就是说server会对客户端发过来的语音数据做修改的,而不是透传的。
6,在传统通信公司做语音软件开发,一定要过运营商的入网认证,包括各种场景下的语音质量(MOS值)、one-way-delay、round-trip-delay等指标。这些指标一定要过,不然拿不到入网证,拿不到入网证也就不能卖产品了。这些指标通常都是拿仪器测是否通过,要想过运营商的指标,公司一般都会有音频实验室,里面放着运营商指定的各种仪器,来模拟指定的各种场景。自己公司实验室里指标测过了才有信心拿到运营商指定的实验室去测。过认证是一个很痛苦的过程,因为这些都是系统性的问题,解决起来都是不容易的,有可能某个指标花了很长时间解决都不达标。话说回来,解决这些系统性问题的过程也是自己能力提高的过程,整个指标一遍做下来,能力会有一个大的提高。
在移动互联网公司做APP上的语音软件开发,不会有入网认证,任何时候都可以发布产品。一般公司也不会建音频实验室,因为建一个音频实验室花费较大(像腾X这样的巨头是有的,它做的很专业,它的两款APP产品这么大的用户量要求它必须做的很专业,做的不专业音质不好会把产品口碑做差的,而且这点花费对它来说不算什么)。各种场景下的语音质量等指标没有一个确切的数据。用户下载了APP用后觉得语音质量好就会继续用,觉得语音质量不好的话就会卸掉不会再用了。
-A
备份全库
-B
备某一个数据库下的所有表
-R, --routines
备份存储过程和函数数据
--triggers
备份触发器数据
--master-data={1|2}
告诉你备份后时刻的binlog位置
如果等于1,则将其打印为CHANGE MASTER命令; 如果等于2,那么该命令将以注释符号为前缀。
--single-transaction
对innodb引擎进行热备
-F, --flush-logs
刷新binlog日志
-x, --lock-all-tables
锁定所有数据库的所有表。这是通过在整个转储期间采用全局读锁来实现的。
-l, --lock-tables
锁定所有表以供读取
-d
仅表结构
-t
仅数据
--compact
减少无用数据输出(调试)
一个完整的备份语句:
innodb引擎的备份命令如下:
mysqldump -A -R --triggers --master-data=2 --single-transaction |gzip >/opt/all_$(date +%F).sql.gz
适合多引擎混合(例如:myisam与innodb混合)的备份命令如下:
mysqldump -A -R --triggers --master-data=2 |gzip >/opt/all_$(date +%F).sql.gz
1.3.3 -A 参数
备份全库,备份语句
mysqldump -uroot -p123 -A > /backup/full.sql
1.3.4 -B 参数
备某一个数据库下的所有表
增加建库(create)及“use库”的语句,可以直接接多个库名,同时备份多个库* -B 库1 库2
mysqldump -uroot -p123 -B world > /backup/worldb.sql
备份语句:
create database if not 存在
use db1
drop table
create table
insert into
不加-B备份数据库时,只是备份数据库下的所有表,不会创建数据库
只能备份单独的数据库(一般用于备份单表时使用)
mysqldump -uroot -p123 world > /backup/world.sql
备份单表
mysqldump -uroot -p123 world city > /backup/world_city.sql
对于单表备份的粒度,再恢复数据库数据时速度最快。
备份多个表
mysqldump 库1 表1 表2 表3 >库1.sql
mysqldump 库2 表1 表2 表3 >库2.sql
分库备份:for循环
mysqldump -www.dfgjyl.cn/ uroot -p'mysql123' -B mysql ...
mysqldump www.chushiyl.cn -uroot -p'mysql123' -B mysql_utf8 ...
mysqldump http://feishenbo.cn/ -uroot -p'mysql123' -B mysql ...
......
分库备份
for name in `mysql -e "show databases;"|sed 1d`
do
mysqldump -uroot -p'mysql123' -B $name
done
1.3.5 --master-data={1|2}参数
告诉你备份后时刻的binlog位置
2为注释 1为非注释,要执行的(主从复制)
[root@db02 logs]# sed -n '22p' /opt/t.sql
CHANGE MASTER TO MASTER_LOG_FILE='clsn-bin.000005', MASTER_LOG_POS=344;
[root@db02 logs]# mysqldump -B --master-data=2 clsn >/opt/t.sql
以上就是我基于做过的公司观察到的一些不同点,有可能有遗漏,后面想到了再补上。也有可能其他移动互联网公司做法有不同的地方,欢迎大家补充
今天是2018年的第一天,祝大家新年快乐!希望自己在18年多出精品,自己知道不可能高产,差不多一个月两篇原创的节奏。平时工作很忙,周末有私事,包括带小孩参加各种培训班,好多都是周末在小孩上课时我写出来的。