/zport

zport 是一个轻量且使用方便的http推流库。通过它,你可以让自定义的媒体数据轻易地在任意播放器上播放

Primary LanguageC++

zport 是一个轻量且使用方便的http推流库。通过它,你可以让自定义的媒体数据轻易地在任意播放器上播放。

zport特点:

  • 易用的接口,可以轻易对接你的媒体源
  • 支持seek
  • 轻量,c++编写,无其他依赖,跨平台,容易移植、集成

使用

为了方便最低成本理解代码,并使用该项目。作者避免了引入复杂的代码层级结构。

代码分两部分:zport框架 + MediaReader

zport框架代码在src目录,一般无需修改。

MediaReader是你需要实现的内容,通过实现MediaReader把要推流的资源描述清楚,

比如file/reader.cpp是一个“读取本地文件进行推流的MediaReader”,最简单的编译方法:

g++ -o server -std=c++11 -I./file -I./src src/*.cpp main.cpp

执行./server就可以通过http://127.0.0.1:1000/media?path=/path/to/file访问本地文件了

IMediaReader

IMediaReader是提供给用户继承实现的。

主要的方法是:open/close/read/size。参考file/reader.cpp的实现。

特别指出的是read的实现:

virtual void read(int64_t offset, 
            std::function<void(const char *data, size_t data_len)> dataSink,
            std::function<void(int info)> notify)

zport会在推流过程中不断回调该方法,直到读到所有数据。

用户有两种实现方案:

  1. 在单次read中多次调用dataSink,把所有数据给zport
  2. 每次read,只作一次dataSink,取可用数据给zport

上述两种方法对zport而言,并没有区别,可以按照你喜欢的方式使用。

** 不可seek资源 **

对于不可seek资源,通过size()返回小于0的数值,告知zport,zport就会以chunked方式推流。

实现IMediaReader::read时,通过notify(READER_EOF)告知zport数据完成

** 支持seek的资源 **

对于支持seek的资源,就需要通过size()返回整个资源的长度,并正确响应open时传入的请求,特别是from/to指定的范围。

实现IMediaReader::read时,需要一直返回足够的数据(to-from+1)后,zport才会停止回调(数据不足,会忽略READER_EOF)。中途只能通过READER_ERROR出错退出。

CMakeLists.txt编译

mkdir build
cd build
cmake .. -DREADER=file -DBUILD_EXE=1 -DCMAKE_BUILD_TYPE=Debug

cmake支持的参数:

  • READER: 指定reader.cpp所在的目录,比如指定file,则编译file/reader.cpp
  • BUILD_EXE: 指定是否编译为可执行程序,与BUILD_TEST冲突。不指定或0,则编译为动态库
  • BUILD_TEST: 编译测试代码(需要先下载googletest代码到test目录下)
  • CMAKE_BUILD_TYPE: Debug编译调试模式代码;Release编译发布模式代码

开发计划

  • 支持https
  • test

代码结构

  • src: zport代码
  • file/decrypt: MediaReader的各种example
  • test:单元测试代码
  • mockserver: 一个简单的http server,测试用

关于http MediaReader的实现

要代理远程http的资源,你需要学习一种http client的API,以拉取远程资源

并且,一般的http模块,提供的API都是”推数据“模式,也就是注册一个回调,由模块告诉你数据ready了,来拿走。在做http推流的时候,我们希望数据是”拉“模式——”我要多少数据,立即给我“。两种模式的转换方法需要一定技巧,在example在实现有点喧宾夺主

“拉http资源 -> 转换 -> 推流”算是共性需求,写了example,难免让“拿来主义”盛行——拷贝代码就走人了

虽然是共性需求,但每个需求中的服务器不同,对于转换的实现不同,性能要求不同,都会在很大程度上影响如何实现。也是要花精力去设计和调优,example不一定能覆盖所有需求。参考第三点,如果出了代码质量问题,这锅zport不背

鉴于以上4点(和作者的私心),如果有需要http MediaReader example的,可以到这里购买支持作者:https://mianbaoduo.com/o/bread/Yp2alZY=

如何代理远程服务器的加密视频,给本地任意播放器播放?

这也是本项目的创建初衷。

解决方法也不难,只需要在上一节的http MediaReader的基础上整合decrypt reader的解密代码,就可以实现功能了。

如果需要代码,也可以直接在这里下载:https://mianbaoduo.com/o/bread/mbd-Yp2alZo=