diff --git a/src/main/java/com/yutou/biliapi/bean/live/database/LiveVideoDatabaseBean.java b/src/main/java/com/yutou/biliapi/bean/live/database/LiveVideoDatabaseBean.java index 73a6537..059f9e4 100644 --- a/src/main/java/com/yutou/biliapi/bean/live/database/LiveVideoDatabaseBean.java +++ b/src/main/java/com/yutou/biliapi/bean/live/database/LiveVideoDatabaseBean.java @@ -14,6 +14,8 @@ public class LiveVideoDatabaseBean extends AbsDatabasesBean { String roomInfoJson; @JSONField(name = "start_time") Date startTime; + @JSONField(name = "stop_time") + Date stopTime; @JSONField(name = "path") String path; diff --git a/src/main/java/com/yutou/biliapi/databases/BiliLiveDatabase.java b/src/main/java/com/yutou/biliapi/databases/BiliLiveDatabase.java index 64f4e84..7af770e 100644 --- a/src/main/java/com/yutou/biliapi/databases/BiliLiveDatabase.java +++ b/src/main/java/com/yutou/biliapi/databases/BiliLiveDatabase.java @@ -118,8 +118,6 @@ public class BiliLiveDatabase extends SQLiteManager { } public JSONObject getGiftInfo(long startTimeLong, long endTimeLong) { - String startTime = DateFormatUtils.getInstance().format(startTimeLong); - String endTime = DateFormatUtils.getInstance().format(endTimeLong); String giftSql = "WITH filtered_gifts AS (" + "SELECT " + "`gift_name`," + @@ -132,8 +130,8 @@ public class BiliLiveDatabase extends SQLiteManager { "FROM " + "`gift` " + "WHERE " + - "`sql_time` >= '" + startTime + "' " + - "AND `sql_time` <= '" + endTime + "' " + + "`sql_time` >= '" + startTimeLong + "' " + + "AND `sql_time` <= '" + endTimeLong + "' " + "GROUP BY " + "`gift_name`, `coin_type`" + ")" + @@ -147,10 +145,10 @@ public class BiliLiveDatabase extends SQLiteManager { "GROUP BY " + "`gift_name`, `icon`;"; String guardSql = "SELECT `gift_name`, SUM(`num`) AS `total_num`,SUM(`price`*`num`) as `total_price`" + - "FROM `guardBuy` where `sql_time` >= '" + startTime + "' and `sql_time` <= '" + endTime + "'" + + "FROM `guardBuy` where `sql_time` >= '" + startTimeLong + "' and `sql_time` <= '" + endTimeLong + "'" + "GROUP BY `gift_name`;"; String superChatSql = "SELECT SUM(`price`*100) as `total_price`, count(`price`) as `total_count`" + - "FROM `superChat` where `sql_time` >= '" + startTime + "' and `sql_time` <= '" + endTime + "';"; + "FROM `superChat` where `sql_time` >= '" + startTimeLong + "' and `sql_time` <= '" + endTimeLong + "';"; JSONObject json = new JSONObject(); JSONArray giftInfo = get(giftSql); JSONArray guardInfo = get(guardSql); @@ -177,15 +175,14 @@ public class BiliLiveDatabase extends SQLiteManager { } private void createInfo(LiveVideoDatabaseBean bean) { - String format = DateFormatUtils.getInstance().format(bean.getSql_time()); - if (get(bean.getTableName(), " `sql_time` = '" + format + "'", LiveVideoDatabaseBean.class).isEmpty()) { + if (get(bean.getTableName(), " `sql_time` = '" + bean.getSql_time().getTime() + "'", LiveVideoDatabaseBean.class).isEmpty()) { add(bean); } else { update(bean); } } - public List getOfTime(String startTime, String endTime, Class clazz) { + public List getOfTime(Long startTime, Long endTime, Class clazz) { String tableName = null; StringBuilder sb = new StringBuilder(); String where = null; diff --git a/src/main/java/com/yutou/bilibili/Controllers/VideoFileController.java b/src/main/java/com/yutou/bilibili/Controllers/VideoFileController.java index a6d863e..be5b03f 100644 --- a/src/main/java/com/yutou/bilibili/Controllers/VideoFileController.java +++ b/src/main/java/com/yutou/bilibili/Controllers/VideoFileController.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLDecoder; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; @@ -109,6 +110,13 @@ public class VideoFileController { @RequestMapping("/video/play") @ResponseBody public JSONObject getVideoUrl(String roomId, String videoId) { - return ResultData.success("/live/"+videoService.getVideoPlay(roomId, videoId)); + String url = videoService.getVideoPlay(roomId, videoId); + /* String[] split = url.split("/"); + StringBuilder sb=new StringBuilder(); + for (String s : split) { + sb.append(URLEncoder.encode(s,StandardCharsets.UTF_8)).append("/"); + } + sb.setLength(sb.length()-1);*/ + return ResultData.success("/live"+url); } } diff --git a/src/main/java/com/yutou/bilibili/services/LiveDanmuService.java b/src/main/java/com/yutou/bilibili/services/LiveDanmuService.java index e6a6c64..82dd7dd 100644 --- a/src/main/java/com/yutou/bilibili/services/LiveDanmuService.java +++ b/src/main/java/com/yutou/bilibili/services/LiveDanmuService.java @@ -59,18 +59,21 @@ public class LiveDanmuService { public void saveDanmuXML(LiveVideoDatabaseBean videoDatabaseBean, BiliLiveDatabase database) { File videoFile = new File(videoDatabaseBean.getPath()); - long videoTime = FFmpegUtils.getVideoTime(videoFile) + videoDatabaseBean.getStartTime().getTime(); + long videoTime; + if (videoDatabaseBean.getStopTime() == null) { + videoTime = System.currentTimeMillis(); + } else { + videoTime = videoDatabaseBean.getStopTime().getTime(); + } Log.i("开始时间:" + videoDatabaseBean.getStartTime().getTime()); Log.i("结束时间:" + videoTime); - String startTime = DateFormatUtils.getInstance().format(videoDatabaseBean.getStartTime()); - String endTime = DateFormatUtils.getInstance().format(videoTime); - List danmus = database.getOfTime(startTime, endTime, LiveDanmuDatabaseBean.class); + List danmus = database.getOfTime(videoDatabaseBean.getStartTime().getTime(), videoTime, LiveDanmuDatabaseBean.class); Log.i("弹幕数量:" + danmus.size()); - AssTools assTools = new AssTools(videoFile.getName().replace(".flv", ""), videoDatabaseBean.getStartTime()); + AssTools assTools = new AssTools(videoFile.getName().replace(".m3u8", ""), videoDatabaseBean.getStartTime()); for (LiveDanmuDatabaseBean dm : danmus) { assTools.addDanmu(dm.createDanmuData()); } - assTools.saveDanmu(videoFile.getAbsolutePath().replace(".flv", ".ass")); + assTools.saveDanmu(videoFile.getAbsolutePath().replace(".m3u8", ".ass")); } public String toTimeString(long videoTime) { @@ -90,19 +93,10 @@ public class LiveDanmuService { if (videoBean == null) { return new LiveVideoDanmu(); } - File videoFile = new File(videoBean.getPath().replace(".flv", ".mp4")); - if (!videoFile.exists()) { - videoFile = new File(videoBean.getPath()); - } - long videoTime = FFmpegUtils.getVideoTime(videoFile); long startTime = Long.parseLong(videoId); - long endTime = Long.parseLong(videoId) + videoTime; - // videoTime = 0; - if (videoTime == 0) { - endTime = System.currentTimeMillis(); - } - List danmuList = liveDatabase.getOfTime(DateFormatUtils.getInstance().format(startTime), DateFormatUtils.getInstance().format(endTime), LiveDanmuDatabaseBean.class); - List superChatList = liveDatabase.getOfTime(DateFormatUtils.getInstance().format(startTime), DateFormatUtils.getInstance().format(endTime), LiveSuperChatDatabaseBean.class); + long endTime = videoBean.getStopTime() == null ? System.currentTimeMillis() : videoBean.getStopTime().getTime(); + List danmuList = liveDatabase.getOfTime(startTime, endTime, LiveDanmuDatabaseBean.class); + List superChatList = liveDatabase.getOfTime(startTime, endTime, LiveSuperChatDatabaseBean.class); for (LiveDanmuDatabaseBean bean : danmuList) { LiveVideoDanmu.Danmu danmu = createDanmu(bean, startTime); danmus.getDanmu().add(danmu); diff --git a/src/main/java/com/yutou/bilibili/services/LiveService.java b/src/main/java/com/yutou/bilibili/services/LiveService.java index 3aa929e..5370007 100644 --- a/src/main/java/com/yutou/bilibili/services/LiveService.java +++ b/src/main/java/com/yutou/bilibili/services/LiveService.java @@ -87,7 +87,7 @@ public class LiveService { if (info.getLiveTime() == 0) { liveData.setLiveTime("未开播"); } else { - liveData.setLiveTime(DateFormatUtils.getInstance().formatMillis(System.currentTimeMillis() - info.getLiveTime()*1000)); + liveData.setLiveTime(DateFormatUtils.getInstance().formatMillis(System.currentTimeMillis() - info.getLiveTime() * 1000)); } liveData.setDownloadVideo(videoDownloadService.checkDownload(info.getRoomId())); liveData.setDanmu(danmuService.check(info.getRoomId())); @@ -113,16 +113,8 @@ public class LiveService { if (videoBean == null) { return null; } - File videoFile = new File(videoBean.getPath().replace(".flv", ".mp4")); - if (!videoFile.exists()) { - videoFile = new File(videoBean.getPath()); - } - long videoTime = FFmpegUtils.getVideoTime(videoFile); - long startTime = Long.parseLong(videoId); - long endTime = Long.parseLong(videoId) + videoTime; - if(videoTime==0){ - endTime=System.currentTimeMillis(); - } + long startTime = videoBean.getStartTime().getTime(); + long endTime = videoBean.getStopTime() == null ? System.currentTimeMillis() : videoBean.getStopTime().getTime(); return database.getGiftInfo(startTime, endTime); } diff --git a/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java b/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java index f963f10..08da3cb 100644 --- a/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java +++ b/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java @@ -120,7 +120,7 @@ public class LiveVideoDownloadService { File rootPath; LiveConfigDatabaseBean config; BiliLiveDatabase database; - LiveVideoDatabaseBean videoDatabaseBean; + LiveVideoDatabaseBean videoDatabaseBean = null; LiveRoomInfo roomInfo; public VideoTask(LiveConfigDatabaseBean bean, LiveRoomInfo roomInfo) { @@ -136,8 +136,8 @@ public class LiveVideoDownloadService { String time = DateUtils.format(new Date().getTime(), DATE_FORMAT_10_DASH); rootPath = new File(bean.getRecordPath() + File.separator + bean.getAnchorName() + File.separator + time + File.separator + "[" + DateUtils.format(new Date(), - "yyyy-MM-dd HH-mm-ss") + "]" + roomInfo.getTitle()); - savePath = rootPath.getAbsolutePath() + File.separator + roomInfo.getTitle() + "-%04d.ts"; + "HH-mm-ss") + "]" + roomInfo.getTitle()); + savePath = rootPath.getAbsolutePath() + File.separator + roomInfo.getTitle() + ".m3u8"; if (!rootPath.exists()) { rootPath.mkdirs(); } @@ -148,14 +148,14 @@ public class LiveVideoDownloadService { } private void stop() { - videoRecord.kill(bean.getRoomId().toString()); - api.getRoomInfo(config.getRoomId().toString()).enqueue(new HttpCallback() { + videoRecord.kill(bean.getRoomId()); + api.getRoomInfo(config.getRoomId()).enqueue(new HttpCallback() { @Override public void onResponse(Headers headers, int code, String status, LiveRoomInfo response, String rawResponse) { if (response.getLiveStatus() == 1) { LiveVideoDownloadService.this.start(bean, false); } else { - LiveVideoDownloadService.this.stop(bean.getRoomId().toString(), false); + LiveVideoDownloadService.this.stop(bean.getRoomId(), false); } } @@ -289,20 +289,19 @@ public class LiveVideoDownloadService { // .withNotSymbolParam("-bufsize", "10M") .withNotSymbolParam("-f", "segment") .withNotSymbolParam("-segment_time", "60") - .withNotSymbolParam("-segment_format", "flv") - .withParam("-segment_list", rootPath + File.separator + roomInfo.getTitle() + ".m3u8") + .withNotSymbolParam("-segment_format", "mpegts") + .withNotSymbolParam("-map", "0") + .withParam("-segment_list", savePath) .withNotSymbolParam("-c", "copy") .withNotSymbolParam("-bsf:a", "aac_adtstoasc") // .withNotSymbolParam("-loglevel", "debug") .withNotSymbolParam("-y", "") - //-reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 2 - // .withNotSymbolParam("-progress",new File("cache",config.getRoomId()+".txt").getAbsolutePath()); //输出进度日志,暂时没啥用 ; if (ck != null) { // builder = builder.withParam("-cookies", cookie); } - FFmpegUtils command = builder.build(config.getRoomId(), ffmpegPath, url, savePath); + FFmpegUtils command = builder.build(config.getRoomId(), ffmpegPath, url, savePath.replace(".m3u8","-%04d.ts")); Log.i(command.getCommandDecode()); try { command.start(new DownloadInterface() { @@ -335,6 +334,10 @@ public class LiveVideoDownloadService { task.cancel(); task = null; } + if (videoDatabaseBean != null) { + videoDatabaseBean.setStopTime(new Date()); + database.addLiveInfo(videoDatabaseBean); + } } }); @@ -430,8 +433,8 @@ public class LiveVideoDownloadService { File videoFile = new File(videoInfo.getPath().replace("-%04d.ts", ".m3u8")); if (!videoFile.exists()) { videoFile = new File(videoInfo.getPath()); - }else{ - return videoInfo.getPath().replace(new File("live").getAbsolutePath(),"").replace(File.separator,"/").replace("-%04d.ts", ".m3u8"); + } else { + return videoInfo.getPath().replace(new File("live").getAbsolutePath(), "").replace(File.separator, "/").replace("-%04d.ts", ".m3u8"); } FFmpegUtils ffmpeg = FFmpegUtils.segment(videoId, ffmpegPath, videoFile, ConfigTools.load(ConfigTools.CONFIG, "outVideoPath", String.class)); System.out.println(ffmpeg.getCommandDecode()); diff --git a/src/main/java/com/yutou/common/databases/SQLiteManager.java b/src/main/java/com/yutou/common/databases/SQLiteManager.java index 07a6049..1bdfc42 100644 --- a/src/main/java/com/yutou/common/databases/SQLiteManager.java +++ b/src/main/java/com/yutou/common/databases/SQLiteManager.java @@ -380,11 +380,10 @@ public abstract class SQLiteManager { protected boolean delete(T t) { Statement statement = null; try { - String id = DateUtils.format(t.getSql_time(), "yyyy-MM-dd HH:mm:ss.SSS"); statement = getConnection().createStatement(); StringBuilder sb = new StringBuilder(); sb.append("DELETE FROM `").append(t.getTableName()).append("` "); - sb.append(" WHERE `sql_time` = ").append("'").append(id).append("'"); + sb.append(" WHERE `sql_time` = ").append("'").append(t.getSql_time().getTime()).append("'"); int ret = statement.executeUpdate(sb.toString()); return ret != 0; } catch (Exception e) { diff --git a/src/main/java/com/yutou/common/utils/FFmpegUtils.java b/src/main/java/com/yutou/common/utils/FFmpegUtils.java index 1c330d7..75a18f1 100644 --- a/src/main/java/com/yutou/common/utils/FFmpegUtils.java +++ b/src/main/java/com/yutou/common/utils/FFmpegUtils.java @@ -182,7 +182,6 @@ public class FFmpegUtils extends AbsVideoRecord { process.exitValue(); return (long) (Double.parseDouble(data) * 1000); } catch (Exception e) { - Log.e(e); return 0; } }