Skip to content

Commit

Permalink
add option: export high quality gif
Browse files Browse the repository at this point in the history
  • Loading branch information
anosu committed Sep 23, 2024
1 parent 95f6df0 commit 08494f9
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 22 deletions.
42 changes: 27 additions & 15 deletions electron/backend.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const {app, BrowserWindow, ipcMain, Menu, MenuItem, dialog, session} = require('electron/main')
const {exec} = require('child_process')
const {exec, spawn} = require('child_process')
const path = require('path')
// const http = require("http");
const fs = require("fs");
Expand Down Expand Up @@ -81,6 +81,7 @@ const createWindow = (log) => {

app.whenReady().then(() => {
let log = {
name: 'app',
error: ''
}
if (!fs.existsSync(process.env.CACHE_PATH)) {
Expand All @@ -93,15 +94,15 @@ app.whenReady().then(() => {
createWindow(log)

session.defaultSession.webRequest.onBeforeRequest({urls: ['file://*']}, (details, callback) => {
let reqUrl = details.url
const filePath = decodeURIComponent(reqUrl.slice(8))

if (filePath.endsWith('.atlas') && !fs.existsSync(filePath)) {
reqUrl = reqUrl + '.txt'
callback({redirectURL: reqUrl})
} else {
callback({cancel: false})
const reqUrl = details.url
if (reqUrl.endsWith('.atlas')) {
const filePath = decodeURIComponent(reqUrl.slice(8))
if (!fs.existsSync(filePath)) {
callback({redirectURL: reqUrl + '.txt'})
return
}
}
callback({cancel: false})
})

ipcMain.handle('port', () => server.address().port)
Expand Down Expand Up @@ -151,18 +152,29 @@ app.whenReady().then(() => {
ipcMain.handle('save-image-cache', (ev, image) => saveBase64Image(image))
ipcMain.handle('ffmpeg', (ev, options) => {
const imagePath = path.join(process.env.CACHE_PATH, filename)
const outputPath = options.path
let instruction;
const inputPath = path.join(imagePath, '%05d.png')
const outputPath = path.join(options.path, options.filename)
const ffmpegArgs = ['-y', '-r', options.framerate.toString(), '-i', inputPath]
switch (options.format) {
case 'MP4':
instruction = `"${process.env.FFMPEG_PATH}" -y -r ${options.framerate} -i "${path.join(imagePath, '%05d.png')}" -vf "crop=if(mod(iw\\,2)\\,iw-1\\,iw):if(mod(ih\\,2)\\,ih-1\\,ih)" -crf 17 -pix_fmt yuv420p "${path.join(outputPath, options.filename + '.mp4')}"`
ffmpegArgs.push(...['-vf', 'crop=if(mod(iw\\,2)\\,iw-1\\,iw):if(mod(ih\\,2)\\,ih-1\\,ih)', '-crf', '17', '-pix_fmt', 'yuv420p', `${outputPath}.mp4`])
break
case 'GIF-HQ':
ffmpegArgs.push(...['-vf', 'split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse', `${outputPath}.gif`])
break
case 'GIF':
default:
instruction = `"${process.env.FFMPEG_PATH}" -y -r ${options.framerate} -i "${path.join(imagePath, '%05d.png')}" "${path.join(outputPath, options.filename + '.gif')}"`
ffmpegArgs.push(`${outputPath}.gif`)
break
}
exec(instruction, (error, stdout, stderr) => {
const ffmpegProcess = spawn(process.env.FFMPEG_PATH, ffmpegArgs)
ffmpegProcess.stdout.on('data', (data) => {
win.webContents.send('logs-out', {name: 'ffmpeg', stdout: data.toString()})
})
ffmpegProcess.stderr.on('data', (data) => {
win.webContents.send('logs-out', {name: 'ffmpeg', stderr: data.toString()})
})
ffmpegProcess.on('close', (code) => {
fs.readdir(imagePath, (err, files) => {
files.forEach(file => {
const filePath = path.join(imagePath, file);
Expand All @@ -172,7 +184,7 @@ app.whenReady().then(() => {
}
)
win.webContents.send('export-complete')
win.webContents.send('logs-out', {stdout, stderr})
win.webContents.send('logs-out', {name: 'export', code})
})
})

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spine-viewer-vue",
"version": "1.0.2",
"version": "1.0.3",
"main": "electron/backend.js",
"private": true,
"scripts": {
Expand Down
11 changes: 7 additions & 4 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {useAppStore} from "@/stores/app";
import useApp from "@/hooks/useApp";
ipcRenderer.on('logs-out', (_ev, logs) => {
console.log('logs: ', logs)
console.log('[INFO] ', logs)
})
// 子组件
Expand Down Expand Up @@ -74,12 +74,13 @@ const exportAnimation = () => {
standard.index = i
standard.duration = info.totalDuration
}
c.setAutoUpdate(false)
})
let {format, framerate, filename, path} = exportStore.options
if (!standard.duration || !path) return
appStore.containers.forEach(c => c.setAutoUpdate(false))
if (Number.isNaN(framerate) || framerate < 1 || framerate > 60) {
framerate = format === 'MP4' ? 30 : 20
}
Expand Down Expand Up @@ -140,11 +141,13 @@ ipcRenderer.on('export-complete', () => {
window.onerror = function (message) {
if (message.includes('Texture Error')) {
console.error(message)
alert('贴图尺寸与图集不符合!')
location.reload()
} else if (message.includes('Region not found')) {
alert('Spine文件错误')
location.reload()
}
};
}
function loadFiles(fileUrls) {
pixiApp.loader
Expand Down
8 changes: 7 additions & 1 deletion src/components/Export.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</div>
<div class="export-option input">
<select id="export-format" v-model="store.options.format">
<option v-for="option in ['GIF', 'MP4']">{{ option }}</option>
<option v-for="(desc, option) in formats" :value="option">{{ desc }}</option>
</select>
<input type="number" min="1" max="60"
v-model.number="store.options.framerate"
Expand Down Expand Up @@ -47,6 +47,12 @@ const selectExportPath = async () => {
store.options.path = await ipcRenderer.invoke('select-export-path')
}
const formats = {
'GIF': 'GIF',
'MP4': 'MP4',
'GIF-HQ': 'GIF (HQ)',
}
</script>

<style scoped>
Expand Down
1 change: 0 additions & 1 deletion src/utils/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export const createTag = (e) => {

export const getFileUrl = (filePath) => {
// return `http://localhost:${port}/${filePath.replaceAll('\\', '/')}`
console.log(filePath)
return filePath.replaceAll('\\', '/')
}

Expand Down

0 comments on commit 08494f9

Please sign in to comment.