belfastqiu

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  5 随笔 :: 0 文章 :: 0 评论 :: 23 阅读

  这个项目是我大三做的,和我的very very nice的好哥们Pz做的。其中他负责了idea、Sample Montior的C++底层的部分和最后测试,我负责了流式传输部分
  现在我们来看一看这份代码

import threading
import ffmpeg
from screeninfo import get_monitors

monitors = get_monitors()
secondary_monitor = monitors[0]
screen_x = secondary_monitor.width
screen_y = secondary_monitor.height

# 设置UDP传输地址和端口
udp_url = 'udp://127.0.0.1:12345'

output_format = 'mp4'
output_file = f'output.{output_format}'

input_params = {
    'f': 'gdigrab',  # 屏幕录像并推流
    'framerate': 30,  # 帧率
    'offset_x': monitors[0].x,
    'offset_y': monitors[0].y,
    's': f'{screen_x}x{screen_y}',
    'probesize': '50M',  # 输入流格式时应该读取的数据量
}

output_params = {
    'f': 'mpegts',  # 延迟优化
    'vcodec': 'libx264',
    'pix_fmt': 'yuv420p',
    'vf': 'fps=30',
    's': '1920x1080',  # 根据需要调整分辨率
    'pkt_size': 1316
}

input_stream = ffmpeg.input('desktop', **input_params)
output_stream1 = ffmpeg.output(input_stream, output_file, **output_params)
output_stream2 = ffmpeg.output(input_stream, udp_url, **output_params)


# 定时器回调函数
def stop_recording():
    process.communicate()
    print("录制结束")


# 设置录制时间(以秒为单位)
record_time = 10
timer = threading.Timer(record_time, stop_recording)
timer.start()


# 开始录制
key1 = input("按 'q' 开始录制...")
if key1 == "q":
    process = ffmpeg.run_async(output_stream2)
    print("开始录制...")

# 结束录制
key2 = input("按 'q' 停止录制...")
if key2 == "q":
    timer.cancel()  # 取消定时器
    process.terminate()  # 终止录制进程
    print("录制终止")

  那个时候,我对于视频传输一无所知,所以在经过了大量的学习,和询问chatGpt后,才有了一份这样的代码,我想先说说她的缺点、优点,再仔细的讲解她
  (用女字旁更多的是对代码有怀念,就像船员称呼自己的舰船一样)
关于代码
1.优点:
    简单、好懂
    是我自己写的

2.缺点:
    延迟高,不可用
    不可以传声音

3.讲解:
    讲解主要分为两个部分——输入字典的解析+输出字典的解析,因为其他的确实没啥好讲的(所以好懂,太初学者了)
  (1)输入字典
      f: 'gdigrab':这是指定输入格式为 gdigrab(Graphics Device Interface Grab),它是 Windows 下 FFmpeg 用来捕获屏幕的一个格式。它可以直接录制屏幕的内容。
      framerate: 30:设置录制的帧率为 30 帧每秒,这意味着每秒录制 30 帧画面。
      offset_x 和 offset_y:这两个参数定义了屏幕截图的起始位置(左上角的坐标);monitors[0].x 和 monitors[0].y 是显示器的坐标信息,并从某个特定的屏幕区域开始录制。
      s: f'{screen_x}x{screen_y}':这里设置了录制区域的分辨率。screen_x 和 screen_y 表示需要录制的屏幕区域的宽度和高度。
      probesize: '50M':这是 FFmpeg 用来检测输入流格式的参数。probesize 指定了 FFmpeg 在读取数据流之前,应该读取的最大数据量。
  (2)输出字典
      f: 'mpegts':指定输出格式为 mpegts(MPEG Transport Stream),通常用于流媒体传输,尤其是在网络推流时有优化延迟的效果。
      vcodec: 'libx264':指定视频编码使用 libx264,这是一种常用的 H.264 编码器,广泛支持并且提供了高压缩效率。
      pix_fmt: 'yuv420p':这是输出视频的像素格式。yuv420p 是一种常见的格式,特别适用于 H.264 编码。
      vf: 'fps=30':这是视频过滤器选项,指定了输出视频的帧率是 30 帧每秒。这保证了输出流的帧率和输入流一致。
      s: '1920x1080':输出视频的分辨率,这里设置为 1920x1080,适合高清格式。如果你希望调整输出分辨率,可以根据需求修改。
      pkt_size: 1316:指定每个网络包的大小。这个值是根据网络带宽、延迟等因素优化的,以减少传输中的延迟。1316 字节是一个常用的包大小,它有助于提高实时推流的性能。

问题
  1.什么是gdigrab?

  2.为什么FFmpeg 在读取数据流之前,要读取的最大数据量?

  3.什么是mpegts?

  4.libx264前的libx是什么?

  5.yuv420p前的yuv是什么?

回答
  1.gdigrab 是 FFmpeg 在 Windows 系统下提供的一种视频输入格式,用于捕获屏幕上的图像或特定应用窗口的内容。
   (1)GDI (Graphics Device Interface)是 Windows 操作系统中的一个重要图形接口,它允许应用程序与显示器或打印机交互。通过 GDI,程序可以绘制图形、捕获屏幕内容等。
   (2)其命令行为ffmpeg -f gdigrab -framerate 30 -i desktop output.mp4,抓取名为desktop屏幕,每秒30帧,输出output.mp4文件

  2.为了让 FFmpeg 能够有效地解析输入流的格式,并准确地了解数据流的结构
   (1)流格式探测:FFmpeg 需要一定的样本数据来探测和识别输入流的格式、编码信息、分辨率、音频或视频轨道等;通过读取一定量的数据,FFmpeg 可以判断编码类型、帧率、分辨率等信息。
   (2)避免数据流阻塞:如果流源非常大或存在未知的封装格式,FFmpeg 可能无法立即解析所有信息。通过设置 probesize 限制 FFmpeg 读取的数据量,防止解析过程中过度占用系统资源或阻塞过长时间。
   (3)在完成上面两项任务后,还需要解析输入流,其中 probesize 大小设置一般为5MB或50MB

  3.mpegts(MPEG Transport Stream)是一种广泛用于音视频流传输的容器格式,通常用于广播和网络流媒体传输。
   (1)容错性强、适用于实时传输、小的数据包、时间戳和同步
   (2)用于数字电视广播、视频流媒体
   (3)结构:头部+负载(我将信息介绍放在最下面)

  4.libx264 中 libx 是 x264 编码器的一个 软件库(library),用于实现 H.264 视频编码标准。

  5.yuv420p 中 yuv 是 图像存储格式,颜色存储空间;只有 y 时图片是黑白的,u 表示蓝色与亮度的差异, v 表示红色与亮度的差异。

头部与负载

  1. 头部:包含了用于同步、标识流类型和控制流的基本信息,包括一个 4 字节的标识符,通常包括:
    • Sync byte:同步字节,确保数据包的起始位置
    • PID标识(Packet Identifier):标识当前数据包所属的流或数据类型
    • PES标识(Packetized Elementary Stream):指示包内是否包含原始的音视频数据
    • 时间戳:用于流的同步和错误恢复
  1. 负载:包含了实际的音频、视频或其他数据,是数据包的主要部分。
    • 压缩的音视频数据
    • 字幕信息
    • 数据流的控制信息

那个时候好像,我的前女友也在。。。唉,仅仅纪念一下美好的项目生涯和恋爱生活~!

posted on   Belfast_Qiu  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示