【项目】视频点播系统1

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 【项目】视频点播系统

一、项目介绍

1. 对视频点播系统的认识

搭建视频共享点播服务器,可以让所有人通过浏览器访问服务器,实现视频的上传查看,以及管理并播放的功能。主要是完成服务器端的程序业务功能的实现以及前端访问界面 html 的编写,能够支持客户端浏览器针对服务器上的所有视频进行操作。

2. 服务端功能模块划分

该视频点播系统基本上包含四个模块:数据管理、网络通信、业务处理、前端界面,其功能如下:

  • 数据管理模块:负责针对客户端上传的视频信息进行管理。
  • 网络通信模块:搭建网络通信服务器,实现与客户端通信。
  • 业务处理模块:针对客户端的各个请求进行对应业务处理并响应结果。
  • 前端界面模块:完成前端浏览器上视频共享点播的各个 html 页面,在页面中支持增删改查以及观看功能。

二、环境搭建

2.1 升级GCC

由于在该项目中会引入许多第三方库,比如httplib库,该库就会要求gcc编译器必须是较新的版本。如果使用老版本的编译器要么编译不通过,要么就会运行报错。因此我们需要对gcc进行升级,以下是升级至 gcc 7.3 的方法:

  • 查看当前gcc版本
gcc --version
  • 安装centos-release-scl
sudo yum install centos-release-scl-rh centos-release-scl
  • 安装devtoolset
sudo yum install devtoolset-7-gcc devtoolset-7-gcc-c++

这里需要注意一下,如果想安装7.版本的,就改成devtoolset-7-gcc,以此类推。

  • 激活对应的devtoolset
source /opt/rh/devtoolset-7/enable

此时GCC就成功升级到了 7.3 版本。

需要注意的是scl命令启用只是临时的,退出 shell 或重启就会恢复原系统gcc版本。如果想要一启动shell就立即生效可以进行以下配置:

echo "source /opt/rh/devtoolset-7/enable" >> ~/.bashrc

即把启动scl的命令添加到文件.bashrc中,每次启动shell就会执行该语句。

2.2 安装JsonCpp库

JSON 是一种轻量级的数据交换格式。它可以代表数字、字符串、值的有序序列和名称/值的集合对。

JsonCpp 是一个C++库,允许操作 JSON 值,包括字符串的序列化和反序列化。它还可以保存反序列化/序列化步骤中的现有注释,方便

用于存储用户输入文件的格式。

以下是安装JsonCpp的命令:

sudo yum install epel-release
sudo yum install jsoncpp-devel

安装好的JsonCpp存放在/usr/include/jsoncpp/json目录下:

2.3 引入httplib库

cpp-httplib 是个开源的库,是一个c++封装的http库,使用这个库可以在linux、windows平台下完成http客户端、http服务端的搭建,这是一个多线程“阻塞”HTTP 库。使用起来非常方便,只需要包含头文件httplib.h即可。

获取httplib库:

git clone https://github.com/yhirose/cpp-httplib.git

2.4 MySQL数据库及开发包安装

此次项目的开发我们使用的数据库是MariaDB,MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。

以下是安装MariaDB数据库的步骤:

  • 安装 MariaDB 服务
sudo yum install -y mariadb-server
  • 安装 MariaDB 命令行客户端
sudo yum install -y mariadb
  • 安装 MariaDB C library
sudo yum install -y mariadb-libs

其实 MariaDB 的服务中包含了客户端和相关的C语言接口,因此只需要安装 mariadb-server即可。

  • 安装 MariaDB 开发包
sudo yum install -y mariadb-devel

安装完成后,以下是启动数据库的命令:

  • 启动服务
systemctl start mariadb

执行该命令启动服务之后,如果重启或者关机了,下次还需要重新启动,可以执行下列指令设置开启自启。

  • 设置服务开机自启
systemctl enable mariadb
  • 查看服务状态
systemctl status mariadb

启动服务成功后,我们可以看到MariaDB 的状态是 active(running):


● mariadb.service - MariaDB database server

Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled)

Active: active (running) since Wed 2023-03-01 20:25:02 CST; 1min 32s ago

Main PID: 7678 (mysqld_safe)

CGroup: /system.slice/mariadb.service

├─7678 /bin/sh /usr/bin/mysqld_safe --basedir=/usr

└─7844 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mariadb/mariadb.log --pid-file=/var/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql…

然后可以测试连接数据库:

  • 使用命令行客户端尝试连接
mysql -uroot

出现以下结果就代表连接成功了:


Welcome to the MariaDB monitor. Commands end with ; or \g.

Your MariaDB connection id is 2

Server version: 5.5.68-MariaDB MariaDB Server


Copyright © 2000, 2018, Oracle, MariaDB Corporation Ab and others.


Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.


MariaDB [(none)]>

  • 查看 mariadb 版本号
MariaDB [(none)]> select version();
+----------------+
| version()      |
+----------------+
| 5.5.68-MariaDB |
+----------------+
1 row in set (0.00 sec)

更改配置:

为了在使用数据库时支持中文,还需要进行以下配置。

  • /etc/my.cnf.d/client.cnf文件的 [client]下添加default-character-set = utf8

  • /etc/my.cnf.d/mysql-client.cnf文件下的[mysql]下添加default-character-set = utf8
  • /etc/my.cnf.d/server.cnf下的[mysqld]添加以下语句
collation-server = utf8_general_ci
init-connect = 'SET NAMES utf8'
character-set-server = utf8
sql-mode = TRADITIONAL

三、第三方库的认识

3.1 认识JsonCpp

首先认识Json:


Json 是一种数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。

例如:使用Json来表示张三同学的学生信息。

const char* name1 = "张三";
int age1 = 18;
float scores1[3] = {60.0, 59.5, 61.0};
const char* name2 = "李四";
int age2 = 19;
float scores2[3] = {69.0, 58.5, 64.0};
// Json这种数据交换格式就是将这样的多种数据对象封装成一个字符串:
[
  {
    "姓名" : "张三",
    "年龄" : 18,
    "成绩" : [860.0, 59.5, 61.0]
  },
  {
    "姓名" : "李四",
    "年龄" : 19,
    "成绩" : [69.0, 58.5, 64.0]
  },
] 


Json可以封装的数据对象可以是:对象,数组,字符串,数字等等。


认识JsonCpp:

JsonCpp 库用于实现 Json 格式的序列化和反序列化,完成将多个数据对象组织成为 Json 格式字符串,以及将 Json

格式字符串解析得到多个数据对象的功能。


其中主要借助三个类以及对于的几个成员函数完成的。

Json 数据对象:

class Json::Value{
  Value &operator=(const Value &other); // Value重载了[]和=,因此所有的赋值和获取数据都可以通过
  Value& operator[](const std::string& key);// 简单的方式完成 val["姓名"] = "小明";
  Value& operator[](const char* key);
  Value removeMember(const char* key);// 移除元素
  const Value& operator[](ArrayIndex index) const; // val["成绩"][0]
  Value& append(const Value& value);// 添加数组元素val["成绩"].append(88);
  ArrayIndex size() const;// 获取数组元素个数 val["成绩"].size();
  std::string asString() const;// 转string string name = val["name"].asString();
  const char* asCString() const;// 转char* char *name = val["name"].asCString();
  Int asInt() const;// 转int int age = val["age"].asInt();
  float asFloat() const;// 转float
  bool asBool() const;// 转 bool
}


Json序列化类:

// 建议低版本使用
class JSON_API Writer {
  virtual std::string write(const Value& root) = 0;
}
class JSON_API FastWriter : public Writer {
  virtual std::string write(const Value& root);
}
class JSON_API StyledWriter : public Writer {
  virtual std::string write(const Value& root);
}
// 建议较高版本使用,如果用低版本接口可能报错
class JSON_API StreamWriter {
  virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
  virtual StreamWriter* newStreamWriter() const;
}

Json反序列化类:

// 低版本用起来更简单
class JSON_API Reader {
  bool parse(const std::string& document, Value& root, bool collectComments = true);
}
// 高版本更推荐
class JSON_API CharReader {
  virtual bool parse(char const* beginDoc, char const* endDoc,
  Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {
  virtual CharReader* newCharReader() const;
}


3.2 JsonCpp实现序列化

#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{
  const char* name = "张三";
  int age = 18;
  float scores[3] = {60.0, 59.5, 61.0};
  Json::Value value;
  value["姓名"] = name;
  value["年龄"] = age;
  value["成绩"].append(scores[0]);
  value["成绩"].append(scores[1]);
  value["成绩"].append(scores[2]);
  Json::StreamWriterBuilder swb;
  std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
  std::stringstream ss;
  int ret = sw->write(value, &ss);
  if(ret != 0)
  {
     std::cout << "write falied!" << std::endl;
     return -1;
  }
  std::cout << ss.str() << std::endl;
  return 0;
}

运行结果:

3.3 JsonCpp实现反序列化

#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{
    std::string str = R"({"姓名":"李四", "年龄":19, "成绩":[69.0, 58.5, 64.0]})";
    Json::Value root;
    Json::CharReaderBuilder crb;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    std::string err;
    cr->parse(str.c_str(), str.c_str() + str.size(), &root, &err);
    std::cout << root["姓名"].asString() << std::endl;
    std::cout << root["年龄"].asInt() << std::endl;
    int sz = root["成绩"].size();
    for (int i = 0; i < sz; ++i)
        std::cout << root["成绩"][i].asFloat() << std::endl;
    for(auto it = root["成绩"].begin(); it != root["成绩"].end(); ++it)
        std::cout << it->asString() << std::endl;
    return 0;
}


运行结果:

3.4 认识MySQL数据库的API

MySQL C语言API就是用C语言编写的MySQL编程接口,使用这些接口函数可以实现对MySQL数据库的查询等操作。以下是MySQL的C语言API接口。

  1. MySQL句柄初始化
MYSQL* mysql_init(MYSQL* mysql);

【说明】

  • 参数为空则动态申请句柄空间进行初始化,如果调用成功则返回MySQL句柄,失败则返回NULL

句柄是什么?

句柄(handle)是C++程序设计中经常提及的一个术语。它并不是一种具体的、固定不变的数据类型或实体,而是代表了程序设计中的一个广义的概念。句柄一般是指获取另一个对象的方法——一个广义的指针,它的具体形式可能是一个整数、一个对象或就是一个真实的指针,而它的目的就是建立起与被访问对象之间的唯一的联系。


在C++中,要访问一个对象,通常可以建立一个指向对象的指针。但是在很多具体的应用中,直接用指针代表对象并不是一个好的解决方案。因此引入了句柄的概念。


  1. 连接MySQL服务器
MYSQL* mysql_real_connect(MYSQL* mysql, const char* host, const char* user, const char* passwd, 
            const char* db, unsigned int port, const char* unix_socket, unsigned long client_flag);

【参数说明】


  • mysql:初始化完成的句柄
  • host:连接的MySQL服务器的地址
  • user:连接的数据库的用户名
  • passwd:该用户连接数据库的密码
  • db:默认选择的数据库名称
  • port:连接的MySQL服务器的端口,默认0是3306端口
  • unix_socket:通信管道文件或者socket文件,通常置为NULL
  • client_flag:客户端的标志位,通常置为0【返回值】
  • 连接成功返回MySQL句柄,失败则返回NULL
  1. 设置当前客户端的字符集
int mysql_set_character_set(MYSQL* mysql, const char* csname);

【参数说明】

  • mysql:初始化完成的句柄
  • csname:字符集名称,通常为utf8

【返回值】

  • 调用成功返回0,失败则返回非0
  1. 选择操作的数据库
int mysql_select_db(MYSQL* mysql, const char* db);

【参数说明】

  • mysql:初始化完成的句柄
  • db:要进行操作的数据库名称

【返回值】

  • 调用成功返回0,失败则返回非0
  1. 执行SQL语句
int mysql_query(MYSQL* mysql, const char* stmt_str);

【参数说明】

  • mysql:初始化完成的句柄
  • stmt_str:要执行的sql语句

【返回值】

  • 调用成功返回0,失败则返回非0
  1. 保存查询结果到本地
MYSQL_RES* mysql_store_result(MYSQL* mysql);

【参数说明】

  • mysql:初始化完成的句柄

【返回值】

  • 调用成功返回结果集的首地址,失败则返回NULL
  1. 获取结果集中的行数
uint64_t mysql_num_rows(MYSQL_RES* result);

【参数说明】

  • result:保存到本地的结果集

【返回值】

  • 返回结果集中数据的条数,也是是行数。
  1. 获取每一条结果集的列数
unsigned int mysql_num_fields(MYSQL_RES* result);

【参数说明】

  • result:保存到本地的结果集

【返回值】

  • 返回结果每一条集中数据的列数
  1. 遍历结果集
MYSQL_ROW mysql_fecth_row(MYSQL_RES* result);

【参数说明】

  • result:保存到本地的结果集

【返回值】

  • MYSQL_ROW实际上是一个char** 类型的二级指针将每一条数据表示成了字符串指针数组。比如row[0]表示第0行,row[1]表示第一行。
  • 并且这个接口会保存当前读取的结果集位置,每次获取的都是下一条数据。
  1. 释放结果集
void mysql_free_result(MYSQL_RES* result);

【说明】

  • result是保存到本地的结果集,无返回值。

注意一定要释放结果集,否则会造成内存泄漏。

  1. 关闭数据库客户端的连接,销毁MySQL句柄
void mysql_close(MYSQL* mysql);
  1. 获取MySQL接口中执行错误的原因
const char* mysql(MYSQL* mysql);

【说明】

  • 该函数会返回执行sql语句失败的原因。

3.5 使用MySQL的API实现对数据的增删改查

  1. 创建一个测试所用数据库和表
create database if not exists test_db;
use test_db;
create table if not exists test_tb(
  id int primary key auto_increment,
  age int,
  name varchar(32),
  score decimal(4, 2)
);

创建成功使用desc test_tb;语句查看对test_tb的描述:

对数据库进行增删改查的代码样例:


  • 向数据库里面增加数据
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <mysql/mysql.h>
//添加数据
int add(MYSQL* mysql)
{
    const char* sql = "insert into test_tb values (null, 18, '张三', 61.5)";
    int ret = mysql_query(mysql, sql);
    if(ret != 0)
    {
        printf("query %s failed, error massage: %s\n", sql, mysql_error(mysql));
      return -1;
    }
    return 0;
}
int main()
{
  //初始化操作句柄
  MYSQL* mysql = mysql_init(NULL);
  if(NULL == mysql)
  {
    printf("init mysql handle failed!\n");
    return -1;
  }
  //连接mysql服务器
  if (mysql_real_connect(mysql, "127.0.0.1", "root", "", "test_db", 0, NULL, 0) == NULL)
  {
    printf("mysql connect failed!\n");
    return -1;
  }
  //设置客户端字符集
  mysql_set_character_set(mysql, "utf8");
  add(mysql);
  //关闭句柄
  mysql_close(mysql);
  return 0;
}

编译指令:

gcc -o mysql_test mysql_test.c -L/usr/lib64/mysql -lmysqlclient

【项目】视频点播系统2:https://developer.aliyun.com/article/1384001

目录
相关文章
|
5月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的视频点播系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的视频点播系统附带文章源码部署视频讲解等
96 17
|
4月前
|
存储 前端开发 JavaScript
在视频点播系统工程中,我们关注的是构建一个能够处理视频内容、用户交互、数据存储和检索等功能的系统。
在视频点播系统工程中,我们关注的是构建一个能够处理视频内容、用户交互、数据存储和检索等功能的系统。
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的在线视频点播系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的在线视频点播系统附带文章和源代码部署视频讲解等
79 8
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的视频点播系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的视频点播系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
6月前
|
JavaScript Java 测试技术
基于ssm+vue.js的视频点播系统附带文章和源代码设计说明文档ppt
基于ssm+vue.js的视频点播系统附带文章和源代码设计说明文档ppt
38 0
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的在线视频点播系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的在线视频点播系统的详细设计和实现(源码+lw+部署文档+讲解等)
118 0
|
6月前
|
NoSQL Java 微服务
前后端分离项目知识汇总(阿里云Oss,EasyExcel,视频点播,SpringCloud,Redis,Nuxt)-3
前后端分离项目知识汇总(阿里云Oss,EasyExcel,视频点播,SpringCloud,Redis,Nuxt)
201 1
|
6月前
|
前端开发 NoSQL easyexcel
前后端分离项目知识汇总(阿里云Oss,EasyExcel,视频点播,SpringCloud,Redis,Nuxt)-2
前后端分离项目知识汇总(阿里云Oss,EasyExcel,视频点播,SpringCloud,Redis,Nuxt)
162 0
|
6月前
|
NoSQL 应用服务中间件 对象存储
前后端分离项目知识汇总(阿里云Oss,EasyExcel,视频点播,SpringCloud,Redis,Nuxt)-1
前后端分离项目知识汇总(阿里云Oss,EasyExcel,视频点播,SpringCloud,Redis,Nuxt)
133 0
|
11月前
|
JSON 前端开发 数据库
【项目】视频点播系统2
【项目】视频点播系统
131 0

热门文章

最新文章