1. LVGL8 自带的有一个音乐播放器的Demo,效果不错,充分展示了LVGL8的弹性网格布局,动画等效果,来学习GUI是非常不错的,只是这个Demo并不能真正的播放音乐,但是已经把音乐播放的逻辑都给实现了,现在我们就动手给它注入灵魂----mpv
  2. 最初是用的sox这个号称音频界的瑞士军刀的工具,但是编写过程中碰到一个比较棘手的问题,那就是无法使用管道重定向输出(play本身不支持管道,只能借助sox),也就没办法获取播放进度,会造成进度条时间与实际播放时间有点误差,最后就放弃使用sox了

        if (pid == 0){LOG_D("child pid:%d\n", getpid());char cmd[32];prctl(PR_SET_PDEATHSIG, SIGKILL);close(0);dup2(pip[1], 1); //标准输出重定向到管道输出close(pip[0]);sprintf(buf, "./music/%s", _lv_demo_music_get_title(track_id));sprintf(cmd, "--start=%d", _time, _lv_demo_music_get_track_length(track_id));// execlp("ls", "ls", "./music", NULL);// execlp("play", "play", "-p", buf, "trim", cmd, NULL);// execlp("sox", "sox", buf, "-p", "|", "play", "-", "trim", cmd, NULL);//最后知道怎么使用管道了,但是这是2个进程// sox ./music/云非非\ -\ 邂逅.flac -t flac - | play -t flac - &// sox ./music/云非非\ -\ 邂逅.flac -t flac - | play - &// sox ./music/云非非\ -\ 邂逅.flac -p | play - &return 0;}
  1. 下边请出在后台默默工作的大佬MPV

    MPV播放器是什么?

    MPV是著名开源播放器mplayer和mplayer2的一个分支。
    mplayer则是这个地球上最强的播放器(没有之一),跨平台的特性使得windows、mac、linux上都可以见到它的身影,电脑、手机上很多播放器也是基于它开发的,由于mplayer不带界面,所以很多时候你都不知道是它在默默为你工作。
    并且mplayer播放视频时对于资源的消耗往往最少,所以你会发现在一台配置极差的电脑上播放高清电影,mplayer通常是最流畅的,使用快进时最能体现出差距,其他播放器已经画面卡死时,mplayer的画面可能只是感觉到掉帧而已。
    MPV播放器继承这些众多优良特性的同时,添加了内置于窗口的播放控制界面(OSC),对硬解的良好支持,以及其他额外特性。由于口碑很好,使得著名的mplayer前端:smplayer在不久前也添加了对MPV的支持,现在的smplayer你可以在mplayer和MPV2个核心之间切换使用。
    mpv官网的开发文档比较好,参考使用手册都可以使用起来

  2. 下边简单说一下过程
    a.首先要获取播放列表 播放列表里的字体是浪漫雅圆,使用freetype渲染的 。获取列表有2种方法

      方法1:int scan_music_list(char *_path){char path[128];sprintf(path, "ls %s", _path);FILE *fp = popen(path, "r");if (ferror(fp)){LOG_D("error\n");}char buf[128];while (!feof(fp)){fgets(buf, sizeof(buf), fp);strncpy(title_list[idx], buf, strlen(buf) - 1); //去掉文件名后的\nget_music_info(title_list[idx], idx);idx++;usleep(1);}return idx;} 
     方法2:int list_dir(char *path, int depth){DIR *dir;struct dirent *file;struct stat st;dir = opendir(path);if (!dir){LOG_D("open dir %s failed!", path);return -1;}LOG_D("open dir %s ok!", path);while ((file = readdir(dir)) != NULL){if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0){continue;}strcpy(title_list[idx++], file->d_name);if (stat(file->d_name, &st) >= 0 && S_ISDIR(st.st_mode) && depth <= 5){list_dir(file->d_name, depth + 1);}}closedir(dir);return 0;}      ```
    

    b.程序启动时创建一个子进程,一个线程获取播放进度,一个线程获取各种输入

      void lv_demo_music(void){lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x343247), 0);music_num = scan_music_list(MUSIC_PATH);list = _lv_demo_music_list_create(lv_scr_act());ctrl = _lv_demo_music_main_create(lv_scr_act());pid = vfork();if (pid == 0){LOG_D("child pid:%d\n", getpid());prctl(PR_SET_PDEATHSIG, SIGKILL);execlp("mpv", "mpv", "--quiet", "--no-terminal", "--no-video", "--idle=yes", "--term-status-msg=", "--input-ipc-server=/tmp/mpvsocket", NULL);LOG_D("child exit!\n");return 0;}else if (pid > 0){LOG_D("parent pid:%d\n", getpid());sleep(1);close(0);act.sa_handler = sigusr1;sigfillset(&act.sa_mask);act.sa_flags = SA_RESTART; /* don't fiddle with EINTR */sigaction(SIGUSR1, &act, NULL);addr.sun_family = AF_UNIX;strcpy(addr.sun_path, "/tmp/mpvsocket");fd_mpv = socket(AF_UNIX, SOCK_STREAM, 0);if (fd_mpv == -1){LOG_D("Create socket failed\n");}if (connect(fd_mpv, (struct sockaddr *)&addr, sizeof(addr)) == -1){LOG_D("Cannot connect to socket %s\n", addr.sun_path);}if (pthread_create(&mthread, NULL, get_music_percent_pos, NULL) != 0){LOG_D("pthread create error!\n");return 0;}// LOG_D("get music pos pthread create ok!\n");}else{LOG_D("fork error:\n");}#if LV_DEMO_MUSIC_AUTO_PLAYlv_timer_create(auto_step_cb, 1000, NULL);#endif}这里说明一下mpv里的参数"--quiet", //输出尽量少的信息"--no-terminal", //不接受终端输入"--no-video", //不需要视频"--idle=yes", //播放完不能出进程"--term-status-msg=", //状态信息不打印"--input-ipc-server=/tmp/mpvsocket"//使用sock方式与mpv通信这里使用的是mpv推荐的基于socket的JSON-based IPC protocol通信方式
    

    c. 一个线程启动时向mpv发送命令,然后监听事件就可以知道当前进度及状态

      void *get_music_percent_pos(void *arg){// char cmd[] = "{\"command\": [ \"get_property\", \"playback-time\"] }\n";// char cmd[] = "{\"command\": [ \"get_property\", \"percent-pos\"] ,\"request_id\":2}\n";char cmd2[] = "{\"command\": [ \"observe_property\",2, \"percent-pos\"]}\n";char cmd1[] = "{\"command\": [  \"observe_property\",1,\"time-pos\"]}\n";char buf[512];cJSON *root;cJSON *event;cJSON *percent;write(fd_mpv, cmd1, strlen(cmd1));_msleep(100);write(fd_mpv, cmd2, strlen(cmd2));memset(buf, 0, sizeof(buf));while (1){if (read(fd_mpv, buf, sizeof(buf)) > 0){//LOG_D("--->:%s\n", buf);root = cJSON_Parse(buf);if (root == NULL){LOG_D("cJSON parse error!\n");return;}// LOG_D("cJSON parse ok!\n");if (cJSON_HasObjectItem(root, "event")){event = cJSON_GetObjectItem(root, "event");if (event != NULL){if (strcmp(event->valuestring, "start-file") == 0){}else if (strcmp(event->valuestring, "metadata-update") == 0){}else if (strcmp(event->valuestring, "file-loaded") == 0){}else if (strcmp(event->valuestring, "property-change") == 0 && (cJSON_GetObjectItem(root, "id")->valueint == 1)){percent = cJSON_GetObjectItem(root, "data");lv_label_set_text_fmt(time_obj, "%02d:%02d", (int)percent->valuedouble / 60, (int)percent->valuedouble % 60);LOG_D("time pos:%d\n", (int)percent->valuedouble);}else if (strcmp(event->valuestring, "property-change") == 0 && (cJSON_GetObjectItem(root, "id")->valueint == 2)){percent = cJSON_GetObjectItem(root, "data");lv_slider_set_value(slider_obj, (int)percent->valuedouble, LV_ANIM_ON);LOG_D("percent pos:%d\n", (int)percent->valuedouble);}else if (strcmp(event->valuestring, "end-file") == 0){LOG_D("end-file\n");is_loaded = true;_lv_demo_music_album_next(true);}else if (strcmp(event->valuestring, "playback-restart") == 0){}else if (strcmp(event->valuestring, "idle") == 0){LOG_D("idle\n");}}}free(root);}//_msleep(250);}pthread_exit(NULL);LOG_D("pthread exit:\n");}这里通信都是采用JSON格式,使用了cJSON来解析送来的数据``````
    
  3. 这些实现完成后,音乐播放器也就有了灵魂,就是一个真正的音乐播放器了,几乎支持所有音乐格式,我测试的常见的有wav,mp3,flac,ape,dts等
  4. 效果预览 (240*320) 项目位置:D1扩展板

原贴链接:https://bbs.aw-ol.com/topic/435/
全志在线开发者交流企鹅群(客服机器人24小时在线解答):498263967
资源获取、问题讨论可以到全志在线开发者社区进行:https://www.aw-ol.com/
全志及开发者最新动态可以关注全志在线微信公众号

基于全志D1-H哪吒让LVGL8带的Music-Demo音乐响起来相关推荐

  1. 基于Wemos D1的感应开盖垃圾桶

    参考:基于Wemos D1的感应开盖垃圾桶(增加自己的代码实现部分) 作者:LEO-max 发布时间:2020-12-29 15:21:26 网址:https://blog.csdn.net/zouc ...

  2. 基于Wemos D1避障WiFi小车及智能垃圾桶设计

    基于Wemos D1避障WiFi小车及智能垃圾桶设计 一.实验器材 主控芯片 Wemos D1 其他器材 HC-SR04超声波.L9110s电机.ESP82660WiFi模块.蜂鸣器 所需设备 TCP ...

  3. 基于MPI的H.264并行编码代码移植与优化

    2010 03 25 基于MPI的H.264并行编码代码移植与优化 范 文 洛阳理工学院计算机信息工程系 洛阳 471023 摘 要 H.264获得出色压缩效果和质量的代价是压缩编码算法复杂度的增加. ...

  4. 基于IP的H.264关键技术

    一. 引言 H.264是ITU-T最新的视频编码标准,被称作ISO/IEC14496-10或MPEG-4 AVC,是由运动图像专家组(MPEG)和ITU的视频编码专家组共同开发的新产品.H.264分两 ...

  5. 稚晖君又整活啦!基于全志F1C200s的超迷你

    转自全志在线 B站最强小电视(基于全志H3) 钢铁侠机械臂 曾经靠着"B站最强小电视"以及号称"钢铁侠机械臂"等硬核产品出圈的稚晖君又双叒叕来整活啦! 稚晖君B ...

  6. 基于ADSP-BF561的H.264视频编码器的实现

    基于ADSP-BF561的H.264视频编码器的实现 [日期:2008-7-14] 来源:中电网  作者:崔海燕,王卿 [字体:大 中 小] <script src="http://w ...

  7. 基于全志A33开发板linux系统移植学习记录(Boot0)

    基于全志A33开发板linux系统移植学习记录 第一章 Boot0基于ARMGCC的编译与修改 文章目录 基于全志A33开发板linux系统移植学习记录 前言 一.全志A33简介以及上电引导流程 二. ...

  8. ajax实现上传文件的进度,基于Ajax技术实现文件上传带进度条

    1.概述 在实际的Web应该开发或网站开发过程中,经常需要实现文件上传的功能.在文件上传过程中,经常需要用户进行长时间的等待,为了让用户及时了解上传进度,可以在上传文件的同时,显示文件的上传进度条.运 ...

  9. 稚晖君又整活啦,基于全志F1C200s的超迷你低成本开发板开源

    B站最强小电视(基于全志H3) 钢铁侠机械臂 曾经靠着"B站最强小电视"以及号称"钢铁侠机械臂"等硬核产品出圈的稚晖君又双叒叕来整活啦! 这次稚晖君开源了基于全 ...

最新文章

  1. MyBatis-Plus,搭配 Spring Boot 使用,一篇就够了
  2. 苹果8参数_八年磨两苹果,日本精致农业“秘密” 打造不一样的智慧农业园区...
  3. HDOJ/HDU 1556 Color the ball(树状数组)
  4. rgb565和rgb555的文件头区别_Windows可执行文件格式
  5. Java演示手机发送短信验证码功能实现
  6. Linux 学习和教训
  7. sublime text3的一些小技巧记录(配gif图)
  8. 三通道HART / Modbus网关HTM-631
  9. 计算机长宽高公式,单位换算公式大集合
  10. 西瓜数据集3.0 python_决策树对西瓜数据集2.0二分类
  11. Springboot中自动转JSON输出
  12. 苹果开发者账号双重验证忘记密保终极解决办法
  13. linux计算机连接PEAP企业网的wi-fi
  14. 简述计算机数控系统的工作原理,计算机数控系统复习题-20210321010307.docx-原创力文档...
  15. 一天 第一章 花在花苞未有泪,人见不识无言对
  16. 单主机上,多个Git用户,同时提交下载代码的配置
  17. matlab函数全能速查宝典 pdf,MATLAB函数全能速查宝典
  18. Python分析《权力的游戏》最终季...... | 附源码
  19. easyui datagrid 多列checkbox
  20. 贴片式T卡的测试与应用

热门文章

  1. Camera Metadata原理
  2. 基于opencv 的 fftshift, ifftshift 函数的实现
  3. 回顾|Acala TC5 万圣糖果节历程总结
  4. (全剧终)C/C++ 与 嵌入式软件开发招聘记录(华为、中兴、联发科、海康、大华、oppo、vivo、地平线、科大讯飞、广联达、绿盟、CVTE、诺瓦等)
  5. 记录:element UI table 表格 固定列单元格上下错位
  6. java高级应用,坦克大战的屏幕闪烁问题
  7. Gartner2019年十大安全项目详解
  8. 最火热的季节,却承载着最盛大的离别
  9. jasper生成动态报表
  10. MSYS的下载与安装