安卓播放H264/H265实时流(安卓实时预览H264/H265 安卓实时预览AVC/HEVC)

这篇具有很好参考价值的文章主要介绍了安卓播放H264/H265实时流(安卓实时预览H264/H265 安卓实时预览AVC/HEVC)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

   实际项目中经常遇到两种场景,第一种从无人机拿H264/H265码流转GB28181等协议,转协议的同时可能还需要实时预览无人机画面; 第二种是安卓接USB外置摄像头, 由于USB2.0传输带宽有限,对于高分辨率图像, 带宽无法满足YUV图像的传输, 摄像头只好先将图像编码成MJPEG,H264或H265等格式再传输。

   对于上述两种场景,安卓拿到的都是已编码的H264或H265码流,这用来转GB28181、RTSP、RTMP和录像存储很方便, 但没法直接实时预览, 实时预览需要先解码,再显示. 这样增加了不少开发成本,为了方便使用, 在我的播放器上直接增加了传H264/H265字节流接口,只要把H264/H265数据传给播放器就好,播放器负责解码(软解或硬解)显示。

  下面先介绍下H264/H265 Annex B Byte stream format:

  字节流格式:字节流由1到多个字节流nal_unit组成.

  字节流nal_unit:{前缀码(0x000001) + nal_unit} 或 {zero_byte(0x00) + 前缀码(0x000001) + nal_unit}. 前缀码为网络字节序.

  需要注意的是: 1.字节流中第一个字节流nal_unit头部可能包含1个或多个leading_zero_8bits(某些安卓硬编码器会出这样的数据); 2.字节流nal_unit单元尾部可能包含一个或多个trailing_zero_8bits.(前后额外加0字节是为了保持字节对齐).

  leading_zero_8bits:  一个0x00字节.

  trailing_zero_8bits: 一个0x00字节.

  对于VPS, SPS, PPS前缀应是 0x00000001(H264只有SPS, PPS), An access unit的第一个nal unit的前缀应是0x00000001.

  字节流NAL单元语法(H264和H265是一致的):

android h264,Android AVC预览,Android HEVC预览,安卓H264实时预览,安卓H265实时预览,安卓播放H265

    H264 NAL unit 语法:

android h264,Android AVC预览,Android HEVC预览,安卓H264实时预览,安卓H265实时预览,安卓播放H265

    常用的h264 nal_unit_type: 5(IDR), 6(SEI), 7(SPS), 8(PPS).

    H265 NAL unit 语法:

android h264,Android AVC预览,Android HEVC预览,安卓H264实时预览,安卓H265实时预览,安卓播放H265 android h264,Android AVC预览,Android HEVC预览,安卓H264实时预览,安卓H265实时预览,安卓播放H265

   H265的nal_unit_type请参考265文档。

   更详细的描述请参考264和265文档,对于如何调用播放器接口,上面的描述基本够用了,播放器接口如下:

/*
* Copyright (C) 1130758427@qq.com. All rights reserved.
*/

/**
	 * 投递视频包给播放器
	 *
	 * @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);

调用代码:

/*
* Copyright (C) 1130758427@qq.com. All rights reserved.
*/


// 启动播放器
 private long start_play(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, "open player failed");
            return 0;
        }

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

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

        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_play(SmartPlayerJniV2 lib_player, long handle) {
        if (null == lib_player)
            return;

        if (0 == handle)
            return;

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

// 投递H264或H265数据给播放器
public void onVideoDataCallback(int ret, int video_codec_id, int size, int is_key_frame, long timestamp, int width, int height, long presentation_timestamp) {
  if (player_handle_ !=0)
    lib_player_.PostVideoPacketByteBuffer(player_handle_, video_codec_id, video_buffer_, 0, size, timestamp, 0, is_key_frame, null,0, 0, 0);
				
}

   Android也可以用MediaCodec直接解码显示,但MediaCodec坑较多,从一个演示版到稳定版周期较长成本较高,直接在现有成熟稳定的播放器SDK上加接口实现AVC/HEVC实时预览更可行些. 我在Windows上启动一个内置rtsp server流, 安卓拉rtsp流,然后将H264/H265传给播放器显示,延时非常低(毫秒级),并支持H264和H265码流实时切换预览,分辨率实时切换预览,  也支持解码后YUV/RGB数据回调,  实时截图等功能。另外苹果的VideoToolbox只支持AVCC格式,不支持Annex B格式,需要转换后再输入,更多问题联系qq: 1130758427文章来源地址https://www.toymoban.com/news/detail-609100.html

到了这里,关于安卓播放H264/H265实时流(安卓实时预览H264/H265 安卓实时预览AVC/HEVC)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RK3318 android12 HEVC-1080P 4K VP9等格式视频播放不了

    同样视频在同样硬件在android10的固件刷机测试播放正常 在android12播放失败,在媒体中心点开视频直接闪退了 在android10 能播放4K视频, 我对比了ddr频率  cat /d/clk/clk_summary | grep ddr android10 clk_ddrmon 0 0 0 24000000 0 0 50000 pclk_ddr 3 3 0 61440000 0 0 50000 pclk_ddr_grf 1 1 0 61440000 0 0 50000 pclk_d

    2024年02月07日
    浏览(44)
  • 基于rk3568 Android H265推流SRS低延迟网页播放方案

           在音视频领域,融合推流,低码流,低延迟,浏览器H5化是一个降低成本,提升用户体验的重要手段。同时适配现有直播的生态也是一个必要条件。       在满足上述要求的情况下,我做了以下实践,取得了良好的效果。      在实践中,我们选择采用了成熟的rtmp做

    2024年02月01日
    浏览(52)
  • 基于WebAssembly无插件解码H264/H265码流播放器

    基于WebAssembly无插件解码H264/H265码流播放器 之前看到一篇文章:web无插件解码播放H264/H265(WebAssembly解码HTML5播放) H.265/HEVC在Web视频播放的实践 按照文章思路,已经复现了web端无插件解码H265码流。首先说明下我这边的环境,框架。 在海思主板上移植了web服务器nginx,用于pc端请

    2024年01月16日
    浏览(47)
  • vue中使用EasyPlayer播放监控视频HLS,H265、H264

    1.使用npm下载依赖 2.将EasyPlayer-lib.min.js文件、EasyPlayer.wasm文件、libDecoder.wasm文件放置到public下 3.创建components,html代码如下 4.使用props接收数据 5.在父组件中引入,传递props中的数据即可运行即可

    2024年02月03日
    浏览(46)
  • c++高性能264/265实时h5流媒体服务器前后端整体解决方案

    c++高性能264/265实时h5流媒体服务器前后端整体解决方案 下图展示了前端播放效果。 播放1路264视频流,4路265视频流 CPU占用率10%(测试机器上运行着c++服务端和其他工具程序) GPU0占用率17% 1.1 作者测试机器配置 处理器 11th Gen Intel® Core™ i7-11800H @ 2.30GHz 2.30 GHz 机带 RAM 32.0 GB (31.

    2024年02月12日
    浏览(48)
  • Android MediaCodec将h264实时视频流数据解码为yuv,并转换yuv的颜色格式为nv21

    初始化mediacodec 处理数据,解码h264数据为yuv格式 这里传入的是h264格式的实时视频流数据。 处理获取到的nv21颜色格式的yuv数据  yuv视频数据颜色格式转换 h264实时视频流的数据来源 写入h264视频流到sdcard中 rtsp获取h264实时视频流数据  编写C代码加载ffmpeg库 源码地址 https://gi

    2024年01月17日
    浏览(62)
  • Android 修改 SELinux avc 权限的方法

    系统版本:Android 11.0     平         台:RK3568 在 Android 系统的开发及适配过程中,我们常常需要对 SELinux avc  权限进行修改,以下是我对 SELinux avc  权限修改总结的方法。 一、验证功能是否存在 selinux 权限问题 #进入Android终端 adb shell #获取root权限 su #查看系统当前 s

    2024年02月09日
    浏览(38)
  • Unity 安卓(Android)端AVProVideo插件播放不了视频,屏幕一闪一闪的

    编辑器运行没有问题,但是安卓就有问题,在平板上运行就会报错: vulkan graphics API is notsupported 说不支持Vulkan图形API,解决方法:把Vulkan删除掉

    2024年02月09日
    浏览(36)
  • C++版Android实时投屏软件系统源码,安卓手机投屏软件源码,无需root权限

    QtScrcpy 可以通过 USB / 网络连接Android设备,并进行显示和控制。无需root权限。 同时支持 GNU/Linux ,Windows 和 MacOS 三大主流桌面平台。 完整代码下载地址:C++版Android实时投屏软件系统源码 它专注于: 精致 (仅显示设备屏幕) 性能 (30~60fps) 质量 (1920×1080以上) 低延迟 (35~70ms) 快速启

    2024年02月05日
    浏览(50)
  • HEVC(H.265)视频压缩编码格式与其原理

    本人最近开始研究视频重编码的检测,因此做个笔记记录一下自己学习的视频编码相关知识。视频编码的目的是为了压缩原始视频,压缩的主要思路是从空间、时间、编码、视觉等几个主要角度去除冗余信息。而H.265(HEVC)则是目前常用的视频压缩编码格式,本文将主要介绍其

    2024年02月05日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包