本期分享的是使用进程、mplayer应用使用mplayer命令实现一个媒体播放器的功能,本次使用到的主要有进程间通信(pipe),字符串的操作,多函数功能整合等。

功能主流程图如下:

各个分支模块的流程图如下:

这个就是主流程图以及各个分支函数的细节流程图;

头文件如下:

#ifndef __HEAD_H
#define __HEAD_H#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>/* mplayer 媒体列表 */
typedef struct __media_list__
{char medialist[100][128];      //播放歌曲曲目int curmedialist;               //目录下歌曲个数
}MediaList_t;/* mplayer 播放状态 */
typedef enum __mplayer_stat__
{MPLAYER_STAT_FREE,MPLAYER_STAT_PLAY,MPLAYER_STAT_PAUSE,
}MplayerStat_en;/* mplayer 播放速度 */
typedef enum __mplayer_speed__
{MPLAYER_SPEED_ONE,MPLAYER_SPEED_TWO,MPLAYER_SPEED_FOUR,
}MplayerSpeed_en;/* mplayer 播放模式 */
typedef enum __mplayer_mode__
{MPLAYER_MODE_SINGLE,MPLAYER_MODE_ORDER,MPLAYER_MODE_RANDOM,
}MplayerMode_en;/* mplayer 当前工作状态 */
typedef struct __media_stat__
{MplayerStat_en curstat;MplayerSpeed_en curspeed;MplayerMode_en curmode;int curmedianum;
}MediaStat_t;extern void handler(int signo);extern int showTerminal(void);
extern int choiceMode(void);
extern int loadMediaFile(const char *direntname);extern int listOfMusicFile(void);
extern int Pause(void);
extern int playMedia(char *pMediaPath);
extern int playPause(void);
extern int pthreadOfWork();
extern int Stop(void);
extern int preMusic(void);
extern int nextMusic(void);
extern int addSpeed(void);
extern int seekPosition(void);
extern int changeModeOfWork(void);extern int openLogFile(void);
extern int writeLogFile(const char *errbuf);
extern int closeLogFile(void);
#endif

日志文件的主要实现过程:

#include "head.h"FILE *fp = NULL;
int openLogFile(void)
{fp = fopen("./log.txt", "a");if (NULL == fp){perror("fail to fopen");return -1;}return 0;
}int writeLogFile(const char *errbuf)
{char tmpbuf[1024] = {0};time_t t;struct tm *pp = NULL;time(&t);pp = localtime(&t);sprintf(tmpbuf, "[%d-%d-%d %02d:%02d:%02d]:%s\n", pp->tm_year+1900, pp->tm_mon+1, pp->tm_mday, pp->tm_hour, pp->tm_min, pp->tm_sec, errbuf);fwrite(tmpbuf, 1, strlen(tmpbuf), fp);return 0;
}int closeLogFile(void)
{fclose(fp);return -1;
}

所有的功能代码如下:

#include "head.h"
pid_t pid;MediaList_t MediaList;        //媒体列表结构体
MediaStat_t MplayerStat;    //媒体状态结构体//打印媒体播放器菜单
int showTerminal(void)
{printf("============= 媒体播放器 =============\n");printf("1.查看播放列表\n");printf("2.开始/暂停\n");printf("3.停止\n");printf("4.上一曲\n");printf("5.下一曲\n");printf("6.快进\n");printf("7.定位\n");printf("8.播放方式\n");printf("9.退出\n");printf("======================================\n");return 0;
}//循环打印媒体播放器菜单并进行模式选择
int choiceMode(void)
{int n = -1;while (1){showTerminal();              //显示终端printf("请选择:");scanf("%d", &n);           //输入需要选择的功能序号switch (n)                 //条件分支进行选择执行相应功能{case 1: listOfMusicFile();break;case 2: playPause();break;case 3:  Stop();break;case 4:    preMusic();break;case 5: nextMusic();break;case 6: addSpeed();break;case 7: seekPosition();break;case 8: changeModeOfWork();break;case 9: exit(0);break;}}return 0;
}//判断一个文件是否为媒体文件
int isMediaFile(const char *filename)
{while (filename)           //找到文件后缀的点{if (*filename == '.'){break;}filename++;}if (!strcmp(filename, ".mp3") || !strcmp(filename, ".mp4") || !strcmp(filename, ".flv") || !strcmp(filename, ".avi")){return 1;}return 0;
}//加载媒体文件,使得媒体文件存入二维数组中
int loadMediaFile(const char *direntname)
{DIR *dp = NULL;struct dirent *pp = NULL;MplayerStat.curmode = MPLAYER_MODE_ORDER;       //起初初始化为顺序播放MplayerStat.curstat = MPLAYER_STAT_FREE;       //起初状态设置为空闲状态MplayerStat.curmedianum = 0;                  //当前曲目为0dp = opendir(direntname);                      //打开文件夹if (NULL == dp){writeLogFile("fail to opendir");return -1;}while (1){pp = readdir(dp);                          //读取文件夹下的文件名if (NULL == pp)                               //读到没有文件时结束{break;}if (pp->d_name[0] == '.')                 //忽略隐藏文件{continue;}if (isMediaFile(pp->d_name))              //判断是否为媒体文件{if (MediaList.curmedialist < 100){strcpy(MediaList.medialist[MediaList.curmedialist], pp->d_name);    //储存该媒体文件printf("%s\n", MediaList.medialist[MediaList.curmedialist]);     MediaList.curmedialist++;                                         //媒体文件个数 +1}else{printf("播放列表加载歌曲超过100首\n");                             //最多存储100首break;}}}closedir(dp);return 0;
}//列出目录下的所有媒体文件
int listOfMusicFile(void)
{int n = -1;printf("============= 音乐列表 =============\n");for (n = 0;n < MediaList.curmedialist;++n){puts(MediaList.medialist[n]);}printf("====================================\n");while (1){printf("请选择(按0返回上一级):");scanf("%d", &n);if (n == 0){break;}if (MplayerStat.curstat != MPLAYER_STAT_FREE){kill(pid, SIGKILL);}playMedia(MediaList.medialist[n - 1]);MplayerStat.curmedianum = n -1;}return 0;
}//实现mplayer停止功能
int Pause(void)
{int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "pause\n", 6);close(fd);MplayerStat.curstat = MPLAYER_STAT_PAUSE;return 0;
}//实现继续播放功能
int Continue(void)
{int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "pause\n", 6);close(fd);MplayerStat.curstat = MPLAYER_STAT_PLAY;return 0;
}//播放指定的媒体文件
int playMedia(char *pMediaPath)
{printf("pMediaPath = %s\n", pMediaPath);pid = fork();if (pid < 0){writeLogFile("fail to fork");return -1;}if (pid == 0){close(1);   //关闭stdoutclose(2); //关闭stderrexeclp("mplayer", "mplayer", "-slave", "-input", "file=/tmp/myfifo", pMediaPath, NULL);}MplayerStat.curstat = MPLAYER_STAT_PLAY;MplayerStat.curspeed = MPLAYER_SPEED_ONE;//  wait(NULL);return 0;
}//开始或者暂停播放
int playPause(void)
{printf("进入playPause了\n");if (MplayerStat.curstat == MPLAYER_STAT_FREE){//      printf("1");if (MplayerStat.curmode == MPLAYER_MODE_SINGLE){printf("当前单曲循环\n");playMedia(MediaList.medialist[MplayerStat.curmedianum]);}else if (MplayerStat.curmode == MPLAYER_MODE_ORDER){printf("当前顺序播放\n");playMedia(MediaList.medialist[MplayerStat.curmedianum + 1]);MplayerStat.curmedianum++;}else if (MplayerStat.curmode == MPLAYER_MODE_RANDOM){printf("当前随机播放\n");int ret = -1;srand(time(NULL));ret = rand() % 2;playMedia(MediaList.medialist[ret]);MplayerStat.curmedianum = ret;}}else if (MplayerStat.curstat == MPLAYER_STAT_PLAY){printf("1");Pause();}else if (MplayerStat.curstat == MPLAYER_STAT_PAUSE){printf("1");Continue();}return 0;}//停止播放
int Stop(void)
{int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "quit\n", 5);close(fd);kill(pid, SIGKILL);MplayerStat.curstat = MPLAYER_STAT_FREE;return 0;
}//切换下一曲
int nextMusic(void)
{kill(pid, SIGKILL);playMedia(MediaList.medialist[MplayerStat.curmedianum + 1]);MplayerStat.curmedianum++;return 0;
}//切换上一曲
int preMusic(void)
{kill(pid, SIGKILL);playMedia(MediaList.medialist[MplayerStat.curmedianum - 1]);MplayerStat.curmedianum--;return 0;
}//加速视频播放
int addSpeed(void)
{int fd = -1;char cmdbuf[128] = {0};int n = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}printf("请输入你需要设置的视频速度:");scanf("%d", &n);getchar();sprintf(cmdbuf, "speed_set %d\n", n);write(fd, cmdbuf, strlen(cmdbuf));printf("当前播放%d倍速!\n", n);if (1 == n){MplayerStat.curspeed = MPLAYER_SPEED_ONE;}else if (2 == n){MplayerStat.curspeed = MPLAYER_SPEED_TWO;}else if (4 == n){MplayerStat.curspeed = MPLAYER_SPEED_FOUR;}close(fd);return 0;
}//定位视频播放的位置(秒计时)
int seekPosition(void)
{int fd = -1;char cmdbuf[128] = {0};int n = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}printf("请输入你需要跳转的位置:");scanf("%d", &n);getchar();sprintf(cmdbuf, "seek %d 2\n", n);write(fd, cmdbuf, strlen(cmdbuf));close(fd);return 0;
}//切换视频的播放状态
int changeModeOfWork(void)
{if (MplayerStat.curmode == MPLAYER_MODE_RANDOM){MplayerStat.curmode = MPLAYER_MODE_SINGLE;printf("当前单曲循环\n");}else if (MplayerStat.curmode == MPLAYER_MODE_SINGLE){MplayerStat.curmode = MPLAYER_MODE_ORDER;printf("当前顺序播放\n");}else if (MplayerStat.curmode == MPLAYER_MODE_ORDER){MplayerStat.curmode = MPLAYER_MODE_RANDOM;printf("当前随机播放\n");}return 0;
}//信号处理函数
void handler(int signo)
{int status = 0;wait(&status); //获取进程状态if (WIFSIGNALED(status))    //判断进程是否被信号杀死{return;}else if (WIFEXITED(status))       //判断进程是否正常结束(如果是则按照当前的播放模式继续播放下一首){MplayerStat.curstat = MPLAYER_STAT_FREE;MplayerStat.curspeed = MPLAYER_SPEED_ONE;playPause();}return;
}

主函数如下:

#include "head.h"
pid_t pid;MediaList_t MediaList;        //媒体列表结构体
MediaStat_t MplayerStat;    //媒体状态结构体//打印媒体播放器菜单
int showTerminal(void)
{printf("============= 媒体播放器 =============\n");printf("1.查看播放列表\n");printf("2.开始/暂停\n");printf("3.停止\n");printf("4.上一曲\n");printf("5.下一曲\n");printf("6.快进\n");printf("7.定位\n");printf("8.播放方式\n");printf("9.退出\n");printf("======================================\n");return 0;
}//循环打印媒体播放器菜单并进行模式选择
int choiceMode(void)
{int n = -1;while (1){showTerminal();              //显示终端printf("请选择:");scanf("%d", &n);           //输入需要选择的功能序号switch (n)                 //条件分支进行选择执行相应功能{case 1: listOfMusicFile();break;case 2: playPause();break;case 3:  Stop();break;case 4:    preMusic();break;case 5: nextMusic();break;case 6: addSpeed();break;case 7: seekPosition();break;case 8: changeModeOfWork();break;case 9: exit(0);break;}}return 0;
}//判断一个文件是否为媒体文件
int isMediaFile(const char *filename)
{while (filename)           //找到文件后缀的点{if (*filename == '.'){break;}filename++;}if (!strcmp(filename, ".mp3") || !strcmp(filename, ".mp4") || !strcmp(filename, ".flv") || !strcmp(filename, ".avi")){return 1;}return 0;
}//加载媒体文件,使得媒体文件存入二维数组中
int loadMediaFile(const char *direntname)
{DIR *dp = NULL;struct dirent *pp = NULL;MplayerStat.curmode = MPLAYER_MODE_ORDER;       //起初初始化为顺序播放MplayerStat.curstat = MPLAYER_STAT_FREE;       //起初状态设置为空闲状态MplayerStat.curmedianum = 0;                  //当前曲目为0dp = opendir(direntname);                      //打开文件夹if (NULL == dp){writeLogFile("fail to opendir");return -1;}while (1){pp = readdir(dp);                          //读取文件夹下的文件名if (NULL == pp)                               //读到没有文件时结束{break;}if (pp->d_name[0] == '.')                 //忽略隐藏文件{continue;}if (isMediaFile(pp->d_name))              //判断是否为媒体文件{if (MediaList.curmedialist < 100){strcpy(MediaList.medialist[MediaList.curmedialist], pp->d_name);    //储存该媒体文件printf("%s\n", MediaList.medialist[MediaList.curmedialist]);     MediaList.curmedialist++;                                         //媒体文件个数 +1}else{printf("播放列表加载歌曲超过100首\n");                             //最多存储100首break;}}}closedir(dp);return 0;
}//列出目录下的所有媒体文件
int listOfMusicFile(void)
{int n = -1;printf("============= 音乐列表 =============\n");for (n = 0;n < MediaList.curmedialist;++n){puts(MediaList.medialist[n]);}printf("====================================\n");while (1){printf("请选择(按0返回上一级):");scanf("%d", &n);if (n == 0){break;}if (MplayerStat.curstat != MPLAYER_STAT_FREE){kill(pid, SIGKILL);}playMedia(MediaList.medialist[n - 1]);MplayerStat.curmedianum = n -1;}return 0;
}//实现mplayer停止功能
int Pause(void)
{int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "pause\n", 6);close(fd);MplayerStat.curstat = MPLAYER_STAT_PAUSE;return 0;
}//实现继续播放功能
int Continue(void)
{int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "pause\n", 6);close(fd);MplayerStat.curstat = MPLAYER_STAT_PLAY;return 0;
}//播放指定的媒体文件
int playMedia(char *pMediaPath)
{printf("pMediaPath = %s\n", pMediaPath);pid = fork();if (pid < 0){writeLogFile("fail to fork");return -1;}if (pid == 0){close(1);   //关闭stdoutclose(2); //关闭stderrexeclp("mplayer", "mplayer", "-slave", "-input", "file=/tmp/myfifo", pMediaPath, NULL);}MplayerStat.curstat = MPLAYER_STAT_PLAY;MplayerStat.curspeed = MPLAYER_SPEED_ONE;//  wait(NULL);return 0;
}//开始或者暂停播放
int playPause(void)
{printf("进入playPause了\n");if (MplayerStat.curstat == MPLAYER_STAT_FREE){//      printf("1");if (MplayerStat.curmode == MPLAYER_MODE_SINGLE){printf("当前单曲循环\n");playMedia(MediaList.medialist[MplayerStat.curmedianum]);}else if (MplayerStat.curmode == MPLAYER_MODE_ORDER){printf("当前顺序播放\n");playMedia(MediaList.medialist[MplayerStat.curmedianum + 1]);MplayerStat.curmedianum++;}else if (MplayerStat.curmode == MPLAYER_MODE_RANDOM){printf("当前随机播放\n");int ret = -1;srand(time(NULL));ret = rand() % 2;playMedia(MediaList.medialist[ret]);MplayerStat.curmedianum = ret;}}else if (MplayerStat.curstat == MPLAYER_STAT_PLAY){printf("1");Pause();}else if (MplayerStat.curstat == MPLAYER_STAT_PAUSE){printf("1");Continue();}return 0;}//停止播放
int Stop(void)
{int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "quit\n", 5);close(fd);kill(pid, SIGKILL);MplayerStat.curstat = MPLAYER_STAT_FREE;return 0;
}//切换下一曲
int nextMusic(void)
{kill(pid, SIGKILL);playMedia(MediaList.medialist[MplayerStat.curmedianum + 1]);MplayerStat.curmedianum++;return 0;
}//切换上一曲
int preMusic(void)
{kill(pid, SIGKILL);playMedia(MediaList.medialist[MplayerStat.curmedianum - 1]);MplayerStat.curmedianum--;return 0;
}//加速视频播放
int addSpeed(void)
{int fd = -1;char cmdbuf[128] = {0};int n = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}printf("请输入你需要设置的视频速度:");scanf("%d", &n);getchar();sprintf(cmdbuf, "speed_set %d\n", n);write(fd, cmdbuf, strlen(cmdbuf));printf("当前播放%d倍速!\n", n);if (1 == n){MplayerStat.curspeed = MPLAYER_SPEED_ONE;}else if (2 == n){MplayerStat.curspeed = MPLAYER_SPEED_TWO;}else if (4 == n){MplayerStat.curspeed = MPLAYER_SPEED_FOUR;}close(fd);return 0;
}//定位视频播放的位置(秒计时)
int seekPosition(void)
{int fd = -1;char cmdbuf[128] = {0};int n = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}printf("请输入你需要跳转的位置:");scanf("%d", &n);getchar();sprintf(cmdbuf, "seek %d 2\n", n);write(fd, cmdbuf, strlen(cmdbuf));close(fd);return 0;
}//切换视频的播放状态
int changeModeOfWork(void)
{if (MplayerStat.curmode == MPLAYER_MODE_RANDOM){MplayerStat.curmode = MPLAYER_MODE_SINGLE;printf("当前单曲循环\n");}else if (MplayerStat.curmode == MPLAYER_MODE_SINGLE){MplayerStat.curmode = MPLAYER_MODE_ORDER;printf("当前顺序播放\n");}else if (MplayerStat.curmode == MPLAYER_MODE_ORDER){MplayerStat.curmode = MPLAYER_MODE_RANDOM;printf("当前随机播放\n");}return 0;
}//信号处理函数
void handler(int signo)
{int status = 0;wait(&status); //获取进程状态if (WIFSIGNALED(status))    //判断进程是否被信号杀死{return;}else if (WIFEXITED(status))       //判断进程是否正常结束(如果是则按照当前的播放模式继续播放下一首){MplayerStat.curstat = MPLAYER_STAT_FREE;MplayerStat.curspeed = MPLAYER_SPEED_ONE;playPause();}return;
}

以上就是所有的媒体播放器的相关实现过程,主要的收获有以下几个:
(1)自定义结构体与共用体的区别:结构体每个变量可以自主进行定义开辟空间,但是共用体内部变量共用一个空间,这个变量的值只能是共用体中的一个;
(2)信号处理函数的使用,当收到一个这个样的信号时该如何进行后续业务流程的处理;
以下是本项目的所有相关文件;链接:https://pan.baidu.com/s/1jAWbshZpsStZmbuwJ8fYIg?pwd=gsic 提取码:gsic

使用进程、mplayer命令实现媒体播放器相关推荐

  1. java编写的媒体播放器_BlogJava: 用Java构造自己的媒体播放器

    一.概述 首先我们来看看构造这个媒体播放器要达到什么样的目标,确定了目标也就确定了代码量和程序的复杂程度.本文的媒体播放器要达到如下目标: 媒体播放器是一个菜单驱动的简单AWT应用. 媒体播放器包含一 ...

  2. linux安装vlc只能命令行启动,Ubuntu安装多功能的媒体播放器VLC播放器的步骤

    VLC是一款多功能的媒体播放器,支持多种视频格式,最大的优点就是可以播放"残缺"视频,那么Ubuntu下要如何安装VLC播放器呢?下面小编就给大家介绍下Ubuntu14.0安装VL ...

  3. 媒体播放器三大底层架构

    2019独角兽企业重金招聘Python工程师标准>>> 媒体播放工具,这里主要指视频播放,因为要面临庞大的兼容性和纷繁复杂的算法,从架构上看,能脱颖而出的体系屈指可数.大体来说业界主 ...

  4. 媒体播放器三大底层架构_射手科技zz

    媒体播放器三大底层架构_射手科技 自射手影音推出以来,生活中越来越多的时间开始被代码和各种Bug-Fix淹没.埋头在田里太久,常常会在一时之间忘记身处何方.所以偶尔上来透透气,顺便将一些经验和心得与大 ...

  5. linux 嵌入式 播放器,基于Linux的嵌入式媒体播放器研究

    摘要: 计算机多媒体技术和嵌入式技术的高速发展,各种集计算机.通信.消费电子产品等特征于一体的电子产品得以广泛应用,嵌入式媒体播放器已经成为此类产品中主要的应用软件.同时,随着Linux系统在各种嵌入 ...

  6. VLC媒体播放器Web插件详细说明

    原文地址:https://wiki.videolan.org/Documentation:WebPlugin/ 简介:使用视频构建网页 该VLC媒体播放器 webplugins是原生浏览器插件,类似于 ...

  7. linux自带视频播放VLC,如何将VLC媒体播放器设置为默认视频播放器?

    问题描述 我似乎无法将VLC媒体播放器设置为默认视频播放器.我已进入系统设置→系统信息→默认应用程序,并将"Video"更改为VLC媒体播放器. 但是,默认情况下,所有电影仍然使用 ...

  8. 易语言html5播放器问题,易语言媒体播放器 - 已处理问题存放区 - 中国红客联盟 - Powered by HUC...

    前几天吧,我们副组长教了个媒体播放器器.所以呢今天我就写这个媒体播放器.好了话不多说,请看源码.不好的话,请多多指教. 组件:高级表格.按钮×2.滑块条×2.时钟.媒体播放. 首先添加一个高级表格组件 ...

  9. Qt6实战教程:媒体播放器示例

    Media Player示例使用Microsoft Media Player ActiveX控件来实现功能正常的媒体播放器应用程序. 开始前先介绍一下我们的Qt商业控件: QtitanRibbon|  ...

最新文章

  1. Python离线安装依赖包
  2. The connection to adb is down, and a severe error has occured.问题解决方法小结
  3. java stream 求和_谈谈Java任务的并行处理
  4. GTank iOS App Technical Support
  5. Action详解(一)
  6. 菜鸟学习Spring——SpringMVC注解版解析不同格式的JSON串
  7. centos 安装jenkins
  8. 案例4-4 Windows消息队列 (25 分)(优先队列的优先级设定)
  9. nvm简介与常见命令
  10. 优先经验回放(Prioritized Experience Replay)
  11. 【十】比例尺添加以及调整
  12. 盘点百度 4 个牛逼哄哄的开源项目
  13. D 语言编写CGI程序
  14. java seo优化_JavaWeb 项目如果从技术选型的角度来做 Seo 优化
  15. 跑通SpringBoot + dubbo3.0.8 + zookeeper
  16. 国家进口的爱乐维与德国药店的爱乐维的区别
  17. mysqldump逻辑备份
  18. js前台提示:参数不规范,请检查json的格式和参数对应的类型是否正确
  19. 中国云计算服务网:盛大云体验报告
  20. 《痞子衡嵌入式半月刊》 第 51 期

热门文章

  1. 数据仓库的定义和特征
  2. java斐波那切数列_如何用java语言输出斐波那契数列
  3. HTML搜索框的制作过程
  4. python 谷歌地图_google地图 api python
  5. 2021大厂字节跳动笔试题(含答案)
  6. Chrome/Edge/Firefox浏览器离线安装包下载地址总汇
  7. League of Legends Epic Dubstep
  8. docker可用容量 查看_查询docker中磁盘使用量大的容器
  9. XN297L 2.4G无线模块 寄存器读写测试
  10. yolov5-计算fps(新加入:4. 记录运行B导yolov7-tiny后计算fps的方法)