前言

由于项目需要最近接到公司的一个研发任务,尝试开发视频直播功能,要求双方可以对讲互动,并提供微信小程序、PC、Web等版本。由于之前对流媒体技术有所积累,这个任务只要满足功能演示,因此这个任务对我来说还不是太困难。技术人员要对自身掌握的技术要不断更新,技术的积累不要仅满足于工作,更要拓展自身的技术视野,不断去尝试哪些新技术。只有这样在将来的工作中才不至于被突入其来的新任务为难。

技术

视频直播其实就是把基于硬件产生的模拟信号数据化的过程,但涉及的技术方面比较广,我也只是学习了一些皮毛,在这里简单介绍一下,视频直播其它主要包括音频和视频的数据整合,单向的流媒体数据传输过程主要如下六大过程。详见“视频直播技术随笔”文章中有详细说明。

1. 音视频数据采集

主要是通过终端硬件设备产生原始音视频数据模拟信号,如手机、摄像头、麦克等,现在主流音频数据主要是PCM格式数据,视频数据主要是YUV格式的数据,由于这些数据是直接由硬件设备产生,对硬件设备有天然的高契合度。此外还需重点关注数据的“采样率”、“位宽”、“声道”和“帧”等参数。

2. 数据加工处理

主要针对已经过采样的音视频数据在编码前需要进行必要的优化处理,这此阶段要对音视频数据进行降噪处理,原始的PCM和YUV数据中由受环境、电路、辐射等影响产生大量的冗余噪点。这些冗余数据使严重影响音视频的质量。因此我们在音视频数据采集完成后要进行二次工作处理。
视频:降噪、水印、滤镜等
音频:降噪、混音、特效等

3. 流媒体数据编码

音视频二次加工处理完成以后就需要进行编码操作了,编码其它就是数据压缩,为了数据可以在网络中快速传播,我们要想办法把数据体积压缩到最小。
视频:H.264、H.2645、VP8、VP9等格式,主流使用H.264。
音频:SPEEX AAC, OPUS, G.711等格式,主流使用AAC。

4. 数据网络传输

数据压缩完成以后要进行网络传输,对实时性要求不高的应用视频直播平台一般都使用RTMP协议进行数据的传输,RTMP是在TCP之上的网络协议。对于实时互动要求高的视频直播则必须使用UDP进行数据传输。

5. 流媒体数据解码

就是将对编码数据做反向操作。如音频是AAC编码,则它再解为PCM格式数据。视频是H.264再解为YUV数据。

6. 音视频渲染播放

对于音频直接将PCM数据放入到音频驱动缓冲驱,驱动程序就会将音频播放出来。对于视频一般会通过 opengl利用 GPU进行图像渲染。

实现

微信小程序版
微信小程序提供了2个组件live-pusher以及live-player来完成对音视频的数据推送和拉取等操作,但是因为官方文档过于简略,以至于很多人难以上手。
视频流推送 live-pusher
微信小程序通过live-pusher标签将手机麦克和摄像头产生的媒体数据通过RTMP网络协议向媒体服务器端推送数据,详细参数说明可以查阅微信开放文档。
视频流拉取 live-player
微信小程序通过live-player标签采用RTMP网络协议从指定媒体服务器拉取媒体流数据进行渲染,详细参数说明可以查阅微信开放文档。

界面设计

模仿微信视频电话的界面,实现点对点的视频对讲功能。
pusher.wxml的代码如下:

<view class="page-body"><view class="page-section tc"><!-- 拉流--><live-player id="player" src="{{playerUrl}}" mode="RTC" autoplay object-fit="fillCrop"  bindstatechange="onPlayerStateChange" bindnetstatus="onPlayerNetstatusChange" binderror="onError"  wx:if="{{isplayerexit}}" ><cover-view class="btn-area"><cover-view bindtap='bindMute' class="page-body-button btn-mute"><cover-image src="../../images/mute{{muteStatus}}.png" class="img-mute"></cover-image></cover-view><cover-view bindtap='bindStop' class="page-body-button btn-stop">挂断</cover-view><cover-view bindtap="bindSwitchCamera" class="page-body-button btn-camera"><cover-image src="../../images/camera.png" class="img-camera"></cover-image></cover-view></cover-view></live-player><!-- 推流--><live-pusher id="pusher" url="{{pusherUrl}}" mode="RTC" autopush bindstatechange="onPusherStateChange" wx:if='{{ispusherexit}}' style="width:{{pusherwidth}};height:{{pusherheight}}"><cover-view class="btn-area" wx:if="{{isIconShow}}"><cover-view bindtap='bindStop' class="page-body-button btn-stop">挂断</cover-view></cover-view><cover-view class="fullscreen"   style="top:{{top}};right:{{right}}"></cover-view></live-pusher></view>
</view>

上面代码所示live-player 中mode属性指明要将声音与视频数据一起推送到src绑定的服务器地址。设置autoplay可以地界面加载完成后自动开始数据推送操作。
pusher.js 业务逻辑代码如下:

var room = require("../../service/roomService.js");
var videoStream = require("../../component/videoStream.js");
const string = require("../../utils/string.js");
const app = getApp()
Page({wxPusher: null, ///推流器wxPlayer: null, ///拉流器hasPerson: null,otherRoom: '',data: {ispusherexit: true, //推流是否存在pusherUrl: '', //推流地址isplayerexit: true, //拉流是否存在playerUrl: '', //拉流地址pusherwidth: '100px',pusherheight: '100px',isIconShow: true,top: '5px',right: '5px',muteStatus: '1'},onReady(res) {this.wxPusher = wx.createLivePusherContext('pusher')this.wxPlayer = wx.createLivePlayerContext('player');this.setData({pusherUrl: videoStream.pusher.url(),});},onLoad(option) {this.otherRoom = option.roomid;string.isEmpty(this.otherRoom, this.getSelfRommPerson, roomid => {console.log("进入其它直播间");this.setData({playerUrl: videoStream.player.url(roomid)});});},getSelfRommPerson: function () {var that = this;this.hasPerson = setInterval(function () {room.otherPerson(person => {that.setData({playerUrl: videoStream.player.url(person.id)});clearInterval(that.hasPerson);});}, 1000);},//点击左上角的返回时调用onUnload() {string.isEmpty(this.otherRoom, s=>{room.delete();}, s => {room.removeSelf(s);});},onPlayerNetstatusChange: function (e) {videoStream.player.event.netstatus(e);},onPlayerStateChange: function (e) {videoStream.player.event.statechange(e);},onPusherStateChange: function (e) {videoStream.pusher.event.statechange(e);},onError: function (e) {videoStream.error(e);},//停止推流bindStop(e) {console.log("停止推流");this.wxPusher.stop()wx.reLaunch({url: '/pages/index/index'})},//转换摄像头bindSwitchCamera() {this.wxPusher.switchCamera()},//拉流静音bindMute() {if (this.data.muteStatus == '1') {this.setData({muteStatus: '0'})} else {this.setData({muteStatus: '1'})}this.wxPlayer.mute();}
})

运行结果

总结

通过测试微信小程序对RTMP支持还是很给力的,点对点视频流推送延迟也做了细致优化,基本可以满足实际项目中的应用。

视频直播终端开发之微信小程序版相关推荐

  1. 基于云开发的微信小程序:个人相册ByUestcXiye

    基于云开发的微信小程序:个人相册ByUestcXiye 作业要求 第一次作业 第二次作业 结课作业 小程序开发入门 开发前的准备 注册微信小程序 新建一个模板小程序 开通云开发服务 第一次作业 参考资 ...

  2. 开发一个微信小程序,对酒店经营管理有哪些好处?

    据腾讯2022年第一季度财报数据显示,微信小程序日活跃账户已经突破5亿,流量巨大.不论企业用户还是个体商家都积极使用小程序开展商业活动,从这庞大流量里获利. 酒店行业也不例外,很多酒店都开发了微信小程 ...

  3. 【微信小程序控制硬件 第13篇】安信可B站直播学习总结,微信小程序MQTT远程控制ESP8266 NodeMCU,谈谈微信生态那些事;

    [微信小程序控制硬件第1篇 ] 全网首发,借助 emq 消息服务器带你如何搭建微信小程序的mqtt服务器,轻松控制智能硬件! [微信小程序控制硬件第2篇 ] 开始微信小程序之旅,导入小程序Mqtt客户 ...

  4. 云开发(微信-小程序)笔记(十四)---- 收藏,点赞(上)

    云开发(微信-小程序)笔记(十三)---- 注册登陆 1.简介 点赞,收藏等都是程序的最简单的功能,在现实的应用中也很常见.这里我就来给大家介绍一下小程序的这个功能. 图标下载地址 先去网站上http ...

  5. 都2020年,开发制作微信小程序商城,需要准备什么资料?应该不会不知道吧!

    微信小程序使用越来越广泛,而还未入局的对于微信小程序开发需要什么材料甚至不清楚,其实这些材料很简单.总结就是微信支付.微信小程序注册.小程序代码,下面展开说说. 小程序红利 从腾讯刚发布的财报看,微信 ...

  6. vue.js反编译_基于electron-vue开发的微信小程序反编译客户端

    开源一个小程序反编译客户端 咨询小程序反编译的同学比较多,虽然有开源库但是还是有同学不清楚如何去操作,所以索性做了一个客户端方便进行小程序的反编译 # 技术选型 网上已经有大佬实现了C#版的反编译工具 ...

  7. core和node开发小程序_成都小程序开发:微信小程序开发要多少钱?

    定制开发一个微信小程序要多少钱呢? 成都小程序开发需要多少钱,成都小程序定制多少钱,成都小程序开发获得报价 微信小程序背靠腾讯的亿级流量,有着非常强大的线上引流功能,目前微信小程序的开发越来越火爆,选 ...

  8. 一个程序如何连接到外网_如何从头开始开发一个微信小程序

    网上有很多的人在问:怎么开发一个微信小程序?今天我来给大家详细讲讲如何申请开发并部署一个微信小程序,大家看完这篇文章后就能够自己运营一个属于自己的小程序了. 现在的小程序有百度小程序,头条小程序,支付 ...

  9. 全栈开发工程师微信小程序-上(中)

    全栈开发工程师微信小程序-上(中) width: 750rpx; 复制代码 750rpx代表与屏幕等宽,rpx的缩写responsive pixel,这个单位是可以根据屏幕大小进行自适应调整的像素单位 ...

最新文章

  1. Hessian 初探
  2. boost之timer,progress_timer,progress_display的介绍及使用
  3. el-input 输入框类型;只能输入数字的输入框;保留两位小数输入框;只能输入正整数和0的输入框;手机号正则校验;车牌号码正则校验
  4. 2797:最短前缀 Trie
  5. oracle的脚本语言是什么意思,Oracle中的sql脚本语言中的循环语句介绍
  6. 将一个数组拼接成一个指定字符串返回
  7. 10000个科学难题书籍介绍
  8. 为php-fpm安装pdo pgsql驱动支持
  9. 大数据可视化陈为智慧树_智慧树知到_大数据可视化_答案新版
  10. 前台 时不时报 could not proxy request_长春中考成绩不理想可以报的高中
  11. I00007 打印菱形字符图案
  12. 分层架构(第一张章)
  13. 汉诺塔问题(递归之路)
  14. Java 网络爬虫,就是这么的简单
  15. 安装wps后,新建的excel报错,因为文件格式或着文件扩展名无效
  16. linux类mac桌面,让Linux Mint看起来更像Mac桌面的主题
  17. ajax谷歌浏览器提示等待超时,调用谷歌浏览器爬虫,selenium webdriver等设置等待时间和超时时间...
  18. 12款免费HTML5开发框架和开发工具…
  19. pyecharts 在地图上根据经纬度和量值,画出散点图/热力图
  20. centos7.6下载地址

热门文章

  1. css鼠标滑过按钮出现flash闪光效果
  2. amr格式转换为MP3格式
  3. 扫描二维码和签到打卡应用程序
  4. android widget零基础,Android Widget详解(一)
  5. BAT的“江湖地位”毋庸置疑,但互联网公司这些奇葩绰号,你知道吗?
  6. 电子书籍下载网站集锦(不断更新中...)
  7. python中保留字的含义_Python中的变量之保留字与标识符
  8. mysql innodb repair_MySQL数据库INNODB 表损坏修复处理过程 无法repair的变通方法
  9. 2022年全球及中国家用破壁料理机行业头部企业市场占有率及排名调研报告
  10. 4核处理器_麒麟990和麒麟990e哪个处理器好?选择哪款芯片更好?