@@ -10,8 +10,10 @@ VIDEO_INTERNAL_UPLOAD=${VIDEO_INTERNAL_UPLOAD:-$SE_VIDEO_INTERNAL_UPLOAD}
1010VIDEO_UPLOAD_BATCH_CHECK=${SE_VIDEO_UPLOAD_BATCH_CHECK:- " 10" }
1111UPLOAD_RETRY_MAX_ATTEMPTS=${SE_UPLOAD_RETRY_MAX_ATTEMPTS:- 3}
1212UPLOAD_RETRY_DELAY=${SE_UPLOAD_RETRY_DELAY:- 5}
13- UPLOAD_FILE_READY_WAIT=${SE_UPLOAD_FILE_READY_WAIT:- 1}
13+ UPLOAD_FILE_READY_WAIT=${SE_UPLOAD_FILE_READY_WAIT:- 3}
14+ UPLOAD_FILE_STABILITY_RETRIES=${SE_UPLOAD_FILE_STABILITY_RETRIES:- 5}
1415UPLOAD_VERIFY_CHECKSUM=${SE_UPLOAD_VERIFY_CHECKSUM:- " true" }
16+ UPLOAD_VALIDATE_MP4=${SE_UPLOAD_VALIDATE_MP4:- " true" }
1517ts_format=${SE_LOG_TIMESTAMP_FORMAT:- " %Y-%m-%d %H:%M:%S,%3N" }
1618process_name=" video.uploader"
1719
@@ -49,6 +51,36 @@ upload_success_count=0
4951upload_failed_count=0
5052graceful_exit_called=false
5153
54+ function validate_mp4_moov_atom() {
55+ local file=$1
56+
57+ if [[ " ${UPLOAD_VALIDATE_MP4} " != " true" ]]; then
58+ return 0
59+ fi
60+
61+ # Only validate MP4/M4V files
62+ if [[ ! " ${file} " =~ \. (mp4| m4v)$ ]]; then
63+ return 0
64+ fi
65+
66+ # Check if file has moov atom using ffmpeg probe
67+ local error_output=$( ffmpeg -v error -i " ${file} " -f null - 2>&1 )
68+
69+ if echo " ${error_output} " | grep -q " moov atom not found" ; then
70+ echo " $( date -u +" ${ts_format} " ) [${process_name} ] - ERROR: MP4 file missing moov atom: ${file} "
71+ return 1
72+ fi
73+
74+ # Quick validation: check if ffmpeg can read the file
75+ if ! ffmpeg -v error -i " ${file} " -t 0.1 -f null - 2> /dev/null; then
76+ echo " $( date -u +" ${ts_format} " ) [${process_name} ] - ERROR: MP4 file validation failed: ${file} "
77+ return 1
78+ fi
79+
80+ echo " $( date -u +" ${ts_format} " ) [${process_name} ] - MP4 validation passed: ${file} "
81+ return 0
82+ }
83+
5284function verify_file_ready() {
5385 local file=$1
5486
@@ -71,13 +103,44 @@ function verify_file_ready() {
71103 return 1
72104 fi
73105
74- # Wait for file to be stable (no longer being written)
75- local initial_size=${file_size}
76- sleep ${UPLOAD_FILE_READY_WAIT}
77- local final_size=$( stat -f%z " ${file} " 2> /dev/null || stat -c%s " ${file} " 2> /dev/null)
106+ # Wait for file to be stable (no longer being written) with retries
107+ echo " $( date -u +" ${ts_format} " ) [${process_name} ] - Waiting for file to stabilize: ${file} "
108+ local retry=0
109+ local stable=false
110+
111+ while [ ${retry} -lt ${UPLOAD_FILE_STABILITY_RETRIES} ]; do
112+ local initial_size=${file_size}
113+ sleep ${UPLOAD_FILE_READY_WAIT}
114+ local final_size=$( stat -f%z " ${file} " 2> /dev/null || stat -c%s " ${file} " 2> /dev/null)
115+
116+ if [ " ${initial_size} " = " ${final_size} " ]; then
117+ # Size is stable, force filesystem sync and verify again
118+ sync
119+ sleep 1
120+ local verify_size=$( stat -f%z " ${file} " 2> /dev/null || stat -c%s " ${file} " 2> /dev/null)
121+
122+ if [ " ${final_size} " = " ${verify_size} " ]; then
123+ stable=true
124+ echo " $( date -u +" ${ts_format} " ) [${process_name} ] - File size stable at ${final_size} bytes after ${retry} retries"
125+ break
126+ fi
127+ fi
128+
129+ retry=$(( retry + 1 ))
130+ file_size=${final_size}
131+
132+ if [ ${retry} -lt ${UPLOAD_FILE_STABILITY_RETRIES} ]; then
133+ echo " $( date -u +" ${ts_format} " ) [${process_name} ] - File size changed (${initial_size} -> ${final_size} ), waiting more (retry ${retry} /${UPLOAD_FILE_STABILITY_RETRIES} )"
134+ fi
135+ done
136+
137+ if [ " ${stable} " != " true" ]; then
138+ echo " $( date -u +" ${ts_format} " ) [${process_name} ] - WARNING: File did not stabilize after ${UPLOAD_FILE_STABILITY_RETRIES} retries: ${file} "
139+ return 1
140+ fi
78141
79- if [ " ${initial_size} " != " ${final_size} " ] ; then
80- echo " $( date -u + " ${ts_format} " ) [ ${process_name} ] - WARNING: File is still being written: ${ file} (size changed from ${initial_size} to ${final_size} ) "
142+ # Validate MP4 moov atom if enabled
143+ if ! validate_mp4_moov_atom " ${ file} " ; then
81144 return 1
82145 fi
83146
0 commit comments