在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这样 ...
随机推荐
- HDU--杭电--3415--Max Sum of Max-K-sub-sequence--暴力或单调队列
Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ...
- Easyui表单验证扩展
简介: 使用Easyui,我们省了好多事情,不用为UI费心,只需要关注业务层面即可,下面是一些常用的验证方面的扩展,收藏下自己用 //重载$.fn.validatebox.defaults.rules ...
- linux学习心得之目录树开端与/etc(图文)
linux学习心得之目录树开端与/etc(图文) linux中“一切皆文件”,学习linux一年了,在学习过程中对目录树的一点心得,分享给大家,有不对的地方敬请斧正. 不多说了,先上图: 根目录: / ...
- SVN中Branch的创建于合并
SVN中Branch的创建于合并 在使用源代码版本控制工具时,最佳实践是一直保持一个主干版本.但是为了应付实际开发中的各种情况,适时的开辟一些分支也是很有必要的.比如在持续开发新功能的同时,需要发布一 ...
- JSP和JavaBean
JSP JSP全称是Java Server Pages.JSP实际上就是Servlet. JSP原理:JSP会被Tomcat翻译成一个Servlet JSP语法 1)JSP的Java脚本表达式 作用: ...
- How to make workflow chart using several tools in Linux?
Just as what I said, I usually use yED to make workflow chart and markdown as the language to write ...
- Visual Studio 2013 Preview - ASP.NET, MVC 5, Web API 2新功能搶先看
Visual Studio 2013 Preview - ASP.NET, MVC 5, Web API 2新功能搶先看 來自TechEd North America 2013的第一手消息 以下資訊均 ...
- [置顶] MyElipse9.0 M1安装svn(测试100%通过)
为什么标题要写100%通过呢?原因是以前的方法(直接复制到plugin里(MyEclipse 6.0可以,我试过),link安装)都不好用了,9.0M1不吃这一套,所以告诉大家这么做一定能够装上!! ...
- for惠普2013实习生
似乎快两个月了,惠普招实习生的时间好像确实有点久. 记得是从五月中旬的时候,惠普来学校招实习生的.因为没能够去腾讯,能拿到惠普的实习生offer也是我所愿了. 记得宣讲的那天,兴冲冲的过去了,惠普的一 ...
- 更新android SDK的问题
由于我大天朝将google屏蔽的原因,在更新android SDK的时候,可能速度慢还是个小问题,重要的是你更新的时候出各种错误,比如错误 Failed to fetch URL https ...