269 lines
8.7 KiB
C
269 lines
8.7 KiB
C
//
|
||
// Created by CC-star on 25-5-9.
|
||
//
|
||
|
||
// (2) 用户功能:
|
||
// 多种类型的歌曲查询、显示功能:
|
||
// 按歌曲名、歌手名、歌曲类别等查询歌曲。
|
||
// 点歌功能:用户录入歌曲编号,被点播歌曲按点播顺序放入播放表,每一分钟删除最前面一首歌,表示已经播放完毕。
|
||
// 当全部点播歌曲播放完毕,提示"点播歌曲已经播完,请继续点播"。
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
#include "../Shear/C3_shear.h"
|
||
// 播放队列
|
||
typedef struct {
|
||
int songIds[100]; // 歌曲ID
|
||
int count; // 歌曲数量
|
||
} PlayQueue;
|
||
|
||
// PlayQueue playQueue = {.count = 0}; // 指定count = 0
|
||
PlayQueue playQueue = {0};
|
||
// int i;//找到的歌曲索引
|
||
|
||
|
||
// 显示当前播放队列
|
||
void ShowPlayQueue() {
|
||
printf("\n---------------------👇当前播放队列👇----------------------\n");
|
||
if (playQueue.count == 0) {
|
||
printf("播放队列为空\n");
|
||
} else {
|
||
for (int i = 0; i < playQueue.count; i++) {
|
||
for (int j = 0; j < songCount; j++) {
|
||
if (SongList[j].id == playQueue.songIds[i]) {
|
||
printf("%d. %s - %s\n", i + 1, SongList[j].artist, SongList[j].name);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
printf("-----------------------👆播放队列👆------------------------\n");
|
||
}
|
||
|
||
// 移除队列中的第一首歌
|
||
void RemoveFirstSong() {
|
||
if (playQueue.count > 0) {
|
||
for (int i = 0; i < playQueue.count - 1; i++) {
|
||
playQueue.songIds[i] = playQueue.songIds[i + 1];
|
||
}
|
||
playQueue.count--;
|
||
}
|
||
}
|
||
|
||
void PlayMusic(int songId) {
|
||
char command[256];
|
||
char filename[256];
|
||
int found = 0;
|
||
for (int i = 0; i < songCount; i++) {
|
||
if (SongList[i].id == songId) {
|
||
sprintf(filename, "%d-%s-%s-%s.mp3",
|
||
SongList[i].id,
|
||
SongList[i].artist,
|
||
SongList[i].name,
|
||
SongList[i].category);
|
||
//afplay "/Users/music/song.mp3" &
|
||
sprintf(command, "afplay \"%s/%s\" & -t 10", MRES_PATH, filename);
|
||
system(command);
|
||
printf("正在播放: %s - %s\n", SongList[i].artist, SongList[i].name);
|
||
found = 1;
|
||
break;
|
||
}
|
||
}
|
||
if (!found) {
|
||
printf("未找到ID为 %d 的歌曲,无法播放\n", songId);
|
||
}
|
||
ShowPlayQueue();
|
||
}
|
||
|
||
// 播放控制
|
||
void ControlPlayback(int control) {
|
||
switch (control) {
|
||
case 0: // 停止播放
|
||
system("pkill afplay");
|
||
printf("播放已停止\n");
|
||
break;
|
||
case 1: // 暂停播放
|
||
system("pkill -STOP afplay");
|
||
printf("播放已暂停\n");
|
||
break;
|
||
case 2://继续播放
|
||
system("pkill -CONT afplay");
|
||
printf("继续播放\n");
|
||
break;
|
||
case 3: // 下一首
|
||
system("pkill afplay");
|
||
if (playQueue.count > 0) {
|
||
RemoveFirstSong();
|
||
if (playQueue.count > 0) {
|
||
PlayMusic(playQueue.songIds[0]);
|
||
}else {
|
||
printf("播放歌单已播放完毕,请添加歌曲");
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
printf("⚠️输入有误,请重新输入⚠️\n");
|
||
break;
|
||
}
|
||
}
|
||
|
||
int IsSongFinished() {
|
||
FILE *fp = popen("ps aux | grep afplay | grep -v grep", "r");
|
||
if (fp == NULL) {
|
||
return 0;
|
||
}
|
||
char line[256];
|
||
int isPlaying = 0;
|
||
while (fgets(line, sizeof(line), fp)) {
|
||
if (strstr(line, "afplay") != NULL) {
|
||
isPlaying = 1;
|
||
break;
|
||
}
|
||
}
|
||
pclose(fp);
|
||
return isPlaying;
|
||
}
|
||
|
||
|
||
// 自动播放
|
||
void AutoPlayNext() {
|
||
if (playQueue.count > 0) {
|
||
if (IsSongFinished() == 0) {
|
||
RemoveFirstSong();
|
||
if (playQueue.count > 0) {
|
||
printf("播放完毕,自动切换下一首中。。。\n");
|
||
PlayMusic(playQueue.songIds[0]);
|
||
} else {
|
||
printf("播放队列已空,请继续点歌\n");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
int hasInput() {
|
||
int result;
|
||
struct timeval tv = {0, 0};
|
||
fd_set fds;
|
||
FD_ZERO(&fds);
|
||
FD_SET(STDIN_FILENO, &fds);
|
||
result = select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv) > 0;
|
||
return result;
|
||
}
|
||
|
||
//开始点歌
|
||
void Start_Muisc() {
|
||
Read_MuiscFile();
|
||
if (songCount > 0) {
|
||
int shown = 0;
|
||
while (1) {
|
||
AutoPlayNext();
|
||
if (!hasInput()) {
|
||
if (!shown) {
|
||
printf("\n==================================================\nℹ️ 按回车键继续...\n");
|
||
shown = 1;
|
||
}
|
||
usleep(100000);//0.1秒
|
||
continue;
|
||
}
|
||
shown = 0;
|
||
printf("\n---------------------👇点歌控制面板👇----------------------\n");
|
||
printf("1. 添加歌曲到播放队列\n");
|
||
printf("2. 显示当前播放队列\n");
|
||
printf("3. 控制播放(0.停止|1.暂停|2.继续|3.下一首):\n");
|
||
printf("0. 返回主菜单\n");
|
||
printf("-----------------------👆选择对应数字👆------------------------\n");
|
||
printf("请输入选择:");
|
||
int choice;
|
||
scanf("%d", &choice);
|
||
while (getchar() != '\n');
|
||
switch (choice) {
|
||
case 1: {
|
||
printf("请输入要播放的歌曲id: \n");
|
||
int songId;//需要播放的歌曲id
|
||
scanf("%d", &songId);
|
||
while (getchar() != '\n');
|
||
int found = 0;
|
||
for (int i = 0; i < songCount; ++i) {
|
||
if (songId == SongList[i].id) {
|
||
printf("歌曲【%d-%s-%s-%s】已添加到播放队列\n", SongList[i].id, SongList[i].artist, SongList[i].name, SongList[i].category);
|
||
if (playQueue.count < 100) {
|
||
// songId = songId - 1;
|
||
playQueue.songIds[playQueue.count] = songId;
|
||
playQueue.count++;
|
||
|
||
if (playQueue.count == 1) {
|
||
PlayMusic(songId);
|
||
}
|
||
} else {
|
||
printf("播放队列已满,无法添加更多歌曲\n");
|
||
break;
|
||
}
|
||
found = 1;
|
||
break;
|
||
}
|
||
}
|
||
if (!found) {
|
||
printf("未找到ID为 %d 的歌曲\n", songId);
|
||
}
|
||
// ShowPlayQueue();
|
||
break;
|
||
}
|
||
case 2:
|
||
ShowPlayQueue();
|
||
break;
|
||
case 3: {
|
||
int control;
|
||
printf("请输入控制命令 (0.停止|1.暂停|2.继续|3.下一首): ");
|
||
scanf("%d", &control);
|
||
while (getchar() != '\n');
|
||
ControlPlayback(control);
|
||
break;
|
||
}
|
||
case 0:
|
||
printf("⚠️停止音乐中...⚠️\n");
|
||
system("pkill afplay");
|
||
printf("⚠️音乐已停止,返回控制台中...⚠️\n");
|
||
return;
|
||
default:
|
||
printf("无效的选择,请重新输入\n");
|
||
}
|
||
}
|
||
} else {
|
||
printf("⚠️找不到歌曲...⚠️\n");
|
||
}
|
||
}
|
||
|
||
int C3_User() {
|
||
while (1) {
|
||
printf("\n---------------------👇用户控制面板👇----------------------\n");
|
||
printf("1. 歌曲查询\n");
|
||
printf("2. 歌曲游览\n");
|
||
printf("3. 开始点歌\n");
|
||
printf("0.返回控制台\n");
|
||
printf("-----------------------👆选择对应数字👆------------------------\n");
|
||
printf("请输入选择:");
|
||
int opt;
|
||
scanf("%d", &opt);
|
||
while (getchar() != '\n');
|
||
switch (opt) {
|
||
case 1:
|
||
Song_query();
|
||
break;
|
||
case 2:
|
||
BrowseSongs();
|
||
break;
|
||
case 3:
|
||
Start_Muisc();
|
||
break;
|
||
case 0:
|
||
printf("⚠️返回主控制台中...⚠️\n");
|
||
return 0;
|
||
default:
|
||
printf("⚠️输入有误,请重新输入⚠️\n");
|
||
break;
|
||
}
|
||
}
|
||
}
|