视频显示当前帧附加信息(通过vtt字幕方式)

本文介绍了一种使用Java生成VTT字幕文件的方法,并提供了一个前端示例展示如何播放带有元数据字幕的视频流。具体包括:后端通过Maven依赖和自定义模板生成包含时间戳与位置信息的VTT文件,前端则利用HLS.js播放器加载这些字幕。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值