Files
QQBot/src/main/java/com/yutou/qqbot/bilibili/AssTools.java

171 lines
5.1 KiB
Java

package com.yutou.qqbot.bilibili;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class AssTools {
private final StringBuilder builder;
private String title;
private int y = 0;
private List<String> filters = new ArrayList<>();
private String alpha="80";
/**
* 弹幕转换ass
* @param title 标题
*/
public AssTools(String title) {
builder = new StringBuilder();
this.title=title;
initAssHeader();
}
/**
* 弹幕过滤器
* @param filter 过滤词
*/
public void addFilter(String... filter) {
filters.addAll(Arrays.asList(filter));
}
/**
* 弹幕透明度
* @param alpha 0 完全不透明 255 完全透明
*/
public void setAlpha(int alpha){
this.alpha=Integer.toHexString(alpha);
}
private void addBuilder(String txt) {
builder.append(txt).append("\n");
}
private void initAssHeader() {
addBuilder("[Script Info]");
addBuilder("Title: " + title);
addBuilder("Original Script: 本字幕由@yutou生成");
addBuilder("ScriptType: v4.00+");
addBuilder("Collisions: Normal");
addBuilder("PlayResX: 1920");
addBuilder("PlayResY: 1080");
addBuilder("Timer: 10.0000");
addBuilder("");
addBuilder("[V4+ Styles]");
addBuilder("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, ");
addBuilder("MarginL, MarginR, MarginV, Encoding");
addBuilder("Style: Fix,Microsoft YaHei UI,45,&H66FFFFFF,&H66FFFFFF,&H66000000,&H66000000,1,0,0,0,100,100,0,0,1,2,0,2,20,20,2,0");
addBuilder("Style: R2L,Microsoft YaHei UI,45,&H00FFFFFF,&H000000FF,&H00161616,&H00000000,0,0,0,0,100,100,0,0,1,2,0,2,20,20,20,1");
addBuilder("");
addBuilder("[Events]");
addBuilder("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text");
}
/**
* 保存弹幕文件
* @param savePath 存储路径
* @return 存储结果
*/
public boolean saveDanmu(String savePath) {
System.out.println("savePath = " + savePath);
File file = new File(savePath+File.separator+title+".ass");
FileWriter writer;
try {
if (file.exists()) {
if (!file.delete()) {
return false;
}
}
boolean mkdirs = file.mkdirs();
boolean delete = file.delete();
if (!mkdirs || !delete) {
return false;
}
if (!file.createNewFile()) {
return false;
}
writer = new FileWriter(file);
writer.write(builder.toString());
writer.flush();
writer.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}finally {
}
return false;
}
/**
* 添加弹幕
* @param list 弹幕
*/
public void addDanmu(List<DanmuData> list) {
list.sort((o1, o2) -> {
if (o1.getTime() == o2.getTime()) {
return 0;
}
return o1.getTime() < o2.getTime() ? -1 : 1;
});
for (DanmuData danmuData : list) {
addDanmu(danmuData);
}
}
/**
* 添加弹幕
* @param danmuData 弹幕
*/
public void addDanmu(DanmuData danmuData) {
if (filters.contains(danmuData.getDanmu())) {
return;
}
addY();
long _time = danmuData.getTime();
long h = TimeUnit.MILLISECONDS.toHours(_time);
long m = TimeUnit.MILLISECONDS.toMinutes(_time) % 60;
long s = TimeUnit.MILLISECONDS.toSeconds(_time) % 60;
String sTime = String.format("%s:%s:%s.0",
new DecimalFormat("00").format(h),
new DecimalFormat("00").format(m),
new DecimalFormat("00").format(s));
if (s >= 52) {
s = (s + 8) - 60;
m++;
} else {
s += 8;
}
String eTime = String.format("%s:%s:%s.0",
new DecimalFormat("00").format(h),
new DecimalFormat("00").format(m),
new DecimalFormat("00").format(s));
float x1, x2;
x1 = 1920 + (danmuData.getDanmu().length() * 12.5f);
x2 = 0 - (danmuData.getDanmu().length() * 12.5f);
String ass = String.format("Dialogue: 0,%s,%s,R2L,,20,20,2,,{\\move(%.1f,%d,%.1f,%d)\\c&%s\\alpha&H%s}%s",
sTime,
eTime,
x1,
y,
x2,
y,
danmuData.getFontColorHex(),
alpha,
danmuData.getDanmu()
);
addBuilder(ass);
}
private void addY() {
y += 40;
if (y >= 1080) {
y = 40;
}
}
}