vtt 字幕文件
WEBVTT
1604651411941
00:00:01.000 --> 00:00:02.000
{
"position":"pos:0",
"pole":"pole:0",
"km":"km:0"
}
1604651412941
00:00:02.000 --> 00:00:03.000
{
"position":"pos:1",
"pole":"pole:1",
"km":"km:1"
}
前端实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<video id="video" width="800" height="500" controls crossorigin="anonymous">
<track id="texttrack" src="http://192.168.3.210:9999/hls/20200715130242297_沈大线_大连北站_沈阳站_1_global/hls.vtt" kind="metadata"
label="中文字幕" srclang="zh" default>
</video>
<script>
if (Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
// bind them together
hls.attachMedia(video);
hls.on(Hls.Events.MEDIA_ATTACHED, function () {
hls.loadSource("http://192.168.3.210:9999/hls/hls.m3u8");
hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
});
});
video.play();
}
let textTrackElem = document.getElementById("texttrack");
textTrackElem.oncuechange = (event) => {
let cues = event.target.track.activeCues;
# 打印当前帧信息
console.info(cues[0].text)
};
</script>
</body>
</html>
vtt文件生成
- maven
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>enjoy</artifactId>
<version>4.9.02</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.6</version>
</dependency>
- template.vtt
WEBVTT
#for(tmp : list)
#(tmp.begin) --> #(tmp.end)
{
"position":"#(tmp.position)",
"pole":"#(tmp.pole)",
"km":"#(tmp.km)"
}
#end
- VttPo
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liaozesong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class VttPo {
private long beginTs;
private long endTs;
private String begin;
private String end;
private String position;
private String pole;
private String km;
public VttPo(long beginTimestamp, long beginTs, long endTs, String position, String pole, String km) {
this.beginTs = beginTs;
this.endTs = endTs;
this.position = position;
this.pole = pole;
this.km = km;
this.begin = timestampToTime(beginTs, beginTimestamp);
this.end = timestampToTime(endTs, beginTimestamp);
}
private static String timestampToTime(long timestamp, long beginTimestamp) {
long between = timestamp - beginTimestamp;
long ms = between % 1000;
long second = (between / 1000) % 60;
long minute = (between / 1000 / 60) % 60;
long hour = (between / 1000 / 60 / 60) % 60;
return StrUtil.format("{}:{}:{}.{}", padPre(hour, 2), padPre(minute, 2), padPre(second, 2), padPre(ms, 3));
}
private static String padPre(long ms, int length) {
return StrUtil.padPre(String.valueOf(ms), length, '0');
}
}
- VttUtil
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import com.guotie.dpc.data.location.config.PathConfig;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* 生成vtt 字幕文件
* 保存位置信息
*
* @author liaozesong
*/
public class VttUtil {
private static final String PATH = PathConfig.FILE_SEPARATOR;
public static String gen(String groupId, String name) {
long beginTimestamp = 1604651410941L;
TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));
Template template = engine.getTemplate("template.vtt");
List<VttPo> list = new ArrayList<>();
long tmp = beginTimestamp;
for (int i = 0; i < 60 * 60 * 2; i++) {
tmp = tmp + 1000;
list.add(new VttPo(beginTimestamp, tmp, tmp + 1000, "pos:" + i, "pole:" + i, "km:" + i));
}
Dict set = Dict.create()
.set("list", list);
String result = template.render(set);
PathConfig config = SpringUtil.getBean(PathConfig.class);
String m3u8Path = config.getM3u8Path();
String m3u8Url = config.getM3u8Url();
if (StrUtil.isEmpty(name)) {
name = "hls";
}
String outPath = StrUtil.format("{}{}{}{}{}.vtt", m3u8Path, PATH, groupId, PATH, name);
String outUrlPath = StrUtil.format("{}/{}/{}.vtt", m3u8Url, groupId, name);
FileUtil.writeString(result, outPath, Charset.defaultCharset());
return outUrlPath;
}
}