当前位置: 首页 > article >正文

FFmpeg在python里推流被处理过的视频流

链式算法处理视频流

 视频源是本地摄像头

# coding=gbk
# 本地摄像头直接推流到 RTMP 服务器
import cv2
import mediapipe as mp
import subprocess as sp

# 初始化 Mediapipe
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_holistic = mp.solutions.holistic

holistic = mp_holistic.Holistic(
    min_detection_confidence=0.7,
    min_tracking_confidence=0.7
)

# AI 算法处理帧
def frame_handler(image):
    image.flags.writeable = False
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = holistic.process(image_rgb)
    if results.pose_world_landmarks is not None:
        image.flags.writeable = True
        mp_drawing.draw_landmarks(
            image,
            results.pose_landmarks,
            mp_holistic.POSE_CONNECTIONS,
            landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style()
        )
    return image

# 设置摄像头
camera_index = 0
cap = cv2.VideoCapture(camera_index)
if not cap.isOpened():
    raise IOError("无法打开本地摄像头")

# 设置分辨率和帧率
width, height = 640, 360  # 分辨率
fps = 15                 # 帧率
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
cap.set(cv2.CAP_PROP_FPS, fps)

# FFmpeg 推流地址
dst = "rtmp://localhost:1935/live/dest-local"

# FFmpeg 推流命令
command = [
    'ffmpeg',
    '-y',                  # 覆盖输出文件
    '-f', 'rawvideo',      # 输入原始视频流格式
    '-vcodec', 'rawvideo',
    '-pix_fmt', 'bgr24',   # 像素格式
    '-s', f"{width}x{height}",  # 分辨率
    '-r', str(fps),        # 帧率
    '-i', '-',             # 从标准输入读取视频流
    '-c:v', 'libx264',     # 视频编码格式
    '-preset', 'ultrafast',  # 超快编码模式
    '-tune', 'zerolatency',  # 优化零延迟
    '-bufsize', '64k',       # 缓冲区设置较小
    '-maxrate', '1M',        # 最大码率控制
    '-g', '15',              # GOP(关键帧间隔,降低到 15 帧)
    '-f', 'flv',            # 输出格式
    dst
]

# 启动 FFmpeg 子进程
pipe = sp.Popen(command, stdin=sp.PIPE)

# 视频处理和推流
try:
    while True:
        ret, frame = cap.read()
        if not ret:
            print("无法读取摄像头数据,程序退出")
            break

        # 使用 Mediapipe 算法处理帧
        processed_frame = frame_handler(frame)

        # 将帧写入 FFmpeg 输入管道
        pipe.stdin.write(processed_frame.tobytes())

        # 显示处理结果
        cv2.imshow('Video', processed_frame)

        # 按 'q' 键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
finally:
    # 释放资源
    cap.release()
    cv2.destroyAllWindows()
    pipe.stdin.close()
    pipe.wait()

print("程序结束")

视频流是网络流 :

# coding=gbk
# 网络摄像头直接推流到 RTMP 服务器
import subprocess as sp

import cv2
import mediapipe as mp

# 初始化 Mediapipe
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_holistic = mp.solutions.holistic

holistic = mp_holistic.Holistic(
    min_detection_confidence=0.7,
    min_tracking_confidence=0.7
)


# AI 算法处理帧
def frame_handler(image):
    image.flags.writeable = False
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = holistic.process(image_rgb)
    if results.pose_world_landmarks is not None:
        image.flags.writeable = True
        mp_drawing.draw_landmarks(
            image,
            results.pose_landmarks,
            mp_holistic.POSE_CONNECTIONS,
            landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style()
        )
    return image


# 设置网络摄像头地址
camera_index = "rtsp://admin:@xxzx@192.168.1.64:554/Streaming/Channels/101"  # 替换为你的网络摄像头地址
cap = cv2.VideoCapture(camera_index)
if not cap.isOpened():
    raise IOError(f"无法打开网络摄像头流:{camera_index}")

# 设置分辨率和帧率
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 自动获取分辨率宽度
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 自动获取分辨率高度
fps = int(cap.get(cv2.CAP_PROP_FPS))  # 自动获取帧率

# 如果获取失败,设置默认值
if fps == 0:
    fps = 15
if width == 0 or height == 0:
    width, height = 640, 360  # 设置默认分辨率

# RTMP 推流地址
dst = "rtmp://localhost:1935/live/dest-net"

# FFmpeg 推流命令
command = [
    'ffmpeg',
    '-y',  # 覆盖输出文件
    '-f', 'rawvideo',  # 输入原始视频流格式
    '-vcodec', 'rawvideo',
    '-pix_fmt', 'bgr24',  # 像素格式
    '-s', f"{width}x{height}",  # 分辨率
    '-r', str(fps),  # 帧率
    '-i', '-',  # 从标准输入读取视频流
    '-c:v', 'libx264',  # 视频编码格式
    '-preset', 'ultrafast',  # 超快编码模式
    '-tune', 'zerolatency',  # 优化零延迟
    '-bufsize', '64k',  # 缓冲区设置较小
    '-maxrate', '1M',  # 最大码率控制
    '-g', '15',  # GOP(关键帧间隔,降低到 15 帧)
    '-f', 'flv',  # 输出格式
    dst
]

# 启动 FFmpeg 子进程
pipe = sp.Popen(command, stdin=sp.PIPE)

# 视频处理和推流
try:
    while True:
        ret, frame = cap.read()
        if not ret:
            print("无法读取网络摄像头流,程序退出")
            break

        # 使用 Mediapipe 算法处理帧
        processed_frame = frame_handler(frame)

        # 将帧写入 FFmpeg 输入管道
        pipe.stdin.write(processed_frame.tobytes())

        # 显示处理结果
        cv2.imshow('Video', processed_frame)

        # 按 'q' 键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
finally:
    # 释放资源
    cap.release()
    cv2.destroyAllWindows()
    pipe.stdin.close()
    pipe.wait()

print("程序结束")


http://www.kler.cn/a/452416.html

相关文章:

  • MyBatis如何处理延迟加载?
  • 三维扫描在汽车/航空行业应用
  • Java web的发展历史
  • C#中的委托机制:深入理解与应用
  • 基于earthSDK三维地图组件开发
  • vue.js 指令的修饰符
  • 16.2、网络安全风险评估技术与攻击
  • 解决Gradle下载很慢,运行及打包很慢
  • 在开发嵌入式系统时,尤其是处理大数时,会遇到取值范围的问题。51单片机通常没有内建大整数支持,因此我们需要采用不同的方法来解决这一问题
  • 【ELK】ES单节点升级为集群并开启https【亲测可用】
  • 探索 Samba 服务器:搭建跨平台文件共享的桥梁
  • Converseen:全能免费批量图像处理专家
  • uniapp下拉选择组件
  • 金融租赁系统的发展与全球化战略实施探讨
  • 直连交换机简单应用
  • Docker 部署 SpringBoot VUE项目
  • STL heap原理和用法
  • js数字处理的相关方法
  • 【UE5.3.2】生成vs工程并rider打开
  • 完全免费英语听力数字日期部分训练软件