腾讯云直播开发日记 (一) 直播播放和观看
腾讯云直播开发日记 (一)
视频直播这一两年在移动互联网上可以说是非常的火,各种视频直播软件层出不穷. 直播和短视频也变成了连体婴儿, 那么我们如何进行这种项目的开发呢? 如果自己实现 SDK
的话成本高, 技术难度大, 不过钱是万能的, 直接买, 不差钱。博主现在也是在一家电商直播的公司, 选择的就是腾讯的直播服务,官网文档写的一般, 比较官方,博主会根据开发经验写一些腾讯云直播相关的文章,避免采坑。
腾讯云直播产品介绍
首先腾讯云有解决方案,互动直播和通用视频,都是根据他们的产品组合来解决不同问题,也就是你直播是个服务得买,你短视频是个服务也得买,总而言之钱越多能解决的问题越多。那博主这边简单介绍一下这边的几个产品作用,大家可以根据业务选择
云直播
这个就是专门针对的直播的服务了,主播通过推流软件,推到腾讯这边,用户通过拉流地址进行拉流,就能看到画面,支持各种协议,多人互动 混流就行,高效解决直播延时等问题
云点播
直播之后,要看回放怎么办? 买这个,本地有视频想让用户看也能上传。结合云直播使用
服务端的话就介绍这个,根据业务选择解决方案,自己也可以选择不同服务。我们公司自己选的服务,我的IM没有用腾讯的
客户端SDK也得看看
移动直播 SDK
集多种SDK
于一身, IM
直播
美颜
等等 ,但是对应SDK
的服务也是需要购买呢
腾讯有一个小直播
的开源项目,方便开发者二开,只要开通对应服务就能快速搭建一个直播平台.
短视频 SDK
上传
、存储
、转码
、分发的云点播能力,提供集成了采集
、剪辑
、拼接
、特效
、分享
、播放
等功能的客户端SDK
, 配合云点播
播放器 SDK
结合云点播
、直播服务
,拥有流畅稳定的播放性能,可以做广告植入
美颜特效 SDK
美颜特效已集成到(移动直播/短视频)企业版 SDK
中, 如果你的产品做类似抖音这种短视频服务,发短视频的时候需要特性, 嘻嘻, 这个拍摄设置大眼、瘦脸、V 脸、下巴调整, 50W/年
直播接入步骤
我们需要直播自然要购买云直播,这个主要是购买流量包,新账号会送20G
,可以进行测试, 进入控制台进行相关测试
域名管理
直播主要就是推流和拉流, 我们在这需要这个一个播放地址和推流地址, 这个设置文档上有 https://cloud.tencent.com/document/product/267/13551
配置完CNAME
后需要几分钟,所以不要着急测试, CNAME
不成功是无法使用云直播的。
OBS +VLC 测试推拉流
然后我们测试一下推拉流是否正常,控制台有个 辅助工具
-> 地址生成器
下载一个OBS
的软件, 可以进行推流测试
- 设置
- 推流
- 服务选择自定义
- 服务器填写
OBS
推流地址 - 串流秘钥填写
OBS
推流名称 - 设置推流资源 可以是视频 也可以是图片
- 开始推流
下载VLC
进行网络串流播放
在地址生成器那将推流的 StreamName
放进行生成播放地址, 直接利用 VLC
打开网络串就能看见直播了
这样就是可以正常推拉流了,也就是所谓的正常直播和观看,我们再往代码上落实一下。
使用php进行开发
我们需要建立一张 live_rooms
的数据表,初步定义字段完成主播的相关业务
参数名 |
说明 |
---|---|
id |
自增主建 |
user_id |
用户ID |
live_url |
播放地址 |
obs_url |
推流地址 |
avatar |
直播封面 |
title |
直播标题 |
status |
直播状态 是否在播 |
- php
composer
安装一下SDK tencentcloud/tencentcloud-sdk-php
将云直播的相关配置
放入服务端,服务端的可以在创建直播间的时候获取推流地址, 在用户进入直播间的时候获取拉流地址。
这样就可以做到主播开播出现在直播列表,用户进去观看主播, 根据这个之后我们可以再去扩展其他业务, 例如 区分主播类型是颜值的还是游戏的 附近主播 是不是还得加上经纬度 直播间里面要互动 肯定需要绑定聊天室 等等
这里推流地址需要 StreamName
, 这个文档上也有说,就是标识不同直播间的,不能重复,我们也不需要去腾讯那边注册,直接拼接到推流地址里面, 我数据表里面并没有增加这个字段, 因为我直接用user_id
当StreamName
, 如果你的推流地址中的StreamName
相同,那么只有第一个开始推流的是有效的,也就是说同样的推流地址,谁先推谁的有效,拉流只能拉到第一个推流的那个。 特别在测试的时候, 测试数据库和正式用户id
一样的话,你懂的.
/**
* 获取推流地址
* 如果不传key和过期时间,将返回不含防盗链的url
*
* @param string $streamName 您用来区别不同推流地址的唯一流名称
* @return String url
*/
public static function getLiveStream($streamName)
{
$time = time()+config('tencentcloud.invalid_time');
$key = config('tencentcloud.tx_push_api_key');
$txTime = strtoupper(base_convert($time,10,16));
$txSecret = md5($key.$streamName.$txTime);
$extStr = '?'.http_build_query([
'txSecret' => $txSecret,
'txTime' => $txTime
]);
return "rtmp://".config('tencentcloud.push_domain')."/live/".$streamName . (isset($extStr) ? $extStr : "");
}
/**
* 获取播放地址
* 若开启了域名鉴权,实际过期时间等于 txTime + 鉴权有效时间。
*
* @param string $streamName 您用来区别不同推流地址的唯一流名称
* @param string $playFormat 播放格式 有rtmp,FLV,HLS三种格式
* @return String url
*/
public static function getPlayStream($streamName, $playFormat = 'rtmp')
{
$time = time()+config('tencentcloud.invalid_time');
$key = config('tencentcloud.tx_play_api_key');
$txTime = strtoupper(base_convert($time,10,16));
$txSecret = md5($key.$streamName.$txTime);
$extStr = '?'.http_build_query([
'txSecret' => $txSecret,
'txTime' => $txTime
]);
switch ($playFormat)
{
case 'flv':
$playUrl = "http://".config('tencentcloud.play_domain')."/live/".$streamName .'.flv'. (isset($extStr) ? $extStr : "");
break;
case 'hls':
$playUrl = "http://".config('tencentcloud.play_domain')."/live/".$streamName .'.m3u8'. (isset($extStr) ? $extStr : "");
break;
case 'rtmp':
default:
$playUrl = "rtmp://".config('tencentcloud.play_domain')."/live/".$streamName . (isset($extStr) ? $extStr : "");
break;
}
return $playUrl;
}
其他业务场景下次再写啦!
- 数据库安全·保护表字段
- 【实践】伪造名人的脸—做一个小示例了解生成式对抗网络
- Spring 常见问题与解决方法
- 如何通过css控制内容显示顺序 第二行的内容优先显示
- 杨廷琨 - 用SQL解析神奇的扑克牌魔术
- Spring boot with Spring security
- Spring RestFul and RestTemplate
- Spring boot with Velocity template
- Oracle 11g R2 RAC 高可用连接特性 – SCAN 详解
- Spring boot · 链接池配置
- Linux下命令行图片格式转换
- 用SQL解一道有趣的数学题:Gauss和Poincare
- OpenSSL 转换证书格式
- 电子邮件服务器DKIM配置
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android自定义控件实现球赛比分条效果
- rxjs里concat operators的用法
- rxjs里merge operators的用法
- Android实现多参数文件和数据上传
- 解决pyPdf和pyPdf2在合并pdf时出现异常的问题
- rxjs里scan operators的用法
- rxjs里switchMap operators的用法
- rxjs里concatMap operators的用法
- rxjs里takeWhile operators的用法
- Python sql注入 过滤字符串的非法字符实例
- rxjs里combineLatest operators的用法
- rxjs里withLatestFrom operators的用法
- rxjs里distinctUntilChanged operators的用法
- pycharm安装及如何导入numpy
- rxjs里debounceTime operators的用法