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

当我重新开始找工作时(是的,我仍然#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
Python的混合方法:编译和解释合并Python的混合方法:编译和解释合并May 08, 2025 am 12:16 AM

pythonuseshybridapprace,ComminingCompilationTobyTecoDeAndInterpretation.1)codeiscompiledtoplatform-Indepententbybytecode.2)bytecodeisisterpretedbybythepbybythepythonvirtualmachine,增强效率和通用性。

了解python的' for”和' then”循环之间的差异了解python的' for”和' then”循环之间的差异May 08, 2025 am 12:11 AM

theKeyDifferencesBetnewpython's“ for”和“ for”和“ loopsare:1)” for“ loopsareIdealForiteringSequenceSquencesSorkNowniterations,而2)”,而“ loopsareBetterforConterContinuingUntilacTientInditionIntionismetismetistismetistwithOutpredefinedInedIterations.un

Python串联列表与重复Python串联列表与重复May 08, 2025 am 12:09 AM

在Python中,可以通过多种方法连接列表并管理重复元素:1)使用 运算符或extend()方法可以保留所有重复元素;2)转换为集合再转回列表可以去除所有重复元素,但会丢失原有顺序;3)使用循环或列表推导式结合集合可以去除重复元素并保持原有顺序。

Python列表串联性能:速度比较Python列表串联性能:速度比较May 08, 2025 am 12:09 AM

fasteStmethodMethodMethodConcatenationInpythondependersonListsize:1)forsmalllists,operatorseffited.2)forlargerlists,list.extend.extend()orlistComprechensionfaster,withextendEffaster,withExtendEffers,withextend()withextend()是extextend()asmoremory-ememory-emmoremory-emmoremory-emmodifyinginglistsin-place-place-place。

您如何将元素插入python列表中?您如何将元素插入python列表中?May 08, 2025 am 12:07 AM

toInSerteLementIntoApythonList,useAppend()toaddtotheend,insert()foreSpificPosition,andextend()formultiplelements.1)useappend()foraddingsingleitemstotheend.2)useAddingsingLeitemStotheend.2)useeapecificindex,toadapecificindex,toadaSpecificIndex,toadaSpecificIndex,blyit'ssssssslorist.3 toaddextext.3

Python是否列表动态阵列或引擎盖下的链接列表?Python是否列表动态阵列或引擎盖下的链接列表?May 07, 2025 am 12:16 AM

pythonlistsareimplementedasdynamicarrays,notlinkedlists.1)他们areStoredIncoNtiguulMemoryBlocks,mayrequireRealLealLocationWhenAppendingItems,EmpactingPerformance.2)LinkesedlistSwoldOfferefeRefeRefeRefeRefficeInsertions/DeletionsButslowerIndexeDexedAccess,Lestpypytypypytypypytypy

如何从python列表中删除元素?如何从python列表中删除元素?May 07, 2025 am 12:15 AM

pythonoffersFourmainMethodStoreMoveElement Fromalist:1)删除(值)emovesthefirstoccurrenceofavalue,2)pop(index)emovesanderturnsanelementataSpecifiedIndex,3)delstatementremoveselemsbybybyselementbybyindexorslicebybyindexorslice,and 4)

试图运行脚本时,应该检查是否会遇到'权限拒绝”错误?试图运行脚本时,应该检查是否会遇到'权限拒绝”错误?May 07, 2025 am 12:12 AM

toresolvea“ dermissionded”错误Whenrunningascript,跟随台词:1)CheckAndAdjustTheScript'Spermissions ofchmod xmyscript.shtomakeitexecutable.2)nesureThEseRethEserethescriptistriptocriptibationalocatiforecationAdirectorywherewhereyOuhaveWritePerMissionsyOuhaveWritePermissionsyYouHaveWritePermissions,susteSyAsyOURHomeRecretectory。

See all articles

热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

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

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具