ffmpeg - asyncio.create_subprocess_shell 错误:从未检索到未来异常 - BrokenPipeError
问题描述
每当我将 asyncio.create_subprocess_shell() 与 sp.communicate() 一起使用时,我都会在程序结束时收到此错误。
如果我使用 asyncio 运行多个 suprocesses,则会在每个进程的末尾打印错误。
虽然它不会影响我的程序,但我想找到源并解决问题。谢谢您的帮助!
追溯:
Future exception was never retrieved
future: <Future finished exception=BrokenPipeError(32, 'The pipe has been ended', None, 109, None)>
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\asyncio\subprocess.py", line 153, in _feed_stdin
await self.stdin.drain()
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\asyncio\streams.py", line 387, in drain
await self._protocol._drain_helper()
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\asyncio\streams.py", line 197, in _drain_helper
await waiter
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\asyncio\proactor_events.py", line 379, in _loop_writing
f.result()
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\asyncio\windows_events.py", line 812, in _poll
value = callback(transferred, key, ov)
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\asyncio\windows_events.py", line 538, in finish_send
return ov.getresult()
BrokenPipeError: [WinError 109] The pipe has been ended
代码:
async def get(cs, url):
async with cs.get(url) as r:
b = b''
while True:
chunk = await r.content.read(4000000)
b += chunk
if not chunk:
break
if int(r.headers['content-length']) < 8000000:
result = BytesIO(b)
return [result, 'full']
else:
command = f"ffmpeg -y -i - -c:v copy -fs 8000000 -f matroska -"
sp = await asyncio.create_subprocess_shell(command, stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
stdout, stderr = await sp.communicate(b)
sp.wait()
print(stderr.decode())
print(len(stdout))
output = str(stderr)
index_d = output.find('Duration: ')
index_t = output.rfind('time=')
duration = await get_sec(output[index_d + 10:].split(",")[0])
time_ = await get_sec(output[index_t + 5:].split(" ")[0])
percentage = f"{round((time_ / duration) * 100)}%"
result = BytesIO(stdout)
return [result, 'preview', percentage]
async def main(urls):
async with aiohttp.ClientSession() as cs:
tasks = []
for url in urls:
task = asyncio.create_task(get(cs, url))
tasks.append(task)
results = []
for task in tasks:
result = await task
results.append(result)
return results
loop = asyncio.get_event_loop()
results = loop.run_until_complete(main(urls))
解决方案
推荐阅读
- python - 在odoo 12中更改销售订单报价预览页面
- android - TextViewCompat.setTextAppearance 不起作用
- java - Javers - java.lang.ClassCastException: org.javers.core.diff.changetype.ValueChange 不能转换为 org.javers.core.diff.changetype.map.MapChange
- c - 当在其条件中使用赋值和后缀运算符时,while 循环如何工作
- .net - 在 Visual Studio for Mac 上进行单声道更新后的框架不匹配
- c# - 单屏按按键几个版本
- java - 在Android中如何检查设备是否有前置闪光灯(Camera2 API)
- sql-server - SQL Server Management Studio 64位安装问题
- hadoop - 在 impala 数据库名称中使用连字符
- mongodb - 在聚合管道的 $project 中形成的字典顺序,在 pymongo 中获取时发生变化