361 lines
10 KiB
C
Executable File
361 lines
10 KiB
C
Executable File
/*================================================================
|
||
* Copyright (C) 2018 FREEDOM Ltd. All rights reserved.
|
||
*
|
||
* 文件名称:music.c
|
||
* 创 建 者:chenjie.gu
|
||
* 创建日期:2018年05月24日
|
||
* 描 述:
|
||
*
|
||
================================================================*/
|
||
|
||
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include "audio_player.h"
|
||
#include <time.h>
|
||
#include "cJSON.h"
|
||
#include <unistd.h>
|
||
#include <pthread.h>
|
||
#include <stdbool.h>
|
||
|
||
audio_player_t *aplayer = NULL;
|
||
float vol_multiplier = 0.4;
|
||
int player_is_end = 0;
|
||
pthread_mutex_t music_mutex;
|
||
|
||
int play_judge_f(int index, int count, int mode);
|
||
void play_manager_f(const char *cmd, const char *data);
|
||
|
||
static int g_player_ev = AUDIO_PLAYER_EV_END;
|
||
|
||
bool music_is_playing(void) {
|
||
if (g_player_ev == AUDIO_PLAYER_EV_END ||
|
||
g_player_ev == AUDIO_PLAYER_EV_ERROR ||
|
||
g_player_ev == AUDIO_PLAYER_EV_STOPPED)
|
||
return false;
|
||
else
|
||
return true;
|
||
}
|
||
|
||
static int play_callback(void *userdata, int ev) {
|
||
printf("++++++%s: ev %d\n", __func__, ev);
|
||
if (ev == AUDIO_PLAYER_EV_END) {
|
||
player_is_end = 1;
|
||
}
|
||
|
||
g_player_ev = ev;
|
||
return 0;
|
||
}
|
||
|
||
void *player_routine(void *user) {
|
||
while (1) {
|
||
if (player_is_end) {
|
||
player_is_end = 0;
|
||
play_manager_f("player.end", NULL);
|
||
}
|
||
usleep(100 * 1000);
|
||
}
|
||
return (void *)0;
|
||
}
|
||
|
||
int music_player_init(char *dev) {
|
||
aplayer = audio_player_new(dev, play_callback, NULL);
|
||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||
pthread_mutex_init(&music_mutex, NULL);
|
||
return 0;
|
||
}
|
||
|
||
int music_player_play(char *path) {
|
||
audio_player_play(aplayer, path);
|
||
}
|
||
|
||
int music_player_start() {
|
||
int ret;
|
||
pthread_t tid;
|
||
pthread_create(&tid, NULL, player_routine, NULL);
|
||
|
||
return 0;
|
||
}
|
||
|
||
void play_manager_f(const char *cmd, const char *data) {
|
||
|
||
/*
|
||
* 1. volume.set
|
||
* 2. play.list.update
|
||
* 3. play.list.clear
|
||
* 4. play.list.get
|
||
* 5. status.set
|
||
* 6. change.set
|
||
* 7. mode.set
|
||
* 8. play.choose.update
|
||
* 9. play.collect.choose
|
||
* 10. play.uncollect.choose
|
||
* 11. player.end
|
||
*/
|
||
|
||
enum PLAY_MODE {
|
||
sequence, random, single, loop
|
||
};
|
||
|
||
enum PLAY_STATUS {
|
||
idle, pause, playing
|
||
};
|
||
|
||
static enum PLAY_MODE mode = sequence;
|
||
static enum PLAY_STATUS status = idle;
|
||
static int count = 0;
|
||
static int index = 0;
|
||
static int old_index = 0;
|
||
static cJSON *root = NULL;
|
||
|
||
printf("play_manager_f cmd: %s\tdata: %s\n", cmd, data);
|
||
|
||
pthread_mutex_lock(&music_mutex);
|
||
|
||
if (!strcmp(cmd, "volume.set")) {
|
||
// 设置音量
|
||
if (!strcmp(data, "+")) {
|
||
vol_multiplier += 0.05;
|
||
if (vol_multiplier > 1.0) vol_multiplier = 0.99;
|
||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||
|
||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||
}
|
||
|
||
else if (!strcmp(data, "-")) {
|
||
vol_multiplier -= 0.05;
|
||
if (vol_multiplier < 0.01) vol_multiplier = 0.01;
|
||
|
||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||
}
|
||
else {
|
||
int vol = atoi(data);
|
||
vol_multiplier = vol / 100.0;
|
||
|
||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||
}
|
||
}
|
||
|
||
else if (!strcmp(cmd, "play.list.clear")) {
|
||
// 清空播放列表
|
||
printf("clear the play list info\n");
|
||
audio_player_stop(aplayer);
|
||
cJSON_Delete(root);
|
||
root = NULL;
|
||
index = 0;
|
||
old_index = 0;
|
||
count = 0;
|
||
status = idle;
|
||
}
|
||
|
||
else if (!strcmp(cmd, "play.list.get")) {
|
||
}
|
||
else if (!strcmp(cmd, "play.list.check")) {
|
||
// 开始真正播放
|
||
cJSON *temp, *music;
|
||
if (root) {
|
||
if (status == idle) {
|
||
temp = cJSON_GetObjectItem(root, "count");
|
||
count = temp->valueint;
|
||
if (count > 0) {
|
||
status = playing;
|
||
music = cJSON_GetObjectItem(root, "content");
|
||
temp = cJSON_GetArrayItem(music, index);
|
||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||
printf("ready to play url is %s\n", temp->valuestring);
|
||
audio_player_play(aplayer, temp->valuestring);
|
||
}
|
||
}
|
||
else if (status == pause) {
|
||
status = playing;
|
||
audio_player_resume(aplayer);
|
||
}
|
||
}
|
||
}
|
||
else if (!strcmp(cmd, "play.list.update")) {
|
||
// 更新播放列表
|
||
// TODO: update
|
||
printf("update the play list info\n");
|
||
audio_player_stop(aplayer);
|
||
if (root) cJSON_Delete(root);
|
||
root = NULL;
|
||
index = 0;
|
||
old_index = 0;
|
||
count = 0;
|
||
status = idle;
|
||
root = cJSON_Parse(data);
|
||
}
|
||
else if (!strcmp(cmd, "status.set")) {
|
||
// 设置播放状态
|
||
printf("status.set data is %s status is %d\n", data, status);
|
||
if (!strcmp(data, "pause") && status == playing) {
|
||
status = pause;
|
||
audio_player_pause(aplayer);
|
||
}
|
||
else if (!strcmp(data, "resume") && status == pause) {
|
||
status = playing;
|
||
audio_player_resume(aplayer);
|
||
}
|
||
else if (!strcmp(data, "replay") && status == pause) {
|
||
status = playing;
|
||
|
||
cJSON *temp, *music;
|
||
music = cJSON_GetObjectItem(root, "content");
|
||
temp = cJSON_GetArrayItem(music, index);
|
||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||
printf("ready to play url is %s\n", temp->valuestring);
|
||
audio_player_stop(aplayer);
|
||
audio_player_play(aplayer, temp->valuestring);
|
||
}
|
||
else if (!strcmp(data, "step")) {
|
||
if (status == playing) {
|
||
status = pause;
|
||
audio_player_pause(aplayer);
|
||
}
|
||
else if (status == pause) {
|
||
status = playing;
|
||
audio_player_resume(aplayer);
|
||
}
|
||
}
|
||
}
|
||
else if (!strcmp(cmd, "mode.set")) {
|
||
// 播放模式
|
||
if (!strcmp(data, "sequence")) mode = sequence;
|
||
else if (!strcmp(data, "random")) mode = random;
|
||
else if (!strcmp(data, "single")) mode = single;
|
||
else if (!strcmp(data, "loop")) mode = loop;
|
||
}
|
||
else if (!strcmp(cmd, "change.set")) {
|
||
// 歌曲切换
|
||
// TODO: update
|
||
if (!strcmp(data, "prev")) {
|
||
// 上一首
|
||
index = old_index;
|
||
}
|
||
else if (!strcmp(data, "next")) {
|
||
// 下一首
|
||
old_index = index;
|
||
index = play_judge_f(index, count, mode);
|
||
}
|
||
else if (!strcmp(data, "change")) {
|
||
// 换一首
|
||
old_index = index;
|
||
index = play_judge_f(index, count, mode);
|
||
}
|
||
|
||
if (index == -1) {
|
||
// 播放结束
|
||
cJSON_Delete(root);
|
||
audio_player_stop(aplayer);
|
||
root = NULL;
|
||
index = 0;
|
||
old_index = 0;
|
||
count = 0;
|
||
status = idle;
|
||
}
|
||
else {
|
||
// 待播放指定的音频
|
||
status = idle;
|
||
}
|
||
}
|
||
else if (!strcmp(cmd, "play.choose.update")) {
|
||
// 播放特定歌曲
|
||
// TODO: update
|
||
int find = 0;
|
||
int i = 0;
|
||
cJSON *temp = cJSON_Parse(data);
|
||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||
|
||
cJSON *music = cJSON_GetObjectItem(root, "content");
|
||
cJSON *xx;
|
||
for (i = 0; i < count; i++) {
|
||
xx = cJSON_GetArrayItem(music, i);
|
||
xx = cJSON_GetObjectItem(xx, "linkUrl");
|
||
if (!strcmp(xx->valuestring, temp->valuestring)) {
|
||
find = 1;
|
||
break;
|
||
}
|
||
}
|
||
if (find) {
|
||
old_index = index;
|
||
index = i;
|
||
printf("ready to play url is %s\n", temp->valuestring);
|
||
audio_player_stop(aplayer);
|
||
audio_player_play(aplayer, temp->valuestring);
|
||
}
|
||
else {
|
||
// 播放歌曲不在播放列表里面
|
||
printf("wwwwwwwwwwwwwwwwwwwwwwwwwww\n");
|
||
}
|
||
}
|
||
else if (!strcmp(cmd, "play.collect.choose")) {
|
||
// 收藏歌曲
|
||
}
|
||
|
||
else if (!strcmp(cmd, "play.uncollect.choose")) {
|
||
// 取消收藏
|
||
}
|
||
|
||
else if (!strcmp(cmd, "player.end") && root) {
|
||
// 播放器播放结束
|
||
// TODO: update
|
||
old_index = index;
|
||
index = play_judge_f(index, count, mode);
|
||
printf("play_judge_f index is %d\n", index);
|
||
if (index == -1) {
|
||
// 播放结束
|
||
audio_player_stop(aplayer);
|
||
cJSON_Delete(root);
|
||
root = NULL;
|
||
index = 0;
|
||
old_index = 0;
|
||
count = 0;
|
||
status = idle;
|
||
}
|
||
else {
|
||
// 播放指定的音频
|
||
cJSON *temp, *music;
|
||
music = cJSON_GetObjectItem(root, "content");
|
||
temp = cJSON_GetArrayItem(music, index);
|
||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||
printf("ready to play url is %s\n", temp->valuestring);
|
||
audio_player_stop(aplayer);
|
||
audio_player_play(aplayer, temp->valuestring);
|
||
}
|
||
}
|
||
|
||
pthread_mutex_unlock(&music_mutex);
|
||
}
|
||
|
||
int play_judge_f(int index, int count, int mode) {
|
||
// sequence, random, single, loop
|
||
if (mode == 0) {
|
||
// 顺序播放
|
||
if (index + 1 == count) return -1;
|
||
else return index + 1;
|
||
}
|
||
else if (mode == 1) {
|
||
// 随机播放
|
||
srand(time(0));
|
||
return rand() % count;
|
||
}
|
||
else if (mode == 2) {
|
||
// 单曲循环
|
||
return index;
|
||
}
|
||
else if (mode == 3) {
|
||
// 循环播放
|
||
return (index + 1) % count;
|
||
}
|
||
|
||
else return -1;
|
||
}
|
||
|
||
|