Android如何回调编码后的音视频数据

有开发者提到,在RTMP推送端的基础上,希望能回调编码后的音视频数据,便于开发者对接第三方系统,如GB28181.

为此,我们加了一下接口:

1. 设置音视频callback

对应接口:

	/*** Set Audio Encoded Data Callback.** @param audio_encoded_data_callback: Audio Encoded Data Callback.** @return {0} if successful*/public native int SmartPublisherSetAudioEncodedDataCallback(long handle, Object audio_encoded_data_callback);/*** Set Video Encoded Data Callback.** @param video_encoded_data_callback: Video Encoded Data Callback.** @return {0} if successful*/public native int SmartPublisherSetVideoEncodedDataCallback(long handle, Object video_encoded_data_callback);

设置回调:

libPublisher.SmartPublisherSetAudioEncodedDataCallback(publisherHandle, new PublisherAudioEncodedDataCallback());libPublisher.SmartPublisherSetVideoEncodedDataCallback(publisherHandle, new PublisherVideoEncodedDataCallback());

2. 实现 PublisherAudioEncodedDataCallback 和 PublisherVideoEncodedDataCallback:

    class PublisherAudioEncodedDataCallback implements NTAudioDataCallback{private int audio_buffer_size = 0;private int param_info_size = 0;private ByteBuffer audio_buffer_ = null;private ByteBuffer parameter_info_ = null;@Overridepublic ByteBuffer getAudioByteBuffer(int size){//Log.i("getAudioByteBuffer", "size: " + size);if( size < 1 ){return null;}if ( size <= audio_buffer_size && audio_buffer_ != null ){return audio_buffer_;}audio_buffer_size = size + 512;audio_buffer_size = (audio_buffer_size+0xf) & (~0xf);audio_buffer_ = ByteBuffer.allocateDirect(audio_buffer_size);// Log.i("getAudioByteBuffer", "size: " + size + " buffer_size:" + audio_buffer_size);return audio_buffer_;}@Overridepublic ByteBuffer getAudioParameterInfo(int size){//Log.i("getAudioParameterInfo", "size: " + size);if(size < 1){return null;}if ( size <= param_info_size &&  parameter_info_ != null ){return  parameter_info_;}param_info_size = size + 32;param_info_size = (param_info_size+0xf) & (~0xf);parameter_info_ = ByteBuffer.allocateDirect(param_info_size);//Log.i("getAudioParameterInfo", "size: " + size + " buffer_size:" + param_info_size);return parameter_info_;}public void onAudioDataCallback(int ret, int audio_codec_id, int sample_size, int is_key_frame, long timestamp, int sample_rate, int channel, int parameter_info_size, long reserve){Log.i("onAudioDataCallback", "ret: " + ret + ", audio_codec_id: " + audio_codec_id + ", sample_size: " + sample_size + ", timestamp: " + timestamp +",sample_rate:" + sample_rate + ",chn: " + channel + ", parameter_info_size:" + parameter_info_size);if ( audio_buffer_ == null)return;audio_buffer_.rewind();if ( ret == 0 && publisherHandle2 != 0 ) {libPublisher.SmartPublisherPostAudioEncodedData(publisherHandle2, audio_codec_id, audio_buffer_, sample_size, is_key_frame, timestamp, parameter_info_, parameter_info_size);}}}class PublisherVideoEncodedDataCallback implements NTVideoDataCallback{private int video_buffer_size = 0;private ByteBuffer video_buffer_ = null;@Overridepublic ByteBuffer getVideoByteBuffer(int size){//Log.i("getVideoByteBuffer", "size: " + size);if( size < 1 ){return null;}if ( size <= video_buffer_size &&  video_buffer_ != null ){return  video_buffer_;}video_buffer_size = size + 1024;video_buffer_size = (video_buffer_size+0xf) & (~0xf);video_buffer_ = ByteBuffer.allocateDirect(video_buffer_size);// Log.i("getVideoByteBuffer", "size: " + size + " buffer_size:" + video_buffer_size);return video_buffer_;}public void onVideoDataCallback(int ret, int video_codec_id, int sample_size, int is_key_frame, long timestamp, int width, int height, long presentation_timestamp){Log.i("onVideoDataCallback", "ret: " + ret + ", video_codec_id: " + video_codec_id + ", sample_size: " + sample_size + ", is_key_frame: "+ is_key_frame +  ", timestamp: " + timestamp +",width: " + width + ", height:" + height + ",presentation_timestamp:" + presentation_timestamp);if ( video_buffer_ == null)return;video_buffer_.rewind();if ( ret == 0 && publisherHandle2 !=0 ) {libPublisher.SmartPublisherPostVideoEncodedData(publisherHandle2, video_codec_id, video_buffer_, sample_size, is_key_frame, timestamp, presentation_timestamp);}}}

3. 提供开始回调数据和停止回调数据接口:

	/*** Start output Encoded Data(用于编码后的音视频数据回调)** @return {0} if successful*/public native int SmartPublisherStartOutputEncodedData(long handle);/***  Stop output Encoded Data** @return {0} if successful*/public native int SmartPublisherStopOutputEncodedData(long handle);

4. 上层demo调用实例:

    class ButtonEncodedDataCallbackListener implements OnClickListener {public void onClick(View v) {if (isEncodedDatacallbackRunning) {stopEncodedDataCallback();if (!isPushing && !isRTSPPublisherRunning && !isRecording) {ConfigControlEnable(true);}btnEncodedDataCallback.setText("启动编码数据回调");isEncodedDatacallbackRunning = false;if (publisherHandle2 != 0) {libPublisher.SmartPublisherStopPublisher(publisherHandle2);libPublisher.SmartPublisherClose(publisherHandle2);publisherHandle2 = 0;}return;}Log.i(TAG, "onClick start encoded data callback..");if (libPublisher == null)return;if (!isPushing && !isRTSPPublisherRunning && !isRecording) {InitAndSetConfig();}libPublisher.SmartPublisherSetAudioEncodedDataCallback(publisherHandle, new PublisherAudioEncodedDataCallback());libPublisher.SmartPublisherSetVideoEncodedDataCallback(publisherHandle, new PublisherVideoEncodedDataCallback());int startRet = libPublisher.SmartPublisherStartOutputEncodedData(publisherHandle);if (startRet != 0) {isEncodedDatacallbackRunning = false;Log.e(TAG, "Failed to start encoded data callback.");return;}if (!isPushing && !isRTSPPublisherRunning && !isRecording) {if (pushType == 0 || pushType == 1) {CheckInitAudioRecorder();    //enable pure video publisher..}ConfigControlEnable(false);}btnEncodedDataCallback.setText("停止编码数据回调");isEncodedDatacallbackRunning = true;int audio_opt = 2;int video_opt = 2;publisherHandle2 = libPublisher.SmartPublisherOpen(myContext, audio_opt, video_opt,videoWidth, videoHeight);if (publisherHandle2 == 0) {Log.e(TAG, "sdk open failed!");return;}String relayUrl = "rtmp://player.daniulive.com:1935/hls/stream8888";libPublisher.SmartPublisherSetURL(publisherHandle2, relayUrl);libPublisher.SmartPublisherStartPublisher(publisherHandle2);}};
    //停止编码后数据回调private void stopEncodedDataCallback() {if(!isEncodedDatacallbackRunning){return;}if (!isPushing && !isRTSPPublisherRunning && !isRecording) {if (audioRecord_ != null) {Log.i(TAG, "stopRecorder, call audioRecord_.StopRecording..");audioRecord_.Stop();if (audioRecordCallback_ != null) {audioRecord_.RemoveCallback(audioRecordCallback_);audioRecordCallback_ = null;}audioRecord_ = null;}}if (libPublisher != null) {libPublisher.SmartPublisherStopOutputEncodedData(publisherHandle);}if (!isPushing && !isRTSPPublisherRunning && !isRecording) {if (publisherHandle != 0) {if (libPublisher != null) {libPublisher.SmartPublisherClose(publisherHandle);publisherHandle = 0;}}}}

此demo为了便于演示方便,另启动了个新的推送实例,音视频编码后的数据,通过新的实例,调用编码后的音视频数据接口,继续推RTMP出去。

此Demo的优越性在于,回调编码后的音视频数据功能,可与推RTMP、录像、内置RTSP服务SDK组合使用,亦可单独使用。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/553157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软的OneNote正在获得类似Win11风格的外观

由于主要功能几乎相同&#xff0c;究竟应该用OneNote还是OneNote for Windows 10来做笔记&#xff0c;可能会让人相当困惑。幸运的是&#xff0c;微软现在正计划将两个OneNote桌面客户端合并&#xff0c;通过为用户提供尽可能好的产品来简化这种情况。 微软的OneNote正在获得类…

Android播放器实现视频窗口实时放大缩小功能

很多开发者希望Android播放端实现视频窗口的放大缩小功能&#xff0c;为此&#xff0c;我们做了个简单的demo&#xff0c;通过播放端回调RGB数据&#xff0c;直接在上层view操作处理即可&#xff0c;Github&#xff1a;https://github.com/daniulive/SmarterStreaming 无视频无…

轻量级RTSP服务SDK

为满足内网无纸化/电子教室等内网超低延迟需求&#xff0c;避免让用户配置单独的服务器&#xff0c;大牛直播SDK在推送端发布了轻量级RTSP服务SDK&#xff1a; 简单来说&#xff0c;之前推送端SDK支持的功能&#xff0c;内置轻量级RTSP服务SDK后&#xff0c;功能继续支持。 一…

技术员联盟win11系统64位专业版镜像v2021.08

技术员联盟win11系统64位专业版镜像v2021.08以微软官方原版作为母盘对系统进行了全面优化更新&#xff0c;用户使用更加流畅顺手&#xff0c;轻松体验到系统的优秀性能&#xff0c;适用目前市场最新机型以及老旧机型&#xff0c;多种安装方式供用户选择&#xff0c;且更新时间短…

多路RTSP-RTMP转RTMP定制版

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

Win11系统无法安装GPT分区的解决方法

越来越多的人使用大容量硬盘&#xff0c;比如3T、4T容量硬盘&#xff0c;传统的MBR分区表不支持大容量硬盘&#xff0c;所以GPT分区格式就逐渐成为主流&#xff0c;尤其是现在UEFI主板非常普遍&#xff0c;很多人都选择用GPT分区安装Win11系统&#xff0c;那么该如何具体操作呢…

基于智慧教室|无纸化会议的新选择:RTMP解决方案

基于智慧教室或是会议的技术方案&#xff0c;一般主要是涉及到屏幕采集和推送&#xff0c;整体技术方案这块&#xff0c;一般建议走RTMP&#xff0c;说到这里&#xff0c;好人开发者提到&#xff0c;市面上也有RTSP的技术方案&#xff0c;甚至RTSP组播方案&#xff0c;这块&…

轻量级RTSP服务模块和RTSP推流模块适用场景区别

好多开发者一直搞不清轻量级RTSP服务SDK和RTSP推流SDK的区别&#xff08;Github下载地址&#xff09;&#xff0c;以下是相关区别&#xff1a; 1. 轻量级RTSP服务模块&#xff1a;轻量级RTSP服务解决的核心痛点是避免用户或者开发者单独部署RTSP或者RTMP服务&#xff0c;实现本…

钉钉怎么投屏到设备

钉钉想要使用投屏&#xff0c;该怎么使用呢?下面我们就来看看钉钉投屏的教程。 1、打开钉钉的聊天对话框&#xff0c;在右上角个人中心头像左边有三个按钮&#xff0c;点击中间的投屏按钮&#xff0c;根据系统提示来设置投屏选项。 钉钉怎么投屏到设备? 2、点击之后需要输…

如何实现多路海康大华等RTSP数据转RTMP推送

一个好的转发模块&#xff0c;首先要低延迟&#xff01;其次足够稳定、灵活、有状态反馈机制、资源占用低&#xff0c;跨平台&#xff0c;最好以接口形式提供&#xff0c;便于第三方系统集成。 以Windows平台为例&#xff0c;我们的考虑的点如下 1. 拉流&#xff1a;通过RTSP…

如何在RTSP/RTMP直播过程中加入SEI扩展数据发送和接收解析

在直播系统中&#xff0c;除了直播音视频之外&#xff0c;有时候还想从主播端发布文本信息等&#xff0c;这些信息可以不通过视频传输通道发送给用户播放端&#xff0c;但如果传输的数据想和视频保持精准同步&#xff0c;那最好的办法就是这些信息和视频数据打包在一起传输&…

网易邮箱大师如何添加Word附件 添加附件方法步骤详细介绍

网易邮箱大师是一款非常好用的邮箱软件&#xff0c;可同时管理包括网易的各大邮箱&#xff0c;界面简洁&#xff0c;非常好用&#xff0c;其中还有很多功能&#xff0c;比如添加附件等&#xff0c;但是很多小伙伴不知道怎么添加Word及其他附件&#xff0c;接下来看完这篇文章你…

RTSP播放器开发过程中需要考虑哪些关键因素

好多开发者&#xff0c;在自研或者选择市面上的播放器的时候&#xff0c;除了常规的播放功能&#xff0c;还有很多点值得关注&#xff0c;如延迟、资源占用、网络异常处理、多实例支持、长时间运行稳定性等。以下是我们开发直播播放器过程中&#xff0c;考虑的部分关键因素&…

如何拉取公网RTSP/RTMP流在内网多客户端播放

好多情况下&#xff0c;一路RTSP或RTMP网络流过来后&#xff0c;想共享给更多局域网内的客户端播放&#xff0c;一般来说&#xff0c;有两种设计方案&#xff1a; 1. 拉取的RTSP或RTMP流&#xff0c;回调后的数据&#xff0c;转推RTMP服务器&#xff0c;内网部署一台RTMP服务器…

爱链工具怎么使用 爱链工具详细使用图文教程

爱链工具是爱站seo软件独立推出的一款免费友链交换平台&#xff0c;也是目前互联网上最强外链交换平台&#xff0c;不但拥有丰富的友链资源&#xff0c;智能的链接匹配系统&#xff0c;全面的SEO基础数据等等&#xff0c;而且率先推出目录链接交换功能&#xff0c;可以大大提升…

如何在Unity3d平台下低延迟播放RTMP或RTSP流

随着VR类、工业仿真、智慧城市等场景的快速发展&#xff0c;开发者对Unity3d低延迟的直播需求量越来越大&#xff0c;前两年&#xff0c;大牛直播SDK发布了Windows平台、Android平台和iOS平台的Unity3d RTMP和RTSP的播放&#xff0c;好多公司用起来体验都非常好&#xff0c;以下…

轻量级RTSP服务存在的意义

为什么要设计轻量级RTSP服务 轻量级RTSP服务解决的核心痛点是避免用户或者开发者单独部署RTSP或者RTMP服务。 轻量级RTSP服务可满足内网无纸化/电子教室等内网超低延迟的低并发需求&#xff0c;避免让用户配置单独的服务器&#xff0c;大牛直播SDK在推送端发布了轻量级RTSP服…

foxmail邮件怎样打印日历

foxmail邮件中的日历有很多信息&#xff0c;想要打印日历&#xff0c;该怎么打印呢?我们点击日历信息。点击设置按钮&#xff0c;再点击打印按钮&#xff0c;先进行设置打印机&#xff0c;然后打印邮件的日历&#xff0c;下面我们就来看看详细的图文教程。 foxmail邮件怎样打…

Windows平台RTMP/RTSP直播推送模块设计和使用说明

开发背景 好多开发者一直反馈&#xff0c;Windows平台&#xff0c;做个推屏或者推摄像头&#xff0c;推RTMP或者RTSP出去&#xff0c;不知道哪些功能是必须的&#xff0c;哪些设计是可有可无的&#xff0c;还有就是&#xff0c;不知道如何选技术方案&#xff0c;以下是基于我们…

跨平台低延迟的RTMP/RTSP直播播放器设计实现

开发背景 2015年&#xff0c;当我们试图在市面上找一款专供直播播放使用的低延迟播放器&#xff0c;来配合测试我们的RTMP推送模块使用时&#xff0c;居然发现没有一款好用的&#xff0c;市面上的&#xff0c;如VLC或Vitamio&#xff0c;说白了都是基于FFMPEG&#xff0c;在点…