|
local assdraw = require 'mp.assdraw' |
|
local msg = require 'mp.msg' |
|
local opt = require 'mp.options' |
|
local utils = require 'mp.utils' |
|
|
|
-- default options, convert_script.conf is read |
|
local options = { |
|
bitrate_multiplier = 0.975, -- to make sure the file won’t go over the target file size, set it to 1 if you don’t care |
|
output_directory = "$HOME", |
|
use_pwd_instead = false, -- overrides output_directory |
|
use_same_dir = false, -- puts the output files where the original video was |
|
libvpx_threads = 4, -- libvpx only |
|
crop_individually = true, |
|
libvpx_options = "--ovcopts-add=cpu-used=0,auto-alt-ref=1,lag-in-frames=25,quality=good", |
|
libvpx_vp9_options = "", |
|
legacy_yad = false, -- if you don’t want to upgrade to at least yad 0.18 |
|
libvpx_fps = "--oautofps", -- --ofps=24000/1001 for example |
|
audio_bitrate = 112, -- mpv default, in kbps |
|
} |
|
|
|
read_options(options, "convert_script") |
|
options.output_directory = '"' .. options.output_directory .. '"' |
|
yad_table = {} |
|
|
|
------------------------------------- |
|
-- Rectangle selection and drawing -- |
|
------------------------------------- |
|
|
|
alpha = 180 |
|
rect_x1, rect_x2, rect_y1, rect_y2 = 0, 0, 0, 0 |
|
|
|
function render() |
|
|
|
ass = assdraw.ass_new() |
|
ass:draw_start() |
|
ass:append(string.format("{\\1a&H%X&}", alpha)) |
|
ass:rect_cw(rect_x1, rect_y1, rect_x2, rect_y2) |
|
ass:pos(0, 0) |
|
ass:draw_stop() |
|
mp.set_osd_ass(width, height, ass.text) |
|
|
|
end |
|
|
|
|
|
function tick() |
|
|
|
if set_mouse_area then |
|
mp.set_mouse_area(0, 0, width, height, "draw_rectangle") |
|
end |
|
|
|
end |
|
|
|
|
|
|
|
function rect_button_press_event(mouse, event) |
|
|
|
if event == "down" then |
|
|
|
rect_x1, rect_y1 = mp.get_mouse_pos() |
|
rect_x2, rect_y2 = rect_x1, rect_y1 |
|
button_pressed = true |
|
|
|
elseif event == "up" then |
|
|
|
button_pressed = nil |
|
if (rect_x1 == rect_x2) and (rect_y1 == rect_y2) then |
|
mp.set_osd_ass(width, height, "") |
|
end |
|
|
|
if rect_x2 > rect_x1 then |
|
rect_width = rect_x2 - rect_x1 |
|
else |
|
rect_width = rect_x1 -rect_x2 |
|
rect_x1 = rect_x2 |
|
end |
|
if rect_y2 > rect_y1 then |
|
rect_height = rect_y2 - rect_y1 |
|
else |
|
rect_height = rect_y1 -rect_y2 |
|
rect_y1 = rect_y2 |
|
end |
|
if rect_x1 < 0 then |
|
rect_x1 = 0 |
|
end |
|
if rect_y1 < 0 then |
|
rect_y1 = 0 |
|
end |
|
if (rect_width + rect_x1) >= tonumber(width) then |
|
rect_width = width - rect_x1 |
|
end |
|
if (rect_height + rect_y1) >= tonumber(height) then |
|
rect_height = height - rect_y1 |
|
end |
|
call_gui() |
|
|
|
end |
|
end |
|
|
|
|
|
function mouse_move() |
|
|
|
if button_pressed then |
|
rect_x2, rect_y2 = mp.get_mouse_pos() |
|
render() |
|
end |
|
|
|
end |
|
|
|
|
|
|
|
----------------- |
|
-- Main script -- |
|
----------------- |
|
|
|
function convert_script_hotkey_call () |
|
|
|
if mp.get_property("playback-time") then |
|
playback_time = "playback-time" |
|
else |
|
playback_time = "time-pos" |
|
end |
|
|
|
set_mouse_area = true |
|
width = mp.get_property("dwidth") |
|
height = mp.get_property("dheight") |
|
mp.set_osd_ass(width, height, "") |
|
|
|
if timepos1 then |
|
|
|
timepos2 = mp.get_property_native(playback_time) |
|
timepos2_humanreadable = mp.get_property_osd(playback_time) |
|
|
|
if tonumber(timepos1) > tonumber(timepos2) then |
|
|
|
length = timepos1-timepos2 |
|
start = timepos2 |
|
start_humanreadable = timepos2_humanreadable |
|
end_humanreadable = timepos1_humanreadable |
|
msg.info("End frame set") |
|
|
|
elseif tonumber(timepos2) > tonumber(timepos1) then |
|
|
|
length = timepos2-timepos1 |
|
start = timepos1 |
|
start_humanreadable = timepos1_humanreadable |
|
end_humanreadable = timepos2_humanreadable |
|
msg.info("End frame set") |
|
|
|
else |
|
|
|
msg.error("Both frames are the same, ignoring the second one") |
|
mp.osd_message("Both frames are the same, ignoring the second one") |
|
timepos2 = nil |
|
return |
|
|
|
end |
|
|
|
timepos1 = nil |
|
call_gui() |
|
|
|
else |
|
|
|
timepos1 = mp.get_property_native(playback_time) |
|
timepos1_humanreadable = mp.get_property_osd(playback_time) |
|
msg.info("Start frame set") |
|
mp.osd_message("Start frame set") |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
------------ |
|
-- Encode -- |
|
------------ |
|
|
|
function preparations() |
|
|
|
video = mp.get_property("path") |
|
video = string.gsub(video, "'", "'\\''") |
|
|
|
if options.use_pwd_instead then |
|
|
|
local pwd = os.getenv("PWD") |
|
pwd = string.gsub(pwd, "'", "'\\''") |
|
options.output_directory = "'" .. pwd .. "'" |
|
|
|
end |
|
if options.use_same_dir then |
|
options.output_directory = "'" .. utils.split_path(video) .. "'" |
|
end |
|
|
|
local filename_ext = mp.get_property_osd("media-title") |
|
filename_ext = string.gsub(filename_ext, "'", "'\\''") |
|
local filename = string.gsub(filename_ext, "%....$","") |
|
metadata_title = filename |
|
|
|
if string.len(filename) > 230 then |
|
|
|
filename = mp.get_property("options/title") |
|
if filename == 'mpv - ${media-title}' or string.len(filename) > 230 then |
|
filename = 'output' |
|
end |
|
|
|
end |
|
|
|
filename = filename .. " " .. start_humanreadable .. "-" .. end_humanreadable .. extension |
|
filename = string.gsub(filename, ":", ".") |
|
full_output_path = options.output_directory .. "/'" .. filename .. "'" |
|
|
|
end |
|
|
|
function encode(enc) |
|
|
|
set_mouse_area = nil |
|
if rect_width == nil or rect_width == 0 then |
|
crop = "" |
|
if not aspect_first then |
|
aspect_first = mp.get_property_native("video-params/aspect") |
|
end |
|
else |
|
-- odd numbers for video resolution are a bad idea |
|
rect_width = round(rect_width) - (math.fmod(round(rect_width), 2)) |
|
rect_height = round(rect_height) - (math.fmod(round(rect_height), 2)) |
|
crop = rect_width .. ":" .. rect_height .. ":" .. round(rect_x1) .. ":" .. round(rect_y1) |
|
if not aspect_first then |
|
aspect_first = rect_width / rect_height |
|
width_first = rect_width |
|
height_first = rect_height |
|
if not no_scale then |
|
if scale_width then |
|
width_first = scale |
|
else |
|
height_first = scale |
|
end |
|
end |
|
end |
|
rect_width, rect_height = nil |
|
end |
|
|
|
local sid = mp.get_property("sid") |
|
local sub_visibility = mp.get_property("sub-visibility") |
|
local aid = "" |
|
aid = " --aid=" .. mp.get_property("aid") |
|
local af = mp.get_property("af") |
|
local vf = mp.get_property("vf") |
|
if string.len(vf) > 0 then |
|
vf = vf .. "," |
|
end |
|
local sub_file_table = mp.get_property_native("options/sub-file") |
|
local sub_file = "" |
|
for index, param in pairs(sub_file_table) do |
|
sub_file = sub_file .. " --sub-file='" .. string.gsub(tostring(param), "'", "'\\''") .. "'" |
|
end |
|
local audio_file_table = mp.get_property_native("options/audio-file") |
|
local audio_file = "" |
|
for index, param in pairs(audio_file_table) do |
|
audio_file = audio_file .. " --audio-file='" .. string.gsub(tostring(param), "'", "'\\''") .. "'" |
|
end |
|
if mp.get_property_native("mute") then |
|
audio_file = "" |
|
aid = "" |
|
audio = "--no-audio" |
|
end |
|
local sub_auto = mp.get_property("options/sub-auto") |
|
local sub_delay = mp.get_property("sub-delay") |
|
local hr_seek_demuxer_offset = mp.get_property_native("options/hr-seek-demuxer-offset") |
|
|
|
preparations() |
|
|
|
if options.crop_individually then |
|
vf = vf .. 'sub,crop=' .. crop .. ',scale=SCALE…VAR' |
|
else |
|
vf = vf .. 'sub,crop=CROP…VAR,scale=SCALE…VAR' |
|
end |
|
|
|
local mpv_options = "'" .. video .. "' --start=+" .. start .. ' --length=' .. length |
|
.. ' ' .. sub_file .. ' --sid=' .. sid .. ' --sub-visibility=' .. sub_visibility |
|
.. ' --sub-delay=' .. sub_delay .. ' --sub-auto=' .. sub_auto .. aid |
|
.. ' --vf-add=' .. vf .. ' --hr-seek-demuxer-offset=' .. hr_seek_demuxer_offset |
|
.. ' --af=' .. af .. ' ' .. audio_file |
|
|
|
if not (ovc == "gif") then |
|
ovc_c = ' --ovc=' .. ovc |
|
else |
|
ovc_c = ' ' |
|
end |
|
local encode_options = ' ' .. ovc_c |
|
if ovc == "libvpx" or ovc == "libvpx-vp9" then |
|
encode_options = encode_options .. ' ' .. options.libvpx_fps .. ' --ovcopts-add=threads=' .. options.libvpx_threads .. ' ' |
|
if ovc == "libvpx" then |
|
encode_options = encode_options .. options.libvpx_options |
|
else |
|
encode_options = encode_options .. options.libvpx_vp9_options |
|
--libvpx-vp9 produces slightly bigger files |
|
if bitrate then |
|
bitrate = bitrate * 0.93 |
|
end |
|
end |
|
|
|
|
|
end |
|
if twopass then |
|
encode_options = encode_options .. ' --ovcopts-add=b=' .. bitrate |
|
else |
|
if not (ovc == "gif") then |
|
encode_options = encode_options .. ' --ovcopts-add=crf=' .. tostring(crf) |
|
end |
|
if ovc == "libvpx" or ovc == "libvpx-vp9" then |
|
encode_options = encode_options .. ' --ovcopts-add=b=10000000' |
|
end |
|
end |
|
|
|
if advanced then |
|
encode_options = ' ' .. advanced_output .. advanced_encode |
|
end |
|
|
|
if not segments then |
|
segments = "" |
|
segment_count = 0 |
|
end |
|
segment_count = segment_count + 1 |
|
|
|
segments = segments .. " --\\{ " .. mpv_options .. " --\\}" |
|
|
|
local full_command = '( mpv' .. segments |
|
if twopass then |
|
encode_options = encode_options .. ' --ovcopts-add=flags=+pass' |
|
full_command = full_command .. ' --no-audio ' .. encode_options .. '1' |
|
end |
|
if ovc == "gif" then |
|
local handle = io.popen("mktemp -d") |
|
tmpfolder = handle:read("*a") |
|
handle:close() |
|
tmpfolder = string.gsub(tmpfolder, '\n', '') |
|
encode_options = encode_options .. ' --no-keep-open --vo=image:format=png:outdir=' .. tmpfolder |
|
else |
|
full_command = full_command .. ' --o=' .. full_output_path |
|
end |
|
if twopass then |
|
full_command = full_command .. ' && mpv' .. segments .. ' ' .. audio .. ' ' .. encode_options .. '2' |
|
.. ' --o=' .. full_output_path |
|
.. ' && rm ' .. full_output_path .. '-vo-lavc-pass1.log' |
|
else |
|
full_command = full_command .. ' ' .. audio .. ' ' .. encode_options |
|
end |
|
|
|
if not framestep then |
|
framestep = 1 |
|
dither = "+dither" |
|
fuzz = "1%" |
|
end |
|
local delay = framestep * 4 |
|
if ovc == "gif" then |
|
full_command = full_command .. ' --vf-add=lavfi=graph=\\"framestep=' .. framestep .. '\\" && convert ' |
|
.. tmpfolder .. '/*.png -set delay ' .. delay .. ' -loop 0 -fuzz ' .. fuzz .. '% ' .. dither .. ' -layers optimize ' |
|
.. full_output_path .. ' && rm -rf ' .. tmpfolder .. ' && notify-send "Gif done") & disown' |
|
else |
|
full_command = full_command .. ' && notify-send "Encoding done"; mkvpropedit ' |
|
.. full_output_path .. ' -s title="' .. metadata_title .. '") & disown' |
|
end |
|
|
|
|
|
if enc then |
|
|
|
-- mpv parses --{ --} last and --no-audio gets overwritten by --aid, so remove them |
|
if audio == "--no-audio" then |
|
full_command = string.gsub(full_command, "--aid=%d* ", " ") |
|
end |
|
local dwidth, dheight = mp.get_property_native("dwidth"), mp.get_property_native("dheight") |
|
|
|
if width_first then |
|
if scale_width then |
|
scale = width_first |
|
else |
|
scale = height_first |
|
end |
|
end |
|
|
|
if scale_width then |
|
local scale_2 = round(scale / aspect_first) |
|
scale = scale .. ":" .. (scale_2 - (math.fmod(scale_2, 2))) |
|
else |
|
local scale_2 = round(scale * aspect_first) |
|
scale = (scale_2 - math.fmod(scale_2, 2)) .. ":" .. scale |
|
end |
|
if no_scale and not width_first then |
|
scale = dwidth .. ":" .. dheight |
|
end |
|
|
|
full_command = string.gsub(full_command, "CROP…VAR", crop) |
|
full_command = string.gsub(full_command, "SCALE…VAR", scale) |
|
msg.info(full_command) |
|
os.execute(full_command) |
|
clear() |
|
|
|
end |
|
end |
|
|
|
function encode_copy(enc) |
|
|
|
preparations() |
|
if not mkvmerge_parts then |
|
mkvmerge_parts = "--split parts:" |
|
sep = "" |
|
end |
|
|
|
mkvmerge_parts = mkvmerge_parts .. sep .. math.floor(start) .. "s-" .. math.ceil(start + length) .. "s" |
|
sep = ",+" |
|
|
|
if enc then |
|
local command = "mkvmerge '" .. video .. "' " .. mkvmerge_parts .. " -o " .. full_output_path |
|
msg.info(command) |
|
os.execute(command) |
|
clear() |
|
end |
|
|
|
end |
|
|
|
function clear() |
|
|
|
mkvmerge_parts = nil |
|
aspect_first = nil |
|
height_first = nil |
|
width_first = nil |
|
sep = nil |
|
segments = nil |
|
segments_length = 0 |
|
|
|
end |
|
|
|
--------- |
|
-- GUI -- |
|
--------- |
|
|
|
function call_gui () |
|
|
|
mp.disable_key_bindings("draw_rectangle") |
|
mp.resume_all() |
|
extension = "" |
|
local factor = 1024 |
|
local format_dropdown_content |
|
local mode_dropdown_content |
|
local resize_to_width_instead |
|
local include_audio |
|
local yad_offset_10 = 0 |
|
|
|
if not scale_sav then |
|
scale_sav = 540 |
|
end |
|
if not yad_table[5] then |
|
yad_table[5] = "" |
|
end |
|
|
|
if not options.legacy_yad then |
|
|
|
if yad_table[5]:find("(MiB)") then |
|
mode_dropdown_content = "'Target file size (KiB)!^Target file size (MiB)!CRF'" |
|
elseif yad_table[5]:find("(KiB)") then |
|
mode_dropdown_content = "'^Target file size (KiB)!Target file size (MiB)!CRF'" |
|
elseif yad_table[5]:find("CRF") then |
|
mode_dropdown_content = "'Target file size (KiB)!Target file size (MiB)!^CRF'" |
|
else |
|
mode_dropdown_content = "'^Target file size (KiB)!Target file size (MiB)!CRF'" |
|
end |
|
|
|
if yad_table[7] == "vp8/webm" then |
|
format_dropdown_content = "'^vp8/webm!vp9/webm!h264/mkv!h264/mp4!h265/mkv!gif!stream copy/mkv'" |
|
elseif yad_table[7] == "vp9/webm" then |
|
format_dropdown_content = "'vp8/webm!^vp9/webm!h264/mkv!h264/mp4!h265/mkv!gif!stream copy/mkv'" |
|
elseif yad_table[7] == "h264/mkv" then |
|
format_dropdown_content = "'vp8/webm!vp9/webm!^h264/mkv!h264/mp4!h265/mkv!gif!stream copy/mkv'" |
|
elseif yad_table[7] == "h264/mp4" then |
|
format_dropdown_content = "'vp8/webm!vp9/webm!h264/mkv!^h264/mp4!h265/mkv!gif!stream copy/mkv'" |
|
elseif yad_table[7] == "h265/mkv" then |
|
format_dropdown_content = "'vp8/webm!vp9/webm!h264/mkv!h264/mp4!^h265/mkv!gif!stream copy/mkv'" |
|
elseif yad_table[7] == "gif" then |
|
format_dropdown_content = "'vp8/webm!vp9/webm!h264/mkv!h264/mp4!h265/mkv!^gif!stream copy/mkv'" |
|
elseif yad_table[7] == "stream copy/mkv" then |
|
format_dropdown_content = "'vp8/webm!vp9/webm!h264/mkv!h264/mp4!h265/mkv!gif!^stream copy/mkv'" |
|
else |
|
format_dropdown_content = "'^vp8/webm!vp9/webm!h264/mkv!h264/mp4!h265/mkv!gif!stream copy/mkv'" |
|
end |
|
|
|
else |
|
mode_dropdown_content = "'Target file size (KiB)!Target file size (MiB)!CRF'" |
|
format_dropdown_content = "'vp8/webm!vp9/webm!h264/mkv!h264/mp4!h265/mkv!gif!stream copy/mkv'" |
|
yad_offset_10 = -2 |
|
end |
|
|
|
|
|
|
|
|
|
if (yad_table[2] == "TRUE") then |
|
resize_to_width_instead = '"true"' |
|
else |
|
resize_to_width_instead = '"false"' |
|
end |
|
|
|
if (yad_table[4] == "TRUE") then |
|
include_audio = '"true"' |
|
else |
|
include_audio = '"false"' |
|
end |
|
|
|
if (not yad_table[6]) then |
|
yad_table[6] = '"3072"' |
|
end |
|
|
|
|
|
local yad_command = [[LC_NUMERIC=C yad --title="Convert Script" --center --form --fixed --always-print-result \ |
|
--name "convert script" --class "Convert Script" --field="Resize to height:NUM" "]] .. scale_sav --yad_table 1 |
|
.. [[" --field="Resize to width instead:CHK" ]] .. resize_to_width_instead .. " " --yad_table 2 |
|
if options.legacy_yad then |
|
yad_command = yad_command .. [[--field="Don't resize at all:CHK" "false" ]] |
|
else |
|
yad_command = yad_command |
|
.. [[--field="Don't resize at all:BTN" "@bash -c 'if ]] .. '[[ "a%1" == "a0.000000" ]]' |
|
.. [[; then printf '\''1:1\n2:false'\''; else printf '\''1:0.000000\n1:@disabled@\n2:@disabled@'\''; fi'" ]] |
|
end |
|
yad_command = yad_command .. '--field="Include audio:CHK" ' .. include_audio .. ' ' --yad_table 4 |
|
|
|
if yad_ret then |
|
yad_command = yad_command |
|
.. [[--field="2pass:CHK" "false" ]] --yad_table 5 |
|
.. [[--field="Encode options::CBE" '! --ovcopts=b=2000,cpu-used=0,auto-alt-ref=1,lag-in-frames=25,quality=good,threads=4' ]] --yad_table 6 |
|
.. [[--field="Output format::CBE" ' --ovc=libx264! --oautofps --of=webm --ovc=libvpx' ]] |
|
.. [[--field="Simple:FBTN" 'bash -c "echo \"simple\" && kill -s SIGUSR1 \"$YAD_PID\""' ]] |
|
advanced = true |
|
else |
|
yad_command = yad_command |
|
.. '--field="Mode::CB" ' .. mode_dropdown_content --yad_table 5 |
|
.. ' --field="Value::NUM" ' .. yad_table[6] --yad_table 6 |
|
.. ' --field="Output format::CB" ' .. format_dropdown_content --yad_table 7 |
|
if not options.legacy_yad then |
|
yad_command = yad_command .. [[ --field="Advanced:FBTN" 'bash -c "echo \"advanced\" && kill -s SIGUSR1 \"$YAD_PID\""' ]] |
|
end |
|
end |
|
if not options.legacy_yad then |
|
yad_command = yad_command |
|
.. [[--field="Append another segment:FBTN" 'bash -c "echo \"append\" && kill -s SIGUSR1 \"$YAD_PID\""' ]] |
|
end |
|
yad_command = yad_command .. [[ --button="Crop:1" --button="gtk-cancel:2" --button="gtk-ok:0"; ret=$? && echo $ret]] |
|
|
|
if gif_dialog then |
|
yad_command = [[echo $(LC_NUMERIC=C yad --title="Gif settings" --name "convert script" --class "Convert Script" \ |
|
--center --form --always-print-result --separator="…" \ |
|
--field="Fuzz Factor:NUM" '1!0..100!0.5!1' \ |
|
--field="Framestep:NUM" '3!1..3!1' \ |
|
--field="Dither:CB" 'None!E-Dither!Ordered Dither' \ |
|
--button="Ok:0")]] |
|
end |
|
|
|
local handle = io.popen(yad_command) |
|
local yad = handle:read("*a") |
|
handle:close() |
|
if yad == "127\n" then |
|
msg.error("Error: Cannot find yad!") |
|
mp.osd_message("Error: Cannot find yad!") |
|
return |
|
end |
|
yad_table = {} |
|
local function helper(line) table.insert(yad_table, line) return "" end |
|
helper((yad:gsub("(.-)|", helper))) |
|
for i, e in pairs(yad_table) do |
|
msg.debug(i .. " → " .. e) |
|
end |
|
|
|
if not gif_dialog then |
|
|
|
yad_ret = tonumber(yad_table[10+yad_offset_10]) |
|
if yad_table[1]:find("append") then |
|
yad_table[1] = string.gsub(yad_table[1], "append\n", "") |
|
yad_ret = -1 |
|
end |
|
if yad_table[1]:find("advanced") then |
|
yad_table[1] = string.gsub(yad_table[1], "advanced\n", "") |
|
yad_ret = -2 |
|
if yad_table[7]:find("gif") then |
|
gif_dialog = true |
|
end |
|
end |
|
if yad_table[1]:find("simple") then |
|
yad_table[1] = string.gsub(yad_table[1], "simple\n", "") |
|
yad_ret = -2 |
|
end |
|
|
|
scale = tonumber(yad_table[1]) - (math.fmod(tonumber(yad_table[1]), 2 )) |
|
scale_sav = scale |
|
if (yad_table[2] == "FALSE") and (tonumber(yad_table[1]) > 0) then |
|
scale_width = false |
|
no_scale = false |
|
elseif yad_table[1] == "0.000000" then |
|
no_scale = true |
|
else |
|
scale_width = true |
|
no_scale = false |
|
end |
|
if yad_table[3] == "TRUE" then |
|
no_scale = true |
|
end |
|
|
|
if yad_table[4] == "FALSE" then |
|
audio = "--no-audio" |
|
else |
|
audio = "" |
|
end |
|
|
|
if not segments_length then |
|
segments_length = 0 |
|
end |
|
|
|
segments_length = segments_length + length |
|
|
|
if (yad_table[5] == "TRUE") or yad_table[5]:find("Target") then |
|
twopass = true |
|
else |
|
twopass = false |
|
end |
|
|
|
if advanced then |
|
advanced_encode = yad_table[6] |
|
advanced_output = yad_table[7] |
|
yad_table[6] = '"3072"' |
|
else |
|
if yad_table[7]:find("webm") then |
|
extension = ".webm" |
|
elseif yad_table[7]:find("mkv") then |
|
extension = ".mkv" |
|
elseif yad_table[7]:find("mp4") then |
|
extension = ".mp4" |
|
end |
|
|
|
if yad_table[7]:find("h264") then |
|
ovc = "libx264" |
|
elseif yad_table[7]:find("h265") then |
|
ovc = "libx265" |
|
elseif yad_table[7]:find("vp8") then |
|
ovc = "libvpx" |
|
elseif yad_table[7]:find("vp9") then |
|
ovc = "libvpx-vp9" |
|
elseif yad_table[7]:find("gif") then |
|
ovc = "gif" |
|
extension = ".gif" |
|
twopass = false |
|
elseif yad_table[7]:find("stream copy") then |
|
ovc = "stream copy" |
|
end |
|
|
|
if yad_table[5]:find("(MiB)") then |
|
factor = 1048576 |
|
end |
|
if twopass then |
|
local total_bitrate = yad_table[6] * factor |
|
if audio == "" then |
|
total_bitrate = total_bitrate - ( options.audio_bitrate * 1000 * segments_length / 8 ) |
|
end |
|
bitrate = math.floor(total_bitrate*8/segments_length*options.bitrate_multiplier) |
|
else |
|
crf = yad_table[6] |
|
end |
|
|
|
end |
|
|
|
if yad_ret == 1 then |
|
mp.enable_key_bindings("draw_rectangle") |
|
yad_ret = nil |
|
return |
|
end |
|
|
|
else |
|
|
|
gif_dialog = nil |
|
helper((yad:gsub("(.-)…", helper))) |
|
fuzz = yad_table[2] |
|
framestep = yad_table[3] |
|
if yad_table[4] == "None" then |
|
dither = "+dither" |
|
elseif yad_table[4] == "Ordered Dither" then |
|
dither = "-ordered-dither o8x8,20" |
|
else |
|
dither = "" |
|
end |
|
yad_table[7] = "gif" |
|
|
|
end |
|
|
|
|
|
mp.set_osd_ass(width, height, "") |
|
|
|
if yad_ret == 0 then |
|
if ovc == "stream copy" then |
|
encode_copy(true) |
|
else |
|
encode(true) |
|
end |
|
elseif yad_ret == -1 then |
|
if ovc == "stream copy" then |
|
encode(false) |
|
encode_copy(false) |
|
else |
|
encode(false) |
|
encode_copy(false) |
|
end |
|
end |
|
|
|
if yad_ret == -2 then |
|
if advanced then |
|
advanced = false |
|
yad_ret = false |
|
end |
|
call_gui() |
|
end |
|
|
|
if yad_ret == 2 then |
|
clear() |
|
end |
|
yad_ret = nil |
|
advanced = nil |
|
|
|
end |
|
|
|
function round(n) |
|
return math.floor((math.floor(n*2) + 1)/2) |
|
end |
|
|
|
|
|
|
|
|
|
mp.set_key_bindings({ |
|
{"mouse_move", mouse_move}, |
|
{"mouse_btn0", function(e) rect_button_press_event("mouse_btn0", "up") end, function(e) rect_button_press_event("mouse_btn0", "down") end}, |
|
}, "draw_rectangle", "force") |
|
|
|
mp.add_key_binding("alt+w", "convert_script", convert_script_hotkey_call) |
|
|
|
mp.register_event("tick", tick) |
Encoding fails when playing a file with non-48 kHz audio (e.g. 44.1 kHz) and encoding to WebM with audio included:
[ffmpeg] libopus: Specified sample rate 44100 is not supported
(Note that the solution is not as simple as specifying
--oacopts-add=ar=48000
, you have to insert a resample filter e.g.--af=resample:srate=48000
)