当前位置: 首页 > news >正文

FFmpeg第三话:FFmpeg 视频解码详解

FFmpeg 探索之旅

一、FFmpeg 简介与环境搭建
二、FFmpeg 主要结构体剖析
三、FFmpeg 视频解码详解


FFmpeg第三话:FFmpeg 视频解码详解

  • FFmpeg 探索之旅
  • 前言
    • 一、视频解码基础
    • 二、FFmpeg 关键 API 深度剖析
      • (一)avformat_open_input()
      • (二)avformat_find_stream_info()
      • (三)avcodec_find_decoder()
      • (四)avcodec_alloc_context3() 与 avcodec_parameters_to_context()
      • (五)avcodec_open2()
      • (六)av_read_frame() 与解码循环(含 avcodec_send_packet()、avcodec_receive_frame())
    • 四、实战案例全流程解析
  • 总结


前言

  在多媒体技术蓬勃发展的当下,视频处理已然成为众多领域不可或缺的关键环节。而 FFmpeg,这款开源、跨平台且功能强大到近乎“神器”级别的音视频处理库,始终站在行业的前沿,为视频解码、编码、转码、滤镜处理等一系列复杂操作提供坚实的技术支撑。今天,就让我们一同深入探寻 FFmpeg 视频解码的核心世界,从基础概念到实际代码,彻底揭开它神秘的面纱。


一、视频解码基础

视频解码本质:

  视频在存储与传输过程中,为削减数据量、节省带宽以及提升存储效率,会借助如 H.264、H.265、AV1 等先进编码标准进行高强度压缩。视频解码,恰似一场逆向的精密工程,旨在将这些压缩后的数据依照特定算法与规则,逐步还原为可供显示设备直接呈现或后续深度处理的原始视频帧序列,这些帧通常采用 YUV 或 RGB 色彩空间格式,每帧都蕴含着丰富的像素信息,精准勾勒出画面的每一处细节。

  例如,H.264 编码巧妙运用帧间预测、帧内预测、变换编码及熵编码等复杂技术,去除画面中的冗余信息,仅保留关键数据;解码时,则需依据编码规则,反向推算出每个像素的原始取值,涉及运动补偿以还原帧间动态变化、熵解码恢复原始数据分布等关键步骤,确保画面流畅、清晰地重现。

二、FFmpeg 关键 API 深度剖析

(一)avformat_open_input()

  此 API 作为开启视频解码之旅的首道大门,肩负着至关重要的使命。它接受一个 AVFormatContext 结构体指针的地址作为参数,旨在精准打开指定路径的视频文件,并深度剖析文件头信息,从而精准判定视频流的封装格式,诸如常见的 MP4、AVI、MKV 等,抑或是新兴的网络流封装格式。成功调用后,AVFormatContext 结构体将宛如一位信息渊博的向导,装满视频文件的基础元数据,涵盖文件时长、码率、各路音视频流数量及基本特性等关键情报,为后续解码流程铺就坚实基石。

  示例代码:

#include <libavformat\avformat.h>
#include <stdio.h>int main()
{AVFormatContext* fmt_ctx = NULL;// 指定输入文件的路径const char* input_file_name = "input_video.mp4";// 打开输入文件int ret = avformat_open_input(&fmt_ctx, input_file_name, NULL, NULL);if (ret < 0) {// 如果打开失败,打印错误信息char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);fprintf(stderr, "Unable to open input video file.");return -1;}// ...// 释放资源avformat_close_input(&fmt_ctx);return 0;
}

  这段代码尝试打开名为 "input_video.mp4" 的文件,若遭遇阻碍,借助 av_strerror 获取详细错误信息并输出,随即终止程序,凸显严谨的错误处理逻辑。

(二)avformat_find_stream_info()

  avformat_find_stream_info() 对已打开的视频文件展开深度扫描与剖析。它遍历视频文件的每一处角落,不仅进一步完善 AVFormatContext 结构体中既有信息的细节,更精准定位各路音视频流,详细解析出视频流的分辨率、帧率、编码参数,音频流的采样率、声道布局等核心要素,为后续精准分离与处理不同类型媒体流提供精准导航。

示例代码:

ret = avformat_find_stream_info(fmt_ctx, NULL);
if (ret < 0) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);fprintf(stderr, "无法获取视频流信息: %s\n", errbuf);avformat_close_input(&fmt_ctx);return -1;
}

  在此,若信息获取环节出现差池,及时关闭已打开文件资源,避免内存泄漏等隐患,同时输出错误详情,确保程序稳定性与可维护性。

(三)avcodec_find_decoder()

  avcodec_find_decoder() 依据视频流特定编码 ID(如 AV_CODEC_ID_H264AV_CODEC_ID_HEVC 等),在 FFmpeg 庞大的解码器库中迅速定位匹配解码器。一旦觅得,即刻返回 AVCodec 结构体指针,此指针恰似解码器的操控手册,掌控着解码流程的核心算法与关键参数设置,是后续构建解码环境的核心依托。

示例代码:

AVCodec *codec = NULL;
int video_stream_index = -1;
for (int i = 0; i < fmt_ctx->nb_streams; i++) {if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {video_stream_index = i;codec = avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id);if (!codec) {fprintf(stderr, "未找到视频解码器\n");avformat_close_input(&fmt_ctx);return -1;}break;}
}

  这段代码遍历视频文件所有流,锁定视频流后竭力寻找适配解码器,若搜寻无果,果断关闭文件资源,终止程序,以防陷入无意义的后续操作。

(四)avcodec_alloc_context3() 与 avcodec_parameters_to_context()

  • avcodec_alloc_context3() 为选定解码器精心分配 AVCodecContext 结构体内存空间,并初始化一系列默认参数,搭建起解码操作的基础场地框架,准备迎接后续精细配置。
    示例代码:
AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
if (!codec_ctx) {fprintf(stderr, "无法分配解码器上下文\n");avformat_close_input(&fmt_ctx);return -1;
}

若内存分配环节遇阻,迅速清理现场,关闭文件,保障程序稳健运行。

  • avcodec_parameters_to_context() 负责将视频流 AVStream 结构体中 AVCodecParameters 所蕴含的编码参数,毫厘不差地复制到 AVCodecContext 结构体中,确保解码器精准遵循视频流原始编码规则行事,从像素格式到分辨率,从帧率到码率控制参数,全方位保障解码一致性。

示例代码:

ret = avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);
if (ret < 0) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);fprintf(stderr, "无法复制编解码器参数: %s\n", errbuf);avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);return -1;
}

  复制过程若现异常,立即释放已分配解码器上下文内存,关闭文件,避免资源浪费与错误蔓延。

(五)avcodec_open2()

  avcodec_open2() 依据 AVCodecContext 结构体中精心配置的参数,深度初始化解码器内部复杂算法机制,调配所需系统资源,完成解码器初始化的最后冲刺。此刻,解码器宛如一台蓄势待发的引擎,静候视频数据输入,准备释放强大解码效能。

示例代码:

ret = avcodec_open2(codec_ctx, codec, NULL);
if (ret < 0) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);fprintf(stderr, "无法打开解码器: %s\n", errbuf);avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);return -1;
}

  一旦解码器启动失败,迅速拆解已构建的解码环境,关闭文件,严守程序稳定防线。

(六)av_read_frame() 与解码循环(含 avcodec_send_packet()、avcodec_receive_frame())

  • av_read_frame() 用于严格依循视频文件封装格式规则,逐帧从文件中读取数据包,将其妥善封装于 AVPacket 结构体中,该结构体满载未解码的原始视频数据、所属流索引以及关键时间戳信息,成为解码流程数据源头的稳定供给站。

示例代码:

AVPacket pkt;
while (av_read_frame(fmt_ctx, &pkt) >= 0) {if (pkt.stream_index == video_stream_index) {// 此数据包属视频流,送解码器处理// 后续解码代码......}av_packet_unref(&pkt); 
}

  循环读取数据包,一旦识别出视频流数据包,即刻送入后续解码流程,每轮循环末尾,借助 av_packet_unref() 释放数据包资源,避免内存泄漏,确保数据流转顺畅。

  • avcodec_send_packet() 恰似解码流水线的前端“调度员”,将 AVPacket 数据包精准推送至解码器输入缓冲区,若缓冲区满溢或遭遇特殊状况,及时反馈错误码,巧妙调控解码节奏,开启帧数据解码之旅。

示例代码:

ret = avcodec_send_packet(codec_ctx, &pkt);
if (ret < 0) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);fprintf(stderr, "发送数据包至解码器出错: %s\n", errbuf);av_packet_unref(&pkt);continue; 
}

  遇发送异常,迅速处理错误,释放数据包引用,无缝衔接下一轮数据读取,保障流程连贯性。

  • avcodec_receive_frame() 则扮演解码流水线末端的“收获者”角色,全神贯注地尝试从解码器获取解码完毕的完整视频帧(封装于 AVFrame 结构体),该结构体满载珍贵原始像素数据,静候进一步处理或存储。成功收获帧数据则返回 0,若暂无帧就绪或已达视频尾声,则相应返回特定错误码,循环调用此函数直至完整视频帧序列尽收囊中。

示例代码:

AVFrame *frame = av_frame_alloc();
while (ret >= 0) {ret = avcodec_receive_frame(codec_ctx, frame);if (ret == 0) {// 成功获取解码帧,可处理或保存// 后续帧处理代码......} else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {// 无帧或已到视频尾,跳出或继续读取数据包break;} else {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);fprintf(stderr, "接收解码帧出错: %s\n", errbuf);break;}
}
av_frame_free(&frame);

  每轮循环谨慎判断返回值,依据不同情形灵活抉择继续读取、跳出循环或处理错误,最终释放 AVFrame 资源,完美收官解码流程。

四、实战案例全流程解析

  以下奉上一段基于 FFmpeg 完整解码本地视频文件并将解码后 YUV420P 格式帧数据存储至 output.yuv 文件的示例代码,全程穿插严谨错误处理机制,确保程序稳健运行:

#include <iostream>
#include <string>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libswscale/swscale.h>
}void handle_ffmpeg_error(int ret, const char* msg) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);fprintf(stderr, "%s: %s\n", msg, errbuf);
}int main() {AVFormatContext* fmt_ctx = avformat_alloc_context();std::string file_path = "F:/QT/mp4_flv/x.mp4";// 打开输入视频文件,建立 AVFormatContextint ret = avformat_open_input(&fmt_ctx, file_path.c_str(), NULL, NULL);if (ret < 0) {handle_ffmpeg_error(ret, "Failed to open video file");return -1;}// 解析视频流信息,填充 AVFormatContext 细节ret = avformat_find_stream_info(fmt_ctx, NULL);if (ret < 0) {handle_ffmpeg_error(ret, "Error in obtaining video stream information");return -1;}// 定位视频流找到适合的解码器const AVCodec* codec = NULL;int video_stream_idx = -1;for (unsigned int i = 0; i < fmt_ctx->nb_streams; i++) {if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {video_stream_idx = i;codec = avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id);if (!codec) {fprintf(stderr, "Video decoder not found\n");avformat_close_input(&fmt_ctx);return -1;}break;}}// 分配解码器上下文,关联解码器与参数AVCodecContext* codec_ctx = avcodec_alloc_context3(codec);if (!codec_ctx) {fprintf(stderr, "Decoder context allocation failed\n");avformat_close_input(&fmt_ctx);return -1;}ret = avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[video_stream_idx]->codecpar);if (ret < 0) {handle_ffmpeg_error(ret, "Copying codec parameters failed");avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);return -1;}// 打开解码器ret = avcodec_open2(codec_ctx, codec, NULL);if (ret < 0) {handle_ffmpeg_error(ret, "Decoder open failed!");avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);return -1;}// 分配 AVFrame 存储解码帧,准备输出 YUV 文件AVFrame* frame = av_frame_alloc();FILE* out_file = nullptr;if (fopen_s(&out_file, "output.yuv", "wb") != 0) {perror("无法创建输出 YUV 文件");av_frame_free(&frame);avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);return -1;}// 读取视频帧数据包,解码循环AVPacket pkt;while (av_read_frame(fmt_ctx, &pkt) >= 0) {if (pkt.stream_index == video_stream_idx) {ret = avcodec_send_packet(codec_ctx, &pkt);if (ret < 0) {handle_ffmpeg_error(ret, "Error sending data packet to decoder.");av_packet_unref(&pkt);continue;}while (ret >= 0) {ret = avcodec_receive_frame(codec_ctx, frame);if (ret == 0) {// 将解码后的 YUV 数据写入文件for (int i = 0; i < frame->height; i++) {fwrite(frame->data[0] + i * frame->linesize[0], 1, frame->width, out_file);}for (int i = 0; i < frame->height / 2; i++) {fwrite(frame->data[1] + i * frame->linesize[1], 1, frame->width / 2, out_file);}for (int i = 0; i < frame->height / 2; i++) {fwrite(frame->data[2] + i * frame->linesize[2], 1, frame->width / 2, out_file);}}else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {break;}else {handle_ffmpeg_error(ret, "Error receiving decoded frame.");break;}}}av_packet_unref(&pkt);}// 释放资源,关闭文件与上下文fclose(out_file);av_frame_free(&frame);avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);return 0;
}

总结

  本文围绕 FFmpeg 视频解码进行了全面讲解,核心内容包括:

  • 视频解码基础概念:介绍视频存储与传输时会压缩,解码则是逆向还原为原始视频帧序列的过程,以常见编码标准举例说明了编码和解码的关键技术要点。
  • FFmpeg 关键 API 剖析:详细解读了多个关键 API,如avformat_open_input()用于打开文件获取基础元数据;avformat_find_stream_info()完善流信息解析;avcodec_find_decoder()定位解码器;avcodec_alloc_context3()和avcodec_parameters_to_context()搭建与配置解码环境;avcodec_open2()初始化解码器;以及av_read_frame()、avcodec_send_packet()、avcodec_receive_frame()协同完成数据读取、发送与帧接收等操作,各 API 都附带有示例代码与错误处理逻辑展示。
  • 实战案例解析:呈现了完整解码本地视频并存储解码帧数据的示例代码,其中融入了严谨的错误处理机制,体现从视频文件打开到最终资源释放、文件关闭的全流程操作,确保程序稳定运行。

相关文章:

FFmpeg第三话:FFmpeg 视频解码详解

FFmpeg 探索之旅 一、FFmpeg 简介与环境搭建 二、FFmpeg 主要结构体剖析 三、FFmpeg 视频解码详解 FFmpeg第三话&#xff1a;FFmpeg 视频解码详解 FFmpeg 探索之旅前言一、视频解码基础二、FFmpeg 关键 API 深度剖析&#xff08;一&#xff09;avformat_open_input()&#xff…...

解决 vue3 中 echarts图表在el-dialog中显示问题

原因&#xff1a; 第一次点开不显示图表&#xff0c;第二次点开虽然显示图表&#xff0c;但是图表挤在一起&#xff0c;页面检查发现宽高只有100px,但是明明已经设置样式宽高100% 这可能是由于 el-dialog 还没有完全渲染完成&#xff0c;而你的 echarts 组件已经开始尝试渲染图…...

C++ OpenGL学习笔记(4、绘制贴图纹理)

相关链接&#xff1a; C OpenGL学习笔记&#xff08;1、Hello World空窗口程序&#xff09; C OpenGL学习笔记&#xff08;2、绘制橙色三角形绘制、绿色随时间变化的三角形绘制&#xff09; C OpenGL学习笔记&#xff08;3、绘制彩色三角形、绘制彩色矩形&#xff09; 通过前面…...

关于我的Java考试被老师挂掉的这件事......

目录 1.事情起源 2.问题出现 3.最后的考试结果 4.问题如何解决的 5.此件事情引发我的思考 1.事情起源 现在是2024-12-25中午的13:08分&#xff0c;我于今天上虞结束了这个学期的Java课程的学习&#xff0c;上午的课程内容就是开始&#xff0c;使用MVC实现对于题目要求的这…...

Websocket客户端从Openai Realtime api Sever只收到部分数据问题分析

目录 背景 分析 解决方案 背景 正常情况下&#xff0c;会从Openai Realtime api Sever收到正常的json数据,但是当返回音频数据时&#xff0c;总会返回非json数据。这是什么问题呢&#xff1f; 分析 期望的完整响应数据如下&#xff1a; {"session": {"inp…...

Unity 6 中的新增功能

Unity 6 是 Unity 的最新版本。 一、编辑器和工作流程 Unity 6 中引入的更改 在 Linux 上实现了将文件和资源从 Unity 拖放到外部应用程序的功能。将 Asset Manager for Unity 包添加到 Package Manager > Services > Content Management 部分中。此包允许用户轻松浏览…...

[ComfyUI]颜色提取插件,Flux专属,让出图更加可控

一、介绍​ 今天介绍这个好玩的插件 ComfyUI APQNodes&#xff0c;默认的Flux模型是无法理解准确的颜色代码。​ 而这个插件可以帮我忙将输入的十六进制颜色代码转换为 FLUX.1 Dev 已知的最相似的颜色名称&#xff08;来自预先测试的 155 个颜色名称&#xff09;。​ ​ 所以就…...

【magic-dash】01:magic-dash创建单页面应用及二次开发

文章目录 一、magic-dash是什么1.1 安装1.2 使用1.2.1 查看内置项目模板1.2.2 生成指定项目模板1.2.3 查看当前magic-dash版本1.2.4 查看命令说明1.2.5 内置模板列表二、创建虚拟环境并安装magic-dash三、magic-dash单页工具应用开发3.1 创建单页面项目3.1.1 使用命令行创建单页…...

ChatGPT等大语言模型与水文水资源、水环境领域的深度融合

聚焦GPT等大语言模型与水文水资源领域的深度融合&#xff0c;通过系统化内容与实践案例&#xff0c;讲解如何高效完成时间序列分析、空间数据处理、水文模型优化以及智能科学写作等任务。同时&#xff0c;展示AI在高级机器学习模型开发、资源优化算法编程与模型微调中的最新应用…...

机器学习连载

1 机器学习基础知识 机器学习&#xff08;Machine learning&#xff09;是人工智能的子集&#xff0c;是实现人工智能的一种途径&#xff0c;但并不是唯一的途径。它是一门专门研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识或技能&#xff0c;重新组织已…...

linux查看天气预报

wttr.in 是一个简单且功能强大的命令行天气查询工具&#xff0c;实现了命令行下查看天气的炫酷效果。 开源地址&#xff1a;GitHub - chubin/wttr.in: :partly_sunny: The right way to check the weather 一. 什么是 wttr.in&#xff1f; wttr.in 是一个基于 Web 的命令行天…...

minikube start --driver=docker --force

minikube start --driver=docker --force 😄 minikube v1.34.0 on Debian 11.7 (amd64) ❗ minikube skips various validations when --force is supplied; this may lead to unexpected behavior ✨ Using the docker driver based on user configuration 🛑 The…...

游戏引擎学习第58天

发现一个vscode Log 断点的用法 回顾 我们正在继续推进工作&#xff0c;之前做了一些测试和清理工作&#xff0c;但还有一件事没有完成&#xff0c;因此我们还没有完全回到功能平衡的状态。昨天我们已经为实体做了空间划分&#xff0c;所以接下来的目标是继续完成这部分工作&a…...

我用火语言RPA生成EXE可执行文件,并使用激活码对EXE进行管理

火语言RPA&#xff0c;不仅可以生成EXE独立可执行文件&#xff0c;还可以使用激活码的功能对EXE进行管理&#xff0c;限制激活类型&#xff1a;在线、离线,EXE有效天数等进行管理&#xff0c;有限制的自由才是真正的自由&#xff01; 生成EXE的时候选择App注册码验证类型 当分享…...

【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版 (1)11

文章目录 一、算法概念11二、算法原理&#xff08;一&#xff09;感知机&#xff08;二&#xff09;多层感知机1、隐藏层2、激活函数sigma函数tanh函数ReLU函数 3、反向传播算法 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、MLP分类任务实…...

32位MCU主控智能电表方案

智能电表作为电网数据采集的核心设备&#xff0c;承担着至关重要的角色。它主要用于采集、计量和传输原始的电能数据&#xff0c;确保电力系统的高效运行。该设备配备了多种通讯接口&#xff0c;如RS485和以太网&#xff0c;使得用户能够轻松进行用电检测、集中抄表以及电力管理…...

ConstraintLayout是完美的布局吗?

非也&#xff01; <TextViewandroid:id"id/tv_tittle_msg"android:layout_width"wrap_content"android:layout_height"wrap_content"android:layout_marginLeft"16dp"android:layout_marginRight"16dp"android:layout_ma…...

39.在 Vue3 中使用 OpenLayers 导出 GeoJSON 文件及详解 GEOJSON 格式

一、引言 在 Web 地图开发领域&#xff0c;Vue3 作为一款流行的前端框架&#xff0c;结合强大的 OpenLayers 地图库&#xff0c;能够实现丰富多样的地图功能。其中&#xff0c;将地图数据以 GeoJSON 格式导出是一项常见且实用的需求&#xff0c;本文将深入探讨如何在 Vue3 环境…...

Feign的调用demo 和 EnableFeignClients的包名

在你的场景下&#xff0c;如果刷题微服务通过 Maven 引入了 auth-api 模块&#xff0c;并且 auth-api 中定义了 Feign 接口&#xff08;例如获取用户名的方法&#xff09;&#xff0c;你需要在 刷题微服务 中的启动类上配置 EnableFeignClients 注解。配置中 basePackages 参数…...

简化开发流程:如何通过 JDBC 自动生成符合 Java 命名规范的实体类

在这篇博客中&#xff0c;我分享了如何通过 Java 和 JDBC 自动生成数据库实体类的过程。通常&#xff0c;手动编写实体类代码既繁琐又容易出错&#xff0c;尤其是在数据库表结构发生变化时&#xff0c;手动更新代码的工作量非常大。为了提高开发效率&#xff0c;我利用 JDBC 连…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...