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