一、工具准备
- exiftool,用于导出视频的GPS信息(包括海拔高度)
下载地址:https://exiftool.org/ - ffmpeg,给视频增加字幕
- Java,将exiftool导出的位置文件转换为字幕文件srt
二、操作步骤
1. 导出视频中的位置信息
exiftool -p /path/to/gpx.fmt -ee xxx.MP4 >out.gpx
–gpx.fmt下载地址:
https://github.com/exiftool/exiftool/tree/master/fmt_files
out.gpx内容:
<trkpt lat="{经度}" lon="{纬度}">
<ele>{高度}</ele>
<time>{GPS时间}</time>
</trkpt>
2. 使用Java将位置信息转换为srt
public class SrtTest {
private static final SimpleDateFormat EXIF_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
private static final SimpleDateFormat SRT_TIME_FORMAT = new SimpleDateFormat("HH:mm:ss.mmm");
public static void main(String[] args) throws IOException, ParseException {
String exifFilePath = "xxx";
List<PosInfo> infoList = parseExifFile(exifFilePath);
// 转换成字幕文件,保存到outputSrtFile
String outputSrtFile="out.srt";
transferToSrt(infoList,outputSrtFile);
}
private static void transferToSrt(List<PosInfo> infoList,String outputFile) throws IOException, ParseException {
File output = new File(outputFile);
BufferedWriter fw = new BufferedWriter(new FileWriter(output,false));
//1
//00:00:00.000 --> 00:01:00.000
//测试字幕
Date videoStart = SRT_TIME_FORMAT.parse("00:00:00.000");
infoList.sort(Comparator.comparing(o -> o.time));
for(int i=1;i<infoList.size();i++){
fw.write(i+"\r\n");
long currTime = infoList.get(i).time.getTime();
int displaySec = (int)(currTime-infoList.get(i-1).time.getTime())/1000;
String process = buildTimeLine(videoStart,displaySec);
fw.write(process+"\r\n");
fw.write("高度:"+infoList.get(i).height+"\r\n");
fw.write("\r\n");
addDisplay(videoStart,displaySec);
}
fw.flush();
}
private static void addDisplay(Date videoStart,int displaySec){
Calendar calendar = Calendar.getInstance();
calendar.setTime(videoStart);
calendar.add(Calendar.SECOND,displaySec);
videoStart=calendar.getTime();
}
//00:00:00.000 --> 00:01:00.000
private static String buildTimeLine(Date videoStart,int displaySec){
String process = SRT_TIME_FORMAT.format(videoStart)+" --> ";
Calendar calendar = Calendar.getInstance();
calendar.setTime(videoStart);
calendar.add(Calendar.SECOND,displaySec);
process += SRT_TIME_FORMAT.format(calendar.getTime());
return process;
}
private static List<PosInfo> parseExifFile(String filePath) throws IOException, ParseException {
List<String> lines = Files.readAllLines(new File(filePath).toPath());
Iterator<String> iter = lines.iterator();
List<PosInfo> infoList = Lists.newArrayList();
while(iter.hasNext()){
String line = iter.next();
if(line.contains("<ele>")){
float height =Float.parseFloat(line.substring(line.indexOf("<ele>")+5,line.indexOf("</ele>")));
System.out.println(height);
String nextLine=iter.next();
String timeStr= nextLine.substring(nextLine.indexOf("<time>")+6,nextLine.indexOf("</time>"));
Date time = EXIF_TIME_FORMAT.parse(timeStr);
System.out.println(time);
infoList.add(new PosInfo(height,time));
}
}
return infoList;
}
private static class PosInfo{
float height;
Date time;
public PosInfo(float height, Date time) {
this.height = height;
this.time = time;
}
}
}
获得字幕信息,如下:
1
00:00:00.000 --> 00:00:01.000
高度:20.1
2
00:00:01.000 --> 00:00:02.000
高度:20.3
3
00:00:02.000 --> 00:00:03.000
高度:20.3
表示: 第0->1秒,字幕显示"高度:20.1"。
3. 视频+字幕合并(ffmpeg)
ffmpeg -i xxx.MP4 -vf subtitles=out.srt output.mp4
参考材料
- 视频文件信息导出,看回答。https://stackoverflow.com/questions/40333901/export-gps-points-from-dash-cam-with-ffmpeg
- MP4合成字幕。https://www.jianshu.com/p/f33910818a1c