ijkplayer自定义协议播放加密视频
FFmpeg实现http、https这些标准协议,但是要播放加密视频怎么办呢?ijkplayer在FFmpeg的libavformat模块进行扩展ijkio、ijklongurl、ijktcphook、ijkhttphook,我们也可以在这个基础上,自定义协议来进行解密播放。主要基于URLProtocol和AVClass进行扩展,实现protocol对应的方法。
URLProtocol的结构体如下:
typedef struct URLProtocol {const char *name;int (*url_open)(URLContext *h, const char *url, int flags);int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);int (*url_accept)(URLContext *s, URLContext **c);int (*url_handshake)(URLContext *c);int (*url_read)(URLContext *h, unsigned char *buf, int size);int (*url_write)(URLContext *h, const unsigned char *buf, int size);int64_t (*url_seek)(URLContext *h, int64_t pos, int whence);int (*url_close)(URLContext *h);int priv_data_size;const AVClass *priv_data_class;const char *default_whitelist;
} URLProtocol;
FFmpeg实现的标准协议有包括http、https、hls、tcp、rtmp等,如下图所示:
1、添加自定义协议
新建一个源文件ijkdecrypt.c放在libavformat,实现ijkdecrypt_open、ijkdecrypt_read、ijkdecrypt_seek、ijkdecrypt_close等方法,然后把方法注册到URLProtocol:
static int ijkdecrypt_open(URLContext *h) {return decrypt_open(h);
}
static int ijkdecrypt_read(URLContext *h, unsigned char *buf, int size) {return decrypt_read(h, buf, size);
}
static int64_t decrypt_seek(URLContext *h, int64_t offset, int whence) {return decrypt_seek(h, offset, whence);
}
static int decrypt_close(URLContext *h) {return decrypt_close(h);
}static const AVClass ijkio_context_class = {.class_name = "IjkDecrypt",.item_name = av_default_item_name,.option = options,.version = LIBAVUTIL_VERSION_INT,
};URLProtocol ijkimp_ff_ijkio_protocol = {.name = "ijkdecrypt",.url_open2 = ijkdecrypt_open,.url_read = ijkdecrypt_read,.url_seek = ijkdecrypt_seek,.url_close = ijkdecrypt_close,.priv_data_size = sizeof(Context),.priv_data_class = &ijkio_context_class,
};
2、声明自定义协议
修该libavformat/protocols.c,添加自定义协议并声明为全局变量:
extern const URLProtocol ff_ijkdecrypt_protocol;
在ffbuild/config.mak会自动生成CONFIG_FF_IJKDECRYPT_PROTOCOL
3、依赖自定义协议
在libavformat/makefile添加依赖文件:
OBJS-$(CONFIG_FF_IJKDECRYPT_PROTOCOL) += ijkdecrypt.o
4、dummy自定义协议
在libavformat/ijkutils.c添加dummy的ijkdecrypt:
IJK_DUMMY_PROTOCOL(ijkdecrypt);
dummy过程是生成AVClass和URLProtocol:
#define IJK_DUMMY_PROTOCOL(x) \
IJK_FF_PROTOCOL(x); \
static const AVClass ijk_##x##_context_class = { \.class_name = #x, \.item_name = av_default_item_name, \.version = LIBAVUTIL_VERSION_INT, \}; \\
URLProtocol ff_##x##_protocol = { \.name = #x, \.url_open2 = ijkdummy_open, \.priv_data_size = 1, \.priv_data_class = &ijk_##x##_context_class, \
};
5、注册自定义协议
在allformats.c调用ijkav_register_all进行注册自定义协议:
void ijkav_register_all(void)
{av_register_all();/* protocols */
#ifdef __ANDROID__IJK_REGISTER_PROTOCOL(ijkmediadatasource);
#endifIJK_REGISTER_PROTOCOL(ijkio);IJK_REGISTER_PROTOCOL(async);IJK_REGISTER_PROTOCOL(ijklongurl);IJK_REGISTER_PROTOCOL(ijktcphook);IJK_REGISTER_PROTOCOL(ijkhttphook);IJK_REGISTER_PROTOCOL(ijksegment);/* demuxers */IJK_REGISTER_DEMUXER(ijklivehook);IJK_REGISTER_DEMUXER(ijklas);
}
IJK_REGISTER_PROTOCOL()对应的宏定义:
#define IJK_REGISTER_PROTOCOL(x)
{ \ extern URLProtocol ijkmp_ff_##x##_protocol; \ int ijkav_register_##x##_protocol(URLProtocol *protocol, int protocol_size); \ijkav_register_##x##_protocol(&ijkimp_ff_##x##_protocol, sizeof(URLProtocol));\
}
其中ijkav_register_##x##_protocol的宏定义如下:
int ijkav_register_##x##_protocol(URLProtocol *protocol, int protocol_size)
{ if (protocol_size != sizeof(URLProtocol)) {av_log(NULL, AV_LOG_ERROR, "ABI mismatch.\n"); return -1; } memcpy(&ff_##x##_protocol, protocol, protocol_size); return 0;
}
6、拦截自定义协议
首先在ijkioprotocol.c声明自定义协议:
extern IjkURLProtocol ijkio_decrypt_protocol;
然后对scheme进行拦截,把自定义协议赋值给IjkURLProtocol:
int ijkio_alloc_url(IjkURLContext **ph, const char *url) {if (!ph) {return -1;}IjkURLContext *h = NULL;if (!strncmp(url, "httphook:", strlen("httphook:"))) {h = (IjkURLContext *)calloc(1, sizeof(IjkURLContext));h->prot = &ijkio_httphook_protocol;h->priv_data = calloc(1, ijkio_httphook_protocol.priv_data_size);} else if (!strncmp(url, "decrypt:", strlen("decrypt:"))) {h = (IjkURLContext *)calloc(1, sizeof(IjkURLContext));h->prot = &ijkio_decrypt_protocol;h->priv_data = calloc(1, ijkio_decrypt_protocol.priv_data_size);} else {return -1;}*ph = h;return 0;
}
7、查找自定义协议
在avformat_open_input时,会初始化input、打开avio、根据scheme查找对应协议,完整调用路径为init_input->avio_open2->ffurl_open->ffurl_alloc->url_find_protocol。在avio.c的查找协议过程为:
static const struct URLProtocol *url_find_protocol(const char *filename) {......protocols = ffurl_get_protocols(NULL, NULL);if (!protocols)return NULL;for (i = 0; protocols[i]; i++) {const URLProtocol *up = protocols[i];if (!strcmp(proto_str, up->name)) {av_freep(&protocols);return up;}if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME &&!strcmp(proto_nested, up->name)) {av_freep(&protocols);return up;}}av_freep(&protocols);return NULL;
}
ijkplayer自定义协议播放加密视频相关推荐
- 如何在HTML5页面播放加密视频
如何在HTML5页面播放加密视频 - Polyv blog 如何在HTML5页面播放加密视频 Polyv移动端加密默认是可以直接支持HTML5浏览器播放的,如果担心视频在移动端被下载, 需要在Poly ...
- .NET MVC对接POLYV——HTML5播放器播放加密视频
官方参考文档:http://dev.polyv.net/2017/videoproduct/v-playerapi/html5player/html5-docs/ 1.上传视频之前根据自己需要对所上传 ...
- 从blob协议的加密视频地址下载视频
目标下载视频地址:blob:http://www.yunxiedu.net/2be908de-216b-4b57-badb-1d3be699e077 如下图视频还是弹窗网页视频: I (1)安装插件浏 ...
- RTSP协议播放网络视频
海康摄像头 主码流 rtsp://admin:12345@192.0.0.64:81/h264/ch1/main/av_stream rtsp://admin:12345@192.0.0.64:81/ ...
- 移动端加密视频的授权播放
移动端加密视频的授权播放 Polyv的移动端加密视频由hls(m3u8文件)来实现. 移动端加密视频授权播放分三个级别 1.开放授权 开放授权意味着视频可以被随意观看,视频解密的key不被保护. 2. ...
- vep加密视频破解转换翻录为mp4教程
可能有很多人都没有听说过这个视频格式,这是大黄蜂云课堂播放器所独有的格式,只有通过该播放器才能够打开这个加密的视频,安全系数很高,但也极大的限制了一个视频的传播和播放.如果我们在网络上下载了vep格式 ...
- vep加密视频破解转换为mp4教程
可能有很多人都没有听说过这个视频格式,这是大黄蜂云课堂播放器所独有的格式,只有通过该播放器才能够打开这个加密的视频,安全系数很高,但也极大的限制了一个视频的传播和播放.如果我们在网络上下载了vep格式 ...
- Unity 使用 Ffmpeg 加密视频
Unity 使用 Ffmpeg 加密视频 参考 Ffmpeg 命令加密视频 -i "{STREAMING_ASSETS_PATH}/3D.mp4" -c:v copy -c:a c ...
- 开源播放器 ijkplayer (一) :使用Ijkplayer播放直播视频
1.ijkplayer 编码 IjkPlayer支持硬解码和软解码. 软解码时不会旋转视频角度这时需要你通过onInfo的what == IMediaPlayer.MEDIA_INFO_VIDEO_R ...
- Html5视频加密/html5播放器视频加密应用实例
说说html5的视频加密,HTML5因无需插件可跨平台使用.开发免费.对搜索引擎友好等,深受广大开发者的喜爱,成为主流播放器的发展趋势. 市面上常见的H5加密,采用标准的Apple HLS Encry ...
最新文章
- 为什么对高斯分布的方差的极大似然估计是有偏的?
- vivo 全球商城:商品系统架构设计与实践
- 《虚拟化与云计算》第4章 虚拟化的业界动态
- 各种ARM仿真器接口图
- Hbase 删表过程
- js中的关键子in的使用方法
- Citrix 整体架构 端口列表 Tcp Port
- demo连接php,PHP获取网页所有连接的方法(附demo源码下载)
- nyoj 779 兰州烧饼
- CSS 获取当前可视屏幕高度--使用calc()方法动态计算宽度或者高度
- 批量检测百度云分享链接有效性方法
- 使用 GNU gettext 实现国际化
- 【3D目标检测】学习过的论文整理
- 三国时期曹魏五大名将-五子良将
- Java对URL中的中文进行UrlEncode转码
- 大数据技术——HBase简介
- ASP.NET Core学习之路03
- 音频放大电路制作记录
- 【原创】Java获取CPU占用率、内存占用率最简单的方式
- assert预处理宏与预处理变量