diff --git a/README.md b/README.md index 61e80f4..242d396 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,37 @@ mv视频搜索服务 # 请求接口 + +## Vod搜索接口 +http://localhost:7777/mv/vod?maxCount=100&wd=五月天后来的我们 + +请求参数定义 +~~~ +wd :搜索值,mv名称或者歌手名 都可以 +ids :vodId,同wd +maxCount:最大返回值,返回结果里面 list 最大数量。 最大值1000 +~~~ +返回参数结果 +~~~ +{ + "code": 1, + "page": 1, + "pagecount": 1, + "limit": 1, + "total": 1, + "list": [{ + "vod_id": "五月天", + "vod_name": "五月天", + "vod_actor": "五月天", + "vod_play_from": "mv", + "vod_pic": "http://m4.auto.itc.cn/auto/content/20230611/45d65d8a001f0c5aa008030f41c98666.jpeg", + "vod_play_url": "五月天-出头天$http://em.21dtv.com/songs/60012964.mkv#五月天-纯真$http://em.21dtv.com/songs/60013405.mkv#五月天-兄弟$http://em.21dtv.com/songs/60137298.mkv#五月天-雌雄同体$http://em.21dtv.com/songs/60013442.mkv#五月天-洗衣机$http://em.21dtv.com/songs/60070028.mkv#五月天-为什么$http://em.21dtv.com/songs/60044059.mkv#五月天-孙悟空$http://em.21dtv.com/songs/60041009.mkv#五月天-米老鼠$http://em.21dtv.com/songs/60087264.mkv#五月天-垃圾车$http://em.21dtv.com/songs/60025892.mkv#五月天-开天窗$http://em.21dtv.com/songs/60025022.mkv#五月天-知足$http://em.21dtv.com/songs/60058693.mkv" + }] +} +~~~ + + +## 搜素接口 http://localhost:7777/mv/search?maxCount=100&query=五月天后来的我们 请求参数定义 @@ -35,4 +66,28 @@ maxCount:最大返回值,返回结果里面 list 最大数量。 最大值10 } ] } -~~~ \ No newline at end of file +~~~ + + +# TvBox配置 +~~~ json +{ + "sites": [ + { + "key": "MV_vod", + "name": "👀┃MV┃视频", + "type": 1, + "api": "http://你自己域名:7777/mv/vod", + "searchable": 1, + "quickSearch": 1, + "filterable": 1 + } + ] +~~~ + + +## 感谢 +### 直播MV来源: +小武哥 :https://t.me/BoBaiBroo + +直播文件:https://t.me/fongmi_offical/54024/244800 \ No newline at end of file diff --git a/src/main/java/com/leosam/tvbox/mv/controller/VodController.java b/src/main/java/com/leosam/tvbox/mv/controller/VodController.java new file mode 100644 index 0000000..31bff81 --- /dev/null +++ b/src/main/java/com/leosam/tvbox/mv/controller/VodController.java @@ -0,0 +1,28 @@ +package com.leosam.tvbox.mv.controller; + +import com.leosam.tvbox.mv.data.VodResult; +import com.leosam.tvbox.mv.service.MvService; +import com.leosam.tvbox.mv.utils.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author admin + * @since 2023/6/11 18:54 + */ +@RestController +public class VodController { + + @Autowired + private MvService mvService; + + @RequestMapping(value = {"/mv/vod"}) + public VodResult searchVod(String wd, String ac, String ids, String maxCount) throws Exception { + int max = Math.min(Math.max(NumberUtils.toInt(maxCount, 100), 10), 1000); + String query = StringUtils.hasText(wd) ? wd : ids; + return mvService.searchVod(query, max); + } + +} diff --git a/src/main/java/com/leosam/tvbox/mv/data/Vod.java b/src/main/java/com/leosam/tvbox/mv/data/Vod.java new file mode 100644 index 0000000..0a10d6c --- /dev/null +++ b/src/main/java/com/leosam/tvbox/mv/data/Vod.java @@ -0,0 +1,94 @@ +package com.leosam.tvbox.mv.data; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author admin + * @since 2023/6/11 18:58 + */ +public class Vod { + + @JsonProperty("vod_id") + private String vodId; + + @JsonProperty("vod_name") + private String vodName; + + @JsonProperty("vod_actor") + private String vodActor; + + @JsonProperty("vod_play_from") + private String vodPlayFrom; + + @JsonProperty("vod_pic") + private String vodPic; + + @JsonProperty("vod_play_url") + private String vodPlayUrl; + + public String getVodId() { + return vodId; + } + + public Vod setVodId(String vodId) { + this.vodId = vodId; + return this; + } + + public String getVodName() { + return vodName; + } + + public Vod setVodName(String vodName) { + this.vodName = vodName; + return this; + } + + public String getVodActor() { + return vodActor; + } + + public Vod setVodActor(String vodActor) { + this.vodActor = vodActor; + return this; + } + + public String getVodPlayFrom() { + return vodPlayFrom; + } + + public Vod setVodPlayFrom(String vodPlayFrom) { + this.vodPlayFrom = vodPlayFrom; + return this; + } + + public String getVodPic() { + return vodPic; + } + + public Vod setVodPic(String vodPic) { + this.vodPic = vodPic; + return this; + } + + public String getVodPlayUrl() { + return vodPlayUrl; + } + + public Vod setVodPlayUrl(String vodPlayUrl) { + this.vodPlayUrl = vodPlayUrl; + return this; + } + + @Override + public String toString() { + return "Vod{" + + "vodId='" + vodId + '\'' + + ", vodName='" + vodName + '\'' + + ", vodActor='" + vodActor + '\'' + + ", vodPlayFrom='" + vodPlayFrom + '\'' + + ", vodPic='" + vodPic + '\'' + + ", vodPlayUrl='" + vodPlayUrl + '\'' + + '}'; + } +} diff --git a/src/main/java/com/leosam/tvbox/mv/data/VodResult.java b/src/main/java/com/leosam/tvbox/mv/data/VodResult.java new file mode 100644 index 0000000..cb52c05 --- /dev/null +++ b/src/main/java/com/leosam/tvbox/mv/data/VodResult.java @@ -0,0 +1,79 @@ +package com.leosam.tvbox.mv.data; + +import java.util.List; + +/** + * @author admin + * @since 2023/6/11 18:57 + */ +public class VodResult { + + private int code; + private int page; + private int pagecount; + private int limit; + private int total; + private List list; + + public void init() { + this.code = 1; + this.page = 1; + this.pagecount = 1; + this.limit = 1; + this.total = 1; + } + + public int getCode() { + return code; + } + + public VodResult setCode(int code) { + this.code = code; + return this; + } + + public int getPage() { + return page; + } + + public VodResult setPage(int page) { + this.page = page; + return this; + } + + public int getPagecount() { + return pagecount; + } + + public VodResult setPagecount(int pagecount) { + this.pagecount = pagecount; + return this; + } + + public int getLimit() { + return limit; + } + + public VodResult setLimit(int limit) { + this.limit = limit; + return this; + } + + public int getTotal() { + return total; + } + + public VodResult setTotal(int total) { + this.total = total; + return this; + } + + public List getList() { + return list; + } + + public VodResult setList(List list) { + this.list = list; + 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 c6b5105..921180d 100644 --- a/src/main/java/com/leosam/tvbox/mv/service/MvService.java +++ b/src/main/java/com/leosam/tvbox/mv/service/MvService.java @@ -2,6 +2,8 @@ package com.leosam.tvbox.mv.service; 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.VodResult; import com.leosam.tvbox.mv.lucene.MvIndex; import com.leosam.tvbox.mv.lucene.MvSearcher; import com.leosam.tvbox.mv.utils.ClassPathReaderUtils; @@ -15,12 +17,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.util.StopWatch; import org.springframework.util.StringUtils; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.LinkedList; +import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; /** @@ -80,6 +87,34 @@ public class MvService implements InitializingBean { return result; } + public VodResult searchVod(String wd, int max) throws Exception { + MvResult search = search(wd, max); + if (CollectionUtils.isEmpty(search.getList())) { + return new VodResult(); + } + Vod vod = new Vod(); + vod.setVodId(wd); + vod.setVodName(wd); + vod.setVodPlayFrom("mv"); + 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()) { + playUrlList.add(content.getName() + "$" + content.getUrl()); + if (vodActorList.size() < 5 && StringUtils.hasText(content.getSongUser())) { + vodActorList.add(content.getSongUser()); + } + } + vod.setVodPlayUrl(String.join("#", playUrlList)); + vod.setVodActor(String.join(",", vodActorList)); + + VodResult vodResult = new VodResult(); + vodResult.init(); + vodResult.setList(new ArrayList<>()).getList().add(vod); + // logger.debug("searchVod , wd{}, vodResult={}", wd, JsonUtils.writeValue(vodResult)); + return vodResult; + } + @Override public void afterPropertiesSet() throws Exception { // 重建索引 @@ -151,4 +186,6 @@ public class MvService implements InitializingBean { stopWatch.stop(); logger.info("重建索引中....完成,耗时 {} 毫秒, 索引位置:{}", stopWatch.getTotalTimeMillis(), file.getPath()); } + + } diff --git a/src/main/java/com/leosam/tvbox/mv/utils/JsonUtils.java b/src/main/java/com/leosam/tvbox/mv/utils/JsonUtils.java new file mode 100644 index 0000000..abe6181 --- /dev/null +++ b/src/main/java/com/leosam/tvbox/mv/utils/JsonUtils.java @@ -0,0 +1,93 @@ +package com.leosam.tvbox.mv.utils; + + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.HashMap; + +/** + * + */ +public class JsonUtils { + + private static final Logger LOG = LoggerFactory.getLogger(JsonUtils.class); + private static final TypeReference> TYPE_MAP = + new TypeReference>() { + }; + + public static ObjectMapper objectMapper = new ObjectMapper(); + + static { + objectMapper.registerModule(new Jdk8Module()); + objectMapper.enable(JsonParser.Feature.ALLOW_COMMENTS); + } + + public static String writeValue(Object o) { + try { + return writeValueThrowException(o); + } catch (Exception e) { + return ""; + } + } + + public static String writeValuePrettyPrinter(Object o) { + try { + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(o); + } catch (Exception e) { + LOG.error("exception occur when Json serializePretty", e); + return ""; + } + } + + + public static String writeValueThrowException(Object o) throws JsonProcessingException { + try { + return objectMapper.writeValueAsString(o); + } catch (Exception e) { + LOG.error("exception occur when Json serialize", e); + throw e; + } + } + + public static T readValue(String json, Class clazz) { + try { + return readValueThrowException(json, clazz); + } catch (IOException e) { + return null; + } + } + + public static T readValueThrowException(String json, Class clazz) throws IOException { + try { + return objectMapper.readValue(json, clazz); + } catch (IOException e) { + LOG.warn("Failed to deserialize from JSON string", e); + throw e; + } + } + + public static T readValue(String json, TypeReference typeReference) { + try { + return readValueThrowException(json, typeReference); + } catch (IOException e) { + return null; + } + } + + public static T readValueThrowException(String json, TypeReference typeReference) throws IOException { + try { + return objectMapper.readValue(json, typeReference); + } catch (IOException e) { + LOG.warn("Failed to deserialize from JSON string", e); + throw e; + } + } + +} diff --git a/src/main/java/com/leosam/tvbox/mv/view/MyTimeInterceptor.java b/src/main/java/com/leosam/tvbox/mv/view/MyTimeInterceptor.java new file mode 100644 index 0000000..3632e31 --- /dev/null +++ b/src/main/java/com/leosam/tvbox/mv/view/MyTimeInterceptor.java @@ -0,0 +1,40 @@ +package com.leosam.tvbox.mv.view; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.servlet.HandlerInterceptor; + +/** + * @author admin + * @since 2023/6/11 20:03 + */ +public class MyTimeInterceptor implements HandlerInterceptor { + + private static final Logger logger = LoggerFactory.getLogger(MyTimeInterceptor.class); + /** + * 线程变量 - 开始执行时间 + */ + private final ThreadLocal startTime = new ThreadLocal<>(); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + startTime.set(System.nanoTime()); + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + if (startTime.get() == null) { + return; + } + long processTime = System.nanoTime() - startTime.get(); + if (logger.isInfoEnabled()) { + logger.info("RequestURL[{}], Referer[{}], TIME[{} ms]", request.getRequestURL().toString(), request.getHeader("Referer"), String.format("%.3f", (processTime / 1_000_000.0))); + } + startTime.remove(); + } + +} + diff --git a/src/main/java/com/leosam/tvbox/mv/view/MyWebMvcConfig.java b/src/main/java/com/leosam/tvbox/mv/view/MyWebMvcConfig.java new file mode 100644 index 0000000..e208f7b --- /dev/null +++ b/src/main/java/com/leosam/tvbox/mv/view/MyWebMvcConfig.java @@ -0,0 +1,27 @@ +package com.leosam.tvbox.mv.view; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @author admin + */ +@Configuration +public class MyWebMvcConfig implements WebMvcConfigurer { + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + // 页面运行时间统计 + registry.addInterceptor(new MyTimeInterceptor()) + .addPathPatterns("/**") + .excludePathPatterns("/static/**") + .excludePathPatterns("/favicon.ico"); + } +}