Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Gopro HERO5 #76

Merged
merged 1 commit into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions app/src/provider/Commons.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ const fs = require('fs');
const moment = require('moment');
const {ipcRenderer} = require('electron');

const HERO5LOW = 'hero5-';
const HERO5HIGH = 'hero+';
const HEROMAX = 'max';
const NONE = 'undefined';

module.exports = {
/**
* Function that returns if app is packaged or not (Only for main process)
Expand Down Expand Up @@ -31,6 +36,32 @@ module.exports = {
return dirContent;
},

/**
* Function that try to identify GoPro camera model based on file naming convention
*
* @param fileName
* @returns {string}
*/
identifyGoProModel(fileName) {
const validHERO5Pus = ['GH', 'GX'];

for (const token of validHERO5Pus) {
if (fileName.startsWith(token)) {
return HERO5HIGH;
}
}

if (fileName.startsWith('GS')) {
return HEROMAX;
}

if (fileName.startsWith('GOPR') || fileName.startsWith('GP')) {
return HERO5LOW;
}

return NONE;
},

/**
* Function that sorts gopro names (Main and render process)
* Accepts a maximum number of 999 chapters
Expand All @@ -40,6 +71,14 @@ module.exports = {
*/
sortGoProNames(arr) {
return arr.sort(function (x, y) {
if (module.exports.identifyGoProModel(x) === HERO5LOW) {
return 1;
}

if (module.exports.identifyGoProModel(y) === HERO5LOW) {
return -1;
}

x = isNaN(x.substring(1, 4)) ? x.substring(2, 4) : x.substring(1, 4);
y = isNaN(y.substring(1, 4)) ? y.substring(2, 4) : y.substring(1, 4);

Expand Down Expand Up @@ -107,5 +146,9 @@ module.exports = {
return JSON.parse(JSON.stringify(array))
},

HERO5LOW,
HERO5HIGH,
HEROMAX,
NONE,
version
}
55 changes: 48 additions & 7 deletions app/src/provider/VideoProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ class VideoProcessor {

if (fs.existsSync(path.join(project.projectPath, outputNameToCheck))) {
const dirFiles = Commons.readDir(path.join(project.projectPath));
const fileRegex = /^(G[HXS]?(\d{6}|\d{7}))_joined(_\d*)?\.(MP4|mp4|360)/;
const fileRegex = /^(G(OPR)?[HXS]?(\d{6}|\d{7}|\d{4}))_joined(_\d*)?\.(MP4|mp4|360)/;
let maxNumber = 1;

for (const file of dirFiles) {
Expand Down Expand Up @@ -542,13 +542,32 @@ class VideoProcessor {
* @returns {{}}
*/
static scanGoProDir(dirPath) {
const HERO5LOWRegex = /^(G(OPR)?(P)?(\d{6}|\d{4}))\.(MP4|mp4)/;
const HERO5HIGHRegex = /^G[PHXS]?(\d{6}|\d{7})\.(MP4|mp4)/;
const MAXRegex = /^GS?(\d{6}|\d{7})\.360/;

const goProGroupedFiles = {};
const goProFiles = [];
const files = Commons.readDir(dirPath);

//Get GoPro files
for (const file of files) {
if (/^(G[HXS]?(\d{6}|\d{7}))\.(MP4|mp4|360)/.test(file) && !goProFiles.includes(file)) {
let rgx;
switch (Commons.identifyGoProModel(file)) {
case Commons.HERO5LOW:
rgx = HERO5LOWRegex;
break;
case Commons.HERO5HIGH:
rgx = HERO5HIGHRegex;
break;
case Commons.HEROMAX:
rgx = MAXRegex;
break;
case Commons.NONE:
continue;
}

if (rgx.test(file) && !goProFiles.includes(file)) {
goProFiles.push(file);
}
}
Expand All @@ -571,13 +590,10 @@ class VideoProcessor {

//Check consecutive chapters in groups
for (const [key, values] of Object.entries(goProGroupedFiles)) {
const firstValue = values[0];
let lastChapterNum = parseInt(isNaN(firstValue.substring(1, 4)) ? firstValue.substring(2, 4) : firstValue.substring(1, 4));
let lastChapterNum = this.getChapterNum(values[0]);

for (const chapterFile of values) {
const chapterNum = isNaN(chapterFile.substring(1, 4)) ? chapterFile.substring(2, 4) : chapterFile.substring(1, 4);

if (parseInt(chapterNum) !== lastChapterNum) {
if (this.getChapterNum(chapterFile) !== lastChapterNum) {
throw new NotConsecutiveChaptersError(`Group (${key}) have not consecutive chapters`);
} else {
lastChapterNum++;
Expand All @@ -588,6 +604,31 @@ class VideoProcessor {
return goProGroupedFiles;
}


/**
* Function that gets chapter number of gopro file name
*
* @param chapterFile
* @returns {number}
*/
static getChapterNum(chapterFile) {
let chapterNum = 0;

switch (Commons.identifyGoProModel(chapterFile)) {
case Commons.HERO5LOW:
if (!chapterFile.startsWith('GOPR')) {
chapterNum = isNaN(chapterFile.substring(1, 4)) ? chapterFile.substring(2, 4) : chapterFile.substring(1, 4);
}
break;
case Commons.HEROMAX:
case Commons.HERO5HIGH:
chapterNum = isNaN(chapterFile.substring(1, 4)) ? chapterFile.substring(2, 4) : chapterFile.substring(1, 4);
break;
}

return Number(chapterNum);
}

/**
* Function that generates the thumbnail of the project
*
Expand Down