【实践分享】教你直播的解决方案

  备案动态     |      2023-09-07
【实践分享】教你直播的解决方案

导语

风口上飞的永远是猪,但如果你仔细看,你会发现它永远不会是同一头。

如果说人工智能是2019年最火的猪,那么2020年一定是直播。斗鱼、虎牙等都养成了看直播的习惯。薇娅和李佳琪让直播带入了大家的视线,而“老罗”罗永浩的入局个人认为是真正意义上的直播了。子业完整。老罗之后,各行业纷纷将直播带入P0的产品需求。本文将介绍如何基于腾讯云服务实现一套直播解决方案。

基础介绍

本文涉及的腾讯云服务主要包括云直播和云点播视频两个产品。主要从主播端推流、用户端播放、视频录制和播放三个角度介绍实现过程。在介绍具体方案之前,我们先来看看什么是推、拉、直播、点播?

推流:主播将本地视频源和音频源推送到腾讯视频云服务器,部分场景也称为“RTMP发布”。直播:直播视频源实时生成。只有有人推流,直播才有意义。同时,一旦主播停止直播,直播网址将失效。而且由于是实时直播,所以播放器在播放直播视频时是没有进度条的。点播:点播实际上对应的是视频源是云端的文件,只要该文件不被提供商删除,就可以随时播放(类似腾讯视频),而由于整个视频都在服务器上,因此无需播放。进度条。点播是视频播放的基础。我们将分别解决这个问题: 1. 直播; 2、视频录制和回放; 3、账户资源隔离。

直播推拉流

为了实现直播,需要两个必要的元素,推流地址和播放地址。我们先看一下流地址的生成。

推流

云直播平台为我们提供了以数字开头的系统直播域名。当然,基本上在官方项目的使用中,我们也可以添加自己注册的域名进行串流。根据直播域名,我们可以计算出直播地址。流地址有一套拼接算法。符合腾讯云标准的推流URL由以下四部分组成:

我们来实际计算一个推流地址,域名假设为12345.livepush.myqcloud.com,AppName假设为live,StreamName假设为stream_test_01,txSecret用于防止盗链(可以在下配置)各个域名)假设为1qaz2wsx ,txTime 表示当前推流的有效期,可以用于告知腾讯云URL 过期时间,假设为2020-05-28 23:59:59。那么我们可以得到的流地址是:

rtmp://99995.livepush.myqcloud.com/live/stream_test_01?txSecret=691bef580972ac54691b1e5ee40460ectxTime=5ECDFFFFF

以上推流为2020-05-28 23:59:59之前可推流至云端的游戏网址,推流成功后即可在推流中看到实时在线直播控制台的管理。注意:txSecret字段用于安全防盗链。其作用是防止攻击者伪造您的后台生成推送URL或非法窃取您的播放地址牟利。

拉流

关于直播域名,需要添加我们自己注册的直播域名。然后只需要填写与推流地址相同的StreamName,就可以播放对应的流了。拉取地址也有与推送地址类似的合成算法,这里不再赘述。

上述汇编算法逻辑的Java实现demo如下:

private static String byteArrayToHexString(byte[] data) { char[] out=new char[data.length 1]; for (int i=0, j=0; i data.length; i++) { out[j++]=DIGITS_LOWER [(0xF0 data[i]) 4]; out[j++]=DIGITS_LOWER[0x0F 数据[i]]; } return new String(out);} private static String getSafeUrl(String key, String streamName, long txTime) { String input=new StringBuilder().append(key).append(streamName).append(Long.toHexString(txTime) .toUpperCase()).toString();字符串txSecret=null;尝试{ MessageDigest messageDigest=MessageDigest.getInstance(' MD5'); txSecret=byteArrayToHexString(messageDigest.digest(input.getBytes('UTF-8'))); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace() ;返回txSecret==null ? '' : new StringBuilder().append('txSecret=').append(txSecret).append('').append('txTime=').append(Long.toHexString(txTime ).toUpperCase()).toString ();}public ListString CreateLiveUrls(String streamName, long txTime) { String pushExt=getSafeUrl(cloudVideoConfig.getPushKey(), streamName, txTime); String pullExt=getSafeUrl(cloudVideoConfig.getPullKey() , streamName, txTime);字符串appid='直播'; String PushUrl=String.format('rtmp://%s/' + appid + '/%s?%s', cloudVideoConfig.getPushDomain(), StreamName, PushExt) ; String pullUrl=String.format('http://%s/' + appid + '/%s.flv?%s', cloudVideoConfig.getPullDomain(), streamName, pullExt); ListString 列表=new ArrayList();列表.add(pushUrl);列表.add(pullUrl); return list;} 复制一下,对于appid,我们使用live,没有任何其他改动,因为在整个云直播系统中,一个直播流是通过流名唯一标识的,无论哪个应用。当我们推送数据流成功后,我们就可以从码流管理测试中观看,当然也可以在VLC中通过网络码流进行观看测试。

录播回放

介绍完推拉流后,我们来介绍如何实现视频播放和观看的功能。

首先我们来看一下我们的需求是什么,视频播放,显然当前主播的直播结束后,需要将完整的直播内容播放给用户。腾讯云云直播服务通过开放云点播服务,将原始直播流转换为音视频包得到的文件存储(不修改音频、视频数据以及对应的时间戳等信息)来实现直播。到云点播平台。视频存储。

直播录制

云直播平台支持API或控制台创建和录制直播视频。从功能上来看,有4种记录方式:

使用场景

阐明

根据推流域名和流名进行多级录制

您可以配置是否在推送域名和流名级别进行录制。

按指定时间段记录

您可以通过调用API控制录音的开始和结束时间,并按照您指定的时间进行录音。

精彩视频录制

当直播过程中遇到精彩场景时,可以通过调用API实时生成录音。

仅音频录制

如果流式传输为纯音频,您可以配置AAC 纯音频录制。

如果你想详细了解不同场景下使用哪种方法,可以去官网详细了解。在我们目前描述的场景中,主要是为了实现直播流的完整播放功能,所以我们采用第一种方法,即能够对推流下的所有直播流进行录制。为了实现该功能,我们需要在云直播-功能模板-录音配置中配置模板,截图如下:

可以看到上面的子应用进行录制的地方就是指定云点播平台的应用。然后进入域名管理,将上面配置的录音模板绑定到我们的直播域名地址上,如下图:

绑定完成后,我们就形成了流媒体-录制模板-点播端这样的录制数据流向。

点播

上面提到了,我们的直播录音数据是存储在云端点播服务中的。接下来我们继续介绍云点播平台。进入点播后,默认如下图所示。其中,所有从云直播放置的视频记录都显示在媒体资产管理中。

云点播除了提供基本的视频存储外,还具有视频编辑等一系列重要的增值功能。

视频拼接

完成以上配置后,我们就可以实现一个基本的直播-播放-评论功能线了。不过细心的同学可能会发现两个问题:

1、录制模板配置中最大时长只有120分钟,但现在直播时长大概率会超过120分钟。如果超过了怎么办?

2、直播过程中,主播经常会断开视频流(主动断开或因网络不好被动断开),这样的断开会影响视频播放吗?

也就是说,在一次完整的直播过程中,我们的录制文件可能会被分成很多部分并存储在云端,而如果需要正常播放,就需要将这些视频文件按照正确的顺序重新组织成一个完整的文件。为了解决这个视频拼接问题,我们需要借用服务端视频编辑API的能力。 EditMedia接口可以对视频进行编辑(剪切、拼接等),生成新的点播视频。编辑功能包括:

点播编辑文件生成新视频;按需拼接多个文件生成新视频;按需编辑拼接多个文件生成新视频;直接点播流生成新视频;按需剪辑流以生成新视频;按需拼接多个码流生成新视频;多个流被剪辑然后拼接生成新的视频。我们这里主要使用第二个功能:点播中拼接多个文件,生成新的视频。关于视频编辑接口的具体参数和使用方法,可以去官网查看,下面是java中的调用方法:

private String editMedia(ListString fileIds) { EditMediaResponse resp; try { //参数生成int len=fileIds.size(); EditMediaFileInfo[] 文件=new EditMediaFileInfo[len]; for (int i=0; i len; i++) { EditMediaFileInfo f=new EditMediaFileInfo(); f.setFileId(fileIds.get(i));文件[i]=f; EditMediaRequest req=new EditMediaRequest(); req.setFileInfos(文件); //req.setSessionId() ;//TODO req.setInputType(VOD_INPUT_TYPE_FILE); req.setDefinition(VOD_DEFINITION_HIGH_DEFINITION); req.setTasksPriority(VOD_PRIORITY_MEDIUM); req.setSubAppId(cloudVideoConfig.getVodSubAppId()); //启动拼接点播录制任务Credential cred=new Credential(cloudVideoConfig .getSecretId(), cloudVideoConfig.getSecretKey()); ClientProfile clientProfile=new ClientProfile(); clientProfile.setSignMethod(ClientProfile.SIGN_TC3_256); VodClient 客户端=new VodClient(cred, cloudVideoConfig.getRegion(), clientProfile );响应=客户端。编辑媒体(请求); } catch (Exception e) { e.printStackTrace(); log.info(e.getMessage());抛出新的UserBizException(BizErrorCode.VOD_GENERATOR_RECORD_ERROR); } return resp.getTaskId();} 复制视频片段完成的文件也像之前云直播中经常生成的文件一样按需放到云端。当然,每个文件的fileid是不同的。对于文件类型,我们可以通过视频源、录制或视频处理来区分。

事件处理

为什么要提到事件处理?上面我们讲了如何推流、拉流,然后如何通过视频片段获取播放内容。但串联和推动整个过程的却是一个又一个的事件。那么我们来介绍一下直播和点播中的事件处理流程。

直播事件处理

开始/暂停推流

直播/暂停推送事件是主播开始/停止推送时,直播服务内部发生事件,消息会通过事件通知服务回调给观众。是否向受众推送消息是业务需求,但是通过关注这个事件,我们可以及时获取流的开启状态,这是非常有必要的。

为了接收直播事件,我们需要进入云直播-功能模板-回调配置,进行类似的配置操作,如下:

配置回调模板后,需要将直播域名与回调模板绑定才能生效,如下图:

在做事件接收的时候,需要注意的几个点就是几个检查:

1、对于事件时间验证,需要保证过去事件的时间不能与当前服务器时间相差太大,可以通过字段t与当前时间进行比较来判断;

2、事件类型验证需要保证传入事件的类型是需要的类型。事件枚举如下:

直播事件,event_type=1 直播事件,event_type=0 录制文件生成事件,event_type=100 截图文件生成事件,event_type=200 复制3. 事件签名验证,签名算法可参考文档:sign=MD5 ( key + t),腾讯云将加密密钥与t连接,通过MD5计算出符号值,放入通知消息中。您的后台服务器收到通知消息后,可以根据相同的算法符号确认其是否正确,进而确认该消息是否确实来自腾讯云后台。

当这些检查通过后,就可以处理事件的内容。

文件生成事件

我们在介绍录播的时候,需要做视频拼接,但是什么时候进行视频编辑,每个剪辑视频文件的地址(或者云文件fileid)是多少,这就是文件生成事件通知云直播平台相关事宜已通报。

文件生成事件的处理方法与上面提到的类似,这里不再赘述。这里需要提到的是,由于事件是异步的,所以我们在接收事件和处理文件列表时需要特别注意顺序,不能颠倒拼接文件的顺序。这将导致整个录制的视频出现问题。

点播事件处理

我们上面提交了视频编辑请求后,编辑后的文件的生成也是基于事件通知的。云点播平台提供了视频编辑完成事件供我们使用。当应用配置了事件通知时,在编辑视频后,应用后台可以通过“正常回调”或“可靠回调”获取事件通知。事件通知内容是EditMediaTask结构体。

资源隔离

以上内容基本结束了整个直播流程。这里需要介绍一下云直播和云点播平台的资源隔离系统。因为项目使用的时候,云点播的所有资源都存储在这里。一个很大的问题就是资源隔离的问题。例如,我们通常使用腾讯云帐户,但需要同时承载不同的项目。每个项目都有一套腾讯云账号,因此需要隔离不同环境下不同项目应用的数据。

云直播资源隔离

我们来看看云直播的资源隔离系统。从实际使用的角度来看,假设我们有两个项目proj1和proj2,同时有环境dev、qa和online,我们一般申请域名如下:

----proj1推流

proj1-dev.push.tencent.com

proj1-qa.push.tencent.com

proj1.push.tencent.com

----proj1拉流

proj1-dev.pull.tencent.com

proj1-qa.pull.tencent.com

proj1.pull.tencent.com

----proj2推流

proj2-dev.push.tencent.com

proj2-qa.push.tencent.com

proj2.push.tencent.com

----proj2拉流

proj2-dev.pull.tencent.com

proj2-qa.pull.tencent.com

proj2.pull.tencent.com

首先我们需要非常清楚,腾讯云账号下的云直播的流媒体资源是通过streamId的流名来区分的,与域名无关。这意味着域名之间不存在隔离和映射关系。当我们有多个推流域名时,无论使用哪个域名推流,只要streamId相同,就是同一个流。同理,当一个云账号下有多个流媒体域名时,只要获取到流媒体名称,任何一个流媒体域名都可以播放流媒体数据。基于这样的前提,我们必须保证stream id的唯一性,并且根据不同的环境,streamId最好有一个前缀/后缀标识。

当然,至于需要帮助推流和拉流进行一一绑定,实现完全隔离,控制台上没有这个东西,但是你可以去咨询相关人员,或者启动工单咨询,也许会有一点惊喜。

云点播资源隔离

为了让开发者能够在云点播中实现资源隔离,云点播提供了子应用特性。这里所说的资源包括云点播中的媒体文件及其属性、由媒体文件衍生的其他文件、各种配置、CDN域名、使用点播服务产生的统计信息等。

分应用是VOD的一个内部概念,是一种资源划分方式。子应用的对外表现类似于独立的点播账号。创建子应用前后,我们对比点播资源的归属形式如下图所示:

通过使用子应用,我们可以实现:多部门/多业务隔离、权限控制、区分正式环境和测试环境等。子应用系统中存在三种身份:管理员、主应用和子应用,子应用的介绍可以在官网看到。

当我们的账户打开子应用系统时,我们的控制台侧边栏的颜色会变成白色(应该是为了区分显示),我们可以在不同的应用之间切换(管理员、主应用、子应用A、子应用)乙等):

那么,我们的直播解决方案中,如何应用到这里的点播子应用系统中呢?这就又回到了我们上面的云直播模板配置界面。在录音模板界面,当我们启用云点播子应用时,就可以选择我们直播录音模板的【录制到子应用】。相应的点播应用实现了从直播到点播的资源隔离。

总结

通过以上,基于腾讯云的能力,我们详细介绍了如何推直播、拉流、事件处理、项目环境资源隔离四大方面。其实基于这些已经可以实现一个标准的直播项目了。当然,我们的项目肯定有业务需求远不止于此,比如带货、直播间、计划管理等等,这需要所有研发兄弟和产品兄弟,斗智斗勇,祝你好运!