From 4c25797ddac695e54022597909e1a79e04a603d5 Mon Sep 17 00:00:00 2001
From: leosam1024 <127861447+leosam1024@users.noreply.github.com>
Date: Sat, 17 Jun 2023 21:03:40 +0800
Subject: [PATCH] =?UTF-8?q?MOD:=E6=B7=BB=E5=8A=A0=E9=A6=96=E9=A1=B5?=
=?UTF-8?q?=E5=B1=95=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 3 +-
README.md | 5 +-
.../com/leosam/tvbox/mv/MainVerticle.java | 37 ++++++++--
.../com/leosam/tvbox/mv/data/VodClass.java | 30 ++++++++
.../com/leosam/tvbox/mv/data/VodResult.java | 13 ++++
.../leosam/tvbox/mv/service/MvService.java | 73 ++++++++++++++++++-
src/main/resources/static/tvbox.json | 2 +-
src/main/resources/tvbox/home.json | 25 +++++++
8 files changed, 177 insertions(+), 11 deletions(-)
create mode 100644 src/main/java/com/leosam/tvbox/mv/data/VodClass.java
create mode 100644 src/main/resources/tvbox/home.json
diff --git a/.gitignore b/.gitignore
index b83c6e0..f6c6d97 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,4 +35,5 @@ build/
### VS Code ###
.vscode/
-/.mvn
\ No newline at end of file
+/.mvn
+/dependency-reduced-pom.xml
diff --git a/README.md b/README.md
index 242d396..fba7fc8 100644
--- a/README.md
+++ b/README.md
@@ -90,4 +90,7 @@ maxCount:最大返回值,返回结果里面 list 最大数量。 最大值10
### 直播MV来源:
小武哥 :https://t.me/BoBaiBroo
-直播文件:https://t.me/fongmi_offical/54024/244800
\ No newline at end of file
+直播文件:https://t.me/fongmi_offical/54024/244800
+
+### 声明
+仅供学习交流,严禁用于商业用途,请于24小时内删除。
\ No newline at end of file
diff --git a/src/main/java/com/leosam/tvbox/mv/MainVerticle.java b/src/main/java/com/leosam/tvbox/mv/MainVerticle.java
index 28c9953..156ae1f 100644
--- a/src/main/java/com/leosam/tvbox/mv/MainVerticle.java
+++ b/src/main/java/com/leosam/tvbox/mv/MainVerticle.java
@@ -13,6 +13,7 @@ import io.vertx.core.http.HttpServer;
import io.vertx.core.json.Json;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
+import io.vertx.ext.web.handler.StaticHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -52,7 +53,8 @@ public class MainVerticle extends AbstractVerticle {
Router router = Router.router(vertx);
router.route("/mv/search").handler(this::searchMv);
router.route("/mv/vod").handler(this::searchMvVod);
- router.route().handler(req -> req.response().putHeader("content-type", "text/plain").end("Hello from Vert.x!"));
+ router.route("/*").handler(StaticHandler.create("static"));
+ router.route().handler(this::home);
httpServer.requestHandler(router);
httpServer.listen(7777, http -> {
@@ -66,21 +68,36 @@ public class MainVerticle extends AbstractVerticle {
port = httpServer.actualPort();
}
+ /**
+ * 参考 ...
+ * @param req
+ */
private void searchMvVod(RoutingContext req) {
// 获取参数
String wd = VertxUtils.queryParam(req, "wd");
- String ac = VertxUtils.queryParam(req, "ac");
String ids = VertxUtils.queryParam(req, "ids");
- String maxCount = VertxUtils.queryParam(req, "maxCount");
- int max = Math.min(Math.max(NumberUtils.toInt(maxCount, 100), 10), 1000);
String query = StringUtils.isNotEmpty(wd) ? wd : ids;
+ String ac = VertxUtils.queryParam(req, "ac");
+ String type = VertxUtils.queryParam(req, "t");
+ //query = StringUtils.isNotEmpty(query) ? query : "我";
+ String maxCount = VertxUtils.queryParam(req, "maxCount");
+ int max = Math.min(Math.max(NumberUtils.toInt(maxCount, 200), 10), 1000);
+ String pg = VertxUtils.queryParam(req, "pg");
+ int page = NumberUtils.toInt(pg, 0);
// 处理结果
VodResult vodResult = null;
try {
- if (mvService != null) {
+ // 搜索
+ if (mvService != null && StringUtils.isNotEmpty(query) && page <= 0) {
vodResult = mvService.searchVod(query, max);
}
+
+ // 首页
+ if (mvService != null && StringUtils.isEmpty(query)) {
+ vodResult = mvService.searchVodHome(type, page);
+ }
+
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -95,8 +112,10 @@ public class MainVerticle extends AbstractVerticle {
private void searchMv(RoutingContext req) {
// 获取参数
String query = VertxUtils.queryParam(req, "query");
+ String wd = VertxUtils.queryParam(req, "wd");
+ query = StringUtils.isNotEmpty(query) ? query : wd;
String maxCount = VertxUtils.queryParam(req, "maxCount");
- int max = Math.min(Math.max(NumberUtils.toInt(maxCount, 100), 10), 1000);
+ int max = Math.min(Math.max(NumberUtils.toInt(maxCount, 200), 10), 1000);
// 处理结果
MvResult search = null;
@@ -115,6 +134,12 @@ public class MainVerticle extends AbstractVerticle {
.end(jsonString);
}
+ private void home(RoutingContext req) {
+ req.response()
+ .putHeader("content-type", "text/plain;charset=utf-8")
+ .end("MV搜索服务\n源码网址:https://github.com/leosam1024/tvbox-mv");
+ }
+
public static void main(String[] args) throws Exception {
Vertx vertx = Vertx.vertx();
diff --git a/src/main/java/com/leosam/tvbox/mv/data/VodClass.java b/src/main/java/com/leosam/tvbox/mv/data/VodClass.java
new file mode 100644
index 0000000..2b9d0c8
--- /dev/null
+++ b/src/main/java/com/leosam/tvbox/mv/data/VodClass.java
@@ -0,0 +1,30 @@
+package com.leosam.tvbox.mv.data;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class VodClass {
+
+ @JsonProperty("type_id")
+ private String typeId;
+
+ @JsonProperty("type_name")
+ private String typeName;
+
+ public String getTypeId() {
+ return typeId;
+ }
+
+ public VodClass setTypeId(String typeId) {
+ this.typeId = typeId;
+ return this;
+ }
+
+ public String getTypeName() {
+ return typeName;
+ }
+
+ public VodClass setTypeName(String typeName) {
+ this.typeName = typeName;
+ return this;
+ }
+}
diff --git a/src/main/java/com/leosam/tvbox/mv/data/VodResult.java b/src/main/java/com/leosam/tvbox/mv/data/VodResult.java
index cb52c05..041feb1 100644
--- a/src/main/java/com/leosam/tvbox/mv/data/VodResult.java
+++ b/src/main/java/com/leosam/tvbox/mv/data/VodResult.java
@@ -1,5 +1,7 @@
package com.leosam.tvbox.mv.data;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
import java.util.List;
/**
@@ -14,6 +16,8 @@ public class VodResult {
private int limit;
private int total;
private List list;
+ @JsonProperty("class")
+ private List vodClassList;
public void init() {
this.code = 1;
@@ -76,4 +80,13 @@ public class VodResult {
this.list = list;
return this;
}
+
+ public List getVodClassList() {
+ return vodClassList;
+ }
+
+ public VodResult setVodClassList(List vodClassList) {
+ this.vodClassList = vodClassList;
+ return this;
+ }
}
diff --git a/src/main/java/com/leosam/tvbox/mv/service/MvService.java b/src/main/java/com/leosam/tvbox/mv/service/MvService.java
index c03d5d7..a27e872 100644
--- a/src/main/java/com/leosam/tvbox/mv/service/MvService.java
+++ b/src/main/java/com/leosam/tvbox/mv/service/MvService.java
@@ -1,8 +1,11 @@
package com.leosam.tvbox.mv.service;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.leosam.tvbox.mv.data.MvContent;
import com.leosam.tvbox.mv.data.MvResult;
import com.leosam.tvbox.mv.data.Vod;
+import com.leosam.tvbox.mv.data.VodClass;
import com.leosam.tvbox.mv.data.VodResult;
import com.leosam.tvbox.mv.lucene.MvIndex;
import com.leosam.tvbox.mv.lucene.MvSearcher;
@@ -23,9 +26,12 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
@@ -35,9 +41,14 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class MvService {
private static final Logger logger = LoggerFactory.getLogger(MvService.class);
-
private static final String indexDirectoryPath = "index";
private static final String MV_FILE = "tvbox/16wMV.txt";
+ private static final Map> homeConfigMap = new LinkedHashMap<>();
+ private static final String HOME_KEY = "HOME";
+ /**
+ * 最低相似分数
+ */
+ private static final float MIN_QUERY_SCORE = 3.0F;
private MvSearcher mvSearcher;
@@ -56,6 +67,10 @@ public class MvService {
result.setTotalHits(topDocs.totalHits.value);
result.setList(new ArrayList<>(topDocs.scoreDocs.length));
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
+ // 分数太低 忽略
+ if(scoreDoc.score < MIN_QUERY_SCORE){
+ break;
+ }
Document document = mvSearcher.getDocument(scoreDoc.doc);
if (document == null) {
continue;
@@ -97,7 +112,6 @@ public class MvService {
vod.setVodName(wd);
vod.setVodPlayFrom("mv");
vod.setVodPic("http://yanxuan.nosdn.127.net/b6fb987ce79f308949e44f5129a4b51c.jpeg");
- // vod.setVodPic("http://m4.auto.itc.cn/auto/content/20230611/45d65d8a001f0c5aa008030f41c98666.jpeg");
List playUrlList = new LinkedList<>();
Set vodActorList = new LinkedHashSet<>();
for (MvContent content : search.getList()) {
@@ -116,7 +130,51 @@ public class MvService {
return vodResult;
}
+ public VodResult searchVodHome(String type, int page) throws Exception {
+ if (page > 1) {
+ return new VodResult();
+ }
+
+ StopWatch stopWatch = new StopWatch();
+ stopWatch.start();
+
+ VodResult vodResult = new VodResult();
+ vodResult.init();
+ vodResult.setList(new ArrayList<>()).getList();
+
+ // 分类
+ if (StringUtils.isEmpty(type)) {
+ vodResult.setVodClassList(new ArrayList<>(homeConfigMap.size()));
+ Set keySet = homeConfigMap.keySet();
+ for (String key : keySet) {
+ if (HOME_KEY.equalsIgnoreCase(key)) {
+ continue;
+ }
+ VodClass vodClass = new VodClass().setTypeId(key).setTypeName(key);
+ vodResult.getVodClassList().add(vodClass);
+ }
+ }
+
+ // 首页mv推荐
+ String thisType = StringUtils.isNotEmpty(type) ? type : HOME_KEY;
+ List geshouList = homeConfigMap.getOrDefault(thisType, new ArrayList<>());
+ for (String geshou : geshouList) {
+ Vod vod = new Vod();
+ vod.setVodId(geshou);
+ vod.setVodName(geshou);
+ vod.setVodPlayFrom("mv");
+ vod.setVodPic("http://yanxuan.nosdn.127.net/b6fb987ce79f308949e44f5129a4b51c.jpeg");
+ vodResult.getList().add(vod);
+ }
+
+ stopWatch.stop();
+ logger.info("加载首页成功,类型={}, 返回={}条, 耗时{}毫秒", thisType, vodResult.getList().size(), stopWatch.getTotalTimeMillis());
+ return vodResult;
+ }
+
public void initIndex() throws Exception {
+ // 加载首页配置
+ buildHomeConfig();
// 重建索引
String indexAbsolutePath = new File(indexDirectoryPath).getAbsoluteFile().getAbsolutePath();
@@ -129,6 +187,17 @@ public class MvService {
search("五月天", 10);
}
+ private void buildHomeConfig() {
+ try {
+ String content = ClassPathReaderUtils.getContent("tvbox/home.json");
+ Map> map = new ObjectMapper().readValue(content, new TypeReference>>() {
+ });
+ homeConfigMap.putAll(map);
+ logger.info("加载首页配置成功");
+ } catch (Exception e) {
+ logger.error("buildHomeConfig error", e);
+ }
+ }
private static void reBuildIndex(String indexDirectoryPath) throws IOException {
File file = new File(indexDirectoryPath).getAbsoluteFile();
diff --git a/src/main/resources/static/tvbox.json b/src/main/resources/static/tvbox.json
index a644872..426dcc0 100644
--- a/src/main/resources/static/tvbox.json
+++ b/src/main/resources/static/tvbox.json
@@ -4,7 +4,7 @@
"key": "MV_vod",
"name": "👀┃MV┃视频",
"type": 1,
- "api": "http://192.168.31.253:7777/mv/vod",
+ "api": "./mv/vod",
"searchable": 1,
"quickSearch": 1,
"filterable": 1
diff --git a/src/main/resources/tvbox/home.json b/src/main/resources/tvbox/home.json
new file mode 100644
index 0000000..a46caa1
--- /dev/null
+++ b/src/main/resources/tvbox/home.json
@@ -0,0 +1,25 @@
+{
+ "HOME" : [ "周杰伦", "林俊杰", "张学友", "邓紫棋", "五月天", "梁咏琪", "王菲", "张信哲", "陈奕迅", "刘德华", "林忆莲", "Beyond", "F4", "S.H.E", "蔡依林", "张惠妹", "刘若英", "方大同", "林宥嘉", "白安", "金志文", "郭富城", "韦礼安", "容祖儿", "庾澄庆", "华晨宇", "苏打绿", "任贤齐", "庄心妍", "田馥甄", "杨坤", "林忆诗筑", "TFBOYS", "EXO", "李荣浩", "范晓萱", "林玉英", "王力宏", "光良", "邓丽君", "林青霞", "杨洪基", "高慧君", "高胜美", "庞龙", "高晓松", "童丽", "枚文琪", "王菀之", "张格格", "张杰", "黄家驹", "MAX", "薛之谦", "周笔畅", "罗志祥", "林凡", "林志颖", "宋茜", "鞠婧祎", "吴亦凡", "李宇春", "朴树", "许巍", "苏运莹", "郑秀文", "张媛媛", "腾格尔", "邰正宵", "李健", "柯以敏", "叶洛洛", "宋承宪", "龙梅子", "钟汶优", "黄韵玲", "钟欣潼", "罗浩然", "林志炫", "牛奶咖啡", "王琪", "格格", "韩红", "胡夏", "申哥", "孟鹤堂", "毛阿敏", "任然", "伍佰", "信乐团", "凤凰传奇", "刀郎", "刘至佳", "动力列车", "动力火车", "半吨兄弟", "卓依婷", "单依纯", "古巨基", "叶倩文", "告五人", "周传雄", "周华健", "周深", "唐朝乐队", "孙悦", "孙楠", "孙燕姿", "宋亚轩", "宋岳庭", "小乐哥", "小虎队", "小阿七", "尹正", "张国荣", "张宇", "张涵韵", "张碧晨", "张雨生", "张靓颖", "张韶涵", "易烊千玺", "曲肖冰", "李克勤", "李字春", "李宗盛", "李玉刚", "李玟", "杨丞琳", "杨宗纬", "梁静茹", "梅艳芳", "毛不易", "毛宁", "汪佩蓉", "汪峰", "汪苏泷", "王以太", "王小帅", "王心凌", "王忻辰", "王杰", "王艺霖", "王若琳", "王贰浪", "王靖雯", "田震", "白小白", "盂庭苇", "程响", "罗大佑", "羽泉", "老于", "老狼", "胡彦斌", "花儿乐队", "莫文蔚", "萧亚轩", "萧敬腾", "蓝心羽", "街道办GDC", "许嵩", "许飞", "谢霆锋", "谭咏鳞", "谭咏麟", "费玉清", "赵雷", "邓寓君", "那英", "郑智化", "郑源", "郑钧", "郭兰英", "郭顶", "金玟岐", "队长", "阿杜", "阿肆", "阿郎", "陈一郎", "陈慧娴", "陈玉建", "陈珊妮", "陈百强", "陈绮贞", "霍尊", "韩宝仪", "音阙诗听", "风凰传奇", "飞儿乐队", "黑豹乐队", "齐秦", "齐豫", "A-Lin", "BEYOND", "MISSKO", "SHE" ],
+ "A" : [ "阿杜", "阿吉仔", "阿郎", "A-Lin", "阿悄", "阿肆", "阿雅" ],
+ "B" : [ "白安", "鲍勃", "半吨兄弟", "Beyond", "BEYOND", "暴林", "白雪", "白小白" ],
+ "C" : [ "陈百强", "陈洪", "陈海立", "陈慧娴", "崔健", "陈洁灵", "陈洁仪", "陈雷", "草蜢", "蔡琴", "蔡秋凤", "陈绮贞", "陈瑞", "常生", "陈思安", "陈淑桦", "陈珊妮", "陈思思", "陈诗雨", "侧田", "程响", "陈贤聪", "陈晓东", "陈夏辉", "陈西洋", "陈岩", "陈玉建", "蔡依林", "陈雅森", "陈奕迅" ],
+ "D" : [ "丁丁", "杜德伟", "邓鸿", "DJ", "迪克牛仔", "刀郎", "动力火车", "邓丽君", "动力列车", "丁一", "单依纯", "邓寓君", "队长", "邓紫棋" ],
+ "E" : [ "EXO" ],
+ "F" : [ "F4", "方大同", "飞儿乐队", "菲菲", "凤凰传奇", "范晓萱", "风雨", "费玉清" ],
+ "G" : [ "郭顶", "顾峰", "郭富城", "格格", "高慧君", "宫俊", "古巨基", "光良", "郭兰英", "高胜美", "关淑怡", "告五人", "高晓松", "谷小雨", "龚月" ],
+ "H" : [ "黄博", "黑豹乐队", "韩宝仪", "华晨宇", "花儿乐队", "海风", "侯刚", "韩红", "黄娟", "黄家驹", "黄凯芹", "黑龙", "黄品源", "洪荣宏", "海生", "荒山亮", "黄思婷", "镐天", "胡夏", "黄小琥", "黑羽", "胡彦斌", "黄韵玲", "黄雅珉", "何雁诗", "霍尊", "洪卓立" ],
+ "J" : [ "街道办GDC", "江蕙", "蒋蒋", "鞠婧祎", "金玟岐", "江山", "蒋婴", "姜育恒", "佳仔", "甲子慧", "金志文" ],
+ "K" : [ "康慷", "柯以敏" ],
+ "L" : [ "龙奔", "骆超", "鲁朝阳", "刘德华", "罗大佑", "林凡", "李光", "罗桦", "罗浩然", "梁汉文", "李健", "吕继宏", "林俊杰", "刘嘉亮", "梁静茹", "李郡一", "李克勤", "老狼", "李利依", "李玟", "刘明煜", "龙梅子", "鹿乃", "李泉", "林青霞", "林沁仪", "李荣浩", "刘若英", "罗斯", "罗时丰", "李圣杰", "乐天", "李维", "刘心", "李心洁", "李行亮", "蓝心羽", "老于", "李宇春", "林一峰", "李玉刚", "柳影虹", "林宥嘉", "林忆莲", "梁咏琪", "林忆诗筑", "李研心", "林玉英", "李一哲", "李政", "李字春", "刘至佳", "李宗盛", "罗志祥", "林志颖" ],
+ "M" : [ "毛阿敏", "MAX", "毛不易", "梅朵", "民歌", "孟鹤堂", "MISSKO", "孟静", "马丽", "苗苗", "毛宁", "孟庭苇", "枚文琪", "莫文蔚", "马郁", "梅艳芳" ],
+ "N" : [ "牛奶咖啡", "那英" ],
+ "P" : [ "庞龙", "朴树" ],
+ "Q" : [ "齐霖", "齐秦", "群星", "曲肖冰", "齐豫" ],
+ "R" : [ "任然", "任贤齐", "容祖儿" ],
+ "S" : [ "S.H.E", "沙宝亮", "宋承宪", "苏打绿", "申哥", "SHE", "孙露", "孙楠", "SNH48", "宋茜", "孙淑媚", "司唯", "施文彬", "尚雯婕", "石修", "孙悦", "苏永康", "宋岳庭", "宋亚轩", "苏运莹", "孙燕姿", "山子华", "粟紫妍" ],
+ "T" : [ "汤潮", "唐朝乐队", "TFBOYS", "田馥甄", "腾格尔", "推荐", "童丽", "TWINS", "谭维维", "覃源", "谭咏鳞", "田震", "邰正宵" ],
+ "W" : [ "伍佰", "王贰浪", "王菲", "王贺", "望海高歌", "王杰", "吴建豪", "王佳佳", "王靖雯", "王麟", "韦礼安", "王力宏", "乌兰托娅", "王聆燕", "汪佩蓉", "王琪", "巫启贤", "王若琳", "吴若希", "汪苏泷", "魏什么", "王烁巽", "娃娃", "王馨", "王忻辰", "王心凌", "王小帅", "王勇", "吴亦凡", "王艺霖", "五月天", "王菀之", "王子", "王铮亮", "王子熙" ],
+ "X" : [ "小阿七", "玺晨", "谢帝", "许飞", "肖环", "小虎队", "谢慧娴", "小贱", "萧敬腾", "徐佳莹", "谢雷", "小乐哥", "秀兰玛雅", "信乐团", "新奇", "许茹芸", "许嵩", "谢霆锋", "许巍", "萱萱", "徐小凤", "泫雅", "萧亚轩", "欣哲", "许志安", "薛之谦" ],
+ "Y" : [ "叶蓓", "杨丞琳", "庾澄庆", "以冬", "泳儿", "岳峰", "杨光", "雨禾", "杨洪基", "俞灏明", "严爵", "杨坤", "一绫", "叶洛洛", "杨曼", "羽泉", "杨千嬅", "音阙诗听", "叶启田", "叶倩文", "于湉", "盂庭苇", "阎维文", "亦勋", "尤雅", "牙牙乐", "易烊千玺", "杨钰莹", "尹正", "杨宗纬" ],
+ "Z" : [ "周笔畅", "赵传", "周传雄", "张德兰", "子芙", "张格格", "张国荣", "周蕙", "周华健", "张惠妹", "张涵韵", "张杰", "赵景春", "张津涤", "周杰伦", "张继心", "张靓颖", "赵雷", "着迷", "詹曼铃", "朱咪咪", "甄妮", "张蔷", "张蓉蓉", "周深", "张韶涵", "郑少秋", "张伟", "张文娟", "钟汶优", "张行", "周星濠", "郑兴琦", "钟欣潼", "郑秀文", "张学友", "张信哲", "张宇", "钟亚华", "郑颖杰", "张雨生", "卓依婷", "詹雅雯", "张艺兴", "张媛媛", "子子", "郑智化", "祝子杰", "张智霖", "郑紫阳" ]
+}
\ No newline at end of file