1

I am fairly new to python and rq, and have come to a point I can't solve by myself.

I am using ffmpeg-python to encode livestreams, this is distributed in rq workers and displayed on a web app using flask, but since the livestreams can go on forever, I need some way to stop this process while it is still in execution. Opening the terminal where the rq worker is executing the task and pressing 'q' (ffmpeg shortcut to quit) works, and marks the job as OK, but I need to be able to do this from my web app.

I have tried getting the worker ID and sending it a SIGKILL, this stops the worker but the task continues running, which is something I don't understand at all. It's as if the actual ffmpeg process was being executed somewhere else and stopping the worker didn't stop ffmpeg. Note that I am not using ffmpeg.run_async, I am using ffmpeg.run which as far as my limited knowledge goes, should not be executed asynchronously. While the streaming is being encoded the worker is marked as busy and has the Job ID properly assigned, so I really don't understand why, when the worker is killed, the underlying process is still in execution.

If instead of sending a SIGKILL I send a SIGTERM, the worker says it's waiting for a warm exit and is never closed, as the ffmpeg process is still doing it's thing.

One of my ideas was trying to send a 'q' keystroke to the worker (which I have no idea how to do even though i've been doing some research) or trying to switch from rq to celery, that supposedly supports the cancellation of tasks that are being executed.

This is my routes file

@app.route('/streamings', methods=['GET', 'POST'])
@login_required
def streamings():
...
    if form2.submit_stop.data and form2.validate():
        conn1 = Redis.from_url('redis://')
        queue = rq.Queue('tasks-q', connection=Redis.from_url('redis://'))
        workers = rq.Worker.all(queue=queue)

        for worker in workers:
            peine = worker.get_current_job_id()
            if peine == form2.fld1.data:
                os.kill(worker.pid, signal.SIGKILL)

and this is my tasks file

def restream(origin, server, stream_key):
    stream_server = generate_url(server, stream_key)
    try:
        stream_map = None
        stream1 = ffmpeg.input(get_manifest(origin), re=None)
        stream2 = ffmpeg.input('mosca_66.png')
        stream_ol = ffmpeg.overlay(stream1, stream2, x='main_w-overlay_w-50', y='50')
        a1 = stream1.audio
        stream = ffmpeg.output(stream_ol, a1, stream_server, format='flv', vcodec='libx264', acodec='aac', preset='medium', g='120', crf='23', maxrate='4M', bufsize='5M', channel_layout='stereo')
        print(stream.get_args())
        ffmpeg.run(stream)
    except:
        set_complete() 

Any insight on possible solutions would be greatly appreciated.

Thanks

sqr
  • 96
  • 7

0 Answers0