python real-time video streaming

@action(methods=['GET'], detail=True)
    def video(self, request, pk=None):
        """
        Get live video stream
        :param request:
        : Param pk:
        :return:
        """
        device_obj = self.get_object()

        # IF device_obj.status == 0: 
        #      return the Response ({ 'error': 'device off'})

        IF  Not device_obj.rtsp_address:
             return the Response ({ ' error ' : ' missing rtsp address ' })

        cache_id = '_video_stream_{}'.format(device_obj.hash)
        cache_status = cache.get (the cache_id, None)
         IF cache_status IS None:   # task initialization, set the initial time 
            cache.set (the cache_id, the time.time (), timeout = 60 )

        elif the isinstance (cache_status, a float) and the time.time () - cache_status> 30:   # task has timed out, return an error message instead of a period of time into the team 
            return the Response ({ ' error ' : ' number of connections exceeds the limit, please wait try again ' })

        ret = job_queue.enqueue_video(rtsp_address=device_obj.rtsp_address, device_hash=device_obj.hash)

        logger.info('fetch device %s video job status: %s', pk, ret._status)

        IF ret._status == B ' Started '  or  ' Started ' :   # video streams in the normal push refresh playing time, return video ID 
            cache.set (the cache_id, ' Continue ' , timeout = 30 )
             return the Response ({ ' Video ' : '' .join ([settings.FFMPEG_VIDEO, device_obj.hash])})

        elif ret._status == B ' Queued '  or  ' Queued ' :   # video tasks waiting 
            return the Response ({ ' Status ' : ' waiting to establish a video connection ' })

        the else :   # establishing a video task failed 
            return the Response ({ ' error ' : ' Open Video failed ' })
class JobQueue:
     "" " real-time video playback " "" 
    DEF  __init__ (Self):
        self.video_queue = django_rq.get_queue ( ' Video ' )   # video streams push message queue

    def enqueue_video(self, rtsp_address, device_hash):
        """视频流队列"""
        job_id = 'video_{}'.format(device_hash)
        job = self.video_queue.fetch_job(job_id)

        if not job:
            job = self.video_queue.enqueue_call(
                func='utils.ffmpeg.ffmpeg_play',
                args=(rtsp_address, device_hash),
                timeout=-1,
                TTL = 30,   # wait up to 30 seconds 
                result_ttl = 0,
                job_id=job_id
            )

        return job
# -*- coding: utf-8 -*-

import subprocess
import threading
import time
import logging

from django.core.cache import cache


logger = logging.getLogger('server.default')


def ffmpeg_play(stream, name):

    play = True
    cache_id = '_video_stream_{}'.format(name)
    cache.set(cache_id, 'continue', timeout=30)
    process = None

    def upstream():
        cmd = "ffmpeg -i '{}' -c:v h264 -f flv -r 25 -an 'rtmp://127.0.0.1:1935/live/{}'".format(stream, name)
        process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stderr=subprocess.DEVNULL)
        try:
            logger.info('device: {} stream thread start: {}'.format(name, stream))
            while play:
                time.sleep(1)

        except Exception as e:
            logger.info('device: {} stream thread error {}'.format(name, e))

        finally:
            logger.info('device: {} stream thread stop'.format(name))
            process.communicate(b'q')

    thr = threading.Thread(target=upstream)
    thr.start()

    try:
        while True:
            play = cache.get(cache_id, '')
            if play != 'continue':
                logger.info('stop device {} video stream'.format(name))
                play = False
                break
            time.sleep(1)

    except Exception as e:
        logger.info('device: {} play stream error {}'.format(name, e))
        process.communicate(b'q')

    logger.info('wait device {} video thread stop'.format(name))
    thr.join()
    logger.info('device {} video job stop'.format(name))
# Real-time video streaming 
RQ_QUEUES = {
     ' Video ' : {
         ' USE_REDIS_CACHE ' : ' Video ' ,
    }
}

 

Guess you like

Origin www.cnblogs.com/52-qq/p/11812430.html