Skip to content

Commit

Permalink
Merge pull request #34 from nICEnnnnnnnLee/flvcheck_header_split
Browse files Browse the repository at this point in the history
Flvcheck header split
  • Loading branch information
nICEnnnnnnnLee authored Mar 20, 2020
2 parents cc57f0d + 772bb6b commit 2830ac4
Show file tree
Hide file tree
Showing 13 changed files with 425 additions and 163 deletions.
15 changes: 8 additions & 7 deletions DOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import java.io.File;
import java.io.IOException;

import nicelee.bilibili.enums.StatusEnum;
import nicelee.bilibili.live.FlvChecker;
import nicelee.bilibili.live.check.FlvCheckerWithBufferEx;
import nicelee.bilibili.live.RoomDealer;
import nicelee.bilibili.live.domain.RoomInfo;
import nicelee.bilibili.live.impl.RoomDealerBilibili;
Expand All @@ -75,8 +75,8 @@ public class Example0 {
String cookie = "xxx1=xxx; xxx2=xxxx; xxx3=xxxx"; // cookie = null is also allowed
String fileNameWithoutSuffix = "保存文件名";
boolean deleteOnchecked = true; // 处理完录制后,是否删除源文件
boolean splitScriptTagsIfCheck = false; // 针对FLV的处理方式

boolean splitScriptTagsIfCheck = false; // 针对异常FLV的处理方式
boolean splitAVHeaderTagsIfCheck = false; // 针对异常FLV的处理方式

// 获取工具类
RoomDealer dealer = RoomDealer.createRoomDealer(liver);
Expand Down Expand Up @@ -135,7 +135,7 @@ public class Example0 {
File partFile = new File(file.getParent(), file.getName() + ".part");
partFile.renameTo(file);
}
new FlvChecker().check(file.getCanonicalPath(), deleteOnchecked, splitScriptTagsIfCheck);
new FlvCheckerWithBufferEx().check(file.getCanonicalPath(), deleteOnchecked, splitScriptTagsIfCheck, splitAVHeaderTagsIfCheck, null);
} catch (IOException e) {
e.printStackTrace();
}
Expand Down Expand Up @@ -228,12 +228,13 @@ if(dealer.util.getStatus() != StatusEnum.SUCCESS) {
try {
boolean deleteOriginFilesOnchecked = true;
boolean splitScriptTags = false; // Normally, there should be only 1 ScriptTag in FLV. Two methods provided to solve the problem of ScriptTag**s**.
boolean splitAVHeaderTags = false; // Normally, there should be only 1 Video header and 1 Audio header in FLV.

// The method will block the thread util the work is done. Noway to stop it manually.
new FlvChecker().check("D:\Workspace\123.flv", deleteOriginFilesOnchecked, splitScriptTags);
new FlvCheckerWithBufferEx().check("D:\Workspace\123.flv", deleteOriginFilesOnchecked, splitScriptTags, splitAVHeaderTags, "D:\Workspace\");
// D:\Workspace\123-checked0.flv will appear
// D:\Workspace\123-checked1.flv may appear if splitScriptTags = true, it depends on number of ScriptTag**s**
// D:\Workspace\123-checked2.flv may appear if splitScriptTags = true, it depends on number of ScriptTag**s**
// D:\Workspace\123-checked1.flv may appear if splitScriptTags||splitAVHeaderTags = true, it depends on the duplication of ScriptTag**s** and headers
// D:\Workspace\123-checked2.flv may appear if splitScriptTags||splitAVHeaderTags = true, it depends on the duplication of ScriptTag**s** and headers
// ...
} catch (IOException e) {
e.printStackTrace();
Expand Down
33 changes: 22 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,16 @@ Go go go, Bilibili Pikachu!
| socksProxy || 按需配置。socks代理 e.g. `127.0.0.1:1080` |
| trustAllCert || 是否无条件信任所有SSL证书。默认false |
| splitScriptTags || 校准文件时是否分割ScriptTag。默认false |
| splitAVHeaderTags || 校准文件时是否分割a/v header Tag时。默认与splitScriptTags一致 |
| maxAudioHeaderSize || 当Audio tag的data size小于该值时,认为是audio header。默认`10` |
| maxVideoHeaderSize || 当Video tag的data size小于该值时,认为是video header。默认`60` |
| fileName || 文件命名规则,默认`{name}-{shortId} 的{liver}直播{startTime}-{seq}` |
| timeFormat || 文件命名中{startTime}和{endTime}的格式,默认`yyyy-MM-dd HH.mm` |
| saveFolder || 源文件保存路径 |
| saveFolderAfterCheck || FLV文件校准后的保存路径,check为true时有效。默认为空,此时与`saveFolder`等同 |
| retryIfLiveOff || 当目标不在直播时,是否继续重试。默认false |
| maxRetryIfLiveOff || 当目标不在直播时,继续重试的次数。默认0,此时会一直进行尝试,直到主播上线 |
| retryAfterMinutes || 当目标不在直播时,每次获取直播间信息的时间间隔,单位分钟。默认`5.0` |
| checkWithBuffer || 校准时间戳时是否使用缓存,默认true。测试功能,使用后性能有所提升 |
| plugin || 插件功能,允许用户自定义某些操作。默认false |

+ 各直播源解析情况
Expand All @@ -59,7 +61,7 @@ Go go go, Bilibili Pikachu!
| ------------- | ------------- | ------------- |
| bili | 2019/09/19 | `flv`清晰度可多选,可不需要cookie |
| zhanqi | 2019/06/30 | `flv`清晰度可多选,可不需要cookie |
| douyu | 2020/02/20 | `flv`清晰度可多选,但部分高清需要cookie |
| douyu | 2020/03/10 | `flv`清晰度可多选,但部分高清需要cookie |
| kuaishou | 2020/01/12 | `flv`清晰度可多选,可能需要cookie(与登录无关,首次进入直播页面有反爬措施,会需要拖拽验证) |
| huya | 2019/08/30 | `flv`清晰度可多选,可不需要cookie |
| yy | 2019/06/15 | `flv`只支持默认清晰度 |
Expand All @@ -71,15 +73,24 @@ Go go go, Bilibili Pikachu!
<summary>校正某FLV文件的时间戳</summary>


+ `java -Dfile.encoding=utf-8 -cp BiliLiveRecorder.jar nicelee.bilibili.live.check.FlvCheckerWithBufferEx "源文件路径"`
+ `java -Dfile.encoding=utf-8 -cp BiliLiveRecorder.jar nicelee.bilibili.live.FlvChecker "源文件路径"`
+ `java -Dfile.encoding=utf-8 -cp BiliLiveRecorder.jar nicelee.bilibili.live.FlvChecker "源文件路径" true`
+ `java -Dfile.encoding=utf-8 -cp BiliLiveRecorder.jar nicelee.bilibili.live.FlvChecker "源文件路径" true false "保存的文件夹路径"`
+ 两个校验工具使用方法类似,仅入口类不一致。功能稳定后将一直使用缓存减少IO
+ 第二个参数-布尔参数的意义是**当遇到某种特定情况时,是否分割文件**
+ 第三个参数-布尔参数的意义是**是否输出debug信息**
+ 注意:这些操作**没法还原**,所以理论上原始文件最保真。 `不校验时间戳``校验文件不分割` > `校验文件分割scripts tag`
+ 如果仍旧没办法满足需求的话,建议拿着各种版本都去ffmpeg处理一下
+ `java -Dfile.encoding=utf-8 -cp BiliLiveRecorder.jar nicelee.bilibili.live.check.FlvCheckerWithBufferEx "flv=源文件路径&debug=false&splitScripts=true&splitAVHeader=true&saveFolder=保存的文件夹路径"`

| Key | 必选 | 释义 |
| ------------- | ------------- | ------------- |
| flv || 源文件路径 |
| debug || debug模式,输出更多信息。默认true |
| splitScripts || 当出现多个Script tag时,是否分割文件。默认false |
| splitAVHeaders || 当出现多个a/v header时,是否分割文件。默认与splitScripts一致 |
| saveFolder || 校准时间戳后的保存目录。默认与源文件相同目录 |
| deleteOnchecked || 校准后是否删除源文件,默认false |
| maxAudioHeaderSize || 当Audio tag的data size小于该值时,认为是audio header。默认`10` |
| maxVideoHeaderSize || 当Video tag的data size小于该值时,认为是video header。默认`60` |

+ 旧版本的调用方法仍然兼容,但功能已经不再更新
+**主播pk/更换设备/修改推流参数/旋转画面/网络不稳定**时,可能出现许多异常情况。
+ `splitScripts``splitAVHeaders`参数就是针对这些异常采取的某些处理。
+ 当录制正常时,上面两个参数基本没有影响。
+ 注意:这些操作**没法还原**,所以理论上原始文件最保真。 `不校验时间戳``校验文件不分割` > `校验文件分割script/video header/audio header`
</details>

<details>
Expand Down
4 changes: 4 additions & 0 deletions UPDATE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## 更新
+ V2.7.0
* 增加了针对异常FLV文件的处理情况
* 更改了独立调用校准时间戳功能的参数传入方式(兼容旧版本,但后续新特性不再进行维护)

+ V2.6.6
* Plugin增加内部类/匿名类支持
* 增加Plugin用例,能调用ffmpeg将flv转换为mp4
Expand Down
141 changes: 73 additions & 68 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,70 +1,75 @@
<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>top.nicelee</groupId>
<artifactId>live-record</artifactId>
<version>2.6.0</version>
<name>iLiveRecord</name>
<description>B站、斗鱼、虎牙、快手、战旗、花椒直播录制</description>
<build>
<sourceDirectory>${basedir}\src\main\java</sourceDirectory>
<testSourceDirectory>${basedir}\src\test\java</testSourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<archive>
<manifest>
<mainClass>nicelee.bilibili.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!-- 默认的版本为3.8.1,修改为4.x,因为3.x使用的为编程的方式,4.x为注解的形式。 -->
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
</dependencies>

<distributionManagement>
<repository>
<id>github-BilibiliLiveRecorder</id>
<name>GitHub OWNER Apache Maven Packages</name>
<url>https://maven.pkg.github.com/nICEnnnnnnnLee/BilibiliLiveRecorder</url>
</repository>
<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>top.nicelee</groupId>
<artifactId>live-record</artifactId>
<version>2.7.0</version>
<name>iLiveRecord</name>
<description>B站、斗鱼、虎牙、快手、战旗、花椒直播录制</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<sourceDirectory>${basedir}\src\main\java</sourceDirectory>
<testSourceDirectory>${basedir}\src\test\java</testSourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<archive>
<manifest>
<mainClass>nicelee.bilibili.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!-- 默认的版本为3.8.1,修改为4.x,因为3.x使用的为编程的方式,4.x为注解的形式。 -->
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
</dependencies>

<distributionManagement>
<repository>
<id>github-BilibiliLiveRecorder</id>
<name>GitHub OWNER Apache Maven Packages</name>
<url>https://maven.pkg.github.com/nICEnnnnnnnLee/BilibiliLiveRecorder</url>
</repository>
</distributionManagement>
</project>
Binary file modified release/BiliLiveRecorder.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion release/checkFlv.bat
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
CD /D "%~dp0"
java -Dfile.encoding=utf-8 -cp BiliLiveRecorder.jar nicelee.bilibili.live.FlvChecker "%~1"
java -Dfile.encoding=utf-8 -cp BiliLiveRecorder.jar nicelee.bilibili.live.check.FlvCheckerWithBufferEx "%~1"
pause
17 changes: 16 additions & 1 deletion src/main/java/nicelee/bilibili/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@

import javax.net.ssl.HttpsURLConnection;

import nicelee.bilibili.live.check.TagOptions;
import nicelee.bilibili.util.Logger;
import nicelee.bilibili.util.TrustAllCertSSLUtil;

public class Config {

static boolean autoCheck;
static boolean splitScriptTagsIfCheck;
static boolean splitAVHeaderTagsIfCheck;
static boolean deleteOnchecked;
static boolean flvCheckWithBuffer;
static boolean flagZip;
Expand Down Expand Up @@ -77,6 +79,19 @@ public static void init(String[] args) {
if ("true".equals(value)) {
splitScriptTagsIfCheck = true;
}
splitAVHeaderTagsIfCheck = splitScriptTagsIfCheck;
value = getValue(args[0], "splitAVHeaderTags");
if ("true".equals(value)) {
splitAVHeaderTagsIfCheck = true;
}
value = getValue(args[0], "maxAudioHeaderSize");
if (value != null) {
TagOptions.maxAudioHeaderSize = Integer.parseInt(value);
}
value = getValue(args[0], "maxVideoHeaderSize");
if (value != null) {
TagOptions.maxVideoHeaderSize = Integer.parseInt(value);
}
value = getValue(args[0], "delete");
if ("false".equals(value)) {
deleteOnchecked = false;
Expand Down Expand Up @@ -185,7 +200,7 @@ public static void init(String[] args) {
* @param key
* @return
*/
private static String getValue(String param, String key) {
public static String getValue(String param, String key) {
Pattern pattern = Pattern.compile(key + "=([^&]*)");
Matcher matcher = pattern.matcher(param);
if (matcher.find()) {
Expand Down
20 changes: 7 additions & 13 deletions src/main/java/nicelee/bilibili/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.regex.Pattern;

import nicelee.bilibili.enums.StatusEnum;
import nicelee.bilibili.live.FlvChecker;
import nicelee.bilibili.live.RoomDealer;
import nicelee.bilibili.live.check.FlvCheckerWithBufferEx;
import nicelee.bilibili.live.domain.RoomInfo;
Expand All @@ -25,7 +24,7 @@

public class Main {

final static String version = "v2.6.6";
final static String version = "v2.7.0";

/**
* 程序入口
Expand Down Expand Up @@ -67,11 +66,8 @@ public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
if (Config.shortId == null) {
System.out.println("请输入房间号(直播网址是https://xxx.com/xxx,那么房间号就是xxx)");
while (true) {
String line = reader.readLine();
Config.shortId = line;
break;
}
String line = reader.readLine();
Config.shortId = line;
}

// 加载cookies
Expand Down Expand Up @@ -210,12 +206,10 @@ public void run() {
try {
for (String path : fileList) {
System.out.println("校对时间戳开始...");
if (Config.flvCheckWithBuffer)
new FlvCheckerWithBufferEx().check(path, Config.deleteOnchecked,
Config.splitScriptTagsIfCheck, Config.saveFolderAfterCheck);
else
new FlvChecker().check(path, Config.deleteOnchecked, Config.splitScriptTagsIfCheck,
Config.saveFolderAfterCheck);
new FlvCheckerWithBufferEx().check(path, Config.deleteOnchecked,
Config.splitScriptTagsIfCheck,
Config.splitAVHeaderTagsIfCheck,
Config.saveFolderAfterCheck);
System.out.println("校对时间戳完毕。");
}
} catch (IOException e) {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/nicelee/bilibili/live/FlvChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
import nicelee.bilibili.util.Logger;

/**
* 原理 https://www.cnblogs.com/lidabo/p/9018548.html
* 已废弃, 请使用nicelee.bilibili.live.check.FlvCheckerWithBufferEx
*/
@Deprecated
public class FlvChecker {

public static void main(String[] args) throws IOException {
Expand Down
Loading

0 comments on commit 2830ac4

Please sign in to comment.