轻松实现 网络视频播放器

news/2024/7/9 18:39:38 标签: 数据库, epoll, c/c++

  最近用activeX media player做了个播放器,做过的人都知道,几乎没技术含量。在自己无聊的玩弄中,发现这个控件能够解析http、ftp协议,播放互联网的文件资源。现在被困在学校也无事可做,干脆把给这播放器写个服务器,用来播放互联网上的公开资源。

  media player的activeX控件十分强大,只需设置正确的url即可播放本地乃至互联网的文件资源。因此要给播放器做服务端,最重要的是向客户端传达正确的URL的信息。做服务器的思路便是:通过数据库记录下所有文件资源的信息与url,服务端读取这些信息通过列表的形式发送给客户端。客户端将这些信息呈现给用户,又用户选择播放的文件,之后将相应的url传达给播放控件,由播放控件自动向url对应的服务器发起文件请求实现播放。

  综上所述,服务端只需要完成数据库存储,与客户端传输文件信息,以及与播放器传输文件数据即可。为了简化开发,我们这里的文件传输暂时先采用apache这些http服务器,这样也便于更早的调试。

  数据库使用的mysql,服务器使用linux下的c++ socket epoll(其实使用php或是javaweb更方便,但我更想多用用c++)。客户端使用的mfc+ActiveX。

 

  虽然服务器的实现很简单,但客户端更简单,我先从最简单的客户端说起:

  有段时间没摸过vs了,上次使用还是在撸cocos2d的时候。得意与强大的vs和activeX,一个能播放视频的播放器只用了10几分钟就做好了,剩下的时间全花在播放控制与播放列表存储与管理上。

  

  因为用的是vs2012,似乎并没有该activeX的doc,于是自己在网上下载的CWMPPlayer4这些doc。

  可以通过输入url直接播放该地址文件。

  简单而强大,不单单能播放本地与自己服务器的视频。但mkv这些视频格式需要另写解码器,一些其他协议的网络视频需要作额外的处理。客户端的介绍就这么点,真的没再多了,另外只有关于链接服务器的部分。

 

  视频信息服务器:

  首先是数据库的设计,目前就一张表:

nametype
idint
created_attimestap
updated_attimestap
typeint
fileurlstring
imgurlstring
infotext

  其中有个imgurl用于指向视频介绍的截图,用于用户参看。

  因为服务的部分也没太复杂或繁杂的地方,也就没做什么设计,直接在自己以前封装的epoll模型接口上开始写服务逻辑。

  首先是数据库通信,这里使用的自己以前封装的数据库类sqluse,添加上这次的查询格式:

  

  模型:

 1 #define data_statu_end     0
 2 #define data_statu_wait    1
 3 #define data_statu_rewait  2
 4 #define data_statu_error   3
 5 #define data_statu_run     4
 6 
 7 #define data_type_unkonw   0
 8 
 9 struct model_filelist
10 {
11     int id;
12     string created_at;
13     string updated_at;
14     string name;
15     string info;
16     string imageurl;
17     string fileurl;
18     int type;
19 };

然后是协议文件:

 1 #ifndef _PROTO_H_
 2 #define _PROTO_H_
 3 
 4 
 5 #define QUEST_GET_LIST    100
 6 #define QUEST_GET_ONE     200
 7 
 8 #define RQUEST_ERROR     1000
 9 #define RQUEST_GET_LIST  1100
10 #define RQUEST_GET_ONE   1200
11 
12 
13 #define LIST_MAX_NUM 200
14 
15 struct proto_base
16 {
17     unsigned short quest;
18     unsigned long long sign;
19 };
20 
21 struct proto_filelist
22 {
23     int id;
24     char created_at[32];
25     char updated_at[32];
26     char name[64];
27     char info[256];
28     char imageurl[128];
29     char fileurl[128];
30     int type;
31 };
32 
33 struct proto_filelist_id
34 {
35     int num;
36     unsigned int idarr[LIST_MAX_NUM];
37 };
38 
39 #endif // _PROTO_H_

  因为封装的epoll模型网络部分和服务逻辑部分耦合较低,因此还是只通过那一个接口就能联系到网络部分与逻辑部分:

  

 1 #ifndef _MPLAYERSERVER_H_
 2 #define _MPLAYERSERVER_H_
 3 
 4 #include "include/sqluse.h"
 5 #include "include/proto.h"
 6 #include "include/ssock.h"
 7 
 8 
 9 class mplayerserver
10 {
11     sqluse sql;
12 public:
13     mplayerserver();
14     ~mplayerserver();
15 
16     mdata *dealdata(mdata *data);//the only api
17 
18 };
19 
20 #endif //_MPLAYERSERVER_H_

 

  最后就是服务器处理数据的逻辑:

 1 mdata *mplayerserver::dealdata(mdata *data)
 2 {
 3     mdata *newdata=new mdata;
 4     newdata->fd=data->fd;
 5 
 6     proto_base rebase;
 7 
 8     proto_base *basedata=(proto_base *)data->buf;
 9 
10     if(basedata->quest==QUEST_GET_LIST)
11     {
12         proto_filelist_id re;
13         re.num=sql.getfilelistid(re.idarr,sizeof(re.idarr));
14         if(re.num>0)
15         {
16             rebase.quest=RQUEST_GET_LIST;
17             newdata->adddata((char *)&rebase,sizeof(rebase));
18             newdata->adddata((char *)&re,sizeof(re));
19         }
20         else
21         {
22             failmdata(newdata);
23         }
24 
25     }
26     else if(basedata->quest==QUEST_GET_ONE)
27     {
28         unsigned long filelistid=basedata->sign;
29 
30         model_filelist mlist;
31         mlist.id=filelistid;
32         if(sql.getonefilelist(&mlist))
33         {
34             proto_filelist re;
35             re.id=mlist.id;
36             strcpy(re.created_at,mlist.created_at.c_str());
37             strcpy(re.updated_at,mlist.updated_at.c_str());
38             strcpy(re.name,mlist.name.c_str());
39             strcpy(re.info,mlist.info.c_str());
40             strcpy(re.imageurl,mlist.imageurl.c_str());
41             strcpy(re.fileurl,mlist.fileurl.c_str());
42             re.type=mlist.type;
43 
44             rebase.quest=RQUEST_GET_ONE;
45             newdata->adddata((char *)&rebase,sizeof(rebase));
46             newdata->adddata((char *)&re,sizeof(re));
47         }
48         else
49         {
50             failmdata(newdata);
51         }
52     }
53   //more quest..
54 
55     return newdata;
56 }

客户端连接服务器后获取到网络视频列表:

  视频数据传送:

  这里采用的是apache服务器来进行文件传送,通过url导向Apache所在服务器以及文件结构下的视频文件,来实现视频文件传输与播放。这部分以后可以自己用http协议或者是public ftp实现。

   

  一套能用的网络播放器就做好,非常的简单。

  但是这样的播放器还是不能满足现代视频播放的需要的。因为版权与利益的问题,网络上的大量视频都经过加密、路由转换等手段使得其他终端不能轻易的获取与播放,再加之目前的很多视频在容量上有很大的压缩空间,可以通过一些优化的算法与协议对传输的视频数据进行处理,实现视频的高效传输。我因为经历有限,也不想在这方面深入下去。希望自己这微不足道的网络播放器制作经历对大家有点帮助。

 

  笔者都大四该出去实习了,学校逼着留校实训竟然还是让做视频播放器,而且是2人一组使用mfc activeX做一个本地视频播放器,服务端都还是自己主动做的。一共要求做一个月,每天都要写进度文档,666,最多一天就做完的东西,剩下的29天进度文档就要靠想象力。虽然是个本科,但待这学校里面除了靠自己,真学不到任何东西,要出去实习只能去给过学校好处的单位,已经有朋友去其他单位被强制弄回来或是给处分了。系领导是个当兵的,根本就不知道什么是道理与逻辑,自己说什么就是什么。学校一瓢荤菜8块素材4块...还想吐很多学校的槽(最后还是忍住了,肯定还有很多更糟糕的学校,自我安慰下)

转载于:https://www.cnblogs.com/wchrt/p/4772753.html


http://www.niftyadmin.cn/n/1363504.html

相关文章

SQL优化-02-执行计划(EXPLAIN)

1、基本介绍 EXPLAIN语句可以获得关于MySQL如何执行SELECT语句的信息,借助于EXPLAIN,可以知道什么时候必须为表加入索引以得到一个使用索引来寻找记录的更快的SELECT。 2、语法 EXPLAIN [EXTENDED] SELECT select_options3、示例 示例用到的原始表如下…

OC在终端编写和运行

初学者如果想在终端写OC程序的话可以使用一下方法 1、编写.m文件 2、编译.m文件: cc -c 文件名.m 3、再执行: cc 文件名.o -framework Foundation 4、 执行a.out文件: ./a.out 转载于:https://www.cnblogs.com/xiaofeige/p/4781256.html

Java基础-01-基本程序结构

最近在看《算法4》,书中的数据结构和算法是基于Java实现的,所以复习了一下Java的基础知识,并和平时使用较多Python进行了对比。 1、代码 public class Test // 这里的类名必须和.java文件的名称一致 {public static void main(Stri…

android 进程间通信---Service Manager(1)

Bind机制由4个部分组成。bind驱动,Client,ServiceManager &Service 1.Bind其实是一个基于linux系统的驱动,目的是为了实现内存共享。 bind驱动的东西,由于偏向内核,并且bind机制的内容非常庞大,所以我们…

深度学习-Tensorflow2.0实现全连接神经网络

1、数据和问题描述 本文采用Tensorflow实现全连接神经网络,对鸢尾花数据进行分类。首先加载数据集,代码如下: import tensorflow as tf from sklearn import datasets import numpy as np# 读取数据 x_data datasets.load_iris().data y_da…

LeetCode Balanced Binary Tree

原题链接在这里:https://leetcode.com/problems/balanced-binary-tree/ 题目: Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the tw…

深度学习-Pytorch实现全连接神经网络

1、数据和问题描述 本文采用 Pytorch 实现全连接神经网络,对鸢尾花数据进行分类。首先加载数据集,代码如下: import numpy as np import torch import torch.utils.data as Data from torch.nn import functional as F from sklearn import …

IIS使用 URL Rewrite Module 2.0组件 设置伪静态的方法

简体中文版WIn10无法安装,需要改注册表, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp MajorVersion 项,这个也是 dword 值 10(注意是十进制),把它改成9。 简体中文版下载地址是:http://dow…