Skip to content

Commit 6a788e2

Browse files
committed
Fix file recording broken
Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com>
1 parent 980e52d commit 6a788e2

File tree

2 files changed

+90
-12
lines changed

2 files changed

+90
-12
lines changed

Video/video.sh

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ max_attempts=${SE_VIDEO_WAIT_ATTEMPTS:-50}
1919
file_ready_max_attempts=${SE_VIDEO_FILE_READY_WAIT_ATTEMPTS:-5}
2020
wait_uploader_shutdown_max_attempts=${SE_VIDEO_WAIT_UPLOADER_SHUTDOWN_ATTEMPTS:-5}
2121
graceful_stop_delay=${SE_VIDEO_GRACEFUL_STOP_DELAY:-5}
22+
min_recording_duration=${SE_VIDEO_MIN_RECORDING_DURATION:-5}
23+
video_validation_enabled=${SE_VIDEO_VALIDATION_ENABLED:-"true"}
24+
video_fix_corrupted=${SE_VIDEO_FIX_CORRUPTED:-"true"}
2225
ts_format=${SE_LOG_TIMESTAMP_FORMAT:-"%Y-%m-%d %H:%M:%S,%3N"}
2326
process_name="video.recorder"
2427

@@ -187,12 +190,66 @@ function exit_on_max_session_reach() {
187190
fi
188191
}
189192

193+
function validate_mp4_file() {
194+
local video_file="$1"
195+
local session_id_param="$2"
196+
197+
if [[ "${video_validation_enabled}" != "true" ]]; then
198+
return 0
199+
fi
200+
201+
if [[ ! -f "${video_file}" ]]; then
202+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] ERROR: Video file does not exist: ${video_file}"
203+
return 1
204+
fi
205+
206+
# Check if file has moov atom using ffmpeg probe
207+
if ffmpeg -v error -i "${video_file}" -f null - 2>&1 | grep -q "moov atom not found"; then
208+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] ERROR: Video file missing moov atom: ${video_file}"
209+
return 1
210+
fi
211+
212+
# Quick validation: check if ffmpeg can read the file
213+
if ! ffmpeg -v error -i "${video_file}" -t 0.1 -f null - 2>/dev/null; then
214+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] ERROR: Video file validation failed: ${video_file}"
215+
return 1
216+
fi
217+
218+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Video file validation passed: ${video_file}"
219+
return 0
220+
}
221+
222+
function attempt_fix_mp4_file() {
223+
local video_file="$1"
224+
local session_id_param="$2"
225+
226+
if [[ "${video_fix_corrupted}" != "true" ]]; then
227+
return 1
228+
fi
229+
230+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Attempting to fix corrupted MP4 file: ${video_file}"
231+
232+
local temp_file="${video_file}.temp.mp4"
233+
234+
# Try to recover the file by remuxing with faststart
235+
if ffmpeg -v warning -i "${video_file}" -c copy -movflags +faststart "${temp_file}" 2>/dev/null; then
236+
mv "${temp_file}" "${video_file}"
237+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Successfully fixed MP4 file: ${video_file}"
238+
return 0
239+
else
240+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Failed to fix MP4 file: ${video_file}"
241+
rm -f "${temp_file}"
242+
return 1
243+
fi
244+
}
245+
190246
function stop_ffmpeg() {
191247
while true; do
192248
FFMPEG_PID=$(pgrep -f "ffmpeg -hide_banner" | tr '\n' ' ')
193249
if [ -n "$FFMPEG_PID" ]; then
194-
kill -SIGINT $FFMPEG_PID
195-
wait $FFMPEG_PID
250+
# Single SIGTERM for graceful shutdown - allows FFmpeg to write moov atom
251+
kill -SIGTERM $FFMPEG_PID
252+
wait $FFMPEG_PID 2>/dev/null
196253
fi
197254
if ! pgrep -f "ffmpeg -hide_banner" >/dev/null; then
198255
break
@@ -210,11 +267,12 @@ function stop_ffmpeg_graceful_async() {
210267
local session_id_param="$6"
211268

212269
(
213-
# Send SIGINT to FFmpeg
270+
# Send single SIGTERM to FFmpeg for graceful shutdown
271+
# This allows FFmpeg to properly write the moov atom (MP4 metadata)
214272
FFMPEG_PID=$(pgrep -f "ffmpeg -hide_banner" | tr '\n' ' ')
215273
if [ -n "$FFMPEG_PID" ]; then
216-
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Sending SIGINT to FFmpeg PID: $FFMPEG_PID for file: ${video_file_name_param}"
217-
kill -SIGINT $FFMPEG_PID
274+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Sending SIGTERM to FFmpeg PID: $FFMPEG_PID for file: ${video_file_name_param}"
275+
kill -SIGTERM $FFMPEG_PID
218276

219277
# Wait for FFmpeg to finish writing
220278
wait $FFMPEG_PID 2>/dev/null
@@ -223,15 +281,35 @@ function stop_ffmpeg_graceful_async() {
223281
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Waiting ${graceful_stop_delay} seconds for video metadata finalization"
224282
sleep ${graceful_stop_delay}
225283

226-
# Verify file integrity after grace period
284+
# Verify file exists
227285
if [[ -f "${video_file_to_finalize}" ]]; then
228286
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Video file finalized: ${video_file_to_finalize}"
229287

230-
# Trigger upload AFTER file is finalized
231-
if [[ "${should_upload}" = "true" ]] && [[ -n "${upload_dest_prefix}" ]] && [[ -n "${upload_pipe_file}" ]]; then
232-
upload_destination="${upload_dest_prefix}/${video_file_name_param}"
233-
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Add to pipe a signal Uploading video to ${upload_destination}"
234-
echo "${video_file_to_finalize} ${upload_dest_prefix}" >>"${upload_pipe_file}"
288+
# Validate MP4 file integrity
289+
if validate_mp4_file "${video_file_to_finalize}" "${session_id_param}"; then
290+
# File is valid, proceed with upload
291+
if [[ "${should_upload}" = "true" ]] && [[ -n "${upload_dest_prefix}" ]] && [[ -n "${upload_pipe_file}" ]]; then
292+
upload_destination="${upload_dest_prefix}/${video_file_name_param}"
293+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Add to pipe a signal Uploading video to ${upload_destination}"
294+
echo "${video_file_to_finalize} ${upload_dest_prefix}" >>"${upload_pipe_file}"
295+
fi
296+
else
297+
# Validation failed, attempt to fix
298+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Video validation failed, attempting recovery"
299+
if attempt_fix_mp4_file "${video_file_to_finalize}" "${session_id_param}"; then
300+
# Fixed successfully, re-validate and upload
301+
if validate_mp4_file "${video_file_to_finalize}" "${session_id_param}"; then
302+
if [[ "${should_upload}" = "true" ]] && [[ -n "${upload_dest_prefix}" ]] && [[ -n "${upload_pipe_file}" ]]; then
303+
upload_destination="${upload_dest_prefix}/${video_file_name_param}"
304+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] Add to pipe a signal Uploading recovered video to ${upload_destination}"
305+
echo "${video_file_to_finalize} ${upload_dest_prefix}" >>"${upload_pipe_file}"
306+
fi
307+
else
308+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] ERROR: Video file still corrupted after recovery attempt, skipping upload"
309+
fi
310+
else
311+
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] ERROR: Video file recovery failed, skipping upload"
312+
fi
235313
fi
236314
else
237315
echo "$(date -u +"${ts_format}") [${process_name}] - [Session: ${session_id_param}] WARNING: Video file not found after finalization: ${video_file_to_finalize}"

tests/get_started.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def run_browser_instance(browser, grid_url):
4141
print(f"Session created: {driver.session_id} ({browser})")
4242
driver.get('https://www.google.com/')
4343
print(driver.title)
44-
time.sleep(100)
44+
time.sleep(10)
4545
driver.quit()
4646

4747

0 commit comments

Comments
 (0)