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