Jetson Xavier NX 配置(七)—— 数据传输之socket文件传输 & usb摄像头RTSP视频推流

目录

1、Python socket 文件传输

(1)发送单个文件(一次性)

(2)发送一个文件夹下的所有文件(一次性)

(3)发送每个文件夹下的最新文件(等时间间隔持续发送)

2、usb摄像头RTSP视频推流

(1)下载与配置

(2)使用


1、Python socket 文件传输

简介:python的socket库提供了基于TCP/IP协议的数据传输功能,相当于服务器端开了一个通道listen着,等待一台客户端connect,成功建立连接后,通过send和recv的发送和应答来实现数据传输
需要:同一内网下两台设备的ip地址(在cmd中,windows通过ipconfig命令查看,ubuntu通过ifconfig查看)

(1)发送单个文件(一次性)

参考博客:https://blog.csdn.net/m0_55415810/article/details/1214 p54582

(2)发送一个文件夹下的所有文件(一次性)

参考博客:python socket通信传输某文件夹下的所有图片_不告诉你/tp的博客-CSDN博客

这段代码我在运行试用的时候有出现报错。

一开始send一长串十六进制字符串,相当于是在对暗号,对上暗号了服务器才确认发送数据。但是我这里收发都报错,原代码 s.send("\xAA\x96\xAC\x00\x01\x00\x01\x69")  报错 TypeError: a bytes-like object is required, not 'str' ,改成了 s.send(b'\xAA\x96\xAC\x00\x01\x00\x01\x69') ;原代码 if(rev_str[6] == b"\x01") 的判断报错,应该是进制的问题,我改成了 if(str(rev_str[6]) == “1”) 用十进制判断就可以了

另外前面的send和recv,收发的是文件长度等信息,需要encode和decode成utf-8格式,否则也报错TypeError: a bytes-like object is required, not 'str'

(3)发送每个文件夹下的最新文件(等时间间隔持续发送)

前情提要:应用场景是有N个摄像头,对应N个文件夹,定时更新摄像头的最新抓拍截图,需要将最新的图像传输给其他客户端。

基于(2)进行了一些修改,尤其要注意沾包的问题,如果存在两次连续的send,而实际想要发送的这两次是两个独立的数据文件,对于socket来说他认为两次连续发送的内容是粘连在一起发送的。因此要避免连续的send,在send中间加一句recv(),进行阻塞,多一次一问一答的确认。

上代码:

(传输的数据存放方式与命名格式如下,可根据自己的需求自行修改)

 

服务器端-发送(先启动):

import sys
import socket  
import time
import os
import re

s_server = socket.socket()
print("开始创建服务器socket")
host = ''
port = 7891  # 随意设置一个空闲的端口号(和客户端保持一致即可)
addr = (host, port)
s_server.bind(addr)  # 绑定端口
s_server.listen(5)  # 监听等待客户端的connect,没有的话就一直停留在这一步等待

# 客户端程序运行以后就成功建立了连接
to_client, addr = s_server.accept()
print ('...connected from :', addr)
rev_str = to_client.recv(1024)
print(rev_str)

# 确认过暗号,是要接受该客户端的信息
if(str(rev_str[6]) == "1"):
    start = time.time()
    while True:
        # 每隔一定时间(20s)发送一次
        if (time.time() - start) > 20:
            # 遍历文件夹下的所有文件夹
            path_folder = r"/home/ysj/parking/code/cameras/"
            dirs_folder = os.listdir(path_folder)
            print("文件夹个数")
            print(len(dirs_folder)) 
            to_client.send(str(len(dirs_folder)).encode('utf-8'))

            # 遍历文件夹
            for folder in dirs_folder:  

                # 函数阻塞,防止沾包(避免连续两个send)
                to_client.recv(8) 

                start1 = time.time()
                print("当前文件夹:%s"%folder)
                # 获取该文件夹下的所有图片文件
                path_file = path_folder + folder + "/"
                files = os.listdir(path_file)
                # 对文件夹内的图片按文件名中的序号排序,取最大的那张(最新)
                # 我的图片命名格式如:192.168.1.104_15.jpg,需要用正则表达式取出其中的序号“15”
                files.sort(key = lambda x:int(x[re.search('(?<=_)(.+?)(?=\.jpg)', x).span()[0] : re.search('(?<=_)(.+?)(?=\.jpg)', x).span()[1]]))
                # 取最后一张图片
                file_size = os.path.getsize(path_file + files[-1])
                print('即将发送的文件长度是:%d '%file_size)
                file_info='%s|%s'%(files[-1], file_size)
                to_client.send(file_info.encode('utf-8'))
                to_client.recv(6)
                # 一张图片可能要分好几批才能发送完,此处是连续send
                fout = open(path_file + files[-1], "rb")
                has_send = 0
                while has_send < file_size:
                    frame_data = fout.read(1024)
                    to_client.send(frame_data)
                    has_send+=len(frame_data)

                end1 = time.time()
                dur1 = end1 - start1
                print('time cost: %.5f sec' %dur1)
            
            start = time.time()

    # 如果要定时持续接收的话就不关闭连接了
    # print("program exit normally:-> close socket")
    # s_server.close()
    # to_client.close()

客户端-接收:

import socket               # 导入 socket 模块
import time
 
s = socket.socket()         # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 7891       # 设置端口号
 
s.connect(("192.168.1.106", port)) # 服务器的ip地址


while True:
    # 允许一轮接收发的时候才进行
    # 都要encode和decode成utf-8,否则报错无法传输str而是需要字节
    s.send(b'\xAA\x96\xAC\x00\x01\x00\x01\x69')
    # 对上暗号后,接收即将传输的文件夹下的文件个数
    file_num = s.recv(1024).decode('utf-8')
    print(file_num)
    file_num = int(file_num)

    for file_end in range(0, file_num):

        # 对应服务器端的那一句防止沾包的recv,传的内容无所谓
        s.send(str(file_num).encode('utf-8'))

        file_info = s.recv(80).decode('utf-8')
        print(file_info)
        filename,filesize=str(file_info).split('|')
        s.send(filesize.encode('utf-8'))
        filesize=int(filesize)
        # 接收文件的位置
        f_txt = open("./receive0905/"+filename, "ab")
        has_receive = 0
        while has_receive < filesize:
            picture_date = s.recv(1024)
            f_txt.write(picture_date)
            has_receive+=len(picture_date)
        # time.sleep(2)
        f_txt.close()
        print("接收了一个")
 
# s.close()

2、usb摄像头RTSP视频推流

参考博客:2.gstreamer USB摄像头RTSP推流_生如~夏花的博客-CSDN博客_gstreamer usb摄像头

(1)下载与配置

先下gst-rtsp-server,不能要最新版本的,没有autogen.sh,用旧版本

git clone  -b 1.8 https://github.com/GStreamer/gst-rtsp-server.git 

再下载common.git,粘贴到server下common文件夹下:

GitHub - GStreamer/common: 'common' shared submodule. This module is unused and deprecated.

然后就运行autogen.sh,make就好:

cd gst-rtsp-server 
./autogen.sh
sudo make

(2)使用

使用的时候进入examples文件夹
注:device=/dev/video0,此处的序号0是接入的摄像头序号,如果有多个摄像头需要修改

查看摄像头设备
sudo v4l2-ctl --list-devices
./test-launch --gst-debug-level=3 "( v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, format=(string)NV12, width=640, height=480, framerate=30/1 ! queue ! x264enc bitrate=10240 !  rtph264pay name=pay0 pt=96 )"

(不记得最后成功执行的是哪一段代码了)

./test-launch  --gst-debug=3 "( v4l2src ! video/x-raw,width=640,height=480, framerate=30/1 ! omxh264enc ! h264parse ! rtph264pay name=pay0 pt=96 )"

执行后显示:stream ready at rtsp://127.0.0.1:8554/test

在同一局域网下的另一台主机上,就可以在VLC plyaer里打开网络串流,地址改成服务器的ip地址即可

或者通过opencv也可以获取

问题:当前的视频推流延迟太高了,有10s左右,还未深究

主要参考:

python socket通信传输某文件夹下的所有图片_不告诉你/tp的博客-CSDN博客
2.gstreamer USB摄像头RTSP推流_生如~夏花的博客-CSDN博客_usb摄像头rtsp推流

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值