python脚本批量合并m4s音视频文件
2020-05-29 本文已影响0人
求余的小屋
python
一、前言
从B战缓存了一些视频,想把他们提取出来,放到电脑上观看
没想到,B站把视频和文件分离成了音频、视频,两个文件
一个是 vedio.m4s,另一个是 auoid.m4s,于是琢磨怎么把他们合并成一个 mp4 文件
一番查阅后,找到了一个口碑挺不错的命令行工具——ffmpeg
由于缓存的视频比较多,逐个去执行合并命令费时费力
于是便有了这个 python 脚本
记录一下,编写时候遇到的一些困难,以及解决办法
二、遇到的Bug
① 变量名作用域 & 形参
我遇到的问题是:“如何在子函数中,访问另一个 main 函数中的变量”
解决方法很简单,在 main() 函数中,将要被其他函数访问的变量前,加上 global 就可以了
def moveMedioFile(work_paths):
#TODO: 合并好的视频,移动到初始路径下
logging.debug("移动视频文件到目标路径path: " + path)
for targetFile_path, video_file in work_paths:
mp4_file_path = os.path.join(targetFile_path, video_file + '.mp4')
try:
if os.path.isfile(mp4_file_path):
logging.info("正在移动: " + os.path.basename(video_file))
shutil.move(mp4_file_path, path)
----snip----
def main():
global path
---snip---
if __name__ == '__main__':
main()
我在这里卡住的原因是,潜意识里面把 main() 函数里面的变量,当作了全局变量
导致后面子函数访问时出现了 Bug
另外,形参的变量名,尽量避免与全局变量名字取得一样
所以用函数式编程,一定要小心变量作用域的问题!
② 遍历指定数量的元素
我需要处理的数据如下
folders_titleNames = ['G:\\电影\\1\\64', '复仇者联盟一', 'G:\\电影\\2\\32', '复仇者联盟二', 'G:\\电影\\3\\32', '复仇者联盟三']
#经过处理,转变为下面的形式
folder_titleName = [('G:\\电影\\1\\64', '复仇者联盟一'), ('G:\\电影\\2\\32', '复仇者联盟二'), ('G:\\电影\\2\\32', '复仇者联盟三')]
解决代码如下
#TODO: 处理 folders_titleName 列表,转化视频路径、视频标题为元组,方便解包用于命令的执行
#方法一
arguments = []
for i in range(len(folders_titleNames)):
if i % 2 == 0:
folder_titleName = tuple(folders_titleNames[i:i+2])
arguments.append(folder_titleName)
#方法二
i = 0
arguments = []
while i <= len(folders_titleNames):
folder_titleName = tuple(folders_titleNames[i:i+2])
arguments.append(folder_titleName)
i += 2
# 方法三
arguments = []
for i in range(0, len(folders_titleNames), 2):
folder_titleName = tuple(folders_titleNames[i:i+2]
arguments.append(folder_titleName)
其实就是列表切片的处理,一般情况下我们只是逐个访问元素
但是上面的情况,要求两个(甚至可以多个)提取,来满足实际需求
最优雅的就是方法三了
总结
这次编写代码的时候,用到了很多重复的变量名成,比如 “path”
因为主要是为了处理路径和文件名信息,一开始没考虑这么多
导致最后调试的时候,极其费眼... ...
所以尽可能还是遵守 PEP8 的建议,再结合自身编写习惯与风格吧。
*也许用类来组织这段代码,思路会更加清晰
To Be continued... ...