commit 81020b5660ed969dec01583016ee70199f1c1beb Author: 无限超频 <1029559041@qq.com> Date: Tue Oct 9 16:07:49 2018 +0800 init diff --git a/README.md b/README.md new file mode 100644 index 0000000..b5c9533 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +把其他弹幕网站的弹幕转换成B站弹幕格式 \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..797b698 --- /dev/null +++ b/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + org.pqh + format.danmu + 1.0-SNAPSHOT + + 1.8 + 1.8 + + + + + org.jsoup + jsoup + 1.11.3 + + + + com.alibaba + fastjson + 1.2.51 + + + + org.dom4j + dom4j + 2.1.1 + + + + com.luhuiguo + chinese-utils + 1.0 + + + + + junit + junit + 4.12 + compile + + + + commons-io + commons-io + 2.6 + + + \ No newline at end of file diff --git a/src/main/java/AniGamerParser.java b/src/main/java/AniGamerParser.java new file mode 100644 index 0000000..1159684 --- /dev/null +++ b/src/main/java/AniGamerParser.java @@ -0,0 +1,57 @@ +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.luhuiguo.chinese.ChineseUtils; +import org.jsoup.Connection; +import org.jsoup.Jsoup; + +import java.io.IOException; +import java.util.List; + +public class AniGamerParser implements Parser { + + private static final String INTERFACE_URL ="https://ani.gamer.com.tw/ajax/danmuGet.php"; + + @Override + public String color(JSONObject content) { + return Integer.parseInt(content.getString("color").replace("#", ""), 16)+""; + } + + @Override + public String size(JSONObject content) { + if(content.getIntValue("size")==2){ + return "30"; + }else{ + return "25"; + } + } + + @Override + public String text(JSONObject content) { + return ChineseUtils.toSimplified(content.getString("text")); + } + + @Override + public String style(JSONObject content) { + if(content.getIntValue("position")==2){ + return "2"; + }else{ + return "1"; + } + } + + @Override + public String time(JSONObject content) { + return (content.getDoubleValue("time")/10)+""; + } + + @Override + public List parse(String playUrl) { + String tstr; + try { + tstr = Jsoup.connect(INTERFACE_URL).ignoreContentType(true).method(Connection.Method.POST).data("sn", playUrl.replaceAll("\\D+","")).execute().body(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return JSON.parseArray(tstr).toJavaList(JSONObject.class); + } +} diff --git a/src/main/java/BuildDanmu.java b/src/main/java/BuildDanmu.java new file mode 100644 index 0000000..6653fc5 --- /dev/null +++ b/src/main/java/BuildDanmu.java @@ -0,0 +1,38 @@ +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +public class BuildDanmu { + private Parser parser; + + private static final String DANMU_HEADER="\n"; + + public BuildDanmu(Parser parser) { + this.parser = parser; + } + + /** + * 生成弹幕 + * @param playUrl 播放地址 + * @param filepath 生成路径 + */ + public void build(String playUrl,String filepath){ + List list=parser.parse(playUrl); + + File danmuFile=new File(filepath); + + StringBuffer sb=new StringBuffer(DANMU_HEADER); + for(T t:list){ + sb.append("").append(parser.text(t)).append("").append("\n"); + } + sb.append(""); + try { + FileUtils.writeStringToFile(danmuFile,sb.toString(),"UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 0000000..bd61f86 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,30 @@ +import java.util.List; + +/** + * 弹幕内容解释器 + * @param + */ +public interface Parser { + //弹幕颜色 + String color(T content); + + //弹幕大小 + String size(T content); + + //弹幕文本 + String text(T content); + + //弹幕移动样式 + String style(T content); + + //弹幕发送时间 + String time(T content); + + /** + * 根据视频播放地址解析弹幕数据 + * @param playUrl + * @return + */ + List parse(String playUrl); + +} diff --git a/src/main/java/SohuParser.java b/src/main/java/SohuParser.java new file mode 100644 index 0000000..303a513 --- /dev/null +++ b/src/main/java/SohuParser.java @@ -0,0 +1,91 @@ +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; + +import java.io.IOException; +import java.util.List; + +public class SohuParser implements Parser { + @Override + public String color(Element content) { + return content.attributeValue("c"); + } + + @Override + public String size(Element content) { + switch (content.attributeValue("s")) { + case "l": + return "30"; + case "m": + return "25"; + default: + return "18"; + } + } + + @Override + public String text(Element content) { + return content.getText(); + } + + @Override + public String style(Element content) { + if (content.attributeValue("m").contains("f")) { + switch (content.attributeValue("p")) { + case "t": + case "m": + return "5"; + default: + return "4"; + } + } else if (content.attributeValue("m").contains("l")) { + switch (content.attributeValue("p")) { + case "t": + case "m": + return "1"; + default: + return "2"; + } + } else { + return "1"; + } + + } + + @Override + public String time(Element content) { + return content.attributeValue("v"); + } + + @Override + public List parse(String playUrl) { + Document doc; + try { + doc = Jsoup.connect(playUrl).get(); + } catch (IOException e) { + throw new RuntimeException(e); + } + Elements videosrc=doc.select("meta[property=og:videosrc]"); + if(videosrc.size()!=1){ + throw new RuntimeException("该视频:"+playUrl+"找不到弹幕"); + } + String vid = videosrc.get(0).attr("content").replaceAll("\\D",""); + + SAXReader reader = new SAXReader(); + + org.dom4j.Document document; + try { + document = reader.read("http://cdn.danmu.56.com/xml/2/v_" + vid + ".xml"); + } catch (DocumentException e) { + throw new RuntimeException(e); + } + + Element d = document.getRootElement().elements("d").get(0); + + return d.elements("c"); + } + +} diff --git a/src/test/java/TestBuild.java b/src/test/java/TestBuild.java new file mode 100644 index 0000000..27478a4 --- /dev/null +++ b/src/test/java/TestBuild.java @@ -0,0 +1,16 @@ +import com.alibaba.fastjson.JSONObject; +import org.dom4j.Element; +import org.junit.Test; + +import java.io.IOException; + +public class TestBuild { + @Test + public void test() throws IOException { + BuildDanmu b1=new BuildDanmu<>(new SohuParser()); + b1.build("https://tv.sohu.com/v/MjAxNzA2MjIvbjYwMDAxNzkzNC5zaHRtbA==.html?fid=847&pvid=4d4db6d26aa0a4ec","D://BuildDanmu.xml"); + + BuildDanmu buildDanmu=new BuildDanmu<>(new AniGamerParser()); + buildDanmu.build("https://ani.gamer.com.tw/animeVideo.php?sn=10852","D://AniGamerParser.xml"); + } +}