新增B站视频下载功能 #7
@ -0,0 +1,29 @@
|
|||||||
|
package com.yutou.qqbot.Controllers;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.yutou.qqbot.models.BiliBili.BiliVideo;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class BiliBiliController {
|
||||||
|
@RequestMapping("/bilibili/down.do")
|
||||||
|
@ResponseBody
|
||||||
|
public JSONObject downloadBili(String data) {
|
||||||
|
new Thread(() -> {
|
||||||
|
JSONObject json = JSONObject.parseObject(data);
|
||||||
|
System.out.println("json = " + json);
|
||||||
|
String url = json.getString("url");
|
||||||
|
boolean downDanmu = json.containsKey("danmu") && "on".equals(json.getString("danmu"));
|
||||||
|
boolean merge = json.containsKey("merge") && "on".equals(json.getString("merge"));
|
||||||
|
BiliVideo video = new BiliVideo();
|
||||||
|
video.downVideo(url, downDanmu, merge);
|
||||||
|
}
|
||||||
|
).start();
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("msg", "ok");
|
||||||
|
json.put("code", 0);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class QQBotApplication {
|
public class QQBotApplication {
|
||||||
public static final String version="QQBot v.1.3.4";
|
public static final String version="QQBot v.1.3.5";
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println("version = " + version);
|
System.out.println("version = " + version);
|
||||||
SpringApplication.run(QQBotApplication.class, args);
|
SpringApplication.run(QQBotApplication.class, args);
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
package com.yutou.qqbot.models.BiliBili;
|
package com.yutou.qqbot.models.BiliBili;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
|
||||||
import com.google.protobuf.TextFormat;
|
|
||||||
import com.google.protobuf.UnknownFieldSet;
|
|
||||||
import com.google.protobuf.util.JsonFormat;
|
|
||||||
import com.yutou.qqbot.Annotations.UseModel;
|
import com.yutou.qqbot.Annotations.UseModel;
|
||||||
import com.yutou.qqbot.bilibili.*;
|
import com.yutou.qqbot.bilibili.*;
|
||||||
import com.yutou.qqbot.interfaces.DownloadInterface;
|
|
||||||
import com.yutou.qqbot.interfaces.ObjectInterface;
|
import com.yutou.qqbot.interfaces.ObjectInterface;
|
||||||
import com.yutou.qqbot.models.Model;
|
import com.yutou.qqbot.models.Model;
|
||||||
import com.yutou.qqbot.utlis.AppTools;
|
import com.yutou.qqbot.utlis.AppTools;
|
||||||
@ -18,22 +11,18 @@ import com.yutou.qqbot.utlis.ConfigTools;
|
|||||||
import com.yutou.qqbot.utlis.HttpTools;
|
import com.yutou.qqbot.utlis.HttpTools;
|
||||||
import com.yutou.qqbot.utlis.StringUtils;
|
import com.yutou.qqbot.utlis.StringUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.zip.Inflater;
|
|
||||||
@UseModel
|
@UseModel
|
||||||
public class BiliVideo extends Model {
|
public class BiliVideo extends Model {
|
||||||
public String downloadPath = "tmp";
|
public String downloadPath = "tmp";
|
||||||
|
List<DanmuData> danmuDatas = new ArrayList<>();
|
||||||
|
long danmuNextTime = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isUserPublic() {
|
public boolean isUserPublic() {
|
||||||
@ -50,7 +39,11 @@ public class BiliVideo extends Model {
|
|||||||
return "B站视频下载";
|
return "B站视频下载";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downVideo(String url) {
|
public void downVideo(String url) {
|
||||||
|
downVideo(url, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downVideo(String url, boolean downDanmu, boolean merge) {
|
||||||
if (!new BiliLogin().testLogin()) {
|
if (!new BiliLogin().testLogin()) {
|
||||||
System.err.println("未登录");
|
System.err.println("未登录");
|
||||||
return;
|
return;
|
||||||
@ -58,6 +51,7 @@ public class BiliVideo extends Model {
|
|||||||
if (!url.contains("?")) {
|
if (!url.contains("?")) {
|
||||||
url += "?";
|
url += "?";
|
||||||
}
|
}
|
||||||
|
danmuDatas.clear();
|
||||||
JSONObject info = getVideoInfo(url);
|
JSONObject info = getVideoInfo(url);
|
||||||
if (info.getInteger("code") == 0) {
|
if (info.getInteger("code") == 0) {
|
||||||
JSONObject infoData = info.getJSONObject("data");
|
JSONObject infoData = info.getJSONObject("data");
|
||||||
@ -96,6 +90,8 @@ public class BiliVideo extends Model {
|
|||||||
eps.put("cid", infoData.getLong("cid"));
|
eps.put("cid", infoData.getLong("cid"));
|
||||||
}
|
}
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("danmu", downDanmu);
|
||||||
|
json.put("merge", merge);
|
||||||
json.put("avid", infoData.getLong("aid"));
|
json.put("avid", infoData.getLong("aid"));
|
||||||
if (eps.containsKey("cid")) {
|
if (eps.containsKey("cid")) {
|
||||||
json.put("cid", eps.getLong("cid"));
|
json.put("cid", eps.getLong("cid"));
|
||||||
@ -104,6 +100,11 @@ public class BiliVideo extends Model {
|
|||||||
json.put("fourk", 1);
|
json.put("fourk", 1);
|
||||||
downVideo(json, eps);
|
downVideo(json, eps);
|
||||||
} else {
|
} else {
|
||||||
|
System.out.println("json = " + json);
|
||||||
|
System.out.println("eps = " + eps);
|
||||||
|
List<File> list = new ArrayList<>();
|
||||||
|
|
||||||
|
String root = new File("tmp").getAbsolutePath() + File.separator;
|
||||||
for (Object o : eps.getJSONArray("eps")) {
|
for (Object o : eps.getJSONArray("eps")) {
|
||||||
JSONObject item = (JSONObject) o;
|
JSONObject item = (JSONObject) o;
|
||||||
json.put("avid", item.getLong("aid"));
|
json.put("avid", item.getLong("aid"));
|
||||||
@ -112,17 +113,86 @@ public class BiliVideo extends Model {
|
|||||||
json.put("fnval", 80);
|
json.put("fnval", 80);
|
||||||
json.put("fourk", 1);
|
json.put("fourk", 1);
|
||||||
item.put("title", eps.getString("title") + "$(File.separator)" + item.getString("title"));
|
item.put("title", eps.getString("title") + "$(File.separator)" + item.getString("title"));
|
||||||
|
list.add(new File(root + StringUtils.toSaveFileName(item.getString("title") + ".mp4")));
|
||||||
downVideo(json, item);
|
downVideo(json, item);
|
||||||
|
if (downDanmu && merge) {
|
||||||
|
long tmp = 0;
|
||||||
|
for (VideoDanMu.DanmakuElem elem : buildDanmuHttp(json.getLong("cid"), json.getLong("avid"), 1)) {
|
||||||
|
DanmuData danmuData = new DanmuData();
|
||||||
|
danmuData.setDanmu(elem.getContent());
|
||||||
|
danmuData.setFontSize(elem.getFontsize());
|
||||||
|
danmuData.setTime(elem.getProgress() + danmuNextTime);
|
||||||
|
danmuData.setFontColor(elem.getColor());
|
||||||
|
danmuData.setModel(elem.getMode());
|
||||||
|
if (elem.getProgress() > tmp) {
|
||||||
|
tmp = elem.getProgress();
|
||||||
|
}
|
||||||
|
danmuDatas.add(danmuData);
|
||||||
|
}
|
||||||
|
danmuNextTime = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (merge) {
|
||||||
|
merge(root, StringUtils.toSaveFileName(eps.getString("title")), list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void merge(String root, String name, List<File> files) {
|
||||||
|
String saveName = root + name;
|
||||||
|
File fileList = new File(saveName + File.separator + "tmp.txt");
|
||||||
|
System.out.println("fileList.getAbsolutePath() = " + fileList.getAbsolutePath());
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
List<File> tmp = new ArrayList<>();
|
||||||
|
for (File file : files) {
|
||||||
|
System.out.println("file.getName() = " + file.getName());
|
||||||
|
file.renameTo(new File(file.getParentFile(), i + ".mp4"));
|
||||||
|
tmp.add(new File(file.getParentFile(), i + ".mp4"));
|
||||||
|
builder.append("file '").append(i++).append(".mp4'");
|
||||||
|
builder.append("\n");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// boolean b = fileList.createNewFile();
|
||||||
|
// System.out.println("b = " + b);
|
||||||
|
FileWriter fw = new FileWriter(fileList);
|
||||||
|
fw.write(builder.toString());
|
||||||
|
fw.flush();
|
||||||
|
fw.close();
|
||||||
|
|
||||||
|
String exec = String.format("cd \"%s\" && ffmpeg -f concat -i \"%s\" -c copy %s.mp4", saveName, "tmp.txt", name);
|
||||||
|
System.out.println("exec = " + exec);
|
||||||
|
AppTools.exec(exec, new ObjectInterface() {
|
||||||
|
@Override
|
||||||
|
public void out(String data) {
|
||||||
|
super.out(data);
|
||||||
|
// System.out.println(data);
|
||||||
|
System.out.println("over");
|
||||||
|
fileList.delete();
|
||||||
|
for (File file : tmp) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
AssTools tools = new AssTools(name);
|
||||||
|
tools.addDanmu(danmuDatas);
|
||||||
|
boolean saveDanmu = tools.saveDanmu(saveName);
|
||||||
|
System.out.println("弹幕保存:" + saveDanmu);
|
||||||
|
}
|
||||||
|
}, false, false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void downVideo(JSONObject json, JSONObject eps) {
|
private void downVideo(JSONObject json, JSONObject eps) {
|
||||||
eps.put("title", StringUtils.toSaveFileName(eps.getString("title")));
|
eps.put("title", StringUtils.toSaveFileName(eps.getString("title")));
|
||||||
File tmp = new File(HttpTools.downloadPath + eps.getString("title") + ".mp4");
|
File tmp = new File(HttpTools.downloadPath + eps.getString("title") + ".mp4");
|
||||||
downDanmu(json.getLong("cid"), json.getLong("avid"), eps.getString("title"), 1);
|
if (json.getBooleanValue("danmu") && !json.getBooleanValue("merge")) {
|
||||||
|
List<VideoDanMu.DanmakuElem> elems = buildDanmuHttp(json.getLong("cid"), json.getLong("avid"), 1);
|
||||||
|
downDanmu("tmp", eps.getString("title"), elems);
|
||||||
|
}
|
||||||
if (tmp.exists()) {
|
if (tmp.exists()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -148,19 +218,8 @@ public class BiliVideo extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downDanmu(long cid, long avid, String title, int segment_index) {
|
private void downDanmu(String savePath, String title, List<VideoDanMu.DanmakuElem> danmuList) {
|
||||||
System.out.println("cid = " + cid + ", avid = " + avid + ", title = " + title + ", segment_index = " + segment_index);
|
|
||||||
JSONObject json = new JSONObject();
|
|
||||||
json.put("type", 1);
|
|
||||||
json.put("oid", cid);
|
|
||||||
json.put("avid", avid);
|
|
||||||
json.put("segment_index", segment_index);
|
|
||||||
try {
|
try {
|
||||||
List<VideoDanMu.DanmakuElem> tmp, danmuList = new ArrayList<>();
|
|
||||||
while (!(tmp = getDanmu(json)).isEmpty()) {
|
|
||||||
danmuList.addAll(tmp);
|
|
||||||
json.put("segment_index",++segment_index);
|
|
||||||
}
|
|
||||||
AssTools tools = new AssTools(title);
|
AssTools tools = new AssTools(title);
|
||||||
List<DanmuData> list = new ArrayList<>();
|
List<DanmuData> list = new ArrayList<>();
|
||||||
for (VideoDanMu.DanmakuElem elem : danmuList) {
|
for (VideoDanMu.DanmakuElem elem : danmuList) {
|
||||||
@ -173,13 +232,27 @@ public class BiliVideo extends Model {
|
|||||||
list.add(danmuData);
|
list.add(danmuData);
|
||||||
}
|
}
|
||||||
tools.addDanmu(list);
|
tools.addDanmu(list);
|
||||||
tools.saveDanmu("tmp");
|
boolean saveDanmu = tools.saveDanmu(savePath);
|
||||||
|
System.out.println("弹幕保存:" + saveDanmu);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<VideoDanMu.DanmakuElem> buildDanmuHttp(long cid, long avid, int segment_index) {
|
||||||
|
List<VideoDanMu.DanmakuElem> tmp, danmuList = new ArrayList<>();
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("type", 1);
|
||||||
|
json.put("oid", cid);
|
||||||
|
json.put("avid", avid);
|
||||||
|
json.put("segment_index", segment_index);
|
||||||
|
while (!(tmp = getDanmu(json)).isEmpty()) {
|
||||||
|
danmuList.addAll(tmp);
|
||||||
|
json.put("segment_index", ++segment_index);
|
||||||
|
}
|
||||||
|
return danmuList;
|
||||||
|
}
|
||||||
|
|
||||||
private List<VideoDanMu.DanmakuElem> getDanmu(JSONObject json) {
|
private List<VideoDanMu.DanmakuElem> getDanmu(JSONObject json) {
|
||||||
try {
|
try {
|
||||||
byte[] http = BiliBiliUtils.http("https://api.bilibili.com/x/v2/dm/web/seg.so?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.BYTE);
|
byte[] http = BiliBiliUtils.http("https://api.bilibili.com/x/v2/dm/web/seg.so?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.BYTE);
|
||||||
@ -217,7 +290,6 @@ public class BiliVideo extends Model {
|
|||||||
@Override
|
@Override
|
||||||
public void out(String data) {
|
public void out(String data) {
|
||||||
super.out(data);
|
super.out(data);
|
||||||
System.out.println("data = " + data);
|
|
||||||
videoFile.delete();
|
videoFile.delete();
|
||||||
audioFile.delete();
|
audioFile.delete();
|
||||||
}
|
}
|
||||||
@ -265,6 +337,8 @@ public class BiliVideo extends Model {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
BiliVideo video = new BiliVideo();
|
BiliVideo video = new BiliVideo();
|
||||||
|
JSONObject login = new BiliLogin().login();
|
||||||
|
System.out.println(login);
|
||||||
//岚少 480
|
//岚少 480
|
||||||
//video.downVideo("https://www.bilibili.com/video/BV1Ps411m7pt?spm_id_from=333.999.0.0");
|
//video.downVideo("https://www.bilibili.com/video/BV1Ps411m7pt?spm_id_from=333.999.0.0");
|
||||||
//唐诱 合集
|
//唐诱 合集
|
||||||
@ -279,12 +353,14 @@ public class BiliVideo extends Model {
|
|||||||
//video.downVideo("https://www.bilibili.com/video/BV1qF411T7Vf?spm_id_from=444.41.list.card_archive.click");
|
//video.downVideo("https://www.bilibili.com/video/BV1qF411T7Vf?spm_id_from=444.41.list.card_archive.click");
|
||||||
//唐诱正片
|
//唐诱正片
|
||||||
//video.downVideo("https://www.bilibili.com/video/BV1L44y147zR?spm_id_from=333.999.0.0");// ep1
|
//video.downVideo("https://www.bilibili.com/video/BV1L44y147zR?spm_id_from=333.999.0.0");// ep1
|
||||||
//video.downVideo("https://www.bilibili.com/video/BV18L4y1H7rz?spm_id_from=333.999.0.0");// ep5
|
video.downVideo("https://www.bilibili.com/video/BV18L4y1H7rz?spm_id_from=333.999.0.0", true, false);// ep5
|
||||||
// video.downVideo("https://www.bilibili.com/video/BV1SL411g7FS/?spm_id_from=333.788.recommend_more_video.0"); //all ig 1\5
|
// video.downVideo("https://www.bilibili.com/video/BV1SL411g7FS/?spm_id_from=333.788.recommend_more_video.0"); //all ig 1\5
|
||||||
|
|
||||||
// video.downVideo("https://www.bilibili.com/video/BV18L4y1H7rz?spm_id_from=333.999.0.0");
|
// video.downVideo("https://www.bilibili.com/video/BV18L4y1H7rz?spm_id_from=333.999.0.0");
|
||||||
|
// video.downVideo("https://www.bilibili.com/video/BV1Pe4y1Q7MX?spm_id_from=444.41.top_right_bar_window_history.content.click");
|
||||||
// int a=16|2048;
|
// int a=16|2048;
|
||||||
// System.out.println("a = " + a);
|
// System.out.println("a = " + a);
|
||||||
//video.downDanmu(428855000L,976216102L,"【都市_情感】《唐可可的诱惑》第一集",1);
|
//video.downDanmu(428855000L,976216102L,"【都市_情感】《唐可可的诱惑》第一集",1);
|
||||||
|
System.out.println("事件结束");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ public class AppTools {
|
|||||||
printWriter.close();
|
printWriter.close();
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
}
|
}
|
||||||
public static void exec(String exec, ObjectInterface objectInterface, boolean isOutQQBot, boolean isInput) {
|
public static String exec(String exec, ObjectInterface objectInterface, boolean isOutQQBot, boolean isInput) {
|
||||||
try {
|
try {
|
||||||
Process process;
|
Process process;
|
||||||
if (AppTools.isRuntimeSystemOfWindow()) {
|
if (AppTools.isRuntimeSystemOfWindow()) {
|
||||||
@ -69,17 +69,20 @@ public class AppTools {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
String ret;
|
||||||
if (isInput) {
|
if (isInput) {
|
||||||
processOut(process.getInputStream(), objectInterface, isOutQQBot);
|
ret=processOut(process.getInputStream(), objectInterface, isOutQQBot);
|
||||||
processOut(process.getErrorStream(),null,isOutQQBot);
|
processOut(process.getErrorStream(),null,isOutQQBot);
|
||||||
} else {
|
} else {
|
||||||
processOut(process.getErrorStream(), objectInterface, isOutQQBot);
|
ret=processOut(process.getErrorStream(), objectInterface, isOutQQBot);
|
||||||
processOut(process.getInputStream(),null,isOutQQBot);
|
processOut(process.getInputStream(),null,isOutQQBot);
|
||||||
}
|
}
|
||||||
process.destroy();
|
process.destroy();
|
||||||
|
return ret;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isRuntimeSystemOfWindow() {
|
public static boolean isRuntimeSystemOfWindow() {
|
||||||
@ -121,7 +124,7 @@ public class AppTools {
|
|||||||
public static void processOut(InputStream inputStream) {
|
public static void processOut(InputStream inputStream) {
|
||||||
processOut(inputStream,null,true);
|
processOut(inputStream,null,true);
|
||||||
}
|
}
|
||||||
public static void processOut(InputStream inputStream, ObjectInterface objectInterface, boolean isOutQQBot){
|
public static String processOut(InputStream inputStream, ObjectInterface objectInterface, boolean isOutQQBot){
|
||||||
String tmp;
|
String tmp;
|
||||||
StringBuilder str = new StringBuilder();
|
StringBuilder str = new StringBuilder();
|
||||||
try {
|
try {
|
||||||
@ -141,6 +144,7 @@ public class AppTools {
|
|||||||
if(isOutQQBot) {
|
if(isOutQQBot) {
|
||||||
QQBotManager.getInstance().sendMessage(str.toString());
|
QQBotManager.getInstance().sendMessage(str.toString());
|
||||||
}
|
}
|
||||||
|
return str.toString();
|
||||||
}
|
}
|
||||||
public static void sendServer(String title, String msg) {
|
public static void sendServer(String title, String msg) {
|
||||||
try {
|
try {
|
||||||
|
81
web/bilibili.html
Normal file
81
web/bilibili.html
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>BiliBili下载器</title>
|
||||||
|
<link rel="stylesheet" href="layui/css/layui.css">
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="myDiy">
|
||||||
|
<blockquote class="layui-elem-quote">BiliBili下载器
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<br/><br/><br/>
|
||||||
|
|
||||||
|
<div class="layui-bg-gray layui-row layui-col-space15" id="card" style="padding: 30px;">
|
||||||
|
|
||||||
|
<form class="layui-form" action="">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">视频地址</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="url" name="url" required lay-verify="required" placeholder="请输入URL" autocomplete="off" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">复选框</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="checkbox" name="danmu" title="下载弹幕" checked>
|
||||||
|
<input type="checkbox" name="merge" title="合并合集">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
|
||||||
|
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<script src="layui/layui.js"></script>
|
||||||
|
<script src="layui/jquery-3.2.1.js"></script>
|
||||||
|
<script>
|
||||||
|
layui.use('form', function(){
|
||||||
|
let form = layui.form;
|
||||||
|
|
||||||
|
//监听提交
|
||||||
|
form.on('submit(formDemo)', function(_data){
|
||||||
|
//layer.msg(JSON.stringify(data.field));
|
||||||
|
$.post("/bilibili/down.do",{data:JSON.stringify(_data.field)},function (json) {
|
||||||
|
layer.msg(json.msg)
|
||||||
|
})
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.myDiy {
|
||||||
|
width: 40%;
|
||||||
|
height: 300px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user