新增了关键词检测
新增了手动暂停的恢复
This commit is contained in:
parent
31dd9cf1a1
commit
e4e5696b70
@ -43,6 +43,7 @@
|
|||||||
layer.open({
|
layer.open({
|
||||||
type: 2,
|
type: 2,
|
||||||
title: "添加新房间",
|
title: "添加新房间",
|
||||||
|
maxmin: true,
|
||||||
area: ['600px', '500px'],
|
area: ['600px', '500px'],
|
||||||
content: '/html/ui/createConfig.html?roomId=' + roomId
|
content: '/html/ui/createConfig.html?roomId=' + roomId
|
||||||
|
|
||||||
@ -52,6 +53,7 @@
|
|||||||
layer.open({
|
layer.open({
|
||||||
type: 2,
|
type: 2,
|
||||||
title: "批量编辑",
|
title: "批量编辑",
|
||||||
|
maxmin: true,
|
||||||
area: ['600px', '500px'],
|
area: ['600px', '500px'],
|
||||||
content: '/html/ui/createConfig.html?array=' + array
|
content: '/html/ui/createConfig.html?array=' + array
|
||||||
|
|
||||||
@ -88,7 +90,7 @@
|
|||||||
{ field: 'anchorName', title: '用户名', width: 100, fixed: 'left' },
|
{ field: 'anchorName', title: '用户名', width: 100, fixed: 'left' },
|
||||||
{ field: 'anchorFace', title: '头像', width: 80, templet: '<div><image src="" onerror="showImage(\'{{= d.anchorFace }}\',this);" style="width: 30px;height: 30px;"></div>' },
|
{ field: 'anchorFace', title: '头像', width: 80, templet: '<div><image src="" onerror="showImage(\'{{= d.anchorFace }}\',this);" style="width: 30px;height: 30px;"></div>' },
|
||||||
{ field: 'live_room_id', title: '房间号', width: 80, templet: '<div><a href="https://live.bilibili.com/{{= d.live_room_id}}" target="_blank">{{= d.live_room_id}}</a>' },
|
{ field: 'live_room_id', title: '房间号', width: 80, templet: '<div><a href="https://live.bilibili.com/{{= d.live_room_id}}" target="_blank">{{= d.live_room_id}}</a>' },
|
||||||
{ field: 'recordPath', title: '保存路径', width: 120 },
|
{ field: 'keyword', 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: 'syncDanmuForLive', title: '同步录制', width: 120, sort: true },
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" href="/layui/css/layui.css">
|
<link rel="stylesheet" href="/layui/css/layui.css">
|
||||||
|
<link rel="stylesheet" href="/css/inputTag.css">
|
||||||
<style>
|
<style>
|
||||||
.layui-form-label {
|
.layui-form-label {
|
||||||
width: 120px !important;
|
width: 120px !important;
|
||||||
@ -33,7 +38,7 @@
|
|||||||
<label class="layui-form-label">录制视频时<br>同步录制弹幕</label>
|
<label class="layui-form-label">录制视频时<br>同步录制弹幕</label>
|
||||||
<div class="layui-input-block"><br>
|
<div class="layui-input-block"><br>
|
||||||
<input type="checkbox" name="syncDanmuForLive" lay-skin="switch" lay-filter="switchSync" title="启用|禁用">
|
<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>
|
<i class="layui-icon layui-icon-help layui-text-em " onclick="timeTips(3,this)"></i>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
@ -51,13 +56,21 @@
|
|||||||
<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">
|
||||||
|
<label class="layui-form-label">关键词检测</label>
|
||||||
|
<div class="layui-input-inline fairy-tag-container" style="width: 60%;">
|
||||||
|
<input type="text" id="keywordList" name="keywordList" autocomplete="off"
|
||||||
|
class="layui-input fairy-tag-input ">
|
||||||
|
</div>
|
||||||
|
<i class="layui-icon layui-icon-help" onclick="timeTips(4,this)"></i>
|
||||||
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">弹幕录制时间</label>
|
<label class="layui-form-label">弹幕录制时间</label>
|
||||||
<div class="layui-input-inline">
|
<div class="layui-input-inline">
|
||||||
<input type="text" name="recordDanmuDate" id="recordDanmuDate" value="00:00:00 - 23:59:59"
|
<input type="text" name="recordDanmuDate" id="recordDanmuDate" value="00:00:00 - 23:59:59"
|
||||||
lay-verify="required" autocomplete="off" class="layui-input">
|
lay-verify="required" autocomplete="off" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-mid layui-text-em" onclick="timeTips(false,this)"><i
|
<div class="layui-form-mid layui-text-em" onclick="timeTips(1,this)"><i
|
||||||
class="layui-icon layui-icon-help"></i> </div>
|
class="layui-icon layui-icon-help"></i> </div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@ -66,7 +79,7 @@
|
|||||||
<input type="text" name="recordLiveDate" id="recordLiveDate" value="00:00:00 - 23:59:59"
|
<input type="text" name="recordLiveDate" id="recordLiveDate" value="00:00:00 - 23:59:59"
|
||||||
lay-verify="required" autocomplete="off" class="layui-input">
|
lay-verify="required" autocomplete="off" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-mid layui-text-em" onclick="timeTips(true,this)"><i
|
<div class="layui-form-mid layui-text-em" onclick="timeTips(2,this)"><i
|
||||||
class="layui-icon layui-icon-help"></i> </div>
|
class="layui-icon layui-icon-help"></i> </div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
@ -98,19 +111,20 @@
|
|||||||
<script src="/js/jquery-3.2.1.js"></script>
|
<script src="/js/jquery-3.2.1.js"></script>
|
||||||
<script src="/js/httpUtils.js"></script>
|
<script src="/js/httpUtils.js"></script>
|
||||||
<script src="/js/CommonConfig.js"></script>
|
<script src="/js/CommonConfig.js"></script>
|
||||||
|
<script src="/js/inputTag.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function timeTips(isLive, that) {
|
function timeTips(type, that) {
|
||||||
if (isLive) {
|
var tips = ''
|
||||||
layer.tips('是从开始到结束时间范围内,主播开播会启动录制,超过结束范围不会中断正在录制的任务', that);
|
switch (type) {
|
||||||
} else {
|
case 1: tips = '仅在时间范围内录制,如遇到正在直播,则延迟到下播时停止录制<p style="color:red;">注:如果启用同步录制功能,那本设置将无效</p>'; break;
|
||||||
layer.tips('仅在当前时间范围内录制,如遇到正在直播,则延迟到下播时停止录制', that);
|
case 2: tips = '仅在时间范围内录制,主播开播会启动录制,正在直播时超过结束范围则延迟到下播时停止录制'; break;
|
||||||
|
case 3: tips = '启用后,录制视频时会同步录制弹幕,下播后会同步停止录制.同时上面录制弹幕按钮将失效<p style="color:red;">启用该选项必须启用录制视频功能才可有效</p>'; break;
|
||||||
|
case 4: tips = '在监测时间范围内(周X、时段),开播标题包含关键词才会开始录制<p style="color:red;">仅针对录制视频功能,录制弹幕不受关键词影响</p>'; break;
|
||||||
}
|
}
|
||||||
|
layer.alert(tips)
|
||||||
|
|
||||||
}
|
}
|
||||||
function timeTips2(that) {
|
|
||||||
layer.tips('启用后,录制视频时会同步录制弹幕,下播后会同步停止录制.同时上面录制弹幕按钮将失效', that);
|
|
||||||
|
|
||||||
}
|
|
||||||
var roomId = getParam("roomId");
|
var roomId = getParam("roomId");
|
||||||
var editArray = getParam("array")
|
var editArray = getParam("array")
|
||||||
|
|
||||||
@ -119,7 +133,16 @@
|
|||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var laytpl = layui.laytpl;
|
var laytpl = layui.laytpl;
|
||||||
var laydate = layui.laydate;
|
var laydate = layui.laydate;
|
||||||
|
var inputTag = layui.inputTag;
|
||||||
var windowsIndex;
|
var windowsIndex;
|
||||||
|
var keywordList=[];
|
||||||
|
inputTag = inputTag.render({
|
||||||
|
elem: '#keywordList',
|
||||||
|
data: [],
|
||||||
|
onChange: function (data, value, type) {
|
||||||
|
keywordList = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
form.render();
|
form.render();
|
||||||
// 提交事件
|
// 提交事件
|
||||||
form.on('submit(submit-form)', function (data) {
|
form.on('submit(submit-form)', function (data) {
|
||||||
@ -136,6 +159,7 @@
|
|||||||
weeks.push(i.toString());
|
weeks.push(i.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
field.keywordList = keywordList
|
||||||
field.weeks = weeks;
|
field.weeks = weeks;
|
||||||
console.log(field)
|
console.log(field)
|
||||||
if (editArray === null) {
|
if (editArray === null) {
|
||||||
@ -230,6 +254,11 @@
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
if(json.keyword===undefined||json.keyword===null){
|
||||||
|
json.keyword=[]
|
||||||
|
}
|
||||||
|
keywordList = json.keyword;
|
||||||
|
inputTag.setData(json.keyword)
|
||||||
form.val('form-filter', result);
|
form.val('form-filter', result);
|
||||||
if (json.syncDanmuForLive) {
|
if (json.syncDanmuForLive) {
|
||||||
$("[name='recordDanmu']").prop("disabled", true);
|
$("[name='recordDanmu']").prop("disabled", true);
|
||||||
|
@ -68,15 +68,15 @@
|
|||||||
<p>开播时长:{{= item.liveTime}}</p>
|
<p>开播时长:{{= item.liveTime}}</p>
|
||||||
直播录制状态:
|
直播录制状态:
|
||||||
{{# if(item.downloadVideo){ }}
|
{{# if(item.downloadVideo){ }}
|
||||||
<span style="color: #16b777" onclick="clickVideo('{{= item.roomId}}',true,this)">录制中</span>
|
<span style="color: #16b777" onclick="clickVideo('{{= item.roomId}}',true,this)">{{= item.videoListen}}</span>
|
||||||
{{# } else{ }}
|
{{# } else{ }}
|
||||||
<span style="color: #FD482C" onclick="clickVideo('{{= item.roomId}}',false,this)">待机中</span>
|
<span style="color: #FD482C" onclick="clickVideo('{{= item.roomId}}',false,this)">{{= item.videoListen}}</span>
|
||||||
{{# }; }}<br>
|
{{# }; }}<br>
|
||||||
弹幕录制状态:
|
弹幕录制状态:
|
||||||
{{# if(item.danmu){ }}
|
{{# if(item.danmu){ }}
|
||||||
<span style="color: #16b777" onclick="clickDanmu('{{= item.roomId}}',true,this)">录制中</span>
|
<span style="color: #16b777" onclick="clickDanmu('{{= item.roomId}}',true,this)">{{= item.danmuListen}}</span>
|
||||||
{{# } else{ }}
|
{{# } else{ }}
|
||||||
<span style="color: #FD482C" onclick="clickDanmu('{{= item.roomId}}',false,this)">待机中</span>
|
<span style="color: #FD482C" onclick="clickDanmu('{{= item.roomId}}',false,this)">{{= item.danmuListen}}</span>
|
||||||
{{# }; }}<br>
|
{{# }; }}<br>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -98,8 +98,8 @@
|
|||||||
console.log(roomId)
|
console.log(roomId)
|
||||||
window.open("https://live.bilibili.com/" + roomId, '_blank')
|
window.open("https://live.bilibili.com/" + roomId, '_blank')
|
||||||
}
|
}
|
||||||
function clickVideo(roomId, status,that) {
|
function clickVideo(roomId, status, that) {
|
||||||
const title = "是否" + (status ? "停止" : "启动") + "录制视频?"
|
const title = "是否" + (status ? "停止" : "启动") + "录制视频?<p style='color:red;'>手动干预后不再自动监听,第二天或重新配置可清除该状态</p>"
|
||||||
layer.confirm(title, { icon: 3 }, function () {
|
layer.confirm(title, { icon: 3 }, function () {
|
||||||
if (status) {
|
if (status) {
|
||||||
stopLiveVideo(roomId)
|
stopLiveVideo(roomId)
|
||||||
@ -122,7 +122,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function clickDanmu(roomId, status) {
|
function clickDanmu(roomId, status) {
|
||||||
const title = "是否" + (status ? "停止" : "启动") + "录制弹幕?"
|
const title = "是否" + (status ? "停止" : "启动") + "录制弹幕?<p style='color:red;'>手动干预后不再自动监听,第二天或重新配置可清除该状态</p>"
|
||||||
layer.confirm(title, { icon: 3 }, function () {
|
layer.confirm(title, { icon: 3 }, function () {
|
||||||
if (status) {
|
if (status) {
|
||||||
stopLiveDanmu(roomId)
|
stopLiveDanmu(roomId)
|
||||||
|
170
Web/js/inputTag.js
Normal file
170
Web/js/inputTag.js
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Name: inputTag
|
||||||
|
* Author: cshaptx4869
|
||||||
|
* Project: https://github.com/cshaptx4869/inputTag
|
||||||
|
*/
|
||||||
|
(function (define) {
|
||||||
|
define(['jquery'], function ($) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
class InputTag {
|
||||||
|
|
||||||
|
options = {
|
||||||
|
elem: '.fairy-tag-input',
|
||||||
|
theme: ['fairy-bg-red', 'fairy-bg-orange', 'fairy-bg-green', 'fairy-bg-cyan', 'fairy-bg-blue', 'fairy-bg-black'],
|
||||||
|
data: [],
|
||||||
|
removeKeyNum: 8,
|
||||||
|
createKeyNum: 13,
|
||||||
|
permanentData: [],
|
||||||
|
sortable: false
|
||||||
|
};
|
||||||
|
get elem() {
|
||||||
|
return $(this.options.elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
get copyData() {
|
||||||
|
return [...this.options.data];
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(options) {
|
||||||
|
this.render(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(options) {
|
||||||
|
this.init(options);
|
||||||
|
this.listen();
|
||||||
|
}
|
||||||
|
setData(data){
|
||||||
|
this.options.data=data;
|
||||||
|
this.init(this.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(options) {
|
||||||
|
var spans = '', that = this;
|
||||||
|
this.options = $.extend(this.options, options);
|
||||||
|
!this.elem.attr('placeholder') && this.elem.attr('placeholder', '添加标签');
|
||||||
|
$.each(this.options.data, function (index, item) {
|
||||||
|
spans += that.spanHtml(item);
|
||||||
|
});
|
||||||
|
this.elem.before(spans);
|
||||||
|
}
|
||||||
|
|
||||||
|
listen() {
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
this.elem.parent().on('click', 'a', function () {
|
||||||
|
that.removeItem($(this).parent('span'));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.elem.parent().on('click', function () {
|
||||||
|
that.elem.focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.elem.keydown(function (event) {
|
||||||
|
var keyNum = (event.keyCode ? event.keyCode : event.which);
|
||||||
|
if (keyNum === that.options.removeKeyNum) {
|
||||||
|
if (!that.elem.val().trim()) {
|
||||||
|
var closeItems = that.elem.parent().find('a');
|
||||||
|
if (closeItems.length) {
|
||||||
|
that.removeItem($(closeItems[closeItems.length - 1]).parent('span'));
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (keyNum === that.options.createKeyNum) {
|
||||||
|
that.createItem();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.elem.blur(function () {
|
||||||
|
that.createItem();
|
||||||
|
});
|
||||||
|
if (this.options.sortable) {
|
||||||
|
Sortable.create(this.elem.parent()[0], {
|
||||||
|
handle: 'span',
|
||||||
|
onSort: function (event) {
|
||||||
|
that.options.data = that.elem.parent()
|
||||||
|
.find('span.fairy-tag>span')
|
||||||
|
.map(function (index, item) {
|
||||||
|
return $(item).text();
|
||||||
|
}).toArray();
|
||||||
|
|
||||||
|
that.onChange($(event.item).children('span').text(), 'sort');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createItem() {
|
||||||
|
var value = this.elem.val().trim();
|
||||||
|
|
||||||
|
if (this.options.beforeCreate && typeof this.options.beforeCreate === 'function') {
|
||||||
|
var modifiedValue = this.options.beforeCreate(this.copyData, value);
|
||||||
|
if (typeof modifiedValue == 'string' && modifiedValue) {
|
||||||
|
value = modifiedValue;
|
||||||
|
} else {
|
||||||
|
value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
if (!this.options.data.includes(value)) {
|
||||||
|
this.options.data.push(value);
|
||||||
|
this.elem.before(this.spanHtml(value));
|
||||||
|
this.onChange(value, 'create');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.elem.val('');
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItem(target) {
|
||||||
|
var that = this;
|
||||||
|
var closeSpan = target.remove(),
|
||||||
|
closeSpanText = $(closeSpan).children('span').text();
|
||||||
|
var value = that.options.data.splice($.inArray(closeSpanText, that.options.data), 1);
|
||||||
|
value.length === 1 && that.onChange(value[0], 'remove');
|
||||||
|
}
|
||||||
|
|
||||||
|
randomColor() {
|
||||||
|
return this.options.theme[Math.floor(Math.random() * this.options.theme.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
spanHtml(value) {
|
||||||
|
return '<span class="fairy-tag fairy-anim-fadein ' + this.randomColor() + '">' +
|
||||||
|
'<span>' + value + '</span>' +
|
||||||
|
(this.options.permanentData.includes(value) ? '' : '<a href="#" title="删除标签">×</a>') +
|
||||||
|
'</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(value, type) {
|
||||||
|
this.options.onChange && typeof this.options.onChange === 'function' && this.options.onChange(this.copyData, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
return this.copyData;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearData() {
|
||||||
|
this.options.data = [];
|
||||||
|
this.elem.prevAll('span.fairy-tag').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
render(options) {
|
||||||
|
return new InputTag(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
|
||||||
|
var MOD_NAME = 'inputTag';
|
||||||
|
if (typeof module !== 'undefined' && module.exports) { //Node
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else if (window.layui && layui.define) {
|
||||||
|
layui.define('jquery', function (exports) { //layui加载
|
||||||
|
exports(MOD_NAME, factory(layui.jquery));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window[MOD_NAME] = factory(window.jQuery);
|
||||||
|
}
|
||||||
|
}));
|
@ -37,7 +37,7 @@ public class LiveConfigDatabaseBean extends AbsDatabasesBean {
|
|||||||
@JSONField(name = "syncDanmuForLive")
|
@JSONField(name = "syncDanmuForLive")
|
||||||
private boolean isSyncDanmuForLive;
|
private boolean isSyncDanmuForLive;
|
||||||
@JSONField(name = "keyword")
|
@JSONField(name = "keyword")
|
||||||
private List<String> keywordList;
|
private List<String> keywordList=new ArrayList<>();
|
||||||
@JSONField(name = "weeks")
|
@JSONField(name = "weeks")
|
||||||
private List<String> weeks=Arrays.asList("1","2","3","4","5","6","7");
|
private List<String> weeks=Arrays.asList("1","2","3","4","5","6","7");
|
||||||
@JSONField(name = "recordPath")
|
@JSONField(name = "recordPath")
|
||||||
|
@ -97,6 +97,14 @@ public class WebSocketServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeUserStopList(String roomId) {
|
||||||
|
userStopList.remove(roomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUserStopList(String roomId) {
|
||||||
|
return userStopList.contains(roomId);
|
||||||
|
}
|
||||||
|
|
||||||
private class DanmuTask implements Runnable {
|
private class DanmuTask implements Runnable {
|
||||||
LiveRoomConfig roomConfig;
|
LiveRoomConfig roomConfig;
|
||||||
WebSocketClientTh client;
|
WebSocketClientTh client;
|
||||||
|
@ -139,7 +139,7 @@ public class LiveConfigController {
|
|||||||
@RequestMapping(value = "set/array", method = RequestMethod.POST)
|
@RequestMapping(value = "set/array", method = RequestMethod.POST)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public JSONObject addArrayConfig(@RequestBody JSONObject jsonObject) {
|
public JSONObject addArrayConfig(@RequestBody JSONObject jsonObject) {
|
||||||
JSONObject config=jsonObject.getJSONObject("config");
|
JSONObject config = jsonObject.getJSONObject("config");
|
||||||
LiveConfigDatabaseBean bean = config.to(LiveConfigDatabaseBean.class);
|
LiveConfigDatabaseBean bean = config.to(LiveConfigDatabaseBean.class);
|
||||||
if (!bean.verifyLiveTimer()) {
|
if (!bean.verifyLiveTimer()) {
|
||||||
return ResultData.fail(ReturnCode.RC999.getCode(), "视频录制时间格式错误");
|
return ResultData.fail(ReturnCode.RC999.getCode(), "视频录制时间格式错误");
|
||||||
@ -147,15 +147,18 @@ public class LiveConfigController {
|
|||||||
if (!bean.verifyDanmuTimer()) {
|
if (!bean.verifyDanmuTimer()) {
|
||||||
return ResultData.fail(ReturnCode.RC999.getCode(), "弹幕录制时间格式错误");
|
return ResultData.fail(ReturnCode.RC999.getCode(), "弹幕录制时间格式错误");
|
||||||
}
|
}
|
||||||
if("on".equals(config.getString("recordDanmu"))){
|
if ("on".equals(config.getString("recordDanmu"))) {
|
||||||
bean.setRecordDanmu(true);
|
bean.setRecordDanmu(true);
|
||||||
}
|
}
|
||||||
if("on".equals(config.getString("recordLive"))){
|
if ("on".equals(config.getString("recordLive"))) {
|
||||||
bean.setRecordLive(true);
|
bean.setRecordLive(true);
|
||||||
}
|
}
|
||||||
if("on".equals(config.getString("syncDanmuForLive"))){
|
if ("on".equals(config.getString("syncDanmuForLive"))) {
|
||||||
bean.setSyncDanmuForLive(true);
|
bean.setSyncDanmuForLive(true);
|
||||||
}
|
}
|
||||||
|
if (config.containsKey("keywordList")) {
|
||||||
|
bean.setKeywordList(config.getList("keywordList", String.class));
|
||||||
|
}
|
||||||
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,5 +1,6 @@
|
|||||||
package com.yutou.bilibili.Controllers;
|
package com.yutou.bilibili.Controllers;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.yutou.bilibili.datas.ResultData;
|
import com.yutou.bilibili.datas.ResultData;
|
||||||
import com.yutou.bilibili.services.LiveDanmuService;
|
import com.yutou.bilibili.services.LiveDanmuService;
|
||||||
@ -10,6 +11,8 @@ import org.springframework.stereotype.Controller;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class LiveController {
|
public class LiveController {
|
||||||
@Resource
|
@Resource
|
||||||
@ -22,13 +25,31 @@ public class LiveController {
|
|||||||
|
|
||||||
@RequestMapping("/live/list")
|
@RequestMapping("/live/list")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public JSONObject getLiveList(int page,int limit) {
|
public JSONObject getLiveList(int page, int limit) {
|
||||||
return ResultData.success(liveService.getLiveList(page,limit), liveService.getConfigCount());
|
List<JSONObject> list = liveService.getLiveList(page, limit).stream().map(it -> {
|
||||||
|
JSONObject json = JSONObject.parseObject(JSON.toJSONString(it));
|
||||||
|
if (videoService.isUserStopList(it.getRoomId())) {
|
||||||
|
json.put("videoListen", "已暂停");
|
||||||
|
} else if (it.isDownloadVideo()) {
|
||||||
|
json.put("videoListen", "录制中");
|
||||||
|
} else {
|
||||||
|
json.put("videoListen", "待机中");
|
||||||
|
}
|
||||||
|
if (danmuService.isUserStopList(it.getRoomId())) {
|
||||||
|
json.put("danmuListen", "已暂停");
|
||||||
|
} else if (it.isDanmu()) {
|
||||||
|
json.put("danmuListen", "录制中");
|
||||||
|
} else {
|
||||||
|
json.put("danmuListen", "待机中");
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}).toList();
|
||||||
|
return ResultData.success(list, liveService.getConfigCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/live/gift/info")
|
@RequestMapping("/live/gift/info")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public JSONObject download(String roomId, String videoId) {
|
public JSONObject download(String roomId, String videoId) {
|
||||||
return ResultData.success(liveService.getGiftInfo(roomId,videoId));
|
return ResultData.success(liveService.getGiftInfo(roomId, videoId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,10 @@ import java.util.List;
|
|||||||
public class LiveConfigService {
|
public class LiveConfigService {
|
||||||
@Resource
|
@Resource
|
||||||
LiveDatabasesService databasesService;
|
LiveDatabasesService databasesService;
|
||||||
|
@Resource
|
||||||
|
LiveDanmuService danmuService;
|
||||||
|
@Resource
|
||||||
|
LiveVideoDownloadService videoDownloadService;
|
||||||
|
|
||||||
public LiveConfigDatabaseBean addConfig(String url, LiveConfigDatabaseBean bean) {
|
public LiveConfigDatabaseBean addConfig(String url, LiveConfigDatabaseBean bean) {
|
||||||
if (!StringUtils.hasText(url)) {
|
if (!StringUtils.hasText(url)) {
|
||||||
@ -37,6 +41,8 @@ public class LiveConfigService {
|
|||||||
bean.setAnchorFace(infoBean.getInfo().getFace());
|
bean.setAnchorFace(infoBean.getInfo().getFace());
|
||||||
bean.setAnchorName(infoBean.getInfo().getUname());
|
bean.setAnchorName(infoBean.getInfo().getUname());
|
||||||
databasesService.getConfigDatabase().setConfig(bean);
|
databasesService.getConfigDatabase().setConfig(bean);
|
||||||
|
danmuService.removeUserStopList(roomId);
|
||||||
|
videoDownloadService.removeUserStopList(roomId);
|
||||||
return bean;
|
return bean;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -66,7 +72,8 @@ public class LiveConfigService {
|
|||||||
public List<LiveConfigDatabaseBean> getAllConfig() {
|
public List<LiveConfigDatabaseBean> getAllConfig() {
|
||||||
return databasesService.getConfigDatabase().getAllConfig();
|
return databasesService.getConfigDatabase().getAllConfig();
|
||||||
}
|
}
|
||||||
public List<LiveConfigDatabaseBean> getConfigs(int page,int limit) {
|
|
||||||
|
public List<LiveConfigDatabaseBean> getConfigs(int page, int limit) {
|
||||||
return databasesService.getConfigDatabase().getConfigs(page, limit);
|
return databasesService.getConfigDatabase().getConfigs(page, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,12 @@ public class LiveDanmuService {
|
|||||||
public void clearUserList() {
|
public void clearUserList() {
|
||||||
webSocketServer.clearUserStopList();
|
webSocketServer.clearUserStopList();
|
||||||
}
|
}
|
||||||
|
public void removeUserStopList(String roomId) {
|
||||||
|
webSocketServer.removeUserStopList(roomId);
|
||||||
|
}
|
||||||
|
public boolean isUserStopList(String roomId) {
|
||||||
|
return webSocketServer.isUserStopList(roomId);
|
||||||
|
}
|
||||||
|
|
||||||
public List<File> getDanmuFileList(String roomId) {
|
public List<File> getDanmuFileList(String roomId) {
|
||||||
LiveConfigDatabaseBean bean = liveDatabasesService.getConfigDatabase().getConfig(roomId);
|
LiveConfigDatabaseBean bean = liveDatabasesService.getConfigDatabase().getConfig(roomId);
|
||||||
|
@ -67,6 +67,12 @@ public class LiveVideoDownloadService {
|
|||||||
public void clearUserStopList() {
|
public void clearUserStopList() {
|
||||||
userStopList.clear();
|
userStopList.clear();
|
||||||
}
|
}
|
||||||
|
public void removeUserStopList(String roomId) {
|
||||||
|
userStopList.remove(roomId);
|
||||||
|
}
|
||||||
|
public boolean isUserStopList(String roomId) {
|
||||||
|
return userStopList.contains(roomId);
|
||||||
|
}
|
||||||
|
|
||||||
public void start(LiveConfigDatabaseBean bean, boolean isUser) {
|
public void start(LiveConfigDatabaseBean bean, boolean isUser) {
|
||||||
if (!isUser && userStopList.contains(bean.getRoomId())) {
|
if (!isUser && userStopList.contains(bean.getRoomId())) {
|
||||||
@ -82,6 +88,19 @@ public class LiveVideoDownloadService {
|
|||||||
@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) {
|
||||||
|
if (!bean.getKeywordList().isEmpty() && !isUser) {
|
||||||
|
String foundKey = bean.getKeywordList().stream()
|
||||||
|
.filter(key -> response.getTitle().contains(key))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (foundKey != null) {
|
||||||
|
Log.i(response.getRoomId(), "检测到开播关键词", foundKey, response.getTitle());
|
||||||
|
} else {
|
||||||
|
Log.i(response.getRoomId(), "未检测到关键词", response.getTitle(), Arrays.toString(bean.getKeywordList().toArray()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
VideoTask task = new VideoTask(bean, response);
|
VideoTask task = new VideoTask(bean, response);
|
||||||
executor.execute(task);
|
executor.execute(task);
|
||||||
} else {
|
} else {
|
||||||
@ -281,7 +300,7 @@ public class LiveVideoDownloadService {
|
|||||||
// .withNotSymbolParam("-threads", "8")//看bili-go也没有加这个,改成设置好了
|
// .withNotSymbolParam("-threads", "8")//看bili-go也没有加这个,改成设置好了
|
||||||
// .withNotSymbolParam("-bufsize", "10M")
|
// .withNotSymbolParam("-bufsize", "10M")
|
||||||
.withNotSymbolParam("-f", "segment")
|
.withNotSymbolParam("-f", "segment")
|
||||||
.withNotSymbolParam("-rw_timeout","60000000")
|
.withNotSymbolParam("-rw_timeout", "60000000")
|
||||||
.withNotSymbolParam("-segment_time", "60")
|
.withNotSymbolParam("-segment_time", "60")
|
||||||
.withNotSymbolParam("-segment_format", "mpegts")
|
.withNotSymbolParam("-segment_format", "mpegts")
|
||||||
.withNotSymbolParam("-map", "0")
|
.withNotSymbolParam("-map", "0")
|
||||||
|
Loading…
Reference in New Issue
Block a user