首页 后端开发 Python教程 通过ffmpeg子进程进行视频数据IO

通过ffmpeg子进程进行视频数据IO

Dec 27, 2024 pm 09:30 PM

当我重新开始找工作时(是的,我仍然#OpenToWork,请告诉我!),在一份工作申请中,我被要求实现一个处理视频数据的原型。在完成该项目的过程中,由于我在该领域相对缺乏经验,我意外地从生成式 AI 聊天机器人那里得到了很多帮助。

Video data IO through ffmpeg subprocess

如标题所述,使用ffmpeg进行一些预处理工作。该项目的目标之一是能够依次播放多个视频文件。虽然有多种方法可以实现这一目标,但我决定采用最明显的解决方案,将它们连接在一起。

$ cat video1 video2 video3 | python further-work.py
登录后复制
登录后复制

为了实现这一目标,我首先必须将文件重新编码为允许的格式。在与 Google Gemini 对此进行“讨论”后,聊天机器人建议我使用 MPEG-TS。

MPEG 传输流 (MPEG-TS) 通过封装分组基本流来工作。这些流包括音频、视频和 PSIP 数据,它们被打包成小段。每个流被切成 188 字节的部分并交织在一起。此过程可确保更短的延迟和更高的容错能力,使其成为大帧可能导致音频延迟的视频会议的理想选择。

引用自 https://castr.com/blog/mpeg-transport-stream-mp​​eg-ts/

还有其他文件格式可用于此目的,但它们与讨论无关。当我将视频重新编码为这种格式后,视频数据将被发送到队列,供其他进程中运行的其他模块使用。

定义了输入(要在线获取的视频文件列表)和输出(重新编码的视频文件内容)后,是时候弄清楚如何做到这一点了。不幸的是,ffmpeg 是一个非常复杂的实用程序,可以做很多事情。有多次尝试提供一些界面来帮助用户使用它(我真的很想尝试这个,但显然它现在已经死了)。然而,如今生成式人工智能的帮助非常大,只需几个提示即可获得正确的命令。

ffmpeg -hwaccel cuda -i pipe:0 -c:v h264_nvenc -b:v 1.5M -c:a aac -b:a 128k -f mpegts -y pipe:1
登录后复制
登录后复制

它甚至还解释了每个参数的含义,如下面的屏幕截图所示。

Video data IO through ffmpeg subprocess
Gemini 尝试解释 ffmpeg 命令

简而言之,该命令通过 stdin 接受视频文件内容,并将重新编码的视频文件内容输出为 stdout。

现在是时候编写实现代码了,因为我想同时读取和写入 ffmpeg,所以这将是一个异步应用程序。我们这次使用的http客户端库是httpx,它有一个小批量获取下载的方法:

$ cat video1 video2 video3 | python further-work.py
登录后复制
登录后复制

我们稍后担心实际处理,现在我们只需获取将块打印到屏幕上的代码。

接下来我们编写一个函数来调用ffmpeg,通过asyncio.create_subprocess_exec

ffmpeg -hwaccel cuda -i pipe:0 -c:v h264_nvenc -b:v 1.5M -c:a aac -b:a 128k -f mpegts -y pipe:1
登录后复制
登录后复制

理想情况下,我们会按照文档中的建议在此处使用 process.communicate(file_content) ,不幸的是,如果我们这样做,我们将不得不首先下载整个文件,这不可避免地会延迟响应,这并不理想。

我们可以使用 process.stdin.write(),让我们更新原来的 write_input 函数:

import httpx

client = httpx.AsyncClient()

async def write_input(
    client: httpx.AsyncClient, video_link: str, process: asyncio.subprocess.Process
) -> None:
    async with client.stream("GET", video_link) as response:
        async for chunk in response.aiter_raw(1024):
            print(chunk) # this is the downloaded video file, in chunks
登录后复制

每下载一个块,

  1. 我们通过 process.stdin.write(chunk) 将其提供给进程。
  2. 完成后,我们将编写一个 EOF (process.stdin.write_eof()) 来表示文件输入的结束,
  3. 后跟 .close() (和相应的await .wait_angled())

回到video_send函数,我们通过读取process.stdout来继续该函数。能够同时进行读取和写入正是我们通过 asyncio 执行此操作的原因。以前在同步设置中,我们只能按照固定的顺序一个接一个地执行,但现在我们可以让调度程序来关心顺序。现在该函数添加了以下代码,用于读取重新编码的文件内容,并将其发布到队列中:

async def video_send(client: httpx.AsyncClient, video_link: str) -> None:
    logger.info("DATA: Fetching video from link", link=video_link)
    process = await asyncio.create_subprocess_exec(
        "ffmpeg",
        "-hwaccel",
        "cuda",
        "-i",
        "pipe:0",
        "-c:v",
        "h264_nvenc",
        # "libx264",
        "-b:v",
        "1.5M",
        "-c:a",
        "aac",
        "-b:a",
        "128k",
        "-f",
        "mpegts",
        "-y",
        "pipe:1",
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
    )

    asyncio.create_task(write_input(client, video_link, process))
登录后复制

在一个循环中,我们

  1. 从 ffmpeg stdout 获取一大块数据
  2. 如果 chunk 是空字符串,则退出循环
  3. 否则,将块推送到队列(通过 asyncio.to_thread,因为我们在这里使用进程安全版本)
  4. 然后我们通过process.wait()等待命令优雅退出

现在看起来很简单,但我花了整整一个晚上才真正正确地完成了这件事(而且我在写这篇文章时仍在修改代码)。有一半的时间我会检查文档以确保没有遗漏任何内容,其他时间我会让 Gemini 审查我的代码。

希望您觉得本文有用,今天就到此为止,希望我们下周能回到之前承诺的“代码降临”内容。

以上是通过ffmpeg子进程进行视频数据IO的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1663
14
CakePHP 教程
1419
52
Laravel 教程
1313
25
PHP教程
1264
29
C# 教程
1237
24
Python vs.C:申请和用例 Python vs.C:申请和用例 Apr 12, 2025 am 12:01 AM

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。 Python以简洁和强大的生态系统着称,C 则以高性能和底层控制能力闻名。

2小时的Python计划:一种现实的方法 2小时的Python计划:一种现实的方法 Apr 11, 2025 am 12:04 AM

2小时内可以学会Python的基本编程概念和技能。1.学习变量和数据类型,2.掌握控制流(条件语句和循环),3.理解函数的定义和使用,4.通过简单示例和代码片段快速上手Python编程。

Python:游戏,Guis等 Python:游戏,Guis等 Apr 13, 2025 am 12:14 AM

Python在游戏和GUI开发中表现出色。1)游戏开发使用Pygame,提供绘图、音频等功能,适合创建2D游戏。2)GUI开发可选择Tkinter或PyQt,Tkinter简单易用,PyQt功能丰富,适合专业开发。

您可以在2小时内学到多少python? 您可以在2小时内学到多少python? Apr 09, 2025 pm 04:33 PM

两小时内可以学到Python的基础知识。1.学习变量和数据类型,2.掌握控制结构如if语句和循环,3.了解函数的定义和使用。这些将帮助你开始编写简单的Python程序。

Python与C:学习曲线和易用性 Python与C:学习曲线和易用性 Apr 19, 2025 am 12:20 AM

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

Python和时间:充分利用您的学习时间 Python和时间:充分利用您的学习时间 Apr 14, 2025 am 12:02 AM

要在有限的时间内最大化学习Python的效率,可以使用Python的datetime、time和schedule模块。1.datetime模块用于记录和规划学习时间。2.time模块帮助设置学习和休息时间。3.schedule模块自动化安排每周学习任务。

Python:探索其主要应用程序 Python:探索其主要应用程序 Apr 10, 2025 am 09:41 AM

Python在web开发、数据科学、机器学习、自动化和脚本编写等领域有广泛应用。1)在web开发中,Django和Flask框架简化了开发过程。2)数据科学和机器学习领域,NumPy、Pandas、Scikit-learn和TensorFlow库提供了强大支持。3)自动化和脚本编写方面,Python适用于自动化测试和系统管理等任务。

Python:自动化,脚本和任务管理 Python:自动化,脚本和任务管理 Apr 16, 2025 am 12:14 AM

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。

See all articles