当前位置: 首页 > news >正文

Android平台RTMP|RTSP直播播放器功能进阶探讨

我们需要怎样的直播播放器?

很多开发者在跟我聊天的时候,经常问我,为什么一个RTMP或RTSP播放器,你们需要设计那么多的接口,真的有必要吗?带着这样的疑惑,我们今天聊聊Android平台RTMP、RTSP播放器常规功能,如软硬解码设置、实时音量调节、实时快照、实时录像、视频view翻转和旋转、画面填充模式设定、解码后YUV、RGB数据回调等:

 

延迟延迟延迟

RTMP或RTSP直播播放器,特别是在一些交互场景下,对延迟要求近乎苛刻,所以,毫秒级的延迟,是一个直播播放器聊下去的基础,200-400ms的整体时延,是大家比较期望的,是的,你没看错,RTMP的也可以做到极低延迟。

软硬解码设置

Android平台特别是超过1080p的分辨率的流数据,如果设备性能一般,软解效率不一定高,这时候建议硬解码,硬解码我们分两种,一种是设置surface模式的硬解码,这种无法快照和回调yuv、rgb数据,另一种就是常规硬解,直接出原始解码后数据的,区分两种硬解码模式,我们设计了如下的接口:

	/*** 设置视频硬解码下Mediacodec自行绘制模式(此种模式下,硬解码兼容性和效率更好,回调YUV/RGB和快照功能将不可用)** @param handle: return value from SmartPlayerOpen()** @param isHWRenderMode: 0: not enable; 1: 用SmartPlayerSetSurface设置的surface自行绘制** @return {0} if successful*/public native int SmartPlayerSetHWRenderMode(long handle, int isHWRenderMode);

调用如下:

if (isHardwareDecoder && is_enable_hardware_render_mode) {libPlayer.SmartPlayerSetHWRenderMode(playerHandle, 1);
}

硬解码设置如下,分别区分264、265硬解:

if (isHardwareDecoder) {int isSupportHevcHwDecoder = libPlayer.SetSmartPlayerVideoHevcHWDecoder(playerHandle, 1);int isSupportH264HwDecoder = libPlayer.SetSmartPlayerVideoHWDecoder(playerHandle, 1);Log.i(TAG, "isSupportH264HwDecoder: " + isSupportH264HwDecoder + ", isSupportHevcHwDecoder: " + isSupportHevcHwDecoder);
}

实时音量调节

实时音量调节主要用于实时静音和实时调节播放端的音量,特别是多实例播放的时候,非常有必要:

	/*** 设置播放音量** @param handle: return value from SmartPlayerOpen()** @param volume: 范围是[0, 100], 0是静音,100是最大音量, 默认是100** @return {0} if successful*/public native int SmartPlayerSetAudioVolume(long handle, int volume);

RTSP模式设置

针对RTSP的TCP、UDP模式设置,RTSP超时时间设置,大家可能遇到过这样的场景,有些RTSP服务或网络环境下,只支持TCP或UDP,这时候,就需要有TCP/UDP模式设置,还有自动切换TCP UDP模式选项,如果连上RTSP服务,但是收不到数据,通过RTSP timeout时间来设置重连尝试间隔:

	/*** 设置RTSP TCP/UDP模式(默认UDP模式)** @param handle: return value from SmartPlayerOpen()** @param is_using_tcp: if with 1, it will via TCP mode, while 0 with UDP mode** @return {0} if successful*/public native int SmartPlayerSetRTSPTcpMode(long handle, int is_using_tcp);/*** 设置RTSP超时时间, timeout单位为秒,必须大于0** @param handle: return value from SmartPlayerOpen()** @param timeout: RTSP timeout setting** @return {0} if successful*/public native int SmartPlayerSetRTSPTimeout(long handle, int timeout);/*** 设置RTSP TCP/UDP自动切换** @param handle: return value from SmartPlayerOpen()** NOTE: 对于RTSP来说,有些可能支持rtp over udp方式,有些可能支持使用rtp over tcp方式.* 为了方便使用,有些场景下可以开启自动尝试切换开关, 打开后如果udp无法播放,sdk会自动尝试tcp, 如果tcp方式播放不了,sdk会自动尝试udp.** @param is_auto_switch_tcp_udp 如果设置1的话, sdk将在tcp和udp之间尝试切换播放,如果设置为0,则不尝试切换.** @return {0} if successful*/public native int SmartPlayerSetRTSPAutoSwitchTcpUdp(long handle, int is_auto_switch_tcp_udp);

视频翻转、view旋转

	/*** 设置视频垂直反转** @param handle: return value from SmartPlayerOpen()** @param is_flip: 0: 不反转, 1: 反转** @return {0} if successful*/public native int SmartPlayerSetFlipVertical(long handle, int is_flip);/*** 设置视频水平反转** @param handle: return value from SmartPlayerOpen()** @param is_flip: 0: 不反转, 1: 反转** @return {0} if successful*/public native int SmartPlayerSetFlipHorizontal(long handle, int is_flip);/*** 设置顺时针旋转, 注意除了0度之外, 其他角度都会额外消耗性能** @param handle: return value from SmartPlayerOpen()** @param degress: 当前支持 0度,90度, 180度, 270度 旋转** @return {0} if successful*/public native int SmartPlayerSetRotation(long handle, int degress);

设置视频画面填充模式

	/*** 设置视频画面的填充模式,如填充整个view、等比例填充view,如不设置,默认填充整个view* @param handle: return value from SmartPlayerOpen()* @param render_scale_mode 0: 填充整个view; 1: 等比例填充view, 默认值是0* @return {0} if successful*/public native int SmartPlayerSetRenderScaleMode(long handle, int render_scale_mode);

设置实时回调下载速度间隔

通过设置下载速度回调间隔,上层可以知道当前的网络状态,也可根据回调的下载速度,做逻辑上的调整。

	/*** Set report download speed(设置实时回调下载速度)** @param handle: return value from SmartPlayerOpen()** @param is_report: if with 1, it will report download speed, it with 0: does not it.** @param report_interval: report interval, unit is second, it must be greater than 0.** @return {0} if successful*/public native int SmartPlayerSetReportDownloadSpeed(long handle, int is_report, int report_interval );

实时快照

实时快照,对RTSP或RTMP播放器来说,非常有价值,用户感兴趣的帧数据,可以直接写png文件保存下来,后续还可以针对保存下来的png数据,做二次分析。

	/*** Set if needs to save image during playback stream(是否启动快照功能)** @param handle: return value from SmartPlayerOpen()** @param is_save_image: if with 1, it will save current image via the interface of SmartPlayerSaveCurImage(), if with 0: does not it** @return {0} if successful*/public native int SmartPlayerSaveImageFlag(long handle, int is_save_image);/*** Save current image during playback stream(实时快照)** @param handle: return value from SmartPlayerOpen()** @param imageName: image name, which including fully path, "/sdcard/daniuliveimage/daniu.png", etc.** @return {0} if successful*/public native int SmartPlayerSaveCurImage(long handle, String imageName);

调用如下:

btnCaptureImage.setOnClickListener(new Button.OnClickListener() {@SuppressLint("SimpleDateFormat")public void onClick(View v) {String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());String imageFileName = "dn_" + timeStamp; // 创建以时间命名的文件名称String imagePath = imageSavePath + "/" + imageFileName + ".png";Log.i(TAG, "imagePath:" + imagePath);libPlayer.SmartPlayerSaveCurImage(playerHandle, imagePath);}
});

实时录像

实时录像的重要性不言而喻,我们好多开发者对实时录像有些误区,录像不止是写文件就完事了,还需要更精细化的粒度控制,比如单个文件大小设置、只录视频或者音频,其他音频格式转AAC后录制等。

	/*** Create file directory(创建录像目录)** @param path,  E.g: /sdcard/daniulive/rec** <pre> The interface is only used for recording the stream data to local side. </pre>** @return {0} if successful*/public native int SmartPlayerCreateFileDirectory(String path);/*** Set recorder directory(设置录像目录)** @param handle: return value from SmartPlayerOpen()** @param path: the directory of recorder file** <pre> NOTE: make sure the path should be existed, or else the setting failed. </pre>** @return {0} if successful*/public native int SmartPlayerSetRecorderDirectory(long handle, String path);/*** Set the size of every recorded file(设置单个录像文件大小,如超过设定大小则自动切换到下个文件录制)** @param handle: return value from SmartPlayerOpen()** @param size: (MB), (5M~500M), if not in this range, set default size with 200MB.** @return {0} if successful*/public native int SmartPlayerSetRecorderFileMaxSize(long handle, int size);/** 设置录像时音频转AAC编码的开关** @param handle: return value from SmartPlayerOpen()** aac比较通用,sdk增加其他音频编码(比如speex, pcmu, pcma等)转aac的功能.** @param is_transcode: 设置为1的话,如果音频编码不是aac,则转成aac,如果是aac,则不做转换. 设置为0的话,则不做任何转换. 默认是0.** 注意: 转码会增加性能消耗** @return {0} if successful*/public native int SmartPlayerSetRecorderAudioTranscodeAAC(long handle, int is_transcode);/**设置是否录视频,默认的话,如果视频源有视频就录,没有就没得录, 但有些场景下可能不想录制视频,只想录音频,所以增加个开关**@param is_record_video: 1 表示录制视频, 0 表示不录制视频, 默认是1** @return {0} if successful*/public native int SmartPlayerSetRecorderVideo(long handle, int is_record_video);/**设置是否录音频,默认的话,如果视频源有音频就录,没有就没得录, 但有些场景下可能不想录制音频,只想录视频,所以增加个开关**@param is_record_audio: 1 表示录制音频, 0 表示不录制音频, 默认是1** @return {0} if successful*/public native int SmartPlayerSetRecorderAudio(long handle, int is_record_audio);/*** Start recorder stream(开始录像)** @param handle: return value from SmartPlayerOpen()** @return {0} if successful*/public native int SmartPlayerStartRecorder(long handle);/*** Stop recorder stream(停止录像)** @param handle: return value from SmartPlayerOpen()** @return {0} if successful*/public native int SmartPlayerStopRecorder(long handle);

总结

实际上,除了上述提到的功能外,RTMP或RTSP播放器,还需要支持的客制化功能有支持回调H.264/H.265/AAC数据,或回到解码后的YUV或RGB数据,设置播放缓冲、设置快速播放、设置音频输出类型等,一个通用的RTSP、RTMP播放器,延迟是基础、功能完备是加分项,性能优异稳定性好,才敢推给客户,让客户在现场放心使用,无后顾之忧。

相关文章:

Android平台RTMP|RTSP直播播放器功能进阶探讨

我们需要怎样的直播播放器&#xff1f; 很多开发者在跟我聊天的时候&#xff0c;经常问我&#xff0c;为什么一个RTMP或RTSP播放器&#xff0c;你们需要设计那么多的接口&#xff0c;真的有必要吗&#xff1f;带着这样的疑惑&#xff0c;我们今天聊聊Android平台RTMP、RTSP播放…...

Centos7安装Telnet服务

简述 Centos7安装Telnet服务 前情提示 Centos7安装Telnet服务 一说 ● 部分截图、链接等因过期、更换域名、MD语法等可能不显示&#xff0c;可联系反馈&#xff08;备注好博文地址&#xff09;&#xff0c;谢谢❤ ● 带有#号、删除线、不操作、不执行字样的为提示或者备份bash&…...

【C++】GCC对应C++的版本支持

1、查看当前GCC的版本 pffNUC12WSKi7:~$ gcc -v Using built-in specs. COLLECT_GCCgcc COLLECT_LTO_WRAPPER/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper OFFLOAD_TARGET_NAMESnvptx-none:hsa OFFLOAD_TARGET_DEFAULT1 Target: x86_64-linux-gnu Configured with: ../src/co…...

前端面试:【算法】排序、查找、递归、动态规划

算法是计算机科学的核心&#xff0c;是解决问题的方法和步骤。在编程和软件开发中&#xff0c;了解和掌握各种常见算法至关重要。本文将详细介绍四种重要的算法&#xff1a;排序、查找、递归和动态规划&#xff0c;并提供示例来帮助你理解它们的应用。 1. 排序算法&#xff1a;…...

RK3399 开机自启一个shell脚本,一直起不来BUG

开机自启shell脚本如下&#xff1a; diff --git a/device/rockchip/common/sepolicy/file_contexts b/device/rockchip/common/sepolicy/file_contexts index eb6b5e4bb4..0bbe781a7c 100755 --- a/device/rockchip/common/sepolicy/file_contextsb/device/rockchip/common/se…...

[MyBatis系列④]核心配置文件

目录 1、简介 2、DTD 3、typeHandlers 3.1、默认类型处理器 3.2、自定义类型处理器 4、plugins ⭐MyBatis系列①&#xff1a;增删改查 ⭐MyBatis系列②&#xff1a;两种Dao开发方式 ⭐MyBatis系列③&#xff1a;动态SQL 1、简介 MyBatis的核心配置文件&#xff08;通常命…...

系统架构设计高级技能 · 层次式架构设计理论与实践

系列文章目录 系统架构设计高级技能 软件架构概念、架构风格、ABSD、架构复用、DSSA&#xff08;一&#xff09;【系统架构设计师】 系统架构设计高级技能 系统质量属性与架构评估&#xff08;二&#xff09;【系统架构设计师】 系统架构设计高级技能 软件可靠性分析与设计…...

Nuxt3打包部署到Linux(node+pm2安装和运行步骤+nginx代理)

最近&#xff0c;我们项目组的工作接近尾声&#xff0c;需要把项目部署上线。由于前端第一次使用Nuxt3框架&#xff0c;后端也是第一次部署Nuxt3项目&#xff0c;所以刚开始出现了很多问题。在我上网搜索很多教程后&#xff0c;得到了基本的流程。 1.服务器安装node.js环境 N…...

一维数组传参

在C语言中&#xff0c;可以通过指针来传递一维数组。一维数组实际上是指向数组首元素的指针&#xff0c;在函数中传递数组参数时&#xff0c;可以将数组名作为指针传递给函数。以下是一个示例&#xff1a; #include <stdio.h>void myFunction(int arr[], int size) {for…...

七层、四层和五层网络模型区别和联系

七层、四层和五层网络模型区别和联系 概述OSI网络7层模型&#xff08;概念型框架&#xff09;概述图片分析 四层模型概述常用协议OSI与TCP/IP四层的区别 五层模型概述三种网络模型对比 总结 概述 网络模型-七层模型&#xff08;OSI模型&#xff09;、五层协议体系结构和TCP/IP…...

RH1288V3 - 初识物理服务器

如果你拥有一台物理服务器(不是云服务器) 个人比较推荐你用物理服务器&#xff0c;虽然性能会比云要来的差&#xff0c;但是不用每月交钱上。云服务固然方便&#xff0c;但是几个核的性能和一点存储&#xff0c;想做一个动漫网站固然要很多mp4这种影视资源&#xff0c;云服务器…...

excel中如果A列中某项有多条记录,针对A列中相同的项,将B列值进行相加合并统计

excel中如果A列中某项有多条记录&#xff0c;针对A列中相同的项&#xff0c;将B列值进行相加合并统计。注意&#xff1a;B列的数据类型要为数字 如&#xff1a; 实现方法&#xff1a; C1、D1中分别输入公式&#xff0c;然后下拉 IF(COUNTIF($A$1:A1,A1)1, A1,"") …...

开发智能应用的新范式:大数据、AI和云原生如何构建智能软件

文章目录 1.利用大数据实现智能洞察2. 集成人工智能和机器学习3. 云原生架构的弹性和灵活性4. 实现实时处理和响应5. 数据安全和隐私保护6. 可解释性和透明性7. 持续创新和迭代8. 数据伦理和合规性 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &a…...

淘宝免费爬虫数据 商品详情数据 商品销售额销量API

场景&#xff1a;一个宽敞明亮的办公室&#xff0c;一位公司高管坐在办公桌前。 高管&#xff08;自言自语&#xff09;&#xff1a;淘宝&#xff0c;这个平台上商品真是琳琅满目&#xff0c;应该有不少销售数据吧。我该怎么利用这些数据呢&#xff1f; 突然&#xff0c;房间…...

Markdown初级使用指南

前言 大家好&#xff0c;我是艾老虎尤&#xff0c;我在一篇官方的文章中&#xff0c;我了解到了markdown&#xff0c;原本我写博客一直是使用的富文本编译器&#xff0c;之前我也有同学叫我使用MD&#xff0c;但是我嫌它复杂&#xff0c;就比如说一个标题&#xff0c;我在富文…...

国际版阿里云/腾讯云CDN装备运用教程:加快网站拜访速度

阿里云CDN装备运用教程&#xff1a;加快网站拜访速度 本文旨在为读者供给一个关于阿里云CDN的简要教程。咱们将介绍阿里云CDN的基本概念、资源加快过程、同步资源设置以及与阿里云OSS目标存储的结合。期望经过这篇教程&#xff0c;读者能够更好地了解和利用阿里云CDN服务&…...

面试之快速学习计算机网络-http

1. HTTP常见状态码 2. 3开头重定向&#xff0c;4开头客户端错误&#xff0c;5开头服务端错误 2. HTTP 报文 1. start-line&#xff1a;请求行&#xff0c;可以为以下两者之一&#xff1a; 请求行&#xff1a; GET /hello-world2.html HTTP/1.1状态行&#xff1a;HTTP/1.1 200…...

2023水果编曲软件fl studio 21.1.0 .3713官方中文直装破解版

fl studio 21.1.0 .3713官方中文直装破解版是一个完整的软件音乐制作环境或数字音频工作站&#xff08;DAW&#xff09;。它代表了 25 多年的创新发展&#xff0c;将您创作、编曲、录制、编辑、混音和掌握专业品质音乐所需的一切集于一身。 fl studio 21.1.0 .3713官方中文直装…...

【微信小程序】页面路由跳转函数之间的区别

微信小程序开发系列 文章目录 前言一、介绍1.wx.switchTab(Object object)2.wx.reLaunch(Object object)3.wx.redirectTo(Object object)4.wx.navigateTo(Object object)5.wx.navigateBack(Object object) 前言 在开发微信小程序中基本都会用到页面跳转&#xff0c;微信小程序…...

Ubuntu inotify

inotify 是一个用于监视文件系统事件的机制。它允许你监视文件或目录的变化,如文件的创建、修改、删除、移动等,以及目录的访问权限变化。 安装 在 Ubuntu 中,你需要安装 inotify-tools 包,这是一个包含 inotifywait 和 inotifywatch 等实用工具的软件包。你可以使用以下命…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

leetcode_69.x的平方根

题目如下 &#xff1a; 看到题 &#xff0c;我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历&#xff0c;我们是整数的平方根&#xff0c;所以我们分两…...

JavaScript 标签加载

目录 JavaScript 标签加载script 标签的 async 和 defer 属性&#xff0c;分别代表什么&#xff0c;有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...

ffmpeg(三):处理原始数据命令

FFmpeg 可以直接处理原始音频和视频数据&#xff08;Raw PCM、YUV 等&#xff09;&#xff0c;常见场景包括&#xff1a; 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装&#xff08;如封装为 MP4、TS&#xff09; 处理原始 YUV 视频…...