首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )

  • 25-02-16 05:21
  • 3048
  • 5613
blog.csdn.net

文章目录

  • 安卓直播推流专栏博客总结
  • 一、 x264 编码器参数设置引入
  • 二、 获取 x264 编码器参数
  • 三、 设置 x264 编码器编码规格
  • 四、 设置 x264 编码器编码图像数据格式
  • 五、 设置 x264 编码器 码率相关参数
  • 六、 设置 x264 编码器 帧率相关参数
  • 七、 设置 x264 编码器 编码帧相关参数
  • 八、 x264 编码器参数设置代码示例





安卓直播推流专栏博客总结



Android RTMP 直播推流技术专栏 :


0 . 资源和源码地址 :

  • 资源下载地址 : 资源下载地址 , 服务器搭建 , x264 , faac , RTMPDump , 源码及交叉编译库 , 本专栏 Android 直播推流源码 ;
  • GitHub 源码地址 : han1202012 / RTMP_Pusher

1. 搭建 RTMP 服务器 : 下面的博客中讲解了如何在 VMWare 虚拟机中搭建 RTMP 直播推流服务器 ;

  • 【Android RTMP】RTMP 直播推流服务器搭建 ( Ubuntu 18.04.4 虚拟机 )

2. 准备视频编码的 x264 编码器开源库 , 和 RTMP 数据包封装开源库 :

  • 【Android RTMP】RTMPDumb 源码导入 Android Studio ( 交叉编译 | 配置 CMakeList.txt 构建脚本 )

  • 【Android RTMP】Android Studio 集成 x264 开源库 ( Ubuntu 交叉编译 | Android Studio 导入函数库 )

3. 讲解 RTMP 数据包封装格式 :

  • 【Android RTMP】RTMP 数据格式 ( FLV 视频格式分析 | 文件头 Header 分析 | 标签 Tag 分析 | 视频标签 Tag 数据分析 )

  • 【Android RTMP】RTMP 数据格式 ( FLV 视频格式分析 | AVC 序列头格式解析 )

4. 图像数据采集 : 从 Camera 摄像头中采集 NV21 格式的图像数据 , 并预览该数据 ;

  • 【Android RTMP】Android Camera 视频数据采集预览 ( 视频采集相关概念 | 摄像头预览参数设置 | 摄像头预览数据回调接口 )

  • 【Android RTMP】Android Camera 视频数据采集预览 ( NV21 图像格式 | I420 图像格式 | NV21 与 I420 格式对比 | NV21 转 I420 算法 )

  • 【Android RTMP】Android Camera 视频数据采集预览 ( 图像传感器方向设置 | Camera 使用流程 | 动态权限申请 )

5. NV21 格式的图像数据编码成 H.264 格式的视频数据 :

  • 【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )

  • 【Android RTMP】x264 图像数据编码 ( Camera 图像数据采集 | NV21 图像数据传到 Native 处理 | JNI 传输字节数组 | 局部引用变量处理 | 线程互斥 )

  • 【Android RTMP】x264 图像数据编码 ( NV21 格式中的 YUV 数据排列 | Y 灰度数据拷贝 | U 色彩值数据拷贝 | V 饱和度数据拷贝 | 图像编码操作 )

6. 将 H.264 格式的视频数据封装到 RTMP 数据包中 :

  • 【Android RTMP】RTMPDump 封装 RTMPPacket 数据包 ( 封装 SPS / PPS 数据包 )

  • 【Android RTMP】RTMPDump 封装 RTMPPacket 数据包 ( 关键帧数据格式 | 非关键帧数据格式 | x264 编码后的数据处理 | 封装 H.264 视频数据帧 )

  • 【Android RTMP】RTMPDump 推流过程 ( 独立线程推流 | 创建推流器 | 初始化操作 | 设置推流地址 | 启用写出 | 连接 RTMP 服务器 | 发送 RTMP 数据包 )

7. 阶段总结 : 阿里云服务器中搭建 RTMP 服务器 , 并使用电脑软件推流和观看直播内容 ;

  • 【Android RTMP】RTMP 直播推流 ( 阿里云服务器购买 | 远程服务器控制 | 搭建 RTMP 服务器 | 服务器配置 | 推流软件配置 | 直播软件配置 | 推流直播效果展示 )

  • 【Android RTMP】RTMP 直播推流阶段总结 ( 服务器端搭建 | Android 手机端编码推流 | 电脑端观看直播 | 服务器状态查看 )

8. 处理 Camera 图像传感器导致的 NV21 格式图像旋转问题 :

  • 【Android RTMP】NV21 图像旋转处理 ( 问题描述 | 图像顺时针旋转 90 度方案 | YUV 图像旋转细节 | 手机屏幕旋转方向 )

  • 【Android RTMP】NV21 图像旋转处理 ( 图像旋转算法 | 后置摄像头顺时针旋转 90 度 | 前置摄像头顺时针旋转 90 度 )

9. 下面这篇博客比较重要 , 里面有一个快速搭建 RTMP 服务器的脚本 , 强烈建议使用 ;

  • 【Android RTMP】NV21 图像旋转处理 ( 快速搭建 RTMP 服务器 Shell 脚本 | 创建 RTMP 服务器镜像 | 浏览器观看直播 | 前置 / 后置摄像头图像旋转效果展示 )

10. 编码 AAC 音频数据的开源库 FAAC 交叉编译与 Android Studio 环境搭建 :

  • 【Android RTMP】音频数据采集编码 ( 音频数据采集编码 | AAC 高级音频编码 | FAAC 编码器 | Ubuntu 交叉编译 FAAC 编码器 )

  • 【Android RTMP】音频数据采集编码 ( FAAC 头文件与静态库拷贝到 AS | CMakeList.txt 配置 FAAC | AudioRecord 音频采样 PCM 格式 )

11. 解析 AAC 音频格式 :

  • 【Android RTMP】音频数据采集编码 ( AAC 音频格式解析 | FLV 音频数据标签解析 | AAC 音频数据标签头 | 音频解码配置信息 )

12 . 将麦克风采集的 PCM 音频采样编码成 AAC 格式音频 , 并封装到 RTMP 包中 , 推流到客户端 :

  • 【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )

  • 【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频解码信息 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )

  • 【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频采样数据 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )






Android 直播推流流程 : 手机采集视频 / 音频数据 , 视频数据使用 H.264 编码 , 音频数据使用 AAC 编码 , 最后将音视频数据都打包到 RTMP 数据包中 , 使用 RTMP 协议上传到 RTMP 服务器中 ;


Android 端中主要完成手机端采集视频数据操作 , 并将视频数据传递给 JNI , 在 NDK 中使用 x264 将图像转为 H.264 格式的视频 , 最后将 H.264 格式的视频打包到 RTMP 数据包中 , 上传到 RTMP 服务器中 ;


本篇博客中在 NDK 层使用 x264 对 Camera 采集到的数据进行编码 , 将 NV21 格式的视频数据编码为 H.264 格式的数据 , 首先要设置 x264 编码器的参数 ;





一、 x264 编码器参数设置引入



1 . 图像数据转换 : Camera 获取的是 NV21 格式的图像数据, 先将 NV21 格式的图像数据转为 I420 格式的图像数据 , 再将 I420 格式的图像数据编码为 H.264 格式的视频数据 ;


2 . 需要使用 x264 开源库 : 上述图像格式转换中 , I420 图像编码为 H.264 视频就需要使用 x264 开源库 , 这是目前性能最好的开源库 ;


3 . x264 编码器参数设置 : 使用 x264 编码 H.264 视频之前 , 首先要创建 x264 编码器 , 然后设置该编码器参数 ;


4 . 头文件导入 : 使用 x264 编码器之前 , 首先导入头文件 ;

#include 
  • 1

5 . x264 编码器参数 x264_param_t 类型 : 是一个结构体类型 ;

typedef struct x264_param_t
{
	//...
}
  • 1
  • 2
  • 3
  • 4




二、 获取 x264 编码器参数



1 . 获取 x264 编码器参数步骤 :


① 声明 x264 编码器参数 : 在栈内存中声明 x264 编码器参数 , 之后对其进行赋值 ;

// 设置 x264 编码器参数
x264_param_t x264Param;
  • 1
  • 2

② 获取默认的编码器参数 : 调用 x264_param_default_preset 方法 , 可以获取 x264 编码器默认的参数 ;

x264_param_default_preset(&x264Param, "ultrafast", "zerolatency");
  • 1


2 . 函数 x264_param_default_preset ( ) 解析 :


① 参数 x264_param_t * 设置 : x264_param_t 类型的 x264 编码器参数指针 , 即上面声明的 x264 编码器参数的地址 ;

② 参数 const char *preset 设置 : 设置编码速度 , 这里开发直播 , 需要尽快编码推流 , 这里设置最快的速度 ultrafast ;

static const char * const x264_preset_names[] = { "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 };
  • 1

③ 参数 const char *tune 设置 : 视频编码场景设置 , 这里选择 zerolatency 无延迟编码 , 同样要求最低延迟 ;

static const char * const x264_tune_names[] = { "film", "animation", "grain", "stillimage", "psnr", "ssim", "fastdecode", "zerolatency", 0 };
  • 1

④ 函数原型 :

int x264_param_default_preset( x264_param_t *, const char *preset, const char *tune );
  • 1

上述的最快编码速度 ultrafast , 和无延迟编码 zerolatency , 都要求编码速度要尽可能快 , 代价是牺牲了视频的质量 ;





三、 设置 x264 编码器编码规格



1 . 设置 x264 编码器编码规格 : 每个编码规格都有对应的性能指标要求 , 如下图的表格 , 设置的 32 编码规则表示其中的 3.2 级别的 H.264 参数性能 ;

// 编码规格设定, 32 对应的是 3.2 编码规格, 该规格下有指定的 码率, 帧率要求
x264Param.i_level_idc = 32;
  • 1
  • 2

2 . H.264 编码规格 :

在这里插入图片描述





四、 设置 x264 编码器编码图像数据格式



1 . 设置 x264 编码器编码图像数据格式 :


① 编码尺寸设置 : 将 Camera 支持的宽高尺寸 , 设置给该 x264 编码器参数的 i_width , i_height 字段 ;

② 可设置的输入图像格式 : 经过测试 , 只有 X264_CSP_I420 格式能顺利编码成 H.264 视频数据 ;

/* Colorspace type */
#define X264_CSP_MASK           0x00ff  /* */
#define X264_CSP_NONE           0x0000  /* Invalid mode     */
#define X264_CSP_I400           0x0001  /* monochrome 4:0:0 */
#define X264_CSP_I420           0x0002  /* yuv 4:2:0 planar */
#define X264_CSP_YV12           0x0003  /* yvu 4:2:0 planar */
#define X264_CSP_NV12           0x0004  /* yuv 4:2:0, with one y plane and one packed u+v */
#define X264_CSP_NV21           0x0005  /* yuv 4:2:0, with one y plane and one packed v+u */
#define X264_CSP_I422           0x0006  /* yuv 4:2:2 planar */
#define X264_CSP_YV16           0x0007  /* yvu 4:2:2 planar */
#define X264_CSP_NV16           0x0008  /* yuv 4:2:2, with one y plane and one packed u+v */
#define X264_CSP_YUYV           0x0009  /* yuyv 4:2:2 packed */
#define X264_CSP_UYVY           0x000a  /* uyvy 4:2:2 packed */
#define X264_CSP_V210           0x000b  /* 10-bit yuv 4:2:2 packed in 32 */
#define X264_CSP_I444           0x000c  /* yuv 4:4:4 planar */
#define X264_CSP_YV24           0x000d  /* yvu 4:4:4 planar */
#define X264_CSP_BGR            0x000e  /* packed bgr 24bits */
#define X264_CSP_BGRA           0x000f  /* packed bgr 32bits */
#define X264_CSP_RGB            0x0010  /* packed rgb 24bits */
#define X264_CSP_MAX            0x0011  /* end of list */
#define X264_CSP_VFLIP          0x1000  /* the csp is vertically flipped */
#define X264_CSP_HIGH_DEPTH     0x2000  /* the csp has a depth of 16 bits per pixel component */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2 . 设置 x264 编码器编码图像数据格式代码示例 :

// 设置输入到 x264 编码器的数据格式, 宽度, 高度等参数
x264Param.i_csp = X264_CSP_I420;
x264Param.i_width = mWidth;
x264Param.i_height = mHeight;
  • 1
  • 2
  • 3
  • 4




五、 设置 x264 编码器 码率相关参数



码率有三种模式 : X264_RC_CQP 恒定质量 , X264_RC_CRF 恒定码率 , X264_RC_ABR 平均码率 , 这里设置一个平均码率输出 ;

x264Param.rc.i_rc_method = X264_RC_ABR;
// 设置码率, 单位是 kbps
x264Param.rc.i_bitrate = bitrate / 1000;
// 设置最大码率, 单位 kbps, 该配置与 i_vbv_buffer_size 配套使用
x264Param.rc.i_vbv_max_bitrate = bitrate / 1000 * 1.2;
// 该配置与 i_vbv_max_bitrate 配置配套使用, 码率控制缓冲区大小
x264Param.rc.i_vbv_buffer_size = bitrate / 1000;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7




六、 设置 x264 编码器 帧率相关参数



设置 x264 编码器 帧率相关参数 : 设置帧率相关参数 , 帧率是个有理数 , 使用分数形式表示 , 这里分别定义分子和分母 ;

x264Param.i_fps_num = fps;  // 分子
x264Param.i_fps_den = 1;    // 分母
x264Param.i_timebase_den = x264Param.i_fps_num; //分子
x264Param.i_timebase_num = x264Param.i_fps_den; //分母
  • 1
  • 2
  • 3
  • 4




七、 设置 x264 编码器 编码帧相关参数



1 . 关键帧解码数据 : 关键帧及后面的帧如何解码 , 需要根据 SPS , PPS 数据进行解码 ;


2 . 关键帧间距 : 这里使用 fps 描述关键帧之间的间距 , 2 秒一个关键帧 ;



3 . B 帧个数 : B 帧解码时, 既要参考前面的帧, 又要参考后面的帧 ;


① B 帧存在的意义 : 减小视频流的大小 ;

② B 帧存在的弊端 : 增加解码时间 ;

③ 直播场景的选择 : 直播中实时性性能很重要 , 因此这里选择不编码 B 帧 , 直接将 B 帧个数设置为 0 ;



4 . 特殊场景考虑 : 当前开发需求是直播 , 用户可能在任意时间进入直播间 ;


① 解码数据 SPS / PPS : 如果关键帧后面没有自带解码数据 , 那么用户如果进入该直播间 , 将无法观看直播 , 建议关键帧携带 SPS / PPS 解码数据 ;

② 关键帧间距 : 如果关键帧间距太长 , 用户在关键帧空档期间进入直播间 , 那么需要等到下一个关键帧到来 , 才能观看直播 , 建议将帧间距设置在 10 秒以内 ;

/*
   关键帧数据 I 是否附带 SPS PPS 数据
   编码后, 会输出图像编码后的数据
   第一个图像数据输入到 x264 编码器后, 进行编码
   编码的第一个图像编码出来的数据 肯定是 SPS PPS 关键帧 三种数据
   SPS PPS 作用是告知后续如何解码视频中的图像数据
   第二个图像数据输入到 x264 编码器后, 进行编码
   编码的第二个图像编码出来的数据 是 P 帧
   后续 n 个图像编码出 n 个 P 帧
   第 n + 3 个图像又编码出一个关键帧 I
   任何一个画面都可以编码成关键帧
   直播时建议设置成 1
   因为中途会有新用户加入, 此时该用户的播放器必须拿到 SPS PPS 才能解码画面
   否则无法观看视频
   如果设置成 0, 那么就需要开发者自己维护 SPS PPS 数据
   保证后来的用户可以看到直播画面
 */
x264Param.b_repeat_headers = 1;
// 计算帧间距的依据, 该设置表示使用 fps 帧率计算帧间距
// 两帧之间间隔多少 fps
// 也可以使用时间戳计算帧间距
x264Param.b_vfr_input = 0;
/*
   关键帧的间距, 两个关键帧之间的距离
   fps 表示 1 秒钟画面帧的数量, fps * 2 表示 2 秒钟的帧数
   该设置表示每隔 2 秒, 采集一个关键帧数据
   关键帧间隔时间不能太长
   关键帧间隔不能设置太长, 如设置 10 秒
   当用户1观看直播时, 不影响观看
   当用户2进入房间, 此时刚过去一个关键帧, 10秒内没有关键帧
   该用户需要等待 10 秒后收到关键帧数据后, 才有画面显示出来
 */
x264Param.i_keyint_max = fps * 2;
// 设置 B 帧个数, 这里设置没有 B 帧, 只有 I 帧和 P 帧
// B 帧解码时, 既要参考前面的帧, 又要参考后面的帧
// B 帧能减少传输的数据量, 但同时降低了解码速度, 直播中解码速度必须要快
x264Param.i_bframe = 0;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37




八、 x264 编码器参数设置代码示例



x264 编码器参数设置代码示例 :

    // 设置 x264 编码器参数
    x264_param_t x264Param;

    /*
     * 获取 x264 编码器参数
     * int x264_param_default_preset( x264_param_t *, const char *preset, const char *tune )
     * 参数一 : x264_param_t * : x264 编码参数指针
     *
     * 参数二 : const char *preset : 设置编码速度, 这里开发直播, 需要尽快编码推流,
     * 这里设置最快的速度 ultrafast, 字符串常量, 值从 下面的参数中选择 ;
     * static const char * const x264_preset_names[] = { "ultrafast", "superfast", "veryfast",
     * "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 };
     *
     * 参数三 : const char *tune : 视频编码场景设置, 这里选择 zerolatency 无延迟编码
     * static const char * const x264_tune_names[] = { "film", "animation", "grain",
     * "stillimage", "psnr", "ssim", "fastdecode", "zerolatency", 0 };
     *
     * 编码速度快, 意味着牺牲了画面的质量
     */
    x264_param_default_preset(&x264Param, "ultrafast", "zerolatency");

    // 编码规格设定, 32 对应的是 3.2 编码规格, 该规格下有指定的 码率, 帧率要求
    // 参考 https://www.wanweibaike.com/wiki-H.264 中的最大性能级别
    x264Param.i_level_idc = 32;

    // 设置输入到 x264 编码器的数据格式, 宽度, 高度等参数
    x264Param.i_csp = X264_CSP_I420;
    x264Param.i_width = mWidth;
    x264Param.i_height = mHeight;

    /*
       设置码率相关参数
       码率有三种模式 : X264_RC_CQP 恒定质量, X264_RC_CRF 恒定码率, X264_RC_ABR 平均码率
       这里设置一个平均码率输出
     */
    x264Param.rc.i_rc_method = X264_RC_ABR;
    // 设置码率, 单位是 kbps
    x264Param.rc.i_bitrate = bitrate / 1000;
    // 设置最大码率, 单位 kbps, 该配置与 i_vbv_buffer_size 配套使用
    x264Param.rc.i_vbv_max_bitrate = bitrate / 1000 * 1.2;
    // 该配置与 i_vbv_max_bitrate 配置配套使用, 码率控制缓冲区大小
    x264Param.rc.i_vbv_buffer_size = bitrate / 1000;

    // 设置帧率相关参数, 帧率是个有理数, 使用分数形式表示
    x264Param.i_fps_num = fps;  // 分子
    x264Param.i_fps_den = 1;    // 分母
    x264Param.i_timebase_den = x264Param.i_fps_num; //分子
    x264Param.i_timebase_num = x264Param.i_fps_den; //分母


    // 下面是关于帧的先关设置

    /*
       关键帧数据 I 是否附带 SPS PPS 数据
       编码后, 会输出图像编码后的数据

       第一个图像数据输入到 x264 编码器后, 进行编码
       编码的第一个图像编码出来的数据 肯定是 SPS PPS 关键帧 三种数据
       SPS PPS 作用是告知后续如何解码视频中的图像数据

       第二个图像数据输入到 x264 编码器后, 进行编码
       编码的第二个图像编码出来的数据 是 P 帧

       后续 n 个图像编码出 n 个 P 帧

       第 n + 3 个图像又编码出一个关键帧 I

       任何一个画面都可以编码成关键帧

       直播时建议设置成 1
       因为中途会有新用户加入, 此时该用户的播放器必须拿到 SPS PPS 才能解码画面
       否则无法观看视频
       如果设置成 0, 那么就需要开发者自己维护 SPS PPS 数据
       保证后来的用户可以看到直播画面
     */
    x264Param.b_repeat_headers = 1;

    // 计算帧间距的依据, 该设置表示使用 fps 帧率计算帧间距
    // 两帧之间间隔多少 fps
    // 也可以使用时间戳计算帧间距
    x264Param.b_vfr_input = 0;

    /*
       关键帧的间距, 两个关键帧之间的距离
       fps 表示 1 秒钟画面帧的数量, fps * 2 表示 2 秒钟的帧数
       该设置表示每隔 2 秒, 采集一个关键帧数据

       关键帧间隔时间不能太长

       关键帧间隔不能设置太长, 如设置 10 秒
       当用户1观看直播时, 不影响观看
       当用户2进入房间, 此时刚过去一个关键帧, 10秒内没有关键帧
       该用户需要等待 10 秒后收到关键帧数据后, 才有画面显示出来
     */
    x264Param.i_keyint_max = fps * 2;

    // 设置 B 帧个数, 这里设置没有 B 帧, 只有 I 帧和 P 帧
    // B 帧解码时, 既要参考前面的帧, 又要参考后面的帧
    // B 帧能减少传输的数据量, 但同时降低了解码速度, 直播中解码速度必须要快
    x264Param.i_bframe = 0;

    // 是否开启多线程
    x264Param.i_threads = 1;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
注:本文转载自blog.csdn.net的韩曙亮的文章"https://hanshuliang.blog.csdn.net/article/details/106713072"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top