From 81020b5660ed969dec01583016ee70199f1c1beb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=97=A0=E9=99=90=E8=B6=85=E9=A2=91?= <1029559041@qq.com>
Date: Tue, 9 Oct 2018 16:07:49 +0800
Subject: [PATCH] init
---
README.md | 1 +
pom.xml | 54 ++++++++++++++++++
src/main/java/AniGamerParser.java | 57 +++++++++++++++++++
src/main/java/BuildDanmu.java | 38 +++++++++++++
src/main/java/Parser.java | 30 ++++++++++
src/main/java/SohuParser.java | 91 +++++++++++++++++++++++++++++++
src/test/java/TestBuild.java | 16 ++++++
7 files changed, 287 insertions(+)
create mode 100644 README.md
create mode 100644 pom.xml
create mode 100644 src/main/java/AniGamerParser.java
create mode 100644 src/main/java/BuildDanmu.java
create mode 100644 src/main/java/Parser.java
create mode 100644 src/main/java/SohuParser.java
create mode 100644 src/test/java/TestBuild.java
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");
+ }
+}