专辑音乐合并程序

一、背景

闲来无事,想起了自己曾经是一个B站UP主,但是距离自己上一次投稿已经是4年以前的事情了,不投点视频都快过气了。那就投吧,其实也不一定要贴真的视频,可以把自己常听的音乐剪成视频,放上去跟大家共享也可以嘛。
但是我一般都是听整个专辑,或者整个歌单的内容,怎么把这些音乐都合并成一个视频文件上传呢?每次上传视频前都要先合并一次文件,未免太麻烦,于是就写了一个帮助我节省一些工作量的程序。

系统要求:MAC或者Linux。Windows 系统需要看下进程启动指令配置怎么改
开发环境要求:安装Go。

二、ffmpeg 指令测试

1、安装ffmpeg

相信很多小伙伴都听过或者用过格式工厂,对音频或者视频文件进行转码处理。因为几年前的播放器经常对播放格式有各种限制,所以格式工厂还是挺有用的。ffmpeg 的作用也差不多,是一个媒体文件的处理工具,但是如果能用好它,它甚至还能帮你做一些PS、绘声绘影干的事。比如给图片加水印。

MAC 安装方式
brew install ffmpeg
但是安装比较久,下载了一堆跟音频相关的依赖,需要喝杯茶等待一下。

centos 安装方式:
配置源(centos7):
sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm

然后安装:
yum install ffmpeg ffmpeg-devel -y

参考博客

2、测试合并两个flac文件

ffmpeg -y -i “02-ねぐせ.flac” -i “03-こいのうた.flac” -filter_complex ‘[0:0][1:0]concat=n=2:v=0:a=1[out]’ -map ‘[out]’ tempFile.flac

首先整个参数大概可以分为:输入内容、合并方式、输出文件。
-i:输入文件
-filter_complex:ffmpeg 的最核心参数,后面跟流的组合方式,比如concat 选项就是拼接,overlay 一般用于图片和视频的合并,和map 参数配合使用。更详细的官方说明
-map:输出指向的流名称
n:m:第m-1个输入文件的第0个流。比如上面参数中的0:0,就是ねぐせ.flac文件的第0个流。而它是音乐文件,流只有音乐,因此就是音频内容了

3、测试将flac 和 jpeg 文件合并成一个mp4

ffmpeg -loop 1 -t 30 -i 图片.jpeg -i tempFile.flac -c:a aac -b:a 320k output.mp4

参数同样可以分为输入、输出格式和输出文件三大部分。

-loop:由于图片严格上来说不算流式文件,因此需要指定“循环”拼接音乐文件。
1表示跟着音乐流不断循环,0表示不循环,和不指定的效果一样。
-t:图片合入视频中所占时间,不指定表示覆盖整个音乐文件
-c:a:输出音频格式,关于aac和mp3 的比较
-b:a:音频采样率,越高质量越好

更多关于ffmpeg 指令的使用以及参数的说明,可以参考官方文档

三、效果展示

程序整体的执行顺序为:
专辑音乐合并程序

除第一步需要手动操作之外,其他步骤均在这两个方法中实现了,参数也比较好理解,主要就是下载目录、输出文件名称、网易云歌单id 等。

专辑音乐合并程序

最终效果:可在输出目录中找到最终生成的mp4文件。
专辑音乐合并程序

注意:需要设置下载格式为歌曲名。其他两种格式均有空格,执行合并指令时会有问题。
专辑音乐合并程序

四、开发过程

1、爬虫获取网易云歌单中的音乐列表

获取歌单中的歌曲,主要是为了对本地音乐按照顺序重命名。因为网易云客户端下载音乐,下载名字并不能按照歌单顺序来排,最后在程序中,也无法按照歌单中的顺序来合并音乐了。
老套路了:F12 调试找到网易云的歌单页面中,真正返回歌单内容的链接:
专辑音乐合并程序

可以抓到是 /playlist?id=歌单id 这个接口,只有一个歌单id 的参数。
而返回就是一个HTML 文本,因此我直接用 github.com/PuerkitoBio/goquery 这个库来解析,逻辑也比较简单,解析两层标签即可:
专辑音乐合并程序

2、坑-MAC系统对日文中浊音的读取问题
一开始发现问题起因,是filepath.walk 这个方法解析出来的文件名,日文只要有浊音,和歌单中的歌曲名通过strings.contain 方法匹配的时候就会有问题。
专辑音乐合并程序
比如下面两段歌名,看上去一样,实际上拷贝出来,再粘贴到sublime 上,竟然不一样你敢信?
ドラマチックマーケットライド

ドラマチックマーケットライド

分别粘贴出来的效果是这样的:
专辑音乐合并程序

明显上面的日文是错误的,因为将浊音的标注部分直接作为标点符号打印出来了。

后来我自己验证了一下:将正确显示的日文,复制之后粘贴到文件名上,结果依然会匹配失败。确认了这个问题是通用问题:只要通过filepath.walk 方法读取的日文,或者说有可能是mac 系统在当前环境下,保存进文件名的日文都有格式问题,并不是网易云下载的歌曲格式问题。

再稍微看下filepath.walk 读取文件名的源码部分,是通过系统方法调用完成的。再加上不清楚mac 系统保存日文的方式,这个问题就没有什么优化办法了。
dir_darwin.go
专辑音乐合并程序

无奈之下,只好写一个浊音的转换表,强行将正常的浊音转换成带标点符号的格式:
专辑音乐合并程序

参考-日文中的浊音表

3、go 程序执行指令
直接使用exec.Command.Run() 方法即可。注意Start 方法相当于后台启动,Run 才是等待执行完成之后方法才退出。这里我们要使用run 方法。
专辑音乐合并程序
附:代码链接

总结:其实这个小程序的开发本身技术上难度不大的,只是我个人一直的想法都是技术应该多应用于生活中,所以也觉得做这种开发是值得的。未来一定是信息化爆炸的时代,但是如何从中提取出我们真正想要的信息,从出发点来说,和如何从五花八门的技术中选出真正对人类生活有帮助的部分,出发点是一样的。应用在生活中的技术,更有味道。