-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathExport Video.lua
More file actions
157 lines (138 loc) · 4.95 KB
/
Export Video.lua
File metadata and controls
157 lines (138 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
local dlg = Dialog("Export Video")
if app.sprite then
if not (string.find(app.sprite.filename, '/') or string.find(app.sprite.filename, '\\')) then
app.alert('save the file and export the frames first')
end
else
app.alert('no file is opened')
end
dlg:newrow()
dlg:file{
id = 'firstFramePath',
label = 'choose the first frame:',
title = 'Choose THE FIRST exported frame (e.g. 1.png)',
open = false,
save = false,
load = true,
filetypes = {'png', 'jpg'}
}
dlg:newrow()
dlg:file{
id = 'saveTo',
label = 'Save To:',
title = 'Choose where to save the video',
open = false,
save = true,
load = false,
filetypes = {'mkv', 'mp4'}
}
dlg:newrow()
dlg:number{
id = 'loopAmount',
label = 'Loop Number:',
text = "1",
decimals = integer
}
dlg:newrow()
dlg:button{
id = "export",
text = "Export Video",
onclick = function()
local data = dlg.data
local firstFramePath = data.firstFramePath
local saveTo = data.saveTo
local loopAmount = data.loopAmount
if (math.type(loopAmount) ~= "integer") or (loopAmount < 1) then
app.alert('loop amout is wrong')
return
end
loopAmount = loopAmount - 1
if not firstFramePath then
return app.alert('you gotta choose a sample exported frame first')
end
if not saveTo then
return app.alert('choose where to save the file first')
end
local FramesParentFolder = firstFramePath ~= '' and
string.match(firstFramePath, "(.*" .. app.fs.pathSeparator .. ")") or ''
local saveToParentFolder = saveTo ~= '' and string.match(saveTo, "(.*" .. app.fs.pathSeparator .. ")") or ''
local ffconcatContent = "ffconcat version 1.0\n"
local sprite = app.sprite
-- check no latin character in the folder of the sample frame or saveTo
function isnt_safe(str)
-- Match any character that is not in the ASCII range (0-127)
return str:match("[\128-\255]") ~= nil
end
if isnt_safe(FramesParentFolder) or isnt_safe(saveToParentFolder) or isnt_safe(app.fs.fileTitle(saveTo)) then
app.alert("non-latin characters are only permitted for the name of the frame images. " ..
"you should not put any non-latin chraacter in the folder's names or the export file name.")
return
end
-- get the logging status
local ffmpeg_log = false
function loadconf()
local conf = require "conf"
ffmpeg_log = conf.log_ffmpeg
end
pcall(loadconf)
-- find frames files
local FolderFiles = app.fs.listFiles(string.match(firstFramePath, "(.*" .. app.fs.pathSeparator .. ")"))
local frame_images = {}
for _, sframe in ipairs(FolderFiles) do
if string.match(sframe, "%." .. app.fs.fileExtension(firstFramePath) .. "$") then
table.insert(frame_images, sframe)
end
end
table.sort(frame_images, function(a, b)
-- Extract the numeric part from the strings
local numA = tonumber(string.match(a, "%d+"))
local numB = tonumber(string.match(b, "%d+"))
-- Compare based on the numeric part
return numA < numB
end)
-- Create _info ffconcat file
for i, frame in ipairs(sprite.frames) do
local filename = app.fs.joinPath(FramesParentFolder, frame_images[i])
local frameDuration = frame.duration -- Convert duration to seconds
ffconcatContent = ffconcatContent .. string.format("file '%s'\nduration %s\n", filename, frameDuration)
end
local concatFilePath = saveToParentFolder .. "_info"
local concatFile = io.open(concatFilePath, "w")
concatFile:write(ffconcatContent)
concatFile:close()
-- get report argument's text
local report_text = ''
if ffmpeg_log == true then
report_text = ' -report'
end
-- Run ffmpeg command
local ffmpegCommand = string.format('ffmpeg -f concat -safe 0 -y -i "%s" -pix_fmt yuv420p "%s"%s',
concatFilePath, saveTo, report_text)
os.execute(ffmpegCommand)
if loopAmount > 0 then
local loopSaveTo = app.fs.filePathAndTitle(saveTo) .. '_loop' .. loopAmount + 1 .. "." ..
app.fs.fileExtension(saveTo)
os.execute(string.format('ffmpeg -y -stream_loop %s -i "%s" -c copy "%s"%s', loopAmount, saveTo, loopSaveTo,
report_text))
end
end
}
dlg:button{
id = "cancel",
text = "Cancel",
onclick = app.command.Cancel
}
dlg:button{
id = "help",
text = "Help!",
onclick = function()
local helpDlg = Dialog("Help!")
helpDlg:label{
label = "go to github lol"
}
helpDlg:show()
end
}
dlg:show{
wait = false
}