日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

基于C++的视频点播系统

發布時間:2023/12/14 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于C++的视频点播系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

視頻點播系統

  • 項目描述
  • 概要設計
    • 技術調研
  • 詳細設計
    • 數據管理模塊
      • 1.數據存儲
      • 2.封裝實現數據庫訪問類
        • 1.了解mysql的c語言庫接口
        • jsoncpp的基本使用:
      • 3.數據管理模塊代碼
    • 前端界面模塊
      • 1.完成前端html界面的編寫
    • 業務處理模塊
      • 1.http服務器的搭建:
      • 2.請求與響應的網絡通信接口設計
        • 1.靜態頁面請求(首頁,播放)
        • 2.動態數據請求
          • 上傳的視頻文件重名如何處理?
          • 上傳的文件冗余重復(名字不同,數據實際相同)
  • 總結


項目描述

一個用戶可以通過瀏覽器上傳視頻,且對自己上傳的視頻進行管理,而其他用戶可以通過瀏覽器觀看視頻。


概要設計

采用不太嚴謹的MVC框架。此項目分模塊進行設計——數據管理模塊:對數據進行統一管理,外界只能通過此模塊訪問;用戶界面/前端界面模塊:實現用戶交互,提供前端界面;業務處理模塊:接收前端請求進行處理完成用戶的需求。


技術調研

socket、http、tcp、json、mysql、前端三劍客(html、css、js)


詳細設計

數據管理模塊

1.數據存儲

采用MySQL數據庫——免費,采用c/s架構,可以遠程訪問以及有統一接口,安全便于擴展。

數據庫表的設計
視頻信息表:視頻id、視頻名稱、視頻描述、上傳時間、視頻文件路徑、封面圖路徑。

create database if not exists vod_system; use vod_system;create table if not exists tb_video(id int primary key auto_increment,name varchar(32),vdesc text,video_url varchar(255),image_url varchar(255),ctime datetime); insert tb_video values(null,"飛機大戰","這是一部爛片", "/video/plane.mp4","/image/plane.jpg",now());

2.封裝實現數據庫訪問類

該類提供視頻信息的增刪改查(所有視頻/單個視頻);
數據庫表的訪問類的實現

1.了解mysql的c語言庫接口

1.定義mysql句柄
2.初始化mysql句柄
3.連接mysql服務器
4.設置客戶端字符編碼集
5.切換選擇數據庫
6.執行語句(庫,表,數據操作—sql語句的執行)增,刪,改–只要語句執行成功,就表示完成了查-需要執行語句成功后對數據進行操作
①.將查詢結果保存到本地
②.獲取保存的結果集中的數據條數和列數3.遍歷逐條取出結果集中的每一條數據4.釋放結果集
7.關閉句柄,釋放資源
8.獲取某個接口執行失敗原因的接口

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <mysql/mysql.h>int main() {MYSQL *mysql = NULL;//定義,ysql句柄mysql = mysql_init(NULL);//初始化mysql句柄if(mysql == NULL){printf("mysql init error!\n");return -1;}//連接服務器mysql_real_connect(句柄,服務器IP,用戶名,密碼,庫名稱,//端口,套接字文件,客戶端標志)if(mysql_real_connect(mysql,"127.0.0.1","root","ljl12138","vod_system",0,NULL,0)==NULL){printf("connect mysql failed:%s\n", mysql_error(mysql));return -1;}//設置客戶端字符集int ret;ret = mysql_set_character_set(mysql,"utf8");if(ret != 0){printf("set character failed:%s\n",mysql_error(mysql));return -1;}//選擇數據庫 mysql_select_db(mysql,"vod_system");//char * insert = "insert tb_video values(null,'變形金剛','婆媳戰爭',//'video/popo.mp4', '/image/xifu.jpg',now())";//執行語句 mysql_query(句柄,語句)//char *update = "update tb_video set vdesc = '大型家庭瘋整篇' where id=2;";//char *delete = "delete from tb_video where id=2;";char *select = "select * from tb_video;";ret = mysql_query(mysql,select);if(ret != 0){printf("query sql failed:%s\n", mysql_error(mysql));return -1;}//保存結果集到本地MYSQL_RES *res = mysql_store_result(mysql);if(res == NULL){printf("store result failed:%s\n",mysql_error(mysql));return -1;}//獲取結果集條數和列數int row_num = mysql_num_rows(res);int col_num = mysql_num_fields(res);int i = 0;for(i = 0;i<row_num;++i){//逐條遍歷獲取結果集mysql_fetch_row(結果集)MYSQL_ROW row = mysql_fetch_row(res);int j = 0;for(j = 0; j<col_num; ++j){printf("%s\t",row[j]);}printf("\n");}//釋放結果集mysql_free_result(res);mysql_close(mysql);return 0; }

jsoncpp的基本使用:

實現json格式的序列化與反序列化功能

json數據類型:對象 {} ,字符串,整數,布爾,數組[]。

{“學生”:1001,“姓名”:“張三”,“年齡”:18,“婚否”:false,“成績”:[88,77,66]},

Json::Value 中間數據對象;
val[“學號”] = 1001;

Json::Writer 序列化對象,將Json::Value中的各個數據序列化為字符串;
Json::Writer 是基類一般使用它的子類:StyledWrite/FastWriter,后者為整行形式,會去掉空行,空格;前者為會添加換行,空格之類的。
接口:
std::string StyledWriter::write(val),將val按照json序列化格式序列化為字符串將其返回。

Json::Reader 反序列化對象,將一個json格式字符轉換為Json::Value;
Reader::parse(const std::string &str,Json::Value &val)
將str進行反序列化,將其反序列化之后的結果放入val中,通過val形式獲取值。

在安裝使用json時需要先進行gcc的升級:gcc升級及jsoncpp安裝

3.數據管理模塊代碼

因為表中字段有多個,所以使用json序列化將多個字段整合成一個參數傳遞起來會方便很多。


//數據管理模塊 #include <iostream> #include <mysql/mysql.h> #include <jsoncpp/json/json.h> #include <mutex>namespace vod_system { #define MYSQL_HOST "127.0.0.1" #define MYSQL_USER "root" #define MYSQL_PASS "ljl12138" #define MYSQL_NAME "vod_system"static MYSQL *MysqlInit()//初始化接口{MYSQL *mysql = mysql_init(NULL);//句柄初始化if(mysql == NULL){std::cout<<"mysql init failed!\n";return NULL;}if(mysql_real_connect(mysql,MYSQL_HOST,MYSQL_USER,MYSQL_PASS,MYSQL_NAME,0,NULL,0)==NULL)//連接服務器{std::cout<<mysql_error(mysql)<<std::endl;mysql_close(mysql);return NULL;}if(mysql_set_character_set(mysql,"utf8")!=0){//設置字符集std::cout<<mysql_error(mysql)<<std::endl;mysql_close(mysql);return NULL;}return mysql;}static void MysqlRelease(MYSQL *mysql)//數據庫釋放接口{if(mysql != NULL){mysql_close(mysql);}return;}static bool MysqlQuery(MYSQL *mysql, const std::string sql)//執行語句操作接口{//執行接口封裝int ret = mysql_query(mysql,sql.c_str());if(ret != 0)//執行失敗{std::cout<<sql<<std::endl;//要執行的語句std::cout<<mysql_error(mysql)<<std::endl;return false;}return true;}///數據庫訪問類class TableVod{private:MYSQL *_mysql;std::mutex _mutex;public:TableVod()//數據庫句柄初始化連接服務器{_mysql = MysqlInit();if(_mysql == NULL){exit(0);}}~TableVod()//數據庫句柄銷毀{MysqlRelease(_mysql);}//增bool Insert(const Json::Value &video){const char* name = video["name"].asCString();const char* vdesc = video["vdesc"].asCString();const char *video_url = video["video_url"].asCString();const char* image_url = video["image_url"].asCString();char sql[8192] = {0}; #define VIDEO_INSERT "insert tb_video values(null,'%s','%s','%s','%s',now());"sprintf(sql,VIDEO_INSERT, name,vdesc,video_url,image_url);return MysqlQuery(_mysql,sql);}//刪bool Delete(int video_id){ #define VIDEO_DELETE "delete from tb_video where id=%d;"char sql[8192] = {0};sprintf(sql,VIDEO_DELETE,video_id);return MysqlQuery(_mysql,sql);}//改bool Update(int video_id,const Json::Value &video){ #define VIDEO_UPDATE "update tb_video set name='%s',vdesc='%s' where id=%d;"char sql[8192] = {0};sprintf(sql,VIDEO_UPDATE,video["name"].asCString(),video["vdesc"].asCString(),video_id);return MysqlQuery(_mysql,sql);}//查bool GetAll(Json::Value *video){ #define VIDEO_GETALL "select * from tb_video;"_mutex.lock();bool ret = MysqlQuery(_mysql,VIDEO_GETALL);//查詢結果集if(ret ==false){_mutex.unlock();return false;}MYSQL_RES * res = mysql_store_result(_mysql);//保存結果集_mutex.unlock();if(res ==NULL){std::cout<<"store result failed!\n";return false;}int num = mysql_num_rows(res);//獲取結果集條數for(int i = 0;i<num;++i){MYSQL_ROW row = mysql_fetch_row(res);//遍歷結果集Json::Value val;val["id"] = std::stoi(row[0]);val["name"] = row[1];val["vdesc"] = row[2];val["video_url"] = row[3];val["image_url"] = row[4];val["ctime"] = row[5];video->append(val);//添加數組元素,每一條都是一個數組元素}mysql_free_result(res);//釋放結果集return true;}bool GetOne(int video_id,Json::Value *video){ #define VIDEO_GETONE "select * from tb_video where id=%d;"char sql_str[4096] = {0};sprintf(sql_str,VIDEO_GETONE,video_id);_mutex.lock();bool ret = MysqlQuery(_mysql,sql_str);if(ret == false){_mutex.unlock();return false;}MYSQL_RES *res = mysql_store_result(_mysql);_mutex.unlock();if(res == NULL){std::cout<<mysql_error(_mysql)<<std::endl;return false;}int num_row = mysql_num_rows(res);if(num_row != 1){std::cout<<"getone result error\n";mysql_free_result(res);return false;}MYSQL_ROW row = mysql_fetch_row(res);//從結果集獲取一條結果(*video)["id"] = video_id;(*video)["name"] = row[1];(*video)["vdesc"] = row[2];(*video)["video_url"] = row[3];(*video)["image_url"] = row[4];(*video)["ctime"] = row[5];mysql_free_result(res);return true;}}; }

前端界面模塊

實現前端界面能夠與用戶進行交互

1.完成前端html界面的編寫

html+css+js
html:標簽化語言,實現瀏覽器對于最粗糙的界面的渲染;
css:層疊樣式語言,實現對html進行樣式美化;
js:javascript腳本語言,實現讓界面動態渲染,本次我們使用vue.js進行前端頁面的渲染,在使用vue.js前需要本地安裝或者遠程請求服務。

本次項目的界面并非從零開始編寫,在網上找的模板中做些修改即可,在把前端界面初步完成之后,需要使用ajax進行交互

ajax
就像是http客戶端,相當于當前界面分離的一個客戶端與服務器進行數據交互,說白了ajax的作用就是,從后臺獲取到數據。在本次項目中,我們使用jquery ajax,使用前和vue.js一樣需要本地安裝或者遠程請求服務。

前端界面:
負責展示當前服務器上的所有視頻

單個視頻播放界面:
視頻播放界面需要指定到底要播哪個視頻,所以需要回調函數,會用到字符串替換boost庫,使用庫前先安裝。yum -y install boost boost_system


業務處理模塊

接收前端請求進行業務處理最終響應

1.http服務器的搭建:

實現與前端的網絡通信——接受客戶端請求,使用httplib庫完成http服務器的搭建。why不獨立實現http,使用庫項目難度降低,提高開發速度,用庫比自己實現更為穩定。httplib可以幫助我們用更剪短的代碼來搭建http服務器,用戶只需要根據什么樣的服務去做相應的處理就ok,從而不需要放心思至服務器的搭建而是更關注具體的業務。

httplib庫
組成:
Server類:
服務端類;
用于搭建服務器,實現網絡通信,解析http請求,組織http響應;
Server類中就一張map表。當我們實現一個服務端時,就會在里面填充信息,請求與處理函數的映射表。

Request結構體:
將http請求數據解析后就能得到這個類的對象,包含了一次http請求中的所有信息;

Response類:
響應信息類,通常其中的數據需要用戶自己添加。

#include "httplib.h"using namespace httplib;void helloworld(const Request &req, Response &rsp) {rsp.body = "<html><body><h1>Hello</h1></body></html>";rsp.status = 200;rsp.set_header("Content-Type", "text/html"); } int main() {httplib::Server srv;//實例化服務端對象srv.set_base_dir("./wwwroot");srv.Get("/hello",helloworld);srv.listen("0.0.0.0",9000);return 0; }


正則表達式:
用來檢索和替換符合文本規則的文本

2.請求與響應的網絡通信接口設計

1.靜態頁面請求(首頁,播放)

①GET/index.html HTTP/1.1(首頁)
響應:
HTTP/1.1 200 OK
…(正文index.html文件數據)

②GET/video.html?id=1
響應:
HTTP/1.1 200 OK
…(正文video.html文件數據)

2.動態數據請求

視頻數據信息的增刪改查
多個視頻對象的序列化設計——采用restful風格網絡接口設計
1. 基于http,正文數據使用xml或者json格式進行序列化,我們采用json格式序列化;json是一種輕量化的數據交換格式,采用完全獨立于編程語言的文本格式來存儲和表示數據。
Json數值對象:數組、數字、字符串;
eg:表示多個學生信息[{name:“zhangsan”,age:18,score:[77,88,99],marry:false},{name:“zhangsan”,age:18,score:[77,88,99],marry:false}]

2. restful風格里面定義了四種操作類型:新增(POST)、獲取(GET)、修改(PUT)、刪除(DELETE)。

①新增視頻信息:
請求:
POST /video HTTP/1.1
頭部…
正文{name:“變形金剛”…}
響應:
<1>HTTP/1.1 200 OK
頭部…
無正文
<2>HTTP/1.1 500 SEVER ERROR

{result:false,reason:“mysql err”}
(不適宜json格式,因為視頻數據大,存在風險,使用http默認的文件上傳操作html操作)
原生的文件上傳,正文中分為多個表單數據域,每個域表示的是不同的提交的表單項(視頻文件數據,封面圖片數據,視頻名稱,視頻描述)收到請求進行解析。
1.將視頻文件數據,以及圖片數據存儲到對應文件中;
2.將視頻路徑,圖片路徑,視頻名稱,描述存儲到數據庫。

上傳的視頻文件重名如何處理?

當前做法:直接覆蓋式寫入
預想做法:每個用戶上傳的文件名都以一種獨一無二的形式命名(時間戳+用戶名+某種算法)。

上傳的文件冗余重復(名字不同,數據實際相同)

當前做法:不作處理;
預想做法:計算每個文件的md5值存放到視頻信息數據庫中,每個上傳的視頻文件都要計算md5,然后到數據庫中查找有沒有相同md5的文件,如果有,則直接將url路徑拿過來就行,不用存放冗余文件數據。

MD5: 是一種信息摘要算法,常用于文件數據的唯一標識,針對一個文件的數據進行大量用算得到一個md5值;文件內容一有差別得到的MD5值大不相同。Linux中MD5sum命令就是計算文件的MD5值。

②刪除視頻信息:
請求:
DELETE /video?id=1 HTTP/1.1

無正文
響應:
HTTP/1.1 200 OK

正確響應則無正文

③修改視頻信息:
請求
PUT /video/1(或者/video?id=1) HTTP/1.1

{name:"", desc:"", …}
響應:
HTTP/1.1 200 OK

④獲取視頻信息:
獲取所有:
請求:
GET /video HTTP/1.1

無正文
響應:
HTTP/1.1 200 OK

[{視頻1信息},{視頻2信息}…]

獲取單個視頻信息:
請求:
GET /video/1 HTTP/1.1

響應:
HTTP/1.1 200 OK

{視頻信息}

http協議實現
http服務器:實質是tcp服務器,上層使用http協議約定數據格式。

協議格式:
首行:
①請求行:請求方法(GET/HEAD/POST/PUT…),URL(統一資源定位符http://user:pass@ip:port/path?key=val#ch),協議版本(0.9/1.0/1.1/2.0)
②協議行:協議版本,響應狀態碼,狀態碼描述;1××協議切換/2××正確處理/3××重定向/4××客戶端錯誤/5××服務端錯誤

頭部:
鍵值對組成的頭部字段
Content-Type:正文類型
Content-Length:正文長度,解決http拈包問題
Connection:控制長短連接
Location:重定向新鏈接
Cookie、Set-Cookie:維護http通信狀態–保存在客戶端持續傳輸維護狀態
session:保存在服務端,通過cookie傳遞sessionid,包含客戶端隱私信息和狀態信息

空行:
\r\n:間隔頭部與正文,標識頭部結束位置

正文:
提交響應的數據

在基本完成模塊搭建之后,使用postman模擬客戶端對服務端進行請求來交互。

#include <iostream> #include <mysql/mysql.h> #include <jsoncpp/json/json.h> #include <mutex> #include <fstream>//數據管理模塊namespace vod_system { #define MYSQL_HOST "127.0.0.1" #define MYSQL_USER "root" #define MYSQL_PASS "ljl12138" #define MYSQL_NAME "vod_system"static MYSQL *MysqlInit()//初始化接口{MYSQL *mysql = mysql_init(NULL);//句柄初始化if(mysql == NULL){std::cout<<"mysql init failed!\n";return NULL;}if(mysql_real_connect(mysql,MYSQL_HOST,MYSQL_USER,MYSQL_PASS,MYSQL_NAME,0,NULL,0)==NULL)//連接服務器{std::cout<<mysql_error(mysql)<<std::endl;mysql_close(mysql);return NULL;}if(mysql_set_character_set(mysql,"utf8")!=0){//設置字符集std::cout<<mysql_error(mysql)<<std::endl;mysql_close(mysql);return NULL;}return mysql;}static void MysqlRelease(MYSQL *mysql)//數據庫釋放接口{if(mysql != NULL){mysql_close(mysql);}return;}static bool MysqlQuery(MYSQL *mysql, const std::string sql)//執行語句操作接口{//執行接口封裝int ret = mysql_query(mysql,sql.c_str());if(ret != 0)//執行失敗{std::cout<<sql<<std::endl;//要執行的語句std::cout<<mysql_error(mysql)<<std::endl;return false;}return true;}///數據庫訪問類class TableVod{private:MYSQL *_mysql;std::mutex _mutex;public:TableVod()//數據庫句柄初始化連接服務器{_mysql = MysqlInit();if(_mysql == NULL){exit(0);}}~TableVod()//數據庫句柄銷毀{MysqlRelease(_mysql);}//增bool Insert(const Json::Value &video){const char* name = video["name"].asCString();const char* vdesc = video["vdesc"].asCString();const char *video_url = video["video_url"].asCString();const char* image_url = video["image_url"].asCString();char sql[8192] = {0}; #define VIDEO_INSERT "insert tb_video values(null,'%s','%s','%s','%s',now());"sprintf(sql,VIDEO_INSERT, name,vdesc,video_url,image_url);return MysqlQuery(_mysql,sql);}//刪bool Delete(int video_id){ #define VIDEO_DELETE "delete from tb_video where id=%d;"char sql[8192] = {0};sprintf(sql,VIDEO_DELETE,video_id);return MysqlQuery(_mysql,sql);}//改bool Update(int video_id,const Json::Value &video){ #define VIDEO_UPDATE "update tb_video set name='%s',vdesc='%s' where id=%d;"char sql[8192] = {0};sprintf(sql,VIDEO_UPDATE,video["name"].asCString(),video["vdesc"].asCString(),video_id);return MysqlQuery(_mysql,sql);}//查bool GetAll(Json::Value *video){ #define VIDEO_GETALL "select * from tb_video;"_mutex.lock();bool ret = MysqlQuery(_mysql,VIDEO_GETALL);//查詢結果集if(ret ==false){_mutex.unlock();return false;}MYSQL_RES * res = mysql_store_result(_mysql);//保存結果集_mutex.unlock();if(res ==NULL){std::cout<<"store result failed!\n";return false;}int num = mysql_num_rows(res);//獲取結果集條數for(int i = 0;i<num;++i){MYSQL_ROW row = mysql_fetch_row(res);//遍歷結果集Json::Value val;val["id"] = std::stoi(row[0]);val["name"] = row[1];val["vdesc"] = row[2];val["video_url"] = row[3];val["image_url"] = row[4];val["ctime"] = row[5];video->append(val);//添加數組元素,每一條都是一個數組元素}mysql_free_result(res);//釋放結果集return true;}bool GetOne(int video_id,Json::Value *video){ #define VIDEO_GETONE "select * from tb_video where id=%d;"char sql_str[4096] = {0};sprintf(sql_str,VIDEO_GETONE,video_id);_mutex.lock();bool ret = MysqlQuery(_mysql,sql_str);if(ret == false){_mutex.unlock();return false;}MYSQL_RES *res = mysql_store_result(_mysql);_mutex.unlock();if(res == NULL){std::cout<<mysql_error(_mysql)<<std::endl;return false;}int num_row = mysql_num_rows(res);if(num_row != 1){std::cout<<"getone result error\n";mysql_free_result(res);return false;}MYSQL_ROW row = mysql_fetch_row(res);//從結果集獲取一條結果(*video)["id"] = video_id;(*video)["name"] = row[1];(*video)["vdesc"] = row[2];(*video)["video_url"] = row[3];(*video)["image_url"] = row[4];(*video)["ctime"] = row[5];mysql_free_result(res);return true;}};class Util{public:static bool WriteFile(const std::string &name,const std::string &content){std::ofstream of;of.open(name,std::ios::binary);if(!of.is_open()){std::cout<<"open file failed!\n";return false;}of.write(content.c_str(),content.size());if(!of.good()){std::cout<<"write file failed!\n";return false;}of.close();return true;}}; }

主函數

#include <boost/algorithm/string.hpp> #include "db.hpp" #include "httplib.h" #include <fstream>#define WWWROOT "./wwwroot"///video/**.mp4(數據庫中的存儲的的視頻信息)using namespace httplib;vod_system::TableVod *tb_video;//why全局變量,因為httplib庫是基于多線程void VideoDelete(const Request &req, Response &rsp) {//req.path = /video/1 req.matches存放正則表達式匹配到的內容//1.獲取視頻idint video_id= std::stoi(req.matches[1]);//2.從數據庫中獲取到對應視頻信息Json::Value json_rsp;Json::FastWriter writer;Json::Value video;bool ret = tb_video->GetOne(video_id,&video);if(ret == false){std::cout<< "mysql get video info failed!\n";rsp.status = 500;json_rsp["result"] = false;json_rsp["reason"] = "mysql get video info failed!";rsp.body = writer.write(json_rsp);rsp.set_header("Content-Type","application/json");return;}std::string vpath = WWWROOT + video["video_url"].asString();std::string ipath = WWWROOT + video["image_url"].asString();//3.刪除視頻文件,封面圖文件//unlink刪除指定名字的文件unlink(vpath.c_str());unlink(ipath.c_str());//4.刪除數據庫中的數據ret = tb_video->Delete(video_id);if(ret == false){rsp.status = 500;std::cout<<"mysql delete video failed!\n";return;}return; }void VideoUpdate(const Request &req, Response &rsp) {//1.獲取視頻idint video_id= std::stoi(req.matches[1]);Json::Value video;Json::Reader reader;bool ret = reader.parse(req.body ,video);//提交上來的需要修改的json序列化后的字符串if(ret ==false){std::cout<<"update video : parse video json failed!\n";rsp.status = 400;//表示客戶端錯誤return;}ret = tb_video->Update(video_id, video);if(ret == false){std::cout<<"update video:mysql update failed!\n";rsp.status=5000;//服務器內部錯誤return;}return; }void VideoGetAll(const Request &req, Response &rsp) {Json::Value videos;Json::FastWriter writer;bool ret = tb_video->GetAll(&videos);if(ret == false){std::cout<<"getall video:mysql operation failed!\n";rsp.status = 500;return;}rsp.body = writer.write(videos);rsp.set_header("Content-Type", "application/json");}void VideoGetOne(const Request &req, Response &rsp) {int video_id= std::stoi(req.matches[1]);Json::Value video;Json::FastWriter writer;bool ret = tb_video->GetOne(video_id,&video);if(ret == false){std::cout<<"getone video:mysql operation failed!\n";rsp.status = 500;return;}rsp.body = writer.write(video);rsp.set_header("Content-Type", "application/json"); }#define VIDEO_PATH "/video/" #define IMAGE_PATH "/image/" void VideoUpload(const Request &req, Response &rsp) {//視頻名稱auto ret = req.has_file("video_name");//判斷是否存在該字段if(ret == false){std::cout<<"have no video name!\n";rsp.status = 400;//請求格式問題return;}const auto & file = req.get_file_value("video_name");//獲取該字段對應的信息//視頻描述ret = req.has_file("video_desc");if(ret == false){std::cout<<"have no video desc!\n";rsp.status = 400;//請求格式問題return;}const auto& file1 = req.get_file_value("video_desc");//視頻文件ret = req.has_file("video_file");if(ret == false){std::cout<<"have no video file!\n";rsp.status = 400;//請求格式問題return;}const auto& file2 = req.get_file_value("video_file");//封面文件ret = req.has_file("image_file");if(ret == false){std::cout<<"have no image file!\n";rsp.status = 400;//請求格式問題return;}const auto& file3 = req.get_file_value("image_file");const std::string &videoname = file.content;//視頻名const std::string &videodesc = file1.content;//描述const std::string& videofile = file2.filename;//***.mp4const std::string& videocont = file2.content;//視頻文件數據const std::string &imagefile = file3.filename;//***。jpgconst std::string &imagecont = file3.content;//封面文件數據///組織路徑std::string vurl = VIDEO_PATH + file2.filename;std::string iurl = IMAGE_PATH + file3.filename;std::string wwwroot = WWWROOT;//因為WWWROOT是const char *沒有重載+vod_system::Util::WriteFile(wwwroot + vurl,file2.content);//組織出來的實際路徑并完成文件寫入vod_system::Util::WriteFile(wwwroot + iurl,file3.content);Json::Value video;video["name"] = videoname;video["vdesc"] = videodesc;video["video_url"] = vurl;video["image_url"] = iurl;ret = tb_video->Insert(video);if(ret == false){rsp.status = 500;//服務器內部錯誤std::cout<<"insert video: mysql operation failed!\n";return;}rsp.set_redirect("/");return;}bool ReadFile(const std::string &name, std::string *body) {std::ifstream ifile;ifile.open(name, std::ios::binary);if(!ifile.is_open()){printf("open file failed111:%s\n",name.c_str());ifile.close();return false;}ifile.seekg(0,std::ios::end);uint64_t length = ifile.tellg();ifile.seekg(0,std::ios::beg);body->resize(length);ifile.read(&(*body)[0],length);if(ifile.good() == false){printf("read file failed:%s\n", name.c_str());ifile.close();return false;}ifile.close();return true; }void VideoPlay(const Request &req, Response &rsp) {Json::Value video;int video_id = std::stoi(req.matches[1]);bool ret = tb_video->GetOne(video_id,&video);if(ret == false){std::cout<<"getone video:mysql operation failed!\n";rsp.status = 500;return;}std::string newstr = video["video_url"].asString();std::string oldstr = "{{video_url}}";std::string play_html = "./wwwroot/single-video.html";ReadFile(play_html,&rsp.body);boost::algorithm::replace_all(rsp.body,oldstr,newstr);rsp.set_header("Content-Type", "text/html");return;}int main() {tb_video = new vod_system::TableVod();Server srv;srv.set_base_dir("./wwwroot");///動態數據請求srv.Delete(R"(/video/(\d+))",VideoDelete);//正則表達式,\d表示匹配一個數字字符//+表示匹配字符一次或多次 //R"(string)"去除括號中字符串中每個字符的特殊含義srv.Put(R"(/video/(\d+))",VideoUpdate);srv.Get(R"(/video)",VideoGetAll);srv.Get(R"(/video(\d+))",VideoGetOne);srv.Post(R"(/video)",VideoUpload);srv.Get(R"(/play/(\d+))",VideoPlay);srv.listen("0.0.0.0",9000);//監聽return 0; }/*//插入測試 void test() {vod_system::TableVod tb_vod;Json::Value val;val["name"] = "電鋸驚魂2";val["vdesc"] = "這是個比較凈損的電影";val["video_url"] = "/video/saw2.mp4";val["image_url"] = "/video/saw2.jpg";tb_vod.Insert(val);return; }*//* void test()//查詢測試 {vod_system::TableVod tb_vod;Json::Value val;tb_vod.GetOne(3,&val);Json::StyledWriter writer;std::cout<<writer.write(val)<<std::endl;return;}*//* void test()//刪除測試 {vod_system::TableVod tb_vod;Json::Value val;val["name"] = "電鋸驚魂";val["vdesc"] = "這是個比較凈損的電影";val["video_url"] = "/video/saw.mp4";val["image_url"] = "/video/saw.jpg";tb_vod.Delete(2);return; }*//* void test()//修改測試 {vod_system::TableVod tb_vod;Json::Value val;val["name"] = "電鋸驚魂";val["vdesc"] = "這是個很血腥的電影";val["video_url"] = "/video/saw.mp4";val["image_url"] = "/video/saw.jpg";tb_vod.Update(2,val);return; }*//*void test1() {vod_system::TableVod tb_vod;Json::Value val;val["name"] = "速度與激情9";val["vdesc"] = "這是個非常刺激的電影";val["video_url"] = "/video/speed.mp4";val["image_url"] = "/video/speed.jpg";tb_vod.Insert(val);return; }*/ /* int main() {//局部功能測試test();return 0; }*/

總結

項目源碼

總結

以上是生活随笔為你收集整理的基于C++的视频点播系统的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。