• Little Practical Annoyances

    From c186282@c186282@nnada.net to comp.os.linux.misc on Sun Feb 8 01:00:02 2026
    From Newsgroup: comp.os.linux.misc

    Wrote a Python app to record an RTSP stream from
    a security cam. The SOUND was most important so
    the saved vid was scaled down about 50% to use
    less disk space.

    Ffmpeg, with a lot of obscure params, runs the
    RTSP capture and vid resize. Works.

    Now, ffmpeg stuff uses kind of a lot of CPU, so
    the app was structured to detect and prevent
    multiple instances from running.

    This normally worked quite well. HOWEVER it
    IS possible for ffmpeg to HANG every so often.
    So, if looking for it, the defective instance
    remains, looks like a good active process.

    Fix, record WHEN ffmpeg was started and IF it
    is still running beyond the allocated time
    frame KILL it. If NOT beyond the allocated
    time span, ignore.

    So. run 'ps' then look for an ffmpeg process
    with telltale params that mean it's with the
    particular recording app. "grep" CAN be used
    to narrow things down, but we look for TWO
    confirming strings and at minimum evil regex
    crap would be needed.

    Oh, note for running 'ps' stuff with Python
    in interactive mode ... it knows the terminal
    width and ONLY returns x-character strings,
    Adding 'grep' ... it knows the terminal width
    and SPLITS lines with newlines where you can't
    tell if the line is supposed to be all one
    thing or not. Could not find a param to fake
    an infinite-width terminal. In any case, the
    in-terminal lines may be too short to be useful.
    In Python NON-terminal apps it seems to return
    the full report string.

    Anyway, eventually made a little function :

    def pAlive() :
    pL=[]
    s=os.popen("ps ax").read().split("\n")
    for line in s :
    if ("ffmp" in line) and ("mkv" in line) :
    line=line.split(" ")
    pL.append(line[2]) # the process number(s)
    return pL

    With 'ps -ax' the third field is the process number.
    There MIGHT be more than one instance of the dead
    ffmpeg, ergo putting them all into the returned list.

    So, down in the real pgm, we record the TIME the
    ffmpeg process is started. Ffmpeg is evoked in
    non-blocking mode. We come back to the code block
    every two minutes, but ffmpeg is supposed to
    run for ten.

    We use the function. If it has been more than ten
    minutes since ffmpeg was started then it SHOULD
    have ended. We then just do an 'os.system("kill ...")
    on everything returned by the function and proceed
    down to restart ffmpeg. If it hasn't been ten minutes
    then we never get far enough down to even try to
    start ffmpeg.

    The non-blocking startup is critical here. If
    we did blocking then there'd be no way to check
    if there was a problem short of some external
    watchdog, more complication.

    Note that this app is started/managed by systemd.
    It WILL notice if the app dies and restart it.
    However a hung ffmpeg doesn't crash the app, so
    systemd thinks it's still all OK and doesn't do
    anything, doesn't trigger its watchdog aspect.

    Now all this is to show how, even if you do code
    right, HANG-UPS can sabotage everything. Ffmpeg
    can indeed hang. it's big and complicated and
    uses a lot of CPU. On random days my app would
    run for eight or nine hours and then ffmpeg
    would crap out - no recordings, no error msgs.
    Not every app in Linux is PERFECT - so it may
    be necessary to DEAL with possible unexpected
    imperfections. Never ASSUME perfection.

    So, 'simple' code had to become somewhat LESS simple
    due to fuckin' REALITY.

    ('mkv' is a kind of video format, a bit more
    compact than mp4)

    --- Synchronet 3.21b-Linux NewsLink 1.2