you-get下载视频自动化
#0:回顾
之前我们讨论了使用you-get自动化下载音乐的一个实例,但是如果我下载视频,又应该怎么办呢?
诚然you-get功能强大,但是如果你直接输入:
you-get https://www.bilibili.com/video/AV******
那么你得到的一般都是视频编码错误的提示。因为you-get在没有指定格式的时候会使用MP4,但是B站上的视频一般是FLV,所以我们需要设置stream参数。但是,B站视频的stream参数有时是flv,有时是flv720或者别的什么参数,所以还需要用you-get -i https://www.bilibili.com/video/AV****** 来查看支持的stream参数。这就很麻烦了。而且万一我不是想看视频,而只是想要BGM呢?当然可以去网上找,但是万一是原创音乐而没有发布到音乐平台上呢?也可以用ffmpeg转换,但是就更麻烦了。所以就需要一个自动化程序。但是,在实际测试过之后我发现B站似乎不支持Tampermonkey脚本,所以我们需要写一个应用程序。当然如果你喜欢命令行,你可以直接用sys传参或者使用input输入,但是我就是想要图形界面,那么应该如何来写呢?
#1:图形界面
我以前学wx、tikinter和QT的时候对他们的布局和回调函数非常恼火,我又不要什么高大上的布局,自动左对齐就行了,但是这都需要设置,而回调函数也是一团糟。直到我发现了dearpygui,这个确实十分方便。所以我就使用这个来构建我们的程序(具体的配置和使用可以百度)。
先放出要实现的GUI效果:
一个输入网址的输入框,三个复选框(决定下载完之后的操作)和一个确认按钮(后面那个1是因为dearpygui不允许同名元素,而元素显示的文字即它们的名称,所以有一个编号)。
那么,实现这些东西需要哪些代码呢?
from dearpygui.core import * from dearpygui.simple import * set_main_window_size(620, 650) with window("随便什么名字"): add_text("URL:") add_same_line(spacing=5) add_input_text(" ", default_value="Input video\'s url") add_checkbox("Turn to MP4") add_same_line(spacing=10) add_checkbox("Turn to MP3") add_same_line(spacing=10) add_checkbox("Delete source file") add_button("Determine1",callback=bcallback) start_dearpygui(primary_window="与上面一致")
先导入库,然后设置主窗口大小(等会就知道为什么要设这么大了),然后挨个添加元素,因为dearpygui会自动换行,所以需要一个add_same_line来告诉它这个元素需要添加在同一行。
#2:参数接收与处理
仔细看了上面那段代码就会发现,确认按钮有一个callback参数,这个参数指向它的回调函数。所以我们来编写它的回调函数。
import os def bcallback(sender, data): argv=[get_value(\' \')] if get_value(\'Turn to MP4\'): argv.append(\'-4\') if get_value(\'Turn to MP3\'): argv.append(\'-3\') if get_value(\'Delete source file\'): argv.append(\'-d\') b=os.popen(\'you-get \'+get_value(\' \')+\' -i\') s=b.read() add_window(\'Stream\') add_text(s) add_text("Stream:") add_same_line(spacing=5) add_input_text(" ", default_value="Input stream") add_button("Determine2",callback=scallback,callback_data=argv) end()
这里因为需要获取支持的stream列表,所以导入了os库。先获取输入的参数(使用get_value(\’元素名称\’)),然后把它们全部放入列表。然后通过os.popen方法获得指令执行的结果。然后需要把这个结果显示给用户,但是我们不可能再调出命令行,所以这里我们在主窗口内部添加一个子窗口,把所有的stream都写上去,然后再提供一个输入框让用户选择stream参数(这下知道为什么主窗口需要这么大了吧),然后·用end()来告诉程序,子窗口结束。现在只需要下载视频,然后进行转换就可以了。
#3:下载与转换部分
子窗口的确认按钮回调了一个函数,这个就是我们的下载与转换函数。不同于上一个回调,这个还有一个callback_data参数,因为dearpygui的所有回调函数都有且只有两个参数,一个是sender,告诉函数是谁在调用;一个是data,就是那些没办法通过get_value获取的东西。这里的callback_data就是用来传递data参数的。
然后来看看下载部分:
from you_get import common def scallback(sender, data): link=data[0] stream=get_value(\' \') path=\'████████████\' fb=os.listdir(path) common.any_download(url=link,output_dir=r\'F:\\admin\\video\\\'+dir_id,stream_id=stream,caption=False,merge=True)
这里的下载路径替换成你自己的下载路径,其他的跟下载音乐是没有什么大的区别,除了需要指定stream_id。(可能你会疑惑这个fb变量是要干嘛,后面就知道了)
然后是转换部分,这里我使用了ffmpy进行转换操作,而且把它放入了一个外部程序中(万一其他的程序需要呢?鬼知道,所以这是为了方便使用),先来看看这个程序吧。
from ffmpy import FFmpeg def transform(ifile,ofile): ff = FFmpeg(inputs={ifile: None},outputs={ofile: None}) ff.run()
非常简单,而且我省略了if __name__==\’__main__\’:那一段,因为不重要。
那么我们该如何调用这个呢?
def scallback(sender, data): link=data[0] stream=get_value(\' \') path=\'██████████\' fb=os.listdir(path) common.any_download(url=link,output_dir=path,stream_id=stream,caption=False,merge=True) fa=os.listdir(path) for f in fa: if not (f in fb): file=f opi=data[1:] filename=file.split(\'.\')[0] for o in opi: if o==\'-4\': transform(os.path.join(path,file),os.path.join(path,filename+\'.mp4\')) if o==\'-3\': transform(os.path.join(path,file),os.path.join(mpath,filename+\'.mp3\')) if o==\'-d\': os.remove(file)
现在你知道了吧,我通过对下载前后文件夹的对比找出下载的文件名(因为you-get没有返回值)。然后就是进行转换,应该都没有什么问题。
就是这样了,其实自己开发应用程序还是挺简单的。