技术研究之阿里云直播

标签: 无 分类: 未分类 创建时间:2024-11-28 06:21:20 更新时间:2025-01-17 10:39:23

1.前言

阿里云提供了 RTMP 直播服务,有两种计费方式,不包括视频截图,存储量费用。
(1)按量计算:流量阶梯单价 x 流量
假设1000人同时在线并同时观看视频1小时,流量计算方式为:[1000(人)] X [0.5(视频码率Mbps)] X [3600(观看时间/秒)] [1024 8(将Mbps换算为GB)] = 219.7GB,0.29(阶梯流量单价:元/GB)x 219.7(流量:GB) = 63.71 元

适合突发流量的情况。

(2)按峰值带宽计算:峰值带宽阶梯单价 X 峰值
假设1000人同时在线并同时观看视频1小时,流量计算方式为:[1000(人)] X [0.5(视频码率Mbps)] = 500Mbps。1.00(峰值带宽阶梯单价:元/Mbps)X 500 (Mbps) = 500 元

适合全天都平稳进行直播的场景。

超低延时直播RTS按[峰值带宽]计费 1.32 元,还需要加上一个转码费用,如果在 web 端播放 artc 协议,需要做一个转码。

参考文章:
【1】.视频直播 详细价格信息
【2】.视频直播产品定价 流量估计:
【3】.直播转码费用

2.配置域名

这里就要到 视频直播 -> 推/播流域名管理 界面增加域名,其实还挺麻烦的,推流和拉流两个域名还不能一样。

配置完了推流和拉流地址,需要将推流地址和拉流地址进行关联,在拉流地址里面选择 “域名管理” 可以配置推流地址。

参考文章:
【1】.验证域名归属权

3.控制台生成地址

有两种方式生成推流和拉流地址,(1) 控制台,(2) 代码生成。控制台生成 可以直接生成推流和拉流地址
(1) 登录视频直播控制台。

(2) 在左侧导航栏选择直播工具箱 > 地址生成器。

(3) 在直播地址生成器页签,完成以下配置获取推流地址和播放地址。
选择播流域名,关联的推流域名,输入 AppName,StreamName 然后点击开始生成,就可以获取一个 rtmp 地址,可以将这个地址配置到 OBS 中进行直播了。

参考文章:
【1】.生成推流地址和播放地址 表格中RTS地址,即超低延时直播RTS地址,使用前需开通超低延时直播功能。
【2】.直播推流 1.使用OBS推流;2.使用阿里云直播Demo推流;

4.代码生成地址

通过API自定义拼接地址,下面的代码基本上可以使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.lang3.*;
public class Create_Live_Url {

/**
* 计算md5
* @param param
* @return
*/
public static String md5(String param) {
if(param == null || param.length() == 0) {
return null;
}
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(param.getBytes());
byte[] byteArray = md5.digest();

BigInteger bigInt = new BigInteger(1, byteArray);
// 参数16表示16进制
String result = bigInt.toString(16);
// 不足32位高位补零
while(result.length() < 32) {
result = "0" + result;
}
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* 生成推流地址
* @param pushDomain 推流域名
* @param pushKey 推流域名配置的鉴权Key
* @param appName 推流AppName
* @param streamName 推流StreamName
* @param expireTime 过期时间(单位是秒)
*/
public static void generate_push_url(String pushDomain,String pushKey,String appName,String streamName,long expireTime) {
String pushUrl = "";
//推流域名未开启鉴权功能的情况下
if(pushKey=="") {
pushUrl = "rtmp://"+pushDomain+"/"+appName+"/"+streamName;
}else {
long timeStamp = System.currentTimeMillis()/1000L + expireTime;
String stringToMd5 = "/"+appName+"/"+streamName+"-"+Long.toString(timeStamp)+"-0-0-"+pushKey;
String authKey = md5(stringToMd5);
pushUrl = "rtmp://"+pushDomain+"/"+appName+"/"+streamName+"?auth_key="+Long.toString(timeStamp)+"-0-0-"+authKey;
}
System.out.println("推流地址是: "+pushUrl);
}
/**
* 生成播放地址
* @param pullDomain 播放域名
* @param pullKey 播放鉴权Key
* @param appName 播放appName(同推流appName)
* @param streamName 播放streamName,播放源流时,streamName 同推流streamName;播放转码流时,streamName 为推流streamName_{转码模板ID}
* @param expireTime 过期时间(单位是秒)
*/
public static void general_pull_url(String pullDomain,String pullKey,String appName,String streamName,long expireTime) {
String rtmpUrl = ""; //rtmp的拉流地址
String hlsUrl = ""; //m3u8的拉流地址
String flvUrl = ""; //flv的拉流地址
String artcUrl =""; // 超低延迟
//播放域名未配置鉴权Key的情况下
if(pullKey == "") {
rtmpUrl = "rtmp://"+pullDomain+"/"+appName+"/"+streamName;
hlsUrl = "http://"+pullDomain+"/"+appName+"/"+streamName+".m3u8";
flvUrl = "http://"+pullDomain+"/"+appName+"/"+streamName+".flv";
}else {
long timeStamp = System.currentTimeMillis()/1000L + expireTime;
String rtmpToMd5 = "/"+appName+"/"+streamName+"-"+Long.toString(timeStamp)+"-0-0-"+pullKey;
String rtmpAuthKey = md5(rtmpToMd5);
rtmpUrl = "rtmp://"+pullDomain+"/"+appName+"/"+streamName+"?auth_key="+Long.toString(timeStamp)+"-0-0-"+rtmpAuthKey;

String hlsToMd5 = "/"+appName+"/"+streamName+".m3u8-"+Long.toString(timeStamp)+"-0-0-"+pullKey;
String hlsAuthKey = md5(hlsToMd5);
hlsUrl = "http://"+pullDomain+"/"+appName+"/"+streamName+".m3u8"+"?auth_key="+Long.toString(timeStamp)+"-0-0-"+hlsAuthKey;

String flvToMd5 = "/"+appName+"/"+streamName+".flv-"+Long.toString(timeStamp)+"-0-0-"+pullKey;
String flvAuthKey = md5(flvToMd5);
flvUrl = "http://"+pullDomain+"/"+appName+"/"+streamName+".flv"+"?auth_key="+Long.toString(timeStamp)+"-0-0-"+flvAuthKey;

String artcToMd5 = "/"+appName+"/"+streamName+"-"+Long.toString(timeStamp)+"-0-0-"+appKey;
String artcAuthKey = md5(artcToMd5);
artcUrl = "http://"+pullDomain+"/"+appName+"/"+streamName+"?auth_key="+Long.toString(timeStamp)+"-0-0-"+artcAuthKey;
}
System.out.println("RTMP播放地址为: "+rtmpUrl);
System.out.println("m3u8播放地址为: "+hlsUrl);
System.out.println("flv播放地址为: "+flvUrl);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//生成长度为5的随机字符串作为appName和streamName(字母和数字组合)
String appName = RandomStringUtils.randomAlphanumeric(5);;
String streamName = RandomStringUtils.randomAlphanumeric(5);;

long expireTime = 3600L;
String pullDomain = "mxl-pull.pier39.cn";
String pullKey = "querty1234";

String pushDomain = "mxl-push.pier39.cn";
String pushKey = "querty123";
Create_Live_Url.general_pull_url(pullDomain, pullKey, appName, streamName, expireTime);
Create_Live_Url.generate_push_url(pushDomain, pushKey, appName, streamName, expireTime);
}
}

需要注意:
(1)鉴权的有效时长应该和控制台配置的有效时长相同,默认是 1440 分钟,也就是一天。

(2)需要注意 pushKey 和 pullKey 不一样,需要在直播域名的详情页的访问控制中进行查看。

参考文章:
【1】.RTMP协议接入流程 RTMP、HLS、HTTP-FLV 协议对比:RTMP 延迟1s-3s;HLS:>10s;HTTP-FLV:1s-3s。
【2】.推流、拉流与播流 1.准备工具和环境;2.按需拉取直播流;3.获取推流与播放地址;4.推流设置与操作;5.播放设置与查看
【3】.如何通过PHP或Java代码生成推流地址和播放地址?
【4】.配置URL鉴权
【5】.鉴权代码示例

5.超低延时

登录视频直播控制台,
(1) 在左侧导航栏选择推/播流域名管理,进入域名管理页面。
(2) 单击需要开启超低延时直播的播流域名操作列的域名配置,进入域名管理页面。
(3) 选择直播管理 > 超低延时播放 RTS。
(4) 打开RTS播放开关。
(5) 选择版本低延时直播(RTS 1.0),打开H5自动转码开关。

参考文章:
【1】.超低延时直播简介
【2】.开通超低延时直播功能
【3】.生成推流地址和播放地址 支持RTMP、FLV、M3U8、RTS格式,推荐使用RTS格式地址播放。示例:RTS:artc://example.aliyundoc.com/app/stream?auth_key={鉴权串}
【4】.URL鉴权

6.配置https

使用超低延迟 rts 播放,需要为拉流地址配置 ssl 证书,否则无法播放。我在操作的时候,又遇到了问题,问题就是在阿里云签发证书的时候,总是出现失败的情况。
(1)购买证书
去阿里云 ssl 证书管理页面申请一个免费的证书。如果在阿里云购买了证书之后,可以选择一键部署,直接部署到拉流端域名。

(2)配置直播域名
在视频直播 -> 推/播流域名管理,选择拉流域名,选择 HTTPS 配置,开启HTTPS证书。

(3)验证证书是否生效
设置完成待证书1分钟后全网生效,使用HTTPS方式访问资源,如果浏览器中出现锁样的标识,则HTTPS安全加速生效。

参考文章:
【1】.Demo体验 您需要为域名配置SSL证书,* 如果您在体验过程中出现问题,可优先前往直播控制台工具箱>自助问题排查中快速诊断常见推/播流问题,并提供解决建议。
【2】.配置HTTPS安全加速 这里是阿里云详细的操作步骤。
【3】.部署证书至阿里云云产品(云产品部署)

6.超低延迟播放

可以到 问题自查 查看自己的直播是否可用。
(1) 安装

1
pnpm add aliyun-aliplayer --save

(2) 配置license
直播工具箱 -> SDK管理 -> 我的授权,需要先购买 License,然后创建应用,将 license 和应用绑定就可以了。(多个应用共用一个license)

1
2
3
4
license: {
domain: 'xxx.tech', // 申请 License 时填写的域名
key: 'xx', // 申请成功后,在控制台可以看到 License Key
},

(3) 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div id="J_prismPlayer"></div>
<script>
//先通过 npm install 安装
import Aliplayer from 'aliyun-aliplayer';
import 'aliyun-aliplayer/build/skins/default/aliplayer-min.css';
var player = new Aliplayer({
id: 'J_prismPlayer',
source: '<your play URL>', // 播放地址,使用超低延时直播(RTS)地址,协议是artc://。
isLive: true, // 是否为直播播放。
// rtsFallback: false, //(可选)是否开启RTS自动降级,默认为 true
// rtsFallbackType: 'HLS', //(可选)指定降级到的协议,可选 HLS/FLV,默认是自动选择,优先选择延迟更低的FLV,如果浏览器不支持则降级到 HLS
// rtsFallbackSource: '<your play URL>', // (可选)指定降级地址,而不是让播放器自动选择
// rtsVersion: 'x.x.x', // (可选)可以手动指定RTS SDK的版本。
},function(player){
console.log('The player is created.')
});
// 当RTS拉流成功时触发,通过订阅该事件,可以获取到RTS TraceId。 回调函数的参数中traceId为拉流的TraceId,source为当前RTS流的播放地址。
player.on('rtsTraceId', function(event) {
console.log('EVENT rtsTraceId', event.paramData);
})
// 当RTS降级时触发,参数reason为降级的原因,fallbackUrl为降级到的地址。
player.on('rtsFallback', function(event) {
console.log(' EVENT rtsFallback', event.paramData);
})
</script>
参考文章:
【1】.接口说明
【2】.快速使用阿里云ARTC Web SDK 这里是使用的 web sdk 进行的直播,使用这种方式就少了一个视频转码的费用,如果使用 h5 播放,还有一个视频转码的费用。
【3】.超低延时直播(RTS)视频播放 超低延时直播(RTS)使用URL方式播放,无需额外设置参数。
【4】.阿里云 Vue 播放器 demo 这是阿里云播放器进行播放的例子,可以直接使用播放器直接播放。
【5】.进阶功能
【6】.Aliplayer阿里云Web播放器 -Aliplayer 错误码 4004 地址不存在

7.样式修改

参考文章:
【1】.Web播放器常见问题 此黑边为播放器容器的背景色,可以通过给video标签设置css属性object-fit: cover;来解决该问题。

8.视频截图

参考文章:
【1】.阿里云Aliplayer高级功能介绍(一):视频截图 使用 canvas 进行了截图处理。

问题

1.直播黑屏

在同一个页面中,创建两个实例,结果就会出现其中一个实例黑屏的问题,这个问题是偶发的,我开始的时候以为是 id 的问题,我把这个 id 号改为了随机,结果也还是不行。

2.直播卡顿

在手机的webview中进行视频播放的时候,总是出现卡顿的现象,不知道为什么。

(1) 上行带宽不足或网络抖动,导致的数据发送速率下降,无法达到流畅播放的帧率要求
(2) 码率、帧率或编码档位设置的过高,但硬件条件存在限制,导致编码速度变慢,无法达到流畅播放的帧率要求。
(3) 推流过程中会有一定的CPU损耗,硬件配置较差的低端手机,在推流过程中若整体CPU 使用率超过80%以上,画面会出现不同程度的卡顿,花屏等现象,会影响到视频的采集,同时也会影响到用户端的观看。
(4) 视频采集参数的设置过低。

参考文章:
【1】.视频直播出现卡顿现象

3.新版本报错

最新的版本 v.2.28.5,好像引用了一个私有依赖,导致安装之后运行报错,出现的错误莫名其妙:“./node_modules/.pnpm/aliyun-aliplayer@2.28.5/node_modules/aliyun-aliplayer/build/aliplayer-min.js 6:881,Module parse failed: Unexpected token (6:881) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders”

【解决方案】
所以最好就是在 package.json 中锁定版本

1
"aliyun-aliplayer": "2.27.1"
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。