直播架构

业务服务器:负责协调直播类应用的业务逻辑
创建直播房间
返回直播房间播放地址列表
关闭直播房间
LiveNet 实时流网络:负责流媒体的分发、直播流的创建、查询等相关操作
采集端:负责采集和推送流媒体
播放端:负责拉取并播放流媒体

直播云API:https://developer.qiniu.com/pili

服务端

SDK:https://developer.qiniu.com/pili/sdk/1220/server-sdk

关键代码:

        // 配置企业开发者密钥,密钥使用七牛账号登录https://portal.qiniu.com/user/key 获取
String accessKey = "xxx";
String secretKey = "xxx"; // 直播空间名称
// 直播空间必须事先存在,可以在 portal.qiniu.com 上创建
String hubName = "xxx"; Config.APIHost = "pili.qiniuapi.com"; //初始化client
Client cli = new Client(accessKey,secretKey); //初始化Hub
Hub hub = cli.newHub(hubName);
//列出所有流
try{
Hub.ListRet listRet = hub.list("liu", 0, "");
System.out.printf("hub=%s 列出流: keys=%s marker=%s\n", hubName,printArrary(listRet.keys) , listRet.omarker);
}catch (PiliException e){
e.printStackTrace();
return;
} //列出正在直播的流
try{
Hub.ListRet listRet = hub.listLive("liu", 0, "");
System.out.printf("hub=%s 列出正在直播的流: keys=%s marker=%s\n", hubName, printArrary(listRet.keys), listRet.omarker); }catch (PiliException e){
e.printStackTrace();
return;
} // RTMP推流地址
String url = cli.RTMPPublishURL("pili-publish.www.gs369.cn", hubName, keyA, 3600);
System.out.printf("keyA=%s RTMP推流地址=%s\n", keyA, url); //RTMP直播地址
String RTMPUrl = cli.RTMPPlayURL("pili-live-rtmp.www.gs369.cn", hubName, keyA);
System.out.printf("keyA=%s RTMP直播地址=%s\n", keyA, RTMPUrl);
request.setAttribute("RTMPUrl",urlTimestamp(RTMPUrl)); //HLS直播地址
String HLSUrl = cli.HLSPlayURL("pili-live-hls.www.gs369.cn", hubName, keyA);
System.out.printf("keyA=%s HLS直播地址=%s\n", keyA, HLSUrl);
request.setAttribute("HLSUrl",urlTimestamp(HLSUrl)); //HDL直播地址
String FLVUrl = cli.HDLPlayURL("pili-live-hdl.www.gs369.cn", hubName, keyA);
System.out.printf("keyA=%s HDL直播地址=%s\n", keyA, FLVUrl);
request.setAttribute("FLVUrl",urlTimestamp(FLVUrl)); // 截图直播地址
url = cli.SnapshotPlayURL("pili-live-snapshot.www.gs369.cn", hubName, keyA);
System.out.printf("keyA=%s 截图直播地址=%s\n", keyA, url);
 

将URL添加时间戳代码:

    private static String urlTimestamp(String url,String key){
String t = Long.toHexString(new Long(new Date().getTime() + 60));
//String key = "yuanda";
int index = url.indexOf("/",url.indexOf("//")+3);
String s = key+url.substring(index)+t;
System.out.println("s:"+s);
String sign="";
try {
MessageDigest md5 = MessageDigest.getInstance("md5");
md5.update(s.getBytes());
byte[] tmp = md5.digest();
StringBuilder sb = new StringBuilder();
for (byte b : tmp) {
if (b > 0 && b < 16)
sb.append("0");
sb.append(Integer.toHexString(b & 0xff));
}
sign=sb.toString().toLowerCase();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//System.out.println("sign:"+sign);
String resultUrl = url + "?sign=" + sign + "&t=" + t ;
return resultUrl;
}

播放端

web播放端,m3u8格式,此处JSP

 <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD//XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Qiniu Web Player in HTML5</title> </head>
<body> HLSUrl: ${HLSUrl } <br/>
RTMPUrl: ${RTMPUrl } <br/>
FLVUrl: ${FLVUrl } <br/>
<hr/>
HLS格式播放:
<link href="http://sdk-release.qnsdk.com/qiniuplayer-0.3.9.min.css" rel="stylesheet">
<script src="http://sdk-release.qnsdk.com/qiniuplayer-0.3.9.min.js"></script>
<video id="demo-video" class="video-js vjs-big-play-centered"></video>
<p>播放器状态: 0: 视频尚未开始加载,当前没有可用媒体信息;
1: 视频元数据已经可用;
2: 视频可以播放;
3: 视频可以播放,并且可以被快进;
4: 视频可以无终止的播放。</p>
<p id="ddd"></p> <script>
var options = {
controls: true,
url: '${HLSUrl }',
type: 'MP4', //视频播放类型hls或MP4
preload: true,
autoplay: false, // 如为 true,则视频将会自动播放
poster: '', //视频封面
};
var player = new QiniuPlayer('demo-video', options);
//实时显示播放状态
setInterval(function () {
var d=document.getElementById("ddd").innerHTML=player.state();
},2000);
</script>
</body>
</html>

-------------------或者videojs播放器:

源码:https://github.com/saysmy/videojs-hls

<video style="height:300px;width:400px" id="roomVideo" class="video-js vjs-default-skin vjs-big-play-centered" x-webkit-airplay="allow" poster="" webkit-playsinline playsinline x5-video-player-type="h5" x5-video-player-fullscreen="true" preload="auto">
<source src="${HLSUrl }" type="application/x-mpegURL">
</video>
<button id="btn">play</button> <script src="./videojs/video.js?v=fc5104a2ab23"></script>
<script src="./videojs/videojs-contrib-hls.js?v=c726b94b9923"></script> <script type="text/javascript">
var myPlayer = videojs('roomVideo',{
bigPlayButton : false,
textTrackDisplay : false,
posterImage: true,
errorDisplay : false,
controlBar : false
},function(){
console.log(this)
this.on('loadedmetadata',function(){
console.log('loadedmetadata');
//加载到元数据后开始播放视频
//startVideo();
}) this.on('ended',function(){
console.log('ended')
})
}); document.getElementById('btn').addEventListener('click', function(){
myPlayer.play();
}) var isVideoBreak;
function startVideo() { myPlayer.play(); //微信内全屏支持
document.getElementById('roomVideo').style.width = window.screen.width + "px";
document.getElementById('roomVideo').style.height = window.screen.height + "px"; //判断开始播放视频,移除高斯模糊等待层
var isVideoPlaying = setInterval(function(){
var currentTime = myPlayer.currentTime();
if(currentTime > 0){
$('.vjs-poster').remove();
clearInterval(isVideoPlaying);
}
},200) //判断视频是否卡住,卡主3s重新load视频
var lastTime = -1,
tryTimes = 0; clearInterval(isVideoBreak);
isVideoBreak = setInterval(function(){
var currentTime = myPlayer.currentTime();
console.log('currentTime'+currentTime+'lastTime'+lastTime); if(currentTime == lastTime){
//此时视频已卡主3s
//设置当前播放时间为超时时间,此时videojs会在play()后把currentTime设置为0
myPlayer.currentTime(currentTime+10000);
myPlayer.play(); //尝试5次播放后,如仍未播放成功提示刷新
if(++tryTimes > 5){
alert('您的网速有点慢,刷新下试试');
tryTimes = 0;
}
}else{
lastTime = currentTime;
tryTimes = 0;
}
},3000)
}
</script>

七牛直播云-m3u8格式直播的更多相关文章

  1. video.js支持m3u8格式直播

    为什么要使用video.js? 1. PC端浏览器并不支持video直接播放m3u8格式的视频 2. 手机端各式各样的浏览器定制的video界面风格不统一,直接写原生的js控制视频兼容性较差 3. v ...

  2. UEditor+七牛,实现图片直连上传

    最近做的项目,涉及到使用富文本编辑器,我选择了百度的UEditor.同时,我们的图片放在七牛云存储上.关于这两者间的集成,我写下一些个人的经验,与大家分享. 图片上传方案 目前来说,Web端基于七牛等 ...

  3. WordPress网站加速优化,一键免费使用七牛CDN插件

    利用wordpress搭建网站是个人建站的主流方案,我曾分享过wordpress网站加速优化必做的十件事,帮助了不少个人站长.今天介绍帮助wordpress网站提升速度至少10倍的免费CDN加速插件: ...

  4. 「视频直播技术详解」系列之七:直播云 SDK 性能测试模型

    ​关于直播的技术文章不少,成体系的不多.我们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面.深入地了解视频直播技术,更好地技术选型. 本系列文章大纲如下: ...

  5. (转)云存储:阿里云OSS 、又拍云和 七牛 的比较

    阿里OSS:好处就是,那是一套完整的体系,存储,数据库,CDN,服务器,阿里都可以给你全包.缺点,费用对于没有盈利的网站来说太高了,好像定位就是给那些高端客户使用的,而且CDN,OSS的流量是分开收费 ...

  6. 从QQ音乐开发,探讨如何利用腾讯云SDK在直播中加入视频动画

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云发表于云+社区专栏 看着精彩的德甲赛事,突然裁判一声口哨,球赛断掉了,屏幕开始自动播放"吃麦趣鸡盒,看德甲比赛&q ...

  7. 自建存储与使用微软Azure、七牛等第三方云存储综合考察分析

    http://www.cnblogs.com/sennly/p/4136734.html 各种云服务这两年炒的火热,加之可以降低成本,公司想先在部分业务上尝试使用下,刚好最近有个项目有大量小文件需要存 ...

  8. 七牛对用户使用webp图片格式的使用建议

    Qiniu 七牛问题解答 Chrome浏览器是可打开WebP格式的.可是并非全部的浏览器都支持webp格式,比如360.ie等浏览器是不支持的. WebP格式,谷歌(google)开发的一种旨在加快图 ...

  9. 阿里云 ECS 迁移到七牛 QVM 记

    操作 下载脚本 curl -O http://p70nwjoid.bkt.clouddn.com/go2qvm_client1.5_linux_x86_64.zip 解压填写配置 unzip go2q ...

随机推荐

  1. 模板小程序】求小于等于N范围内的质数

    xiaoxi666 联系邮箱: xiaoxi666swap@163.com 博客园 首页 新随笔 联系 订阅 管理 [模板小程序]求小于等于N范围内的质数   1 //筛法求N以内的素数(普通法+优化 ...

  2. 【干货】Kafka 事务特性分析

    特性背景 消息事务是指一系列的生产.消费操作可以要么都完成,要么都失败,类似数据库的事务.这个特性在0.10.2的版本是不支持的,从0.11版本开始才支持.华为云DMS率先提供Kafka 1.1.0的 ...

  3. JSP-Runoob:JSP 链接数据库

    ylbtech-JSP-Runoob:JSP 链接数据库 1.返回顶部 1. JSP 连接数据库 本教程假定您已经了解了 JDBC 应用程序的工作方式.在您开始学习 JSP 数据库访问之前,请访问 J ...

  4. E20171016-mk

    chaos   n. 混乱,紊乱; (天地未出现的) 浑沌世界; 〈古〉无底深渊; 一团糟;

  5. struts2什么情况用#和EL表达示

    1:struts2标签使用中,什么时候用#,什么时候可以不用# 值栈中的对象的不使用#,非值栈中的对象使用#如果不理解值栈的作用,简单点理解:当前action,或者处于action链中的action所 ...

  6. jquery中对于为一组标签赋予点击事件

    可以用each,但是each不能对动态的元素进行事件的绑定, 不过,其实也很简单,只需要获取所有的标签集,然后用动态绑定的方法,比如live进行绑定就可以了. 有时候,其实不难,只是自己想的太过复杂. ...

  7. 洛谷P1478 陶陶摘苹果(升级版)

    题目数据范围小,开两个数组手写冒泡应该也能过,不过和之前在牛客上的一题类似用结构体数组就好了,主要是注意用结构体数组的排序 题目 题目描述 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果 ...

  8. Akka源码分析-Persistence

    在学习akka过程中,我们了解了它的监督机制,会发现actor非常可靠,可以自动的恢复.但akka框架只会简单的创建新的actor,然后调用对应的生命周期函数,如果actor有状态需要回复,我们需要h ...

  9. IE版本的判断

    var Sys = {};var ua = navigator.userAgent.toLowerCase(); var s;(s = ua.match(/msie ([\d.]+)/)) ? Sys ...

  10. 【POJ3255/洛谷2865】[Usaco2006 Nov]路障Roadblocks(次短路)

    题目: POJ3255 洛谷2865 分析: 这道题第一眼看上去有点懵-- 不过既然要求次短路,那估计跟最短路有点关系,所以就拿着优先队列优化的Dijkstra乱搞,搞着搞着就通了. 开两个数组:\( ...