@@ -25,6 +25,7 @@ use std::{
2525 path:: { Path , PathBuf } ,
2626 pin:: pin,
2727 str:: FromStr ,
28+ sync:: { Arc , Mutex , PoisonError } ,
2829 time:: Duration ,
2930} ;
3031use tauri:: { AppHandle , ipc:: Channel } ;
@@ -631,13 +632,15 @@ fn multipart_uploader(
631632
632633 stream:: once ( async move {
633634 let use_md5_hashes = app. is_server_url_custom ( ) . await ;
635+ let first_chunk_presigned_url = Arc :: new ( Mutex :: new ( None :: < ( String , Instant ) > ) ) ;
634636
635637 stream:: unfold (
636638 ( Box :: pin ( stream) , 1 ) ,
637639 move |( mut stream, expected_part_number) | {
638640 let app = app. clone ( ) ;
639641 let video_id = video_id. clone ( ) ;
640642 let upload_id = upload_id. clone ( ) ;
643+ let first_chunk_presigned_url = first_chunk_presigned_url. clone ( ) ;
641644
642645 async move {
643646 let ( Some ( item) , presigned_url) = join ( stream. next ( ) , async {
@@ -690,6 +693,16 @@ fn multipart_uploader(
690693 && ( part_number == expected_part_number || md5_sum. is_some ( ) )
691694 {
692695 url
696+ } else if part_number == 1
697+ // We have a presigned URL left around from the first chunk
698+ && let Some ( ( url, expiry) ) = first_chunk_presigned_url
699+ . lock ( )
700+ . unwrap_or_else ( PoisonError :: into_inner)
701+ . clone ( )
702+ // The URL hasn't expired
703+ && expiry. elapsed ( ) < Duration :: from_secs ( 60 * 50 )
704+ {
705+ url
693706 } else {
694707 api:: upload_multipart_presign_part (
695708 & app,
@@ -700,8 +713,17 @@ fn multipart_uploader(
700713 )
701714 . await ?
702715 } ;
703- let size = chunk. len ( ) ;
704716
717+ // We cache the presigned URL for the first chunk,
718+ // as for instant mode we upload the first chunk at the end again to include the updated video metadata.
719+ if part_number == 1 {
720+ * first_chunk_presigned_url
721+ . lock ( )
722+ . unwrap_or_else ( PoisonError :: into_inner) =
723+ Some ( ( presigned_url. clone ( ) , Instant :: now ( ) ) ) ;
724+ }
725+
726+ let size = chunk. len ( ) ;
705727 let url = Uri :: from_str ( & presigned_url) . map_err ( |err| {
706728 format ! ( "uploader/part/{part_number}/invalid_url: {err:?}" )
707729 } ) ?;
0 commit comments