update 调整弹幕按批次加载,防止过多
This commit is contained in:
parent
903ba44bbb
commit
4474da490f
@ -1,5 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
@ -11,15 +12,56 @@
|
|||||||
<div id="header"></div>
|
<div id="header"></div>
|
||||||
不想做了,鸽
|
不想做了,鸽
|
||||||
</body>
|
</body>
|
||||||
<script src="/layui/layui.js"></script>
|
|
||||||
<script src="/js/jquery-3.2.1.js"></script>
|
<script src="/js/jquery-3.2.1.js"></script>
|
||||||
<script src="/js/CommonConfig.js"></script>
|
<script src="/js/CommonConfig.js"></script>
|
||||||
|
<script src="/js/httpUtils.js"></script>
|
||||||
|
<script src="/layui/layui.js"></script>
|
||||||
|
<script src="/js/lodash.min.js"></script>
|
||||||
|
<script src="/js/Chart.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
headerModel=3;
|
headerModel = 3;
|
||||||
|
var roomId = getParam('roomId');
|
||||||
$('#header').load("/html/header.html");
|
$('#header').load("/html/header.html");
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
function init() {
|
||||||
|
if (!hasString(getParam('roomId'))) {
|
||||||
|
showAnchor();
|
||||||
|
return
|
||||||
|
}
|
||||||
|
initTabs()
|
||||||
|
initBarrageRenderer();
|
||||||
|
}
|
||||||
|
function showAnchor() {
|
||||||
|
|
||||||
|
layer.open({
|
||||||
|
type: 2, // page 层类型
|
||||||
|
area: ['320px', '400px'],
|
||||||
|
title: '选择主播',
|
||||||
|
shade: 0.6, // 遮罩透明度
|
||||||
|
shadeClose: false, // 点击遮罩区域,关闭弹层
|
||||||
|
maxmin: true, // 允许全屏最小化
|
||||||
|
anim: 1, // 0-6 的动画形式,-1 不开启
|
||||||
|
btn: ['确定', '取消'],
|
||||||
|
content: '/html/ui/selectAnchor.html',
|
||||||
|
yes: function (index, layero) {
|
||||||
|
var iframeWin = window[layero.find('iframe')[0]['name']];
|
||||||
|
var anchorRoomId = iframeWin.$('#anchorRoomId')[0].value;
|
||||||
|
if (!hasString(anchorRoomId)) {
|
||||||
|
layer.msg("请选择")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let url = new URL(window.location.href);
|
||||||
|
url.searchParams.set('roomId', anchorRoomId);
|
||||||
|
window.location.href = url.toString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -91,10 +91,10 @@
|
|||||||
{ field: 'recordPath', title: '保存路径', width: 120 },
|
{ field: 'recordPath', title: '保存路径', width: 120 },
|
||||||
{ field: 'recordDanmu', title: '录制弹幕', width: 120, sort: true },
|
{ field: 'recordDanmu', title: '录制弹幕', width: 120, sort: true },
|
||||||
{ field: 'recordLive', title: '录制视频', width: 120, sort: true },
|
{ field: 'recordLive', title: '录制视频', width: 120, sort: true },
|
||||||
|
{ field: 'syncDanmuForLive', title: '同步录制', width: 120, sort: true },
|
||||||
{ field: 'recordDanmuDate', title: '弹幕录制预定时间', width: 100, sort: true },
|
{ field: 'recordDanmuDate', title: '弹幕录制预定时间', width: 100, sort: true },
|
||||||
{ field: 'recordLiveDate', title: '视频录制预定时间', width: 100, sort: true },
|
{ field: 'recordLiveDate', title: '视频录制预定时间', width: 100, sort: true },
|
||||||
{ field: 'recordUid', title: '录制账号', width: 120, sort: true, templet: '<div><a href="https://space.bilibili.com/{{= d.recordUid}}" target="_blank">{{= d.recordUid}}</a>' },
|
{ field: 'recordUid', title: '录制账号', width: 120, sort: true, templet: '<div><a href="https://space.bilibili.com/{{= d.recordUid}}" target="_blank">{{= d.recordUid}}</a>' },
|
||||||
{ field: 'recordDanmu', title: '录制弹幕', width: 120, sort: true },
|
|
||||||
{ field: 'sql_time', title: '添加时间', width: 100 },
|
{ field: 'sql_time', title: '添加时间', width: 100 },
|
||||||
{ fixed: "right", title: "操作", width: 190, align: "center", toolbar: "#toolDemo" }
|
{ fixed: "right", title: "操作", width: 190, align: "center", toolbar: "#toolDemo" }
|
||||||
]],
|
]],
|
||||||
|
@ -6,11 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
<title>视频中心</title>
|
<title>视频中心</title>
|
||||||
<link rel="stylesheet" href="/layui/css/layui.css">
|
<link rel="stylesheet" href="/layui/css/layui.css">
|
||||||
<style>
|
|
||||||
canvas {
|
|
||||||
width: 600px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="layui-bg-gray">
|
<body class="layui-bg-gray">
|
||||||
@ -27,36 +23,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-col-xs7">
|
<div class="layui-col-xs7">
|
||||||
<div class="grid-demo" id="container" style="margin-top: 16px; width: 100%;">
|
<div class="layui-row">
|
||||||
<video id="videoElement" controls style="width: 100%;"></video>
|
<div class="grid-demo" id="container" style="margin-top: 16px; width: 100%;">
|
||||||
|
<video id="videoElement" controls style="width: 100%;"></video>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-form layui-col-xs1">
|
||||||
|
<input type="checkbox" id="danmuCheckBox" title="弹幕" lay-skin="tag" lay-filter="danmuCheckBox" on
|
||||||
|
checked>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-xs9" style="text-align: center;">
|
||||||
|
<div id="slider" lay-options="{value: 100,input:true}"></div>
|
||||||
|
<span>弹幕透明度</span>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-xs2" style="text-align: right; align-self: center;">
|
||||||
|
弹幕装载数:<span id="danmuSize">你猜</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-col-xs2" style="margin-left: 16px; width: 22%; margin-top: 16px;">
|
|
||||||
<p style="font-size: 4;font-weight: bold; text-align: center;">Super Chat 列表</p>
|
|
||||||
<div class="flow-demo" id="flow" style="height: 60vh; overflow: auto;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-row">
|
|
||||||
<div class="layui-col-xs2"> </div>
|
|
||||||
<div class="layui-form layui-col-xs1">
|
|
||||||
<input type="checkbox" id="danmuCheckBox" title="弹幕" lay-skin="tag" lay-filter="danmuCheckBox" on checked>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="layui-col-xs4" style="text-align: center;">
|
<div class="layui-col-xs2" style="margin-left: 16px; width: 22%; margin-top: 16px;">
|
||||||
<div id="slider" lay-options="{value: 100,input:true}"></div>
|
<div class="layui-row">
|
||||||
<span>弹幕透明度</span>
|
<div class="layui-col-md12">
|
||||||
</div>
|
<canvas id="giftChart" style="width: 100%; max-height: 100%;"></canvas>
|
||||||
<div class="layui-col-xs2" style="text-align: right; align-self: center;">
|
</div>
|
||||||
弹幕装载数:<span id="danmuSize">你猜</span>
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-col-md12">
|
||||||
|
<p style="font-size: 4;font-weight: bold; text-align: center;">Super Chat 列表</p>
|
||||||
|
<div class="flow-demo" id="flow" style="max-height: 60vh; overflow: auto;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-row">
|
|
||||||
<div class="layui-col-xs2"> </div>
|
|
||||||
<div class="layui-col-xs7" style="width: auto; height: 50%;">
|
<!-- <div style="margin-bottom: 10vh;"></div> -->
|
||||||
<canvas id="giftChart" style="width: 100%; height: 100%;"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style="margin-bottom: 10vh;"></div>
|
|
||||||
</body>
|
</body>
|
||||||
<script id="menulist" type="text/html">
|
<script id="menulist" type="text/html">
|
||||||
<ul class="layui-tab-title">
|
<ul class="layui-tab-title">
|
||||||
@ -252,7 +256,7 @@
|
|||||||
lables.push(item.gift_name + "\n" + item.total_price / 100 + "¥")
|
lables.push(item.gift_name + "\n" + item.total_price / 100 + "¥")
|
||||||
values.push(item.total_gift_num)
|
values.push(item.total_gift_num)
|
||||||
});
|
});
|
||||||
if(chartView!==null){
|
if (chartView !== null) {
|
||||||
chartView.destroy()
|
chartView.destroy()
|
||||||
}
|
}
|
||||||
chartView = new Chart($('#giftChart').get(0), {
|
chartView = new Chart($('#giftChart').get(0), {
|
||||||
@ -332,13 +336,23 @@
|
|||||||
}
|
}
|
||||||
function initDanmu() {
|
function initDanmu() {
|
||||||
barrageRenderer.setBarrages([])
|
barrageRenderer.setBarrages([])
|
||||||
getDanmu(getParam('roomId'), videoId)
|
loadDanmu(0)
|
||||||
|
}
|
||||||
|
function loadDanmu(page) {
|
||||||
|
getDanmu(getParam('roomId'), videoId, page)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
barrageRenderer.setBarrages(data.data.danmu);
|
if (page === 0) {
|
||||||
$('#danmuSize').get(0).innerHTML = data.data.danmu.length
|
initSC(data.data.superChat)
|
||||||
initSC(data.data.superChat)
|
$('#danmuSize').get(0).innerHTML = data.data.danmuCount;
|
||||||
|
barrageRenderer.setBarrages(data.data.danmu)
|
||||||
|
}else{
|
||||||
|
barrageRenderer.barrageLayoutCalculate.allBarrageInstances.push(...data.data.danmu);
|
||||||
|
}
|
||||||
|
if(data.data.nextDanmu){
|
||||||
|
loadDanmu(page+1)
|
||||||
|
}
|
||||||
|
// barrageRenderer.setBarrages(data.data.danmu);
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
function initSC(scList) {
|
function initSC(scList) {
|
||||||
flow.load({
|
flow.load({
|
||||||
@ -347,10 +361,7 @@
|
|||||||
isAuto: true,
|
isAuto: true,
|
||||||
isLazyimg: false,
|
isLazyimg: false,
|
||||||
done: function (page, next) { // 加载下一页
|
done: function (page, next) { // 加载下一页
|
||||||
// 模拟插入
|
|
||||||
console.log(scList)
|
|
||||||
laytpl($('#superChatCard').get(0).innerHTML).render(scList, function (html) {
|
laytpl($('#superChatCard').get(0).innerHTML).render(scList, function (html) {
|
||||||
console.log(html)
|
|
||||||
next(html, false)
|
next(html, false)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<li class="layui-nav-item video"><a href="/html/body/video.html">视频管理</a></li>
|
<li class="layui-nav-item video"><a href="/html/body/video.html">视频管理</a></li>
|
||||||
<li class="layui-nav-item data" ><a href="/html/body/data.html">数据中心</a></li>
|
<li class="layui-nav-item data" ><a href="/html/body/data.html">数据中心</a></li>
|
||||||
<li class="layui-nav-item user"><a href="/html/body/user.html">用户中心</a></li>
|
<li class="layui-nav-item user"><a href="/html/body/user.html">用户中心</a></li>
|
||||||
|
<li class="layui-nav-item config layui-layout-right"> <a href="/html/body/config.html"><i class="layui-icon layui-icon-set-fill" style="font-size: 20px; margin-right: 10px;"></i>系统设置</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
<!-- <script src="/layui/layui.js"></script> -->
|
<!-- <script src="/layui/layui.js"></script> -->
|
||||||
@ -15,11 +16,13 @@
|
|||||||
$(".video").removeClass("layui-this")
|
$(".video").removeClass("layui-this")
|
||||||
$(".data").removeClass("layui-this")
|
$(".data").removeClass("layui-this")
|
||||||
$(".user").removeClass("layui-this")
|
$(".user").removeClass("layui-this")
|
||||||
|
$(".config").removeClass("layui-this")
|
||||||
switch(headerModel){
|
switch(headerModel){
|
||||||
case 0:$(".index").addClass('layui-this');break;
|
case 0:$(".index").addClass('layui-this');break;
|
||||||
case 1:$(".live").addClass('layui-this');break;
|
case 1:$(".live").addClass('layui-this');break;
|
||||||
case 2:$(".video").addClass('layui-this');break;
|
case 2:$(".video").addClass('layui-this');break;
|
||||||
case 3:$(".data").addClass('layui-this');break;
|
case 3:$(".data").addClass('layui-this');break;
|
||||||
case 4:$(".user").addClass('layui-this');break;
|
case 4:$(".user").addClass('layui-this');break;
|
||||||
|
case 5:$(".config").addClass('layui-this');break;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -29,16 +29,26 @@
|
|||||||
<input type="checkbox" name="recordLive" lay-skin="switch" lay-filter="switchTest" title="启用|禁用">
|
<input type="checkbox" name="recordLive" lay-skin="switch" lay-filter="switchTest" title="启用|禁用">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="layui-form-item" pane>
|
||||||
|
<label class="layui-form-label">录制视频时<br>同步录制弹幕</label>
|
||||||
|
<div class="layui-input-block"><br>
|
||||||
|
<input type="checkbox" name="syncDanmuForLive" lay-skin="switch" lay-filter="switchSync" title="启用|禁用">
|
||||||
|
<i class="layui-icon layui-icon-help layui-text-em " onclick="timeTips2(this)"></i>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
<div class="layui-form-item" pane>
|
<div class="layui-form-item" pane>
|
||||||
<label class="layui-form-label">录制日期</label>
|
<label class="layui-form-label">录制日期</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="checkbox" name="week_1" title="周一" lay-skin="tag">
|
<input type="checkbox" name="week_1" title="周一" lay-skin="tag">
|
||||||
<input type="checkbox" name="week_2" title="周二" lay-skin="tag">
|
<input type="checkbox" name="week_2" title="周二" lay-skin="tag">
|
||||||
<input type="checkbox" name="week_3" title="周三" lay-skin="tag">
|
<input type="checkbox" name="week_3" title="周三" lay-skin="tag">
|
||||||
<input type="checkbox" name="week_4" title="周四" lay-skin="tag">
|
<input type="checkbox" name="week_4" title="周四" lay-skin="tag">
|
||||||
<input type="checkbox" name="week_5" title="周五" lay-skin="tag">
|
<input type="checkbox" name="week_5" title="周五" lay-skin="tag">
|
||||||
<input type="checkbox" name="week_6" title="周六" lay-skin="tag">
|
<input type="checkbox" name="week_6" title="周六" lay-skin="tag">
|
||||||
<input type="checkbox" name="week_7" title="周日" lay-skin="tag">
|
<input type="checkbox" name="week_7" title="周日" lay-skin="tag">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@ -96,6 +106,10 @@
|
|||||||
layer.tips('仅在当前时间范围内录制,如遇到正在直播,则延迟到下播时停止录制', that);
|
layer.tips('仅在当前时间范围内录制,如遇到正在直播,则延迟到下播时停止录制', that);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function timeTips2(that) {
|
||||||
|
layer.tips('启用后,录制视频时会同步录制弹幕,下播后会同步停止录制.同时上面录制弹幕按钮将失效', that);
|
||||||
|
|
||||||
}
|
}
|
||||||
var roomId = getParam("roomId");
|
var roomId = getParam("roomId");
|
||||||
var editArray = getParam("array")
|
var editArray = getParam("array")
|
||||||
@ -125,7 +139,7 @@
|
|||||||
field.weeks = weeks;
|
field.weeks = weeks;
|
||||||
console.log(field)
|
console.log(field)
|
||||||
if (editArray === null) {
|
if (editArray === null) {
|
||||||
var loadIndex=showLoadingDialog();
|
var loadIndex = showLoadingDialog();
|
||||||
addRoomConfig(field)
|
addRoomConfig(field)
|
||||||
.then(json => {
|
.then(json => {
|
||||||
layer.close(loadIndex)
|
layer.close(loadIndex)
|
||||||
@ -141,7 +155,7 @@
|
|||||||
editArray.split(',').forEach(element => {
|
editArray.split(',').forEach(element => {
|
||||||
array.push(element)
|
array.push(element)
|
||||||
});
|
});
|
||||||
var loadIndex=showLoadingDialog();
|
var loadIndex = showLoadingDialog();
|
||||||
setArrayRoomConfig(array, field)
|
setArrayRoomConfig(array, field)
|
||||||
.then(json => {
|
.then(json => {
|
||||||
layer.close(loadIndex)
|
layer.close(loadIndex)
|
||||||
@ -170,6 +184,14 @@
|
|||||||
type: 'time',
|
type: 'time',
|
||||||
range: true
|
range: true
|
||||||
});
|
});
|
||||||
|
form.on('switch(switchSync)', function (data) {
|
||||||
|
if (form.val('form-filter').syncDanmuForLive === 'on') {
|
||||||
|
$("[name='recordDanmu']").prop("disabled", true);
|
||||||
|
} else {
|
||||||
|
$("[name='recordDanmu']").prop("disabled", false);
|
||||||
|
}
|
||||||
|
form.render();
|
||||||
|
});
|
||||||
function init() {
|
function init() {
|
||||||
getUserInfo();
|
getUserInfo();
|
||||||
if (roomId !== null) {
|
if (roomId !== null) {
|
||||||
@ -202,13 +224,18 @@
|
|||||||
'recordDanmu': json.recordDanmu,
|
'recordDanmu': json.recordDanmu,
|
||||||
'recordDanmuDate': json.recordDanmuDate,
|
'recordDanmuDate': json.recordDanmuDate,
|
||||||
'recordLiveDate': json.recordLiveDate,
|
'recordLiveDate': json.recordLiveDate,
|
||||||
|
'syncDanmuForLive': json.syncDanmuForLive,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let i = 0; i < json.weeks.length; i++) {
|
for (let i = 0; i < json.weeks.length; i++) {
|
||||||
result[`week_${json.weeks[i]}`] = true;
|
result[`week_${json.weeks[i]}`] = true;
|
||||||
}
|
}
|
||||||
form.val('form-filter', result);
|
form.val('form-filter', result);
|
||||||
|
if (json.syncDanmuForLive) {
|
||||||
|
$("[name='recordDanmu']").prop("disabled", true);
|
||||||
|
} else {
|
||||||
|
$("[name='recordDanmu']").prop("disabled", false);
|
||||||
|
}
|
||||||
$('#url').get(0).disabled = true;
|
$('#url').get(0).disabled = true;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -13,8 +13,8 @@ function get(url) {
|
|||||||
return error;
|
return error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function post(url, formData, isJSON) {
|
function post(url, formData, isJSON) {
|
||||||
return sendPost(url,true,formData,isJSON)
|
return sendPost(url, true, formData, isJSON)
|
||||||
}
|
}
|
||||||
function sendPost(url, isFormData, formData, isJSON) {
|
function sendPost(url, isFormData, formData, isJSON) {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
@ -129,7 +129,7 @@ function setArrayRoomConfig(rooms, config) {
|
|||||||
return sendPost("/live/config/set/array", false, json, true)
|
return sendPost("/live/config/set/array", false, json, true)
|
||||||
}
|
}
|
||||||
function deleteArrayRoomConfig(rooms) {
|
function deleteArrayRoomConfig(rooms) {
|
||||||
return sendPost("/live/config/delete/array", false,rooms, true)
|
return sendPost("/live/config/delete/array", false, rooms, true)
|
||||||
}
|
}
|
||||||
function deleteAllRoomConfig() {
|
function deleteAllRoomConfig() {
|
||||||
return get("/live/config/delete/all")
|
return get("/live/config/delete/all")
|
||||||
@ -192,8 +192,8 @@ function startLiveDanmu(roomId) {
|
|||||||
function stopLiveDanmu(roomId) {
|
function stopLiveDanmu(roomId) {
|
||||||
return get("/live/danmu/stop?roomId=" + roomId)
|
return get("/live/danmu/stop?roomId=" + roomId)
|
||||||
}
|
}
|
||||||
function getDanmu(roomId, videoId) {
|
function getDanmu(roomId, videoId, page) {
|
||||||
return get("/live/danmu/get?roomId=" + roomId + "&videoId=" + videoId)
|
return get("/live/danmu/get?roomId=" + roomId + "&videoId=" + videoId + "&page=" + page)
|
||||||
}
|
}
|
||||||
//----------------弹幕相关接口end
|
//----------------弹幕相关接口end
|
||||||
//----------------用户相关接口
|
//----------------用户相关接口
|
||||||
|
@ -34,6 +34,8 @@ public class LiveConfigDatabaseBean extends AbsDatabasesBean {
|
|||||||
private boolean isRecordLive;
|
private boolean isRecordLive;
|
||||||
@JSONField(name = "recordDanmu")
|
@JSONField(name = "recordDanmu")
|
||||||
private boolean isRecordDanmu;
|
private boolean isRecordDanmu;
|
||||||
|
@JSONField(name = "syncDanmuForLive")
|
||||||
|
private boolean isSyncDanmuForLive;
|
||||||
@JSONField(name = "keyword")
|
@JSONField(name = "keyword")
|
||||||
private List<String> keywordList;
|
private List<String> keywordList;
|
||||||
@JSONField(name = "weeks")
|
@JSONField(name = "weeks")
|
||||||
|
@ -8,6 +8,7 @@ import lombok.Data;
|
|||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Data
|
@Data
|
||||||
@ -23,7 +24,7 @@ public class LiveDanmuDatabaseBean extends AbsDatabasesBean {
|
|||||||
@JSONField(name = "color")
|
@JSONField(name = "color")
|
||||||
private String fontColor;
|
private String fontColor;
|
||||||
@JSONField(name = "time")
|
@JSONField(name = "time")
|
||||||
private long time;
|
private Date time;
|
||||||
@JSONField(name = "uid")
|
@JSONField(name = "uid")
|
||||||
private String uid;
|
private String uid;
|
||||||
@JSONField(name = "uname")
|
@JSONField(name = "uname")
|
||||||
@ -40,7 +41,7 @@ public class LiveDanmuDatabaseBean extends AbsDatabasesBean {
|
|||||||
model = danmu.getModel();
|
model = danmu.getModel();
|
||||||
fontSize = danmu.getFontSize();
|
fontSize = danmu.getFontSize();
|
||||||
fontColor = danmu.getFontColor();
|
fontColor = danmu.getFontColor();
|
||||||
time = danmu.getTime();
|
time = new Date(danmu.getTime());
|
||||||
uid = danmu.getUid();
|
uid = danmu.getUid();
|
||||||
uname = danmu.getUname();
|
uname = danmu.getUname();
|
||||||
}
|
}
|
||||||
@ -52,7 +53,7 @@ public class LiveDanmuDatabaseBean extends AbsDatabasesBean {
|
|||||||
data.setModel(model);
|
data.setModel(model);
|
||||||
data.setFontSize(fontSize);
|
data.setFontSize(fontSize);
|
||||||
data.setFontColor(fontColor);
|
data.setFontColor(fontColor);
|
||||||
data.setTime(time);
|
data.setTime(time.getTime());
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,9 +207,39 @@ public class BiliLiveDatabase extends SQLiteManager {
|
|||||||
return super.get(tableName, where, clazz);
|
return super.get(tableName, where, clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T extends AbsDatabasesBean> List<T> getOfTime(Long startTime, Long endTime, int page,int pageSize, Class<T> clazz) {
|
||||||
|
String tableName = null;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String where = null;
|
||||||
|
if (startTime != null) {
|
||||||
|
sb.append(" `sql_time` >= ").append("\"").append(startTime).append("\"");
|
||||||
|
}
|
||||||
|
if (endTime != null) {
|
||||||
|
if (!sb.isEmpty()) {
|
||||||
|
sb.append(" and ");
|
||||||
|
}
|
||||||
|
sb.append(" `sql_time` <= ").append("\"").append(endTime).append("\"");
|
||||||
|
}
|
||||||
|
sb.append("ORDER BY `sql_time` LIMIT ").append(page).append("*").append(pageSize).append(",").append(pageSize);
|
||||||
|
if (!sb.isEmpty()) {
|
||||||
|
where = sb.toString();
|
||||||
|
}
|
||||||
|
for (AbsDatabasesBean bean : getDataBean()) {
|
||||||
|
if (bean.getClass() == clazz) {
|
||||||
|
tableName = bean.getTableName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.get(tableName, where, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount(String table) {
|
||||||
|
return super.getCount(table);
|
||||||
|
}
|
||||||
|
|
||||||
public LiveVideoDatabaseBean getVideo(String videoId) {
|
public LiveVideoDatabaseBean getVideo(String videoId) {
|
||||||
for (LiveVideoDatabaseBean info : getLiveInfos()) {
|
for (LiveVideoDatabaseBean info : getLiveInfos()) {
|
||||||
System.out.println(videoId + " " + info.getSql_time().getTime());
|
|
||||||
if (videoId.trim().equals(String.valueOf(info.getSql_time().getTime()))) {
|
if (videoId.trim().equals(String.valueOf(info.getSql_time().getTime()))) {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -241,8 +271,8 @@ public class BiliLiveDatabase extends SQLiteManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
BiliLiveDatabase biliLiveDatabase = new BiliLiveDatabase(LiveRoomConfig.buildConfig("7688602"));
|
BiliLiveDatabase biliLiveDatabase = new BiliLiveDatabase(LiveRoomConfig.buildConfig("33989"));
|
||||||
biliLiveDatabase.resetSQL();
|
// biliLiveDatabase.resetSQL();
|
||||||
biliLiveDatabase.resetData();
|
biliLiveDatabase.resetData();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ import com.yutou.biliapi.bean.websocket.WebSocketHeader;
|
|||||||
import com.yutou.biliapi.bean.websocket.live.WSData;
|
import com.yutou.biliapi.bean.websocket.live.WSData;
|
||||||
import com.yutou.biliapi.databases.BiliBiliLoginDatabase;
|
import com.yutou.biliapi.databases.BiliBiliLoginDatabase;
|
||||||
import com.yutou.biliapi.databases.BiliLiveDatabase;
|
import com.yutou.biliapi.databases.BiliLiveDatabase;
|
||||||
import com.yutou.biliapi.utils.BiliUserUtils;
|
|
||||||
import com.yutou.biliapi.utils.BytesUtils;
|
import com.yutou.biliapi.utils.BytesUtils;
|
||||||
import com.yutou.common.okhttp.HttpBody;
|
import com.yutou.common.okhttp.HttpBody;
|
||||||
import com.yutou.common.okhttp.HttpCallback;
|
import com.yutou.common.okhttp.HttpCallback;
|
||||||
@ -39,20 +38,20 @@ import java.util.concurrent.ArrayBlockingQueue;
|
|||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class WebSocketManager {
|
public class WebSocketClientManager {
|
||||||
ThreadPoolExecutor executor;
|
ThreadPoolExecutor executor;
|
||||||
private static WebSocketManager instance;
|
private static WebSocketClientManager instance;
|
||||||
Map<LiveRoomConfig, DanmuTask> roomMap;
|
Map<LiveRoomConfig, DanmuTask> roomMap;
|
||||||
private final List<String> userStopList = new ArrayList<>();//手动停止列表
|
private final List<String> userStopList = new ArrayList<>();//手动停止列表
|
||||||
|
|
||||||
private WebSocketManager() {
|
private WebSocketClientManager() {
|
||||||
roomMap = new HashMap<>();
|
roomMap = new HashMap<>();
|
||||||
executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
|
executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WebSocketManager getInstance() {
|
public static WebSocketClientManager getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new WebSocketManager();
|
instance = new WebSocketClientManager();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@ -105,7 +104,7 @@ public class WebSocketManager {
|
|||||||
|
|
||||||
public DanmuTask(LiveRoomConfig config) {
|
public DanmuTask(LiveRoomConfig config) {
|
||||||
this.roomConfig = config;
|
this.roomConfig = config;
|
||||||
WebSocketManager.getInstance().roomMap.put(roomConfig, this);
|
WebSocketClientManager.getInstance().roomMap.put(roomConfig, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -118,7 +117,7 @@ public class WebSocketManager {
|
|||||||
roomConfig.setRoomInfo(execute.body() != null ? execute.body().getData() : null);
|
roomConfig.setRoomInfo(execute.body() != null ? execute.body().getData() : null);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
WebSocketManager.getInstance().roomMap.remove(roomConfig);
|
WebSocketClientManager.getInstance().roomMap.remove(roomConfig);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
api.getLiveRoomDanmuInfo(String.valueOf(roomConfig.getRoomId())).enqueue(new HttpCallback<LiveDanmuInfo>() {
|
api.getLiveRoomDanmuInfo(String.valueOf(roomConfig.getRoomId())).enqueue(new HttpCallback<LiveDanmuInfo>() {
|
||||||
@ -132,7 +131,7 @@ public class WebSocketManager {
|
|||||||
roomConfig.setLiveInfo(response);
|
roomConfig.setLiveInfo(response);
|
||||||
client = new WebSocketClientTh(new URI(url), roomConfig);
|
client = new WebSocketClientTh(new URI(url), roomConfig);
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
WebSocketManager.getInstance().roomMap.remove(roomConfig);
|
WebSocketClientManager.getInstance().roomMap.remove(roomConfig);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,7 +139,7 @@ public class WebSocketManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable throwable) {
|
public void onFailure(Throwable throwable) {
|
||||||
WebSocketManager.getInstance().roomMap.remove(roomConfig);
|
WebSocketClientManager.getInstance().roomMap.remove(roomConfig);
|
||||||
Log.e(throwable);
|
Log.e(throwable);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -152,10 +151,9 @@ public class WebSocketManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class WebSocketClientTh extends WebSocketClient {
|
private static class WebSocketClientTh extends WebSocketClient {
|
||||||
private LiveRoomConfig roomConfig;
|
private final LiveRoomConfig roomConfig;
|
||||||
private HeartbeatTask heartbeatTask;
|
private final HeartbeatTask heartbeatTask;
|
||||||
BiliLiveDatabase liveDatabase;
|
BiliLiveDatabase liveDatabase;
|
||||||
private boolean itTmp = true;
|
|
||||||
|
|
||||||
public WebSocketClientTh(URI serverUri, LiveRoomConfig roomId) {
|
public WebSocketClientTh(URI serverUri, LiveRoomConfig roomId) {
|
||||||
super(serverUri);
|
super(serverUri);
|
||||||
@ -192,7 +190,7 @@ public class WebSocketManager {
|
|||||||
@Override
|
@Override
|
||||||
public void onClose(int i, String s, boolean b) {
|
public void onClose(int i, String s, boolean b) {
|
||||||
Log.e("WebSocketClientTh.onClose", "i = " + i + ", s = " + s + ", b = " + b, roomConfig.getRoomId(), heartbeatTask.socket.isOpen());
|
Log.e("WebSocketClientTh.onClose", "i = " + i + ", s = " + s + ", b = " + b, roomConfig.getRoomId(), heartbeatTask.socket.isOpen());
|
||||||
WebSocketManager.getInstance().roomMap.remove(roomConfig);
|
WebSocketClientManager.getInstance().roomMap.remove(roomConfig);
|
||||||
liveDatabase.close();
|
liveDatabase.close();
|
||||||
heartbeatTask.cancel();
|
heartbeatTask.cancel();
|
||||||
}
|
}
|
||||||
@ -201,7 +199,7 @@ public class WebSocketManager {
|
|||||||
public void onError(Exception e) {
|
public void onError(Exception e) {
|
||||||
Log.i("WebSocketClientTh.onError", roomConfig.getRoomId());
|
Log.i("WebSocketClientTh.onError", roomConfig.getRoomId());
|
||||||
Log.e(e);
|
Log.e(e);
|
||||||
WebSocketManager.getInstance().roomMap.remove(roomConfig);
|
WebSocketClientManager.getInstance().roomMap.remove(roomConfig);
|
||||||
liveDatabase.close();
|
liveDatabase.close();
|
||||||
heartbeatTask.cancel();
|
heartbeatTask.cancel();
|
||||||
}
|
}
|
||||||
@ -285,30 +283,25 @@ public class WebSocketManager {
|
|||||||
}
|
}
|
||||||
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().getCookie(roomConfig.getLoginUid());
|
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().getCookie(roomConfig.getLoginUid());
|
||||||
Log.d("cookie:", cookie, "RoomId:" + roomConfig);
|
Log.d("cookie:", cookie, "RoomId:" + roomConfig);
|
||||||
String buvid = BiliUserUtils.getBuvid(cookie);
|
try {
|
||||||
if (buvid != null) {
|
json.put("roomid", new BigInteger(roomConfig.getRoomId()));
|
||||||
try {
|
json.put("protover", 3);
|
||||||
json.put("roomid", new BigInteger(roomConfig.getRoomId()));
|
json.put("platform", "web");
|
||||||
json.put("protover", 3);
|
json.put("type", 2);
|
||||||
json.put("buvid", buvid);
|
json.put("key", roomConfig.getLiveInfo().getToken());
|
||||||
json.put("platform", "web");
|
byte[] bytes = {0, 16, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1};
|
||||||
json.put("type", 2);
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
json.put("key", roomConfig.getLiveInfo().getToken());
|
|
||||||
byte[] bytes = {0, 16, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1};
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
// Log.i("bytes.length = " + bytes.length);
|
// Log.i("bytes.length = " + bytes.length);
|
||||||
Log.i(json);
|
Log.i(json);
|
||||||
outputStream.write(BytesUtils.toLH(json.toString().length() + 16));
|
outputStream.write(BytesUtils.toLH(json.toString().length() + 16));
|
||||||
outputStream.write(bytes);
|
outputStream.write(bytes);
|
||||||
outputStream.write(json.toJSONString().getBytes(StandardCharsets.UTF_8));
|
outputStream.write(json.toJSONString().getBytes(StandardCharsets.UTF_8));
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
// BytesUtils.printHex(outputStream.toByteArray());
|
// BytesUtils.printHex(outputStream.toByteArray());
|
||||||
Log.i(socket.isOpen(), json.toString());
|
Log.i(socket.isOpen(), json.toString());
|
||||||
socket.send(outputStream.toByteArray());
|
socket.send(outputStream.toByteArray());
|
||||||
|
} catch (Exception e) {
|
||||||
} catch (Exception e) {
|
Log.e(e);
|
||||||
Log.e(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14,7 +14,6 @@ import com.yutou.bilibili.services.LiveConfigService;
|
|||||||
import com.yutou.bilibili.services.LiveLoginService;
|
import com.yutou.bilibili.services.LiveLoginService;
|
||||||
import com.yutou.bilibili.services.LiveUserService;
|
import com.yutou.bilibili.services.LiveUserService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
@ -154,6 +153,9 @@ public class LiveConfigController {
|
|||||||
if("on".equals(config.getString("recordLive"))){
|
if("on".equals(config.getString("recordLive"))){
|
||||||
bean.setRecordLive(true);
|
bean.setRecordLive(true);
|
||||||
}
|
}
|
||||||
|
if("on".equals(config.getString("syncDanmuForLive"))){
|
||||||
|
bean.setSyncDanmuForLive(true);
|
||||||
|
}
|
||||||
JSONArray jsonArray = jsonObject.getJSONArray("array");
|
JSONArray jsonArray = jsonObject.getJSONArray("array");
|
||||||
List<LiveConfigDatabaseBean> list = jsonArray.stream().map(roomId -> configService.addConfig(roomId.toString(), bean)).toList();
|
List<LiveConfigDatabaseBean> list = jsonArray.stream().map(roomId -> configService.addConfig(roomId.toString(), bean)).toList();
|
||||||
int countNull = list.stream().filter(Objects::isNull).toList().size();
|
int countNull = list.stream().filter(Objects::isNull).toList().size();
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package com.yutou.bilibili.Controllers;
|
package com.yutou.bilibili.Controllers;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.yutou.biliapi.bean.live.LiveRoomConfig;
|
|
||||||
import com.yutou.biliapi.net.WebSocketManager;
|
|
||||||
import com.yutou.bilibili.datas.ResultData;
|
import com.yutou.bilibili.datas.ResultData;
|
||||||
import com.yutou.bilibili.datas.ReturnCode;
|
import com.yutou.bilibili.datas.ReturnCode;
|
||||||
import com.yutou.bilibili.services.LiveDanmuService;
|
import com.yutou.bilibili.services.LiveDanmuService;
|
||||||
@ -44,7 +42,7 @@ public class LiveDanmuController {
|
|||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@RequestMapping("/live/danmu/get")
|
@RequestMapping("/live/danmu/get")
|
||||||
public JSONObject getDanmu(String roomId, String videoId) {
|
public JSONObject getDanmu(String roomId, String videoId, int page) {
|
||||||
return ResultData.success(service.getDanmu(roomId, videoId));
|
return ResultData.success(service.getDanmu(roomId, videoId, page));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,8 @@ public class LiveVideoDanmu {
|
|||||||
|
|
||||||
List<Danmu> danmu = new ArrayList<>();
|
List<Danmu> danmu = new ArrayList<>();
|
||||||
List<SuperChat> superChat = new ArrayList<>();
|
List<SuperChat> superChat = new ArrayList<>();
|
||||||
|
boolean isNextDanmu = false;
|
||||||
|
long danmuCount = 0;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class Addition {
|
public static class Addition {
|
||||||
@ -60,7 +61,7 @@ public class LiveVideoDanmu {
|
|||||||
this.backgroundBottomColor = bean.getBackgroundBottomColor();
|
this.backgroundBottomColor = bean.getBackgroundBottomColor();
|
||||||
this.userName = bean.getUserName();
|
this.userName = bean.getUserName();
|
||||||
this.userAvatar = bean.getUserAvatar();
|
this.userAvatar = bean.getUserAvatar();
|
||||||
this.userNameColor=bean.getUserNameColor();
|
this.userNameColor = bean.getUserNameColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,44 +10,44 @@ import com.yutou.biliapi.bean.live.database.LiveVideoDatabaseBean;
|
|||||||
import com.yutou.biliapi.bean.websocket.live.WSData;
|
import com.yutou.biliapi.bean.websocket.live.WSData;
|
||||||
import com.yutou.biliapi.databases.BiliLiveConfigDatabase;
|
import com.yutou.biliapi.databases.BiliLiveConfigDatabase;
|
||||||
import com.yutou.biliapi.databases.BiliLiveDatabase;
|
import com.yutou.biliapi.databases.BiliLiveDatabase;
|
||||||
import com.yutou.biliapi.net.WebSocketManager;
|
import com.yutou.biliapi.net.WebSocketClientManager;
|
||||||
import com.yutou.bilibili.Tools.AssTools;
|
import com.yutou.bilibili.Tools.AssTools;
|
||||||
import com.yutou.bilibili.Tools.DateFormatUtils;
|
|
||||||
import com.yutou.bilibili.Tools.Tools;
|
import com.yutou.bilibili.Tools.Tools;
|
||||||
import com.yutou.bilibili.datas.web.LiveVideoDanmu;
|
import com.yutou.bilibili.datas.web.LiveVideoDanmu;
|
||||||
import com.yutou.common.utils.FFmpegUtils;
|
|
||||||
import com.yutou.common.utils.Log;
|
import com.yutou.common.utils.Log;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class LiveDanmuService {
|
public class LiveDanmuService {
|
||||||
|
|
||||||
public void start(String roomId, boolean isUser) {
|
public void start(String roomId, boolean isUser) {
|
||||||
WebSocketManager.getInstance().addRoom(LiveRoomConfig.buildConfig(roomId), isUser);
|
WebSocketClientManager.getInstance().addRoom(LiveRoomConfig.buildConfig(roomId), isUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start(LiveConfigDatabaseBean roomId, boolean isUser) {
|
||||||
|
WebSocketClientManager.getInstance().addRoom(LiveRoomConfig.buildConfig(roomId.getRoomId()), isUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean check(String roomId) {
|
public boolean check(String roomId) {
|
||||||
LiveRoomConfig roomConfig = new LiveRoomConfig();
|
LiveRoomConfig roomConfig = new LiveRoomConfig();
|
||||||
roomConfig.setRoomId(roomId);
|
roomConfig.setRoomId(roomId);
|
||||||
return WebSocketManager.getInstance().checkRoom(roomConfig);
|
return WebSocketClientManager.getInstance().checkRoom(roomConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop(String roomId, boolean isUser) {
|
public void stop(String roomId, boolean isUser) {
|
||||||
WebSocketManager.getInstance().stopRoom(roomId, isUser);
|
WebSocketClientManager.getInstance().stopRoom(roomId, isUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONArray getLiveRoomList() {
|
public JSONArray getLiveRoomList() {
|
||||||
return WebSocketManager.getInstance().getLiveRoomList();
|
return WebSocketClientManager.getInstance().getLiveRoomList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearUserList() {
|
public void clearUserList() {
|
||||||
WebSocketManager.getInstance().clearUserStopList();
|
WebSocketClientManager.getInstance().clearUserStopList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<File> getDanmuFileList(String roomId) {
|
public List<File> getDanmuFileList(String roomId) {
|
||||||
@ -86,21 +86,33 @@ public class LiveDanmuService {
|
|||||||
return String.format("%d小时%d分钟%d秒", hours, minutes, finalRemainingSeconds);
|
return String.format("%d小时%d分钟%d秒", hours, minutes, finalRemainingSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveVideoDanmu getDanmu(String roomId, String videoId) {
|
public LiveVideoDanmu getDanmu(String roomId, String videoId, int page) {
|
||||||
LiveVideoDanmu danmus = new LiveVideoDanmu();
|
LiveVideoDanmu danmus = new LiveVideoDanmu();
|
||||||
BiliLiveDatabase liveDatabase = new BiliLiveDatabase(LiveRoomConfig.buildConfig(roomId));
|
BiliLiveDatabase liveDatabase = new BiliLiveDatabase(LiveRoomConfig.buildConfig(roomId));
|
||||||
LiveVideoDatabaseBean videoBean = liveDatabase.getVideo(videoId);
|
LiveVideoDatabaseBean videoBean = liveDatabase.getVideo(videoId);
|
||||||
if (videoBean == null) {
|
if (videoBean == null) {
|
||||||
return new LiveVideoDanmu();
|
return new LiveVideoDanmu();
|
||||||
}
|
}
|
||||||
long startTime = Long.parseLong(videoId);
|
long startTime = videoBean.getStartTime().getTime();
|
||||||
long endTime = videoBean.getStopTime() == null ? System.currentTimeMillis() : videoBean.getStopTime().getTime();
|
long endTime = videoBean.getStopTime() == null ? System.currentTimeMillis() : videoBean.getStopTime().getTime();
|
||||||
List<LiveDanmuDatabaseBean> danmuList = liveDatabase.getOfTime(startTime, endTime, LiveDanmuDatabaseBean.class);
|
|
||||||
List<LiveSuperChatDatabaseBean> superChatList = liveDatabase.getOfTime(startTime, endTime, LiveSuperChatDatabaseBean.class);
|
List<LiveSuperChatDatabaseBean> superChatList = liveDatabase.getOfTime(startTime, endTime, LiveSuperChatDatabaseBean.class);
|
||||||
for (LiveDanmuDatabaseBean bean : danmuList) {
|
|
||||||
LiveVideoDanmu.Danmu danmu = createDanmu(bean, startTime);
|
long count = liveDatabase.getCount(new LiveDanmuDatabaseBean().getTableName());
|
||||||
danmus.getDanmu().add(danmu);
|
int pageSize = 10000;
|
||||||
|
int pageCount = (int) Math.ceil((double) count / pageSize);
|
||||||
|
|
||||||
|
List<LiveVideoDanmu.Danmu> danmuList = liveDatabase.getOfTime(startTime, endTime, page, pageSize, LiveDanmuDatabaseBean.class)
|
||||||
|
.stream()
|
||||||
|
.map(item -> createDanmu(item, startTime))
|
||||||
|
.filter(item-> item.getTime()>=0)
|
||||||
|
.toList();
|
||||||
|
danmus.getDanmu().addAll(danmuList);
|
||||||
|
danmus.setDanmuCount(count);
|
||||||
|
if (page < pageCount) {
|
||||||
|
danmus.setNextDanmu(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (LiveSuperChatDatabaseBean bean : superChatList) {
|
for (LiveSuperChatDatabaseBean bean : superChatList) {
|
||||||
LiveVideoDanmu.SuperChat superChat = new LiveVideoDanmu.SuperChat(startTime, bean);
|
LiveVideoDanmu.SuperChat superChat = new LiveVideoDanmu.SuperChat(startTime, bean);
|
||||||
danmus.getSuperChat().add(superChat);
|
danmus.getSuperChat().add(superChat);
|
||||||
@ -117,7 +129,7 @@ public class LiveDanmuService {
|
|||||||
danmu.setText(bean.getDanmu());
|
danmu.setText(bean.getDanmu());
|
||||||
danmu.setColor("#" + bean.getFontColor());
|
danmu.setColor("#" + bean.getFontColor());
|
||||||
danmu.setFontSize(bean.getFontSize());
|
danmu.setFontSize(bean.getFontSize());
|
||||||
danmu.setTime(bean.getTime() - startTime);
|
danmu.setTime(bean.getTime().getTime() - startTime);
|
||||||
if (bean.getModel() < 4) {
|
if (bean.getModel() < 4) {
|
||||||
danmu.setBarrageType(LiveVideoDanmu.Danmu.DANMU_TYPE_SCROLL);
|
danmu.setBarrageType(LiveVideoDanmu.Danmu.DANMU_TYPE_SCROLL);
|
||||||
} else if (bean.getModel() == 4) {
|
} else if (bean.getModel() == 4) {
|
||||||
|
@ -18,11 +18,9 @@ import com.yutou.biliapi.enums.LiveVideoCodec;
|
|||||||
import com.yutou.biliapi.enums.LiveVideoDefinition;
|
import com.yutou.biliapi.enums.LiveVideoDefinition;
|
||||||
import com.yutou.biliapi.enums.LiveVideoFormat;
|
import com.yutou.biliapi.enums.LiveVideoFormat;
|
||||||
import com.yutou.biliapi.net.BiliLiveNetApiManager;
|
import com.yutou.biliapi.net.BiliLiveNetApiManager;
|
||||||
import com.yutou.biliapi.net.WebSignManager;
|
import com.yutou.biliapi.net.WebSocketClientManager;
|
||||||
import com.yutou.bilibili.Tools.DateFormatUtils;
|
import com.yutou.bilibili.Tools.DateFormatUtils;
|
||||||
import com.yutou.bilibili.Tools.FileServerUtils;
|
import com.yutou.bilibili.Tools.FileServerUtils;
|
||||||
import com.yutou.bilibili.Tools.LiveInfoNfoTools;
|
|
||||||
import com.yutou.bilibili.Tools.ProcessUtils;
|
|
||||||
import com.yutou.bilibili.datas.VideoFilePath;
|
import com.yutou.bilibili.datas.VideoFilePath;
|
||||||
import com.yutou.bilibili.interfaces.DownloadInterface;
|
import com.yutou.bilibili.interfaces.DownloadInterface;
|
||||||
import com.yutou.common.okhttp.HttpCallback;
|
import com.yutou.common.okhttp.HttpCallback;
|
||||||
@ -32,13 +30,14 @@ import com.yutou.common.utils.ConfigTools;
|
|||||||
import com.yutou.common.utils.FFmpegUtils;
|
import com.yutou.common.utils.FFmpegUtils;
|
||||||
import com.yutou.common.utils.Log;
|
import com.yutou.common.utils.Log;
|
||||||
import okhttp3.Headers;
|
import okhttp3.Headers;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -65,16 +64,16 @@ public class LiveVideoDownloadService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void start(LiveConfigDatabaseBean bean, boolean isUser) {
|
public void start(LiveConfigDatabaseBean bean, boolean isUser) {
|
||||||
if (!isUser && userStopList.contains(bean.getRoomId().toString())) {
|
if (!isUser && userStopList.contains(bean.getRoomId())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isUser) {
|
if (isUser) {
|
||||||
userStopList.remove(bean.getRoomId().toString());
|
userStopList.remove(bean.getRoomId());
|
||||||
}
|
}
|
||||||
if (videoRecord.check(bean.getRoomId().toString())) {
|
if (videoRecord.check(bean.getRoomId())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BiliLiveNetApiManager.getInstance().getApi(bean.getRecordUid()).getRoomInfo(bean.getRoomId().toString()).enqueue(new HttpCallback<LiveRoomInfo>() {
|
BiliLiveNetApiManager.getInstance().getApi(bean.getRecordUid()).getRoomInfo(bean.getRoomId()).enqueue(new HttpCallback<LiveRoomInfo>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Headers headers, int code, String status, LiveRoomInfo response, String rawResponse) {
|
public void onResponse(Headers headers, int code, String status, LiveRoomInfo response, String rawResponse) {
|
||||||
if (response.getLiveStatus() == 1) {
|
if (response.getLiveStatus() == 1) {
|
||||||
@ -178,20 +177,9 @@ public class LiveVideoDownloadService {
|
|||||||
config.setRoomInfo(roomInfo);
|
config.setRoomInfo(roomInfo);
|
||||||
config.setRootPath(bean.getRecordPath());
|
config.setRootPath(bean.getRecordPath());
|
||||||
database = new BiliLiveDatabase(config);
|
database = new BiliLiveDatabase(config);
|
||||||
try {
|
|
||||||
var keyframe = roomInfo.getKeyframe();
|
|
||||||
if (!StringUtils.hasText(keyframe)) {
|
|
||||||
keyframe = roomInfo.getUserCover();
|
|
||||||
}
|
|
||||||
HttpDownloadUtils.download(new HttpDownloadUtils.Builder().setUrl(keyframe)
|
|
||||||
.setPath(rootPath.getAbsolutePath())
|
|
||||||
.setFileName("poster.jpg"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
saveLiveInfo(roomInfo);
|
saveLiveInfo(roomInfo);
|
||||||
api.getLiveRoomPlayInfo(
|
api.getLiveRoomPlayInfo(
|
||||||
bean.getRoomId().toString(),
|
bean.getRoomId(),
|
||||||
LiveProtocol.getAll(),
|
LiveProtocol.getAll(),
|
||||||
LiveVideoFormat.getAll(),
|
LiveVideoFormat.getAll(),
|
||||||
LiveVideoCodec.getAll(),
|
LiveVideoCodec.getAll(),
|
||||||
@ -285,7 +273,7 @@ public class LiveVideoDownloadService {
|
|||||||
// .withNotSymbolParam("-loglevel", "error")
|
// .withNotSymbolParam("-loglevel", "error")
|
||||||
// .withNotSymbolParam("-progress", "-")
|
// .withNotSymbolParam("-progress", "-")
|
||||||
// .withNotSymbolParam("-fflags", "+genpts")
|
// .withNotSymbolParam("-fflags", "+genpts")
|
||||||
.withNotSymbolParam("-threads", "8")
|
// .withNotSymbolParam("-threads", "8")//看bili-go也没有加这个,改成设置好了
|
||||||
// .withNotSymbolParam("-bufsize", "10M")
|
// .withNotSymbolParam("-bufsize", "10M")
|
||||||
.withNotSymbolParam("-f", "segment")
|
.withNotSymbolParam("-f", "segment")
|
||||||
.withNotSymbolParam("-segment_time", "60")
|
.withNotSymbolParam("-segment_time", "60")
|
||||||
@ -301,7 +289,7 @@ public class LiveVideoDownloadService {
|
|||||||
if (ck != null) {
|
if (ck != null) {
|
||||||
// builder = builder.withParam("-cookies", cookie);
|
// builder = builder.withParam("-cookies", cookie);
|
||||||
}
|
}
|
||||||
FFmpegUtils command = builder.build(config.getRoomId(), ffmpegPath, url, savePath.replace(".m3u8","-%04d.ts"));
|
FFmpegUtils command = builder.build(config.getRoomId(), ffmpegPath, url, savePath.replace(".m3u8", "-%04d.ts"));
|
||||||
Log.i(command.getCommandDecode());
|
Log.i(command.getCommandDecode());
|
||||||
try {
|
try {
|
||||||
command.start(new DownloadInterface() {
|
command.start(new DownloadInterface() {
|
||||||
@ -316,6 +304,7 @@ public class LiveVideoDownloadService {
|
|||||||
VideoTask.this.onStart();
|
VideoTask.this.onStart();
|
||||||
Log.i("启动录制:" + playInfo.getRoomId());
|
Log.i("启动录制:" + playInfo.getRoomId());
|
||||||
task = null;
|
task = null;
|
||||||
|
|
||||||
cancel();
|
cancel();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -333,11 +322,18 @@ public class LiveVideoDownloadService {
|
|||||||
if (task != null) {
|
if (task != null) {
|
||||||
task.cancel();
|
task.cancel();
|
||||||
task = null;
|
task = null;
|
||||||
|
try {
|
||||||
|
FileUtils.deleteDirectory(rootPath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.i(rootPath.getAbsolutePath());
|
||||||
|
Log.e(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (videoDatabaseBean != null) {
|
if (videoDatabaseBean != null) {
|
||||||
videoDatabaseBean.setStopTime(new Date());
|
videoDatabaseBean.setStopTime(new Date());
|
||||||
database.addLiveInfo(videoDatabaseBean);
|
database.addLiveInfo(videoDatabaseBean);
|
||||||
}
|
}
|
||||||
|
stopRecordDanmu();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -353,8 +349,21 @@ public class LiveVideoDownloadService {
|
|||||||
videoDatabaseBean.setRoomInfoJson(JSONObject.toJSONString(roomInfo));
|
videoDatabaseBean.setRoomInfoJson(JSONObject.toJSONString(roomInfo));
|
||||||
videoDatabaseBean.setStartTime(new Date());
|
videoDatabaseBean.setStartTime(new Date());
|
||||||
database.addLiveInfo(videoDatabaseBean);
|
database.addLiveInfo(videoDatabaseBean);
|
||||||
|
recordDanmu();
|
||||||
// LiveInfoNfoTools.saveLiveInfoNfo(roomInfo, rootPath.getAbsolutePath(), new File(savePath).getName().replace(".flv", ".nfo"));
|
// LiveInfoNfoTools.saveLiveInfoNfo(roomInfo, rootPath.getAbsolutePath(), new File(savePath).getName().replace(".flv", ".nfo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//录制弹幕
|
||||||
|
private void recordDanmu() {
|
||||||
|
if (bean.isSyncDanmuForLive() && !WebSocketClientManager.getInstance().checkRoom(LiveRoomConfig.buildConfig(bean.getRoomId()))) {
|
||||||
|
WebSocketClientManager.getInstance().addRoom(LiveRoomConfig.buildConfig(bean.getRoomId()), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopRecordDanmu() {
|
||||||
|
if (bean.isSyncDanmuForLive() && WebSocketClientManager.getInstance().checkRoom(LiveRoomConfig.buildConfig(bean.getRoomId()))) {
|
||||||
|
WebSocketClientManager.getInstance().stopRoom(bean.getRoomId(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,20 @@ public class SystemService {
|
|||||||
}
|
}
|
||||||
for (LiveConfigDatabaseBean bean : list) {
|
for (LiveConfigDatabaseBean bean : list) {
|
||||||
try {
|
try {
|
||||||
if (bean.isRecordDanmu() && bean.checkRecordDanmuTime()) {
|
// 如果bean需要录制弹幕,并且检查录制弹幕时间,并且不需要同步直播弹幕,则录制弹幕
|
||||||
|
if (bean.isRecordDanmu() && bean.checkRecordDanmuTime() && !bean.isSyncDanmuForLive()) {
|
||||||
recordDanmu(bean);
|
recordDanmu(bean);
|
||||||
} else if (!bean.checkRecordDanmuTime()) {
|
} else if (!bean.checkRecordDanmuTime() && !bean.isSyncDanmuForLive()) {
|
||||||
|
// 如果不在录制弹幕时间,并且不需要同步直播弹幕,则停止录制弹幕
|
||||||
stopRecordDanmu(bean);
|
stopRecordDanmu(bean);
|
||||||
}
|
}
|
||||||
|
// 如果bean需要录制直播,并且检查录制直播时间
|
||||||
if (bean.isRecordLive() && bean.checkRecordLiveTime()) {
|
if (bean.isRecordLive() && bean.checkRecordLiveTime()) {
|
||||||
|
// 如果需要同步直播弹幕,则录制弹幕
|
||||||
|
if (bean.isSyncDanmuForLive()) {
|
||||||
|
recordDanmu(bean);
|
||||||
|
}
|
||||||
|
// 录制视频
|
||||||
recordVideo(bean);
|
recordVideo(bean);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -83,7 +91,7 @@ public class SystemService {
|
|||||||
|
|
||||||
// 录制弹幕
|
// 录制弹幕
|
||||||
private void recordDanmu(LiveConfigDatabaseBean bean) {
|
private void recordDanmu(LiveConfigDatabaseBean bean) {
|
||||||
danmuService.start(bean.getRoomId().toString(), false);
|
danmuService.start(bean, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 录制视频
|
// 录制视频
|
||||||
|
Loading…
Reference in New Issue
Block a user