/* * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef CONFIG_XPLAYER #include "cmd_util.h" #include #include #include #include #include "xplayer.h" #include "xrecord.h" #include "CaptureControl.h" #include "driver/chip/hal_snd_card.h" #include "audio/manager/audio_manager.h" // #define CEDARX_SUPPORT_ICY // #define CEDARX_UPDATE_HTTPS static struct KeyValuePairS cedarx_http_header[] = { { "User-Agent", "Mozilla/5.0 (FreeRTOS; OS 10.2.1) Xradio Xradio/1.0", }, #ifdef CEDARX_SUPPORT_ICY { "Icy-MetaData", "0", }, #endif #ifdef CEDARX_UPDATE_HTTPS { "upgrade-insecure-requests", "1", }, #endif }; extern SoundCtrl *SoundDeviceCreate(); typedef struct DemoPlayerContext { XPlayer *mAwPlayer; int mSeekable; int mError; CdxKeyedVectorT *pHeaders; } DemoPlayerContext; static void set_source(DemoPlayerContext *demoPlayer, char *pUrl) { demoPlayer->mSeekable = 1; //* set url to the AwPlayer. if (XPlayerSetDataSourceUrl(demoPlayer->mAwPlayer, (const char *)pUrl, NULL, demoPlayer->pHeaders) != 0) { printf("error:\n"); printf(" AwPlayer::setDataSource() return fail.\n"); return; } printf("setDataSource end\n"); if ((!strncmp(pUrl, "http://", 7)) || (!strncmp(pUrl, "https://", 8)) || (!strncmp(pUrl, "fifo://", 7))) { if (XPlayerPrepareAsync(demoPlayer->mAwPlayer) != 0) { printf("error:\n"); printf(" AwPlayer::prepareAsync() return fail.\n"); return; } } printf("preparing...\n"); } static void play(DemoPlayerContext *demoPlayer) { if (XPlayerStart(demoPlayer->mAwPlayer) != 0) { printf("error:\n"); printf(" AwPlayer::start() return fail.\n"); return; } printf("playing.\n"); } static void pause(DemoPlayerContext *demoPlayer) { if (XPlayerPause(demoPlayer->mAwPlayer) != 0) { printf("error:\n"); printf(" AwPlayer::pause() return fail.\n"); return; } printf("paused.\n"); } static void stop(DemoPlayerContext *demoPlayer) { if (XPlayerReset(demoPlayer->mAwPlayer) != 0) { printf("error:\n"); printf(" AwPlayer::reset() return fail.\n"); return; } printf("stopped.\n"); } //* a callback for awplayer. static int CallbackForAwPlayer(void *pUserData, int msg, int ext1, void *param) { DemoPlayerContext *pDemoPlayer = (DemoPlayerContext *)pUserData; switch (msg) { case AWPLAYER_MEDIA_INFO: { switch (ext1) { case AW_MEDIA_INFO_NOT_SEEKABLE: { pDemoPlayer->mSeekable = 0; printf("info: media source is unseekable.\n"); break; } case AW_MEDIA_INFO_RENDERING_START: { printf("info: start to show pictures.\n"); break; } } break; } case AWPLAYER_MEDIA_ERROR: { printf("error: open media source fail.\n"); pDemoPlayer->mError = 1; loge(" error : how to deal with it"); break; } case AWPLAYER_MEDIA_PREPARED: { logd("info : preared"); printf("info: prepare ok.\n"); break; } case AWPLAYER_MEDIA_PLAYBACK_COMPLETE: { printf("info: play complete.\n"); break; } case AWPLAYER_MEDIA_SEEK_COMPLETE: { printf("info: seek ok.\n"); break; } case AWPLAYER_MEDIA_CHANGE_URL: { printf("suggest to play:%s\n", (char *)param); break; } default: { //printf("warning: unknown callback from AwPlayer.\n"); break; } } return 0; } static DemoPlayerContext *demoPlayer; static enum cmd_status cmd_cedarx_create_exec(char *cmd) { demoPlayer = malloc(sizeof(*demoPlayer)); audio_manager_handler(AUDIO_SND_CARD_DEFAULT, AUDIO_MANAGER_SET_VOLUME_LEVEL, AUDIO_OUT_DEV_SPK, 14); //* create a player. memset(demoPlayer, 0, sizeof(DemoPlayerContext)); demoPlayer->mAwPlayer = XPlayerCreate(); if (demoPlayer->mAwPlayer == NULL) { printf("can not create AwPlayer, quit.\n"); return -1; } else { printf("create AwPlayer success.\n"); } //* set callback to player. XPlayerSetNotifyCallback(demoPlayer->mAwPlayer, CallbackForAwPlayer, (void *)demoPlayer); //* check if the player work. if (XPlayerInitCheck(demoPlayer->mAwPlayer) != 0) { printf("initCheck of the player fail, quit.\n"); XPlayerDestroy(demoPlayer->mAwPlayer); demoPlayer->mAwPlayer = NULL; return -1; } else printf("AwPlayer check success.\n"); SoundCtrl *sound = SoundDeviceCreate(); XPlayerSetAudioSink(demoPlayer->mAwPlayer, (void *)sound); int header_count = sizeof(cedarx_http_header) / sizeof(struct KeyValuePairS); demoPlayer->pHeaders = malloc(sizeof(CdxKeyedVectorT) + header_count * sizeof(KeyValuePairT)); if (demoPlayer->pHeaders) { demoPlayer->pHeaders->size = header_count; for (int i = 0; i < demoPlayer->pHeaders->size; i++) { demoPlayer->pHeaders->item[i].key = cedarx_http_header[i].key; demoPlayer->pHeaders->item[i].val = cedarx_http_header[i].val; } } return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_destroy_exec(char *cmd) { if (demoPlayer->mAwPlayer != NULL) { XPlayerDestroy(demoPlayer->mAwPlayer); demoPlayer->mAwPlayer = NULL; } free(demoPlayer->pHeaders); printf("destroy AwPlayer.\n"); free(demoPlayer); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_play_exec(char *cmd) { play(demoPlayer); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_stop_exec(char *cmd) { stop(demoPlayer); msleep(5); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_pause_exec(char *cmd) { pause(demoPlayer); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_seturl_exec(char *cmd) { set_source(demoPlayer, cmd); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_getpos_exec(char *cmd) { int msec; XPlayerGetCurrentPosition(demoPlayer->mAwPlayer, &msec); cmd_write_respond(CMD_STATUS_OK, "played time: %d ms", msec); return CMD_STATUS_ACKED; } static enum cmd_status cmd_cedarx_seek_exec(char *cmd) { int nSeekTimeMs = atoi(cmd); XPlayerSeekTo(demoPlayer->mAwPlayer, nSeekTimeMs); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_setvol_exec(char *cmd) { int vol = atoi(cmd); if (vol > 31) vol = 31; audio_manager_handler(AUDIO_SND_CARD_DEFAULT, AUDIO_MANAGER_SET_VOLUME_LEVEL, AUDIO_OUT_DEV_SPK, vol); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_playdic_exec(char *cmd) { return CMD_STATUS_OK; } static XRecord *xrecord; static enum cmd_status cmd_cedarx_rec_exec(char *cmd) { XRECODER_AUDIO_ENCODE_TYPE type; if (strstr(cmd, ".amr")) type = XRECODER_AUDIO_ENCODE_AMR_TYPE; else if (strstr(cmd, ".pcm")) type = XRECODER_AUDIO_ENCODE_PCM_TYPE; else { printf("do not support this encode type\n"); return CMD_STATUS_INVALID_ARG; } audio_manager_handler(AUDIO_SND_CARD_DEFAULT, AUDIO_MANAGER_SET_VOLUME_LEVEL, AUDIO_IN_DEV_AMIC, 3); xrecord = XRecordCreate(); if (xrecord == NULL) { printf("xrecord create failed\n"); return CMD_STATUS_FAIL; } CaptureCtrl *cap = CaptureDeviceCreate(); if (!cap) { printf("cap device create failed\n"); XRecordDestroy(xrecord); xrecord = NULL; return CMD_STATUS_FAIL; } XRecordSetAudioCap(xrecord, cap); XRecordConfig audioConfig; audioConfig.nChan = 1; audioConfig.nSamplerate = 8000; audioConfig.nSamplerBits = 16; audioConfig.nBitrate = 12200; XRecordSetDataDstUrl(xrecord, cmd, NULL, NULL); XRecordSetAudioEncodeType(xrecord, type, &audioConfig); XRecordPrepare(xrecord); XRecordStart(xrecord); printf("record start\n"); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_end_exec(char *cmd) { XRecordStop(xrecord); XRecordDestroy(xrecord); printf("record destroy\n"); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_log_exec(char *cmd) { int level = atoi(cmd); if (level > 6) level = 6; void log_set_level(unsigned level); log_set_level(level); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_version_exec(char *cmd) { XPlayerShowVersion(); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_showbuf_exec(char *cmd) { XPlayerShowBuffer(); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_setbuf_exec(char *cmd) { int argc; char *argv[4]; XPlayerBufferConfig cfg; int maxAudioFrameSize; argc = cmd_parse_argv(cmd, argv, 4); if (argc < 4) { CMD_ERR("invalid cedarx set buf cmd, argc %d\n", argc); goto exit; } cfg.maxStreamBufferSize = cmd_atoi(argv[0]); cfg.maxBitStreamBufferSize = cmd_atoi(argv[1]); cfg.maxPcmBufferSize = cmd_atoi(argv[2]); cfg.maxStreamFrameCount = 0; cfg.maxBitStreamFrameCount = 0; cfg.maxMovStszBufferSize = 0; cfg.maxMovStcoBufferSize = 0; maxAudioFrameSize = cmd_atoi(argv[3]); XPlayerSetBuffer(demoPlayer->mAwPlayer, &cfg); XPlayerSetPcmFrameSize(demoPlayer->mAwPlayer, maxAudioFrameSize); XPlayerShowBuffer(); exit: return CMD_STATUS_OK; } extern void CdxBufAutoStatStart(void); static enum cmd_status cmd_cedarx_bufinfo_exec(char *cmd) { CdxBufAutoStatStart(); return CMD_STATUS_OK; } static enum cmd_status cmd_cedarx_aacsbr_exec(char *cmd) { int use_sbr = atoi(cmd); if (demoPlayer->mAwPlayer) { XPlayerSetAacSbr(demoPlayer->mAwPlayer, use_sbr); printf("set aac sbr success\n"); } else { printf("set aac sbr fail\n"); } return CMD_STATUS_OK; } /* * brief cedarx Test Command * cedarx play * cedarx stop * cedarx pause * cedarx seturl file://music/01.mp3 * cedarx getpos * cedarx seek 6000 * cedarx setvol 8 * cedarx playdic file://music * cedarx rec file://record/wechat.amr * cedarx end */ static enum cmd_status cmd_cedarx_help_exec(char *cmd); static const struct cmd_data g_cedarx_cmds[] = { { "create", cmd_cedarx_create_exec, CMD_DESC("create cedarx object") }, { "destroy", cmd_cedarx_destroy_exec, CMD_DESC("destroy cedarx object") }, { "play", cmd_cedarx_play_exec, CMD_DESC("cedarx play") }, { "stop", cmd_cedarx_stop_exec, CMD_DESC("cedarx stop") }, { "pause", cmd_cedarx_pause_exec, CMD_DESC("cedarx pause") }, { "seturl", cmd_cedarx_seturl_exec, CMD_DESC("set url, eg. cedarx seturl file://music/01.mp3") }, { "getpos", cmd_cedarx_getpos_exec, CMD_DESC("get current position") }, { "seek", cmd_cedarx_seek_exec, CMD_DESC("seek to position, eg. cedarx seek 6000") }, { "setvol", cmd_cedarx_setvol_exec, CMD_DESC("set volume, 0~31, eg. cedarx setvol 8") }, { "playdic", cmd_cedarx_playdic_exec, CMD_DESC("not support") }, { "log", cmd_cedarx_log_exec, CMD_DESC("set log level") }, { "version", cmd_cedarx_version_exec, CMD_DESC("show version") }, { "showbuf", cmd_cedarx_showbuf_exec, CMD_DESC("show buffer") }, { "setbuf", cmd_cedarx_setbuf_exec, CMD_DESC("set buffer size") }, { "bufinfo", cmd_cedarx_bufinfo_exec, CMD_DESC("show buffer info") }, { "aacsbr", cmd_cedarx_aacsbr_exec, CMD_DESC("set use aac sbr") }, { "rec", cmd_cedarx_rec_exec, CMD_DESC("record start, eg. cedarx rec file://record/wechat.amr or wechat.pcm") }, { "end", cmd_cedarx_end_exec, CMD_DESC("record destroy") }, { "help", cmd_cedarx_help_exec, CMD_DESC(CMD_HELP_DESC) }, }; static enum cmd_status cmd_cedarx_help_exec(char *cmd) { return cmd_help_exec(g_cedarx_cmds, cmd_nitems(g_cedarx_cmds), 8); } enum cmd_status cmd_cedarx_exec(char *cmd) { return cmd_exec(cmd, g_cedarx_cmds, cmd_nitems(g_cedarx_cmds)); } #endif /* CONFIG_XPLAYER */