文章目录

  • 1.项目介绍
  • 2.前端代码
    • 1.httplib快速搭建一个http服务器
    • 2.B/S双方的数据交互选择JSON数据格式,http请求和响应的正文中采用jsoncpp开源库
    • 3.前段的js代码向发送ajax请求
  • 三、服务端代码
    • 1.搭建一个music_player这样的一个类
    • 2.增加注册按钮,并且点击注册按钮跳转到注册界面
    • 3.服务端代码当中调用mysql-c api连接数据库,进行操作
    • 4.登录查询用户是否存在校验邮箱和密码
    • 5.通过命令行参数获取ip地址和端口号信息
    • 6.保存登录的会话信息session,使用md5摘要保护登录信息,否则造成直接跳转list.html界面
    • 7.用哈希表保存多个用户的信息
    • 8.数据库存放音乐相关信息,通过json串返回给浏览器
    • 9.查询音乐、喜欢的音乐、添加喜欢的音乐

1.项目介绍

音乐播放器拥有注册登录功能,查看所有的音乐列表,也可以听音乐,也可以将音乐添加到自己的喜欢列表。

2.前端代码

1.httplib快速搭建一个http服务器

     1   #include<stdio.h>2    #include<iostream>3   4   #include<string.h>5   #include"httplib.h"6  7   using namespace httplib;8   using namespace std;9   10  int g_val=100;11   12  void Get_CallBackFunc(const Request& req, Response& resp)13 {14     printf("%d\n",g_val);15       cout<<req.method<<endl;16       printf("i am Get_CallBackFunc\n");17      18      const char* lp="<html><h2>hello world!</h2></html>";19       resp.set_content(lp,strlen(lp),"text/html");20    }21 22  23  24  int main()25    {26     Server http_svr;27      int a=10;28    29      http_svr.Get("/abc",Get_CallBackFunc);30      http_svr.Post("/111",[a](const Request& req,Response& resp){31                printf("a:%d\n",a);32 33      });34       //直接访问web里面的文件35        //逻辑根目录指定为web文件夹36      http_svr.set_mount_point("/","./web");37        http_svr.listen("0.0.0.0",21010);38   39      return 0;40 }


2.B/S双方的数据交互选择JSON数据格式,http请求和响应的正文中采用jsoncpp开源库


     1   #include<stdio.h>2    #include<iostream>3   #include<jsoncpp/json/json.h>4    5   using namespace std;6   7   int main()8 {9  10      Json::Value v1;11       v1["id"]=1;12        v1["name"]="yyw";13        cout<<v1<<endl;14   15      Json::Value v2;16       v2["id"]=2;17        v2["name"]="yy";18     cout<<v2<<endl;19   20      Json::Value v3;21       v3["v1"]=v1;22       v3["v2"]=v2;23       cout<<v3<<endl;24   25      Json::Value v4;26       v4.append(v1);27        v4.append(v2);28        cout<<v4<<endl;29   30      for(int i=0;i<2;i++)31        {32         cout<<v4[i]["id"]<<":"<<v4[i]["name"]<<endl;33        }34 35      //序列化36     Json::FastWriter w;37       string json_str=w.write(v4);38     cout<<json_str<<endl;39     //反序列化40        Json::Reader r;41       Json::Value vv;42       r.parse(json_str,vv);43     cout<<vv<<endl;44       return 0;45 }

JSON数据格式有三种显示方法:平铺、嵌套、数组形式。



序列化和反序列化:

3.前段的js代码向发送ajax请求

#include<stdio.h>
#include<iostream>#include<jsoncpp/json/json.h>
#include<string.h>
#include"httplib.h"using namespace httplib;
using namespace std;int g_val=100;void Get_CallBackFunc(const Request& req, Response& resp)
{printf("%d\n",g_val);cout<<req.method<<endl;printf("i am Get_CallBackFunc\n");const char* lp="<html><h2>hello world!</h2></html>";resp.set_content(lp,strlen(lp),"text/html");
}int main()
{Server http_svr;http_svr.Get("/abc",Get_CallBackFunc);//发送post请求/login,回调这个表达式http_svr.Post("/login",[](const Request& req,Response& resp){cout<<req.body<<endl; //打印正文信息Json::Value resp_json;resp_json["login_status"]=true;  //浏览器返回登录状态//序列化//系列化成完整的字符串的内容放到响应的正文中Json::FastWriter w;resp.body= w.write(resp_json);//告诉浏览器返回的内容就是json串,对json解析resp.set_header("Content-Type","application/json");});//直接访问web里面的文件//逻辑根目录指定为web文件夹http_svr.set_mount_point("/","./web");http_svr.listen("0.0.0.0",21010);return 0;
}



三、服务端代码

1.搭建一个music_player这样的一个类

     1   #pragma once2   #include"database.hpp"3   #include<stdio.h>4    #include<iostream>5   #include<string>6 #include"httplib.h"7  8   #include<jsoncpp/json/json.h>9    10  using namespace std;11  12  using namespace httplib;13  14  #define MUSIC_SVR_IP "0.0.0.0"15  #define MUSIC_SVR_PORT 1898916  17  class MusicServer18 {19     public:20           MusicServer()21         {22             svr_ip_=MUSIC_SVR_IP;23                svr_port_=MUSIC_SVR_PORT;24                db_svr_=NULL;25            }26         ~MusicServer()27            {28 29          }30 31          //1.初始化当前类接32           int InitMusicServer(string ip=MUSIC_SVR_IP,uint16_t port=MUSIC_SVR_PORT)33            {34             svr_ip_=ip;35              svr_port_=port;36  37              db_svr_=new DataBaseSvr("1.14.165.138","yy","123","music_svr");38              if(db_svr_==NULL)39               {40                 return -1;41                }42             return 0;43         }44         //2.启动服务的接口45           int StartMusicServer()46            {47             //1.注册个若干个http请求的对应的回调函数48              /*49                 *请求:{"name":"yy","passwd":"123","email":"123@qq.com","phonenum":"1231"}50              *响应:{"register_status":"xxxx"}51                *52                 *53                 * */54             http_svr_.Post("/register",[this](const Request& req,Response& resq){55                       cout<<req.body<<endl;56                     //1.需要将浏览器中的数据持久化(保存在数据库中) 57                       //58                        //1.将用户提交的数据进行反序列化,拿到一个json对象59                      Json::Reader r;60                       Json::Value v;61                        r.parse(req.body,v);62  63                      cout<<v["name"]<<endl;64                      cout<<v["passwd"]<<endl;65                        cout<<v["email"]<<endl;66                     cout<<v["phonenum"]<<endl;67  68                      db_svr_->InsertUserInfo(v);69                        });70   71              http_svr_.Post("/login",[](const Request& req,Response& resq){72                  /*73                     *1.74                   *2.75                   *3.76                   * */77             cout<<req.body<<endl;78 79              });80   81              //2.设置http服务器静态路径(逻辑根目录)82              http_svr_.set_mount_point("/","./web");83               //3.监听起来84              http_svr_.listen(svr_ip_.c_str(),svr_port_);85          }86     private:87          //httplib 当中的server对象88         Server http_svr_;89 90          string svr_ip_;91           uint16_t svr_port_;92   93          //数据库操作模块94         DataBaseSvr* db_svr_;95 };

2.增加注册按钮,并且点击注册按钮跳转到注册界面

    54               http_svr_.Post("/register",[this](const Request& req,Response& resq){55                       cout<<req.body<<endl;56                     //1.需要将浏览器中的数据持久化(保存在数据库中) 57                       //58                        //1.将用户提交的数据进行反序列化,拿到一个json对象59                      Json::Reader r;60                       Json::Value v;61                        r.parse(req.body,v);62  63                      cout<<v["name"]<<endl;64                      cout<<v["passwd"]<<endl;65                        cout<<v["email"]<<endl;66                     cout<<v["phonenum"]<<endl;67  68                      db_svr_->InsertUserInfo(v);69                        });

3.服务端代码当中调用mysql-c api连接数据库,进行操作

    1    #pragma once2   #include<stdio.h>3    #include<unistd.h>4   #include<iostream>5   #include<string>6 7   #include<mysql/mysql.h>8  #include<jsoncpp/json/json.h>9    using namespace std;10  class DataBaseSvr11 {12     public:13           DataBaseSvr(const string& db_host,const string& db_user,const string& db_password,const string& db_name,unsigned int db_port=3306)14           {15             mysql_init(&mysql_);16              db_host_=db_host;17                db_user_=db_user;18                db_password_=db_password;19                db_port_=db_port;20                db_name_=db_name;21            }22         ~DataBaseSvr()23            {24 25          }26 27          int ConnectToMysql()28          {29             if(!mysql_real_connect(&mysql_,db_host_.c_str(),db_user_.c_str(),db_password_.c_str(),db_name_.c_str(),db_port_,NULL,CLIENT_FOUND_ROWS))30              {31                 cout<<mysql_error(&mysql_)<<endl;32                 return -1;33                }34             return 0;35         }36 37          //提交上来的对象38         int InsertUserInfo(const Json::Value& v)39          {40             //1.连接数据库41             if(ConnectToMysql()<0)42             {43                 return -1;44                }45             //2.组织sql语46                47              string name=v["name"].asString();48              string password=v["password"].asString();49              string email=v["email"].asString();50                string phonenum=v["phonenum"].asString();51  52  #define INSERT_USER_INFO  "insert into sys_user(user_name,password,email,phone_num) values('%s','%s','%s','%s');"53   54              char sql[1024]={0};55              snprintf(sql,sizeof(sql)-1,INSERT_USER_INFO,name.c_str(),password.c_str(),email.c_str(),phonenum.c_str());56                cout<<"sql:"<<sql<<endl;57  58              //3.继续执行sql59               //4.返回插入结果给调用者60            }61     private:62          MYSQL mysql_;63 64          string db_host_;65          string db_user_;66          string db_password_;67          string db_name_;68          unsigned int db_port_;69    };

4.登录查询用户是否存在校验邮箱和密码

 //查询用户是否存在105          int QueryUserExist(const Json::Value& v)106          {107               /* //0 链接108             if(ConnectToMysql()<0)109                {110                    return -1;111               }*/112              //1.从json对象当中解析出来 邮箱和密码113  114             string email = v["email"].asString();115             string password = v["password"].asString();116   117             //2.使用邮箱作为查询条件在sys_user表当中进行查询(如果没有查找到用户,则返回)118   #define QUERY_USER "select * from sys_user where email='%s';"119               char sql[1024] = {0};120               snprintf(sql, sizeof(sql) - 1, QUERY_USER, email.c_str());121               cout << sql << endl;122                     123              //3.针对查询的结果当中的密码, 进行比对124               MYSQL_RES* res = NULL;125              if(ExecuteSql(sql, &res) == false)126             {127                    return -2;128               }129                130             //3.1 针对结果集进行操作, 判断下,结果集当中的行数是否等于1131             //    等于1, 继续往下执行132             //    不等1 , 直接返回133              //my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res);134               if(mysql_num_rows(res) != 1)135                {136                    cout << "No Data for sql!, sql is " << sql <<endl;137                   mysql_free_result(res);138                  return -3;139               }140    141             //3.2 在结果集当中获取一行数据142               //MYSQL_ROW   STDCALL mysql_fetch_row(MYSQL_RES *result);143                //     如果重复调用msyql_fetch_row这个函数, 默认是取下一行的数据144              MYSQL_ROW row = mysql_fetch_row(res);145   146             //3.3 比对密码147               string db_password = row[2];148                if(db_password != password )149                {150                    return -4;151               }152                153             mysql_free_result(res);154              //4.返回查询结果155               return atoi(row[0]); 156            }

5.通过命令行参数获取ip地址和端口号信息

     1   #include"music_player.hpp"2   void Usage()3   {4      cout << "./MusicServer [command key] [command value] ..." << endl;5       cout << "   " << "-ip : svr listen ip" << endl;6      cout << "   " << "-port : svr listen port" << endl;7      cout << "   " << "-db_ip : msyql server ip address" << endl;8     cout << "   " << "-db_port : mysql port" << endl;9        cout << "   " << "-db_user : mysql user" << endl;10       cout << "   " << "-db_passwd : mysql password" << endl;11     cout << "   " << "-db_db : which database " << endl;12        cout << "   " << "-h : show usage" << endl;13 }14 15  //通过命令行参数获取ip地址和端口号之类的信息16  int main(int argc, char* argv[])17  {18     if(argc == 2 && strcmp(argv[1], "-h") == 0)19     {20         Usage();21          exit(1);22      }23     string svr_ip, db_ip, db_user, db_db, db_passwd;24      uint16_t svr_port, db_port;25       for(int i = 0; i < argc; i++)26       {27         if(strcmp(argv[i], "-ip") == 0 && i + 1 < argc)28           {29             svr_ip = argv[i + 1];30           }31         else if(strcmp(argv[i], "-port") == 0 && i + 1 < argc)32            {33             svr_port = atoi(argv[i + 1]);34           }35         else if(strcmp(argv[i], "-db_ip") == 0 && i + 1 < argc)36           {37             db_ip = argv[i + 1];38            }39         else if(strcmp(argv[i], "-db_port") == 0 && i + 1 < argc)40         {41             db_port = atoi(argv[i + 1]);42            }43         else if(strcmp(argv[i], "-db_user") == 0 && i + 1 < argc)44         {45             db_user = argv[i + 1];46          }47         else if(strcmp(argv[i], "-db_db") == 0 && i + 1 < argc)48           {49             db_db = argv[i + 1];50            }51         else if(strcmp(argv[i], "-db_passwd") == 0 && i + 1 < argc)52           {53             db_passwd = argv[i + 1];54            }55 }56     cout<<"please check info:"<<endl;57       cout << "svr_ip: " << svr_ip << endl;58     cout << "svr_pot: " << svr_port << endl;59      cout << "db_ip: " << db_ip << endl;60       cout << "db_port: " << db_port << endl;61       cout << "db_user: " << db_user << endl;62       //cout << "db_passwd: " << db_passwd << endl;63     cout << "db_db: " << db_db << endl;64   65      //重新输出ip66      int select  = 0;67     cout << "enter check result: currect input 1, error input 0;" << endl;68      cout << "[input select]: ";69       cin >> select;70      switch(select)71        {72         case 0:73               cout << "plase retry start server.." << endl;74               break;75            case 1:76               {77                 MusicServer* ms = new MusicServer();78                 if(ms == NULL)79                  {80                     return -1;81                    }82 83                  if(ms->InitMusicServer(db_ip, db_port, db_user, db_passwd, db_db, svr_ip, svr_port) < 0)84                    {85                     return -2;86                    }87                 ms->StartMusicServer();88                    delete ms;89                    break;90                }91         default:92              printf("input select num error, please input 1(currect) or 0(error)\n");93                break;94        }95 96      return 0;97 }

6.保存登录的会话信息session,使用md5摘要保护登录信息,否则造成直接跳转list.html界面



     1   #pragma once2   #include <stdio.h>3   #include <unistd.h>4  #include <string.h>5  #include <openssl/md5.h>6 #include <iostream>7  #include <string>8    #include <unordered_map>9 10  #include <jsoncpp/json/json.h>11  #include "httplib.h"12    13  using namespace std;14  using namespace httplib;15  16  typedef enum UserStatus17   {18     //不在线19     OFFLINE = 0,20     //在线状态21        ONLINE,22   }USER_STATUS;23 24  25  //针对与登录的用户创建的会话信息26 27  class Session28 {29     public:30           Session()31         {32 33          }34 35          Session(const Json::Value& v, int user_id)36            {37             user_id_ = user_id;38  39              real_str_ += v["email"].asString();40               real_str_ += v["password"].asString();41    42              us_status_ = ONLINE;43         }44 45          ~Session()46            {47 48          }49 50  51          bool CalcMd5()52            {53             MD5_CTX ctx;54              MD5_Init(&ctx);55   56              //int MD5_Update(MD5_CTX *c, const void *data, unsigned long len);57                if(MD5_Update(&ctx, real_str_.c_str(), real_str_.size()) != 1)58               {59                 return false;60             }61 62              //int MD5_Final(unsigned char *md, MD5_CTX *c);63               //md ==> 16字节64                unsigned char md5[16] = { 0 };65               if(MD5_Final(md5, &ctx) != 1)66                {67                 return false;68             }69 70              char tmp[2] = {0};71               char buf[32] = {0};72              for(int i = 0; i < 16; i++)73             {74                 sprintf(tmp, "%02x", md5[i]);75                   strncat(buf, tmp, 2);76             }77 78              session_id_ = buf;79               cout << "session_id_" << session_id_ << endl;80             return true;81          }82 83          string& GetSessionID()84            {85             //1.计算sessionID86               CalcMd5();87                //2.返回session_id88              return session_id_;89           }90 91          int GetUserId()92           {93             return user_id_;94          }95 96      private:97          string session_id_;98   99          //生成会话ID的源字符串100            string real_str_;101    102         int user_id_;103    104         UserStatus us_status_;105   };

7.用哈希表保存多个用户的信息


   107   //哈希查找多用户的时刻更快108   class AllSessionInfo109 {110        public:111          AllSessionInfo()112         {113                all_sess_map_.clear();114               pthread_mutex_init(&map_lock_, NULL);115            }116    117         ~AllSessionInfo()118            {119                pthread_mutex_destroy(&map_lock_);120           }121    122         void InsertSessionInfo(const string session_id, const Session sess)123          {124                pthread_mutex_lock(&map_lock_);125              all_sess_map_.insert(make_pair(session_id, sess));126               pthread_mutex_unlock(&map_lock_);127            }128    129         int CheckSession(const Request& req)130         {131                /*132                * 1.通过http请求头当中的 Cookie字段, 获取对应的value(会话ID)133               * 2.通过会话ID, 在all_sess_map_当中查找, 是否有对应的会话信息134                 * */135                string sess_id = req.get_header_value("Cookie");136  137             pthread_mutex_lock(&map_lock_);138              auto iter = all_sess_map_.find(sess_id);139                if(iter == all_sess_map_.end())140                {141                    pthread_mutex_unlock(&map_lock_);142                    return -1;143               }144                int user_id = iter->second.GetUserId();145              pthread_mutex_unlock(&map_lock_);146                return user_id;147          }148        private:149         unordered_map<string, Session> all_sess_map_;150          pthread_mutex_t map_lock_;151   };



8.数据库存放音乐相关信息,通过json串返回给浏览器

         int GetMusic(string sql, Json::Value& resp_json)161         {162                MYSQL_RES* res = NULL;163              if(ExecuteSql(sql, &res) == false)164             {165                    return -2;166               }167    168             int row_nums = mysql_num_rows(res);169             if(row_nums <= 0)170                {171                    printf("No data: sql is \"%s\"", sql.c_str());172                   mysql_free_result(res);173                  return -3;174               }175    176             MYSQL_ROW row = mysql_fetch_row(res);177               Json::Value music_value;178             while(row != NULL)179              {180                    //1.保存数据到json当中181                  Json::Value tmp;182                 tmp["id"] = row[0];183                   tmp["title"] = row[1];184                    tmp["singer"] = row[2];185                   tmp["url"] = row[3];186  187                 music_value.append(tmp);188                 row = mysql_fetch_row(res);189             }190    191             resp_json["music"] = music_value;192             mysql_free_result(res);193              return 0;194            }195    196 197         int GetAllMusic(Json::Value& resp_json)198          {199                /*200                * 1.组织查询的sql语句201               * 2.调用ExecuteSql函数执行sql语句202                * 3.检查结果集当中的行数203               * 4.将获取到的结果集, 进行遍历操作204              * 4.组织json对象205                 * */206                const char* sql = "select * from music;";207             return GetMusic(sql, resp_json);208         }209    210        211  212         int InsertLoveMusic(const Request& req, int user_id)213         {214                /*215                * 1.通过req当中的正文信息, 获取music_id216              * 2.使用music_id, user_id组织sql语句217               * 3.执行sql语句218              * */219                Json::Reader r;220              Json::Value v;221               r.parse(req.body, v);222    223             int music_id = v["music_id"].asInt();224 225 #define INSERT_LOVE_MUSIC "insert into love_music(user_id, music_id) values(%d, %d);"226              char sql[1024] = {0};227               snprintf(sql, sizeof(sql) - 1, INSERT_LOVE_MUSIC, user_id, music_id);228    229             if(ExecuteSql(sql) == false)230               {231                    return -1;232               }233                return 1;234            }235    236         int GetLoveMusic(int user_id, Json::Value& resp_json)237            {238                /*239                * 1.组织查询sql240              * 2.调用GetMusic函数241                 * */242    #define GET_LOVE_MUSIC "select * from music where music_id in(select music_id from love_music where user_id=%d);"243             char sql[1024] = {0}; 244              snprintf(sql, sizeof(sql) - 1, GET_LOVE_MUSIC, user_id);245             return GetMusic(sql, resp_json);246         }

9.查询音乐、喜欢的音乐、添加喜欢的音乐

             http_svr_.Get("/findMusic", [this](const Request& req, Response& resp){137                        /*138                        * 1.会话校验, 从当前http请求的请求体当中拿到 Cookie对应的value值, 会话ID139                      *   1.1 通过会话ID, 在all_sess_当中查找是否有对应的会话140                        *      找到了, 则认为该用户是登录用户, 就可以做后续查找音乐的操作141                         *      没有找到, 则认为该用户是非登录用户, 则返回status为-1142                        * 2.通过数据库模块在数据表music当中查找音乐信息, 则将查找到的音乐信息组织成为json串143                         * 3.组织应答144                         * */145                        Json::Value resp_json;146                       int user_id = all_sess_->CheckSession(req);147                      resp_json["status"] = user_id;148                        if(user_id > 0)149                       {150                        /* 1.会话校验成功的逻辑151                        * 2.访问数据库, 获取到数据表music的音乐信息152                       */153                      db_svr_->GetAllMusic(resp_json); 154                     }155    156                     Json::FastWriter w;157                      resp.body = w.write(resp_json);158                     resp.set_header("Content-Type", "application/json");159             });  160    161             http_svr_.Post("/loveMusic", [this](const Request& req, Response& resp){162                       Json::Value resp_json;163                       int user_id = all_sess_->CheckSession(req);164                      resp_json["status"] = user_id;165                        if(user_id > 0)166                       {167                        cout << "user_id: " << user_id << ", req正文信息:" <<  req.body << endl;168                        resp_json["status"] = db_svr_->InsertLoveMusic(req, user_id);169                      }170    171                     Json::FastWriter w;172                      resp.body = w.write(resp_json);173                     resp.set_header("Content-Type", "application/json");174                     });175  176             http_svr_.Get("/findLoveMusic", [this](const Request& req, Response& resp){177                        /*178                        * 1.会话校验,通过会话校验, 如果成功就能获取当前请求的用户ID179                         * 2.查数据库, 当前用户喜欢的音乐180                       * 3.组织json, 将用户喜欢的音乐返回给浏览器181                        * */182                        Json::Value resp_json;183                       int user_id = all_sess_->CheckSession(req);184                      resp_json["status"] = user_id;185                        if(user_id > 0)186                       {187                        //去数据库当中查询喜欢的音乐188                      db_svr_->GetLoveMusic(user_id, resp_json);189                        }190    191                     Json::FastWriter w;192                      resp.body = w.write(resp_json);193                     resp.set_header("Content-Type", "application/json");194                     }); 195             //2.设置http服务器静态路径(逻辑根目录)196             http_svr_.set_mount_point("/","./web");197              //3.监听起来198             http_svr_.listen(svr_ip_.c_str(),svr_port_);199         }

Linux项目:音乐播放器相关推荐

  1. 微信小程序练手项目-音乐播放器

    微信小程序练手项目-音乐播放器 该项目只适合练手,大佬请绕道 项目展示图: 项目介绍 微信小程序音乐播放器 页面: 音乐推荐.播放器.播放列表 功能: 播放.暂停.上一首.下一首.跳转播放列表.实时进 ...

  2. Java web项目——音乐播放器

    Java web项目--音乐播放器 1,需求分析 ①登录并查看自己的音乐列表 ②从本地上传音乐 ③删除某个音乐 ④删除选中的音乐 ⑤查询音乐(支持模糊查询) ⑥添加音乐到喜欢列表且可进行移除 ⑦可在喜 ...

  3. 基于嵌入式linux的音乐播放器设计,基于嵌入式Linux的多媒体音乐播放器的设计与实现...

    中图分类号:TP316.5 文献标识码:A 文章编号:1009-2552(2009)06-0102-03 基于嵌入式Linux的多媒体音乐播放器的设计与实现 王 奇 (黑龙江八一农垦大学信息技术学院, ...

  4. linux播放器安装程序,Linux下音乐播放器Audacious 3.10下载与安装

    一款Linux下的音乐播放器Audacious 3.10正式发布下载了,它带来了新的功能和一些重要改进,尽管Audacious 4.0(具有功能齐全的 Qt UI)还没有开发出来,但他们也没有闲着,代 ...

  5. linux终端音乐播放器,Linux终端音乐播放器cmus攻略: 操作歌单

    cmus是一款开源的终端音乐播放器.它小巧快速,而又功能强大.cmus支持Ogg/Vorbis.MP3.FLAC.Musepack.WavPack.WMA.WAV.AAC.MP4等格式,包含Gaple ...

  6. linux qt4 音乐播放器,Ubuntu 14.04下安装音乐播放器 Clementine 1.2.3

    Clementine 是一款非常不错的自由开源音乐播放器,支持很多国外的云空间,比如box.com.Clementine使用qt4编写,灵感来自Amarok 1.4.Clementine还是一款跨平台 ...

  7. 个人项目——音乐播放器(一)

    1 功能需求及技术可行性分析 1.1编写目的   现今社会生活紧张,而欣赏音乐史其中最好的舒缓压力的方式之一,音乐播放类的软 件数不胜数,为什么我还要再写一个播放器出来呢?因为现有的音乐播放器功能实在 ...

  8. linux 中文 音乐播放器,linux下的常见音乐播放器

    xmms 老牌的音乐播放器,模仿Windows下*的播放器Winamp,其强大的功能不输于Winamp,具有极强的可扩展性,支持mp3.ogg.wav等格式播放,添加插件后还可以播放AAC.wma等格 ...

  9. WEB项目-音乐播放器

    音乐播放器 需求分析 数据库设计 实体类 Dao层 Servlet层 补充 需求分析 1.注册登陆 使用post请求,登陆路径为/login,传输的数据为username,password,这里就使用 ...

最新文章

  1. 打破定式,突破屏障,走出自己的创意舒适区
  2. 【Android 进程保活】Android 进程优先级 ( 前台进程 | 可见进程 | 服务进程 | 后台进程 | 空进程 )
  3. easyui表单网格列错位_《HTML5从入门到精通》——第3章 HTML表格与表单
  4. Tkinter的Scrollba组件
  5. 想转行人工智能?机会来了!
  6. java公平索非公平锁_java中的非公平锁不怕有的线程一直得不到执行吗
  7. 前端学习(1316):静态资源
  8. Python学习笔记:使用Python操作数据库
  9. swift版本hello
  10. 50阶乘c语言思想,求10000的阶乘(c语言代码实现)
  11. maven(二) maven项目构建ssh工程(父工程与子模块的拆分与聚合)
  12. linux下电子词典里的扩展存储卡不能访问到的问题
  13. 磁盘驱动器号的修改恢复
  14. 内蒙古自治区及其盟市行政单位中英文名称对照表
  15. win10忘记账户密码完美解决方案
  16. c语言实现小球跳动的效果
  17. 奇迹服务器数据修改,奇迹Mu商业服务端 客户端装备外观修改说明!
  18. edge浏览器添加新标签页问题
  19. 当老师退出伽卡他卡教师端,但是还没下课时,程序一直提示连接失败真的很烦,下面和大家分享一下怎么退出伽卡他卡
  20. 如何使用图片的exif信息计算相机焦距

热门文章

  1. Java Agent入门教程
  2. libusb介绍及简单使用
  3. stm32f767之ADC
  4. 前端web:响应式Web开发优缺点总结
  5. UEFI与 Legacy BIOS两种启动模式详解
  6. Matlab GUI编程技巧(十三):checkbox创建复选框
  7. java添加一个复选框_java添加多个复选框控件
  8. singletask和onNewintent
  9. java中构造方法(或者叫构造方法)
  10. 微信小程序wxml和wxss样式