2020-03-04 10:41:40 +00:00
import padStart from 'lodash/padStart' ;
import Swal from 'sweetalert2' ;
2020-03-19 15:37:38 +00:00
import i18n from 'i18next' ;
2016-11-03 21:31:13 +00:00
2020-03-04 10:41:40 +00:00
import randomColor from './random-color' ;
2019-01-28 17:09:54 +00:00
2020-03-04 10:41:40 +00:00
const path = window . require ( 'path' ) ;
const fs = window . require ( 'fs-extra' ) ;
2019-01-28 17:09:54 +00:00
2020-03-04 10:41:40 +00:00
export function formatDuration ( { seconds : _seconds , fileNameFriendly , fps } ) {
2016-11-03 21:31:13 +00:00
const seconds = _seconds || 0 ;
const minutes = seconds / 60 ;
const hours = minutes / 60 ;
2020-03-04 10:41:40 +00:00
const hoursPadded = padStart ( Math . floor ( hours ) , 2 , '0' ) ;
const minutesPadded = padStart ( Math . floor ( minutes % 60 ) , 2 , '0' ) ;
const secondsPadded = padStart ( Math . floor ( seconds ) % 60 , 2 , '0' ) ;
2020-02-20 11:18:36 +00:00
const ms = seconds - Math . floor ( seconds ) ;
2020-02-14 05:48:58 +00:00
const msPadded = fps != null
2020-03-04 10:41:40 +00:00
? padStart ( Math . floor ( ms * fps ) , 2 , '0' )
: padStart ( Math . floor ( ms * 1000 ) , 3 , '0' ) ;
2016-11-03 21:31:13 +00:00
// Be nice to filenames and use .
2018-05-15 10:36:33 +00:00
const delim = fileNameFriendly ? '.' : ':' ;
return ` ${ hoursPadded } ${ delim } ${ minutesPadded } ${ delim } ${ secondsPadded } . ${ msPadded } ` ;
}
2020-03-04 10:41:40 +00:00
export function parseDuration ( str ) {
2018-05-15 10:36:33 +00:00
if ( ! str ) return undefined ;
const match = str . trim ( ) . match ( /^(\d{2}):(\d{2}):(\d{2})\.(\d{3})$/ ) ;
if ( ! match ) return undefined ;
const hours = parseInt ( match [ 1 ] , 10 ) ;
const minutes = parseInt ( match [ 2 ] , 10 ) ;
const seconds = parseInt ( match [ 3 ] , 10 ) ;
const ms = parseInt ( match [ 4 ] , 10 ) ;
if ( hours > 59 || minutes > 59 || seconds > 59 ) return undefined ;
return ( ( ( ( hours * 60 ) + minutes ) * 60 ) + seconds ) + ( ms / 1000 ) ;
2016-11-03 21:31:13 +00:00
}
2020-03-04 10:41:40 +00:00
export function getOutDir ( customOutDir , filePath ) {
2020-02-20 17:57:14 +00:00
if ( customOutDir ) return customOutDir ;
if ( filePath ) return path . dirname ( filePath ) ;
return undefined ;
2020-02-15 07:57:40 +00:00
}
2020-03-04 10:41:40 +00:00
export function getOutPath ( customOutDir , filePath , nameSuffix ) {
2020-02-20 17:57:14 +00:00
if ( ! filePath ) return undefined ;
2020-02-28 10:28:04 +00:00
const parsed = path . parse ( filePath ) ;
2017-08-14 12:25:27 +00:00
2020-02-28 10:28:04 +00:00
return path . join ( getOutDir ( customOutDir , filePath ) , ` ${ parsed . name } - ${ nameSuffix } ` ) ;
2017-08-14 12:25:27 +00:00
}
2020-03-31 05:11:55 +00:00
export async function checkDirWriteAccess ( dirPath ) {
try {
await fs . access ( dirPath , fs . constants . W _OK ) ;
} catch ( err ) {
if ( err . code === 'EPERM' ) return false ;
// if (err.code === 'EACCES') return false;
console . error ( err ) ;
}
return true ;
}
2020-03-04 10:41:40 +00:00
export async function transferTimestamps ( inPath , outPath ) {
2017-09-14 17:15:03 +00:00
try {
2020-02-16 04:33:38 +00:00
const stat = await fs . stat ( inPath ) ;
await fs . utimes ( outPath , stat . atime . getTime ( ) / 1000 , stat . mtime . getTime ( ) / 1000 ) ;
2017-09-14 17:15:03 +00:00
} catch ( err ) {
console . error ( 'Failed to set output file modified time' , err ) ;
}
}
2020-03-04 10:41:40 +00:00
export async function transferTimestampsWithOffset ( inPath , outPath , offset ) {
2018-02-11 13:09:01 +00:00
try {
2020-02-16 04:33:38 +00:00
const stat = await fs . stat ( inPath ) ;
2018-02-11 13:09:01 +00:00
const time = ( stat . mtime . getTime ( ) / 1000 ) + offset ;
2020-02-16 04:33:38 +00:00
await fs . utimes ( outPath , time , time ) ;
2018-02-11 13:09:01 +00:00
} catch ( err ) {
console . error ( 'Failed to set output file modified time' , err ) ;
}
}
2020-03-04 10:41:40 +00:00
export const toast = Swal . mixin ( {
2019-01-27 23:21:53 +00:00
toast : true ,
position : 'top' ,
showConfirmButton : false ,
2019-08-12 20:04:43 +00:00
timer : 5000 ,
2019-01-27 23:21:53 +00:00
} ) ;
2020-03-04 10:41:40 +00:00
export const errorToast = ( title ) => toast . fire ( {
2020-02-19 04:56:10 +00:00
icon : 'error' ,
2019-01-27 23:21:53 +00:00
title ,
} ) ;
2020-03-04 10:41:40 +00:00
export async function showFfmpegFail ( err ) {
2019-01-27 23:21:53 +00:00
console . error ( err ) ;
2020-03-19 15:37:38 +00:00
return errorToast ( ` ${ i18n . t ( 'Failed to run ffmpeg:' ) } ${ err . stack } ` ) ;
2019-01-27 23:21:53 +00:00
}
2020-03-04 10:41:40 +00:00
export function setFileNameTitle ( filePath ) {
2019-01-28 01:25:31 +00:00
const appName = 'LosslessCut' ;
2020-02-11 14:15:55 +00:00
document . title = filePath ? ` ${ appName } - ${ path . basename ( filePath ) } ` : appName ;
2019-01-28 01:25:31 +00:00
}
2020-03-04 10:41:40 +00:00
export function filenamify ( name ) {
2020-02-24 09:04:55 +00:00
return name . replace ( /[^0-9a-zA-Z_.]/g , '_' ) ;
}
2020-03-04 10:41:40 +00:00
export async function promptTimeOffset ( inputValue ) {
2020-02-16 04:33:38 +00:00
const { value } = await Swal . fire ( {
2020-03-19 15:37:38 +00:00
title : i18n . t ( 'Set custom start time offset' ) ,
text : i18n . t ( 'Instead of video apparently starting at 0, you can offset by a specified value (useful for viewing/cutting videos according to timecodes)' ) ,
2019-01-28 01:25:31 +00:00
input : 'text' ,
inputValue : inputValue || '' ,
showCancelButton : true ,
inputPlaceholder : '00:00:00.000' ,
} ) ;
if ( value === undefined ) {
return undefined ;
}
const duration = parseDuration ( value ) ;
// Invalid, try again
if ( duration === undefined ) return promptTimeOffset ( value ) ;
return duration ;
}
2019-01-27 23:21:53 +00:00
2020-03-04 10:41:40 +00:00
export function generateColor ( ) {
2019-01-28 17:09:54 +00:00
return randomColor ( 1 , 0.95 ) ;
}
2020-03-04 10:41:40 +00:00
export function withBlur ( cb ) {
2020-02-26 03:11:28 +00:00
return ( e ) => {
cb ( e ) ;
e . target . blur ( ) ;
} ;
}
2020-03-04 10:41:40 +00:00
export function getSegColors ( seg ) {
2020-02-26 03:11:28 +00:00
if ( ! seg ) return { } ;
const { color } = seg ;
return {
segBgColor : color . alpha ( 0.5 ) . string ( ) ,
segActiveBgColor : color . lighten ( 0.5 ) . alpha ( 0.5 ) . string ( ) ,
segBorderColor : color . lighten ( 0.5 ) . string ( ) ,
} ;
}