Python基于FFMPEG自动截图上传至imgbox(三)

本文最后更新于:1 年前

前言


话接上回,我们能够通过传递过来的视频文件路径截图图片存放到指定路径,并且返回了一个列表,那么我们怎么上传到指定图床?

核心代码及思想


我们在这个环节用到了一个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值来获得文件存储信息。预知后事,请听下回分解。



本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!