1 绪论
1.1 课题研究背景
现如今流媒体短视频行业发展迅猛,人们越来越趋向于对短视频和直播类型的娱乐消费。短视频吃掉用户的大量碎片时间,有更强的时间
粘性、更年轻的用户群、更好的变现方式。在短视频江湖,“南抖音、北快手”的竞争格局基本形成,美图的美拍、新浪的秒拍、头条的火
山小视频、西瓜视频等产品基本瓜分了剩余的市场份额。
2017年短视频独立App用户已突破4.1亿人,较去年同期增长116.5%;2017年短视频使用时长占移动互联网总使用时长的5.5%,而这一
比例在2016年刚刚达到1.3%。中国互联网络信息中心(CNNIC)第42次 《中国互联网络发展状况统计报告》显示,截至2018年6月30日,
中国网民规模达8.02亿,互联网普及率为57.7%。短视频应用迅速崛起,74.1%的网民使用短视频应用。 抖音,快手,微视等软件的
快速崛起也证明了直播和短视频类型软件的地位在日渐上升。在全球市场上TikTok走出国门,迅速在全球市场积攒了大量用户。并且国家
网信办网站在3月22日发布消息:国家互联网信息办公室、工业和信息化部、公安部、国家市场监督管理总局四部门联合发布《常见类型
移动互联网应用程序必要个人信息范围规定》,自2021年5月1日起执行。进一步证明了国家方面对此类移动互联网软件重视,要求无需
个人信息即可使用基本功能。因此基于微信小程序端的视频直播内容的App,有着充分的优势,前期用户的积累无需绑定他们的隐私信
息,例如手机、姓名、邮箱等等。平台用户的唯一标识为调用微信wx.login接口返回的OpenID,通过微信的的开放接口获取,无需注册
等繁琐的步骤,从这种角度上来说,所有的微信用户都可以扫码一键成为平台的用户,解决前期用户难注册、难留下的问题。
1.2 国内外研究现状
近年来随着互联网技术、5G、人工智能等的发展,还有互联网头部企业的涌入,为短视频媒体直播的发展提供了充分的条件,更加方便
了内容的输出和用户的交互体验,直播+短视频的内容方式成为了当下的趋势。腾讯、百度、阿里相应推出了自己旗下的短视频直播
APP。根据艾媒咨数据中心的统计,预测中国在2020年结束,在线直播的用户数量将会到达5.26亿。国家与地方都制定了相应的政策予以
支持,例如上海市经信委发布《上海市促进在线新经济发展行动方案》,鼓励直播电子商务,积极推动了行业的发展。在国外市场
TikTok、Kwai、Vmate、都有了自己的一席之地,未来全球在短视频直播的领域中,需求还会进一步的扩大。
1.3 系统实现目标
本次实现的目标为,设计实现一个后台管理、微信小程序、服务提供者三个主要模块的分布式直播系统。后台管理主要功能有视频拍摄的
背景音乐管、视频内容的审核、直播资质的审核、直播间的管理,账号管理、邮件发送。微信小程序端,短视频方面提供拍摄、观看、上
传三部分功能,用户可以根据自己的喜好关注和喜欢相应的视频和内容创作者,直播间主要有拉流观看和弹幕功能,用户提出申请后,得
到管理员审核通过后方可进行直播。服务提供者有注册中心、配置中心、网关、账户服务、内容上传服务、邮件服务、直播间服务、推拉
流服务。因为推拉流需要的并发流量较大,所以为了减少网关压力,除了直播间的推拉流所有HTTP服务都通过网关访问。
2 微服务架构设计
2.1 微服务架构简介
近年来,微服务是备受关注的概念。有人主张微服务是一种革命性的技术创新,也有人认为微服务并没有什么新鲜的,只不过是对SOA
(面向服务架构)的优化重塑。我不想争论这些,因为无论是支持还是反对,都无法阻挡微服务在敏捷开发和复杂的企业级应用开发中的
优势。
通过微服务,我们在应用开发和部署方面取得了显著的进步。将应用开发或者重构成微服务以分离服务,通过 API 以明确的方式来相
互“对话”。例如,每个微服务都是自包含(self-contained),各自维护自己的数据存储(这非常有意义),可以独立更新其服务。
使用基于微服务的方式使得应用程序开发变得更快更容易管理,它只需要较少的人力就能实现更多的功能,可以更快更容易地部署。把应
用程序设计成一套微服务,更加容易在多台具有负载均衡的服务器上运行,使其能够轻松应对需求高峰、由于时间推移而平稳增长的需求和由于硬件或者软件问题导致的宕机事故。
微服务的最大进步在于改变了我们的工作方式。敏捷软件开发技术、应用迁移云端、DevOps 文化、持续集成与持续部署(CI/CD)和容器应用都使用了微服务来革新应用开发与交付。
我们先来看微服务的发展史。
从最原始的单体应用开始:
微服务是由面向服务的架构SOA演变而来,是一种云原生的架构方法,整个应用程序由多个松耦合的服务组成,通常由业务模型划分出最小颗粒度的服务。传统的开发模式下应用程序高度耦合,一处功能的修改往往需要整个模块的重构,部分并发量高的接口可能会拖垮整个程序,虽然后期可以通过Nginx反向代理负载均衡,依然无法从根本上解决上述问题。而在微服务架构下每个服务有自己单独的数据库,它们可以互不依赖的单独部署上线,极大的方便了整个应用程序的迭代更新,减少了后期的运维成本。服务之间通过轻量级的协议RPC远程调用协议或者基于HTTP协议的RESTFUL API 通信。但是微服务架构依然客观存着错误难以定位,开发周期较长,成本开销大等问题。在微服务架构中,一个服务的崩溃可能会导致所有后续服务的超时,产生雪崩效应使整个应用程序不可用,通过熔断器可以有效的减少这种情况发生的概率,对响应超时的服务熔断、隔离,从而使整个应用程序高可用。
2.2 SpringCloud简介
SpringCloud是目前Java方向较为活跃的微服务框架,集合了常用的微服务组件,它帮助开发人员快速构建出一个微服务架构的应用程序,使开发人员聚焦于业务领域。SpringCloud主要由五个组件组成,的每个组件单元由SpringBoot Application组成。五大组件如下图1所示。
图2-1 SpringCloud五大组件图
SpringCloud是基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了基于NetFlix的开源组件做高度抽象封装之外,还有一些选型中立的开源组件。
SpringCloud利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,SpringCloud为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等,它们都可以用SpringBoot的开发风格做到一键启动和部署。
SpringCloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过SpringBoot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包
SpringCloud与SpringBoot的区别 SpringBoot专注于快速方便的开发单个个体微服务。
SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务
SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖的关系.
SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。
2.3 开发环境简介
后端的开发环境为:Java编辑器为IntelliJ IDEA,是一款智能的Java编辑器,具有强大DEBUG断点调试功能,减少不必要的重复工作。Java开发工具包Oracle JDK11,依赖管理工具使用的是Maven,关系型数据库MySQL8.0,使用非关系型数据库Redis做外部缓存,提高系统的并发能力。多媒体处理工具FFmpeg,对用户拍摄的MP4视频与MP3音频编码合成。推拉流服务器使用由Go语言编写的开源服务器Livego,与Nginx服务器性能接近,并且配置相对容易,可以跨平台编译,运行非常方便。
前端开发环境为:Node.js基于Chrome V8引擎的JavasSript,版本为14..16.1LTS长期支持版、Vue2和微信开发者工具。
3 系统概要设计
3.1 功能分析
项目主要有两种账户角色:管理员和用户,分别对应不相同的功能模块。管理员端的登录凭证为邮箱,有密码和邮箱验证码两种方式,登录后可进入管理员的网站页面,未登录的请求页面全部拦截重定向到登录页面。登录后的主要主要操作有系统监控方面,监控显示当前系统的各个服务实例健康状态。视频管理主要是对用户拍摄上传的视频进行内容审核,审核通过才可以在小程序端展示给所有用户,对审核通过的视频也可以撤销审核进行二次检查。合拍音乐分为上传和管理两部分,上传音乐需要填写对应的表单和上传音乐封面海报。直播间管理功能是对用户申请开设直播的审核,和对正在直播的直播间的内容审核。账户管理则为添加修改管理员账号,系统的功能概要图3如下所示:
图3-1系统功能分析图
3.2 服务划分
根据系统的功能模块将系统抽象划分为邮件服务、上传服务、账户服务、直播间服务,服务Service间使用自定义的Http Client通信。每个服务只负责自己的独立部分,统一使用Go WEB框架iris对外提供RESTFUL API服务。邮件服务负责发送邮件和验证码两个主要功能。上传服务有视频上传、音频上传、图片上传、文件下载、合成MP3和MP4。账户服务有管理员和用户两个主要模块,主要由账户主体的信息获取、登录、授权等。直播间服务主要为直播间的检索和直播服务器的推拉流。
3.3 系统架构实现
系统架构为SpringCloud+Go框架下的微服务架构,使用注册中心动态服务发现的模式。成功启动后等待被注册中心发现同步后,Gateway网关会从Eureka注册中心拉取服务名和每个服务实例的IP与端口号,映射为自定义的路由,前端通过自定义的路由访问,统一进行鉴权。数据层的服务有MySQL和Redis两部分,使用Redis Cache的模式减轻数据库的压力。直播服务器流量较大所以不通过网关,并且拉流属于公共行为,推流需要密匙,所以拉流和推流直接开放接口。系统架构图如下图4所示:
图3-2系统架构图
4 数据库设计
4.1 数据库需求分析
数据库的模型设计中,大部分的表结构之间存在相互关联,使用外建或者级连的方式虽然方便了业务模块的编写,但是对数据库端的并发性能影响较大,一个数据的操作可能使关联的多个表进行修改操作,外建和级连的数据库模型设计更适合在单机情况下,并不适用于分布式体系下。因此表的关联全部封装在应用层,在各个Service的中处理关联逻辑。
首先用户信息的保存需要一张用户表,由于用户端只存在小程序端,主键id设置为微信的openId。视频的上传观看需要视频表,用户在拍摄视频时可选择相应的音乐合拍,所以需要音乐表相关联,并且需要存入是否使用音乐的字段,用户在对视频进行点赞操作时首先需要判断用户是否对同一视频点过赞,不能单独在视频表中存入点赞数量统计,可通过视频点赞表与视频和用户两者关联。用户评论操作时需要评论表,评论表要存入视频主键id。直播功能主要负责存储直播间的基本信息和拉流的地址。
4.2 表结构设计
(1)用户表t_user主要存放小程序端用户的基础信息,主键设置为微信的openId,因为部分用户可能只进行简单的浏览,不需要获取个人信息,因此将用户的身份信息字段默认为空,在用户允许获取身份信息时,在后端执行update操作,更新用户表。
表1 用户信息表 ------ t_user
字段名 | 类型 | 是否为空 | 描述 |
---|---|---|---|
id | varchar (50) | NOT NULL | 主键uuid |
nickname | varchar (50) | DEFAULT NULL | 用户的微信昵称 |
address | varchar (255) | DEFAULT NULL | 用户的地址 |
has_info | tinyint |
DEFAULT
0
|
是否通过微信接口获取过用户信息 |
avatar_url | varchar (255) | DEFAULT NULL | 用户头像地址 |
gender | varchar (1) | DEFAULT NULL | 用户性别 |
follow_count | int |
DEFAULT
0
|
关注的用户数 |
fans_count | int |
DEFAULT
0
|
粉丝数量 |
(2)管理员信息表t_admin主要存放后台管理端管理员的基础信息,主键设置为随机生成的uuid,整张表只包含主键、邮箱、密码三个字段,并且全部不可为空值。邮箱字段前端进行判断,必须要真实存在,主要用于管理员登录时接收邮箱验证码。
表2 管理员信息表 ------ t_admin
字段名 | 类型 | 是否为空 | 描述 |
---|---|---|---|
id | varchar (50) | NOT NULL | 主键uuid |
varchar (50) | NOT NULL | 管理员账号邮箱 | |
password | varchar (50) | NOT NULL | 管理员账号密码 |
(3)短视频点赞关联表t_video_like主要存放用户对短视频点赞操作的记录,首先防止同一用户对一个视频多次点赞,其次用来统计视频的喜欢人数,表中的user_id对应用户的id,video_id对应视频的id
表3 点赞关联表 ------ t_video_like
字段名 | 类型 | 是否为空 | 描述 |
---|---|---|---|
id | varchar (50) | NOT NULL | 主键uuid |
user_id | varchar (50) | NOT NULL | 点赞用户id |
video_id | varchar (50) | NOT NULL | 视频id |
(4)短视频的所有相关信息都存在t_video表中,因为系统中使用了为微服务架构,在查询所有短视频的场景下,每个视频信息都要查询相关的用户数据,但是用户信息不在upload-service服务的范围内,只能调用account-service服务,这样一来,假设每次服务调用耗时100ms,获取10个视频就可能耗时1s,这显然是不实际的。因此将前端需要展示的用户信息也存放在视频表中。
表4 视频信息表 ------ t_video
字段名 | 类型 | 是否为空 | 描述 |
---|---|---|---|
id | varchar (50) | NOT NULL | 主键uuid |
user_id | varchar (50) | NOT NULL | 上传用户id |
user_nickname | varchar (50) | NOT NULL | 上传用户昵称 |
user_avatar | varchar (50) | NOT NULL | 上传用户头像 |
music_id | varchar (50) | DEFAULT NULL | 合拍音乐id |
title | varchar (255) | DEFAULT NULL | 视频标题 |
like_count | int | NOT NULL | 点赞数 |
comment_count | int | NOT NULL | 评论数 |
share_count | int | NOT NULL | 分享数 |
poster | varchar (255) | NOT NULL | 视频封面图 |
url | varchar (255) | NOT NULL | 视频地址 |
use_music | tinyint | NOT NULL | 是否使用音乐 |
music_name | varchar (50) | DEFAULT NULL | 音乐名称 |
music_author | varchar (50) | DEFAULT NULL | 音乐作者 |
music_poster | varchar (50) | DEFAULT NULL | 音乐海报 |
music_url | varchar (50) | DEFAULT NULL | 音乐地址 |
status | varchar (50) | NOT NULL | 审核状态(审核 未审核) |
(5)用户关注表t_follow类似于t_video_like,主要关联用户的关注关系,from_user_id为关注用户的id,to_user_id为被关注用户的id。
表5 关注信息表 ------ t_follow
字段名 | 类型 | 是否为空 | 描述 |
---|---|---|---|
id | varchar (50) | NOT NULL | 主键uuid |
from_user_id | varchar (50) | NOT NULL | 谁关注的 |
to_user_id | varchar (50) | NOT NULL | 关注的谁 |
(6)短视频的评论存储在t_comment表,将部分前台需要展示的用户信息,冗余在其中,原因与上述视频表相同,同一个用户可对同一视频进行多次评论,与点赞模块不同。
表6 关注信息表 ------ t_comment
字段名 | 类型 | 是否为空 | 描述 |
---|---|---|---|
id | varchar (50) | NOT NULL | 主键uuid |
video_id | varchar (50) | NOT NULL | 评论的视频id |
user_id | varchar (50) | NOT NULL | 评论用户的id |
user_nickname | varchar (255) | NOT NULL | 用户昵称 |
user_avatar | varchar (255) | NOT NULL | 用户头像url |
content | varchar (500) | NOT NULL | 评论内容 |
create_at | varchar (50) | NOT NULL | 评论时间 |
(7)表t_music为用户在拍摄视频时的合拍音乐,只允许管理员端添加,表中的所有字段都不允许为空。
表7 音乐信息表 ------ t_music
字段名 | 类型 | 是否为空 | 描述 |
---|---|---|---|
id | varchar (50) | NOT NULL | 主键uuid |
name | varchar (255) | NOT NULL | 音乐名字 |
author | varchar (255) | NOT NULL | 作者 |
url | varchar (255) | NOT NULL | url地址 |
poster | varchar (255) | NOT NULL | 封面海报url |
(8)表t_room主要用于存放所有的直播间信息,为了避免其他用户的恶意推流,设置token字段,存放直播间的推流令牌,令牌生成使用随机的uuid,在线人数保存用户下播后的最后在线人数。直播间的状态分为下播、正在直播、封禁、直播异常四种状态,四种状态的修改都由管理员操作。直播间的url地址为拉流地址,微信小程序端可根据url地址实时的观看直播内容。
表8 直播间信息表 ------ t_room
字段名 | 类型 | 是否为空 | 描述 |
---|---|---|---|
id | varchar (50) | NOT NULL | 主键uuid |
user_id | varchar (50) | NOT NULL | 用户id |
token | varchar (255) | NOT NULL | 推流令牌 |
count | varchar (255) | NOT NULL | 在线人数 |
title | varchar (255) | NOT NULL | 直播间标题 |
url | varchar (255) | NOT NULL | 客户端拉流地址 |
status | int | NOT NULL | 直播间状态 |
user_nickname | varchar (255) | NOT NULL | 主播昵称 |
user_avatar | varchar (255) | NOT NULL | 主播头像url |
user_gender | varchar (1) | NOT NULL | 主播性别 |
5 系统设计与实现
5.1 微服务系统搭建
5.1.1 Eureka环境搭建
Eureka的运行需要依赖于SpringBoot Application,在maven项目的pom.xml文件中添加依赖spring-cloud-starter-netflix-eureka-server,版本为于父工程的spring-boot-starter-parent 2.4.5版本一致,在启动类EurekaApplication上添加\@EnableEurekaServer注解和\@SpringBootApplication注解启动注册中心,添加配置defaultZone为http://localhost:8761/eureka/,应用程序启动成功后,打开浏览器访问控制台检查注册中心是否启动成功,Eureka控制台地址为http://localhost:8761,如下图5所示:
图5-1 Eureka控制台图
5.1.2 Gateway网关搭建
项目中使用的网关为SpringCloud Gateway版本为2.2.5 RELEASE,需要与JDK版本不冲突,网关的启动也需要依赖于\@SpringBootApplication启动,注入注解\@EnableDiscoveryClient,使网关也同步到Eureka注册中心,以此从配置中心拉取服务列表。
网关使用全局过滤器的方式获取每次的请求上下文,自定义的过滤器GlobalResponseFilter需要实现GlobalFilter和Ordered两个接口。网关通过配置文件application.yaml配置四个服务的映射地址,分别为account-service、room-service、email-service、upload-service。网关的部分接口需要web端的请求,需要配置浏览器的跨域CORS策略,否则会导致vue端axios的请求失败,网关的配置文件如下图6所示:
图5-2 Gateway application.yaml配置图
5.1.3 服务注册
系统的服务实例通过Eureka Open API注册到Eureka,使用开源的第三方库eureka-client,实现的原理是新建goroutine定时请求Eureka的REST API。首先注册应用的地址为POST http://localhost:8761/eureka/apps/{appId},Response的编码方式为JSON,注册成功后返回状态码Status 204。服务注册成功后需要定时向Eureka Server发送心跳,发送超时Eureka会注销掉当前应用实例,发送心跳的地址为PUT http://localhost:8761/eureka/apps/{appId}/{instanceId},如果请求成功返回HTTP Status 200,如果当前Eureka Server缓存中不存在当前实例,则返回HTTP Status 404。服务注册实现如下图5-3所示:
图5-3 服务注册实现图
5.1.4 服务调用
Golang服务调用其他服务的方式基于HTTP协议实现,服务调用函数callServices需要传入四个参数serviceName(服务名)、method(请求的HTTP方法)、reqUrl(请求路由)、body(请求携带的数据),返回的两个参数本别为byte切片和error类型。服务调用首先从Eureka获取所有的应用实例,忽略大小写匹配服务,如果服务实例切片长度为0返回错误"服务不存在",然后生成随机数索引,实现负载均衡,通过索引获取切片中的服务实例,实例Instances属性HomePageURL存放实例的IP地址,拼接出最终的请求路径,使用golang标准库net/http新建http client发起请求,使用ioutil.ReadAll读出响应数据给调用的客户端。
图5-4 服务调用实现图
5.2 账户服务
账户服务对外提供用户、管理员、关注信息RESTFUL API接口。用户接口主要有三个分别为根据id查询用户、更新用户信息、用户登录,管理员接口有密码登录、验证码登录、查询管理员,关注接口主要由添加关注、根据用户id获取关注列表。
5.2.1 用户登录
小程序端的用户登录流程为:小程序开始初始化时,会首先进入根目录下app.js中的onLaunch方法,调用微信API"wx.login"。在调用成功的钩子函数中,发送微信服务器返回的code到account-service的登录接口,后台发起HTTP请求微信的https://api.weixin.qq.com/sns/jscode2session接口,需要携带三个参数分别为appid、appSecret、code,接口相应内容中包含用户的openid。openid为微信用户的唯一标识,不同的微信账号对应不同的openid。获取openid之后,查询数据库是否存在主键为此openid的用户,如果存在则接口返回用户信息给小程序端,否则插入一条用户数据,主键为openid,同时插入字段has_info为false,标志用户未统一授权获取微信的昵称、头像、地址等基本信息,在用户点击个人页面时,使用微信的wx.getUserInfo接口弹框提醒用户是否同意小程序获取个人信息,用户同意则根据openid执行upadte操作,同步用户的个人信息,并且has_info字段设置为true,避免二次弹窗提升用户体验。用户登录的代码实现如下图8所示:
图5-4 用户登录代码实现图
5.2.2 管理员登录
管理员提供密码和验证码两种登录方式,密码登录的流程较为简单,核心步骤为根据表单判断邮箱和密码是否相同,根据错误类型抛出异常。邮箱验证码登录方式需要调用邮箱服务,服务调用使用Feign客户端的模式。前端首先要请求管理员验证码登录接口,为了避免发送无用验证码,需要查询是否存在该邮箱的管理员账号,不存在则返回身份验证失败异常,存在则调用EmailFegin的checkEmailCode方法。管理员登录web界面如下图9所示:
图5-5 管理员登录代码实现图
5.3 邮箱服务
邮箱服务主要接口有发送一般邮件、发送验证码邮件、检验验证码三个。发送邮箱使用smtp协议,引入Jar包"spring-boot-starter-mail",在配置文件application.yaml中配置发件人的邮箱和授权码。
验证码为6位随机数字,验证码存储的方案有Redis存储,MySQL存储,内部缓存的方式。验证码不需要持久化,并且验证码的调用仅有管理员端,并发量小,使用Redis反而会提高复杂度舍本逐末,经过比较分析最终决定采用内部缓存的方式,使用Java原生的数据结构ConcurrentHashMap\
图5-6 验证码功能代码实现图
5.4 上传服务
5.4.1 视频录制
-
登录状态下的用户,进入"我的"页面,点击"发个视频"按钮,路由跳转到拍摄视频页。
-
发布页面加载,进入生命周期函数onLoad,通过微信wx.getSetting接口查看当前用户是否打开摄像头权限。
-
如果未授予小程序摄像头权限,由于微信的隐私性要求必须使用按钮的绑定事件方式引导用户打开设置页面,无法通过页面加载的回调函数执行wx.openSetting方法,因此以弹出model框提示的方式引导用户是否进入设置页来开启摄像头权限,在model的确认按钮绑定是时间打开权限设置页面,如果用户点击model对话框的取消则退出视频拍摄页面。下次重新进入该界面依然重复上述步骤。
-
获取到用户的摄像头权限后,\
-
用户点击结束后使用stopRecord方法结束录像,方法内的success回方法返回一个response对象,response中包含本次录制过程的视频,视频第一帧jpg图片的微信临时文件路径,使用wx.uploadFile方法将视频MP4文件和封面jpg格式的图片上传至upload-service。
-
临时文件上传成功后,跳转路由到发布视频的表单页,输入视频的标题,点击发布视频后,弹出对话框提示用户再次确认视频标题,点击确认后保存视频信息到t_video表。小程序端的页面实现如下图11所示:
图5-7 视频录制小程序界面实现图
5.4.2 视频合成
用户可在小程序端进行视频的录制上传,可选择视频的背景音乐,如果选择背景音乐将会扣除原视频的声音,并与选择的音乐合成。视频合成在后端部分完成,通过ffmpeg多媒体工具,在Java中调用Runtime包执行Command命令,ffmpeg合成MP4和MP3代码实现如下图12所示:
图5-8 ffmpeg合成视频实现图
5.5 直播间服务
直播间的主要实现功能为客户端拉流和发送弹幕,用户需首先提出直播申请,等待管理员的审核通过。审核结果会以邮件的方式发送给申请用户,用户在拥有直播资质时,在PC端使用推流软件OBS推送直播流到livego直播服务器中,直播推流的密匙以动态的方式生成。用户每次开始直播时,服务器返回一个随机生成的uuid,生成的uuid为本次直播的推流令牌。微信小程序的直播直播模块界面设计如下图13所示:
图5-9 直播功能模块界面图
直播间的弹幕发送以WebSocket的方式发送,WebSocket是定义在TCP协议之上的全双工通信协议,WebSocket可与服务器保持长连接,允许客户端端主动发送消息,进行双向数据传输。
在用户进入直播间的时候,使用微信官方提供的API wx.connectWebSocket新建一个连接,根据直播间的id连接到对应的服务端。如果连接失败,在回调函数wx.onSocketError中返回给用户错误消息提示,引导用户重新进入直播间。
弹幕发送的方法绑定在用户端"submit"按钮的事件上,判断输入值不为空后,使用socket向服务端发送消息内容,服务端根据房间id找到所有在同一房间id下的socket clients,将消息转发出去。其他在同房间的微信小程序客户端使用wx.onSocketMessage来接受服务端的消息,接收成功后推送到video组件。
6 系统调试与优化
6.1 调试环境简介
首先在小程序权限管理端加入小程序的测试者,使用真机扫码调试,微信小程序基础库版本为2.16.1,同时测试iOS和Android两种手机操作系统下的表现,在微信开发工具中实时预览真机控制台输出的日志信息。手机端与服务器端需要连接在同一Wifi网络下进行通信。
6.2 遇到的问题与解决
本次调试过程遇到的主要问题与解决方法如下:
-
使用微信原生的播放组件live-player时,无法加载直播画面。经过阅读官方文档发现,该组件即使在本地测试不上线发布的条件下,依然需要有企业资质的appid才能调用接口。在阅读文档的同时,观察到video组件在iOS和Android下同时支持m3u8格式,因此意味着video组件可支持HLS协议下的直播流播放,经过真机测试验证,该方案可成功播放出直播流画面。
-
短视频模块使用swiper组件,上下滑动为切换视频,水平滑动为切换推荐列表和关注列表。此方法下水平方向有两个swiper-item,每个item中嵌套一个swiper,导致整个视频页面滑动卡顿掉帧较为严重。因为小程序本身并非原生的App,它运行在Chrom v8引擎上,性能与原生App差距较大,将决方法为推荐视频和关注视频单独出两个页面,一个页面仅包含一个swiper组件,允许垂直滑动禁止水平滑动,真机滑动性能提升明显,手机系统刷新率为60 FPS的条件下,上下快速滑动可保证在53 FPS ~ 60 FPS之间。优化前后小程序性能数据对比如下图14所示:
图6-1 性能优化对比图
-
在上传视频选择其中一首音乐后,后端上传服务报空指针异常,但是选择其他音乐时则无异常。证明异常的出现不在于后端,通过一点点调试,小程序端控制台打印数据,发现在使用歌曲作者名为"IU&李智恩"时,控制台出现运行错误,错误出现在JSON.parse方法上,带有特殊字符"&"会导致小程序端js代码解析json数据异常。解决方法为在管理员端上传音乐时,把name和author字段中的特殊字符过滤掉。
-
在播放与MP3合成的视频时,手机端播放一段时间后视频有声音但是,画面静止,单独使用视频的URL在浏览器打开时,情况依然如此,发现视频长度与拍摄的时长不符的问题,原因在于ffmpeg默认以较长时间的mp3作为最终合成mp4的视频时长,导致原视频的音频被剪掉、并且小程序video组件的controls属性controls为false,看不到播放条造成视频暂停的假象。在ffmpeg中加入命令"-shortest"属性解决问题。
7 结论
经过一段时间的努力,本次毕业设计"基于SpringCloud微服务架构的直播平台的设计与实现"已经完成,在此过程中认识到软件的设计首先要指定好方案,不能盲目的开始,良好的设计才能让之后的实现效率更高,但也不可过度设计。在代码实现的过程中,不放过一个问题,不能以得过且过的态度,每一个小的问题都可能导致日后一个难以寻找的BUG,要脚踏实地一步一个脚印。在用户的交互界面中要注意多使用Loading动画,尽量避免页面闪动的情况,在部分点击事件中加入手机震动反馈、从用户的角度出发提升用户体验。在后端的实现中第一要务是保证数据的正确性,其次是保证性能,需要io操作耗时较长的地方尽量使用异步的方式,代码的编写最好有详细的注释。在数据库的设计中要注意字段的命名规范,统一使用下划线的方式分割,遵守数据库的设计范式。
参考文献
[1] Sam Newman.微服务设计[M].北京:人民邮电出版社.2016
[2] Chris Richardson.微服务架构设计模式[M].北京:机械工业出版社.2019
[3]张峰.应用SpringBoot改变web开发模式[J].科技创新与应用.2017(23):193-194
[4] 王磊.微服务架构于实践[M].北京:电子工业出版社.2016
[5] 陈岩.轻量级响应式框架Vue.js应用分析[J].中国管理信息化.2018(3):181-183
[6] 朱二华.基于Vue.js的Web前端应用研究[J].科技与创新.2017(20):119-121
[7] 刘建宏.MySQL数据库优化于集群[J].专题技术.2017(07):47
[8] 方宇荣.网络直播平台的现状于发展研究[D].北京:北京印刷学院.2017
[9] 孟艳华,罗仲伟,廖佳秋.网络直播内容价值感知与顾客契合[J].中国流通经济.2020(09):56-66
[10] 田志友,周元敏,田雨.微信小程序的媒体价值[J].新媒体研究.2018(01):47-49
[11] 吴高阳.基于NIO的Java高性能网络技术的研究与应用[D].西安:西安电子科技大学.2015
[12] 郭晶晶,刘光尧,汪磊,李志刚.FFmpeg在视频图像处理中的应用[J].刑事技术.2020(03):234-247
[13] 李皓,杨成,刘剑波.一种基于HLS的安全直播方案[J].中国传媒大学学报.2018(04):42-47
[14] Biradar S M , Shekhar R , Reddy A P . Build Minimal Docker Container Using Golang[C]// 2018 Second International Conference on Intelligent Computing and Control Systems (ICICCS). 2019.
[15] Wang C , Sun H , Xu Y , et al. Go-Sanitizer: Bug-Oriented Assertion Generation for Golang[C]// 2019 IEEE International Symposium on Software Reliability Engineering Workshops (ISSREW). IEEE, 2020.
致谢
时光如梭光阴似箭,转眼间大学四年的时光就要结束了,在这四年中要感谢我的导师和同学们,老师们的淳淳教诲和同学们的关心照顾都帮助我成长了许多,导师潘灿林老师在大一的时候与我们交流了大学四年的规划问题和毕业设计的相关问题,认真谦虚的回答了每个人的问题,问了我们每个人的大学计划、职业规划等等,让我在接下来的四年有了一个自己的学习目标,对未来的规划有了清晰的认识。与同学们的交流相处也是我这四年来的大学生活充满着乐趣,在学习中遇到难懂的问题我们互相交流讨论,使原本枯燥的学习也变得生动起来。四年的大学生活让我更加的明白了学习是一辈子的事,做任何事情都要踏踏实实一步一个脚印。
参考文献
- 基于微服务的全媒体英语阅读学习平台的研究与设计(北京邮电大学·臧子晗)
- 面向课堂视频服务系统的设计与实现(华中科技大学·郭誉华)
- 基于Spring技术的大型视频网站后台上传系统的设计与实现(南京大学·徐悦轩)
- 基于开源软件流媒体服务系统的设计与实现(西安电子科技大学·张星亮)
- 面向课堂视频服务系统的设计与实现(华中科技大学·郭誉华)
- 基于开放云平台的微服务架构直播系统设计与实现(华南理工大学·刘慧)
- 基于微服务的全媒体英语阅读学习平台的研究与设计(北京邮电大学·臧子晗)
- 基于开放云平台的微服务架构直播系统设计与实现(华南理工大学·刘慧)
- 基于SpringCloud微服务治理平台的设计与实现(北京邮电大学·祁晖)
- 基于Spring技术的大型视频网站后台上传系统的设计与实现(南京大学·徐悦轩)
- 集成WSH架构技术的Web应用研究与实现(西南交通大学·马崇启)
- 基于微服务架构的在线直播教育平台的设计与实现(华中科技大学·吉国昌)
- 视频内容运营平台服务支持系统的设计与实现(西南交通大学·何开平)
- 视频内容运营平台服务支持系统的设计与实现(西南交通大学·何开平)
- 基于微服务架构的在线直播教育平台的设计与实现(华中科技大学·吉国昌)
本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:代码驿站 ,原文地址:https://m.bishedaima.com/yuanma/35705.html