大牛直播SDK多路RTSP-RTMP转RTMP官方定制版

视沃科技(大牛直播SDK)多路RTMP/RTSP转RTMP转发软件,系原有转发SDK基础上,官方推出的Windows平台定制版。在秉承低延迟、灵活稳定、低资源占用的前提下,客户无需关注开发细节,只需图形化配置转发等各类参数,实现产品快速上线目的。

如监控类摄像机、NVR等,通过厂商说明或Onvif工具,获取拉流的RTSP地址,图形化配置,完成拉流转发等操作,轻松实现标准RTMP服务器(或CDN)对接。

视频转发支持H.264、H.265(需要RTMP服务器或CDN支持扩展H.265),音频支持配置PCMA/PCMU转AAC后转发,并支持只转发/录制视频或音频,RTSP拉流端支持鉴权和TCP/UDP模式设置和TCP/UDP模式自动切换,整个拉流、转发模块都有非常完善的自动重连机制。

此外,可以通过点击拉流地址或推流地址栏,实现推拉流地址,同步到左侧预览框,实现推拉流音视频数据预览。

运维方面,官方定制版转发系统支持7*24小时不间断运行,自带守护进程,转发程序被误关等各种操作后,会自动启动运行,此外,还支持开机自动启动转发或录像。

官方测试版有1小时限制,拉流超过一小时会自动停止,如需长期运行或直接授权,请联系我们。

image.png

功能说明
  1. 启动程序

支持从守护进程(如需启动转发程序,可点击SmartStreamRelayToolDaemon.exe,守护进程会自动拉起SmartStreamRelayTool.exe,如需关闭转发程序,请先关闭SmartStreamRelayToolDaemon,转发程序方可正常关闭):

image.png
  1. 添加转发项配置信息
image.png

配置说明:

添加配置项:点击页面“添加”按钮:

² 序号:无需关注,系统自动生成;

² 名称:该路转发配置项的描述信息;

² 拉流地址(必须填):需要转发的RTSP或RTMP地址;

² 推流RTMP地址:需要转推的RTMP地址;

² 推流播放地址:需要预览的播放地址;

² 音视频转发选项:可选择之转发音频或视频,亦或同时转发音视频;

² 录像参数配置:可选择录制音频或视频,亦或音视频同时录制,并可设定录像文件前缀。

备注:双击列表配置项,可以查看或编辑配置信息;

删除配置项:选中需要删除的配置数据,点击页面“删除”按钮:

image.png

如何预览推拉流数据?

点击需要预览的“拉流地址”或“推流地址”,URL会同步到左侧预览框,即可实现推拉流数据本地预览。

如不需播放音频,点击“静音”选项即可。

如何转发数据?

  1. 选中需要转发的配置数据项目(如需全部转发,点击全选选项即可);
  2. 点击“拉流”按钮,拉流生效后,页面“流下载速度”会显示当前下载速度;

image.png

  1. 如需停止拉流,选中配置项,点击“停止拉流”即可;
  2. 拉流后,选中需要转发的配置项,点击“推流”按钮;
image.png
  1. 如需停止推流,选中配置项,点击“停止推流”即可;
  2. 如需对某一路录像,在完成“录像全局配置”的前提下,选中配置项,点击“录像”即可;
image.png
  1. 如需停止录像,选中配置项,点击“停止录像”即可。

系统配置:

² 支持程序启动后自动开启转发;

² 支持程序启动后自动开启录像(考虑到Windows平台磁盘读写性能,Windows平台不做多路录像承诺)

² 开机后自动启动(可配置开机自动启动配置名);

image.png

录像全局配置:

² 支持设置录像存储目录;

² 支持设定单个录像文件大小;

² 支持设置文件是否增加日期、时间;

² 支持设置是否音频自动转AAC编码后存储。

image.png
测试版下载链接:点击下载
相关文档:点击下载
QQ交流群:

QQ群1(已满):499687479
QQ群2:294891451

Windows平台多路RTSP/RTMP流转RTMP流深度定制版

大牛直播SDK提供的RTSP/RTMP转RTMP流模块,具备低延迟、足够稳定灵活、有状态反馈机制、资源占用低跨平台,以SDK形式提供,给开发者提供更大的便利,已应用于诸多专业第三方公司。

其中:Windows平台对外提供C++ C#接口,Android提供JNI接口封装,iOS提供object c封装。

Windows/Android/iOS RTMP/RTSP多路流媒体转发SDK功能支持:

  1. 支持拉取rtmp流;
  2. 支持拉取rtsp流;
  3. Windows支持本地flv文件转发(支持制定文件位置转发,或转发过程中seek);
  4. 支持本地预览;
  5. 支持转发过程中,实时静音;
  6. 支持转发过程中,切换rtmp/rtsp url,此外,windows平台还支持切换本地flv文件;
  7. 支持录像模块扩展,可边转发边录制,每个文件录制开始结束,均有状态回馈;
  8. 支持内网RTSP网关模块扩展,拉取的流数据,可以流入到内网RTSP网关模块,对外微型RTSP媒体流服务(RTSP url),便于内网访问;
  9. 音频:AAC,并支持拉流后的音频(PCMU/PCMA,Speex等)转AAC后再转发;
  10. 视频:H.264、H.265,支持h265转发(rtsp/rtmp h265转rtmp h265推送)

对应Demo:

  • Windows测试程序:SmartStreamRelayDemo.exe;
  • Windows C++工程:WIN-RelaySDK-CPP-Demo;
  • Windows C#工程:WIN-RelaySDK-CSharp-Demo;
  • Android工程:SmartRelayDemoV2;
  • iOS工程:SmartiOSRelayDemoV2。

鉴于部分公司人员配备不齐或产品开发周期短,一方面想用好的SDK,另一方面,苦于短期内没有好的人力配备完成上层业务逻辑开发,我们联合第三方开发者实现了Windows转发模块深度定制版本:

先睹为快:

1. 启动SmartStreamRelayDemo.exe

2. 输入登陆用户名、密码,其中,用户名 admin 密码123456

3. 如需配置拉流和转发RTSP RTMP url,请直接在relayconfig.ini配置

4. 页面编辑配置:
4.1 读取INI文件,获取relayconfig.ini配置项;
4.2 保存INI文件,把上层编辑后的URL配置保存下来,配置后的,可直接保存,以便下次使用
4.3 增加工作任务:页面添加新的转发配置项
4.4 启动工作任务:启动所有转发
4.5 停止工作任务:停止所有转发
4.6 录制:如需录制流,直接点击“功能选项”->“录制”按钮,默认录制到“record”目录
4.7 移除任务:如需删除某一路流,直接点击“功能选项”->“移除”按钮
4.8 拉流预览:预览拉取的RTMP/RTSP流,预览过程中,可实时静音
4.9 推流预览:转发后的RTMP流,可实时预览,亦可实时静音

4. demo版,有一小时显示,每超过一小时,自动停止运行

5. 提供底层SDK授权,上层系统OEM或上层源码授权

更多资料或demo下载:

Github: https://github.com/daniulive/SmarterStreaming

官网:https://www.daniulive.com

QQ群:

如何对RTSP播放器做功能和性能评估

好多开发者在做产品竞品分析的时候,不知道如何界定一个RTSP播放器,大牛直播SDK认为,一个RTSP播放器,不是说有几个类似于Open/Close接口就够了,好的RTSP播放器需要具备以下功能和性能属性:

1. 低延迟:大多数RTSP的播放都面向直播场景,所以,如果延迟过大,比如监控行业,小偷都走了,客户端才看到,或者别人已经按过门铃几秒,主人才看到图像,严重影响体验,所以,低延迟是衡量一个好的RTSP播放器非常重要的指标,目前大牛直播SDK的RTSP播放延迟控制在几百毫秒,VLC在几秒,这个延迟,是长时间的低延迟,比如运行1天、一周、一个月甚至更久;

2. 音视频同步或跳转:有些开发者为了追求低延迟体验,甚至不做音视频同步,拿到audio video直接播放,导致a/v不同步,还有就是时间戳乱跳;

3. 支持多实例:一个好的播放器,需要支持同时播放多路音视频数据,比如4-8-9-16-32窗口;

4. 支持buffer time设置:在一些有网络抖动的场景,播放器需要支持精准的buffer time设置,一般来说,以毫秒计;

5. H.265的播放和录制:除了H.264,还需要支持H.265,目前市面上的RTSP H.265摄像头越来越多,支持H.265的RTSP播放器迫在眉睫,此外,单纯的播放H.265还不够,还需要可以能把H.265的数据能录制下来;

6. TCP/UDP模式切换:考虑到好多服务器仅支持TCP或UDP模式,一个好的RTSP播放器需要支持TCP/UDP模式自动切换;

7. 静音支持:比如,多窗口播放RTSP流,如果每个audio都播放出来,体验非常不好,所以实时静音功能非常必要;

8. 视频view旋转:好多摄像头由于安装限制,导致图像倒置,所以一个好的RTSP播放器应该支持如视频view实时旋转(0° 90° 180° 270°)、水平反转、垂直反转;

9. 支持解码后audio/video数据输出(可选):大牛直播SDK接触到好多开发者,希望能在播放的同时,获取到YUV或RGB数据,进行人脸匹配等算法分析,所以音视频回调可选;

10. 快照:感兴趣或重要的画面,实时截取下来非常必要;

11. 网络抖动处理(如断网重连):基本功能,不再赘述;

12. 跨平台:一个好的播放器,跨平台(Windows/Android/iOS)很有必要,起码为了后续扩展性考虑,开发的时候,有这方面的考虑,目前大牛直播SDK的RTSP播放器,完美支持以上平台;

13. 长期运行稳定性:提到稳定性,好多开发者不以为然,实际上,一个好的产品,稳定是最基本的前提,不容忽视!
14. 可以录像:播放的过程中,随时录制下来感兴趣的视频片断,存档或其他二次处理;

15. log信息记录:整体流程机制实时反馈,不多打log,但是不能一些重要的log,如播放过程中出错等;

16. download速度实时反馈:可以看到实时下载速度反馈,以此来监听网络状态;

17. 异常状态处理:如播放的过程中,断网、网络抖动、来电话、切后台后返回等各种场景的处理。

说了这么多,有开发者会反问,大牛直播SDK到底支持了哪些?以下做个简单功能概述,如不单独说明,系Windows、Android、iOS全平台支持:

  •  [支持播放协议]高稳定、超低延迟、业内首屈一指的RTSP直播播放器SDK;
  •  [多实例播放]支持多实例播放;
  •  [事件回调]支持网络状态、buffer状态等回调;
  •  [视频格式]支持H.265、H.264,此外,Windows/Android平台还支持RTSP MJPEG播放;
  •  [音频格式]支持AAC/PCMA/PCMU;
  •  [H.264/H.265软解码]支持H.264/H.265软解;
  •  [H.264硬解码]Android/iOS支持H.264硬解;
  •  [H.265硬解]Android/iOS支持H.265硬解;
  •  [H.264/H.265硬解码]Android支持设置Surface模式硬解和普通模式硬解码;
  •  [RTSP模式设置]支持RTSP TCP/UDP模式设置;
  •  [RTSP TCP/UDP自动切换]支持RTSP TCP、UDP模式自动切换;
  •  [RTSP超时设置]支持RTSP超时时间设置,单位:秒;
  •  [RTSP 401认证处理]支持上报RTSP 401事件,如URL携带鉴权信息,会自动处理;
  •  [缓冲时间设置]支持buffer time设置;
  •  [首屏秒开]支持首屏秒开模式;
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [快速切换URL]支持播放过程中,快速切换其他URL,内容切换更快;
  •  [音视频多种render机制]Android平台,视频:surfaceview/OpenGL ES,音频:AudioTrack/OpenSL ES;
  •  [实时静音]支持播放过程中,实时静音/取消静音;
  •  [实时快照]支持播放过程中截取当前播放画面;
  •  [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
  •  [渲染镜像]支持水平反转、垂直反转模式设置;
  •  [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
  •  [解码前视频数据回调]支持H.264/H.265数据回调;
  •  [解码后视频数据回调]支持解码后YUV/RGB数据回调;
  •  [解码前音频数据回调]支持AAC/PCMA/PCMU/SPEEX数据回调;
  •  [音视频自适应]支持播放过程中,音视频信息改变后自适应;
  •  [扩展录像功能]完美支持和录像SDK组合使用(支持RTSP H.265流录制,支持PCMA/PCMU转AAC后录制,支持设置只录制音频或视频)。

相关资料:Github: https://github.com/daniulive/SmarterStreaming

基于AES加密的RTSP/RTMP多路转发设计方案

很多开发者最近咨询我们,除了我们Windows推送端采集编码的音视频数据可以加密外,其他RTSP/RTMP流如果想更安全的转推到RTMP服务器或相应CDN改怎么办?

实际上,我们在做RTMP整体加密方案的时候已经考虑到这种情况,SmartStreamRelayDemo在拉取RTSP或RTMP流,转推RTMP的时候,可以选择加密视频,加密音频或音视频都加密,废话不多说,参看代码:

bool nt_stream_relay_wrapper::StartPush(const std::string& url)
{
    if ( is_pushing_ )
        return false;

    if ( url.empty() )
        return false;

    if ( !OpenPushHandle() )
        return false;

    auto push_handle = GetPushHandle();
    ASSERT(push_handle != nullptr);

    ASSERT(push_api_ != NULL);
    if ( NT_ERC_OK != push_api_->SetURL(push_handle, url.c_str(), NULL) )
    {
        if ( !is_started_rtsp_stream_ )
        {
            push_api_->Close(push_handle);
            SetPushHandle(nullptr);
        }

        return false;
    }

    // 加密测试 +++

    push_api_->SetRtmpEncryptionOption(push_handle, url.c_str(), 1, 1);

    NT_BYTE test_key[16] = {'1', '2', '3'};

    push_api_->SetRtmpEncryptionKey(push_handle, url.c_str(), test_key, 16);

    // 加密测试 --

    if ( NT_ERC_OK != push_api_->StartPublisher(push_handle, NULL) )
    {
        if ( !is_started_rtsp_stream_ )
        {
            push_api_->Close(push_handle);
            SetPushHandle(nullptr);
        }

        return false;
    }


    // // test push rtsp ++

    // push_api_->SetPushRtspTransportProtocol(push_handle, 1);
    // // push_api_->SetPushRtspTransportProtocol(push_handle, 2);

    // push_api_->SetPushRtspURL(push_handle, "rtsp://player.daniulive.com:554/liverelay111.sdp");

    // push_api_->StartPushRtsp(push_handle, 0);

    // // test push rtsp--

    is_pushing_ = true;

    return true;
}

上图:

relay

这个时候,输入转发设置的Key(支持aes 128, aes 192, aes 256加密,即将发布SM4加密),方可正常播放音视频数据。

此种方案的优势在于基于AES音视频逐帧数据加密音视频数据,第三方即便是破解了URL,也没法播放,通过抓包工具抓取到数据,也没法正常显示。

相关资料:Github: https://github.com/daniulive/SmarterStreaming

Flutter下实现低延迟的跨平台RTSP/RTMP播放

为什么要用Flutter?

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。

Flutter有哪些与众不同

image

1. Beautiful – Flutter 允许你控制屏幕上的每一寸像素,这让「设计」不用再对「实现」妥协;

2. Fast – 一个应用不卡顿的标准是什么,你可能会说 16ms 抑或是 60fps,这对桌面端应用或者移动端应用来说已足够,但当面对广阔的 AR/VR 领域,60fps 仍然会成为使人脑产生眩晕的瓶颈,而 Flutter 的目标远不止 60fps;借助 Dart 支持的 AOT 编译以及 Skia 的绘制,Flutter 可以运行的很快;

3. Productive – 前端开发可能已经习惯的开发中 hot reload 模式,但这一特性在移动开发中还算是个新鲜事。Flutter 提供有状态的 hot reload 开发模式,并允许一套 codebase 运行于多端;其他的,再比如开发采用 JIT 编译与发布的 AOT 编译,都使得开发者在开发应用时可以更加高效;

4. Open – Dart / Skia / Flutter (Framework),这些都是开源的,Flutter 与 Dart 团队也对包括 Web 在内的多种技术持开放态度,只要是优秀的他们都愿意借鉴吸收。而在生态建设上,Flutter 回应 GitHub Issue 的速度更是让人惊叹,因为是真的快(closed 状态的 issue 平均解决时间为 0.29天);

除了支持APICloud, Unity3d, React Native外,大牛直播SDK为什么要做Flutter下的RTSP/RTMP播放器

首先,Flutter则是依靠Flutter Engine虚拟机在iOS和Android上运行,开发人员可以通过Flutter框架和API在内部进行交互。Flutter Engine使用C/C++编写,具有低延迟输入和高帧速率的特点,不像Unity3d一样,我们是回调YUV/RGB数据,在Unity3d里面绘制,Flutter直接调用native SDK,效率更高。

其次,客户和开发者驱动,Flutter发展至今,目前还没有个像样的RTSP或RTMP播放器,一个播放器,不是说,有个界面,有个开始、停止按钮就可以了,一个好用的直播播放器,对功能和性能属性要求很高,特别是稳定性和低延迟这块,不谦虚的说,可能是首款功能强大、真正好用的Flutter RTSP/RTMP直播播放SDK

以大牛直播SDK的播放器为例:

RTMP直播播放器功能介绍:

  • [支持播放协议]高稳定、超低延迟(一秒内,行业内几无效果接近的播放端)、业内首屈一指的RTMP直播播放器SDK;
  • [多实例播放]支持多实例播放;
  • [事件回调]支持网络状态、buffer状态等回调;
  • [视频格式]支持RTMP扩展H.265,H.264;
  • [音频格式]支持AAC/PCMA/PCMU/Speex;
  • [H.264/H.265软解码]支持H.264/H.265软解;
  • [H.264硬解码]Android/iOS支持H.264硬解;
  • [H.265硬解]Android/iOS支持H.265硬解;
  • [H.264/H.265硬解码]Android支持设置Surface模式硬解和普通模式硬解码;
  • [缓冲时间设置]支持buffer time设置;
  • [首屏秒开]支持首屏秒开模式;
  • [低延迟模式]支持类似于线上娃娃机等直播方案的超低延迟模式设置(公网200~400ms);
  • [复杂网络处理]支持断网重连等各种网络环境自动适配;
  • [快速切换URL]支持播放过程中,快速切换其他URL,内容切换更快;
  • [音视频多种render机制]Android平台,视频:surfaceview/OpenGL ES,音频:AudioTrack/OpenSL ES;
  • [实时静音]支持播放过程中,实时静音/取消静音;
  • [实时快照]支持播放过程中截取当前播放画面;
  • [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
  • [渲染镜像]支持水平反转、垂直反转模式设置;
  • [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
  • [解码前视频数据回调]支持H.264/H.265数据回调;
  • [解码后视频数据回调]支持解码后YUV/RGB数据回调;
  • [解码前音频数据回调]支持AAC/PCMA/PCMU/SPEEX数据回调;
  • [音视频自适应]支持播放过程中,音视频信息改变后自适应;
  • [扩展录像功能]完美支持和录像SDK组合使用(支持RTMP扩展H.265流录制,支持PCMA/PCMU/Speex转AAC后录制,支持设置只录制音频或视频)

RTSP直播播放器功能介绍:

  • [支持播放协议]高稳定、超低延迟、业内首屈一指的RTSP直播播放器SDK;
  • [多实例播放]支持多实例播放;
  • [事件回调]支持网络状态、buffer状态等回调;
  • [视频格式]支持H.265、H.264,此外,Windows/Android平台还支持RTSP MJPEG播放;
  • [音频格式]支持AAC/PCMA/PCMU;
  • [H.264/H.265软解码]支持H.264/H.265软解;
  • [H.264硬解码]Android/iOS支持H.264硬解;
  • [H.265硬解]Android/iOS支持H.265硬解;
  • [H.264/H.265硬解码]Android支持设置Surface模式硬解和普通模式硬解码;
  • [RTSP模式设置]支持RTSP TCP/UDP模式设置;
  • [RTSP TCP/UDP自动切换]支持RTSP TCP、UDP模式自动切换;
  • [RTSP超时设置]支持RTSP超时时间设置,单位:秒;
  • [RTSP 401认证处理]支持上报RTSP 401事件,如URL携带鉴权信息,会自动处理;
  • [缓冲时间设置]支持buffer time设置;
  • [首屏秒开]支持首屏秒开模式;
  • [复杂网络处理]支持断网重连等各种网络环境自动适配;
  • [快速切换URL]支持播放过程中,快速切换其他URL,内容切换更快;
  • [音视频多种render机制]Android平台,视频:surfaceview/OpenGL ES,音频:AudioTrack/OpenSL ES;
  • [实时静音]支持播放过程中,实时静音/取消静音;
  • [实时快照]支持播放过程中截取当前播放画面;
  • [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
  • [渲染镜像]支持水平反转、垂直反转模式设置;
  • [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
  • [解码前视频数据回调]支持H.264/H.265数据回调;
  • [解码后视频数据回调]支持解码后YUV/RGB数据回调;
  • [解码前音频数据回调]支持AAC/PCMA/PCMU/SPEEX数据回调;
  • [音视频自适应]支持播放过程中,音视频信息改变后自适应;
  • [扩展录像功能]完美支持和录像SDK组合使用(支持RTSP H.265流录制,支持PCMA/PCMU转AAC后录制,支持设置只录制音频或视频)

Android和iOS手机上RTSP/RTMP播放效果:

1. 视频播放效果:

http://www.iqiyi.com/w_19s8dv6yht.html

2. 界面截图:

image

上接口:

//
//  smartplayer.dart
//  smartplayer
//
//  GitHub: https://github.com/daniulive/SmarterStreaming
//  website: https://www.daniulive.com
//
//  Created by daniulive on 2019/02/25.
//  Copyright © 2014~2019 daniulive. All rights reserved.
//

import 'dart:async';
import 'dart:convert';

import 'package:flutter/services.dart';

class EVENTID {
  static const EVENT_DANIULIVE_COMMON_SDK = 0x00000000;
  static const EVENT_DANIULIVE_PLAYER_SDK = 0x01000000;
  static const EVENT_DANIULIVE_PUBLISHER_SDK = 0x02000000;

  static const EVENT_DANIULIVE_ERC_PLAYER_STARTED =
      EVENT_DANIULIVE_PLAYER_SDK | 0x1;
  static const EVENT_DANIULIVE_ERC_PLAYER_CONNECTING =
      EVENT_DANIULIVE_PLAYER_SDK | 0x2;
  static const EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED =
      EVENT_DANIULIVE_PLAYER_SDK | 0x3;
  static const EVENT_DANIULIVE_ERC_PLAYER_CONNECTED =
      EVENT_DANIULIVE_PLAYER_SDK | 0x4;
  static const EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED =
      EVENT_DANIULIVE_PLAYER_SDK | 0x5;
  static const EVENT_DANIULIVE_ERC_PLAYER_STOP =
      EVENT_DANIULIVE_PLAYER_SDK | 0x6;
  static const EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO =
      EVENT_DANIULIVE_PLAYER_SDK | 0x7;
  static const EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED =
      EVENT_DANIULIVE_PLAYER_SDK | 0x8;
  static const EVENT_DANIULIVE_ERC_PLAYER_SWITCH_URL =
      EVENT_DANIULIVE_PLAYER_SDK | 0x9;
  static const EVENT_DANIULIVE_ERC_PLAYER_CAPTURE_IMAGE =
      EVENT_DANIULIVE_PLAYER_SDK | 0xA;

  static const EVENT_DANIULIVE_ERC_PLAYER_RECORDER_START_NEW_FILE =
      EVENT_DANIULIVE_PLAYER_SDK | 0x21; /*录像写入新文件*/
  static const EVENT_DANIULIVE_ERC_PLAYER_ONE_RECORDER_FILE_FINISHED =
      EVENT_DANIULIVE_PLAYER_SDK | 0x22; /*一个录像文件完成*/

  static const EVENT_DANIULIVE_ERC_PLAYER_START_BUFFERING =
      EVENT_DANIULIVE_PLAYER_SDK | 0x81;
  static const EVENT_DANIULIVE_ERC_PLAYER_BUFFERING =
      EVENT_DANIULIVE_PLAYER_SDK | 0x82;
  static const EVENT_DANIULIVE_ERC_PLAYER_STOP_BUFFERING =
      EVENT_DANIULIVE_PLAYER_SDK | 0x83;

  static const EVENT_DANIULIVE_ERC_PLAYER_DOWNLOAD_SPEED =
      EVENT_DANIULIVE_PLAYER_SDK | 0x91;
}

typedef SmartEventCallback = void Function(int, String, String, String);

class SmartPlayerController {
  MethodChannel _channel;
  EventChannel _eventChannel;
  SmartEventCallback _eventCallback;

  void init(int id) {
    _channel = MethodChannel('smartplayer_plugin_$id');
    _eventChannel = EventChannel('smartplayer_event_$id');
    _eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
  }

  void setEventCallback(SmartEventCallback callback) {
    _eventCallback = callback;
  }

  void _onEvent(Object event) {
    if (event != null) {
      Map valueMap = json.decode(event);
      String param = valueMap['param'];
      onSmartEvent(param);
    }
  }

  void _onError(Object error) {
    // print('error:'+ error);
  }

  Future<dynamic> _smartPlayerCall(String funcName) async {
    var ret = await _channel.invokeMethod(funcName);
    return ret;
  }

  Future<dynamic> _smartPlayerCallInt(String funcName, int param) async {
    var ret = await _channel.invokeMethod(funcName, {
      'intParam': param,
    });
    return ret;
  }

  Future<dynamic> _smartPlayerCallIntInt(
      String funcName, int param1, int param2) async {
    var ret = await _channel.invokeMethod(funcName, {
      'intParam': param1,
      'intParam2': param2,
    });
    return ret;
  }

  Future<dynamic> _smartPlayerCallString(String funcName, String param) async {
    var ret = await _channel.invokeMethod(funcName, {
      'strParam': param,
    });
    return ret;
  }

  /// 设置解码方式 false 软解码 true 硬解码 默认为false
  /// </summary>
  /// <param name="isHwDecoder"></param>
  Future<dynamic> setVideoDecoderMode(int isHwDecoder) async {
    return _smartPlayerCallInt('setVideoDecoderMode', isHwDecoder);
  }

  /// <summary>
  /// 设置音频输出模式: if 0: 自动选择; if with 1: audiotrack模式, 此接口仅限于Android平台使用
  /// </summary>
  /// <param name="use_audiotrack"></param>
  Future<dynamic> setAudioOutputType(int useAudiotrack) async {
    return _smartPlayerCallInt('setAudioOutputType', useAudiotrack);
  }

  /// <summary>
  /// 设置播放端缓存大小, 默认200毫秒
  /// </summary>
  /// <param name="buffer"></param>
  Future<dynamic> setBuffer(int buffer) async {
    return _smartPlayerCallInt('setBuffer', buffer);
  }

  /// <summary>
  /// 接口可实时调用:设置是否实时静音,1:静音; 0: 取消静音
  /// </summary>
  /// <param name="is_mute"></param>
  Future<dynamic> setMute(int isMute) async {
    return _smartPlayerCallInt('setMute', isMute);
  }

  /// <summary>
  /// 设置RTSP TCP模式, 1: TCP; 0: UDP
  /// </summary>
  /// <param name="is_using_tcp"></param>
  Future<dynamic> setRTSPTcpMode(int isUsingTcp) async {
    return _smartPlayerCallInt('setRTSPTcpMode', isUsingTcp);
  }

  /// <summary>
  /// 设置RTSP超时时间, timeout单位为秒,必须大于0
  /// </summary>
  /// <param name="timeout"></param>
  Future<dynamic> setRTSPTimeout(int timeout) async {
    return _smartPlayerCallInt('setRTSPTimeout', timeout);
  }

  /// <summary>
  /// 设置RTSP TCP/UDP自动切换
  /// 对于RTSP来说,有些可能支持rtp over udp方式,有些可能支持使用rtp over tcp方式.
  /// 为了方便使用,有些场景下可以开启自动尝试切换开关, 打开后如果udp无法播放,sdk会自动尝试tcp, 如果tcp方式播放不了,sdk会自动尝试udp.
  /// </summary>
  /// <param name="is_auto_switch_tcp_udp"></param>
  Future<dynamic> setRTSPAutoSwitchTcpUdp(int is_auto_switch_tcp_udp) async {
    return _smartPlayerCallInt('setRTSPAutoSwitchTcpUdp', is_auto_switch_tcp_udp);
  }

  /// <summary>
  /// 设置快速启动该模式,
  /// </summary>
  /// <param name="is_fast_startup"></param>
  Future<dynamic> setFastStartup(int isFastStartup) async {
    return _smartPlayerCallInt('setFastStartup', isFastStartup);
  }

  /// <summary>
  /// 设置超低延迟模式 false不开启 true开启 默认false
  /// </summary>
  /// <param name="mode"></param>
  Future<dynamic> setPlayerLowLatencyMode(int mode) async {
    return _smartPlayerCallInt('setPlayerLowLatencyMode', mode);
  }

  /// <summary>
  /// 设置视频垂直反转
  /// </summary>
  /// <param name="is_flip"></param>
  Future<dynamic> setFlipVertical(int is_flip) async {
    return _smartPlayerCallInt('setFlipVertical', is_flip);
  }

  /// <summary>
  /// 设置视频水平反转
  /// </summary>
  /// <param name="is_flip"></param>
  Future<dynamic> setFlipHorizontal(int is_flip) async {
    return _smartPlayerCallInt('setFlipHorizontal', is_flip);
  }

  /// <summary>
  /// 设置顺时针旋转, 注意除了0度之外, 其他角度都会额外消耗性能
  /// degress: 当前支持 0度,90度, 180度, 270度 旋转
  /// </summary>
  /// <param name="degress"></param>
  Future<dynamic> setRotation(int degress) async {
    return _smartPlayerCallInt('setRotation', degress);
  }

  /// <summary>
  /// 设置是否回调下载速度
  /// is_report: if 1: 上报下载速度, 0: 不上报.
  /// report_interval: 上报间隔,以秒为单位,>0.
  /// </summary>
  /// <param name="is_report"></param>
  /// <param name="report_interval"></param>
  Future<dynamic> setReportDownloadSpeed(
      int isReport, int reportInterval) async {
    return _smartPlayerCallIntInt(
        'setReportDownloadSpeed', isReport, reportInterval);
  }

  /// <summary>
  /// Set playback orientation(设置播放方向),此接口仅适用于Android平台
  /// </summary>
  /// <param name="surOrg"></param>
  /// surOrg: current orientation,  PORTRAIT 1, LANDSCAPE with 2
  Future<dynamic> setOrientation(int surOrg) async {
    return _smartPlayerCallInt('setOrientation', surOrg);
  }

  /// <summary>
  /// 设置是否需要在播放或录像过程中快照
  /// </summary>
  /// <param name="is_save_image"></param>
  Future<dynamic> setSaveImageFlag(int isSaveImage) async {
    return _smartPlayerCallInt('setSaveImageFlag', isSaveImage);
  }

  /// <summary>
  /// 播放或录像过程中快照
  /// </summary>
  /// <param name="imageName"></param>
  Future<dynamic> saveCurImage(String imageName) async {
    return _smartPlayerCallString('saveCurImage', imageName);
  }

  /// <summary>
  /// 播放或录像过程中,快速切换url
  /// </summary>
  /// <param name="uri"></param>
  Future<dynamic> switchPlaybackUrl(String uri) async {
    return _smartPlayerCallString('switchPlaybackUrl', uri);
  }

  /// <summary>
  /// 创建录像存储路径
  /// </summary>
  /// <param name="path"></param>
  Future<dynamic> createFileDirectory(String path) async {
    return _smartPlayerCallString('createFileDirectory', path);
  }

  /// <summary>
  /// 设置录像存储路径
  /// </summary>
  /// <param name="path"></param>
  Future<dynamic> setRecorderDirectory(String path) async {
    return _smartPlayerCallString('setRecorderDirectory', path);
  }

  /// <summary>
  /// 设置单个录像文件大小
  /// </summary>
  /// <param name="size"></param>
  Future<dynamic> setRecorderFileMaxSize(int size) async {
    return _smartPlayerCallInt('setRecorderFileMaxSize', size);
  }

  /// <summary>
  /// 设置录像时音频转AAC编码的开关
  /// aac比较通用,sdk增加其他音频编码(比如speex, pcmu, pcma等)转aac的功能.
  /// </summary>
  /// <param name="is_transcode"></param>
  /// is_transcode: 设置为1的话,如果音频编码不是aac,则转成aac,如果是aac,则不做转换. 设置为0的话,则不做任何转换. 默认是0.
  Future<dynamic> setRecorderAudioTranscodeAAC(int is_transcode) async {
    return _smartPlayerCallInt('setRecorderAudioTranscodeAAC', is_transcode);
  }

  /// <summary>
  /// 设置播放路径
  /// </summary>
  Future<dynamic> setUrl(String url) async {
    return _smartPlayerCallString('setUrl', url);
  }

  /// <summary>
  /// 开始播放
  /// </summary>
  Future<dynamic> startPlay() async {
    return _smartPlayerCall('startPlay');
  }

  /// <summary>
  /// 停止播放
  /// </summary>
  Future<dynamic> stopPlay() async {
    return _smartPlayerCall('stopPlay');
  }

  /// <summary>
  /// 开始录像
  /// </summary>
  Future<dynamic> startRecorder() async {
    return _smartPlayerCall('startRecorder');
  }

  /// <summary>
  /// 停止录像
  /// </summary>
  Future<dynamic> stopRecorder() async {
    return _smartPlayerCall('stopRecorder');
  }

  /// <summary>
  /// 关闭播放
  /// </summary>
  Future<dynamic> dispose() async {
    return await _channel.invokeMethod('dispose');
  }

  void onSmartEvent(String param) {
    if (!param.contains(",")) {
      print("[onNTSmartEvent] android传递参数错误");
      return;
    }

    List<String> strs = param.split(',');

    String code = strs[1];
    String param1 = strs[2];
    String param2 = strs[3];
    String param3 = strs[4];
    String param4 = strs[5];

    int evCode = int.parse(code);

    var p1, p2, p3;
    switch (evCode) {
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
        print("开始。。");
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
        print("连接中。。");
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
        print("连接失败。。");
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
        print("连接成功。。");
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
        print("连接断开。。");
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
        print("停止播放。。");
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
        print("分辨率信息: width: " + param1 + ", height: " + param2);
        p1 = param1;
        p2 = param2;
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
        print("收不到媒体数据,可能是url错误。。");
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_SWITCH_URL:
        print("切换播放URL。。");
        break;

      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CAPTURE_IMAGE:
        print("快照: " + param1 + " 路径:" + param3);

        if (int.parse(param1) == 0) {
           print("截取快照成功。.");
        } else {
           print("截取快照失败。.");
        }
        p1 = param1;
        p2 = param3;
        break;

      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RECORDER_START_NEW_FILE:
        print("[record]开始一个新的录像文件 : " + param3);
        p3 = param3;
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_ONE_RECORDER_FILE_FINISHED:
        print("[record]已生成一个录像文件 : " + param3);
        p3 = param3;
        break;

      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_START_BUFFERING:
        print("Start_Buffering");
        break;

      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_BUFFERING:
        print("Buffering: " + param1 + "%");
        p1 = param1;
        break;

      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP_BUFFERING:
        print("Stop_Buffering");
        break;

      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DOWNLOAD_SPEED:
         print("download_speed:" + (double.parse(param1) * 8 / 1000).toStringAsFixed(0) + "kbps" + ", " + (double.parse(param1) / 1024).toStringAsFixed(0) + "KB/s");
        p1 = param1;
        break;
    }
    if (_eventCallback != null) {
      _eventCallback(evCode, p1, p2, p3);
    }
  }
}

image.gif

调用实例:

//
//  main.dart
//  main
//
//  GitHub: https://github.com/daniulive/SmarterStreaming
//  website: https://www.daniulive.com
//
//  Created by daniulive on 2019/02/25.
//  Copyright © 2014~2019 daniulive. All rights reserved.
//

import 'dart:io';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:smartplayer_native_view/smartplayer.dart';
import 'package:smartplayer_native_view/smartplayer_plugin.dart';

void main() {
  ///
  /// 强制竖屏
  ///
  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);

  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  SmartPlayerController player;
  double aspectRatio = 4.0 / 3.0;

  //输入需要播放的RTMP/RTSP url
  TextEditingController playback_url_controller_ = TextEditingController();

  //Event事件回调显示
  TextEditingController event_controller_ = TextEditingController();

  bool is_playing_ = false;
  bool is_mute_ = false;

  var rotate_degrees_ = 0;

  Widget smartPlayerView() {
      return SmartPlayerWidget(
        onSmartPlayerCreated: onSmartPlayerCreated,
      );
    }

  @override
  void initState() {
     print("initState called..");
    super.initState();
  }

  @override
  void didChangeDependencies() {
    print('didChangeDependencies called..');
    super.didChangeDependencies();
  }

  @override
  void deactivate() {
    print('deactivate called..');
    super.deactivate();
  }

  @override
  void dispose() {
    print("dispose called..");
    player.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Flutter SmartPlayer Demo'),
          ),
          body: new SingleChildScrollView(
            child: new Column(
              children: <Widget>[
                new Container(
                  color: Colors.black,
                  child: AspectRatio(
                    child: smartPlayerView(),
                    aspectRatio: aspectRatio,
                  ),
                ),
                new TextField(
                  controller: playback_url_controller_,
                  keyboardType: TextInputType.text,
                  decoration: InputDecoration(
                    contentPadding: EdgeInsets.all(10.0),
                    icon: Icon(Icons.link),
                    labelText: '请输入RTSP/RTMP url',
                  ),
                  autofocus: false,
                ),
                new Row(
                  children: [
                    new RaisedButton(
                        onPressed: this.onSmartPlayerStartPlay,
                        child: new Text("开始播放")),
                    new Container(width: 20),
                    new RaisedButton(
                        onPressed: this.onSmartPlayerStopPlay,
                        child: new Text("停止播放")),
                    new Container(width: 20),
                    new RaisedButton(
                        onPressed: this.onSmartPlayerMute,
                        child: new Text("实时静音")),
                  ],
                ),
                new Row(
                  children: [
                    new RaisedButton(
                        onPressed: this.onSmartPlayerSwitchUrl,
                        child: new Text("实时切换URL")),
                    new Container(width: 20),
                    new RaisedButton(
                        onPressed: this.onSmartPlayerSetRotation,
                        child: new Text("实时旋转View")),
                  ],
                ),
                new TextField(
                  controller: event_controller_,
                  keyboardType: TextInputType.text,
                  decoration: InputDecoration(
                    contentPadding: EdgeInsets.all(10.0),
                    icon: Icon(Icons.event_note),
                    labelText: 'Event状态回调',
                  ),
                  autofocus: false,
                ),
              ],
            ),
          )),
    );
  }

  void _eventCallback(int code, String param1, String param2, String param3) {
    String event_str;

    switch (code) {
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
        event_str = "开始..";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
        event_str = "连接中..";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
        event_str = "连接失败..";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
        event_str = "连接成功..";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
        event_str = "连接断开..";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
        event_str = "停止播放..";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
        event_str = "分辨率信息: width: " + param1 + ", height: " + param2;
        setState(() {
          aspectRatio = double.parse(param1) / double.parse(param2);
          print('change aspectRatio:$aspectRatio');
        });
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
        event_str = "收不到媒体数据,可能是url错误..";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_SWITCH_URL:
        event_str = "切换播放URL..";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CAPTURE_IMAGE:
        event_str = "快照: " + param1 + " 路径: " + param3;

        if (int.parse(param1) == 0) {
          print("截取快照成功。.");
        } else {
          print("截取快照失败。.");
        }
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RECORDER_START_NEW_FILE:
        event_str = "[record] new file: " + param3;
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_ONE_RECORDER_FILE_FINISHED:
        event_str = "[record] record finished: " + param3;
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_START_BUFFERING:
        //event_str = "Start Buffering";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_BUFFERING:
        event_str = "Buffering: " + param1 + "%";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP_BUFFERING:
        //event_str = "Stop Buffering";
        break;
      case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DOWNLOAD_SPEED:
        event_str = "download_speed:" +
            (double.parse(param1) * 8 / 1000).toStringAsFixed(0) +
            "kbps" +
            ", " +
            (double.parse(param1) / 1024).toStringAsFixed(0) +
            "KB/s";
        break;
    }

    event_controller_.text = event_str;
  }

  void onSmartPlayerCreated(SmartPlayerController controller) async {
    player = controller;
    player.setEventCallback(_eventCallback);

    var ret = -1;

    //设置video decoder模式
    var is_video_hw_decoder = 0;
    if (defaultTargetPlatform == TargetPlatform.android)
    {
      ret = await player.setVideoDecoderMode(is_video_hw_decoder);
    }
    else if(defaultTargetPlatform == TargetPlatform.iOS)
    {
      is_video_hw_decoder = 1;
      ret = await player.setVideoDecoderMode(is_video_hw_decoder);
    }

    //设置缓冲时间
    var play_buffer = 100;
    ret = await player.setBuffer(play_buffer);

    //设置快速启动
    var is_fast_startup = 1;
    ret = await player.setFastStartup(is_fast_startup);

    //是否开启低延迟模式
    var is_low_latency_mode = 0;
    ret = await player.setPlayerLowLatencyMode(is_low_latency_mode);

    //set report download speed(默认5秒一次回调 用户可自行调整report间隔)
    ret = await player.setReportDownloadSpeed(1, 2);

    //设置RTSP超时时间
        var rtsp_timeout = 10;
      ret = await player.setRTSPTimeout(rtsp_timeout);

    var is_auto_switch_tcp_udp = 1;
        ret = await player.setRTSPAutoSwitchTcpUdp(is_auto_switch_tcp_udp);

    // 设置RTSP TCP模式
        //ret = await player.setRTSPTcpMode(1);

    //第一次启动 为方便测试 设置个初始url
    playback_url_controller_.text = "rtmp://live.hkstv.hk.lxdns.com/live/hks2";
  }

  Future<void> onSmartPlayerStartPlay() async {
    var ret = -1;

    if (playback_url_controller_.text.length < 8) {
      playback_url_controller_.text =
          "rtmp://live.hkstv.hk.lxdns.com/live/hks1"; //给个初始url
    }

    //实时静音设置 
    ret = await player.setMute(is_mute_ ? 1 : 0);

    if (!is_playing_) {
      ret = await player.setUrl(playback_url_controller_.text);
      ret = await player.startPlay();

      if (ret == 0) {
        is_playing_ = true;
      }
    }
  }

  Future<void> onSmartPlayerStopPlay() async {
    if (is_playing_) {
      await player.stopPlay();
      playback_url_controller_.clear();
      is_playing_ = false;
      is_mute_ = false;
    }
  }

  Future<void> onSmartPlayerMute() async {
    if (is_playing_) {
      is_mute_ = !is_mute_;
      await player.setMute(is_mute_ ? 1 : 0);
    }
  }

  Future<void> onSmartPlayerSwitchUrl() async {
    if (is_playing_) {
      if (playback_url_controller_.text.length < 8) {
        playback_url_controller_.text =
            "rtmp://live.hkstv.hk.lxdns.com/live/hks1";
      }

      await player.switchPlaybackUrl(playback_url_controller_.text);
    }
  }

  Future<void> onSmartPlayerSetRotation() async {
    if (is_playing_) {
      rotate_degrees_ += 90;
      rotate_degrees_ = rotate_degrees_ % 360;

      if (0 == rotate_degrees_) {
        print("旋转90度");
      } else if (90 == rotate_degrees_) {
        print("旋转180度");
      } else if (180 == rotate_degrees_) {
        print("旋转270度");
      } else if (270 == rotate_degrees_) {
        print("不旋转");
      }

      await player.setRotation(rotate_degrees_);
    }
  }
}

image.gif

经测试,Flutter环境下,RTMP和RTSP播放,拥有Native SDK一样优异的播放体验。

相关资料:Github: https://github.com/daniulive/SmarterStreaming

QQ群:

Windows/Android/iOS平台实现RTMP推送和播放端AES或SM4加解密实例

1. AES算法和SM4算法扫盲

AES算法

密码学中的高级加密标准(AdvancedEncryptionStandard,AES),又称Rijndael加密算法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPSPUB197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。AES有一个固定的128位的块大小和128,192或256位大小的密钥大小。

该算法为比利时密码学家JoanDaemen和VincentRijmen所设计,结合两位作者的名字,以Rijndael命名之。AES在软件及硬件上都能快速地加解密,相对来说较易于操作,且只需要很少的存储空间。作为一个新的加密标准,目前正被部署应用到更广大的范围。

SM4算法

SM4算法全称为SM4分组密码算法,是国家密码管理局2012年3月发布的第23号公告中公布的密码行业标准。SM4算法是一个分组对称密钥算法,明文、密钥、密文都是16字节,加密和解密密钥相同。加密算法与密钥扩展算法都采用32轮非线性迭代结构。解密过程与加密过程的结构相似,只是轮密钥的使用顺序相反。

SM4算法的优点是软件和硬件实现容易,运算速度快。

2. 接口说明及调用展示

大牛直播SDK发布的跨平台(Windows/Android/iOS平台)的基于AES/SM4音视频逐帧数据加密整体解决方案,第三方即便是破解了URL,也没法播放,通过抓包工具抓取到数据,也没法正常显示。

此方案的难点是需要了解音视频编码相关的细节,才能进行适当的扩展。优点是常用的rtmp server可以直接支持,通用性很强。只需要改推送端和播放端就好。

2.1 Windows平台RTMP推送端

C++接口:

		/*
		设置rtmp推送加密选项
		url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
		is_encrypt_video: 1:表示视频加密, 0:表示视频不加密, 默认不加密, 其他值返回错误
		is_encrypt_audio: 1:表示音频加密, 0:表示音频不加密, 默认不加密, 其他值返回错误
		成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetRtmpEncryptionOption)(NT_HANDLE handle, NT_PCSTR url, NT_INT32 is_encrypt_video, NT_INT32 is_encrypt_audio);


		/*
		设置rtmp加密算法
		url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
		encryption_algorithm: 加密算法, 当前支持aes和国标sm4. 1为aes, 2为sm4, 默认为aes.
		*/
		NT_UINT32(NT_API *SetRtmpEncryptionAlgorithm)(NT_HANDLE handle, NT_PCSTR url, NT_INT32 encryption_algorithm);


		/*
		设置rtmp推送加密密钥
		url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
		key:加密密钥
		key_size: 如果加密算法是aes, key_size必须是16, 24, 32 这三个值, 其他返回错误; 如果加密算法是sm4, key_size必须是16, 其他值返回错误.
		成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetRtmpEncryptionKey)(NT_HANDLE handle, NT_PCSTR url, const NT_BYTE* key, NT_UINT32 key_size);


		/*
		设置rtmp推送加密IV(初始化向量), 这个接口不调用的话, 将使用默认IV
		url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
		iv: 初始化向量
		iv_size: 当前必须是16, 其他值返回错误
		成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetRtmpEncryptionIV)(NT_HANDLE handle, NT_PCSTR url, const NT_BYTE* iv, NT_UINT32 iv_size);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

C#接口:

        /*
         * 设置rtmp推送加密选项
         * url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
         * is_encrypt_video: 1:表示视频加密, 0:表示视频不加密, 默认不加密, 其他值返回错误
         * is_encrypt_audio: 1:表示音频加密, 0:表示音频不加密, 默认不加密, 其他值返回错误
         * 
         * 成功返回 NT_ERC_OK
		 */
        [DllImport(@"SmartPublisherSDK.dll")]
		public static extern UInt32 NT_PB_SetRtmpEncryptionOption(IntPtr handle, [MarshalAs(UnmanagedType.LPStr)]String url, Int32 is_encrypt_video, Int32 is_encrypt_audio);


		/*
         * 设置rtmp加密算法
         * url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
         * encryption_algorithm: 加密算法, 当前支持aes和国标sm4. 1为aes, 2为sm4, 默认为aes.
		 */
        [DllImport(@"SmartPublisherSDK.dll")]
        public static extern UInt32 NT_PB_SetRtmpEncryptionAlgorithm(IntPtr handle, [MarshalAs(UnmanagedType.LPStr)]String url, Int32 encryption_algorithm);


		/*
         * 设置rtmp推送加密密钥
         * url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
         * key:加密密钥
         * key_size: 如果加密算法是aes, key_size必须是16, 24, 32 这三个值, 其他返回错误; 如果加密算法是sm4, key_size必须是16, 其他值返回错误.
         * 成功返回 NT_ERC_OK
		 */
        [DllImport(@"SmartPublisherSDK.dll")]
        public static extern UInt32 NT_PB_SetRtmpEncryptionKey(IntPtr handle, [MarshalAs(UnmanagedType.LPStr)]String url, byte[] key, UInt32 key_size);

		/*
         * 设置rtmp推送加密IV(初始化向量), 这个接口不调用的话, 将使用默认IV
         * url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
         * iv: 初始化向量
         * iv_size: 当前必须是16, 其他值返回错误
         * 成功返回 NT_ERC_OK
		 */
        [DllImport(@"SmartPublisherSDK.dll")]
        public static extern UInt32 NT_PB_SetRtmpEncryptionIV(IntPtr handle, [MarshalAs(UnmanagedType.LPStr)]String url, byte[] iv, UInt32 iv_size);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

C#调用展示:

				//设置RTMP加密(AES/SM4)
                /*
                Int32 is_encrypt_video = 1;
                Int32 is_encrypt_audio = 1;
                NTSmartPublisherSDK.NT_PB_SetRtmpEncryptionOption(publisher_handle_, url, is_encrypt_video, is_encrypt_audio);

                Int32 encryption_algorithm = 1;
                NTSmartPublisherSDK.NT_PB_SetRtmpEncryptionAlgorithm(publisher_handle_, url, encryption_algorithm);

                String key_str = "1234567890123456";

                UInt32 key_size = 16;

                if (key_str.Length <= 16)
                {
                    key_size = 16;
                }
                else if (key_str.Length <= 24)
                {
                    key_size = 24;
                }
                else
                {
                    key_size = 32;
                }

                byte[] key = new byte[key_size];

                if (key_str.Length <= 32)
                {
                    key = System.Text.Encoding.Default.GetBytes(key_str);
                }
                else
                {
                    key = System.Text.Encoding.Default.GetBytes(key_str.Substring(0, 32));
                }
                
                NTSmartPublisherSDK.NT_PB_SetRtmpEncryptionKey(publisher_handle_, url, key, key_size);

                String iv_str = "1234567890123456";

                UInt32 iv_size = 16;

                byte[] iv = new byte[iv_size];

                if (iv_str.Length <= 16)
                {
                    iv = System.Text.Encoding.Default.GetBytes(iv_str);
                }
                else
                {
                    iv = System.Text.Encoding.Default.GetBytes(key_str.Substring(0, 16));
                }

                NTSmartPublisherSDK.NT_PB_SetRtmpEncryptionIV(publisher_handle_, url, iv, iv_size);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2.2 Windows平台RTMP播放端

C++接口:

		/*
		*
		* 设置解密key,目前只用来解密rtmp加密流
		* key: 解密密钥
		* size: 密钥长度
		* 成功返回NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetKey)(NT_HANDLE handle, const NT_BYTE* key, NT_UINT32 size);


		/*
		*
		* 设置解密向量,目前只用来解密rtmp加密流
		* iv:  解密向量
		* size: 向量长度
		* 成功返回NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetDecryptionIV)(NT_HANDLE handle, const NT_BYTE* iv, NT_UINT32 size);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

C#接口:

        /*
         * 设置解密key,目前只用来解密rtmp加密流
		 * key: 解密密钥
		 * size: 密钥长度
		 * 成功返回NT_ERC_OK
		 */
        [DllImport(@"SmartPlayerSDK.dll")]
        public static extern UInt32 NT_SP_SetKey(IntPtr handle, byte[] key, UInt32 size);

		/*
		 * 设置解密向量,目前只用来解密rtmp加密流
		 * iv:  解密向量
		 * size: 向量长度
		 * 成功返回NT_ERC_OK
		 */
        [DllImport(@"SmartPlayerSDK.dll")]
        public static extern UInt32 NT_SP_SetDecryptionIV(IntPtr handle, byte[] iv, UInt32 size);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

调用展示:

            String key_str = "1234567890123456";

            UInt32 key_size = 16;

            if (key_str.Length <= 16)
            {
                key_size = 16;
            }
            else if (key_str.Length <= 24)
            {
                key_size = 24;
            }
            else
            {
                key_size = 32;
            }

            byte[] key = new byte[key_size];

            if (key_str.Length <= 32)
            {
                key = System.Text.Encoding.Default.GetBytes(key_str);
            }
            else
            {
                key = System.Text.Encoding.Default.GetBytes(key_str.Substring(0, 32));
            }

            NTSmartPlayerSDK.NT_SP_SetKey(player_handle_, key, key_size);

            String iv_str = "1234567890123456789012345678901211";

            UInt32 iv_size = 16;

            byte[] iv = new byte[iv_size];

            if (iv_str.Length <= 16)
            {
                iv = System.Text.Encoding.Default.GetBytes(iv_str);
            }
            else
            {
                iv = System.Text.Encoding.Default.GetBytes(key_str.Substring(0, 16));
            }
            
            iv = System.Text.Encoding.Default.GetBytes(iv_str);

            NTSmartPlayerSDK.NT_SP_SetDecryptionIV(player_handle_, iv, iv_size);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2.3 Android平台RTMP推送端

	/**
	 * 设置rtmp推送加密选项
	 *
	 * @param url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
	 * @param is_encrypt_video: 1:表示视频加密, 0:表示视频不加密, 默认不加密, 其他值返回错误
	 * @param is_encrypt_audio: 1:表示音频加密, 0:表示音频不加密, 默认不加密, 其他值返回错误
	 *
	 * @return {0} if successful
	 */
	public native int SetRtmpEncryptionOption(long handle,  String url, int is_encrypt_video, int is_encrypt_audio);

	/**
	 * 设置rtmp加密算法
	 *
	 * @param url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
	 * @param encryption_algorithm: 加密算法, 当前支持aes和国标sm4. 1为aes, 2为sm4, 默认为aes.
	 *
	 * @return {0} if successful
	 */
	public native int SetRtmpEncryptionAlgorithm(long handle,  String url, int encryption_algorithm);

	/**
	 * 设置rtmp推送加密密钥
	 *
	 * @param url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
	 * @param key:加密密钥
	 * @param key_size: 当前key_size必须是16, 24, 32 这三个值,其他返回错误
	 *
	 * @return {0} if successful
	 */
	public native int SetRtmpEncryptionKey(long handle, String url, byte[] key, int key_size);

	/**
	 * 设置rtmp推送加密IV(初始化向量), 这个接口不调用的话, 将使用默认IV
	 *
	 * @param url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
	 * @param iv:初始化向量
	 * @param iv_size: 当前必须是16, 其他值返回错误
	 *
	 * @return {0} if successful
	 */
	public native int SetRtmpEncryptionIV(long handle, String url, byte[] iv, int iv_size);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

调用展示:

if(encrypt_key != null && !encrypt_key.isEmpty()) {
                Log.i(TAG, "encrypt_key:" + encrypt_key);

                int is_encrypt_video = 1;
                int is_encrypt_audio = 1;

                if (pushType == 1)
                {
                    is_encrypt_video = 0;
                }
                else if (pushType == 2)
                {
                    is_encrypt_audio = 0;
                }

                libPublisher.SetRtmpEncryptionOption(publisherHandle, publishURL, is_encrypt_video, is_encrypt_audio);

                //加密算法可自行设置
                int encryption_algorithm = 1;
                libPublisher.SetRtmpEncryptionAlgorithm(publisherHandle, publishURL, encryption_algorithm);

                int key_len = 16;

                if (encrypt_key.length() > 16 && encrypt_key.length() <= 24) {
                    key_len = 24;
                } else if (encrypt_key.length() > 24) {
                    key_len = 32;
                }

                byte[] key = new byte[key_len];

                for (int i = 0; i < key_len; i++) {
                    key[i] = 0;
                }

                try {
                    byte[] key_utf8 = encrypt_key.getBytes("UTF-8");

                    int copy_len = key_utf8.length < key_len ? key_utf8.length : key_len;

                    for (int i = 0; i < copy_len; ++i) {
                        key[i] = key_utf8[i];
                    }

                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                int ret = libPublisher.SetRtmpEncryptionKey(publisherHandle, publishURL, key, key.length);

                if(ret != 0)
                {
                    Log.e(TAG, "Call SmartPublisherSetRtmpEncryptionKey failed, errorID: " + ret);
                }
            }

            if(encrypt_iv != null && !encrypt_iv.isEmpty()) {
                int iv_len = 16;

                byte[] iv = new byte[iv_len];

                for (int i = 0; i < iv_len; i++) {
                    iv[i] = 0;
                }

                try {
                    byte[] iv_utf8 = encrypt_iv.getBytes("UTF-8");

                    int copy_len = iv_utf8.length < iv_len ? iv_utf8.length : iv_len;

                    for (int i = 0; i < copy_len; ++i) {
                        iv[i] = iv_utf8[i];
                    }

                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                int ret = libPublisher.SetRtmpEncryptionIV(publisherHandle, publishURL, iv, iv.length);

                if(ret != 0)
                {
                    Log.e(TAG, "Call SetRtmpEncryptionIV failed, errorID: " + ret);
                }
            }

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2.4 Android平台RTMP播放端

	/**
	 * 设置解密key,目前只用来解密rtmp加密流
	 *
	 * @param handle: return value from SmartPlayerOpen()
	 *
	 * @param key:解密密钥
	 *
	 * @param size:密钥长度
	 *
	 * @return {0} if successful
	 */
	public native int SmartPlayerSetKey(long handle, byte[] key, int size);

	/**
	 * 设置解密向量,目前只用来解密rtmp加密流
	 *
	 * @param handle: return value from SmartPlayerOpen()
	 *
	 * @param iv:解密向量
	 *
	 * @param size:向量长度
	 *
	 * @return {0} if successful
	 */
	public native int SmartPlayerSetDecryptionIV(long handle, byte[] iv, int size);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

调用展示:

        if (encrypt_key != null && !encrypt_key.isEmpty()) {
            Log.i(TAG, "encrypt_key:" + encrypt_key);

            int key_len = 16;

            if (encrypt_key.length() > 16 && encrypt_key.length() <= 24) {
                key_len = 24;
            } else if (encrypt_key.length() > 24) {
                key_len = 32;
            }

            byte[] key = new byte[key_len];

            for (int i = 0; i < key_len; i++) {
                key[i] = 0;
            }

            try {
                byte[] key_utf8 = encrypt_key.getBytes("UTF-8");

                int copy_key_len = key_utf8.length < key_len ? key_utf8.length : key_len;

                for (int i = 0; i < copy_key_len; ++i) {
                    key[i] = key_utf8[i];
                }

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            libPlayer.SmartPlayerSetKey(playerHandle, key, key.length);

            if (encrypt_iv != null && !encrypt_iv.isEmpty()) {
                Log.i(TAG, "encrypt_iv:" + encrypt_iv);

                int iv_len = 16;
                byte[] iv = new byte[iv_len];

                for (int i = 0; i < iv_len; i++) {
                    iv[i] = 0;
                }

                try {
                    byte[] iv_utf8 = encrypt_iv.getBytes("UTF-8");

                    int copy_iv_len = iv_utf8.length < key_len ? iv_utf8.length : key_len;

                    for (int i = 0; i < copy_iv_len; ++i) {
                        iv[i] = iv_utf8[i];
                    }

                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                libPlayer.SmartPlayerSetDecryptionIV(playerHandle, iv, iv.length);
            }
        }

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2.5 iOS平台RTMP推送端

/**
 * 设置rtmp推送加密选项
 *
 * @param url 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
 * @param is_encrypt_video 1:表示视频加密, 0:表示视频不加密, 默认不加密, 其他值返回错误
 * @param is_encrypt_audio 1:表示音频加密, 0:表示音频不加密, 默认不加密, 其他值返回错误
 *
 * @return {0} if successful
 */
-(NSInteger)SetRtmpEncryptionOption:(NSString*)url is_encrypt_video:(NSInteger)is_encrypt_video is_encrypt_audio:(NSInteger)is_encrypt_audio;

/**
 * 设置rtmp加密算法
 *
 * @param url 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
 * @param encryption_algorithm 加密算法, 当前支持aes和国标sm4. 1为aes, 2为sm4, 默认为aes.
 *
 * @return {0} if successful
 */
-(NSInteger)SetRtmpEncryptionAlgorithm:(NSString*)url encryption_algorithm:(NSInteger)encryption_algorithm;

/**
 * 设置rtmp推送加密密钥
 *
 * @param url 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
 * @param key 加密密钥
 * @param key_size 当前key_size必须是16, 24, 32 这三个值,其他返回错误
 *
 * @return {0} if successful
 */
-(NSInteger)SetRtmpEncryptionKey:(NSString*)url key:(unsigned char*)key key_size:(NSInteger)key_size;

/**
 * 设置rtmp推送加密IV(初始化向量), 这个接口不调用的话, 将使用默认IV
 *
 * @param url 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致
 * @param iv 初始化向量
 * @param iv_size 当前必须是16, 其他值返回错误
 *
 * @return {0} if successful
 */
-(NSInteger)SetRtmpEncryptionIV:(NSString*)url iv:(unsigned char*)iv iv_size:(NSInteger)iv_size;

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

调用展示:

    NSInteger key_length = [encrypt_key_ length];
    
    if(key_length > 0)
    {
        NSInteger is_encrypt_video = 1;
        NSInteger is_encrypt_audio = 1;
        
        if(video_opt_ == 0)
        {
            is_encrypt_video = 0;
        }
        
        if(audio_opt_ == 0)
        {
            is_encrypt_audio = 0;
        }
        
        [_smart_publisher_sdk SetRtmpEncryptionOption:rtmp_push_url is_encrypt_video:is_encrypt_video is_encrypt_audio:is_encrypt_audio];
        
        //默认AES加密,如需SM4加密,参数设置2即可
        NSInteger encryption_algorithm = 1;
        [_smart_publisher_sdk SetRtmpEncryptionAlgorithm:rtmp_push_url encryption_algorithm:encryption_algorithm];
        
        int key_len = 16;
        
        if (key_length > 16 && key_length <= 24) {
            key_len = 24;
        } else if (key_length > 24) {
            key_len = 32;
        }
        
        unsigned char key[32];
        memset(key, 0, 32);
        
        NSData* key_data = [encrypt_key_ dataUsingEncoding:NSUTF8StringEncoding];
        
        NSInteger copy_key_len = key_length < key_len ? key_length : key_len;
        
        Byte *copy_key_data = (Byte *)[key_data bytes];
        
        for(int i=0;i<copy_key_len;i++)
        {
            key[i] = copy_key_data[i];
        }
            
        [_smart_publisher_sdk SetRtmpEncryptionKey:rtmp_push_url key:key key_size:key_len];
        
        NSInteger iv_length = [encrypt_iv_ length];
        
        if(iv_length > 0)
        {
            int iv_len = 16;
            
            unsigned char iv[16];
            memset(iv, 0, 16);
            
            NSData* iv_data = [encrypt_iv_ dataUsingEncoding:NSUTF8StringEncoding];
            
            NSInteger copy_iv_len = iv_length < iv_len ? iv_length : iv_len;
            
            Byte *copy_iv_data = (Byte *)[iv_data bytes];
            
            for(int i=0;i<copy_iv_len;i++)
            {
                iv[i] = copy_iv_data[i];
            }
            
            [_smart_publisher_sdk SetRtmpEncryptionIV:rtmp_push_url iv:iv iv_size:iv_len];
        }

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2.6 iOS平台RTMP播放端

/**
 * 设置解密key,目前只用来解密rtmp加密流
 *
 * @param key 解密密钥
 *
 * @param key_size 密钥长度
 *
 * @return {0} if successful
 */
- (NSInteger)SmartPlayerSetKey:(unsigned char*)key key_size:(NSInteger)key_size;

/**
 * 设置解密向量,目前只用来解密rtmp加密流
 *
 * @param iv 解密向量
 *
 * @param iv_size 向量长度
 *
 * @return {0} if successful
 */
- (NSInteger)SmartPlayerSetDecryptionIV:(unsigned char*)iv iv_size:(NSInteger)iv_size;

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

调用展示:

    NSInteger key_length = [encrypt_key_ length];
    
    if(key_length > 0)
    {
        int key_len = 16;
        
        if (key_length > 16 && key_length <= 24) {
            key_len = 24;
        } else if (key_length > 24) {
            key_len = 32;
        }
        
        unsigned char key[32];
        memset(key, 0, 32);
        
        NSData* key_data = [encrypt_key_ dataUsingEncoding:NSUTF8StringEncoding];
  
        NSInteger copy_key_len = key_length < key_len ? key_length : key_len;
        
        Byte *copy_key_data = (Byte *)[key_data bytes];
        
        for(int i=0;i<copy_key_len;i++)
        {
            key[i] = copy_key_data[i];
        }
        
        [_smart_player_sdk SmartPlayerSetKey:key key_size:key_len];
    }
    
    NSInteger iv_length = [encrypt_iv_ length];
    
    if(iv_length > 0)
    {
        int iv_len = 16;
        
        unsigned char iv[16];
        memset(iv, 0, 16);
        
        NSData* iv_data = [encrypt_iv_ dataUsingEncoding:NSUTF8StringEncoding];
        
        NSInteger copy_iv_len = iv_length < iv_len ? iv_length : iv_len;
        
        Byte *copy_iv_data = (Byte *)[iv_data bytes];
        
        for(int i=0;i<copy_iv_len;i++)
        {
            iv[i] = copy_iv_data[i];
        }
        
        [_smart_player_sdk SmartPlayerSetDecryptionIV:iv iv_size:iv_len];
    }

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

3.注意事项

1. RTMP推送端什么时候调用加密接口?

回答:SetUrl之后,开始推送之前;

2. RTMP播放端,什么时候设置Key和IV解密向量?

回答:可以实现自动检测,如检测到推送的RTMP流系AES或SM4加密,会回调上来NT_SP_E_EVENT_ID_NEED_KEY事件,弹出输入Key和IV框,如输入的Key和IV不正确,播放端会收到NT_SP_E_EVENT_ID_KEY_ERROR事件

 NT_SP_E_EVENT_ID_NEED_KEY               = NT_SP_E_EVENT_ID_BASE | 0xC,  /*需要输入解密key才能播放*/
 NT_SP_E_EVENT_ID_KEY_ERROR              = NT_SP_E_EVENT_ID_BASE | 0xD,  /*解密key不正确*/

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

3. 设置加解密Key和IV,有什么注意事项?

回答:key_size: 如果加密算法是aes, key_size必须是16, 24, 32 这三个值, 其他返回错误; 如果加密算法是sm4, key_size必须是16, 其他值返回错误;iv_size: 当前必须是16, 其他值返回错误。

相关资料:Github: https://github.com/daniulive/SmarterStreaming

5张图看懂如何实现Windows RTMP实时导播功能

一直以来,好多开发者苦于如何实现RTMP导播数据源实时切换,以下是大牛直播SDK导播切换说明,支持只切换数据源模式,或音视频混音合成输出模式:

数据源:

1. rtmp/rtsp音视频流;

2. 本地屏幕/摄像头/音频数据;

3.本地flv文件。

输出:

1. 多路流合成一路流后,推送到RTMP服务器;

2. 多路合成后的流,支持本地录像、快照。

使用说明:

无视频合成/音频混音模式:

1. 打开SmartStreamRelayDemo.exe,输入一路RTMP或RTSP流,在拉流地址输入需要转推的RTMP的url,如“rtmp://player.daniulive.com:1935/hls/stream666”,先点击“拉流”,再点击“推流”按钮,如需本地预览,可以点击“预览”按钮。

打开SmartPlayer.exe,输入刚刚设置的RTMP url:rtmp://player.daniulive.com:1935/hls/stream666,点击“播放”即可。

如下图所示:

2. 切换一路RTMP数据源,输入新的RTMP地址,点击“切换拉流地址”即可:

3. 切换一路RTSP数据源,输入新的RTSP地址,点击“切换拉流地址”即可:

视频合成/音频混音模式:

1. 合流界面:

2. 播放输出界面:

细心的你会发现,三路流分辨率和协议封装不同,不过依然可自动切换,从而实现播放端观众无感知的导播体验。

技术优势:

1. 以SDK形式输出,企业或开发者可根据需求完成多样化的产品需求;

2. 行业内接口更灵活,资源占用更低;

3. 超低延迟输出,效率更高;

4. 支持合流后的图像预览;

5. 支持合流后的音频混音;

6. 支持导播过程中,随时切断某一路音视频或音频;

7. 岂止是合流,还可以实时录像、快照等,接口更丰富。

相关资料和测试程序下载:

Github: https://github.com/daniulive/SmarterStreaming

官网:https://www.daniulive.com

如何在IE浏览器播放RTSP或RTMP流(RTSP/RTMP OCX播放控件)

好多开发者一直苦恼于如何在IE浏览器环境下,构建低延迟的RTSP或RTMP播放,对于RTSP流来说,好多公司通常的做法是把RTSP转RTMP,然后分发到RTMP服务器,然后服务器转http-flv出来,浏览器直接播放http-flv流,亦或通过flash控件直接播放RTMP流,还有就是,转hls流出来,缺点是hls流延迟更大。

以上方案未尝不可,如果对播放体验和延迟要求更高,最简单的做法是直接在IE浏览器下加载activex控件。

大牛直播SDK在现有SDK的基础上,扩展了ocx控件,用于IE浏览器下的低延迟RTMP或RTSP播放,不谦虚的说,也可能是行业内功能支持和延迟最好的RTMP和RTSP播放器(支持RTMP/RTSP H.265(hevc)播放)。

页面展示

1. 功能齐全的单画面RTMP流或RTSP流播放:

2. 同时播放4路RTMP流或RTSP流画面:

本地播放和集成说明:

点我下载DEMO

本地播放

DEMO说明

  1. 1_player_ocx.html:单个窗口功能展示。
  2. 4_player_ocx.html:4窗口功能展示。
  3. SmartPlayer.exe:cs架构播放器。

运行网页播放端之前,请确保以管理员权限注册ocx控件:regplayerocx.bat右键–>“以管理员身份运行(A)”,同理,反注册也是需要管理员身份。

注意:大牛直播RTSP/RTMP播放OCX控件只适用于微软IE浏览器。

对应封装接口

	ULONG NT_SetLogPath();
	ULONG NT_Open();
	ULONG NT_Close();
	ULONG NT_StartPlay();
	ULONG NT_StopPlay();
	ULONG NT_SetMute(LONG is_mute);
	ULONG NT_SetURL(LPCTSTR url);
	ULONG NT_SetBuffer(LONG buffer);
	ULONG NT_SetRTSPTcpMode(LONG isUsingTCP);
	ULONG NT_SetRtspTimeout(LONG timeout);
	ULONG NT_SetRtspAutoSwitchTcpUdp(LONG is_auto_switch_tcp_udp);
	ULONG NT_SetFastStartup(LONG isFastStartup);
	ULONG NT_SetLowLatencyMode(LONG mode);
	ULONG NT_SetFlipVertical(LONG is_flip);
	ULONG NT_SetFlipHorizontal(LONG is_flip);
	ULONG NT_SetRotation(LONG degress);
	ULONG NT_SwitchURL(LPCTSTR url);
	ULONG NT_SetCaptureImagePath(LPCTSTR path);
	ULONG NT_CaptureImage();
	ULONG NT_SetRecorderDirectory(LPCTSTR dir);
	ULONG NT_SetRecorderFileMaxSize(ULONG size);
	ULONG NT_NT_SP_RecorderFileNameRuler(ULONG type, LPCTSTR file_name_prefix, LONG append_date, LONG append_time);
	ULONG NT_SetRecorderAudioTranscodeAAC(LONG is_transcode);
	ULONG NT_SetRecorderVideo(LONG is_record_video);
	ULONG NT_SetRecorderAudio(LONG is_record_audio);
	ULONG NT_StartRecorder();
	ULONG NT_StopRecorder();
	ULONG NT_FullScreen();
	void OnSDKEventReceived(ULONG event_id, ULONG param1);
	void OnVideoSizeReceived(ULONG width, ULONG height);

设置LOG存放路径:

ULONG CSmartPlayerActiveXCtrl::NT_SetLogPath(LPCTSTR log_path)

请于NT_Open() 之前调用,代码示例:

var obj = document.getElementById("SmartPlayerActiveX");
				
//如需记录log文件,请确保log路径存在, 如多级目录, 可按照"D:\\Daniulive\\log"类似格式设定, 记录文件名: smart_sdk.log

obj.NT_SetLogPath("D:\\");

接口说明:

1.  ULONG NT_Open();

打开player实例;
2. ULONG NT_Close();

关闭player实例;
3. ULONG NT_StartPlay();

开始播放;
4. ULONG NT_StopPlay();

停止播放;
5. ULONG NT_SetMute(LONG is_mute);

设置实时静音;
6. ULONG NT_SetURL(LPCTSTR url);

设置播放的RTMP或RTSP url;
7. ULONG NT_SetBuffer(LONG buffer);

设置buffer time,缓冲时间,单位:毫秒;
8. ULONG NT_SetRTSPTcpMode(LONG isUsingTCP);

设置RTSP TCP/UDP播放模式;
9. ULONG NT_SetRtspTimeout(LONG timeout);

设置RTSP超时时间;
10. ULONG NT_SetRtspAutoSwitchTcpUdp(LONG is_auto_switch_tcp_udp);

设置是否自动切换TCP/UDP模式;
11. ULONG NT_SetFastStartup(LONG isFastStartup);

设置是否快速启动;
12. ULONG NT_SetLowLatencyMode(LONG mode);

设置是否低延迟模式播放;
13. ULONG NT_SetFlipVertical(LONG is_flip);

设置垂直反转模式图像;
14. ULONG NT_SetFlipHorizontal(LONG is_flip);

设置水平反转图像;
15. ULONG NT_SetRotation(LONG degress);

设置旋转图像,可设定角度:0度 90度 180度 270度;
16. ULONG NT_SwitchURL(LPCTSTR url);

设置快速切换RTSP/RTMP url;
17. ULONG NT_SetCaptureImagePath(LPCTSTR path);

设置快照保存位置;
18. ULONG NT_CaptureImage();

设置实时快照功能;
19. ULONG NT_SetRecorderDirectory(LPCTSTR dir);

设置录像保存位置;
20. ULONG NT_SetRecorderFileMaxSize(ULONG size);

设置单个录像文件最大size,单位:兆;
21. ULONG NT_NT_SP_RecorderFileNameRuler(ULONG type, LPCTSTR file_name_prefix, LONG append_date, LONG append_time);

设置录像文件命名规则:是否需要前缀、是否添加日期、是否添加时间;
22. ULONG NT_SetRecorderAudioTranscodeAAC(LONG is_transcode);

设置录像音频文件是否转AAC后录制,支持PCMA/PCMU/SPEEX转AAC后录制文件;
23. ULONG NT_SetRecorderVideo(LONG is_record_video);

设置是否录制视频;
24. ULONG NT_SetRecorderAudio(LONG is_record_audio);

设置是否录制音频;
25. ULONG NT_StartRecorder();

开始录像;
26. ULONG NT_StopRecorder();

停止录像;
27. ULONG NT_FullScreen();

全屏显示窗口。

事件Event: 

1. void OnSDKEventReceived(ULONG event_id, ULONG param1);

回调网络状态、buffering状态、下载速度等;

事件类型:

<script>
	var NT_EVENT_ID_SMART_PLAYER_SDK = 0x01000000;
	var NT_SP_E_EVENT_ID_BASE = NT_EVENT_ID_SMART_PLAYER_SDK;
	var NT_SP_E_EVENT_ID_CONNECTING				= NT_SP_E_EVENT_ID_BASE | 0x2;	/*连接中*/
	var NT_SP_E_EVENT_ID_CONNECTION_FAILED		= NT_SP_E_EVENT_ID_BASE | 0x3;	/*连接失败*/
	var NT_SP_E_EVENT_ID_CONNECTED				= NT_SP_E_EVENT_ID_BASE | 0x4;	/*已连接*/
	var NT_SP_E_EVENT_ID_DISCONNECTED			= NT_SP_E_EVENT_ID_BASE | 0x5;	/*断开连接*/
	var NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED	= NT_SP_E_EVENT_ID_BASE | 0x8;	/*收不到RTMP数据*/
	var NT_SP_E_EVENT_ID_RTSP_STATUS_CODE       = NT_SP_E_EVENT_ID_BASE | 0xB;  /*rtsp status code上报, 目前只上报401, param1表示status code*/

	/* 接下来请从0x81开始*/
	var NT_SP_E_EVENT_ID_START_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x81; /*开始缓冲*/
	var NT_SP_E_EVENT_ID_BUFFERING		 = NT_SP_E_EVENT_ID_BASE | 0x82; /*缓冲中, param1 表示百分比进度*/
	var NT_SP_E_EVENT_ID_STOP_BUFFERING  = NT_SP_E_EVENT_ID_BASE | 0x83; /*停止缓冲*/

	var NT_SP_E_EVENT_ID_DOWNLOAD_SPEED  = NT_SP_E_EVENT_ID_BASE | 0x91; /*下载速度, param1表示下载速度,单位是(Byte/s)*/

	var NT_SP_E_EVENT_ID_PLAYBACK_REACH_EOS		= NT_SP_E_EVENT_ID_BASE | 0xa1; /*播放结束, 直播流没有这个事件,点播流才有*/
	var NT_SP_E_EVENT_ID_RECORDER_REACH_EOS		= NT_SP_E_EVENT_ID_BASE | 0xa2; /*录像结束, 直播流没有这个事件, 点播流才有*/
	var NT_SP_E_EVENT_ID_PULLSTREAM_REACH_EOS   = NT_SP_E_EVENT_ID_BASE | 0xa3; /*拉流结束, 直播流没有这个事件,点播流才有*/
	var NT_SP_E_EVENT_ID_DURATION = NT_SP_E_EVENT_ID_BASE | 0xa8; /*视频时长,如果是直播,则不上报,如果是点播的话, 若能从视频源获取视频时长的话,则上报, param1表示视频时长,单位是毫秒(ms)*/
</script>

调用展示:

<script language='javascript' for="SmartPlayerActiveX"  event="OnSDKEventReceived(event_id, param1)">
		// Test 1 - statically load the script (This is the basis for the hack)
		// Works on IE8, IE9, IE10 and IE11
		
		var show_str = "";

		var connection_status = event_id;

		if (connection_status != 0)
		{
			show_str += "链接状态: ";

			if (NT_SP_E_EVENT_ID_CONNECTING == connection_status)
			{
				show_str += "链接中";
			}
			else if (NT_SP_E_EVENT_ID_CONNECTION_FAILED == connection_status)
			{
				show_str += "链接失败";
			}
			else if (NT_SP_E_EVENT_ID_CONNECTED == connection_status)
			{
				show_str += "链接成功";
			}
			else if (NT_SP_E_EVENT_ID_DISCONNECTED == connection_status)
			{
				show_str += "链接断开";
			}
			else if (NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED == connection_status)
			{
				show_str += "收不到数据";
			}
		}

		var download_speed = -1;
		
		if (NT_SP_E_EVENT_ID_DOWNLOAD_SPEED == event_id)
		{
			download_speed = param1;
		}
		
		if (download_speed != -1)
		{
			show_str += "下载速度:" + (download_speed * 8 / 1000).toFixed(0) + "kbps " + (download_speed / 1024).toFixed(0) + "KB/s";
		}
		
		var buffer_status = 0;
		
		if (NT_SP_E_EVENT_ID_START_BUFFERING == event_id
		|| NT_SP_E_EVENT_ID_BUFFERING == event_id
		|| NT_SP_E_EVENT_ID_STOP_BUFFERING == event_id)
		{
			buffer_status = event_id;
		}

		if (buffer_status != 0)
		{
			show_str += "缓冲状态: ";

			if (NT_SP_E_EVENT_ID_START_BUFFERING == buffer_status)
			{
				show_str += "开始缓冲";
			}
			else if (NT_SP_E_EVENT_ID_BUFFERING == buffer_status)
			{
				show_str += "缓冲中" + param1 + "%";
			}
			else if (NT_SP_E_EVENT_ID_STOP_BUFFERING == buffer_status)
			{
				show_str += "结束缓冲";
			}
		}
		
		var EventMsgText = document.getElementById("EventMsg");
					
		EventMsgText.innerHTML = show_str;
	</script>

2. void OnVideoSizeReceived(ULONG width, ULONG height);

回调视频宽高信息。

调用展示:

<script language='javascript' for="SmartPlayerActiveX"  event="OnVideoSizeReceived(width, height)">
	// Test 1 - statically load the script (This is the basis for the hack)
	// Works on IE8, IE9, IE10 and IE11
	
	var VideoResolutionText = document.getElementById("VideoResolution");
				
	VideoResolutionText.innerHTML = width + "*" + height;
</script>

SDK接口调用实例:

播放和录像调用示例:

var is_player_opened = false;
var is_playing = false;
var is_recording = false;

function OpenPlayer()
{			   
	if(is_player_opened)
	{
		return;
	}
	
	var obj = document.getElementById("SmartPlayerActiveX");
	
	//如需记录log文件,请确保log路径存在, 如多级目录, 可按照"D:\\Daniulive\\log"类似格式设定, 记录文件名: smart_sdk.log
	obj.NT_SetLogPath("D:\\");
	
	var ret = obj.NT_Open();
	
	if(ret == 0)
	{   
		//设置TCP/UDP模式
		var rtsp_tcp_mode = document.getElementById("rtspTcpMode").checked ? 1 : 0;
		obj.NT_SetRTSPTcpMode(rtsp_tcp_mode);
		
		//设置RTSP超时时间
		var rtsp_timeout = document.getElementById("rtspTimeout").value;
		obj.NT_SetRtspTimeout(rtsp_timeout);
		
		//设置是否自动切换TCP-UDP模式
		var rtsp_auto_switch_tcp_udp = document.getElementById("rtspAutoSwitchTcpUdp").checked ? 1 : 0;
		obj.NT_SetRtspAutoSwitchTcpUdp(rtsp_auto_switch_tcp_udp);
		
		//设置是否快速启动
		var fast_startup_mode = document.getElementById("fastStartupMode").checked ? 1 : 0;
		obj.NT_SetFastStartup(fast_startup_mode);
		
		//设置需要播放或录像的RTSP/RTMP url
		var url = document.getElementById("playorReocordUrl").value;
		obj.NT_SetURL(url);
		
		//设置实时截图路径(可自行设置或选取系统存在的文件夹), 如多级目录可按照"D:\\Daniulive\\image"类似格式设定
		//var image_path = "D:\\";
		obj.NT_SetCaptureImagePath(image_path);
	
		is_player_opened = true;
	}
}

function ClosePlayer()
{
	if(is_player_opened)
	{
		var obj = document.getElementById("SmartPlayerActiveX");
		obj.NT_Close();
		
		var EventMsgText = document.getElementById("EventMsg");	
		EventMsgText.innerHTML = "";
		
		is_player_opened = false;
	}
}

function OnBnClickedPlay()
{
	if(!isIE())
	{
		alert("非IE浏览器,请用IE打开播放控件..");
		return;
	}
	
	if(!isActiveXInstalled())
	{
		alert("控件未加载,请先加载控件..");
		return;
	}
	
	if(is_playing)
	{
		StopPlayback();
	}
	else
	{
		StartPlayback();
	}
}

//开始播放
function StartPlayback() {
	
	if(!is_playing && !is_recording)
	{
		OpenPlayer();
	}
	
	var obj = document.getElementById("SmartPlayerActiveX");

	//设置是否启用低延迟模式
	var low_latency_mode = document.getElementById("lowlatencyMode").checked ? 1 : 0;
	obj.NT_SetLowLatencyMode(low_latency_mode);
					
	//设置缓冲时间
	var buffer_time = document.getElementById("bufferTime").value;
	obj.NT_SetBuffer(buffer_time);
					
	var ret = obj.NT_StartPlay();
	
	if(ret == 0)
	{
		is_playing = true;	
		
		var playBtnText = document.getElementById("playBtn");
	
		playBtnText.innerHTML = "停止播放";
	}		
}

//停止播放
function StopPlayback() {

	if(!is_playing)
	{
		return;
	}
	
	var obj = document.getElementById("SmartPlayerActiveX");

	obj.NT_StopPlay();
	 
	is_playing = false;
	
	var playBtnText = document.getElementById("playBtn");
	
	playBtnText.innerHTML = "开始播放";
	
	if(!is_recording)
	{
		ClosePlayer();
	}
	
	var VideoResolutionText = document.getElementById("VideoResolution");
			
	VideoResolutionText.innerHTML = "";
}
			
function OnBnClickedRecord()
{
	if(!isIE())
	{
		alert("非IE浏览器,请用IE打开播放控件..");
		return;
	}
	
	if(!isActiveXInstalled())
	{
		alert("控件未加载,请先加载控件..");
		return;
	}

	if(is_recording)
	{
		StopRecorder();
	}
	else
	{
		StartRecorder();
	}
}

//开始录像
function StartRecorder() {
	
	if(!is_playing && !is_recording)
	{
		OpenPlayer();
	}
	
	var obj = document.getElementById("SmartPlayerActiveX");

	//设置实时录像存放路径(可自行设置或选取系统存在的文件夹), 如多级目录可按照"D:\\Daniulive\\rec"类似格式设定
	var rec_dir = "D:\\";
	obj.NT_SetRecorderDirectory(rec_dir);
	
	var rec_max_size = 200;
	obj.NT_SetRecorderFileMaxSize(rec_max_size);
	
	var type = 0;
	var file_name_prefix = "daniulive";
	var append_date = 1;
	var append_time = 1;
	obj.NT_NT_SP_RecorderFileNameRuler(type, file_name_prefix, append_date, append_time);
	
	var is_transcode = 1;
	obj.NT_SetRecorderAudioTranscodeAAC(is_transcode);
	
	var is_record_video = 1;
	obj.NT_SetRecorderVideo(is_record_video);
	
	var is_record_audio = 1;
	obj.NT_SetRecorderAudio(is_record_audio);
	
	var ret = obj.NT_StartRecorder();
	
	if(ret == 0)
	{
		is_recording = true;
		
		var recordBtnText = document.getElementById("recordBtn");
	
		recordBtnText.innerHTML = "停止录像";
	}
}

//停止录像
function StopRecorder() {

	if(!is_recording)
	{
		return;
	}
	
	var obj = document.getElementById("SmartPlayerActiveX");

	obj.NT_StopRecorder();
	
	is_recording = false;
	
	var recordBtnText = document.getElementById("recordBtn");
	
	recordBtnText.innerHTML = "开始录像";
	
	if(!is_playing)
	{
		ClosePlayer();
	}
}

快速切换URL调用示例:

//快速切换播放URL
function SwitchUrl() {

	if(!is_playing)
	{
		return;
	}

	var obj = document.getElementById("SmartPlayerActiveX");

	var switch_url = document.getElementById("playorReocordUrl").value;
	obj.NT_SwitchURL(switch_url);
}

实时静音调用示例:

//实时静音
var is_mute = 1;	
function SetMute() {
	
	var obj = document.getElementById("SmartPlayerActiveX");
	
	obj.NT_SetMute(is_mute);
	
	var muteText = document.getElementById("MuteBtn");
	
	if(is_mute == 1 )
	{
		is_mute = 0;
		muteText.innerHTML = "取消静音";
	}
	else
	{
		is_mute = 1;
		muteText.innerHTML  = "实时静音";
	}
}

视频view垂直反转、水平反转、旋转调用示例:

//垂直反转
var is_flip_vertical = 1;
function SetFlipVertical() {
	
	var obj = document.getElementById("SmartPlayerActiveX");
	
	obj.NT_SetFlipVertical(is_flip_vertical);
	
	var flipVerticalText = document.getElementById("FlipVerticalBtn");
	
	if(is_flip_vertical == 1 )
	{
		is_flip_vertical = 0;
		flipVerticalText.innerHTML = "取消反转";
	}
	else
	{
		is_flip_vertical = 1;
		flipVerticalText.innerHTML  = "垂直反转";
	}
}

//水平反转
var is_flip_horizontal = 1;
function SetFlipHorizontal() {
	
	var obj = document.getElementById("SmartPlayerActiveX");
	
	obj.NT_SetFlipHorizontal(is_flip_horizontal);
	
	var flipHorizontalText = document.getElementById("FlipHorizontalBtn");
	
	if(is_flip_horizontal == 1 )
	{
		is_flip_horizontal = 0;
		flipHorizontalText.innerHTML = "取消反转";
	}
	else
	{
		is_flip_horizontal = 1;
		flipHorizontalText.innerHTML  = "水平反转";
	}
}

//视频view旋转
var rotate_degrees_ = 0;
function SetRotation() {
	
	rotate_degrees_ += 90;
	rotate_degrees_ = rotate_degrees_ % 360;
	
	var obj = document.getElementById("SmartPlayerActiveX");
	
	obj.NT_SetRotation(rotate_degrees_);
	
	var rotateText = document.getElementById("RotateBtn");
					
	if (0 == rotate_degrees_)
	{
		rotateText.innerHTML = "旋转90度";
	}
	else if (90 == rotate_degrees_)
	{
		rotateText.innerHTML = "旋转180度";
	}
	else if (180 == rotate_degrees_)
	{
		rotateText.innerHTML = "旋转270度";
	}
	else if (270 == rotate_degrees_)
	{
		rotateText.innerHTML = "不旋转";
	}
}

实时截图调用示例:

function CaptureImage() {
	var obj = document.getElementById("SmartPlayerActiveX");

	obj.NT_CaptureImage();
}

全屏显示窗口调用示例:

//全屏显示窗口
function FullScreen() {
	var obj = document.getElementById("SmartPlayerActiveX");

	obj.NT_FullScreen();
}

相关资料和测试控件下载:

Github: https://github.com/daniulive/SmarterStreaming

官网:https://www.daniulive.com

QQ群:

RTSP直播推流SDK

大牛直播RTSP推送端SDK特点:

  1. 全自研框架,易于扩展,自适应算法让延迟更低、采集编码传输效率更高;
  2. 所有功能以SDK接口形式提供,所有状态,均有event回调,完美支持断网自动重连;
  3. SDK模块化,可和大牛直播播放器SDK组合实现流媒体数据转发、内置轻量级RTSP服务、连麦、一对一互动等场景;
  4. Windows推送端SDK以层级模式提供,开发者可以自行组合数据源(如多摄像头/屏幕/水印叠加);
  5. 支持外部YUV/RGB/H.264/AAC/SPEEX/PCMA/PCMU数据源接入;
  6. 所有参数均可通过SDK接口单独设置,亦可通过默认参数,傻瓜式设置;
  7. RTMP推送、RTSP推送、录像、内置轻量级RTSP服务模块完全分离,可单独使用亦可组合使用;
  8. 业内甚至很难找到效果接近的SDK

功能支持:

如不单独说明,系Windows、Android、iOS全平台支持。

  •  [视频采集处理]Windows平台涵盖“Windows视频采集处理SDK”功能;
  •  [音频采集处理]Windows平台涵盖“Windows音频采集处理SDK”功能;
  •  [本地预览]Windows平台支持摄像头/屏幕/合成数据实时预览功能,Android/iOS平台支持本地前后置摄像头预览;
  •  [摄像头反转/旋转]Windows平台支持摄像头水平反转、垂直反转、0°/90°/180°/270°旋转;
  •  [摄像头采集]除常规YUV格式外,还支持MJPEG格式的摄像头采集;
  •  [RTSP推流]超低延时的RTSP协议直播推流SDK;
  •  [视频格式]Windows/Android平台支持H.264/H.265编码(Android H.265硬编码),iOS平台支持H.264编码;
  •  [音频格式]Windows/Android/iOS平台支持AAC编码;
  •  [H.264硬编码]Android/iOS平台支持H.264硬编码;
  •  [H.265硬编码]Android/iOS平台支持H.265硬编码;
  •  [硬编码自适应]Android/iOS平台支持硬编码自适应,如检测到硬编码不支持,自动切换到软编(iOS如H.265硬编,先切换到H.264硬编码,如不支持再尝试H.264软编);
  •  [RTSP鉴权]支持RTSP鉴权推送;
  •  [TCP/UDP模式]支持rtp over udp和rtp over tcp两种传输方式;
  •  [401事件处理]RTSP推送支持401事件上报;
  •  [视频格式]支持H.264/H.265(64位库)编码;
  •  [音频格式]支持AAC编码;
  •  [软硬编码参数配置]支持gop间隔、帧率、bit-rate设置;
  •  [软编码参数配置]支持软编码profile、软编码速度、可变码率设置;
  •  [多实例推送]支持多实例推送(如同时推送屏幕/摄像头和外部数据);
  •  [多分辨率支持]支持摄像头或屏幕多种分辨率设置;
  •  [Windows推屏]Windows平台支持屏幕裁剪、窗口采集、屏幕/摄像头数据合成等多种模式推送;
  •  [事件回调]支持各种状态实时回调;
  •  [水印]Windows平台支持文字水印、png水印、实时遮挡,Android平台支持文字水印、png水印;
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [动态码率]支持根据网络情况自动调整推流码率;
  •  [实时静音]支持推送过程中,实时静音/取消静音;
  •  [实时快照]支持推流过程中,实时快照;
  •  [纯音频推流]支持仅采集音频流并发起推流功能;
  •  [纯视频推流]支持特殊场景下的纯视频推流功能;
  •  [降噪]Windows/Android平台支持降噪处理、自动增益、VAD检测;
  •  [回音消除]Android平台支持实时传递远端PCM数据,方便回音消除处理;
  •  [外部编码前视频数据对接]支持YUV数据对接;
  •  [外部编码前音频数据对接]支持PCM对接;
  •  [外部编码后视频数据对接]支持外部H.264数据对接;
  •  [外部编码后音频数据对接]外部AAC/PCMA/PCMU数据对接;
  •  [推送端休眠设置]Windows平台支持休眠接口(设置成休眠模式后CPU会适当降低);
  •  [扩展录像功能]完美支持和录像SDK组合使用,录像相关功能,可参见”8. Windows/Android/iOS录像SDK“;
  •  [服务器兼容]支持支持自建服务器(如Darin Stream Server)。

对应Demo:

  •  Windows测试程序:SmartPublisherDemo.exe;
  •  Windows C++工程:WIN-PublisherSDK-CPP-Demo;
  •  Android工程:SmartPublisherV2;
  •  iOS工程:SmartiOSPublisherV2。

移动端使用说明不再赘述,点击查看Windows使用说明

大牛直播RTMP播放器SDK

大牛直播RTMP播放器SDK特点:

在没测试过大牛直播SDK的RTMP播放器之前,你甚至不相信行业内,RTMP播放器延迟可以稳定的做到1秒以内。

无需赘述,全自研内核,行业内一致认可的跨平台RTMP直播播放器SDK,功能齐全、高稳定、超低延迟、近200家公司明智之选。

功能支持:

如不单独说明,系Windows、Android、iOS全平台支持。

  •  [支持播放协议]高稳定、超低延迟(一秒内,行业内几无效果接近的播放端)、业内首屈一指的RTMP直播播放器SDK;
  •  [多实例播放]支持多实例播放;
  •  [事件回调]支持网络状态、buffer状态等回调;
  •  [音视频加密]Windows平台支持RTMP推送端加密(AES/SM4(国密))音视频数据正常播放
  •  [视频格式]支持RTMP扩展H.265,H.264;
  •  [音频格式]支持AAC/PCMA/PCMU/Speex;
  •  [H.264/H.265软解码]支持H.264/H.265软解;
  •  [H.264硬解码]Windows/Android/iOS支持H.264硬解;
  •  [H.265硬解]Windows/Android/iOS支持H.265硬解;
  •  [H.264/H.265硬解码]Android支持设置Surface模式硬解和普通模式硬解码;
  •  [缓冲时间设置]支持buffer time设置;
  •  [首屏秒开]支持首屏秒开模式;
  •  [低延迟模式]支持类似于线上娃娃机等直播方案的超低延迟模式设置(公网200~400ms);
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [快速切换URL]支持播放过程中,快速切换其他URL,内容切换更快;
  •  [音视频多种render机制]Android平台,视频:surfaceview/OpenGL ES,音频:AudioTrack/OpenSL ES;
  •  [实时静音]支持播放过程中,实时静音/取消静音;
  •  [实时快照]支持播放过程中截取当前播放画面;
  •  [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
  •  [渲染镜像]支持水平反转、垂直反转模式设置;
  •  [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
  •  [ARGB叠加]Windows平台支持ARGB图像叠加到显示视频(参看C++的DEMO);
  •  [解码前视频数据回调]支持H.264/H.265数据回调;
  •  [解码后视频数据回调]支持解码后YUV/RGB数据回调;
  •  [解码后视频数据缩放回调]Windows平台支持指定回调图像大小的接口(可以对原视图像缩放后再回调到上层);
  •  [解码前音频数据回调]支持AAC/PCMA/PCMU/SPEEX数据回调;
  •  [音视频自适应]支持播放过程中,音视频信息改变后自适应;
  •  [扩展录像功能]完美支持和录像SDK组合使用(支持RTMP扩展H.265流录制,支持PCMA/PCMU/Speex转AAC后录制,支持设置只录制音频或视频),录像相关功能,可参见”Windows/Android/iOS录像SDK“。

对应Demo:

  •  Windows测试程序:SmartPlayer.exe;
  •  Windows C++工程:WIN-PlayerSDK-CPP-Demo;
  •  Windows C#工程:WIN-PlayerSDK-CSharp-Demo;
  •  Android工程:SmartPlayerV2;
  •  iOS工程:SmartiOSPlayerV2。

Demo使用说明

大牛直播sdk-windows-rtmp-rtsp-本地flv播放器使用说明

 

大牛直播RTSP播放器SDK

大牛直播RTSP播放器SDK特点:

无需赘述,全自研内核,行业内一致认可的跨平台RTSP直播播放器SDK,功能齐全、高稳定、超低延迟,适用于安防、教育、单兵指挥等行业。

功能支持:

如不单独说明,系Windows、Android、iOS全平台支持。

  •  [支持播放协议]高稳定、超低延迟、业内首屈一指的RTSP直播播放器SDK;
  •  [多实例播放]支持多实例播放;
  •  [事件回调]支持网络状态、buffer状态等回调;
  •  [视频格式]支持H.265、H.264,此外,Windows/Android平台还支持RTSP MJPEG播放;
  •  [音频格式]支持AAC/PCMA/PCMU;
  •  [H.264/H.265软解码]支持H.264/H.265软解;
  •  [H.264硬解码]Windows/Android/iOS支持H.264硬解;
  •  [H.265硬解]Windows/Android/iOS支持H.265硬解;
  •  [H.264/H.265硬解码]Android支持设置Surface模式硬解和普通模式硬解码;
  •  [RTSP模式设置]支持RTSP TCP/UDP模式设置;
  •  [RTSP TCP/UDP自动切换]支持RTSP TCP、UDP模式自动切换;
  •  [RTSP超时设置]支持RTSP超时时间设置,单位:秒;
  •  [RTSP 401认证处理]支持上报RTSP 401事件,如URL携带鉴权信息,会自动处理;
  •  [缓冲时间设置]支持buffer time设置;
  •  [首屏秒开]支持首屏秒开模式;
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [快速切换URL]支持播放过程中,快速切换其他URL,内容切换更快;
  •  [音视频多种render机制]Android平台,视频:surfaceview/OpenGL ES,音频:AudioTrack/OpenSL ES;
  •  [实时静音]支持播放过程中,实时静音/取消静音;
  •  [实时快照]支持播放过程中截取当前播放画面;
  •  [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
  •  [渲染镜像]支持水平反转、垂直反转模式设置;
  •  [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
  •  [解码前视频数据回调]支持H.264/H.265数据回调;
  •  [解码后视频数据回调]支持解码后YUV/RGB数据回调;
  •  [解码前音频数据回调]支持AAC/PCMA/PCMU/SPEEX数据回调;
  •  [音视频自适应]支持播放过程中,音视频信息改变后自适应;
  •  [扩展录像功能]完美支持和录像SDK组合使用(支持RTSP H.265流录制,支持PCMA/PCMU转AAC后录制,支持设置只录制音频或视频),录像相关功能,可参见”Windows/Android/iOS录像SDK“。

对应Demo:

  •  Windows测试程序:SmartPlayer.exe;
  •  Windows C++工程:WIN-PlayerSDK-CPP-Demo;
  •  Windows C#工程:WIN-PlayerSDK-CSharp-Demo;
  •  Android工程:SmartPlayerV2;
  •  iOS工程:SmartiOSPlayerV2。

Demo使用说明

大牛直播sdk-windows-rtmp-rtsp-本地flv播放器使用说明

一对一互动SDK

大牛直播一对一互动SDK涵盖Windows、Android和iOS平台。

目前市面上大多一对一互动都是基于WebRTC,缺点如下:

  1. 服务器部署非常复杂,不利于私有部署,在一些私密性高的场景下,无法使用,如公安、市政等体系;
  2. 传输基于UDP,很难保证传输质量,由于UDP是不可靠的传输协议,在复杂的公网网络环境下,各种突发流量、偶尔的传输错误、网络抖动、超时等等都会引起丢包异常,都会在一定程度上影响音视频通信的质量;
  3. 难以应对复杂的互联网环境,如跨区跨运营商、低带宽、高丢包等场景;
  4. 整个框架体系不够灵活,代码复杂度高,行话说的好:从demo到实用,中间还差1万个WebRTC

RTMP/RTSP一对一互动SDK有以下优点:

  •  基于官方现有RTMP、RTSP推送、或内置RTSP服务、播放SDK,产品稳定度高,行业内首屈一指的超低延迟特性;
  •  加入噪音抑制、回音消除、自动增益控制等特性,确保通话效果;
  •  采用通用的RTMP和RTSP服务器,如nginx、SRS或 Darwin Stream Server(原生版本),更有利于私有部署;
  •  支持H.264的扩展SEI消息发送机制;
  •  支持H.265编码(Windows 64位库,Android/iOS硬编码)和H.264可变码率设定,换句话说,之前大牛直播SDK推送端支持的功能,都可以同步支持;
  •  支持H.265解码,直播播放器支持的功能,一对一互动模块都可以有选择的支持;
  •  Windows平台支持双流合成大小屏录制;
  •  Windows支持摄像头、屏幕合成、水印等各种组合模式,扩展度高;
  •  适用于应急指挥、教育培训等领域;
  •  支持RTMP扩展AES/SM4加解密,确保音视频数据安全性;

对应Demo:

  •  Windows C++工程:集成可参考WIN-PublisherSDK-CPP-Demo和WIN-PlayerSDK-CPP-Demo,或相应C# demo;
  •  Android工程:SmartEchoCancellationV2;
  •  iOS工程:SmartiOSEchoCancellation。

本地FLV播放SDK

大牛直播本地FLV播放SDK,目前覆盖Windows平台。

功能支持:

  1. 视频:H.264;
  2. 音频:AAC;
  3. 支持本地flv文件播放(支持获取flv文件的duration(时长);
  4. 支持显示当前播放位置;
  5. 支持开始播放或播放过程中seek(跳转播放位置),也许是行业内seek最快的flv点播播放器);
  6. 可通过回调本地FLV音视频数据帧,配合RTMP推送模块,实现本地FLV文件的实时RTMP流转发。

视沃科技(大牛直播SDK)RTMP推送-RTSP/RTMP直播SDK

视沃科技-大牛直播SDK daniulive.com

始于2014年,国内外为数不多致力于极致体验的超强全自研跨平台(windows/android/iOS)流媒体内核,通过模块化自由组合,支持实时RTMP推流、RTMP/RTSP直播播放(支持RTSP/RTMP H.265)、实时录像、多路流媒体转发、音视频导播、动态视频合成、音频混音、互动直播、内置轻量级RTSP服务等,比快更快,业界真正靠谱的超低延迟直播SDK(1秒内,低延迟模式下200~400ms)。

适用于在线教育、无纸化推屏/会议、智慧教室、直播答题、智能可视门禁对讲、智慧安防、智能家居、物联网、智能车载、传统硬件领域、超低延迟娃娃机抓取播放方案、媒体移动直播、应急指挥调度(针对保险、城管、交警、消防、公安等职能管理部门的单兵应急执法系统)、可视化购物、远程专家诊断、可视化巡检、(如电信/电力线路/铁路沿线/水利设施/油田/消防设施巡检)、移动视频安防监控,企业内训、金融在线直播室、微信直播、监控对接、活动现场直播、游戏直播、秀场直播等场景。

latest release note

除此之外,大牛直播SDK播放端,支持APICloudReact Native二次封装,并且全平台支持Unity3D平台,也可能是Unity3D平台下首款真正高稳定、超低延迟的rtmp/rtsp直播播放器。

android/iOS播放器SDK(V2)APICloud调用说明

windows/android/iOS播放器SDK(V2)Unity3D调用说明(更新于2018/10/31)

大牛直播SDK基于unity3d平台的rtmp/rtsp直播播放端SDK视频演示

Unity3D-Windows播放端APP下载(更新于2018/09/04)

Unity3D-Android播放端APK下载(更新于2018/10/24)

Windows端

  •  RTMP直播推流SDK rtmp推送SDK(支持同时推多路url,支持RTMP扩展H.265推送(64位库));
  •  RTMP/RTSP直播播放器SDK 业内首屈一指的rtmp/rtsp超低延迟直播播放器SDK(支持RTMP H.265扩展播放);
  •  Unity3D RTMP/RTSP直播播放器SDK 业内首家Windows支持Unity3D的超低延迟RTMP/RTSP直播播放器SDK,支持快照、录像、实时静音、view旋转、快速切换URL等特性;
  •  RTMP/RTSP多路流媒体转RTMP推送SDK 支持同时多路拉取rtmp/rtsp流/本地flv文件,并分别转发到服务器,支持转发过程中,拉取的rtsp/rtmp或本地flv文件实时内容切换,业内为数不多支持RTSP/RTMP H.265拉流转发的SDK(提供配套RTMP扩展H.265服务器);
  •  轻量级RTSP服务SDK 为满足内网无纸化/电子教室等内网超低延迟需求,避免让用户配置单独的服务器,大牛直播SDK在推送端支持轻量级RTSP服务SDK,推送端SDK支持的功能,内置轻量级RTSP服务SDK后,功能继续支持,windows端64位库支持RTSP H.265视频输出;
  •  内网RTSP网关SDK 内网RTSP网关SDK,系内置轻量级RTSP服务SDK扩展,完成外部RTSP/RTMP数据拉取并注入到轻量级RTSP服务SDK工作,多个内网客户端直接访问内网轻量级RTSP服务获取公网数据,无需部署单独的服务器,支持RTSP/RTMP H.265数据接入;
  •  导播SDK 数据源:1. rtmp/rtsp音视频流;2. 本地屏幕/摄像头/音频数据;3.本地flv文件;多路流合成一路实时导播推送;
  •  录像SDK 支持拉取rtmp/rtsp流实时录像模块/实时快照功能,支持纯音频、纯视频、音视频录制模式,支持音频(PCMU/PCMA,Speex等)转AAC后再录像,业内为数不多的支持RTSP/RTMP H.265录制到MP4文件的录像SDK;
  •  [互动SDK] Windows一对一互动(可windows与windows/android互动);
  •  连麦SDK 以标准协议为基础,完美支持Windows连麦;
  •  [点播播放器SDK] 支持本地flv文件播放(支持获取flv文件的duration(时长);支持显示当前播放位置;支持开始播放或播放过程中seek(跳转播放位置),也许是行业内seek最快的flv点播播放器);
  •  SEI扩展数据发送/接收SDK 支持推送端通过H.264 SEI信息扩展,实时传输文本/二进制数据信息(如实时字幕/时间戳/题目分发/公告广播等),播放端做相应解析和回显;
  •  视频处理SDK 屏幕/多摄像头/水印/遮挡区域多层自由合成模块;
  •  音频处理SDK 多路混音、回音消除、噪音抑制、自动增益、VAD检测模块;

Android端

  •  RTMP直播推流端SDK Android屏幕、摄像头RTMP推流SDK;
  •  RTMP/RTSP直播播放器SDK 业内首屈一指的rtmp/rtsp超低延迟直播播放器SDK(支持RTMP H.265扩展播放);
  •  Unity3D RTMP/RTSP直播播放器SDK 业内首家Android支持Unity3D的超低延迟RTMP/RTSP直播播放器SDK,支持快照、录像、实时静音、view旋转、快速切换URL等特性;
  •  录像SDK 支持拉取rtmp/rtsp流实时录像模块/实时快照功能,支持纯音频、纯视频、音视频录制模式,支持音频(PCMU/PCMA,Speex等)转AAC后再录像,业内为数不多的支持RTSP/RTMP H.265录制到MP4文件的录像SDK;
  •  RTMP/RTSP多路流媒体转RTMP推送SDK 支持实时拉取的rtmp/rtsp流转发到指定rtmp url;
  •  轻量级RTSP服务SDK 为满足内网无纸化/电子教室等内网超低延迟需求,避免让用户配置单独的服务器,大牛直播SDK在推送端支持轻量级RTSP服务SDK,推送端SDK支持的功能,内置轻量级RTSP服务SDK后,功能继续支持;
  •  [互动SDK] Android一对一互动(可android与windows/android/iOS互动);
  •  SEI扩展数据发送/接收SDK 支持推送端通过H.264 SEI信息扩展,实时传输文本/二进制数据信息(如实时字幕/时间戳/题目分发/公告广播等),播放端做相应解析和回显;
  •  视频处理SDKAndroid文字水印、png图片水印;
  •  音频处理SDKAndroid回音消除、噪音抑制、自动增益、VAD检测模块;

iOS端

  •  RTMP直播推流端SDK iOS屏幕(基于ReplayKit)、摄像头RTMP推流SDK;
  •  RTMP/RTSP直播播放器SDK 业内首屈一指的rtmp/rtsp超低延迟直播播放器SDK(支持RTMP H.265扩展播放);
  •  Unity3D RTMP/RTSP直播播放器SDK 业内首家iOS支持Unity3D的超低延迟RTMP/RTSP直播播放器SDK,支持快照、录像、实时静音、view旋转、快速切换URL等特性;
  •  录像SDK 支持拉取rtmp/rtsp流实时录像模块/实时快照功能,支持纯音频、纯视频、音视频录制模式,支持音频(PCMU/PCMA,Speex等)转AAC后再录像,业内为数不多的支持RTSP/RTMP H.265录制到MP4文件的录像SDK;
  •  RTMP/RTSP多路流媒体转RTMP推送SDK 支持实时拉取的rtmp/rtsp流转发到指定rtmp url;
  •  轻量级RTSP服务SDK 为满足内网无纸化/电子教室等内网超低延迟需求,避免让用户配置单独的服务器,大牛直播SDK在推送端支持轻量级RTSP服务SDK,推送端SDK支持的功能,内置轻量级RTSP服务SDK后,功能继续支持;
  •  SEI扩展数据发送/接收SDK 支持推送端通过H.264 SEI信息扩展,实时传输文本/二进制数据信息(如实时字幕/时间戳/题目分发/公告广播等),播放端做相应解析和回显;

本地下载

很多开发者反应,由于项目庞大,github下载整个工程很慢,我们已经把相关demo文件和使用说明,全部上传到QQ群共享:

或者直接从私有服务器下载(Windows提供C#/C++ demo, android提供android studio demo,iOS提供xcode demo):

大牛直播SDK相关demo本地下载

NOTE: Windows平台,以C++ SDK Demo为最新,C# Demo更新速度稍滞于C++ Demo。

大牛直播SDK集成和调用说明

大牛直播SDK Demo使用说明

上层源码目录

  1. android推流 SmartPublisherV2https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/AndroidStudio/SmartPublisherV2
  2. android推流 SmartServicePublisherV2(后台service推送屏幕)https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/AndroidStudio/SmartServicePublisherV2
  3. android推流 SmartServiceCameraPublisherV2(后台service推送摄像头)https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/AndroidStudio/SmartServiceCameraPublisherV2
  4. android一对一回音消除 SmartEchoCancellationV2https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/AndroidStudio/SmartEchoCancellationV2
  5. android播放器 SmartPlayerV2:https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/AndroidStudio/SmartPlayerV2
  6. android转发-录像-播放三合一 SmartRelayDemoV2:https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/AndroidStudio/SmartRelayDemoV2
  7. iOS推流 SmartiOSPublisherV2:https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/IOS/SmartiOSPublisherV2
  8. iOS后台推屏 SmartiOSScreenPublisherV2:https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/IOS/SmartiOSScreenPublisherV2
  9. iOS播放器 SmartiOSPlayerV2:https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/IOS/SmartiOSPlayerV2
  10. iOS转发-录像-播放三合一 SmartiOSRelayDemoV2:https://github.com/daniulive/SmarterStreaming/tree/master/SourceCode/IOS/SmartiOSRelayDemoV2

功能支持


1. Windows视频采集处理SDK

  1. 支持视频源
  •  支持Windows屏幕采集、屏幕裁剪特定窗口采集、摄像头采集、扩展外部H.264数据对接;
  1. 摄像头和屏幕合成
  •  [摄像头和屏幕实时切换]支持推送过程中,摄像头和屏幕互相切换,单画面显示摄像头或屏幕;
  •  [摄像头叠加到屏幕] 支持摄像头按照设置坐标,叠加到屏幕指定位置,并支持实时关闭叠加层;
  •  [屏幕叠加到摄像头] 支持屏幕按照设定坐标,叠加到摄像头指定位置,并支持实时关闭叠加层;
  1. 水印和透明度遮挡
  •  [实时水印]支持动态水印设置,完美支持文字水印、实时时间水印和图片水印
  •  [透明度]可以设置透明度处理(设置遮盖);
  1. 对应Demo:
  •  测试程序:SmartPublisherDemo.exe;
  •  C++工程:WIN-PublisherSDK-CPP-Demo;
  •  C#工程:WIN-PublisherSDK-CSharp-Demo。

2. Windows音频采集处理SDK

  1. 支持音频源
  •  支持Windows采集麦克风扬声器和外部AAC, Speex WB, PCMA, PCMU数据接口输入;
  1. 音频合成
  •  [音频]支持扬声器和麦克风音频混音输出(同时选择“采集扬声器”和“采集麦克风”);
  1. 音频处理
  •  支持音频“端点检测(VAD)”,自适应码流,音频码流更节省;
  •  支持回音消除功能;
  •  支持噪音抑制功能;
  •  支持自动增益控制。
  1. 对应Demo:
  •  测试程序:SmartPublisherDemo.exe;
  •  C++工程:WIN-PublisherSDK-CPP-Demo;
  •  C#工程:WIN-PublisherSDK-CSharp-Demo。

3. Windows/Android/iOS RTMP直播推流SDK

如不单独说明,系Windows、Android、iOS全平台支持。

  •  [视频采集处理]Windows平台涵盖“Windows视频采集处理SDK”功能;
  •  [音频采集处理]Windows平台涵盖“Windows音频采集处理SDK”功能;
  •  [本地预览]Windows平台支持摄像头/屏幕/合成数据实时预览功能,Android/iOS平台支持本地前后置摄像头预览;
  •  [摄像头反转/旋转]Windows平台支持摄像头水平反转、垂直反转、0°/90°/180°/270°旋转;
  •  [RTMP推流]超低延时的RTMP协议直播推流SDK(Windows支持RTMP扩展H.265推送);
  •  [视频格式]Windows平台支持H.264/H.265编码,Android/iOS平台支持H.264编码;
  •  [音频格式]Windows/Android/iOS平台支持AAC编码,Windows/Android平台支持Speex编码;
  •  [音频编码]Windows/Android平台支持Speex推送、Speex编码质量设置;
  •  [H.264硬编码]Android/iOS支持H.264硬编码;
  •  [硬编码码自适应]Android/iOS平台支持硬编码自适应,如检测到硬编码不支持,自动切换到软编;
  •  [编码参数配置]支持gop间隔、帧率、bit-rate、软编码profile、软编码速度设置;
  •  [多实例推送]支持多实例推送(如同时推送屏幕/摄像头和外部数据);
  •  [RTMP扩展H.265]Windows推送SDK支持RTMP扩展H.265推送,针对摄像头采集编码,使用H.265可变码率,带宽大幅节省,效果直逼传统H.265编码摄像头;
  •  [横竖屏推流]Android/iOS平台支持支持横屏、竖屏推流;
  •  [多分辨率支持]支持摄像头或屏幕多种分辨率设置;
  •  [Windows推屏]支持屏幕裁剪、窗口采集、屏幕/摄像头数据合成等多种模式推送;
  •  [移动端推屏]Android平台支持后台service推送摄像头或屏幕(推送屏幕需要5.0+版本);
  •  [移动端推屏]iOS平台支持后台推送屏幕(基于ReplayKit,需要iOS 10.0+版本);
  •  [事件回调]支持各种状态实时回调;
  •  [水印]Windows平台支持文字水印、png水印、实时遮挡,Android平台支持文字水印、png水印;
  •  [RTMP推送模式]支持RTMP推送 live|record模式设置(需服务器支持);
  •  [镜像]Android/iOS平台支持前置摄像头实时镜像功能;
  •  [前后摄像头实时切换]Android/iOS平台支持采集过程中,前后摄像头切换;
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [动态码率]支持根据网络情况自动调整推流码率;
  •  [实时静音]支持推送过程中,实时静音/取消静音;
  •  [实时快照]支持推流过程中,实时快照;
  •  [纯音频推流]支持仅采集音频流并发起推流功能;
  •  [纯视频推流]支持特殊场景下的纯视频推流功能;
  •  [降噪]Windows/Android平台支持环境音、手机干扰等引起的噪音降噪处理、自动增益、VAD检测;
  •  [回音消除]android支持实时传递远端PCM数据,方便回音消除处理;
  •  [外部编码前视频数据对接]支持YUV数据对接;
  •  [外部编码前音频数据对接]支持PCM对接;
  •  [外部编码后视频数据对接]支持外部H.264数据对接;
  •  [外部编码后音频数据对接]外部AAC/PCMA/PCMU/SPEEX数据对接;
  •  [编码后数据输出]Android平台支持输出编码后的H264/AAC数据到上层,方便对接第三方平台(如GB28181)对接(接口说明和demo请点击以下链接);
  •  [扩展录像功能]完美支持和录像SDK组合使用,录像相关功能,可参见”8. Windows/Android/iOS录像SDK“;
  •  [基础美颜]iOS平台自带基础美颜功能;
  •  [裁剪模式]Android/iOS平台支持特定分辨率摄像头裁剪模式设置;
  •  [服务器兼容]支持支持自建服务器(如Nginx、SRS)或CDN。

对应Demo:

  •  Windows测试程序:SmartPublisherDemo.exe;
  •  Windows C++工程:WIN-PublisherSDK-CPP-Demo;
  •  Windows C#工程:WIN-PublisherSDK-CSharp-Demo;
  •  Android工程:SmartPublisherV2;
  •  iOS工程:SmartiOSPublisherV2。

4. Windows/Android/iOS RTMP、RTSP直播播放器SDK

如不单独说明,系Windows、Android、iOS全平台支持。

  •  [支持播放协议]高稳定、超低延迟(一秒内,行业内几无效果接近的播放端)、业内首屈一指的RTMP/RTSP直播播放器SDK;
  •  [多实例播放]支持多实例播放(如同时播放多路RTMP/RTSP流);
  •  [事件回调]支持网络状态、buffer状态等回调;
  •  [视频格式]支持RTSP H.265、RTMP扩展H.265,RTSP/RTMP H.264;
  •  [音频格式]RTMP/RTSP支持AAC/PCMA/PCMU,此外RTMP还支持Speex;
  •  [H.264/H.265软解码]支持H.264/H.265软解;
  •  [H.264硬解码]Android/iOS支持H.264硬解;
  •  [H.265硬解]Android支持H.265硬解;
  •  [H.264/H.265硬解码]Android支持设置Surface模式硬解和普通模式硬解码;
  •  [硬解码自适应]Android/iOS平台支持硬解码码自适应,如检测到硬解码不支持,自动切换到软解;
  •  [RTSP模式设置]支持RTSP TCP/UDP模式设置;
  •  [RTSP TCP/UDP自动切换]支持RTSP TCP、UDP模式自动切换;
  •  [RTSP超时设置]支持RTSP超时时间设置,单位:秒;
  •  [RTSP 401认证处理]支持上报RTSP 401事件,如URL携带鉴权信息,会自动处理;
  •  [缓冲时间设置]支持buffer time设置;
  •  [首屏秒开]支持首屏秒开模式;
  •  [低延迟模式]支持类似于线上娃娃机等直播方案的超低延迟模式设置(公网200~400ms);
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [快速切换URL]支持播放过程中,快速切换其他URL,内容切换更快;
  •  [音视频多种render机制]Android平台,视频:surfaceview/OpenGL ES,音频:AudioTrack/OpenSL ES;
  •  [实时静音]支持播放过程中,实时静音/取消静音;
  •  [实时快照]支持播放过程中截取当前播放画面;
  •  [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
  •  [渲染镜像]支持水平反转、垂直反转模式设置;
  •  [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
  •  [解码前视频数据回调]支持H.264/H.265数据回调;
  •  [解码后视频数据回调]支持解码后YUV/RGB数据回调;
  •  [解码前音频数据回调]支持AAC/PCMA/PCMU/SPEEX数据回调;
  •  [音视频自适应]支持播放过程中,音视频信息改变后自适应;
  •  [扩展录像功能]完美支持和录像SDK组合使用,录像相关功能,可参见”8. Windows/Android/iOS录像SDK“;
  •  [全屏]Windows平台双击画面进入全屏模式;
  •  [Windows本地FLV播放器]支持本地FLV文件播放(支持获取FLV文件的duration(时长);支持显示当前播放位置;
  •  [Windows本地FLV播放器]支持开始播放或播放过程中seek(跳转播放位置),也许是行业内seek最快的flv点播播放器)。

对应Demo:

  •  Windows测试程序:SmartPlayer.exe;
  •  Windows C++工程:WIN-PlayerSDK-CPP-Demo;
  •  Windows C#工程:WIN-PlayerSDK-CSharp-Demo;
  •  Android工程:SmartPlayerV2;
  •  iOS工程:SmartiOSPlayerV2。

5. Windows/Android/iOS内置轻量级RTSP服务SDK

如不单独说明,系Windows、Android、iOS全平台支持。

  •  [基础功能]支持Windows/Android/iOS平台RTMP直播SDK除推送RTMP外的所有常规功能;
  •  [音频格式]AAC;
  •  [视频格式]H.264、H.265;
  •  [协议类型]RTSP;
  •  [端口设置]支持RTSP端口设置;
  •  [鉴权设置]支持RTSP鉴权用户名、密码设置;
  •  [获取session连接数]支持获取当前RTSP服务会话连接数;
  •  [多服务支持]支持同时创建多个内置RTSP服务;
  •  [H.265支持]Windows内置rtsp server支持发布H.265视频(64位库);
  •  [RTSP url回调]支持设置后的rtsp url通过event回调到上层。

对应Demo:

  •  Windows测试程序:SmartPublisherDemo.exe;
  •  Windows C++工程:WIN-PublisherSDK-CPP-Demo;
  •  Windows C#工程:WIN-PublisherSDK-CSharp-Demo;
  •  Android工程:SmartPublisherV2;
  •  iOS工程:SmartiOSPublisherV2。

6. Windows内网RTSP网关SDK

内网RTSP网关SDK,系内置轻量级RTSP服务SDK扩展,完成外部RTSP/RTMP数据拉取并注入到轻量级RTSP服务SDK工作,多个内网客户端直接访问内网轻量级RTSP服务获取公网数据,无需部署单独的服务器,支持RTSP/RTMP H.265数据接入。 简单来说:内置轻量级RTSP服务SDK和内置RTSP网关SDK的区别在于数据来源不同,内置轻量级RTSP服务SDK数据来源于终端设备自带摄像头数据/屏幕数据/外部编码前后数据,内置RTSP网关SDK的数据源是RTSP/RTMP流数据。

  •  [音频格式]AAC;
  •  [视频格式]H.264、H.265;
  •  [接入协议]支持内外网RTMP/RTSP流接入;
  •  [输出协议]RTSP,拉取的RTSP/RTMP流,注入轻量级RTSP服务SDK;
  •  [音频转码]支持音频(PCMU/PCMA,Speex等)转AAC后注入;
  •  [端口设置]支持RTSP端口设置;
  •  [鉴权设置]支持RTSP鉴权用户名、密码设置;
  •  [获取session连接数]支持获取当前RTSP服务会话连接数;
  •  [多服务支持]支持同时创建多个内置RTSP服务;
  •  [H.265支持]Windows内置rtsp server支持发布H.265视频(64位库);
  •  [RTSP url回调]支持设置后的rtsp url通过event回调到上层;

对应Demo:

  •  Windows测试程序:SmartStreamRelayDemo.exe;
  •  Windows C++工程:WIN-RelaySDK-CPP-Demo;
  •  Windows C#工程:WIN-RelaySDK-CSharp-Demo。

7. Windows/Android/iOS RTMP/RTSP多路流媒体转RTMP推送SDK

如不单独说明,系Windows、Android、iOS全平台支持。

  •  [拉流]支持拉取RTSP流;
  •  [拉流]支持拉取RTMP流;
  •  [预览]支持拉取到的RTMP/RTSP随时本地预览、关闭预览;
  •  [拉流音频调节]支持拉取的RTMP/RTSP流静音;
  •  [音频转码]支持拉取的RTMP/RTSP的PCMA/PCMU/SPEEX音频格式转AAC后再转发到RTMP服务器;
  •  [url切换]支持转发过程中,拉取的RTMP/RTSP或本地FLV文件实时内容切换
  •  [转发]超低延迟转发拉取的rtsp/rtmp流到rtmp server;
  •  [H.265支持]业内首家支持RTSP/RTMP H.265转RTMP推送的SDK(提供配套RTMP扩展H.265服务器);

对应Demo:

  •  Windows测试程序:SmartStreamRelayDemo.exe;
  •  Windows C++工程:WIN-RelaySDK-CPP-Demo;
  •  Windows C#工程:WIN-RelaySDK-CSharp-Demo;
  •  Android工程:SmartRelayDemoV2;
  •  iOS工程:SmartiOSRelayDemoV2。

8. Windows导播SDK

  •  [拉流]支持拉取RTSP流;
  •  [拉流]支持拉取RTMP流;
  •  [混音合成]支持本地采集到屏幕或摄像头数据,和远程拉取得RTSP或RTMP流做合成、混音输出;
  •  [导播]支持导播过程中,随时切断某一路音视频或音频;
  •  [混音]支持音频混音(同时选择“采集麦克风”+“采集扬声器”);
  •  [合成]多路流合成一路流后,推送到RTMP服务器;
  •  [扩展录像快照]多路合成后的流,支持本地录像、快照。

对应Demo:

  •  测试程序:SmartMixStreamDemo.exe;
  •  C++工程:WIN-MixStreamSDK-CPP-Demo;

9. Windows/Android/iOS录像SDK

  •  [拉流]支持拉取RTSP流录像;
  •  [拉流]支持拉取RTMP流录像;
  •  [推流端录像]支持推送端同步录像;
  •  [逻辑分离]大牛直播录像SDK不同于普通录像接口,更智能,和推送、播放、转发、内置轻量级RTSP服务SDK功能完全分离,支持随时录像;
  •  [url切换]在录像过程中,支持切换不同URL,如两个URL配置一致,则可以录制到同一个MP4文件,如不一致,可自动分割到下一个文件;
  •  [参数设置]支持设置单个录像文件大小、录像路径等,并支持纯音频、纯视频、音视频录制模式;
  •  [音频转码]支持音频(PCMU/PCMA,Speex等)转AAC后再录像;
  •  [265支持]支持RTSP/RTMP H.265录制到MP4文件;
  •  [推送端265录像]Windows推送SDK支持H265录像;
  •  [事件回调]从开始录像,到录像结束均有event callback上来,网络堵塞、音视频同步均做了非常友好的处理。

对应Demo:

  •  Windows测试程序:SmartPlayer.exe;
  •  Windows C++工程:WIN-PlayerSDK-CPP-Demo;
  •  Windows C#工程:WIN-PlayerSDK-CSharp-Demo;
  •  测试程序:SmartPublisherDemo.exe;
  •  C++工程:WIN-PublisherSDK-CPP-Demo;
  •  C#工程:WIN-PublisherSDK-CSharp-Demo。
  •  Android工程:SmartPlayerV2;
  •  iOS工程:SmartiOSPlayerV2;
  •  Android工程:SmartPublisherV2;
  •  iOS工程:SmartiOSPublisherV2。

10. Windows/Android/iOS SEI扩展数据发送/接收SDK

  •  [RTSP SEI]支持内置RTSP服务SDK携带SEI扩展信息(H.264);
  •  [RTMP SEI]支持RTMP推送SDK携带SEI扩展信息(H.264);
  •  [自定义数据]持发送自定义用户数据(如自定义utf8字符串);
  •  [二进制数据]支持发送二进制数据;
  •  [播放端解析]RTSP/RTMP直播播放端SDK支持utf8文本、二进制、和原SEI数据解析。

对应Demo:

  •  Windows测试程序:SmartPlayer.exe;
  •  Windows C++工程:WIN-PlayerSDK-CPP-Demo;
  •  Windows C#工程:WIN-PlayerSDK-CSharp-Demo;
  •  测试程序:SmartPublisherDemo.exe;
  •  C++工程:WIN-PublisherSDK-CPP-Demo;
  •  C#工程:WIN-PublisherSDK-CSharp-Demo。
  •  Android工程:SmartPlayerV2;
  •  iOS工程:SmartiOSPlayerV2;
  •  Android工程:SmartPublisherV2;
  •  iOS工程:SmartiOSPublisherV2。

编译注意事项

  • iOS平台支持真机和模拟器编译运行.
  • iOS播放端编译时找不到 libSmartPlayerSDK.a 时,请先到 SmartiOSPlayer/SmartiOSPlayer/libs 目录, 解压libSmartPlayerSDK.zip.
  • iOS推送端编译时找不到 libSmartPublisherSDK.a 时,请先到 SmartiOSPublisher/SmartiOSPublisher/libs 目录, 解压libSmartPublisherSDK.zip.
  • 未授权版本,限制app-name,如果需要集成到自己工程里面调试,可以用以下名字:
Windows推送端:SmartPublisherDemo
Windows播放端:SmartPlayer
Windows转发端:SmartStreamRelayDemo
Windows合流导播端:SmartMixStreamDemo
android推送端:SmartPublisherSDKDemo
android后台Service推送:SmartServicePublisherSDKDemo
android一对一互动:SmartEchoCancellation
android播放器:SmartPlayerSDKDemo
iOS推送端:SmartiOSPublisher
iOS转发端:SmartiOSRelayDemo
iOS播放器:SmartiOSPlayer
  • 集成到自己工程,如何改名字(以推送端为例):
android:strings.xml:
<string name="app_name">SmartPublisherSDKDemo</string>
iOS:Info.plist-->右键Open As-->Source Code,添加或者编辑
<key>CFBundleName</key>	
<string>SmartiOSPublisher</string>

联系我们

点击查看联系方式

QQ交流群:

大牛直播SDK技术交流群1:499687479

大牛直播SDK技术交流群2:294891451

内网RTSP网关SDK

内网RTSP网关SDK,系内置轻量级RTSP服务SDK扩展,完成外部RTSP/RTMP数据拉取并注入到轻量级RTSP服务SDK工作,多个内网客户端直接访问内网轻量级RTSP服务获取公网数据,无需部署单独的服务器,支持RTSP/RTMP H.265数据接入。

简单来说:内置轻量级RTSP服务SDK和内置RTSP网关SDK的区别在于数据来源不同,内置轻量级RTSP服务SDK数据来源于终端设备自带摄像头数据/屏幕数据/外部编码前后数据,内置RTSP网关SDK的数据源是RTSP/RTMP流数据。

  •  [音频格式]AAC;
  •  [视频格式]H.264、H.265;
  •  [接入协议]支持内外网RTMP/RTSP流接入;
  •  [输出协议]RTSP,拉取的RTSP/RTMP流,注入轻量级RTSP服务SDK;
  •  [传输模式]Windows支持单播组播模式,Android/iOS平台支持单播模式;
  •  [音频转码]支持音频(PCMU/PCMA,Speex等)转AAC后注入;
  •  [端口设置]支持RTSP端口设置;
  •  [鉴权设置]支持RTSP鉴权用户名、密码设置;
  •  [获取session连接数]支持获取当前RTSP服务会话连接数;
  •  [多服务支持]支持同时创建多个内置RTSP服务;
  •  [H.265支持]Windows内置rtsp server支持发布H.265视频(64位库);
  •  [RTSP url回调]支持设置后的rtsp url通过event回调到上层;

对应Demo:

  •  Windows测试程序:SmartStreamRelayDemo.exe;
  •  Windows C++工程:WIN-RelaySDK-CPP-Demo;
  •  Windows C#工程:WIN-RelaySDK-CSharp-Demo;
  •  iOS工程:SmartiOSRelayDemoV2.

基本使用步骤:

  1. 点击“配置查看Rtsp服务”按钮,启动rtsp服务;
  2. 输入需要拉流的rtsp或rtmp地址;
  3. 点击拉流,获取rtsp或rtsp流数据;
  4. 点击“发送rtsp流”,即可把数据注入内网rtsp网关sdk;
  5. 发送成功后,会回调可用来播放的内网rtsp url;
  6. 播放端,输入步骤5回调的rtsp地址,完成拉流播放;
  7. 如果查看连接的内网播放session数,点击“配置查看Rtsp服务”,可实时查询每个rtsp service连接的session数;
  8. 如需本地拉取的rtsp或rtmp流,点击“预览”;
  9. 如需停止,点击“停止rtsp流”;

大牛直播SDK Demo展示

大牛直播SDK Demo页面展示:

1. Windows RTMP直播推送SDK:

2. Windows转发SDK:

3.Windows导播SDK:

4. Android RTMP直播推送SDK:

5. iOS RTMP直播推送:

6. Windows RTMP/RTSP直播播放SDK:

7. Android RTMP/RTSP直播播放SDK:

8. iOS RTMP/RTSP直播播放SDK:

9. Android播放、录像、RTMP转发-内置网关SDK(SmartRelayDemoV2)

音频采集处理SDK

Windows音频采集处理SDK

  1. 支持音频源
  •  支持Windows采集麦克风扬声器和外部AAC, Speex WB, PCMA, PCMU数据接口输入;
  1. 音频合成
  •  [音频]支持扬声器和麦克风音频混音输出(同时选择“采集扬声器”和“采集麦克风”);
  1. 音频处理
  •  支持音频“端点检测(VAD)”,自适应码流,音频码流更节省;
  •  支持回音消除功能;
  •  支持噪音抑制功能;
  •  支持自动增益控制。
  1. 对应Demo:
  •  测试程序:SmartPublisherDemo.exe;
  •  C++工程:WIN-PublisherSDK-CPP-Demo;
  •  C#工程:WIN-PublisherSDK-CSharp-Demo。

视频采集处理SDK

Windows视频采集处理SDK

  1. 支持视频源
  •  支持Windows屏幕采集、屏幕裁剪特定窗口采集、摄像头采集、扩展外部H.264数据对接;
  1. 摄像头和屏幕合成
  •  [摄像头和屏幕实时切换]支持推送过程中,摄像头和屏幕互相切换,单画面显示摄像头或屏幕;
  •  [摄像头叠加到屏幕] 支持摄像头按照设置坐标,叠加到屏幕指定位置,并支持实时关闭叠加层;
  •  [屏幕叠加到摄像头] 支持屏幕按照设定坐标,叠加到摄像头指定位置,并支持实时关闭叠加层;
  1. 水印和透明度遮挡
  •  [实时水印]支持动态水印设置,完美支持文字水印、实时时间水印和图片水印
  •  [透明度]可以设置透明度处理(设置遮盖);
  1. 对应Demo:
  •  测试程序:SmartPublisherDemo.exe;
  •  C++工程:WIN-PublisherSDK-CPP-Demo;
  •  C#工程:WIN-PublisherSDK-CSharp-Demo。

大牛直播互动SDK

目前,大牛直播SDK支持Windows/android一对一互动。

其中,windows需要在推送端,开启回音消除功能,移动端,参考 SmartEchoCancellationV2 工程。

互动SDK
功能 功能描述
标准功能 支持推送端常规功能
支持播放端常规功能
回音消除 支持回音消除
降噪 支持环境音、手机干扰等引起的噪音降噪处理、自动增益、VAD检测

大牛直播SEI扩展数据发送/接收SDK

大牛直播SDK支持推送端通过H.264 SEI信息扩展,实时传输文本/二进制数据信息,播放端做相应解析和回显。

适用场景:

1、公告广播:推送将相对/绝对时间戳/时间/公告内容发到播放端,播放端实时接收消息并做相应的逻辑处理。

2、冲顶大会:推流端实时将题目分发到播放端,借助于大牛直播SDK低延迟特性,轻松实现“音-画-题”同步接收;

3、直播:推流端将歌词/字幕分发到播放端,播放端实时绘制出歌词;

4、应急指挥/单兵:推送端将GIS信息/现场采集到的数据实时写入并分发到播放端;

5、在线教育:推流端将激光笔涂鸦操作分发到播放端,播放端实时划圈划线,实现特定特效。

目前Windows/Android/iOS平台推送和播放端均已支持,效果如下:

http://daniulive.gz.bcebos.com/SEI_send_recv.png