Python Opencv和套接字-流式视频以h264编码 [英] Python Opencv and Sockets - Streaming video encoded in h264

查看:691
本文介绍了Python Opencv和套接字-流式视频以h264编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在尝试制作一个流媒体,以将视频从一台计算机流传输到局域网上的另一台计算机(或现在是同一台).我需要它使用尽可能少的带宽,所以我尝试在h264中进行编码.我在执行此操作时遇到了麻烦,而且我真的不知道从哪里开始.现在,它以jpg编码,并且正在逐帧发送.但是,我知道这效率很低,并且占用大量带宽.这是我当前的接收方代码.

so I am trying to make a streamer that streams video from one computer to another (or the same one, for now) on my LAN. I need it to use as little bandwidth as possible so I am trying to encode in h264. I'm having trouble doing this, and I don't really know where to start. Right now it is encoded in jpg, and it is sending frame by frame. I am aware, however, that this is very inefficient and it consumes a lot of bandwidth. This is my current receiver code.

import cv2
import socket
import _pickle
import time

host = "192.168.1.196"
port = 25565
boo = True

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # declares s object with two parameters
s.bind((host, port)) # tells my socket object to connect to this host & port "binds it to it"
s.listen(10) # tells the socket how much data it will be receiving.

conn, addr = s.accept()
buf = ''
while boo:
        pictures = conn.recv(128000) # creates a pictures variable that receives the pictures with a max amount of 128000 data it can receive
        decoded = _pickle.loads(pictures) # decodes the pictures
        frame = cv2.imdecode(decoded, cv2.IMREAD_COLOR) # translates decoded into frames that we can see!
        cv2.imshow("recv", frame)
        if cv2.waitKey(1) & 0xFF == ord("q"):  # wait until q key was pressed once and
            break

这是我当前的客户代码(发送方):

And here is my current client code (sender):

import cv2
import numpy as np
import socket
import _pickle
from cv2 import *

host = "192.168.1.196"
port = 25565

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # declares s object with two parameters
s.connect((host, port))  # connects to the host & port
cap = cv2.VideoCapture(1)
cv2.cv.CV_FOURCC('H','2','6','4')
while cap.isOpened(): # while camera is being used
    ret, frame = cap.read()  # reads each frame from webcam
    cv2.imshow("client", frame)
    if ret:
        encoded = _pickle.dumps(cv2.imencode("fourcc", frame)[1]) # encoding each frame, instead of sending live video it is sending pictures one by one
        s.sendall(encoded)
    if cv2.waitKey(1) & 0xFF == ord("q"): # wait until key was pressed once and
        break
cap.release()
cv2.destroyAllWindows()

我只需要一些有关如何在h264中对视频进行编码和解码的帮助.

I just need some help on how to encode the video and decode it in h264.

推荐答案

您可以使用 pyzmq

You can do this using pyzmq and the the publish/subscribe pattern with base64 string encoding/decoding. On the server side, the idea is:

  • 从摄像机流中获取帧
  • 使用 cv2.imencode
  • 从内存缓冲区读取图像
  • 使用base64将 ndarray 转换为 str 并通过套接字发送
  • Get frame from camera stream
  • Read image from memory buffer with cv2.imencode
  • Convert ndarray into str with base64 and send over the socket

在客户端,我们只是简单地逆转该过程:

On the client side we simply reverse the process:

  • 从套接字读取图像字符串
  • 使用base64将 str 转换为 bytes
  • 使用 np.frombuffer + cv2.imdecode
  • bytes 转换为 ndarray

此方法不应使用太多带宽,因为它仅通过套接字发送字符串.

This method shouldn't use much bandwidth since its only sending strings across the socket.

服务器

import base64
import cv2
import zmq

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect('tcp://localhost:7777')

camera = cv2.VideoCapture(0)

while True:
    try:
        ret, frame = camera.read()
        frame = cv2.resize(frame, (640, 480))
        encoded, buf = cv2.imencode('.jpg', frame)
        image = base64.b64encode(buf)
        socket.send(image)
    except KeyboardInterrupt:
        camera.release()
        cv2.destroyAllWindows()
        break

客户

import cv2
import zmq
import base64
import numpy as np

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.bind('tcp://*:7777')
socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))

while True:
    try:
        image_string = socket.recv_string()
        raw_image = base64.b64decode(image_string)
        image = np.frombuffer(raw_image, dtype=np.uint8)
        frame = cv2.imdecode(image, 1)
        cv2.imshow("frame", frame)
        cv2.waitKey(1)
    except KeyboardInterrupt:
        cv2.destroyAllWindows()
        break

这篇关于Python Opencv和套接字-流式视频以h264编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆