媒体播放器程序核心功能解析
1. 数据结构与宏定义
-
播放模式枚举
MODE:MODE_CYCLE:循环播放MODE_RANDOM:随机播放MODE_SINGAL:单次播放(注意:代码中拼写为SINGAL,应为SINGLE)
-
播放列表结构体
LIST:ctypedef struct { char name[10][512]; // 存储最多10个媒体文件路径 int total; // 媒体文件总数 int current; // 当前播放索引 MODE mode; // 播放模式 } LIST; -
媒体路径宏 :
c#define MEDIA_PATH "/home/linux/vm/09mp"
2. 初始化函数 do_init()
- 功能:扫描媒体目录,构建播放列表并创建控制管道
- 关键流程 :
- 使用
opendir打开媒体目录 - 遍历目录项,筛选扩展名为
.mp4,.mp3,.flv的文件 - 构建完整文件路径存入
list.name - 初始化播放索引
list.current = 0和播放模式list.mode = MODE_CYCLE - 使用
mkfifo创建命名管道/home/linux/vm/09mp/fifo(忽略已存在错误)
- 使用
3. 播放控制函数
-
do_play(char* name):cpid_t pid = fork(); if (0 == pid) { execlp("mplayer", "mplayer", "-slave", "-input", "file=/home/linux/vm/09mp/fifo", name, "-quiet", NULL); exit(1); }- 通过
fork+execlp调用mplayer - 使用
-slave模式和-input file=...指定控制管道
- 通过
-
do_pause():cint fd = open("/home/linux/vm/09mp/fifo", O_RDWR); write(fd, "pause\n", 6); close(fd); -
do_stop():- 包含完整的错误处理逻辑:
- 检查管道打开状态
- 验证写入字节数
- 确保资源关闭
- 包含完整的错误处理逻辑:
4. 播放列表管理
do_list():- 打印播放列表索引和路径
- 通过
fgets获取用户输入 - 根据输入索引调用
do_play()
5. 播放导航
-
do_prev():- 在
MODE_CYCLE模式下实现循环上一曲
cnum = list.current; num--; if(num == -1) num = list.total - 1; // 修正边界: num = 2 -> list.total-1 - 在
-
do_next():- 在
MODE_CYCLE模式下实现循环下一曲
cnum = list.current; num = (num + 1) % list.total; // 取模实现循环 - 在
6. 高级控制
-
do_seek():csprintf(buf,"seek %d 1\n",num); // 百分比跳转 write(fd, buf, strlen(buf)); -
do_speed():- 未完整实现(函数体不完整)
技术要点总结
- 目录遍历 :使用
dirent.h实现文件系统扫描 - 进程控制 :
fork()+execlp()调用外部播放器 - 进程间通信 :通过命名管道(FIFO)向
mplayer发送控制命令 - 模式管理:枚举类型实现播放模式状态机
- 边界处理:播放索引的循环计算