Skip to content

Commit

Permalink
Merge pull request #194 from entrylabs/develop
Browse files Browse the repository at this point in the history
version up 2.1.12
  • Loading branch information
Tnks2U authored Feb 29, 2024
2 parents 1965f60 + 54deb0f commit f6b102d
Show file tree
Hide file tree
Showing 19 changed files with 17,532 additions and 158 deletions.
2 changes: 1 addition & 1 deletion build/entryx64.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
!define MUI_UNICON "icon.ico"
!define PRODUCT_NAME "Entry"
!define APP_NAME "Entry.exe"
!define PRODUCT_VERSION "2.1.11"
!define PRODUCT_VERSION "2.1.12"
!define PRODUCT_PUBLISHER "EntryLabs"
!define PRODUCT_WEB_SITE "http://www.playentry.org/"

Expand Down
2 changes: 1 addition & 1 deletion build/entryx86.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
!define MUI_UNICON "icon.ico"
!define PRODUCT_NAME "Entry"
!define APP_NAME "Entry.exe"
!define PRODUCT_VERSION "2.1.11"
!define PRODUCT_VERSION "2.1.12"
!define PRODUCT_PUBLISHER "EntryLabs"
!define PRODUCT_WEB_SITE "http://www.playentry.org/"

Expand Down
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"private": true,
"productName": "Entry",
"name": "entry",
"version": "2.1.11",
"version": "2.1.12",
"description": "Entry for offline",
"main": "src/main_build/main.bundle.js",
"scripts": {
Expand Down Expand Up @@ -33,13 +33,17 @@
"@babel/core": "^7.20.7",
"@electron/remote": "^2.0.8",
"@entrylabs/modal": "^1.2.7",
"@ffmpeg-installer/ffmpeg": "^1.1.0",
"@ffprobe-installer/ffprobe": "^2.1.2",
"@types/fluent-ffmpeg": "^2.1.24",
"async-csv": "^2.1.3",
"axios": "^0.19.2",
"cross-spawn": "^7.0.3",
"entry-hw": "git+https://github.com/entrylabs/entry-hw.git#dist/v1.9.49",
"entry-js": "git+https://github.com/entrylabs/entryjs.git#dist/offline_v2.1.11",
"entry-hw": "git+https://github.com/entrylabs/entry-hw.git#dist/v1.9.50",
"entry-js": "git+https://github.com/entrylabs/entryjs.git#dist/offline_v2.1.12",
"entry-tool": "git+https://github.com/entrylabs/entry-tool.git#dist/20231026",
"excel4node": "^1.7.0",
"fluent-ffmpeg": "^2.1.2",
"fs-extra": "^8.1.0",
"image-size": "^0.8.3",
"jquery": "^3.4.1",
Expand Down
54 changes: 54 additions & 0 deletions src/main/fileUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,26 @@ import rimraf from 'rimraf';
import tar, { CreateOptions, FileOptions } from 'tar';
import { nativeImage, NativeImage } from 'electron';
import createLogger from './utils/functions/createLogger';
import ffmpeg from 'fluent-ffmpeg';
import ffmpegInstaller from '@ffmpeg-installer/ffmpeg'
import ffprobeInstaller from '@ffprobe-installer/ffprobe'
import get from 'lodash/get';

type tarCreateOption = FileOptions & CreateOptions;
type readFileOption = { encoding?: string | null; flag?: string } | string | undefined | null;
type Dimension = { width: number; height: number };

const logger = createLogger('main/fileUtils.ts');
const ffmpegPath = ffmpegInstaller.path.replace(
'app.asar',
'app.asar.unpacked'
);
const ffprobePath = ffprobeInstaller.path.replace(
'app.asar',
'app.asar.unpacked'
);
ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg.setFfprobePath(ffprobePath);

export const ImageResizeSize: { [key: string]: Dimension } = {
thumbnail: { width: 96, height: 96 },
Expand Down Expand Up @@ -282,4 +296,44 @@ export default class {
logger.info(`moveFile to ${src} to ${dest}`);
fse.moveSync(src, dest, { overwrite: true });
}

static getSoundInfo = (filePath: string, isExtCheck = true): Promise<ProbeData> =>
new Promise((resolve, reject) => {
ffmpeg.ffprobe(filePath, (err: any, probeData: any) => {
if (err) {
return reject(err);
}
const { format = {} } = probeData;
const { format_name: formatName } = format;
if (isExtCheck && formatName !== 'mp3') {
return reject(new Error('업로드 파일이 MP3 파일이 아닙니다.'));
}
resolve(probeData);
});
});

static getDuration = (soundInfo: any) => {
const duration = get(soundInfo, ['format', 'duration'], 0);
return Number(duration).toFixed(1);
};

static convertStreamToMp3AndSave = (filePath: string, targetPath: string): Promise<string> => {
return new Promise((resolve, reject) => {
// INFO : targetPath경로에 해당하는 디렉토리를 미리 만들어 줘야함
this.ensureDirectoryExistence(targetPath);
ffmpeg(filePath)
.audioCodec('libmp3lame')
.toFormat('mp3')
.output(targetPath)
.on('end', () => resolve(targetPath))
.on('error', (err: any) => {
if (err && err.message) {
console.error(`Error: ${err.message}`);
logger.error(`Error: ${err.message}`);
}
reject(err);
})
.run();
});
};
}
9 changes: 7 additions & 2 deletions src/main/ipcMainHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ new (class {
ipcMain.handle('checkPermission', this.checkPermission.bind(this));
ipcMain.handle('getOpenSourceText', () => ''); // 별다른 표기 필요없음
ipcMain.handle('isValidAsarFile', this.checkIsValidAsarFile.bind(this));
ipcMain.handle('saveSoundBuffer', this.saveSoundBuffer.bind(this));
}

async saveProject(event: IpcMainInvokeEvent, project: ObjectLike, targetPath: string) {
Expand All @@ -56,8 +57,8 @@ new (class {
logger.verbose(`loadProject called, ${filePath}`);
try {
return await MainUtils.loadProject(filePath);
} catch (e: any) {
logger.error(`loadProject failed, ${e.message}`);
} catch (e) {
logger.error('loadProject failed, ${e.message}');
throw e;
}
}
Expand Down Expand Up @@ -248,6 +249,10 @@ new (class {
return [global.sharedObject.version, data];
}

async saveSoundBuffer(event: IpcMainInvokeEvent, buffer: ArrayBuffer, prevFileUrl: string) {
return MainUtils.saveSoundBuffer(buffer, prevFileUrl);
}

openUrl(event: IpcMainInvokeEvent, url: string) {
logger.info(`openUrl called : ${url}`);
shell.openExternal(url);
Expand Down
89 changes: 77 additions & 12 deletions src/main/mainUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,10 @@ export default class MainUtils {
});

Promise.all(copyObjectPromise)
.then(function () {
.then(function() {
resolve('success');
})
.catch(function (err) {
.catch(function(err) {
reject(err);
});
} catch (e) {
Expand Down Expand Up @@ -574,32 +574,46 @@ export default class MainUtils {
'src',
'preload_build',
'preload.bundle.js'
)
),
},
})
});
const windowId = captureWindow.id;
remoteMain.enable(captureWindow.webContents);
captureWindow.loadURL(
`file:///${path.resolve(app.getAppPath(), 'src', 'main', 'views', 'capture.html')}`
)
`file:///${path.resolve(
app.getAppPath(),
'src',
'main',
'views',
'capture.html'
)}`
);

// captureWindow의 송수신 및 라이프사이클 관련 함수
ipcMain.handle(`getImageString_${windowId}`, () => {
return image;
})
});
ipcMain.on(`captureAndSave_${windowId}`, async () => {
// 렌더러에서 svg를 그리는데 다소 시간이 걸리므로 대기 후 실행
await setTimeout(async () => {
const capturedImage = await captureWindow.webContents.capturePage({ x: 0, y: 0, width, height });
await FileUtils.writeFile(capturedImage.toPNG(), `${filePath}${index}${'.png'}`);
const capturedImage = await captureWindow.webContents.capturePage({
x: 0,
y: 0,
width,
height,
});
await FileUtils.writeFile(
capturedImage.toPNG(),
`${filePath}${index}${'.png'}`
);
captureWindow.close();
}, WAITING_TIME);
})
});
captureWindow.addListener('closed', () => {
ipcMain.removeAllListeners(`captureAndSave_${windowId}`);
ipcMain.removeHandler(`getImageString_${windowId}`);
})
})
});
});
} catch (error) {
console.error(error);
}
Expand Down Expand Up @@ -827,4 +841,55 @@ export default class MainUtils {
};
}
}

static saveSoundBuffer(arrayBuffer: ArrayBuffer, prevFileUrl: string) {
return new Promise(async (resolve, reject) => {
let tempBufferPath;
let saveFilePath;
try {
// 1. buffer상태로 임시 저장
const tempBufferId = CommonUtils.createFileId();
tempBufferPath = path.join(
Constants.tempSoundPath(tempBufferId),
`${tempBufferId}`
);
const buffer = Buffer.from(arrayBuffer);
await FileUtils.writeFile(buffer, tempBufferPath);

// 2. 최종저장 경로 생성
const filename = CommonUtils.createFileId();
const filePath = path.join(Constants.tempSoundPath(filename), `${filename}.mp3`);

// 3. 유효성 검사
const soundInfo = await FileUtils.getSoundInfo(tempBufferPath, false);
if (soundInfo?.format?.format_name !== 'wav') {
throw new Error('sound not supported');
}

// 5. buffer파일 mp3로 변환 후 저장
saveFilePath = await FileUtils.convertStreamToMp3AndSave(tempBufferPath, filePath);

// 6. response 작성
const sound = {
duration: FileUtils.getDuration(soundInfo),
filename,
filePath: saveFilePath,
};
resolve(sound);
} catch (err) {
console.error(err);
reject(err);
} finally {
try {
// INFO: 기존파일과 임시버퍼 제거, fileurl이 temp로 시작하는 경우에만 제거됨
const prevTempPath = path.join(Constants.appPath, prevFileUrl);
saveFilePath && (await FileUtils.deleteFile(prevTempPath));
tempBufferPath && (await FileUtils.deleteFile(tempBufferPath));
} catch (e) {
console.error('sound file unlink fail', e);
reject(e);
}
}
});
}
}
3 changes: 3 additions & 0 deletions src/main/views/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
<script type='text/javascript' src='../../../node_modules/entry-js/extern/util/ndgmr.Collision.js'></script>

<script type='text/javascript' src='../../../node_modules/literallycanvas-mobile/lib/js/literallycanvas.js'></script>
<script type='text/javascript' src="../../renderer/resources/vendor/react18/react.production.min.js"></script>
<script type='text/javascript' src="../../renderer/resources/vendor/react18/react-dom.production.min.js"></script>
<script type="text/javascript" src="../../renderer/resources/vendor/sound-editor.js"></script>
<script type='text/javascript' src='../../../node_modules/entry-js/dist/entry.js'></script>
<script type='text/javascript' src='../../renderer/resources/paint/static/js/entry-paint.js'></script>

Expand Down
Loading

0 comments on commit f6b102d

Please sign in to comment.