1
0
mirror of https://github.com/mifi/lossless-cut.git synced 2024-11-21 18:02:35 +01:00

add support for dji mini gps #2072

This commit is contained in:
Mikael Finstad 2024-09-03 12:11:23 +02:00
parent 0499100aff
commit a2d7961903
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26
4 changed files with 70 additions and 18 deletions

View File

@ -12,6 +12,40 @@ Subtitle 2 line 2
"
`;
exports[`parseGpsLine 1`] = `
{
"alt": 19,
"distance": 67.78,
"dzoom": undefined,
"ev": -1,
"f": "F/2.8",
"height": 20.3,
"horizontalSpeed": 1.03,
"iso": 100,
"lat": 15.0732,
"lng": 67.9771,
"ss": 776.89,
"verticalSpeed": 0,
}
`;
exports[`parseGpsLine 2`] = `
{
"alt": 26,
"distance": 0.57,
"dzoom": 1,
"ev": 0,
"f": "F/2.8",
"height": 102.4,
"horizontalSpeed": 0,
"iso": 100,
"lat": -3.913,
"lng": 56.5019,
"ss": 678.52,
"verticalSpeed": -0,
}
`;
exports[`parses DV Analyzer Summary.txt 1`] = `
[
{

View File

@ -1,10 +1,10 @@
import fs from 'node:fs/promises';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { it, describe, expect } from 'vitest';
import { it, describe, expect, test } from 'vitest';
import { parseSrtToSegments, formatSrt, parseYouTube, formatYouTube, parseMplayerEdl, parseXmeml, parseFcpXml, parseCsv, parseCsvTime, getFrameValParser, formatCsvFrames, getFrameCountRaw, parsePbf, parseDvAnalyzerSummaryTxt, parseCutlist } from './edlFormats';
import { parseSrtToSegments, formatSrt, parseYouTube, formatYouTube, parseMplayerEdl, parseXmeml, parseFcpXml, parseCsv, parseCsvTime, getFrameValParser, formatCsvFrames, getFrameCountRaw, parsePbf, parseDvAnalyzerSummaryTxt, parseCutlist, parseGpsLine } from './edlFormats';
// eslint-disable-next-line no-underscore-dangle
const __dirname = dirname(fileURLToPath(import.meta.url));
@ -317,3 +317,9 @@ it('format srt', async () => {
it('parses DV Analyzer Summary.txt', async () => {
expect(parseDvAnalyzerSummaryTxt(await readFixture('DV Analyzer Summary.txt', 'utf8'))).toMatchSnapshot();
});
test('parseGpsLine', () => {
expect(parseGpsLine('F/2.8, SS 776.89, ISO 100, EV -1.0, GPS (15.0732, 67.9771, 19), D 67.78m, H 20.30m, H.S 1.03m/s, V.S 0.00m/s')).toMatchSnapshot();
// https://github.com/mifi/lossless-cut/issues/2072#issuecomment-2325755148
expect(parseGpsLine('F/2.8, SS 678.52, ISO 100, EV 0, DZOOM 1.000, GPS (-3.9130, 56.5019, 26), D 0.57m, H 102.40m, H.S 0.00m/s, V.S -0.00m/s')).toMatchSnapshot();
});

View File

@ -427,3 +427,22 @@ export function parseSrtToSegments(text: string) {
export function formatSrt(segments) {
return segments.reduce((acc, segment, index) => `${acc}${index > 0 ? '\r\n' : ''}${index + 1}\r\n${formatDuration({ seconds: segment.start }).replaceAll('.', ',')} --> ${formatDuration({ seconds: segment.end }).replaceAll('.', ',')}\r\n${segment.name || '-'}\r\n`, '');
}
export function parseGpsLine(line: string) {
const gpsMatch = line.match(/^\s*([^,]+),\s*SS\s+([^,]+),\s*ISO\s+([^,]+),\s*EV\s+([^,]+)(?:,\s*DZOOM\s+([^,]+))?,\s*GPS\s+\(([^,]+),\s*([^,]+),\s*([^,]+)\),\s*D\s+([^m]+)m,\s*H\s+([^m]+)m,\s*H\.S\s+([^m]+)m\/s,\s*V\.S\s+([^m]+)m\/s\s*$/);
if (!gpsMatch) return undefined;
return {
f: gpsMatch[1]!,
ss: parseFloat(gpsMatch[2]!),
iso: parseInt(gpsMatch[3]!, 10),
ev: parseFloat(gpsMatch[4]!),
dzoom: gpsMatch[5] != null ? parseFloat(gpsMatch[5]) : undefined,
lat: parseFloat(gpsMatch[6]!),
lng: parseFloat(gpsMatch[7]!),
alt: parseFloat(gpsMatch[8]!),
distance: parseFloat(gpsMatch[9]!),
height: parseFloat(gpsMatch[10]!),
horizontalSpeed: parseFloat(gpsMatch[11]!),
verticalSpeed: parseFloat(gpsMatch[12]!),
};
}

View File

@ -7,6 +7,7 @@ import { FaMapMarkerAlt } from 'react-icons/fa';
import { extractSrtGpsTrack } from './ffmpeg';
import { ReactSwal } from './swal';
import { handleError } from './util';
import { parseGpsLine } from './edlFormats';
export default async function tryShowGpsMap(filePath: string, streamIndex: number) {
@ -14,24 +15,16 @@ export default async function tryShowGpsMap(filePath: string, streamIndex: numbe
const subtitles = await extractSrtGpsTrack(filePath, streamIndex);
const gpsPoints = subtitles.flatMap((subtitle) => {
const firstLine = subtitle.lines[0];
// example:
// "F/2.8, SS 776.89, ISO 100, EV -1.0, GPS (15.0732, 67.9771, 19), D 67.78m, H 20.30m, H.S 1.03m/s, V.S 0.00m/s"
const gpsMatch = firstLine?.match(/^\s*([^,]+),\s*SS\s+([^,]+),\s*ISO\s+([^,]+),\s*EV\s+([^,]+),\s*GPS\s+\(([^,]+),\s*([^,]+),\s*([^,]+)\),\s*D\s+([^m]+)m,\s*H\s+([^m]+)m,\s*H\.S\s+([^m]+)m\/s,\s*V\.S\s+([^m]+)m\/s\s*$/);
if (!gpsMatch || firstLine == null) return [];
const { index } = subtitle;
if (firstLine == null || index == null) return [];
const parsed = parseGpsLine(firstLine);
if (parsed == null) return [];
return [{
index: subtitle.index,
...parsed,
index,
raw: firstLine,
f: gpsMatch[1]!,
ss: parseFloat(gpsMatch![2]!),
iso: parseInt(gpsMatch![3]!, 10),
ev: parseFloat(gpsMatch![4]!),
lat: parseFloat(gpsMatch![5]!),
lng: parseFloat(gpsMatch![6]!),
alt: parseFloat(gpsMatch![7]!),
distance: parseFloat(gpsMatch![8]!),
height: parseFloat(gpsMatch![9]!),
horizontalSpeed: parseFloat(gpsMatch![10]!),
verticalSpeed: parseFloat(gpsMatch![11]!),
}];
});
// console.log(gpsPoints)