Android平台如何实现外部编码后(H.264/H.265)数据实时预览播放

news2024/11/13 19:17:40

技术背景

我们在对接开发者的时候,遇到这样的诉求:除了正常的RTMP、RTSP直播播放外,有些硬件设备输出编码后(H.264/H.265)的数据,比如无人机或类似硬件产品,回调出来的H.264/H.265数据,除了正常转推到RTMP、轻量级RTSP服务或GB28181外,还需要本地预览甚至重新对数据做二次处理,基于这样的场景诉求,我们开发了外部编码后数据实时预览播放模块。

接口设计

废话不多说,外部H.264/H.265投递接口设计如下:

	// SmartPlayerJniV2.java
    // Author: daniusdk.com
    /**
	 * 投递视频包给外部Live Source
	 *
	 * @param codec_id: 编码id, 当前仅支持H264和H265, 1:H264, 2:H265
	 *
	 * @param packet: 视频数据, ByteBuffer必须是DirectBuffer, 包格式请参考H264/H265 Annex B Byte stream format, 例如:
	 *                0x00000001 nal_unit 0x00000001 ...
	 *                H264 IDR: 0x00000001 sps 0x00000001 pps 0x00000001 IDR_nal_unit .... 或 0x00000001 IDR_nal_unit ....
	 *                H265 IDR: 0x00000001 vps 0x00000001 sps 0x00000001 pps 0x00000001 IDR_nal_unit .... 或 0x00000001 IDR_nal_unit ....
	 *
	 * @param offset: 偏移量
	 * @param size: packet size
	 * @param timestamp_ms: 时间戳, 单位毫秒
	 * @param is_timestamp_discontinuity: 是否时间戳间断,0:未间断,1:间断
	 * @param is_key: 是否是关键帧, 0:非关键帧, 1:关键帧
	 * @param extra_data: 可选参数,可传null, 对于H264关键帧包, 如果packet不含sps和pps, 可传0x00000001 sps 0x00000001 pps
	 *                    ,对于H265关键帧包, 如果packet不含vps,sps和pps, 可传0x00000001 vps 0x00000001 sps 0x00000001 pps
	 * @param extra_data_size: extra_data size
	 * @param width: 图像宽, 可传0
	 * @param height: 图像高, 可传0
	 *
	 * @return {0} if successful
	 */
	public native int PostVideoPacketByteBuffer(long handle, int codec_id,
									  java.nio.ByteBuffer packet, int offset, int size, long timestamp_ms, int is_timestamp_discontinuity, int is_key,
									  byte[] extra_data, int extra_data_size, int width, int height);


	/*
	* 请参考 PostVideoPacketByteBuffer说明
	 */
	public native int PostVideoPacketByteArray(long handle, int codec_id,
												byte[] packet, int offset, int size, long timestamp_ms, int is_timestamp_discontinuity, int is_key,
												byte[] extra_data, int extra_data_size, int width, int height);

PostVideoPacketByteBuffer()和PostVideoPacketByteArray()接口设计基本类似,唯一的区别在于,一个数据类型是ByteBuffer,一个是byte数组。

其中codec_id,系编码id,目前仅支持H.264和H.265类型。

 packet视频数据,需要注意的是,ByteBuffer必须是DirectBuffer, 包格式请参考H264/H265 Annex B Byte stream format, 例如:

0x00000001 nal_unit 0x00000001 ...
H264 IDR: 0x00000001 sps 0x00000001 pps 0x00000001 IDR_nal_unit .... 或 0x00000001 IDR_nal_unit ....
H265 IDR: 0x00000001 vps 0x00000001 sps 0x00000001 pps 0x00000001 IDR_nal_unit .... 或 0x00000001 IDR_nal_unit ....

extra_data: 可选参数,可传null, 对于H264关键帧包,如果packet不含sps和pps,可传0x00000001 sps 0x00000001 pps,对于H265关键帧包,如果packet不含vps,sps和pps, 可传0x00000001 vps 0x00000001 sps 0x00000001 pps

调用逻辑

下面我们看看逻辑调用,本文基于大牛直播SDK的RTSP|RTMP转RTMP推送demo做展示,先拉取到RTSP或RTMP的流数据,然后把拉取到的H.264/H.265数据回调上来,调用我们外部live source数据接口,投递到底层,实现实时数据的播放,如果外部数据,可以忽略拉流这块,直接在数据回调的地方,调live source数据投递接口即可。

数据投递:

		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 +
			//		",presentation_timestamp:" + presentation_timestamp);

			if ( video_buffer_ == null)
				return;

			video_buffer_.rewind();

			if (0 == ret && ex_live_src_player_handle_ !=0) {
				libPlayer.PostVideoPacketByteBuffer(ex_live_src_player_handle_, video_codec_id, video_buffer_, 0, sample_size, timestamp, 0, is_key_frame, null,0, 0, 0);
			}

		}

 启动外部数据播放:

可以看到,外部数据可以用软解码或硬解码播放,如果分辨率很大可以考虑特定机型硬解码,外部数据播放,依然可以设置铺满或按比例显示。如果需要针对数据做二次处理,也可以把设置RGB或YUV数据回调,对回调后的数据做二次处理,甚至二次编码(如做视频分析、实时水印等)。

	private long start_ex_live_src_player(SmartPlayerJniV2 lib_player, Context context, SurfaceView surface_view, boolean is_hardware_decoder) {
		if (null ==lib_player || null == context || null == surface_view)
			return 0;

		long handle = lib_player.SmartPlayerOpen(context);
		if (0 == handle) {
			Log.e(TAG, "start_ex_live_src_player open player failed");
			return 0;
		}

		// 设置0, 尽可能降低预览延时
		lib_player.SmartPlayerSetBuffer(handle, 0);

		lib_player.SmartPlayerSetUrl(handle, "ntexternal://livesource/implemention0");

		lib_player.SmartPlayerSetSurface(handle, surface_view);

		// 图像等比例缩放或铺满view
		lib_player.SmartPlayerSetRenderScaleMode(handle, 1);

		lib_player.SmartPlayerSetFastStartup(handle, 1);

		// 不要播放音频,静音就好
		lib_player.SmartPlayerSetMute(handle, 1);

		// 大分辨率可能需要硬解,小分辨率推荐软解,硬解延时可能大些
		if (is_hardware_decoder) {
			lib_player.SetSmartPlayerVideoHevcHWDecoder(handle, 1);
			lib_player.SetSmartPlayerVideoHWDecoder(handle, 1);
		}

		// 有些场景可能需要解码出来的图像用来做分析或重新编码
		// 这里可以设置yuv或rgb callback, 把图像给Caller
		// lib_player.SmartPlayerSetExternalRender(handle, new RGBAExternalRender());
		// lib_player.SmartPlayerSetExternalRender(handle, new I420ExternalRender());

		if (0 == lib_player.SmartPlayerStartPlay(handle))
			return handle;

		lib_player.SmartPlayerClose(handle);

		return 0;
	}

停止外部数据播放:

	private void stop_ex_live_src_play(SmartPlayerJniV2 lib_player, long handle) {
		if (null == lib_player)
			return;

		if (0 == handle)
			return;

		lib_player.SmartPlayerStopPlay(handle);
		lib_player.SmartPlayerClose(handle);
	}

总结

Android平台外部编码后H.264/H.265数据实时预览播放,在一些传统行业里面,可以说是意义非常大,除了可以预览回调过来的数据外,还可以针对外部数据做二次视频分析、二次编辑投递(实时水印、字符叠加等),感兴趣的开发者可以试试看。

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

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

相关文章

C#中的委托是什么

https://www.cnblogs.com/deepalley/p/12150931.html 1.什么是委托?(方法作另一个方法的参数) delegate void MyDel(int value); //声明委托类型 和类一样,委托是用户自定义的类型,但是类是数据和方法的集合&#…

vue实现功能完整的购物商城,商品零食、电商通用商城

目录 一、项目结构 1.项目截图 2.项目简介 3.项目布局 二、首页 1.效果图 2.源码 三、商品详情 1.效果图 2.源码 四、分类 1.效果图 五、购物车、提交订单 1.效果图 六、个人中心 1.源码结构 2、效果图 七、总结 一、项目结构 1.项目截图 2.项目简介 项目基于vue…

海睿思分享 | 一文读懂企业数据资产目录建设的重要性

小王是某公司信息化部门负责人。 某天,公司领导需要获取近三年来生产部门的人员信息全面数据,小王费了九牛二虎之力,召开了各种会议,在各个系统里来回找数据,最终找到了这些数据。然而领导所需的人员职称、人员获奖信…

UOS服务器系统配置bond

一、Bond介绍 bond可以将多个网卡绑定到一起,可以让两个或多个接口作为一个接口,同时提高带宽,并提供网络链路的冗余,当有其中一块网卡故障的时候,不会中断服务器的业务。 二、Bond模式 1、mode0(balanc…

老杨说运维 | 运维数智化转型正确打开方式是什么?他这样说

2023年5月9日,中国计算机用户协会信息科技审计分会会员大会暨金融科技风险管理与审计论坛成功于北京召开。擎创科技CEO杨辰受邀与会,并分享了在数智运维发展过程中对企业数智化转型建设的规划思考以及相关实践经验。 同时,年会上举行了“金融…

《基础知识》提示学习的基本知识

《基础知识》提示学习的基本知识 提示学习背景提示的形式和元素提示学习的输入形式提示学习的重要元素提示学习的输入形式举例基本提示任务提示学习 内容参考:打工人转型之道(二):提示工程(Prompt Engineering)进阶篇

【服务器】利用树莓派搭建 web 服务器【无需公网IP】

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员,2024届电子信息研究生 目录 概述 使用 Raspberry Pi Imager 安装 Raspberry Pi OS 设置 Apache Web 服务器 测试 web 站点 安装静态样例站点 将web站点发布到公网 安装 Cpolar内网穿透 cpolar进行tok…

基于 FPGA 的彩色图像灰度化的设计实现(image_stitche_x)

文章目录 前言一、图像合并模块的设计二、仿真文件 前言 image_stitche_x 模块:将串口接收的尺寸为 400480 大小的彩色图像与灰度化处理后的 400480 大小的图像数据以左右形式合并成一张 800*480 的图像。 提示:以下是本篇文章正文内容,下面…

AI再度升级,IT业一片哀鸿遍野:程序员真的要失业了吗?

IT人员真的要失业了吗? 随着各个大厂已经相继传来裁员,降薪,减招的消息和ChatGPT等大型AI模型可以定制化写参考代码,甚至通过外接API直接帮助操作,IT人员似乎越来越不吃香了。 其实,ChatGPT有用的不是取代…

Diango学习-用户管理系统(简单部门管理、用户管理)

目录 1、创建项目和app 1.创建项目 2.创建app 2种创建方式 注册app 2、表结构的创建 Django中的模型字段有很多种,包括但不限于: 设计表结构(Django) 在models.py文件中创建表:部门表和员工表 加入性别列&…

FL Studio21.0.3.3517完整试用版

系统要求 FL STUDIO 可以运行在任何计算机上: 支持 WINDOWS: 7, 8, 10 或者更高版本 支持 MacOS: 10.11 或更高版本 不低于 4GB 的可用硬盘空间 建议最低 4GB 内存或 更高 当然CPU 越强大,也就意味着你运行的音源和效果器越多! FL Studio是一个非常受欢迎的数…

轻松实现远程访问本地wamp服务器,无公网IP也不怕,「内网穿透」

目录 前言 1.Wamp服务器搭建 1.1 Wamp下载和安装 1.2 Wamp网页测试 2. Cpolar内网穿透的安装和注册 2.1 本地网页发布 2.2 Cpolar云端设置 2.3 Cpolar本地设置 3. 公网访问测试 4. 结语 转载自cpolar极点云的文章:无公网IP?教你在外远程访问本地…

新零售发展现状剖析

“新零售”的商业生态将涵盖网络页面、实体店面、支付终端、数据系统、物流平台和营销路径等诸多方面。 企业通过使用大数据和人工智能等先进技术升级产品的生产、流通和销售流程,重塑商业结构与生态圈,深度融合线上服务、线下体验和现代物流。将物流、…

Devexpress GridControl 内部调用外面实现的FocusedRowChanged

个人需求是网格自带的条件发生改变时(网格显示的内容会发生改变),同时需要刷新另一个网格的数据源,而另一个网格的数据源是走的这个网格的行焦点改变事件去刷新,自带的条件发生改变时并不会触发行焦点的改变 当前情况…

【HTTP协议】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 1. HTTP协议概述 2. HTTP协议的工作过程 3.…

LabVIEWCompactRIO 开发指南21 使用TCP/IP时处理孤立套接字

LabVIEWCompactRIO 开发指南21 使用TCP/IP时处理孤立套接字 无法重新建立侦听TCP套接字是设计基于TCP/IP的应用程序时最常见的挑战之一。此症状是由终止客户端或服务器应用程序后发生的孤立套接字引起的。如果按照本节中所述的技术设计代码,则可以避免此问题。本节…

大数据拥抱云原生 HashData助力资管数字化转型

5月16日,2023国际资管科技创业者与投资者大会“资管数据处理(大模型)技术”专场在上海举行。本次大会以“资产管理 数智技术”为主题,邀请企业、高校、投资机构等各方开展产业交流与讨论,共享共创行业机遇。 酷克数据…

GPT-5: 超越人类语言的模型,你还不了解一下?

目录 一、GPT-5时代引领者 二、技术特性 1,音频和视频处理 — 更强大的多模态处理能力 2,GPT-5颠覆影视制作:重写媒体消费时代 3,为机器人提供智慧大脑 4,更强的垂直行业应用 三、回顾一下GPT5被紧急叫停&…

设计模式之【命令模式】,方法调用的花式玩法

文章目录 一、什么是命令模式1、命令模式使用场景2、命令模式的主要角色3、命令模式优缺点4、命令模式注意事项及细节 二、使用示例1、命令模式的一般写法2、播放器功能案例3、遥控器案例 三、源码中的命令模式1、Thread 一、什么是命令模式 命令模式(Command Patt…

图像分割标注工具——QuPath使用说明

0、QuPath资源一览 QuPath是一款病理学和生物图像定量分析的软件,支持多种标注方式。一些常用资源如下: 官网:QuPath 官方文档:https://qupath.readthedocs.io/en/stable/docs/intro/index.html 软件下载列表:http…