Python基于FFMPEG自动截图上传至imgbox(三)
本文最后更新于:2 年前
前言
话接上回,我们能够通过传递过来的视频文件路径截图图片存放到指定路径,并且返回了一个列表,那么我们怎么上传到指定图床?
核心代码及思想
我们在这个环节用到了一个imgbox的相关模块——pyimgbox。使用到了协程相关知识,类似于老王泡茶那个故事话不多说,上代码:
import asyncio
import pyimgbox
# 将之前获取到的图片的路径列表传入
async def up_imgbox(filepaths, gallery_name):
result = [] # 用于存放图片上传网址的bbcode列表
async with pyimgbox.Gallery(title=gallery_name) as gallery: # 该命令会创建一个名为gallery_name的相册
gallery.thumb_width = 350 # 有的外站需要缩略图为350像素宽
async for submission in gallery.add(filepaths): # 开始添加任务,异步开始
if not submission['success']: # 失败的话打印任务失败原因
print(f"{submission['filename']}: {submission['error']}")
else:
print(submission)
result.append('[url=%s][img]%s[/img][/url]' % (submission['web_url'], submission['thumbnail_url']))
return result
# 上述函数的调用,标准范式
def run_up_imgbox(img_locs: list=None, gallery_name: str=None):
loop = asyncio.get_event_loop()
task = loop.create_task(up_imgbox(img_locs, gallery_name))
loop.run_until_complete(task)
return task.result()
异步IO采用消息循环的模式,重复读取消息—处理消息的过程,也就是说异步IO模型需要一个消息循环,在消息循环中,主线程不断地重复“读取消息-处理消息”这一过程。
event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数注册到事件循环上。当满足事件发生的时候,调用相应的协程函数。
coroutine 协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。
task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含任务的各种状态。
async/await 关键字: 用于定义协程的关键字,async定义一个协程,await用于挂起阻塞的异步调用接口。
再来看一个简单的例子:同步代码VS异步代码
import time
def hello():
time.sleep(1)
def run():
for i in range(5):
hello()
print('Hello World:%s' % time.time())
if __name__ == '__main__':
run()
Hello World:1536842494.2786784
Hello World:1536842495.2796268
Hello World:1536842496.2802596
Hello World:1536842497.2804587
Hello World:1536842498.2812462
# 定义异步函数
async def hello(i):
print('Hello World %d :%s' % (i, time.time()))
# 必须使用await,不能使用yield from;如果是使用yield from ,需要采用@asyncio.coroutine相对应
await asyncio.sleep(1)
print('Hello wow World %d :%s' % (i, time.time()))
def run():
tasks = []
for i in range(5):
tasks.append(hello(i))
loop.run_until_complete(asyncio.wait(tasks))
if __name__ =='__main__':
loop = asyncio.get_event_loop()
run()
loop.close()
Hello World 4 :1616070393.0068445
Hello World 1 :1616070393.0068445
Hello World 0 :1616070393.0068445
Hello World 2 :1616070393.0068445
Hello World 3 :1616070393.0068445
暂停约1秒钟
Hello wow World 4 :1616070394.0171442
Hello wow World 0 :1616070394.0171442
Hello wow World 3 :1616070394.0171442
Hello wow World 1 :1616070394.0171442
Hello wow World 2 :1616070394.0171442
大概说明一下:
- async def hello(): 定义async异步函数,中间可以添加await async.sleep(N) 来设定中断并执行下一个循环消息
- tasks = [] 任务则是对协程进一步封装,其中包含任务的各种状态。即多个coroutine函数可以封装成一组Task然后并发执行
- loop = asyncio.get_event_loop() #获取“事件循环”对象
- loop.run_until_complete(asyncio.wait(tasks)) #通过事件循环,去调用协程函数
- loop.close() 结束时间循环
总结
pyimgbox已经封装好了其中的一些过程,所以我们可以通过传过来的视频文件路径获取到截图上传的bbcode了,但是其实还有一个mediainfo需要获取,这其实也不是什么难事。假设一个场景,我们从网页判断了一个种子转载的时候缺了截图或者mediainfo想要转到另一个网站,找视频文件地址不容易,或者盒子上也不好找。但是我们可以用qb获取到hash值来获得文件存储信息。预知后事,请听下回分解。