-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVariableFont.lua
More file actions
254 lines (216 loc) · 7.36 KB
/
Copy pathVariableFont.lua
File metadata and controls
254 lines (216 loc) · 7.36 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
local P = {}
local ini = require("ini")
local function round(n)
n = tonumber(n) or 0
if n >= 0 then
return math.floor(n + 0.5)
end
return math.ceil(n - 0.5)
end
local function get_ext(filepath)
return tostring(filepath or ""):match("%.([^./\\]+)$") and
tostring(filepath):match("%.([^./\\]+)$"):lower() or ""
end
local function change_ext(filepath, new_ext)
local newfilepath = tostring(filepath or ""):gsub("%.[^./\\]+$", "")
return newfilepath .. "." .. new_ext
end
local function package_key(filepath)
return tostring(filepath or ""):gsub("%.[^./\\]+$", ""):lower()
end
local function is_supported_file(file)
if type(file) ~= "table" or type(file.filepath) ~= "string" then
return false
end
local ext = get_ext(file.filepath)
return ext == "wav" or ext == "txt"
end
-- ハンドラー名(必須)
P.name = "テキスト、音声ファイルをVariable Font Textオブジェクトに変換"
-- 優先度(省略時は 1000)
-- 数値が小さいほど先に実行されます
P.priority = 1000
function P.drag_enter(files, state)
for _, file in ipairs(files) do
if is_supported_file(file) then
return true
end
end
return false
end
function P.drag_leave()
-- ドラッグがタイムラインから離れたときの処理
end
local function files_package(files)
local packages_by_key = {}
local package_order = {}
for _, file in ipairs(files) do
if is_supported_file(file) then
local key = package_key(file.filepath)
local package_file = packages_by_key[key]
if not package_file then
package_file = {
audio_file = nil,
text_file = nil,
}
packages_by_key[key] = package_file
package_order[#package_order + 1] = package_file
end
if get_ext(file.filepath) == "wav" then
package_file.audio_file = file.filepath
else
package_file.text_file = file.filepath
end
end
end
for _, package_file in ipairs(package_order) do
if package_file.audio_file and not package_file.text_file then
local txt_path = change_ext(package_file.audio_file, "txt")
local txt_file = io.open(txt_path, "rb")
if txt_file then
txt_file:close()
package_file.text_file = txt_path
end
end
end
return package_order
end
local function text_from_file(file_path)
local file = io.open(file_path, "rb")
if not file then
return ""
end
local content = file:read("*a")
file:close()
return content
end
local function parse_bool(v)
if type(v) == "boolean" then
return v
end
local s = tostring(v or ""):lower()
return s == "1" or s == "true" or s == "on" or s == "yes"
end
local function is_conversion_enabled()
local script_dir = gcmz.get_script_directory()
local ini_path = script_dir .. "/VariableFont.ini"
local exists = io.open(ini_path, "rb")
if not exists then
return true
end
exists:close()
local ok, conf = pcall(ini.load, ini_path)
if not ok or type(conf) ~= "table" then
debug_print("VariableFont.ini の読み込みに失敗しました: " .. tostring(conf))
return true
end
local value = conf:get("Switch", "Handle", nil)
if value == nil then
return true
end
return parse_bool(value)
end
function P.drop(files, state)
if not is_conversion_enabled() then
debug_print("オブジェクト変換は無効です。")
return
end
if state and state.alt then
return
end
local data = gcmz.get_project_data()
if not data or not data.rate or not data.scale or data.scale == 0 then
debug_print("プロジェクト情報の取得に失敗しました。")
return
end
local packages = files_package(files)
if #packages == 0 then
return
end
local obj = ini.new()
local totalframes = 0
local obj_idx = 0
local group_idx = 1
for _, file in ipairs(packages) do
local duration_sec = 1
if file.audio_file then
local info, err = gcmz.get_media_info(file.audio_file)
if info and info.total_time then
duration_sec = info.total_time
elseif not info then
debug_print("メディア情報の取得に失敗しました: " .. tostring(err))
end
end
local length_frames = round(duration_sec * (data.rate / data.scale))
if length_frames < 1 then
length_frames = 1
end
local start_frame = totalframes
local end_frame = totalframes + length_frames - 1
if file.audio_file then
-- 音声
obj:set(tostring(obj_idx), "layer", "0")
obj:set(tostring(obj_idx), "frame", tostring(start_frame) .. "," .. tostring(end_frame))
obj:set(tostring(obj_idx), "group", tostring(group_idx))
obj:set(tostring(obj_idx) .. ".0", "effect.name", "音声ファイル")
obj:set(tostring(obj_idx) .. ".0", "ファイル", tostring(file.audio_file))
obj:set(tostring(obj_idx) .. ".1", "effect.name", "音声再生")
obj_idx = obj_idx + 1
end
if file.text_file then
-- セリフ準備
obj:set(tostring(obj_idx), "layer", "1")
obj:set(tostring(obj_idx), "frame", tostring(start_frame) .. "," .. tostring(end_frame))
obj:set(tostring(obj_idx), "group", tostring(group_idx))
obj:set(tostring(obj_idx) .. ".0", "effect.name", "Variable Font Text")
obj:set(tostring(obj_idx) .. ".0", "テキスト", tostring(text_from_file(file.text_file)))
obj:set(tostring(obj_idx) .. ".1", "effect.name", "標準描画")
obj_idx = obj_idx + 1
end
totalframes = end_frame + 1
group_idx = group_idx + 1
end
if obj_idx == 0 then
return
end
local temp_path, temp_err = gcmz.create_temp_file("variable-font.object")
if not temp_path then
debug_print("一時ファイルの作成に失敗しました: " .. tostring(temp_err))
return
end
local temp_file = io.open(temp_path, "wb")
if not temp_file then
debug_print("一時ファイルを開けませんでした: " .. temp_path)
return
end
local write_ok, write_err = temp_file:write(tostring(obj))
temp_file:close()
if not write_ok then
debug_print("一時ファイルの書き込みに失敗しました: " .. tostring(write_err))
return
end
local replacement = {
filepath = temp_path,
mimetype = "application/aviutl-object",
temporary = true,
}
local output_files = {}
local replacement_added = false
for _, file in ipairs(files) do
if is_supported_file(file) then
if not replacement_added then
output_files[#output_files + 1] = replacement
replacement_added = true
end
else
output_files[#output_files + 1] = file
end
end
for index = #files, 1, -1 do
files[index] = nil
end
for index, file in ipairs(output_files) do
files[index] = file
end
end
return P