diff --git a/Web/html/body/bilibili/video.html b/Web/html/body/bilibili/video.html index 46acfb0..5be82c9 100644 --- a/Web/html/body/bilibili/video.html +++ b/Web/html/body/bilibili/video.html @@ -28,6 +28,7 @@ @@ -47,9 +48,9 @@ {field: 'name', title: 'UP主/房间号', width: 150, sort: true, fixed: 'left'} , {field: 'date', title: '日期', width: 120, sort: true} , {field: 'time', title: '时间', width: 80, sort: true} - , {field: 'fileName', title: '文件名', width: 300} + , {field: 'fileName', title: '文件名', width: 250} , {field: 'fileSize', title: '大小', width: 80} - , {field: "right", width: 120, toolbar: '#listTools'} + , {field: "right", width: 170, toolbar: '#listTools'} ]] }); table.on('tool(listTools)', function (obj) { @@ -61,6 +62,15 @@ case 'play': play("/download/" + obj.data.date + "/" + encodeURI(obj.data.fileName), obj.data.fileName); break; + case 'ffmpeg': + $.post('/bili/video/set/ffmpeg.do',{fileName:encodeURI(obj.data.fileName)},function (json) { + if (json.code === undefined || json.code !== 0) { + layer.msg("您无权操作") + return; + } + layer.msg(json.msg) + }) + break; } }) @@ -79,20 +89,18 @@ , area: ['640px', '480px'] , maxmin: false , resize: false - , content: '
暂停/播放' + + , content: '
重播' + - '弹幕' + - '静音' + - '-10s' + - '+10s' + + '弹幕' + + '-10s' + + '+10s' + '
' , success: function (layero, index) { layer.setTop(layero); let videoElement = document.getElementById(id); - videoElement.onended=function (){ - layer.close(index) + videoElement.onended = function () { + layer.close(index) }; let playerConfig = { enableWorker: false, @@ -100,10 +108,14 @@ stashInitialSize: 512 * 1024, enableStashBuffer: true } + let playType = 'flv' + if (url.indexOf('_ffmpeg') !== -1) { + playType = 'mp4' + } flvPlayer = flvjs.createPlayer({ - type: 'flv', + type: playType, url: url - },playerConfig) + }, playerConfig) flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); @@ -114,7 +126,7 @@ } else { flvPlayer.play(); } - isPlay=!isPlay; + isPlay = !isPlay; }) $('#reset').click(function () { flvPlayer.unload(); diff --git a/Web/html/body/user.html b/Web/html/body/user.html index 0692cef..db749ff 100644 --- a/Web/html/body/user.html +++ b/Web/html/body/user.html @@ -57,13 +57,23 @@
- +
- + +
+
+
+ +
+
@@ -135,6 +145,13 @@ $('#bili_login_text').text(json.data.uname); $('#bili_icon_img').attr("src", json.data.icon); + }) + $.post('/system/get/ffmpeg.do', function (json) { + if (json.code === undefined || json.code !== 0) { + return; + } + $('#ffmpeg').val(json.data.ffmpeg_path); + }) $('#login').click(function () { $.post('/bili/login/set/login.do', function (json) { @@ -157,6 +174,14 @@ }) }) }) + $('#ffmpeg').bind('keypress', function (event) { + if (event.keyCode === 13) { + $.post('/system/set/ffmpeg.do', {ffmpeg: encodeURI($('#ffmpeg').val())}, function (json) { + layer.msg(json.msg) + }) + event.preventDefault(); + } + }) $('#header').load("/html/header.html"); $('#footer').load("/html/footer.html"); diff --git a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliVideoController.java b/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliVideoController.java index b922004..ea99b62 100644 --- a/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliVideoController.java +++ b/src/main/java/com/yutou/bilibili/BiliBili/Controllers/BiliVideoController.java @@ -5,8 +5,11 @@ import com.alibaba.fastjson.JSONObject; import com.yutou.bilibili.BiliBili.LiveUtils; import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService; import com.yutou.bilibili.BiliBili.Tools.BiliTools; +import com.yutou.bilibili.Services.ISystemConfigService; import com.yutou.bilibili.Services.IUserService; import com.yutou.bilibili.Tools.AppTools; +import com.yutou.bilibili.Tools.Config; +import com.yutou.bilibili.Tools.FFmpegUtils; import com.yutou.bilibili.Tools.ServiceTools; import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo; import com.yutou.bilibili.mybatis.model.UUser; @@ -19,6 +22,8 @@ import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -29,6 +34,8 @@ public class BiliVideoController { IUserService service; @Resource IBiliBiliLiveService liveService; + @Resource + ISystemConfigService configService; @ResponseBody @RequestMapping("/bili/video/get/list.do") @@ -52,9 +59,19 @@ public class BiliVideoController { List list = AppTools.scanFilePath("live"); JSONArray array = new JSONArray(); for (File f : list) { + JSONObject item = new JSONObject(); + String _time = f.getName().split(" ")[0].substring(1); + File mpeg = new File("ffmpeg_out" + File.separator + _time + File.separator + f.getName()); + if (mpeg.exists()) { + f = mpeg; + item.put("ffmpeg", true); + } else { + item.put("ffmpeg", false); + } String date = f.getName().split(" ")[0].substring(1); String time = f.getName().split(" ")[1].split("\\]")[0]; - String roomid = f.getName().split("\\]")[1].replace(".mp4", "").trim(); + String roomid = f.getName().split("\\]")[1].replace(".mp4", "").replace("_ffmpeg", "").trim(); + BilibiliUpInfo info = liveService.queryUpToRoomId(Integer.parseInt(roomid)); long size = f.length(); String _size; @@ -67,7 +84,7 @@ public class BiliVideoController { } else { _size = (size / 1073741824) + "GB"; } - JSONObject item = new JSONObject(); + item.put("fileName", f.getName()); item.put("fileSize", _size); item.put("date", date); @@ -89,11 +106,34 @@ public class BiliVideoController { @RequestMapping("/bili/video/download/get.do") public ResponseEntity download(String fileName) { - System.out.println(fileName); String time = fileName.split(" ")[0].substring(1); - System.out.println(time); - File file = new File("live" + File.separator + time + File.separator + fileName); + File file = new File("ffmpeg_out" + File.separator + time + File.separator + fileName); + if (!file.exists()) + file = new File("live" + File.separator + time + File.separator + fileName); System.out.println(file.getAbsolutePath()); return AppTools.getFile(file); } + @ResponseBody + @RequestMapping("/bili/video/set/ffmpeg.do") + public JSONObject ffmpegOut(String fileName) throws UnsupportedEncodingException { + fileName= URLDecoder.decode(fileName,"UTF-8"); + JSONObject json=new JSONObject(); + json.put("code",0); + json.put("msg","ok"); + String time = fileName.split(" ")[0].substring(1); + File file = new File("live" + File.separator + time + File.separator + fileName); + int i= FFmpegUtils.add(configService.getConfig(Config.SYSTEM_VIDEO_FFMPEG),file,new File("ffmpeg_out"+File.separator+time)); + json.put("model",i); + switch (i){ + case 0: + json.put("msg","已添加到后台转码"); + case 1: + json.put("msg","已经转码,无须二次转码"); + break; + case 2: + json.put("msg","正在转码"); + break; + } + return json; + } } diff --git a/src/main/java/com/yutou/bilibili/Controllers/SystemConfigController.java b/src/main/java/com/yutou/bilibili/Controllers/SystemConfigController.java index 72d667c..e86cf75 100644 --- a/src/main/java/com/yutou/bilibili/Controllers/SystemConfigController.java +++ b/src/main/java/com/yutou/bilibili/Controllers/SystemConfigController.java @@ -8,6 +8,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; @Controller public class SystemConfigController { @@ -61,5 +63,25 @@ public class SystemConfigController { json.put("data",data); return json; } - + @ResponseBody + @RequestMapping("/system/set/ffmpeg.do") + public JSONObject setFFmpeg(String ffmpeg) throws UnsupportedEncodingException { + ffmpeg= URLDecoder.decode(ffmpeg,"UTF-8"); + configService.setConfig(Config.SYSTEM_VIDEO_FFMPEG,ffmpeg); + JSONObject json=new JSONObject(); + json.put("code",0); + json.put("msg","ok"); + return json; + } + @ResponseBody + @RequestMapping("/system/get/ffmpeg.do") + public JSONObject getFFmpeg(){ + JSONObject json = new JSONObject(); + JSONObject data=new JSONObject(); + String reg = configService.getConfig(Config.SYSTEM_VIDEO_FFMPEG); + data.put(Config.SYSTEM_VIDEO_FFMPEG, reg); + json.put("code",0); + json.put("data",data); + return json; + } } diff --git a/src/main/java/com/yutou/bilibili/Tools/AppTools.java b/src/main/java/com/yutou/bilibili/Tools/AppTools.java index ed43a9b..01ae95b 100644 --- a/src/main/java/com/yutou/bilibili/Tools/AppTools.java +++ b/src/main/java/com/yutou/bilibili/Tools/AppTools.java @@ -248,4 +248,60 @@ public class AppTools { } return ""; } + + public static boolean copyFileToName(String srcFileName,String destFileName,String fileName,boolean overlay) { + File srcFile = new File(srcFileName); + // 判断源文件是否存在 + if (!srcFile.exists()) { + System.err.println("源文件不存在:"+srcFile.getAbsolutePath()+" > "+destFileName); + return false; + } else if (!srcFile.isFile()) { + System.err.println("源文件是目录:"+srcFile.getAbsolutePath()); + return false; + } + + // 判断目标文件是否存在 + File destFile = new File(destFileName); + // 如果目标文件所在目录不存在,则创建目录 + if (!destFile.exists()) { + // 目标文件所在目录不存在 + if (!destFile.mkdirs()) { + // 复制文件失败:创建目标文件所在目录失败 + System.err.println("创建文件夹失败:"+destFile.getAbsolutePath()); + return false; + } + + }else{ + if(srcFileName.equals("Activity.smali")){ + System.out.println("文件夹已存在:"+destFileName); + } + } + + // 复制文件 + int byteread = 0; // 读取的字节数 + InputStream in = null; + OutputStream out = null; + + try { + if(fileName==null) { + fileName=srcFile.getName(); + } + in = new FileInputStream(srcFile); + out = new FileOutputStream(destFile + File.separator +fileName ); + byte[] buffer = new byte[1024]; + + while ((byteread = in.read(buffer)) != -1) { + out.write(buffer, 0, byteread); + } + out.close(); + in.close(); + return true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + return false; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } } diff --git a/src/main/java/com/yutou/bilibili/Tools/Config.java b/src/main/java/com/yutou/bilibili/Tools/Config.java index ab14016..ac427ba 100644 --- a/src/main/java/com/yutou/bilibili/Tools/Config.java +++ b/src/main/java/com/yutou/bilibili/Tools/Config.java @@ -3,4 +3,5 @@ package com.yutou.bilibili.Tools; public class Config { public static final String USER_REG="userReg"; public static final String BILI_LIVE_FLAG="biliLive"; + public static final String SYSTEM_VIDEO_FFMPEG="ffmpeg_path"; } diff --git a/src/main/java/com/yutou/bilibili/Tools/FFmpegUtils.java b/src/main/java/com/yutou/bilibili/Tools/FFmpegUtils.java new file mode 100644 index 0000000..88052de --- /dev/null +++ b/src/main/java/com/yutou/bilibili/Tools/FFmpegUtils.java @@ -0,0 +1,79 @@ +package com.yutou.bilibili.Tools; + +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class FFmpegUtils { + private static final List nowFFmpegList = new ArrayList<>(); + + public static int add(String ffmpeg, File file, File out) { + if (nowFFmpegList.contains(file)) { + return 2; + } + File tmp = new File(file.getAbsolutePath().replace(".mp4", "_ffmpeg.mp4")); + if (tmp.exists()) { + return 1; + } else { + startFFmpeg(ffmpeg, file, out); + } + + return 0; + } + + private synchronized static void startFFmpeg(String ffmpeg, File file, File out) { + if (nowFFmpegList.contains(file)) { + return; + } + nowFFmpegList.add(file); + new Thread(new Runnable() { + @Override + public void run() { + try { + if (!out.exists()) { + out.mkdirs(); + } + String exec = String.format( + "%s -i \"%s\" -c:v copy -y \"%s\" ", + ffmpeg, + file.getAbsolutePath(), + out.getAbsolutePath() + File.separator + file.getName()); + System.out.println(exec); + Process process = Runtime.getRuntime().exec(new String[]{ + "cmd", + "/c", + exec + } + ); + InputStream inputStream = process.getErrorStream(); + byte[] bytes = new byte[1024]; + while (inputStream.read(bytes) > -1) { + } + inputStream.close(); + AppTools.copyFileToName(out.getAbsolutePath()+File.separator+file.getName(), file.getParent() + File.separator, file.getName().replace(".mp4", "_ffmpeg.mp4"), true); + // file.delete(); + out.delete(); + } catch (Exception e) { + e.printStackTrace(); + } + nowFFmpegList.remove(file); + } + }).start(); + } + + public static void main(String[] args) { + File file = new File("D:\\ieda\\bilibili\\live\\2021-03-20\\[2021-03-20 003537]1064046.mp4"); + int i = -1; + while (i != 1) { + i = add("D:\\ffmpeg-4.3.1-2020-11-19-full_build\\bin\\ffmpeg.exe", file.getAbsoluteFile(), new File("ffmpeg_out")); + System.out.println(i); + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("转码完成"); + } +}