@@ -157,6 +157,20 @@ fn escape_concat_path(p: &str) -> String {
157157 p. replace ( '\'' , r"'\''" )
158158}
159159
160+ fn normalize_concat_path ( path : & str ) -> String {
161+ if cfg ! ( windows) {
162+ let mut normalized = path. to_string ( ) ;
163+ if let Some ( rest) = normalized. strip_prefix ( r"\\?\UNC\" ) {
164+ normalized = format ! ( r"\\{}" , rest) ;
165+ } else if let Some ( rest) = normalized. strip_prefix ( r"\\?\" ) {
166+ normalized = rest. to_string ( ) ;
167+ }
168+ normalized. replace ( '\\' , "/" )
169+ } else {
170+ path. to_string ( )
171+ }
172+ }
173+
160174pub async fn concat_segments_mp4 (
161175 segments : Vec < PathBuf > ,
162176 output_path : & Path ,
@@ -166,13 +180,22 @@ pub async fn concat_segments_mp4(
166180 }
167181
168182 let list_path = output_path. with_extension ( "segments.txt" ) ;
183+ let list_dir = list_path. parent ( ) . unwrap_or_else ( || Path :: new ( "." ) ) ;
184+ let list_dir_abs = tokio:: task:: spawn_blocking ( {
185+ let list_dir = list_dir. to_path_buf ( ) ;
186+ move || std:: fs:: canonicalize ( & list_dir) . unwrap_or ( list_dir)
187+ } )
188+ . await ?;
169189
170190 let mut lines = String :: new ( ) ;
171191 for seg in segments {
172- let abs = tokio:: task:: spawn_blocking ( move || std:: fs:: canonicalize ( seg) )
173- . await ??
174- . to_string_lossy ( )
175- . to_string ( ) ;
192+ let abs_path = tokio:: task:: spawn_blocking ( move || std:: fs:: canonicalize ( seg) )
193+ . await ??;
194+ let rel_path = match abs_path. strip_prefix ( & list_dir_abs) {
195+ Ok ( rel) => rel. to_path_buf ( ) ,
196+ Err ( _) => abs_path,
197+ } ;
198+ let abs = normalize_concat_path ( rel_path. to_string_lossy ( ) . as_ref ( ) ) ;
176199
177200 lines. push_str ( "file '" ) ;
178201 lines. push_str ( & escape_concat_path ( & abs) ) ;
0 commit comments