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

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

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

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

fa93784e8eb64e16b9ed4bb6e0bb32cd.jpg

延迟延迟延迟

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播放器,延迟是基础、功能完备是加分项,性能优异稳定性好,才敢推给客户,让客户在现场放心使用,无后顾之忧。

相关文章
|
5天前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
9天前
|
监控 Android开发 iOS开发
深入探索安卓与iOS的系统架构差异:理解两大移动平台的技术根基在移动技术日新月异的今天,安卓和iOS作为市场上最为流行的两个操作系统,各自拥有独特的技术特性和庞大的用户基础。本文将深入探讨这两个平台的系统架构差异,揭示它们如何支撑起各自的生态系统,并影响着全球数亿用户的使用体验。
本文通过对比分析安卓和iOS的系统架构,揭示了这两个平台在设计理念、安全性、用户体验和技术生态上的根本区别。不同于常规的技术综述,本文以深入浅出的方式,带领读者理解这些差异是如何影响应用开发、用户选择和市场趋势的。通过梳理历史脉络和未来展望,本文旨在为开发者、用户以及行业分析师提供有价值的见解,帮助大家更好地把握移动技术发展的脉络。
|
22天前
|
IDE 开发工具 Android开发
安卓与iOS开发对比:平台选择对项目成功的影响
【9月更文挑战第10天】在移动应用开发的世界中,选择正确的平台是至关重要的。本文将深入探讨安卓和iOS这两大主要移动操作系统的开发环境,通过比较它们的市场份额、开发工具、编程语言和用户群体等方面,为开发者提供一个清晰的指南。我们将分析这两个平台的优势和劣势,并讨论如何根据项目需求和目标受众来做出最佳选择。无论你是初学者还是有经验的开发者,这篇文章都将帮助你更好地理解每个平台的特性,并指导你做出明智的决策。
|
22天前
|
开发工具 Android开发 iOS开发
安卓与iOS开发:平台选择的艺术与科学
在移动应用开发的广阔天地中,安卓与iOS两大平台如同东西方哲学的碰撞,既有共通之处又各具特色。本文将深入探讨这两个平台的设计理念、开发工具和市场定位,旨在为开发者提供一份简明扼要的指南,帮助他们在这场技术与商业的博弈中找到自己的道路。通过比较分析,我们将揭示每个平台的优势与局限,以及它们如何影响应用的性能、用户体验和市场接受度。无论你是初涉江湖的新手,还是经验丰富的老手,这篇文章都将为你的选择提供新的视角和思考。
31 5
|
23天前
|
人工智能 Android开发 iOS开发
安卓与iOS开发:平台选择的艺术
在移动应用开发的广阔天地里,安卓和iOS两大操作系统各占半壁江山。本文将深入探讨这两个平台的开发环境、工具及市场趋势,帮助开发者在选择适合自己项目的平台时做出更明智的决策。通过比较各自的优势与局限,我们不仅能更好地理解每个系统的核心特性,还能洞察未来技术发展的脉络。无论你是刚入行的新手还是资深开发者,这篇文章都将为你提供有价值的参考和启示。
38 5
|
22天前
|
Linux Android开发 iOS开发
探索Android与iOS开发:平台之战还是互补共生?
在移动应用开发的浩瀚宇宙中,Android和iOS这两大星系始终吸引着无数开发者的目光。它们各自拥有独特的引力场,引领着技术潮流的方向。本文将穿梭于这两个平台的星际空间,揭示它们背后的力量对比,以及如何在这两者之间找到平衡点,共同推动移动应用开发的进步。
28 1
|
22天前
|
移动开发 开发框架 Android开发
安卓与iOS开发:平台之战的新篇章
在移动应用开发的广阔天地中,安卓和iOS始终占据着主导地位。本文通过比较这两个平台的发展历程、技术特点及未来趋势,探讨了它们之间的竞争与合作。文章旨在为开发者提供一个清晰的平台选择指南,并预测未来移动开发的可能走向。
35 1
|
24天前
|
移动开发 开发工具 Android开发
安卓与iOS开发:平台差异及其对开发者的影响
在移动开发的大潮中,安卓和iOS两大阵营各领风骚。本文将探讨这两个平台的关键差异,包括开发环境、编程语言、用户界面设计、应用分发以及商业模式等方面。通过比较分析,我们旨在为开发者提供一个清晰的指导,帮助他们根据项目需求和个人偏好做出明智的平台选择。同时,文章也将分享一些跨平台开发工具的使用经验,以期最大化开发效率和市场覆盖。
|
6天前
|
开发工具 Android开发 iOS开发
安卓与iOS开发环境对比:选择适合你的平台
【9月更文挑战第26天】在移动应用开发的广阔天地中,安卓和iOS是两大巨头。它们各自拥有独特的优势和挑战,影响着开发者的选择和决策。本文将深入探讨这两个平台的开发环境,帮助你理解它们的核心差异,并指导你根据个人或项目需求做出明智的选择。无论你是初学者还是资深开发者,了解这些平台的异同都至关重要。让我们一起探索,找到最适合你的那片开发天地。
|
8天前
|
Android开发 开发者
Android平台无纸化同屏如何实现实时录像功能
Android平台无纸化同屏,如果需要本地录像的话,实现难度不大,只要复用之前开发的录像模块的就可以,对我们来说,同屏采集这块,只是数据源不同而已,如果是自采集的其他数据,我们一样可以编码录像。
下一篇
无影云桌面