Skip to content

Commit 1f895d3

Browse files
authored
Merge pull request #7 from f0e/feat/custom-join-paths
2 parents 4e80111 + 6f15843 commit 1f895d3

File tree

1 file changed

+79
-9
lines changed

1 file changed

+79
-9
lines changed

mpv-lossless-cut.lua

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,76 @@ local function to_hms(secs)
5656
return #str == 0 and "0" or table.concat(str, "")
5757
end
5858

59+
function join_paths(path1, path2)
60+
if not path1 or path1 == "" then
61+
return path2 or ""
62+
end
63+
if not path2 or path2 == "" then
64+
return path1
65+
end
66+
67+
local separator
68+
if os_name == "windows" then
69+
separator = "\\"
70+
else
71+
separator = "/"
72+
end
73+
74+
-- normalize separators in both paths
75+
path1 = path1:gsub("[/\\]", separator)
76+
path2 = path2:gsub("[/\\]", separator)
77+
78+
-- remove trailing separator from path1
79+
path1 = path1:gsub(separator == "\\" and "\\+$" or "/+$", "")
80+
81+
-- handle absolute path2 (starts with drive letter on Windows or / on Unix)
82+
if path2:match("^[A-Za-z]:") or path2:match("^" .. (separator == "\\" and "\\" or "/")) then
83+
return path2
84+
end
85+
86+
-- handle relative paths with .. and .
87+
local function resolve_path(base, relative)
88+
local parts = {}
89+
90+
-- split base path into parts
91+
local pattern = separator == "\\" and "[^\\\\]+" or "[^/]+"
92+
for part in base:gmatch(pattern) do
93+
table.insert(parts, part)
94+
end
95+
96+
-- process relative path parts
97+
for part in relative:gmatch(pattern) do
98+
if part == ".." then
99+
if #parts > 0 then
100+
table.remove(parts)
101+
end
102+
elseif part ~= "." then
103+
table.insert(parts, part)
104+
end
105+
end
106+
107+
-- reconstruct path
108+
local result = table.concat(parts, separator)
109+
110+
-- handle drive letters on Windows
111+
if base:match("^[A-Za-z]:") then
112+
local drive = base:match("^[A-Za-z]:")
113+
if not result:match("^[A-Za-z]:") then
114+
result = drive .. separator .. result
115+
end
116+
elseif
117+
base:match("^" .. (separator == "\\" and "\\\\" or "/"))
118+
and not result:match("^" .. (separator == "\\" and "\\\\" or "/"))
119+
then
120+
result = separator .. result
121+
end
122+
123+
return result
124+
end
125+
126+
return resolve_path(path1, path2)
127+
end
128+
59129
-- file operations
60130
local function ensure_directory_exists(dir)
61131
local dir_info = mp.utils.file_info(dir)
@@ -199,11 +269,11 @@ local function merge_cuts(temp_dir, filepaths, outpath, input_mtime)
199269
-- i hate that you have to do a separate command and render each cut separately first, i tried using
200270
-- filter_complex for merging with multiple inputs but it wouldn't let me. todo: look into this further
201271

202-
local merge_file = mp.utils.join_path(temp_dir, "merging.txt")
272+
local merge_file = join_paths(temp_dir, "merging.txt")
203273
local content = ""
204274

205275
for _, path in ipairs(filepaths) do
206-
content = content .. string.format("file '%s'\n", ffmpeg_escape_filepath(path))
276+
content = content .. string.format("file '%s'\n", ffmpeg_escape_filepath(path))
207277
end
208278

209279
local file = io.open(merge_file, "w")
@@ -283,12 +353,12 @@ local function cut_render()
283353

284354
local is_stream = input_info == nil
285355

286-
local cwd = mp.utils.getcwd()
287356
local outdir
288-
if options.output_dir == "." then
289-
outdir = cwd
357+
if options.output_dir == "@cwd" or is_stream then
358+
outdir = mp.utils.getcwd()
290359
else
291-
outdir = mp.utils.join_path(cwd, options.output_dir)
360+
input_dir = mp.utils.split_path(input)
361+
outdir = join_paths(input_dir, options.output_dir)
292362
end
293363

294364
-- create output directory if needed
@@ -300,7 +370,7 @@ local function cut_render()
300370
local filename_noext, ext = "", ""
301371
local cache_offset = 0
302372

303-
local temp_cache_file_name = mp.utils.join_path(outdir, "cache-dump.mkv")
373+
local temp_cache_file_name = join_paths(outdir, "cache-dump.mkv")
304374

305375
if not is_stream then
306376
filename_noext, ext = filename:match("^(.*)(%.[^%.]+)$")
@@ -344,7 +414,7 @@ local function cut_render()
344414
ext
345415
)
346416

347-
local cut_path = mp.utils.join_path(outdir, cut_name)
417+
local cut_path = join_paths(outdir, cut_name)
348418

349419
log(string.format("(%d/%d) Rendering cut to %s", i, #cuts, cut_path))
350420

@@ -361,7 +431,7 @@ local function cut_render()
361431
if #cut_paths > 1 and options.multi_cut_mode == "merge" then
362432
local merge_name = string.format("(%d merged cuts) %s%s", #cut_paths, filename_noext, ext)
363433

364-
local merge_path = mp.utils.join_path(outdir, merge_name)
434+
local merge_path = join_paths(outdir, merge_name)
365435

366436
log("Merging cuts...")
367437
local success = merge_cuts(cwd, cut_paths, merge_path, input_info.mtime)

0 commit comments

Comments
 (0)