commit
81020b5660
@ -0,0 +1,54 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>org.pqh</groupId> |
||||
<artifactId>format.danmu</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
<properties> |
||||
<maven.compiler.source>1.8</maven.compiler.source> |
||||
<maven.compiler.target>1.8</maven.compiler.target> |
||||
</properties> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.jsoup</groupId> |
||||
<artifactId>jsoup</artifactId> |
||||
<version>1.11.3</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>fastjson</artifactId> |
||||
<version>1.2.51</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.dom4j</groupId> |
||||
<artifactId>dom4j</artifactId> |
||||
<version>2.1.1</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.luhuiguo</groupId> |
||||
<artifactId>chinese-utils</artifactId> |
||||
<version>1.0</version> |
||||
</dependency> |
||||
|
||||
|
||||
<dependency> |
||||
<groupId>junit</groupId> |
||||
<artifactId>junit</artifactId> |
||||
<version>4.12</version> |
||||
<scope>compile</scope> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>commons-io</groupId> |
||||
<artifactId>commons-io</artifactId> |
||||
<version>2.6</version> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
@ -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<JSONObject> { |
||||
|
||||
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<JSONObject> 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); |
||||
} |
||||
} |
@ -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<T> { |
||||
private Parser<T> parser; |
||||
|
||||
private static final String DANMU_HEADER="<?xml version=\"1.0\" encoding=\"UTF-8\"?><i>\n"; |
||||
|
||||
public BuildDanmu(Parser<T> parser) { |
||||
this.parser = parser; |
||||
} |
||||
|
||||
/** |
||||
* 生成弹幕 |
||||
* @param playUrl 播放地址 |
||||
* @param filepath 生成路径 |
||||
*/ |
||||
public void build(String playUrl,String filepath){ |
||||
List<T> list=parser.parse(playUrl); |
||||
|
||||
File danmuFile=new File(filepath); |
||||
|
||||
StringBuffer sb=new StringBuffer(DANMU_HEADER); |
||||
for(T t:list){ |
||||
sb.append("<d p=\"").append(parser.time(t)).append(",").append(parser.style(t)).append(",").append(parser.size(t)).append(",").append(parser.color(t)) |
||||
.append(",0,0,0,0\">").append(parser.text(t)).append("</d>").append("\n"); |
||||
} |
||||
sb.append("</i>"); |
||||
try { |
||||
FileUtils.writeStringToFile(danmuFile,sb.toString(),"UTF-8"); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 弹幕内容解释器 |
||||
* @param <T> |
||||
*/ |
||||
public interface Parser<T> { |
||||
//弹幕颜色
|
||||
String color(T content); |
||||
|
||||
//弹幕大小
|
||||
String size(T content); |
||||
|
||||
//弹幕文本
|
||||
String text(T content); |
||||
|
||||
//弹幕移动样式
|
||||
String style(T content); |
||||
|
||||
//弹幕发送时间
|
||||
String time(T content); |
||||
|
||||
/** |
||||
* 根据视频播放地址解析弹幕数据 |
||||
* @param playUrl |
||||
* @return |
||||
*/ |
||||
List<T> parse(String playUrl); |
||||
|
||||
} |
@ -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<Element> { |
||||
@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<Element> 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"); |
||||
} |
||||
|
||||
} |
@ -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<Element> b1=new BuildDanmu<>(new SohuParser()); |
||||
b1.build("https://tv.sohu.com/v/MjAxNzA2MjIvbjYwMDAxNzkzNC5zaHRtbA==.html?fid=847&pvid=4d4db6d26aa0a4ec","D://BuildDanmu.xml"); |
||||
|
||||
BuildDanmu<JSONObject> buildDanmu=new BuildDanmu<>(new AniGamerParser()); |
||||
buildDanmu.build("https://ani.gamer.com.tw/animeVideo.php?sn=10852","D://AniGamerParser.xml"); |
||||
} |
||||
} |
Loading…
Reference in new issue