/*================================================================ * Copyright (C) 2018 AISPEECH Ltd. All rights reserved. * * 文件名称:music.c * 创 建 者:chenjie.gu * 创建日期:2018年05月24日 * 描 述: * ================================================================*/ #include #include #include #include "audio_player.h" #include #include "cJSON.h" #include #include audio_player_t *aplayer = NULL; float vol_multiplier = 0.8; 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, char **user_data); static int play_callback(void *userdata, int ev) { if (ev == AUDIO_PLAYER_EV_END) { player_is_end = 1; } return 0; } void *player_routine(void *user) { while (1) { if (player_is_end) { player_is_end = 0; play_manager_f("player.end", NULL, NULL); } usleep(100 * 1000); } return (void *)0; } int music_player_init(char *dev) { aplayer = audio_player_new(play_callback, NULL); audio_player_set_device(aplayer, dev); 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, char **user_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 * 12. music.info */ 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, "music.info")) { if (root) { cJSON *temp, *music; music = cJSON_GetObjectItem(root, "content"); temp = cJSON_GetArrayItem(music, index); *user_data = cJSON_Print(temp); } else *user_data = NULL; } 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 = idle; } 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; }