当前位置:   article > 正文

Python 通过ffmpeg实现视频跟摄像头推流(ubuntu16+ffmpeg+nginx)_python实现视频推流

python实现视频推流

目录

前言:

摄像头实时推流

视频推流:


前言:

最近在做一个搞项目,前端只要求展示原始画面,只需要在接入摄像机的时候,把视频流推送到一个服务器地址上,前端可根据地址获取视频流,前端借助的是一个视频流插件video.js,可拉取rtmp格式的视频流。nginx+rtmp 具体的安装配置可参考:

Ubuntu16.04下配置nginx + RTMP流媒体服务器

                                       

代码参考:

摄像头实时推流

  1. import cv2
  2. import queue
  3. import os
  4. import numpy as np
  5. from threading import Thread
  6. import datetime, _thread
  7. import subprocess as sp
  8. from time import *
  9. # 使用线程锁,防止线程死锁
  10. mutex = _thread.allocate_lock()
  11. # 存图片的队列
  12. frame_queue = queue.Queue()
  13. # 推流的地址,前端通过这个地址拉流,主机的IP,2019是ffmpeg在nginx中设置的端口号
  14. rtmpUrl = "rtmp://139.159.142.192:1935/live/1"
  15. # 用于推流的配置,参数比较多,可网上查询理解
  16. command = ['ffmpeg',
  17. '-y',
  18. '-f', 'rawvideo',
  19. '-vcodec', 'rawvideo',
  20. '-pix_fmt', 'bgr24',
  21. '-s', "{}x{}".format(640, 480), # 图片分辨率
  22. '-r', str(25.0), # 视频帧率
  23. '-i', '-',
  24. '-c:v', 'libx264',
  25. '-pix_fmt', 'yuv420p',
  26. '-preset', 'ultrafast',
  27. '-f', 'flv',
  28. rtmpUrl]
  29. def Video():
  30. # 调用相机拍图的函数
  31. vid = cv2.VideoCapture(r"/usr/local/web/studey/mysite/chat/video/4.mp4")
  32. if not vid.isOpened():
  33. raise IOError("Couldn't open webcam or video")
  34. while (vid.isOpened()):
  35. return_value, frame = vid.read()
  36. # 原始图片推入队列中
  37. frame_queue.put(frame)
  38. def push_frame():
  39. # 推流函数
  40. accum_time = 0
  41. curr_fps = 0
  42. fps = "FPS: ??"
  43. prev_time = time()
  44. # 防止多线程时 command 未被设置
  45. while True:
  46. if len(command) > 0:
  47. # 管道配置,其中用到管道
  48. p = sp.Popen(command, stdin=sp.PIPE)
  49. break
  50. while True:
  51. if frame_queue.empty() != True:
  52. # 从队列中取出图片
  53. frame = frame_queue.get()
  54. # curr_time = timer()
  55. # exec_time = curr_time - prev_time
  56. # prev_time = curr_time
  57. # accum_time = accum_time + exec_time
  58. # curr_fps = curr_fps + 1
  59. # process frame
  60. # 你处理图片的代码
  61. # 将图片从队列中取出来做处理,然后再通过管道推送到服务器上
  62. # 增加画面帧率
  63. # if accum_time > 1:
  64. # accum_time = accum_time - 1
  65. # fps = "FPS: " + str(curr_fps)
  66. # curr_fps = 0
  67. # write to pipe
  68. # 将处理后的图片通过管道推送到服务器上,image是处理后的图片
  69. p.stdin.write(frame.tostring())
  70. def run():
  71. # 使用两个线程处理
  72. thread1 = Thread(target=Video, )
  73. thread1.start()
  74. thread2 = Thread(target=push_frame, )
  75. thread2.start()
  76. if __name__ == '__main__':
  77. run()

视频推流:

  1. import cv2
  2. import subprocess
  3. src = "/usr/local/web/studey/mysite/chat/video/4.mp4"
  4. rtmp = 'rtmp://127.0.0.1:1935/live/1'
  5. cap = cv2.VideoCapture(src)
  6. size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
  7. size = (int(640), int(480))
  8. sizeStr = str(size[0]) + 'x' + str(size[1])
  9. command = ['ffmpeg',
  10. '-y', '-an',
  11. '-f', 'rawvideo',
  12. '-vcodec', 'rawvideo',
  13. '-pix_fmt', 'bgr24',
  14. '-s', sizeStr,
  15. '-r', '25',
  16. '-i', '-',
  17. '-c:v', 'libx264',
  18. '-pix_fmt', 'yuv420p',
  19. '-preset', 'ultrafast',
  20. '-f', 'flv',
  21. rtmp]
  22. pipe = subprocess.Popen(command
  23. , shell=False
  24. , stdin=subprocess.PIPE
  25. )
  26. while cap.isOpened():
  27. success, frame = cap.read()
  28. if success == False:
  29. print("Err")
  30. break
  31. img = cv2.resize(frame, size)
  32. pipe.stdin.write(img.tostring())
  33. cap.release()
  34. pipe.terminate()

确保自己已经安装了ffmpeg ,而且ffmpeg已经和nginx配置好。

在处理图像的时候,最好是将原图存到队列中,再从队列中取出来做处理,之前试过将处理后的图片存到队列中,然后直接推送,发现推送的进程占用了所有的资源,导致处理图像的进程无法执行。所以顺序不对,很容易产生资源占用的情况。

怎样查看推流是否成功,可借助VLC软件

将图片以流的形式放到容器中,容器可以做到均衡负载,高访问量。当然与服务器的通信协议

要以UDP的形式,不容易丢包,ffmpeg内部就封装好了UDP协议,不需要自己额外的实现。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/775904
推荐阅读
相关标签
  

闽ICP备14008679号