forked from lvml/mpv-plugin-excerpt
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathexcerpt.lua
More file actions
269 lines (227 loc) · 8.9 KB
/
Copy pathexcerpt.lua
File metadata and controls
269 lines (227 loc) · 8.9 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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
-- This script allows to create excerpts of a video that is played,
-- press "i" to mark the begin of the range to excerpt,
-- press "o" to mark the end of the range to excerpt,
-- use the chapter markers on the OSD to jump between IN and OUT points,
-- press "E" to toggle between encoding (precise, negligible quality loss) and no-encoding (very fast, no quality loss),
-- press "x" to actually start the creation of the excerpt,
-- which will be done by starting an external executable (ffmpeg)
-- (see bottom of this file for all key bindings)
--
-- homezappa
-- Intel graphics cards vaapi compatible as in https://www.intel.com/content/www/us/en/developer/articles/technical/linuxmedia-vaapi.html
-- GMA X4500HD.
-- Intel® HD Graphics (in Intel® 2010 Core™ i7/i5/i3 processor family). Can't check .. too old board?
-- Intel® HD Graphics 2000/3000 (in 2nd Generation Intel® Core™ i7/i5/i3 Processor family).
-- Intel® HD Graphics 2500/4000 (in 3nd Generation Intel® Core™ i7/i5/i3 Processor family).
-- Intel® HD Graphics 4200/4400/4600/5000, Intel® Iris™ Graphics 5100, and Intel® Iris™ Pro Graphics 5200 (in 4nd Generation Intel®
-- initialization:
utils = require 'mp.utils'
excerpt_begin = 0.0
excerpt_end = mp.get_property_native("length")
if excerpt_end == nil or excerpt_end == "none" then
excerpt_end = 0.0
end
mp.set_property("hr-seek-framedrop","no")
mp.set_property("options/keep-open","always")
function excerpt_on_eof()
-- pause upon reaching the end of the file
mp.msg.log("info", "playback reached end of file")
mp.set_property("pause","yes")
mp.commandv("seek", 100, "absolute-percent", "exact")
end
mp.register_event("eof-reached", excerpt_on_eof)
-- check if intel board is vaapi compatible
function excerpt_check_intel_board( installed_gpus_string )
if not string.find(installed_gpus_string, "intel") then
mp.msg.log("info", "No Intel board")
return false
end
if string.find(installed_gpus_string, "x4500") or
string.find(installed_gpus_string, "x2000") or
string.find(installed_gpus_string, "x2500") or
string.find(installed_gpus_string, "x3000") or
string.find(installed_gpus_string, "x4000") or
string.find(installed_gpus_string, "x4200") or
string.find(installed_gpus_string, "x4400") or
string.find(installed_gpus_string, "x4600") or
string.find(installed_gpus_string, "x5000") or
string.find(installed_gpus_string, "x5100") or
string.find(installed_gpus_string, "x5200") then
mp.msg.log("info", "Intel board vaapi capable")
return true
end
return false
end
-- range marking
function excerpt_mark_begin_handler()
pt = mp.get_property_native("playback-time")
if pt == nil or pt == "none" then
pt = 0.0
end
local all_chapters = mp.get_property_native("chapter-list")
-- table.remove(all_chapters,2) -- TODO find an elegant way to do this without breaking on different lua versions
all_chapters[1] = {
title = "in",
time = pt
}
mp.set_property_native("chapter-list", all_chapters)
excerpt_begin = pt
if excerpt_begin > excerpt_end then
excerpt_end = excerpt_begin
end
local message = "IN point set."
mp.msg.log("info", message)
mp.osd_message(message, 5)
-- alas, the following setting seems to not take effect - needs
-- to be specified on the command line of mpv, instead:
mp.set_property("options/script-opts","osc-layout=bottombar,osc-hidetimeout=120000")
end
function excerpt_mark_end_handler()
pt = mp.get_property_native("playback-time")
if pt == nil or pt == "none" then
pt = 0.0
end
local all_chapters = mp.get_property_native("chapter-list")
all_chapters[2] = {
title = "out",
time = pt
}
mp.set_property_native("chapter-list", all_chapters)
excerpt_end = pt
if excerpt_end < excerpt_begin then
excerpt_begin = excerpt_end
end
local message = "OUT point set."
mp.msg.log("info", message)
mp.osd_message(message, 5)
end
-- writing
srcname = ""
srcpath = ""
srcext = ""
installed_gpus = ""
encoding = true
ffmpeg_profiles = {}
export_profile_idx = 1
function get_destination_filename()
srcname = mp.get_property_native("filename")
local srcnamene = mp.get_property_native("filename/no-ext")
local ext_length = string.len(srcname) - string.len(srcnamene)
srcext = string.sub(srcname, -ext_length)
local name_length = string.len(tostring(srcname))
srcpath = tostring(mp.get_property_native("path")) -- string.sub(tostring(mp.get_property_native("path")), name_length)
return tostring(srcpath .. ".excerpt_" .. excerpt_begin .. "-" .. excerpt_end)
end
function excerpt_encoding_toggle_handler()
export_profile_idx = (export_profile_idx % #ffmpeg_profiles) + 1
mp.osd_message("Export profile: " .. ffmpeg_profiles[export_profile_idx][1], 3)
end
function excerpt_write_handler()
if excerpt_begin == excerpt_end then
message = "excerpt_write: not writing because begin == end == " .. excerpt_begin
mp.osd_message(message, 3)
return
end
dstname = get_destination_filename()
duration = excerpt_end - excerpt_begin
if (dstname == "") then
-- file name creation has failed
return
end
local message = ""
message = message .. "writing to destination file '" .. dstname .. "'" .. "\nPlease wait..."
mp.msg.log("info", message)
mp.osd_message(message, 60)
local cmd = {}
cmd["cancellable"] = false
cmd["args"] = {}
table.insert(cmd["args"], "ffmpeg")
-- try to enable HW acceleration if user selected a GPU profile
if string.find(ffmpeg_profiles[export_profile_idx][1], "GPU") then
-- enable HW acceleration only if supported
if string.find(installed_gpus, "nvidia") then
table.insert(cmd["args"], "-hwaccel")
table.insert(cmd["args"], "cuda")
table.insert(cmd["args"], "-hwaccel_output_format")
table.insert(cmd["args"], "cuda")
elseif excerpt_check_intel_board(installed_gpus) then
table.insert(cmd["args"], "-hwaccel")
table.insert(cmd["args"], "vaapi")
table.insert(cmd["args"], "-hwaccel_output_format")
table.insert(cmd["args"], "vaapi")
table.insert(cmd["args"], "-vaapi_device")
table.insert(cmd["args"], "/dev/dri/renderD128")
end
end
-- set input file and cut options
table.insert(cmd["args"], "-i")
table.insert(cmd["args"], tostring(srcpath))
table.insert(cmd["args"], "-ss")
table.insert(cmd["args"], tostring(excerpt_begin))
table.insert(cmd["args"], "-t")
table.insert(cmd["args"], tostring(duration))
-- set encoding parameters
for k, v in ipairs(ffmpeg_profiles[export_profile_idx]) do
if k == 1 then
-- mp.osd_message("Exporting with profile: " .. v, 1)
else
table.insert(cmd["args"], v)
end
end
-- preserve original extension if user specified "." or apply user provided extension.
local dstext_idx = #ffmpeg_profiles[export_profile_idx]
local dstext = ffmpeg_profiles[export_profile_idx][dstext_idx]
if dstext == "." then
cmd["args"][#cmd["args"]] = dstname .. srcext
else
cmd["args"][#cmd["args"]] = dstname .. dstext
end
local res = utils.subprocess(cmd)
if (res["status"] ~= 0) then
message = message .. "failed!\nfailed to run excerpt - status = " .. res["status"]
if (res["error"] ~= nil) then
message = message .. ", error message: " .. res["error"]
end
mp.msg.log("error", message)
mp.osd_message(message, 10)
else
mp.msg.log("info", "excerpt '" .. dstname .. "' written.")
message = message .. "\n DONE!"
mp.osd_message(message, 10)
end
end
-- things to do whenever a new file was loaded:
function os.capture(cmd, raw)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
if raw then return s end
s = string.gsub(s, '^%s+', '')
s = string.gsub(s, '%s+$', '')
s = string.gsub(s, '[\n\r]+', ' ')
return s
end
function excerpt_on_loaded()
mp.osd_message("excerpt: use i and o to set IN and OUT points.", 3)
local operating_system = string.lower(os.capture("uname"))
installed_gpus = string.lower(os.capture("lspci -k | grep -E 'VGA|3D|Display'"))
-- Set GPU profiles
if operating_system == "darwin" then
table.insert(ffmpeg_profiles, {"ACCURATE (MacOS GPU)", "-c:v", "h264_videotoolbox", "-b:v", "10000k", "-c:a", "aac", ".mp4"})
else
if string.find(installed_gpus, "nvidia") then
table.insert(ffmpeg_profiles, {"ACCURATE (NVIDIA GPU)", "-c:v", "h264_nvenc", "-preset", "slow", "-c:a", "aac", ".mp4"})
elseif excerpt_check_intel_board(installed_gpus) then
table.insert(ffmpeg_profiles, {"ACCURATE (INTEL GPU)", "-vf", "'format=nv12,hwupload'", "-c:v", "h264_vaapi", "-qp", "25", "-c:a", "aac", ".mp4"})
end
end
-- ADD YOUR EXPORT PROFILES HERE
table.insert(ffmpeg_profiles, {"ACCURATE (CPU)", "-c:v", "libx264", "-crf", "23", "-c:a", "aac", ".mp4"})
table.insert(ffmpeg_profiles, {"FAST", "-c:v", "copy", "-c:a", "copy", "."})
end
mp.register_event("file-loaded", excerpt_on_loaded)
-- key bindings
mp.add_key_binding("i", "excerpt_mark_begin", excerpt_mark_begin_handler)
mp.add_key_binding("o", "excerpt_mark_end", excerpt_mark_end_handler)
mp.add_key_binding("shift+E", "excerpt_encoding_toggle", excerpt_encoding_toggle_handler)
mp.add_key_binding("x", "excerpt_write", excerpt_write_handler)