python实现实时视频流播放代码实例


Posted in Python onJanuary 11, 2020

这篇文章主要介绍了python实现实时视频流播放代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

@action(methods=['GET'], detail=True)
  def video(self, request, pk=None):
    """
    获取设备实时视频流
    :param request:
    :param pk:
    :return:
    """
    device_obj = self.get_object()

    # if device_obj.status == 0:
    #   return Response({'error': '设备离线'})

    if not device_obj.rtsp_address:
      return Response({'error': '缺少rtsp地址'})

    cache_id = '_video_stream_{}'.format(device_obj.hash)
    cache_status = cache.get(cache_id, None)
    if cache_status is None: # 任务初始化,设置初始时间
      cache.set(cache_id, time.time(), timeout=60)

    elif isinstance(cache_status, float) and time.time() - cache_status > 30: # 任务已超时, 返回错误信息, 一段时间内不再入队
      return Response({'error': '连接数目超过限制, 请稍后再试'})

    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': # 视频流正常推送中, 刷新播放时间, 返回视频ID
      cache.set(cache_id, 'continue', timeout=30)
      return Response({'video': ''.join([settings.FFMPEG_VIDEO, device_obj.hash])})

    elif ret._status == b'queued' or 'queued': # 视频任务等待中
      return Response({'status': '等待建立视频连接'})

    else: # 建立视频任务失败
      return Response({'error': '打开视频失败'})
class JobQueue:
  """实时视频播放"""
  def __init__(self):
    self.video_queue = django_rq.get_queue('video') # 视频推流消息队列

  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, # 最多等待30秒
        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))
# 实时视频流播放
RQ_QUEUES = {
  'video': {
    'USE_REDIS_CACHE': 'video',
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现在无须过多援引的情况下创建字典的方法
Sep 25 Python
Python线程的两种编程方式
Apr 14 Python
简单介绍Python中利用生成器实现的并发编程
May 04 Python
Python实现将绝对URL替换成相对URL的方法
Jun 28 Python
关于Python正则表达式 findall函数问题详解
Mar 22 Python
python切片及sys.argv[]用法详解
May 25 Python
Python 将Matrix、Dict保存到文件的方法
Oct 30 Python
在Python中调用Ping命令,批量IP的方法
Jan 26 Python
Python 利用切片从列表中取出一部分使用的方法
Feb 01 Python
Python绘制全球疫情变化地图的实例代码
Apr 20 Python
基于python实现音乐播放器代码实例
Jul 01 Python
OpenCV图像变换之傅里叶变换的一些应用
Jul 26 Python
python3下pygame如何实现显示中文
Jan 11 #Python
Pytorch 实现sobel算子的卷积操作详解
Jan 10 #Python
Pytorch保存模型用于测试和用于继续训练的区别详解
Jan 10 #Python
使用pytorch完成kaggle猫狗图像识别方式
Jan 10 #Python
解决Pytorch 加载训练好的模型 遇到的error问题
Jan 10 #Python
Ubuntu16.04安装python3.6.5步骤详解
Jan 10 #Python
Pytorch 保存模型生成图片方式
Jan 10 #Python
You might like
PHP 清空varnish 缓存的详解(包括指定站点下的)
2013/06/20 PHP
php socket客户端及服务器端应用实例
2014/07/04 PHP
php.ini save_handler 修改不生效的解决办法
2014/07/22 PHP
php实现搜索一维数组元素并删除二维数组对应元素的方法
2015/07/06 PHP
浅谈Laravel中的三种中间件的作用
2019/10/13 PHP
如何让动态插入的javascript脚本代码跑起来。
2007/01/09 Javascript
Auntion-TableSort国人写的一个javascript表格排序的东西
2007/11/12 Javascript
JS获取节点的兄弟,父级,子级元素的方法
2014/01/09 Javascript
jQuery获取和设置表单元素的方法
2014/02/14 Javascript
浅谈 jQuery 事件源码定位问题
2014/06/18 Javascript
JavaScript中使用Math.floor()方法对数字取整
2015/06/15 Javascript
使用vue.js开发时一些注意事项
2016/04/27 Javascript
浅谈js中test()函数在正则中的使用
2016/08/19 Javascript
微信小程序如何获取openid及用户信息
2018/01/26 Javascript
详解js模板引擎art template数组渲染的方法
2018/10/09 Javascript
vue axios请求频繁时取消上一次请求的方法
2018/11/10 Javascript
js将URL网址转为16进制加密与解密函数
2020/03/04 Javascript
如何解决vue在ios微信"复制链接"功能问题
2020/03/26 Javascript
[01:02:04]EG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
Python实现动态添加类的属性或成员函数的解决方法
2014/07/16 Python
Python批量合并有合并单元格的Excel文件详解
2018/04/05 Python
详解python3中zipfile模块用法
2018/06/18 Python
python十进制和二进制的转换方法(含浮点数)
2018/07/07 Python
Python字符串、整数、和浮点型数相互转换实例
2018/08/04 Python
python: 自动安装缺失库文件的方法
2018/10/22 Python
Python利用逻辑回归模型解决MNIST手写数字识别问题详解
2020/01/14 Python
python字符串,元组,列表,字典互转代码实例详解
2020/02/14 Python
Python unittest工作原理和使用过程解析
2020/02/24 Python
HTML5 Canvas旋转动画的2个代码例子(一个旋转的太极图效果)
2014/04/10 HTML / CSS
美国一家运动专业鞋类零售商:Warehouse Shoe Sale(WSS)
2018/03/28 全球购物
出生证明公证书
2014/04/09 职场文书
基层党建工作汇报材料
2014/08/15 职场文书
2015年乡镇科普工作总结
2015/05/13 职场文书
新员工试用期工作总结2015
2015/05/28 职场文书
幼儿园体操比赛口号
2015/12/25 职场文书
MySQL系列之六 用户与授权
2021/07/02 MySQL