bash实现/python实现:将带音频ppt中的音频和ppt分离(1: bash 方法)

最近上《形式语言与自动机》的网课,老师会提前给带音频的ppt。我发现不能自由操作音频(比如快进,或者拉动进度条),只好将音频和ppt分开。这里用bash和python两种方式实现将带音频ppt中的音频分离出来。

windows系统可以使用python的方法。

bash方法

阅前须知

  • 你需要

    • MAC OS or LINUX or UNIX-LIKE等其它支持bash的操作系统(总而言之,你要有bash)
    • 了解bash的基本指令和操作
    • bash shellscript基本写法(包括变量、流程跳转、cp、mv等指令)
    • 了解正则表达式
    • sublime text3(非必须,你也可以选用其它编辑器,如vim等)
  • 本章涉及的内容

    • sublime text3 build system基本配置指南

    如果你的sublime text3上有shellscript的build system,或者你不用sublime text3写shellscript,你可以跳过这部分

    • 代码实现与详细的操作流程
    • 对代码中一些少见的用法的详解
    • 提出一些供大家参考的问题
    • 后续工作安排

Sublime text3 new build system 配置方法

之前一直在ubuntu下用vim写bash,这次懒得打开ubuntu了,但是mac上的vim没怎么配置过不是很好用。之前在mac上sublime text3 配置的不错,于是打算配置一个简单的bash一键运行功能,用到了build system。

sublime text3是自带shellscript build system的,但是我配置完了以后才看到…而且不知为何,sublime text3自带的shellscript build system运行比我自己配置的bash build system要快0.5~0.6s。后期配置java等build system也会用到,技巧和下面的大同小异。

具体见sublime text3的官方文档,这里只叙述一些基本操作

  • sublime text3本身只是一个编辑器不带有任何编译环境或解释器。若本地具有gcc、python等编译环境或解释器,可以通过sublime text3中的build system,方便快捷地调用本地(外部)的编译工具,编译运行文件并输出结果。这样sublime text3看起来就像一个轻量级的编译器(解释器)。
  • sublime text3已经内置一些build system,可以根据爱好并结合官方文档实现更多的build system。(下图中出现的c c++ java python3 bash都是自己配置的,要比sublime text3内置的好用)
  1. new一个build system
    在这里插入图片描述
  2. 编写该文件,效果如下:
    在这里插入图片描述
{
	"shell_cmd": "chmod 777 \"$file_name\" && ./\"$file_name\"",
	"selector": "source.bash",
	"file_patterns": ["*.sh"],
	"working_dir": "$file_path",
	"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
	"encoding": "utf-8"
}
"shell_cmd":在shell中执行的命令。通常这里的命令用来调用本地编译器/解释器。
上图中先chmod给shellscript执行权限,接着在命令行中运行文件。
	"$file_name":被执行的文件名称,不带文件路径,带后缀
"selector":The base scope name of the syntax that 
this build system should be enabled for.(官方文档)	
"file_patterns":被执行的文件名称,正则表达式
"working_dir":被执行的文件保存路径
	"$file_path":被执行的文件保存路径
"file_regex":我也没搞懂,我直接复制粘贴了。之后再琢磨琢磨。
"encoding":编码格式
  1. 保存该build system文件,注意文件名后缀一定是xxx.sublime-build
  2. 之后打开自己写的bash文件xx.sh,Tools->Build System->xxx(刚刚保存的build system文件名称),用command+B运行文件。
  3. 除上述之外,还可以增加一些这样的配置:

这是在c build system中的配置,不仅包括上面提到的字段,还包括下图中的字段。

在这里插入图片描述

 "variants":
    [
        {
            "name": "Run",
            "shell_cmd": "gcc -o \"${file_path}/${file_base_name}\" \"${file}\" && open \"${file_path}/${file_base_name}\""
        }
    ]

对于c c++等编译型语言,需要将编译和运行分开的,这种配置就非常有效。效果如下:
在这里插入图片描述
第一行是编译(command+B),第二行是编译+运行(shift+command+B)

实现

  1. 新建一个bash文件,命名为xxx.sh(xxx为任意名称)
  2. 将下述代码复制粘贴进xxx.sh,保存
#!/bin/bash

############################################
#预处理操作,判断命令行的第一个参数是不是PPT文件
PPT_name=$1
output_string_1="The PPT u wanna unzip is ${PPT_name}"

echo ${output_string_1}

if [[ -a $1 ]];
then
	echo "Please wait"
else
	echo "The PPT is not existing, Now exit"
	exit
fi
############################################

############################################
#提取PPT名称中除去后缀名的部分
#备份原始PPT文件
#将PPT文件转为zip文件
echo "We now backup this PPT for you"

PPT_name_postfix=`echo ${PPT_name} | grep -o '.ppt\|.pptx$'`
PPT_name_without_postfix=${PPT_name%$PPT_name_postfix}
cp ${PPT_name} "${PPT_name_without_postfix}_backup_${PPT_name_postfix}"
mv ${PPT_name} "${PPT_name_without_postfix}.zip"

echo "Succeed in transforming the PPT into a ZIP. We now unzip it"
############################################

############################################
#用unzip直接解压转换后的zip文件
#-q:不显示解压详细过程	-d:确定解压后的输出文件夹
PPT_name_zip="${PPT_name_without_postfix}.zip"
unzip -q ${PPT_name_zip} -d ${PPT_name_without_postfix}

echo "Succeed in unzipping the ZIP. We now extract the media directory"
############################################

############################################
#提取出解压后的文件夹内的/ppt/media文件夹
PPT_dir=${PPT_name_without_postfix}
PPT_media_dir="${PPT_name_without_postfix}_media"
mv "${PPT_dir}/ppt/media" ${PPT_media_dir}

echo "Succeed in extracting the media directory. We now do the last step"
echo "To delete files except of media that u actually need"
############################################

############################################
#删除media文件夹中处理所需音频外的文件
cd ${PPT_media_dir}
shopt -s extglob
file_pattern='!(*.m4a)'
rm ${file_pattern}
############################################

#成功并退出
echo "DONE"
exit
  1. 打开命令行,type insource xxx.sh nnn.ppt,其中nnn.ppt是要解压的文件名称。若xxx.sh与nnn.ppt在同一目录下,可以使用相对路径,否则只能使用绝对路径。

这里也可以直接用chmod给xxx.sh赋予运行权限,只需chomod 744 xxx.sh,然后只需./xxx.sh nnn.ppt即可运行。

  1. 运行结束后,将在原ppt所在文件夹得到一份backup,一个解压后的文件夹和提取出media的文件夹。一般只需要media文件夹即可。
  2. 完成。

Tips

上述代码凭借对bash shellscript 和 正则表达式的了解可以写出大部分。代码中还包括一些少见的写法,这里加以说明。

  • 将命令结果赋值给变量,只需要将命令用``扩住即可。注意!这里不是单引号,是反引号。
  • echo A | grep -o 'regex':将字符串A中匹配正则表达式regex的部分提取出来并输出
  • ${A%$B}:A和B是字符串变量,从字符串变量A中把B中的字符串截取掉。
  • unzip -q A.zip -d dir_name
    • -q:避免解压时输出详细过程
    • -d:制定解压后输出文件到文件夹dir_name
  • mv即有移动文件的功能,也有更改文件名称的功能
  • shopt:Toggle the values of settings controlling optional shell behavior.
    • -s: 打开option
    • -u: 关闭option
    • extglob: If set, the extended pattern matching features are enabled.
  • If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pattern-list is a list of one or more patterns separated by a ‘|’. Composite patterns may be formed using one or more of the following sub-patterns:
    在这里插入图片描述

遗留的问题

  • bash中在grep中使用的正则表达式与一般的正则表达式存在许多区别?
    • 前向预查怎么用?echo ${PPT_name} | grep -o '.ppt\|.pptx$'中,我原先试图用的是echo ${PPT_name} | grep -o '.*(?=.ppt|.pptx)'来直接获取文件名除去后缀的部分,但是匹配不成功(匹配后的输出为空)。我用了一些在线测试工具测试该正则表达式的语法是正确的,问题出在了哪里?
    • *是通配符 or 正则表达式中表明任意多个的标志?file_pattern='!(*.m4a)'中,*被用作了通配符,如果这里用的是正则表达式,不应该是file_pattern='!(.*\.m4a)'吗?

接下来的工作

  • 本章代码已在mac平台上测试无误。我将在下一章中用python(或可能临时变换成其它工具)实现类似的功能,并在mac + windows上测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值