需求: 实现一个命令行 mp3 播放器,能够通过命令行播放 mp3 文件。
要实现一个 mp3 音乐播放器,首先要有能够播放音乐的类库,并且支持 mp3 协议。 网上没有看到代码简洁清晰的最小命令行的 mp3 播放器的实现。 调研了几个类库之后实现了一个,供需要的朋友参考。
有不少开源和闭源的音频类库可以使用。 可以选择的类库蛮多的:
ffmpeg, mpg123,bass
fmod,libvlc,sfml,qt media player
尝试了其中的 libvlc 跑不起来, qt media player 依赖于 qt 而比较笨重, ffmpeg 也比较重。
最后用 baas 实现了命令行的 mp3 音乐播放器。
仅仅 4行代码实现命令行 mp3 播放器
如下4行代码, 命令行的第一个参数指定音频文件路径,创建文件音频流,开始播放。
文件 player.c 的内容:
#include <stdio.h>
#include "bass.h"
int main(int argc, char** argv){
BASS_Init(-1, 44100, 0, 0, NULL);
HSTREAM stream = BASS_StreamCreateFile(FALSE, argv[1], 0, 0, 0);
BOOL result = BASS_ChannelPlay(stream, TRUE);
getchar();
}
代码里面用到 bass.h ,从 bass 官网下载的包里面拷贝出来即可。
动态库的安装
从 bass 官网下载动态库: Un4seen Developments
bass 库下载之后(不同操作系统下载不同的压缩包), 把bass 库里面的 so 文件, 或者 dylib, 或者 dll 拷贝到系统的动态库目录中。
比如 Linux 是拷贝 x64/libbass.so (现在几乎没有 32 位的 linux,注意要用 x86 版本的)到 /usr/local/lib 目录下。 然后运行一下 ldconfig 即可编译前面的源代码。
Mac 是拷贝 libbass.dylib 到 /usr/local/lib 目录下。
编译播放器
动态库拷贝到系统的库目录后,Mac/Linux 下面直接用 GCC 编译:
gcc -o player.out player.c -lbass
如果动态库没有拷贝到系统的库目录, 跟 bass 库里面的 bass.h 文件一起, 拷贝到源代码 player.c 相同的目录也是可以的。 编译的时候用 -L 参数指定 Library 路径为当前目录。
gcc -o player.out player.c -lbass -L.
这样在 Mac/Linux 下面就编译出了 player.out 的可执行程序。 可以播放音乐:
./player.out ~/Documents/守候-那音.mp3
让4行代码更完善
前面四行代码的播放器,没有任何的用户帮助,错误提示,也不支持网络歌曲的 URL 播放。
稍微完善一下,让逻辑更完整,工具也更好用,至少出错的时候有一个提示。
#include <stdio.h>
#include <unistd.h> // Windows: #include <windows.h>, replace usleep() -> Sleep()
#include <string.h> //strlen
#include "bass.h"
BOOL startsWith(const char *pre, const char *str){
size_t lenpre = strlen(pre),
lenstr = strlen(str);
return lenstr < lenpre ? FALSE : memcmp(pre, str, lenpre) == 0;
}
int main(int argc, char** argv){
BASS_Init(-1, 44100, 0, 0, NULL);
if(argc==1){
printf("Usage: ./play xxx.mp3 \n");
return -1;
}
HSTREAM stream = 0;
if(startsWith("http", argv[1])){
stream = BASS_StreamCreateURL(argv[1], 0, 0, NULL, 0);
} else {
stream = BASS_StreamCreateFile(FALSE, argv[1], 0, 0, 0);
}
if(!stream){
printf("Usage: ./play xxx.mp3 \n");
printf("Failed to open file, %s code: %d\n", argv[1], BASS_ErrorGetCode());
return -2;
}
BOOL result = BASS_ChannelPlay(stream, TRUE);
if(!result){
printf("Failed to play stream, code: %d\n", BASS_ErrorGetCode());
}
while (TRUE) {
usleep(100);
if(!BASS_ChannelIsActive(stream)){
BASS_StreamFree(stream);
break;
}
}
return 0;
}
这段代码可以在 Mac/Linux 上面编译运行。 参考注释略加修改可以在 Windows 上编译运行。
编译命令跟前面 4行代码版本的编译命令一样。
新编译出来的程序,除了可以播放本机的音乐,也可以播放网络上的音乐。
./player.out ~/Documents/守候-那音.mp3
./player.out http://96.ierge.cn/15/238/476505.mp3
注意 bass 库对于开源的软件,免费的软件是不需要收费的。 如果是商业用途是需要收费的。
商业的播放器可以考虑使用 ffmpeg,qt media player 之类的类库。