RTP裸流合成MP4:H264与AAC封装实战
简介这份资源面向音视频开发初学者与流媒体协议实践者聚焦于将RTP通道中承载的H264视频与AAC音频数据重新封装为可播放的MP4文件解决接收端裸流难以直接播放、存档与二次分析的问题。压缩包共31个文件约197KB以C语言源码与头文件为主体包含17个.h与2个.c实现核心解析与封装逻辑另有Makefile、nbproject工程配置、SDP会话描述文件及一个test.mp4样例便于对照验证输出结果。目录中rtp、isma、mp4v2、track等模块划分清晰覆盖RTP解包、H264与AAC帧提取、MP4容器写入等关键环节读者可据此理解从网络流到本地文件的完整链路并借助样例与工程配置快速编译调试。目前已有486人学习下载适合作为流媒体合成方向的入门参考与代码骨架。1. 从一堆裸流到能播的 MP4这个项目到底在解决什么问题如果你抓过 RTP 包大概经历过这种场景Wireshark 里躺着一串 RTP 流Payload 里是 H264 的 NALU 和 AAC 的原始帧时间戳、序列号、Marker 位都在但你就是没法直接拿播放器打开它。因为 RTP 是传输层协议它只负责把媒体数据切片、打包、按序送达至于这些数据怎么拼回一帧完整的画面、怎么还原出音频的采样边界、怎么写进一个带索引的容器格式RTP 本身一概不管。这个项目要干的事就是把这层「从传输流到文件」的桥搭起来。输入是 RTP 包通常来自抓包文件或实时接收输出是一个标准的 MP4 文件里面封装了 H264 视频轨和 AAC 音频轨能被 VLC、ffplay 或浏览器直接播放。适合谁看做流媒体抓包分析、做音视频测试工具、做监控回放模块的开发者以及任何需要把 RTP 裸流落盘成可检索文件的场景。它不依赖 FFmpeg 命令行而是自己解析 RTP 头、重组 NALU、处理 AAC 的 AU 边界再按 MP4 的 box 结构写文件——这意味着你能完全控制每一字节的写入逻辑也意味着你得自己踩完所有坑。2. 核心链路拆解RTP 包怎么一步步变成 MP4 的 box2.1 整体数据流从 UDP 载荷到文件偏移先看全局。一个 RTP 包进来头部固定 12 字节后面跟 Payload。对于 H264Payload 可能是单个 NALU、分片 FU-A 的起始/中间/结束包或者 STAP-A 聚合包对于 AACPayload 通常是带 AU-headers-length 的多个 AU 或者单个 AU。项目要做的第一件事是按 SSRC 和 Payload Type 分流把视频包和音频包分开缓存。分流之后视频侧走「NALU 重组 → 按时间戳排序 → 生成 AVCC 格式的样本」音频侧走「AU 提取 → 按时间戳排序 → 生成原始 AAC 帧」。两条线各自维护一个样本列表每个样本记录数据内容、解码时间戳DTS、显示时间戳PTS、时长、在文件中的偏移。最后 MP4 写入器根据这些样本列表生成 ftyp、moov、mdat 等 box把数据按偏移写进去。这里的关键是时间戳换算。RTP 的时间戳是 32 位无符号整数单位是采样率。H264 视频通常 90kHz 时钟AAC 音频通常 44.1kHz 或 48kHz。MP4 的 mvhd 和 mdhd 里用 timescale 和 duration 表示时间所以必须把 RTP 时间戳差值映射到 MP4 的 timescale 上。常见做法是视频轨 timescale 设为 90000音频轨设为采样率这样 RTP 时间戳可以直接用省去浮点换算的精度损失。2.2 H264 重组FU-A 分片与 STAP-A 聚合的处理H264 over RTP 的打包方式由 RFC 6184 定义。一个 NALU 如果小于 MTU可能直接放在一个 RTP 包里单一 NALU 模式如果大了就切成 FU-A 分片每个分片有 1 字节的 FU indicator 和 1 字节的 FU headerFU header 的 S 位标记起始E 位标记结束还有 STAP-A 把多个小 NALU 聚在一个包里。重组逻辑的核心是维护一个「当前正在拼的 NALU 缓冲区」。遇到 FU-A 起始包记录 NALU 头由 FU indicator 和 FU header 合成开始累积数据遇到中间包追加数据遇到结束包追加数据后把完整 NALU 推入样本队列。STAP-A 则是一次性拆出多个 NALU逐个推入队列。def parse_rtp_payload(payload, is_video): if not is_video: return parse_aac_payload(payload) nal_type payload[0] 0x1F if nal_type 28: # FU-A fu_header payload[1] start (fu_header 7) 1 end (fu_header 6) 1 nalu_type fu_header 0x1F # 重建 NALU 头F(1) NRI(2) Type(5) nalu_header (payload[0] 0xE0) | nalu_type data payload[2:] return (fu, start, end, nalu_header, data) elif nal_type 24: # STAP-A nals [] offset 1 while offset len(payload): size int.from_bytes(payload[offset:offset2], big) offset 2 nals.append(payload[offset:offsetsize]) offset size return (stap, nals) else: return (single, payload)这段代码里nal_type从 Payload 第一个字节的低 5 位取出。FU-A 的fu_header第 7 位是起始标志第 6 位是结束标志低 5 位是原始 NALU 类型。重建 NALU 头时保留原 FU indicator 的 F 和 NRI 位替换类型位。STAP-A 则按 2 字节大端长度逐个拆包。参数说明payload是 RTP 载荷字节串is_video区分音视频通道。实际项目中我会把重组状态放在一个类里按 SSRC 维护多个上下文避免不同流的包互相干扰。2.3 AAC 提取AU-headers-length 与帧边界AAC over RTP 的打包方式由 RFC 3640 定义。常见模式是 mpeg4-genericPayload 开头有 2 字节的 AU-headers-length表示后面跟多少个 AU 头。每个 AU 头通常是 2 字节包含 13 位 AU 大小和 3 位 AU 索引。根据 AU 大小从 Payload 剩余部分切出每个 AU 的数据。def parse_aac_payload(payload): au_headers_len int.from_bytes(payload[0:2], big) // 8 au_headers payload[2:2au_headers_len] data_start 2 au_headers_len aus [] offset 0 for i in range(0, au_headers_len, 2): au_size int.from_bytes(au_headers[i:i2], big) 3 aus.append(payload[data_startoffset:data_startoffsetau_size]) offset au_size return ausau_headers_len的单位是比特除以 8 得到字节数。每个 AU 头 2 字节右移 3 位得到 13 位的 AU 大小。切出的 AU 就是原始 AAC 帧可以直接作为 MP4 的音频样本。注意有些实现会带 1 字节的 AU 索引但大多数场景下索引为 0可以忽略。如果遇到 AU 大小超出剩余 Payload 长度说明包被截断需要丢弃并记录日志。2.4 MP4 写入moov 与 mdat 的生成顺序MP4 是 box 结构每个 box 有 4 字节大小和 4 字节类型。核心 box 包括 ftyp文件类型、moov元数据、mdat媒体数据。moov 里又嵌套 mvhd、trak、mdia、minf、stbl 等。stbl 下的 stsd 描述编码格式stts 记录时间戳stsc 记录样本到 chunk 的映射stsz 记录样本大小stco 记录 chunk 偏移。写入顺序有两种先写 mdat 再写 moov或者先写 moov 再写 mdat。前者需要回填 moov 里的偏移后者需要预先知道所有样本大小。这个项目采用先写 mdat再写 moov的方式因为样本是流式到达的无法预知总大小。具体做法打开文件先占位 ftyp 和 mdat 头然后逐个写入样本数据同时记录每个样本的大小和偏移。所有样本写完后再生成 moov追加到文件末尾最后回填 mdat 的大小字段。def write_mp4(samples_video, samples_audio, output_path): with open(output_path, wb) as f: f.write(b\x00\x00\x00\x18ftypmp42\x00\x00\x00\x00mp42isom) mdat_start f.tell() f.write(b\x00\x00\x00\x00mdat) # 占位 data_start f.tell() for s in samples_video samples_audio: s.offset f.tell() f.write(s.data) mdat_size f.tell() - mdat_start f.seek(mdat_start) f.write(mdat_size.to_bytes(4, big)) f.seek(0, 2) moov build_moov(samples_video, samples_audio, data_start) f.write(moov)mdat_start记录 mdat box 的起始位置data_start是实际媒体数据的起始偏移。写完所有样本后回填 mdat 大小。build_moov负责构造完整的 moov box里面需要用到每个样本的偏移、大小、时间戳。参数说明samples_video和samples_audio是样本列表每个样本对象包含data、dts、pts、duration、offset属性。实际项目中我会把视频和音频样本分开写入但 mdat 里可以交错存放只要 stco 里的偏移正确即可。3. 环境搭建与最小可跑通流程3.1 依赖选择为什么不用 FFmpeg 的 libavformat这个项目可以纯 Python 实现也可以基于 FFmpeg 的 libavformat 做封装。但既然标题强调「合成 MP4 文件」用 libavformat 就失去了自己控制 box 写入的意义。常见做法是用 Python 的struct模块处理二进制用socket接收 RTP用collections做缓存队列。如果追求性能可以用 C 重写核心解析部分Python 只做胶水层。依赖清单很简单Python 3.8标准库足够。如果需要解析 SDP 获取 Payload Type 和编码参数可以加一个sdp-transform之类的库但也可以手写正则。测试阶段建议用ffplay或vlc验证输出文件用ffprobe查看轨道信息。pip install pytest # 可选用于单元测试 # 不需要额外安装 FFmpeg但建议装一个用于验证3.2 从抓包文件读取 RTP 并生成 MP4最简流程是读一个 pcap 文件提取 UDP 载荷作为 RTP 包然后走完整链路。可以用scapy读 pcap也可以自己解析 pcap 格式。下面是一个最小示例from scapy.all import rdpcap, UDP from rtp_mp4 import RtpParser, Mp4Writer packets rdpcap(capture.pcap) parser RtpParser() for pkt in packets: if UDP in pkt and pkt[UDP].dport % 2 0: # 假设偶数端口是 RTP rtp_data bytes(pkt[UDP].payload) parser.feed(rtp_data) writer Mp4Writer() writer.add_video_samples(parser.video_samples) writer.add_audio_samples(parser.audio_samples) writer.write(output.mp4)RtpParser内部按 SSRC 分流feed方法解析 RTP 头并调用对应的 Payload 处理函数。Mp4Writer负责生成 moov 和 mdat。参数说明pkt[UDP].dport用于区分 RTP 和 RTCP通常 RTP 用偶数端口。实际抓包中SSRC 和 Payload Type 需要从第一个包中学习后续包按相同 SSRC 归类。3.3 实时接收UDP socket 绑定与超时处理实时场景下用 UDP socket 绑定端口循环recvfrom。需要设置超时避免阻塞。收到包后直接喂给RtpParser。当收到 RTCP BYE 或超时无包时触发 MP4 写入。import socket sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((0.0.0.0, 5004)) sock.settimeout(5.0) parser RtpParser() try: while True: data, addr sock.recvfrom(65535) parser.feed(data) except socket.timeout: print(超时开始写文件) writer Mp4Writer() writer.add_video_samples(parser.video_samples) writer.add_audio_samples(parser.audio_samples) writer.write(live.mp4)sock.settimeout(5.0)设置 5 秒无包则超时。实际项目中我会加一个心跳检测如果连续 10 秒没有新包就认为流结束。注意RTP 包可能乱序RtpParser内部需要按序列号排序或者至少按时间戳排序后再生成样本。4. 避坑与排查RTP 转 MP4 时最容易翻车的几个点4.1 时间戳跳变导致音视频不同步现象生成的 MP4 播放时声音比画面快几秒或者画面卡住声音继续。原因RTP 时间戳是 32 位循环的抓包时间长了会回绕。另外音视频的起始时间戳不同如果直接拿绝对值做 DTS会导致音视频起点不一致。解决记录每个轨道的第一个 RTP 时间戳作为基准后续时间戳减去基准值。对于回绕检测到时间戳突然变小超过阈值时加上 2^32 补偿。音视频同步则通过比较两个轨道的第一个时间戳把较晚的那个轨道的起始 DTS 对齐到 0较早的轨道做相应偏移。4.2 FU-A 分片丢失导致 NALU 不完整现象播放到某个位置花屏或者 ffprobe 报「Invalid NAL unit size」。原因UDP 丢包导致 FU-A 的中间分片丢失重组时只拿到起始和结束包中间数据缺失。解决在重组缓冲区里记录期望的序列号范围如果发现序列号不连续丢弃当前正在拼的 NALU并记录日志。不要试图用不完整的数据生成样本否则 MP4 里的样本大小会出错导致后续样本偏移全部错位。4.3 AAC 的 AU-headers-length 解析错误现象音频轨能识别但播放全是噪音或者 ffprobe 显示音频样本数为 0。原因AU-headers-length 的单位是比特不是字节。有些实现直接把它当字节数导致偏移算错。解决严格按 RFC 3640 处理au_headers_len int.from_bytes(payload[0:2], big) // 8。另外如果 AU 头里包含 AU 索引需要跳过索引字节。常见做法是只处理索引为 0 的 AU忽略其他。4.4 moov 里的 stco 偏移未考虑 mdat 头大小现象MP4 文件能播放但进度条拖不动或者播放器报「moov atom not found」。原因stco 里记录的 chunk 偏移是相对于文件开头的如果计算时漏掉了 ftyp 和 mdat 头的大小偏移就会错位。解决在写入样本时用f.tell()记录实际偏移这个偏移已经包含了 ftyp 和 mdat 头。生成 moov 时直接使用这些偏移不要做额外加减。另外mdat 的大小回填后moov 里的 stco 不需要调整因为 mdat 头大小固定为 8 字节。4.5 视频轨缺少 SPS/PPS 导致无法解码现象MP4 能打开但视频黑屏ffprobe 显示「no frame」。原因H264 的 SPS 和 PPS 通常不在 RTP 流里单独传输而是通过 SDP 的 sprop-parameter-sets 传递或者作为 STAP-A 的第一个 NALU。如果没把 SPS/PPS 写进 MP4 的 avcC box解码器就不知道分辨率、帧率等信息。解决在生成 stsd 时构造 avcC box填入 SPS 和 PPS。SPS/PPS 可以从第一个 STAP-A 包里提取也可以从 SDP 里解析。如果都没有可以尝试从第一个 IDR 帧前的 NALU 里找。常见做法是在解析 RTP 时遇到 NALU 类型为 7SPS或 8PPS就缓存起来写入 avcC 时使用。5. 二次开发从能跑到好用几个改造方向5.1 支持 HEVC 和 Opus 的扩展思路当前项目只处理 H264 和 AAC但 RTP 里跑 HEVC 和 Opus 也很常见。扩展的关键是抽象出编解码器接口。把「解析 RTP 载荷」和「生成 MP4 样本」拆成两个接口H264 和 AAC 各实现一套HEVC 和 Opus 再各实现一套。HEVC 的 RTP 打包方式由 RFC 7798 定义NALU 头是 2 字节FU 类型是 49STAP 类型是 48。Opus 的 RTP 载荷就是原始 Opus 帧不需要额外解析但 MP4 里需要用Opussample entry并且要写dOpsbox。改造时我会先定义一个CodecParser基类包含parse_payload和build_sample_entry两个方法。然后每个编解码器实现自己的子类。Mp4Writer只依赖基类接口不关心具体编解码器。这样新增格式时只需要加一个子类不用改写入逻辑。5.2 大文件写入分片与内存控制如果 RTP 流持续几小时样本列表会撑爆内存。改造方向是边收边写维护一个固定大小的样本缓冲区当缓冲区满时先把数据写入 mdat记录偏移和大小然后清空缓冲区。moov 的生成可以延迟到所有数据写完但 stco 里的偏移需要动态追加。具体做法打开文件后先写 ftyp 和 mdat 头然后每收到一个完整样本就写入文件同时把样本元数据大小、偏移、时间戳追加到一个列表。这个列表只存元数据不存数据本身内存占用很小。所有样本写完后再生成 moov。这样即使流跑一天内存也不会爆。class StreamingMp4Writer: def __init__(self, path): self.f open(path, wb) self.f.write(b\x00\x00\x00\x18ftypmp42\x00\x00\x00\x00mp42isom) self.mdat_start self.f.tell() self.f.write(b\x00\x00\x00\x00mdat) self.samples [] def add_sample(self, data, dts, duration, track_id): offset self.f.tell() self.f.write(data) self.samples.append({ offset: offset, size: len(data), dts: dts, duration: duration, track: track_id }) def finalize(self): mdat_size self.f.tell() - self.mdat_start self.f.seek(self.mdat_start) self.f.write(mdat_size.to_bytes(4, big)) self.f.seek(0, 2) moov build_moov_from_meta(self.samples) self.f.write(moov) self.f.close()add_sample每调用一次就写一个样本samples列表只存元数据。finalize回填 mdat 大小并追加 moov。参数说明track_id区分视频和音频轨dts是解码时间戳duration是样本时长。这个改造能把内存占用从 O(总数据量) 降到 O(样本数)对于长时间录制非常关键。5.3 验证方法用 ffprobe 和帧比对做回归改完代码后怎么确认没改坏我的习惯是准备一组固定的 pcap 文件每次改完跑一遍生成 MP4然后用ffprobe检查轨道数、时长、帧数再用ffmpeg解码成原始帧和基线做逐帧比对。ffprobe -v error -show_streams -show_format output.mp4 ffmpeg -i output.mp4 -f rawvideo -pix_fmt yuv420p - 2/dev/null | md5sum第一条命令输出轨道信息确认视频轨是 h264、音频轨是 aac时长和帧数符合预期。第二条命令把视频解码成原始 YUV 数据算 MD5和基线比对。如果 MD5 一致说明解码结果完全一样如果不一致用ffmpeg的-vf framehash逐帧输出哈希定位到具体哪一帧变了。注意帧比对时要确保 ffmpeg 版本一致不同版本的解码器可能有细微差异。建议在 Docker 里固定版本。从那以后我每次改 RTP 解析或 MP4 写入的逻辑都强制走一遍「pcap → mp4 → ffprobe → 帧哈希」的回归流程哪怕只改了一行偏移计算。因为音视频这东西肉眼看着能播不代表数据对只有哈希一致才敢说没改坏。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

毕业论文的“施工进度条”:云智变AI毕业论文撰写生成功能科普|云智变AI官网www.yunzhibian.cn 微信公众号搜一搜云智变ai学术

毕业论文的“施工进度条”:云智变AI毕业论文撰写生成功能科普|云智变AI官网www.yunzhibian.cn 微信公众号搜一搜云智变ai学术

毕业论文写作最大的痛苦,不是“不会写”,而是“失控”。 本科论文八千到一万五,硕士论文三万起步,周期横跨几个月。你明明每天都在想它,却不知道今天该写哪一段;你明明读了很多文献,却不知道它…

2026/10/19 0:49:44 阅读更多 →
MinGW-w64 + MSYS2 编译 libMesh:Windows 有限元环境搭建指南

MinGW-w64 + MSYS2 编译 libMesh:Windows 有限元环境搭建指南

简介:面向需要在Windows下开展有限元仿真与科学计算的开发者,这是一份基于MinGW工具链编译生成的libmesh动态库资源包。libmesh作为开源可扩展有限元库,常被用于网格生成、求解器调用与并行计算;该压缩包将编译产物直接整合&#…

2026/10/18 22:37:19 阅读更多 →
C#零Java环境直连ActiveMQ消息收发Demo

C#零Java环境直连ActiveMQ消息收发Demo

简介:本资源是一套面向C#初学者与中间件开发者的ActiveMQ消息队列实战Demo,聚焦WinForm桌面端的MQ通信基础能力训练,适用于.NET平台下异步解耦、生产者-消费者模型等典型场景的学习与快速验证。压缩包共36个文件,含19个核心C#源码…

2026/10/18 1:34:30 阅读更多 →

最新新闻

Folia Sync-Server 完整部署指南:10 分钟让 AI 主题多端同步

Folia Sync-Server 完整部署指南:10 分钟让 AI 主题多端同步

Folia Sync-Server 完整部署指南:10 分钟让 AI 主题多端同步 【免费下载链接】folia-major 专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器 项目地址: https://gitcode.com/GitHub_Trending/fo/folia-major Folia 是一款本地优先…

2026/10/19 1:57:24 阅读更多 →
Buzz 离线语音转文字:把会议录音和播客变成带时间戳的文字

Buzz 离线语音转文字:把会议录音和播客变成带时间戳的文字

Buzz 离线语音转文字:把会议录音和播客变成带时间戳的文字 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz 周五傍…

2026/10/19 1:57:24 阅读更多 →
硬件开发入门十讲:从选型到量产全流程实战指南

硬件开发入门十讲:从选型到量产全流程实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 1:57:24 阅读更多 →
Cortex-M系列MCU的IAP在线升级设计与排坑指南

Cortex-M系列MCU的IAP在线升级设计与排坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 1:57:24 阅读更多 →
树莓派5外接NVMe SSD实战:USB转接架构与性能调优全指南

树莓派5外接NVMe SSD实战:USB转接架构与性能调优全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 1:57:24 阅读更多 →
显存不够怎么办:HERO-35B-A3B-i1-GGUF用7.6GB跑起35B大模型的极限技巧

显存不够怎么办:HERO-35B-A3B-i1-GGUF用7.6GB跑起35B大模型的极限技巧

【免费下载链接】HERO-35B-A3B-i1-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/mradermacher/HERO-35B-A3B-i1-GGUF 点击查看 免费下载 显存不够,还想本地跑35B大模型?HERO-35B-A3B-i1-GGUF 就是为你准备的。这个项目提供了一套完整的…

2026/10/19 1:56:24 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →