在GNU/Linux下将CD音乐转为mp3
以前我欣赏古典音乐都是听的CD,因而珍藏了不少光盘以及下载到电脑上的ape与flac格式的音乐文件。随着手机硬件性能(如电池续航能力、处理器速度、音质、存储容量等)和软件功能(音乐播放器对于曲目的管理)的提升,便需要考虑如何将这些资源转换成高质量的mp3文件放到手机上聆听。本文介绍如何基于GNU/Linux下的Audacity、k3b、easytag软件,以及自己写的Bash脚本程序来实现此功能。
从光盘抓取音乐并转为mp3
k3b是KDE环境下默认的光盘刻录与抓取软件。其界面如下图所示。
选择菜单Tools中的Rip Audio CD,我们可用它直接从CD光盘上抓取出wav文件。接下来,打开Audacity音乐编辑软件,将抓取的多个wav文件导入(而非打开)为多个音轨。再选择菜单Files中的Export Multiple,将导出格式选为mp3,导出选项中的采样频率设为320 kbps,然后点击导出即可完成转换。如下图所示。
最后,打开easytag软件,填写mp3文件的曲目信息(ID3 Tag)。注意,点击信息文本框旁边的小圆点,可以一次性地将设置应用到所有选中的文件。如下图所示。
将ape或flac文件转为mp3文件
一般下载的CD Rip文件是ape或flac格式的,具有无损音质。可若直接将其拷到手机上,一是某些软件可能不支持这两种格式,二是它们所占用的存储空间太大了,三是由于它们也不包含类似于mp3文件的ID3 tag信息,从而无法被音乐播放软件自动根据专辑名或作曲家名而自动分类管理。因此,有必要将ape和flac文件按曲目拆分并转换为mp3格式,填写曲目信息后再导入手机。
可以看出,这里首先需要解决的是ape与flac文件的曲目拆分问题。一般来说,与它们一同下载的还会有个扩展名为cue的文件。此文件保存了CD的曲目信息,包括音乐风格(GENRE)、制作年份(DATE)、表演者(PERFORMER)、专辑/CD名称(TITLE)、ape或flac文件的名称(FILE),以及每个音轨(TRACK)的标题(TITLE)、表演者(PERFORMER)和开始时间(INDEX 01)。如下所示:
REM GENRE Classical
REM DATE 1991
REM DISCID 9B0E701C
REM COMMENT "ExactAudioCopy v0.95b4"
PERFORMER "Wächter, Sutherland, Schwarzkopf, Taddei, Alva, Sciutti, Frick"
TITLE "Don Giovanni - Giulini 1/3"
FILE "CDImage.ape" WAVE
TRACK 01 AUDIO
TITLE "Sinfonia"
PERFORMER "Wächter, Sutherland, Schwarzkopf, Taddei, Alva, Sciutti, Frick"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "Notte e giorno faticar"
PERFORMER "Wächter, Sutherland, Schwarzkopf, Taddei, Alva, Sciutti, Frick"
INDEX 01 06:18:07
TRACK 03 AUDIO
TITLE "Non sperar, se non m'uccidi"
PERFORMER "Wächter, Sutherland, Schwarzkopf, Taddei, Alva, Sciutti, Frick"
INDEX 01 07:58:31
需要说明的是,某个音轨的信息中可能同时含有INDEX 00与INDEX 01,那么该曲目实际的开始时间是由INDEX 01来指定的。INDEX 01的值比INDEX 00要大一些,目的是为了跳过该曲目前端的空白部分。由INDEX 01指定的时间分为三部分:分钟:秒:1/75秒。
在搞清楚cue文件的格式后,我们再来看音乐编辑软件Audacity所拥有的一个功能:我们可以通过导入包含各音轨信息的标签(label)文件,再选择Export Multiple,则可以将整个的ape或flac文件作拆分并转换为mp3文件。该标签文件的格式如下:
0.000000 0.000000 Sinfonia
378.093333 378.093333 Notte e giorno faticar
478.413333 478.413333 Non sperar, se non m'uccidi
其中,每一行代表一个曲目。每一行中的第一列与第二列的内容相同,都是该音轨的开始时间,单位是秒。第三列则是该曲目的标题。
从cue到label文件的转换可以在这里在线完成,但毕竟不太方便。所以,我写了一个脚本程序cue2lbl.sh,来实现同样的功能。源代码如下:
#!/bin/bash script_name="cue2lbl.sh"
script_usage=$(cat <<EOF
$script_name [OPTIONS] cue_file
EOF
)
script_function=$(cat <<EOF
Convert a cue CD index file to Audacity label file.
EOF
)
script_doc=$(cat <<EOF
Script documentation.
-h Display this help.
-o Specify output lable file.
EOF
)
script_examples=$(cat <<EOF
$script_name -o music.txt music.cue
EOF
)
state_prefix="==="
warning_prefix="***"
error_prefix="!!!" function display_help() {
if [ -n "$script_usage" ]; then
echo -e "Usage: $script_usage"
fi if [ -n "$script_function" ]; then
echo -e "$script_function"
fi if [ -n "$script_doc" ] ; then
echo -e "\n$script_doc"
fi if [ -n "$script_examples" ]; then
echo -e "\nExamples"
echo -e "$script_examples"
fi
} # Output label file
lbl_file="" # Process command options
while getopts ":ho:" opt; do
case $opt in
h ) display_help
exit 0 ;;
o ) lbl_file=$OPTARG ;;
\? ) display_help
exit 1 ;;
esac
done
shift $(($OPTIND - 1)) # Start execute the command
if [ -z "$lbl_file" ]; then
lbl_file="${1%cue}txt"
fi # Label file first time writing
lbl_file_1st_write=1 # Searched state: 0 for start; 1 for track; 2 for title; 3 for index.
searched_state=0 declare -i track_time_minute=0 track_time_second=0 IFS=$'\n'
for line in `grep -i "\(INDEX\)\|\(TITLE\)\|\(TRACK\)" "$1"`; do
case $searched_state in
0 )
if [ -n "`echo "$line" | grep -i TRACK`" ]; then
searched_state=1
fi ;;
1 )
if [ -n "`echo "$line" | grep -i "TITLE"`" ]; then
# Remove blanks at the beginning and end of a line
line=`echo "$line" | gawk -f /usr/local/bin/scripts/rmblank.awk`
# Get title
track_title=`echo "$line" | gawk -f /usr/local/bin/scripts/cue2lbl_get_title.awk`
track_title=`echo "$track_title" | gawk -f /usr/local/bin/scripts/rmblank.awk | tr -d \"`
searched_state=2
fi ;;
2 )
if [ -n "`echo "$line" | grep -i "INDEX"`" ]; then
# Remove blanks at the beginning and end of a line
line=`echo "$line" | gawk -f /usr/local/bin/scripts/rmblank.awk`
# Get track index
line=`echo "$line" | gawk -f /usr/local/bin/scripts/cue2lbl_get_index.awk`
track_index=`echo "$line" | gawk -f /usr/local/bin/scripts/rmblank.awk | cut -f 1 -d " " | tr -d " "`
if [ "$track_index" = "01" ] || [ "$track_index" = "1" ]; then
# Get track time
track_time=`echo "$line" | gawk -f /usr/local/bin/scripts/rmblank.awk | cut -f 2 -d " " | tr -d " "`
track_time_minute=`echo "$track_time" | cut -f 1 -d ":" | gawk '{if (match($0, "^0+$") != 0) {print "0";} else {gsub("^0+", ""); print}}'`
track_time_second=`echo "$track_time" | cut -f 2 -d ":" | gawk '{if (match($0, "^0+$") != 0) {print "0";} else {gsub("^0+", ""); print}}'`
track_time_sub_second=`echo "$track_time" | cut -f 3 -d ":" | gawk '{if (match($0, "^0+$") != 0) {print "0";} else {gsub("^0+", ""); print}}'`
track_time_total_seconds=$(($track_time_minute * 60 + $track_time_second))
track_time_sub_second=`echo "scale=6; $track_time_sub_second / 75" | bc`
if [ "$track_time_sub_second" = "0" ]; then
track_time_sub_second=".000000"
fi
track_time_total_seconds=`echo "$track_time_total_seconds$track_time_sub_second"`
fi
fi if [ -n "`echo "$line" | grep -i "TRACK"`" ]; then
# Print collected track information
if [ "$lbl_file_1st_write" = "1" ]; then
echo -e "$track_time_total_seconds\t$track_time_total_seconds\t$track_title" > "$lbl_file"
lbl_file_1st_write=0
else
echo -e "$track_time_total_seconds\t$track_time_total_seconds\t$track_title" >> "$lbl_file"
fi searched_state=1
fi ;;
esac
done # Print the last collected track information
if [ "$lbl_file_1st_write" = "1" ]; then
echo -e "$track_time_total_seconds\t$track_time_total_seconds\t$track_title" > "$lbl_file"
else
echo -e "$track_time_total_seconds\t$track_time_total_seconds\t$track_title" >> "$lbl_file"
fi
为了完成字符串的匹配,该脚本程序中用到了几个gawk程序,分别如下:
1. 移除行首与行尾的空白字符:
{
gsub("(^[[:blank:]]+)|([[:blank:]]+$)", "");
print;
}
2. 删除INDEX:
/^(INDEX)|(index)/ {print gensub("^(INDEX)|(index)[[:blank:]]+", "", 1);}
3. 删除TITLE:
/^(TITLE)|(title)/ {print gensub("^(TITLE)|(title)[[:blank:]]+", "", 1);}
至此,有了label文件,便可用Audacity将ape和flac转换生成多个mp3文件了。
将mp3文件导入手机
目前我的手机上使用的是“酷我音乐”播放器,可以直接通过Wifi由电脑向手机传歌。如下图所示,打开“酷我音乐”后,点击页面底部的“电脑-手机传歌”:
然后在电脑上打开浏览器,输入提示的地址,添加文件即可。
在GNU/Linux下将CD音乐转为mp3的更多相关文章
- 我在GNU/Linux下使用的桌面环境工具组合
为了使GNU/Linux桌面环境下加载的程序较少以节省内存资源和提高启动时间,我目前并不使用重量级的桌面环境KDE和Gnome,甚至连登录窗界面gdm或xdm都不用,而是直接启动到控制台,登录后调用s ...
- GNU/Linux下Freeplane的界面渲染问题
如下图所示,思维导图软件Freeplane在GNU/Linux下默认的界面渲染效果是很差的,即便将Preferences → Appearance → Antialias设置为Antialias al ...
- 在GNU/Linux下制作Windows 10安装U盘
今年春节回家期间,我需要将家里的一台安装了Debian Stretch的ZaReason笔记本电脑更换为Windows 10系统,好让爸妈从老台式机上的XP系统升级到新的平台上来.回家前,小仙女已在微 ...
- Gnu Linux下文件的字符编码及转换工具
/********************************************************************* * Author : Samson * Date ...
- 在GNU/Linux下使用Lilypond排版简谱
尽管GNU/Linux并非无所不能,但确实能在很多时候提供免费.开放的解决方案.这两天我想做一个简谱,在网上搜索乐谱排版软件,发现了基于GPL协议的Lilypond软件.只不过Lilypond是用来做 ...
- Linux下一个CD翻录 创CUE 压缩flac攻略
于Windows我们通常使用较低EAC翻录压缩发生器CUE找工作的步骤,但在Linux在稍微有点麻烦.每一步,我们需要自己做.经过我的反复尝试寻找和总结了相当不错的方法,使用软件和步骤如下面的. 使用 ...
- arch linux下网易云音乐运行没反应,只能使用root用户运行
本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/netease_music_can_not_open 最近打开网易 ...
- GNU/Linux下LVM配置管理以及快照卷、物理卷、卷组、逻辑卷的创建和删除
LVM是Linux环境中对磁盘分区进行管理的一种机制,是建立在硬盘和分区之上.文件系统之下的一个逻辑层,可提高磁盘分区管理的灵活性.最大的优点是在不损伤数据的前提下调整存储空间的大小. 本篇主要讲述L ...
- 在GNU/Linux下设置与定时更换桌面壁纸
1 简介 在电脑桌面设置一组可以定时更换的壁纸已经不是什么新奇的功能了.比如,Windows 7.KDE桌面环境都可以实现这样的效果.可是,自己目前使用的Debian系统并未安装KDE.GNOME这样 ...
随机推荐
- Modern 阅读笔记 一 PSR标准
一.标准 PSR php standards Recommendation PHP 推荐标准 PSR-1 基本代码风格 PSR-2 严格的代码风格 PSR-3 日志记录器接口 PSR-4 自动加载 ...
- 开发win8 metro monogame,显示pubcenter广告时会使游戏卡住的问题的解决方法。
开发win8 metro游戏,使用monogame,并且还加上pubcenter广告,但是在x64的机子上遇到了问题,广告一出,游戏卡死.经过一系列的判断,发现monogame一直在update和dr ...
- iMac 无线键盘 无法配对
正好小编手里也有一个 Apple wireless keyboard 键盘,经测试发现确实有他所说的问题.在互联网上找了一圈儿都没找到解决方案,苹果官方也没有给出相关方案.只好自己琢磨,还好终于研究出 ...
- Java中Path和CLASSPATH的正确配置
JAVA_HOME: D:\soft\study\jdk1.7.0_01 JAVA_HOME里配置的是我们jdk安装的路径,这样配置就好.如果你是要用到JAVA_HOME的话,那就不要在JAVA_HO ...
- HDFS中文件的压缩与解压
HDFS中文件的压缩与解压 文件的压缩有两大好处:1.可以减少存储文件所需要的磁盘空间:2.可以加速数据在网络和磁盘上的传输.尤其是在处理大数据时,这两大好处是相当重要的. 下面是一个使用gzip工具 ...
- Spring.Net-创建对象
1:通过构造函数创建对象 在配置文件中,指明对象类型<object id="" type="类型全名,程序集名" /> 在代码中指定对象 ...
- aix上使用裸设备安装oracle10g数据库
一.检查系统信息 [root@aix222 /]# oslevel -r 5300-08 [root@aix222 /]# prtconf | grep -i mem Memory Size: 190 ...
- hdu 1728 搜索求最少的转向次数
逃离迷宫 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 初识B/S结构编程技术
B/S结构编程语言 ASP(Active Server Page 动态服务器页面)技术 微软早期推出的B/S编程技术,出现在JSP和ASP.NET之前,PHP当时也很不稳定.ASP之前,动态网站使用G ...
- js 数组常用的操作函数整理
平时多做企业应用开发,抱着实用为主,对前端技术理解得比较肤浅,下面就是肤浅地对 js 数组的属性和方法及对它操作的 jquery 方法做些记录: js 数组是 js 内建的一个非常强大数据类型,由于 ...