当前位置: 首页 > news >正文

如何用4行 C 代码实现一个跨平台的命令行 mp3 播放器

需求: 实现一个命令行 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 之类的类库。

相关文章:

  • ES 查询用法
  • golang泛型
  • 如何快速安装JDK 1.8 以及配置环境变量
  • DataGrip 如何导出和恢复整个数据库数据,使用单个 SQL 文件
  • 基于SpringBoot+MyBatisPlus+DynamicDatasource+mysql的多数据源本地事务方案
  • 计算机毕业设计ssm+vue基本微信的健康食谱交流 论坛小程序
  • 天龙八部科举答题问题和答案(全5/8)
  • Python Matplotlib库:基本绘图补充
  • 类与对象(下)
  • 【DouZero】 强化学习+self play达到人类玩家斗地主水平。
  • CMake Tutorial 巡礼(5)_添加系统自察
  • 注意力机制(attention)学习笔记
  • Cocos3.x 对象池NodePool使用介绍和注意事项
  • 计算机二级WPS 选择题(模拟和解析二)
  • java计算机毕业设计基于安卓Android微信的儿童疫苗接种管理小程序uniApp
  • __proto__ 和 prototype的关系
  • 【347天】每日项目总结系列085(2018.01.18)
  • eclipse(luna)创建web工程
  • ES6之路之模块详解
  • Javascript 原型链
  • Js基础——数据类型之Null和Undefined
  • MySQL的数据类型
  • use Google search engine
  • vue总结
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 从PHP迁移至Golang - 基础篇
  • 电商搜索引擎的架构设计和性能优化
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 数据仓库的几种建模方法
  • 原生 js 实现移动端 Touch 滑动反弹
  • 源码安装memcached和php memcache扩展
  • python最赚钱的4个方向,你最心动的是哪个?
  • Spring Batch JSON 支持
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • # include “ “ 和 # include < >两者的区别
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (1)(1.11) SiK Radio v2(一)
  • (13):Silverlight 2 数据与通信之WebRequest
  • (16)Reactor的测试——响应式Spring的道法术器
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (二)linux使用docker容器运行mysql
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (三)Honghu Cloud云架构一定时调度平台
  • (三十五)大数据实战——Superset可视化平台搭建
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (译) 函数式 JS #1:简介
  • (转)linux 命令大全
  • (转)Oracle存储过程编写经验和优化措施
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • .NET开源项目介绍及资源推荐:数据持久层