bash – FFMPEG audio 0.1ms stutter but video is smooth
I have videos in a folder unprocessed and i’m also using inotifywait to check the folder for new sub folders for videos and process them automatically….
Problem i have is with ffmpeg and stuttering audio in segments while video is smooth. I notice it’s just a small stutter like gibberish for 0.1ms in random segments but no desync. It’s annoying to have this small stutter. Also source MP4 file has smooth audio and video.
I have 100K+ Videos pending HLS processing and files have different dimensions i added the checks for it in the script but ffmpeg keeps messing with me :(. I’m quiet new to ffmpeg…
# Fixed resolutions
RES_480="854:480"
RES_720="1280:720"
# 720p
B_720="2500k"
MAXRATE_720="2500k"
BUFSIZE_720="5000k"
# 480p
B_480="500k"
MAXRATE_480="500k"
BUFSIZE_480="1000k"
process_mp4() {
local mp4_file="$1"
local video_dir_rel="$2"
local mp4_basename="$(basename "$mp4_file" .mp4)"
log "Processing MP4: $mp4_file in video: $video_dir_rel"
local width height
if ! eval "$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height \
-of default=nw=1:nk=1 "$mp4_file" | { read width; read height; echo width=$width; echo height=$height; })"; then
error "Failed to probe $mp4_file. Skipping."
return 1
fi
log "Detected resolution for $mp4_file: ${width}x${height}"
qualities=()
if [ "$height" -ge 1080 ]; then
qualities=("720" "480")
elif [ "$height" -eq 720 ]; then
qualities=("720" "480")
elif [ "$height" -ge 480 ]; then
qualities=("480")
else
qualities=("480")
fi
output_base="$HLS_DIR/$video_dir_rel/$mp4_basename"
mkdir -p "$output_base" || { error "Failed to create $output_base"; return 1; }
ffmpeg_log="$output_base/ffmpeg.log"
playlist_entries=""
for q in "${qualities[@]}"; do
wait_for_slot
variant_dir="$output_base/$q"
variant_dir="$output_base/$q"
mkdir -p "$variant_dir" || { error "Failed to create $variant_dir"; return 1; }
# If original 720p and q=720, copy
# If original 480p and q=480, copy
# if none re encode superfast with fixed bitrate
if [ "$q" = "720" ]; then
scale_filter="scale=$RES_720"
if [ "$height" -eq 720 ]; then
# copy 720p directly
vcodec="copy"
acodec="copy"
filters=""
vparams=""
else
# re-encode to 720p
vcodec="h264"
acodec="aac"
filters="-vf $scale_filter"
vparams="-preset superfast -b:v $B_720 -maxrate $MAXRATE_720 -bufsize $BUFSIZE_720"
fi
else
# q=480
scale_filter="scale=$RES_480"
if [ "$height" -eq 480 ]; then
# copy 480p directly
vcodec="copy"
acodec="copy"
filters=""
vparams=""
else
# re-encode to 480p
vcodec="h264"
acodec="aac"
filters="-vf $scale_filter"
vparams="-preset superfast -b:v $B_480 -maxrate $MAXRATE_480 -bufsize $BUFSIZE_480"
fi
fi
log "Starting ffmpeg for $mp4_file, quality: $q"
(
ffmpeg -y -loglevel error -i "$mp4_file" \
-threads "$CPU_THREADS" \
${vcodec:+-c:v $vcodec} ${acodec:+-c:a $acodec} \
$filters \
$vparams \
-c:a aac -ar 48000 -b:a 128k \
-hls_time 4 -hls_segment_type mpegts \
-hls_segment_filename "$variant_dir/segment.$q.%03d.ts" \
-hls_playlist_type vod \
-hls_flags independent_segments \
-f hls "$variant_dir/index.m3u8" 2>> "$ffmpeg_log"
if [ $? -ne 0 ]; then
error "Encoding failed for $mp4_file, quality: $q. Check $ffmpeg_log for details."
exit 1
else
log "Completed encoding for $mp4_file, quality: $q"
fi
) &
if [ "$vcodec" = "copy" ]; then
# If copying, no scale needed, so original resolution known
if [ "$q" = "720" ]; then
res_line="1280x720"
else
res_line="854x480"
fi
else
# We know the resolutions we scaled to
if [ "$q" = "720" ]; then
res_line="1280x720"
else
res_line="854x480"
fi
fi
bandwidth_line=""
if [ "$q" = "720" ]; then
bandwidth_line="788812" # ~2.5 Mbps
else
bandwidth_line="334795" # ~0.5 Mbps
fi
playlist_entries="${playlist_entries}#EXT-X-STREAM-INF:BANDWIDTH=$bandwidth_line,RESOLUTION=$res_line
$q/index.m3u8
"
done
wait
if [ $? -ne 0 ]; then
error "One or more qualities failed for $mp4_file. See $ffmpeg_log."
return 1
fi
log "Creating master playlist for $mp4_file"
echo "#EXTM3U
#EXT-X-VERSION:3
${playlist_entries}" > "$output_base/master.m3u8"
cat > "$output_base/info.json" <
Read more here: Source link
