FFmpeg AVPacket 全解析:从生命周期到踩坑实战
做音视频开发的人多多少少都绕不开 FFmpeg。刚开始我是照着一套示例代码直接跑avformat_open_input 打开文件av_read_frame 拿数据avcodec_send_packet 喂给解码器最后 avcodec_receive_frame 出帧。流程是通的画面也出来了但一旦涉及音视频同步、多路流切换、内存持续上涨这类问题就彻底抓瞎。回头排查了一圈根子全在同一个地方——AVPacket 的使用姿势不对。这篇博文想把 FFmpeg API 里的 AVPacket 整个拆开讲透。它适合刚接触 FFmpeg 开发、正在为“怎么拿一包数据”“怎么释放一个 packet”纠结的新手也适合已经写过几个 demo、但一遇到时间戳错乱或内存泄漏就头疼的中级开发者。看完之后你应该能清楚一个 packet 从解封装到解码、从编码器到封装器中间每一步该怎么处理以及为什么必须这么做。1. AVPacket 在数据流管线里的两个“搬运”阶段1.1 解封装到解码packet 是你手里第一个“成品”FFmpeg 处理一个媒体文件的起点并不是解码而是解封装。一个 MP4、FLV、TS 文件里音频和视频是按某种容器规则交错存放的。解复用器demuxer负责把文件里的数据块读出来每读出一块就封装成一个 AVPacket 交给你。拿快递打比方AVPacket 就是一个密封的快递盒盒面贴着标签pts、dts、stream_index里面装着你实际上需要的压缩数据data 指针指向的内存区域。这个阶段你拿到的还不是能直接播放的原始像素或 PCM而是编码器吐出来的压缩数据可能是 H.264、AAC 或者其他编码格式。有个细节容易忽略一个 AVPacket 和视频帧、音频帧的关系并非一对一。视频一般是“一个 packet 对应一帧”但音频经常是“一个 packet 里装了好几帧”。你只有在解码之后才知道里面到底包含了多少 PCM 样本或多少视频帧。所以不要试图从压缩数据本身去猜“这一包该播放多久”那是容器和 packet 字段的职责。1.2 编码到封装packet 是转码链路的最终产物如果做的是单纯解码播放AVPacket 走到解码器就结束了。但你要是做转码、录屏、推流这类工作AVPacket 还会再次出现——这次它是编码器的输出。流程是这样的解码器把 AVPacket 变成 AVFrame你对该帧做缩放、滤镜、叠加等处理然后送入编码器。编码器再吐出一个 AVPacket这个 packet 里的内容就是编码后的新数据最后交给复用器muxer写入文件或推流。这个方向的 packet 和读文件拿到的 packet 有个重要差异你读取时拿到的 packet容器已经帮你填好了 stream_index 和流的时间基准编码器吐出来的 packet虽然也有 pts、dts、duration但它的时间基来自编码器上下文。在交给 muxer 之前你需要做时间基准换算并把 packet 挂到正确的输出流上。这一步漏了就会出现输出文件时长不对、播放倍速异常、音画不同步之类的问题。1.3 与 AVFrame 的分工差异很多人把 AVPacket 和 AVFrame 混在一起觉得都是“一帧数据”。实际上两者的分工非常清晰对比项AVPacketAVFrame承载内容压缩后的编码数据解码后的原始数据YUV/RGB、PCM数据布局连续 bufferdata size多平面数据有 linesize 和 channel 布局等参与环节解封装→解码编码→封装解码→滤镜/处理→编码内存特征靠引用计数管理unref 释放同样需要 ref/unref但字段更多更复杂时间戳语义pts/dts 是编码顺序相关需要换算pts 通常是显示顺序单位与流相关一个直观的理解方式AVPacket 是压缩世界的“快递单号”AVFrame 是像素世界的“工作台”。你在工作台上处理数据之前必须先签收快递——也就是解码。2. pts、dts、duration、stream_index 这些字段的真相2.1 字段速查表以及 AVPacket 没有 time_base 这件事先把 AVPacket 常用的字段摆出来每个字段我都标了实际使用中的关键提醒。字段含义使用注意data压缩数据指针不一定以 \0 结尾永远用 size 判断长度size数据字节数解封装后可能为 0这种空包有特殊用途pts显示时间戳单位是所在流的时间基准可能是 AV_NOPTS_VALUEdts解码时间戳与 pts 不同步时代表解码顺序duration该包持续时长单位同样由流的时间基准决定stream_index属于第几条流多路流时必须根据它分发数据flags标志位关键帧、可丢弃等转封装时很关键side_data附加数据数组存储回放增益、调色板等元信息side_data_elemsside_data 数量遍历时需要用到buf内部引用计数 buffer通常不直接操作由 API 管理这里有个新手最常踩的误区AVPacket 里并没有一个叫 time_base 的字段。它的 pts、dts、duration 统统是相对于所属流 AVStream.time_base 的。FLV 里视频流时间基准一般是 1/1000所以 duration 40 意味着 40 毫秒但 MPEG-TS 里视频流时间基准是 1/90000duration 3600 才意味着 40 毫秒。直接把两个容器的 packet 拿来比较时间戳结果一定是一团糟。2.2 pts 与 dts 不一致的场景B 帧和音频 delaypts 是显示时间戳表示这一帧内容什么时候该显示dts 是解码时间戳表示这一帧数据什么时候该进入解码器并完成解码。当编码器用了 B 帧之后两者就会出现差异。举个最直观的例子一段视频显示顺序是 I、B、B、P。解码器在解第一个 B 帧之前必须先把 P 帧解出来因为 B 帧可能参考了它。于是解码器实际拿到的包顺序可能是 I、P、B、B这时候 dts 就是 0、1、2、3而 pts 可能是 0、2、3、1。如果你在代码里直接用 dts 驱动渲染视频就会花屏或顺序颠倒。音频由于没有 B 帧这种参考机制绝大多数情况下 pts 等于 dts。但某些编码格式会有 encoder delay表现为第一个包的 pts 不是 0通常需要配合 side_data 里的延迟信息纠正。所以不能认为音频的 pts 一定从 0 开始。处理时还有一点必须养成的习惯使用 pts、dts 之前先判断是否为 AV_NOPTS_VALUE。有些封装格式根本不写时间戳这个值是约等于 -9223372036854775808 的特殊值直接参与加减乘除会把整个时间轴算崩。2.3 duration 的取值与估算方法duration 表示这个包在 stream 时间基准下的持续时长。它在做精准裁剪、字幕对齐、进度条控制时有价值。视频的 duration 通常是 1 帧的时长。比如帧率 25fps、time_base 1/90000 时一帧时长约为 3600。音频的 duration 取决于一个 packet 里装了多少样本。AAC 一个 packet 通常是 1024 个样本假设采样率 44100、time_base 1/44100那么 duration 就是 1024。问题是不少封装格式并不提供 duration 字段很多 packet 拿到的 duration 就是 0。这种时候如果你确实需要它可以自行估算视频用帧率倒数换到流时间基准音频用样本数除以采样率再换到流时间基准。不能直接在程序里硬编码“一包 20ms”因为不同容器、不同编码格式的实际情况差很多。2.4 stream_index 决定数据去向多路流的文件里demuxer 会交替吐出不同流的 packet。假设某个文件有 1 路视频、2 路音频你从 av_read_frame 拿到的 packetstream_index 可能是 0、1、2 中的任何一个。很多初学的代码写成这样if (pkt-stream_index 0) { // 当成视频处理 }这是赌 stream_index 0 一定是视频但文件结构稍微一变就完蛋。正确做法是从 AVFormatContext 里先遍历 streams根据 codecpar-codec_type 判断出 video_stream_index 和 audio_stream_index再用这个索引去比对 packet-stream_index。多路音频字幕的场景还要维护一个数组做映射而不是只认死一个数字。2.5 flags 与 side_data容易被忽略的“标签”AVPacket.flags 是一个位掩码最常用的是AV_PKT_FLAG_KEY表示这个包是关键帧。做视频剪切、seek 定位、流媒体切片时都要靠它。另一个是AV_PKT_FLAG_DISCARD表示解码器可以跳过这个包还有AV_PKT_FLAG_CORRUPT提示包数据可能损坏。side_data 是挂在 packet 上的一堆附加信息形式上类似“快递盒外面额外贴的标签”。常见类型包括调色板数据、回放增益、跳过的样本数、S12M 时间码等。普通播放场景基本不用管它但做专业转码或设备对接时如果发现输出文件出现“公认的奇怪现象”比如音频延迟对不上、画面颜色不对可以检查一下 side_data 是否在转封装过程中丢掉了。查询 side_data 推荐用新版本封装好的接口不要自己从头遍历 side_data_elems 再猜数据类型。3. 引用计数与释放策略别再手动 malloc 了3.1 av_packet_alloc 和 av_packet_free 的正确使用我在早期项目里见过不少代码直接用 av_malloc 分配一个 AVPacket 结构体然后 memset 清零再手动填字段。这种写法在旧版 FFmpeg 里有人这么干但它绕开了内部 buf 指针和 side_data 的所有权管理稍不留神就是 double free 或者内存泄漏。从新版本 API 开始官方思路已经非常明确用 av_packet_alloc 分配用 av_packet_free 释放。AVPacket *pkt av_packet_alloc(); if (!pkt) { // 分配失败处理错误 } // ... 使用 pkt ... av_packet_free(pkt);av_packet_alloc 只负责分配结构体本身不分配数据 buffer所以刚返回时 data 为 NULL、size 为 0。真正的数据 buffer 是在 av_read_frame、avcodec_receive_packet 等函数往里填包时才分配的。av_packet_free 会先自动清理内部持有的数据再把结构体指针置为 NULL避免你手上残留悬空指针。有些教程还会出现 av_init_packet这个函数在较新版本里已经被弃用。如果你看到的示例还在用它建议直接切到 av_packet_alloc 这套新 API。3.2 ref / move_ref / unref 三者有什么区别AVPacket 内部的数据采用引用计数机制。你可以把它想象成多个快递单号指向同一个仓库里的包裹大家通过一份“引用记录”确认包裹什么时候能销毁。av_packet_ref(dst, src)让 dst 共享 src 的数据 buffer内部引用计数加一然后把 src 的字段复制到 dst。之后 dst 和 src 指向同一份数据但彼此是独立的结构体。av_packet_move_ref(dst, src)把 src 持有的数据所有权整体转移给 dstsrc 被清空。这个操作不需要额外增加引用计数效率更高。适合把临时的 packet“上交”给队列或另一个模块交完之后 src 就彻底废了。av_packet_unref(pkt)让当前 packet 不再持有它引用的数据引用计数减一并且把结构体内部字段重置为空状态。注意它不会释放结构体本身所以你还能继续复用它。特别强调一点不要用memcpy(dst, src, sizeof(AVPacket))去复制 packet。这么做会让两个结构体同时持有一个数据引用却没有正确增加引用计数最终大概率导致 double free 或悬空访问。需要复制时就用 av_packet_ref需要把数据本身完整拷贝一份而不是共享时要先确保源是引用计数管理的再考虑其他深拷贝方案。3.3 一个标准解码循环的生命周期拆解把上面的理论落到最常见的解码循环里大概长这样AVPacket *pkt av_packet_alloc(); if (!pkt) return -1; while (av_read_frame(fmt_ctx, pkt) 0) { if (pkt-stream_index video_stream_idx) { int ret avcodec_send_packet(dec_ctx, pkt); while (ret 0) { AVFrame *frame av_frame_alloc(); ret avcodec_receive_frame(dec_ctx, frame); if (ret AVERROR(EAGAIN) || ret AVERROR_EOF) { av_frame_free(frame); break; } // 处理 frame... av_frame_free(frame); } } av_packet_unref(pkt); // 关键一步每次用完后释放引用 } avcodec_send_packet(dec_ctx, NULL); // flush 解码器 av_packet_free(pkt);我在实际项目中发现一个很典型的错误avcodec_send_packet 之后以为 packet 被解码器“拿走”了后面就不去 unref 了。实际上解码器内部会自己增加一个引用调用者这边的引用必须自己负责清理。少了这行 av_packet_unref每读一包就泄漏一批数据。文件又长又复杂的时候内存增长几乎是肉眼可见的。4. 踩坑实录时间戳跳动、seek 后花屏、flush 丢尾帧、内存持续上涨4.1 时间戳跳动都是 time_base 没有换算有一次做 FLV 转 MP4 的转封装输入文件播放正常输出文件放到播放器里却变成“开头正常播几秒后倍速乱跳”。排查到最后发现输出流的 time_base 已经被 muxer 调整了但 packet 的时间戳还是按输入流的 time_base 在传。FLV 里 video 流时间基准是 1/1000MP4 里可能是 1/12800 或者别的值不换算就直接写播放器的时钟换算必然错乱。正确做法是每次写入前做一次时间基准换算av_packet_rescale_ts(pkt, in_stream-time_base, out_stream-time_base);这个函数的三个参数分别是目标 packet、源时间基准、目标时间基准。它内部会同时换算 pts、dts 和 duration省得你手动对每个字段单独乘除。还有一种常见需求是把时间戳换算成微秒int64_t usec av_rescale_q(pkt-pts, in_stream-time_base, AV_TIME_BASE_Q);这个得到的结果才是 FFmpeg 内部统一时间基准下的微秒值适合用来做跨流的比较或 UI 展示。4.2 seek 后花屏关键帧检查不到位做视频播放器时用户拖动进度条程序先 av_seek_frame 定位然后继续读 packet 送解码器。前面的画面经常是花屏或黑屏要过一会儿才正常。原因在于 seek 落点不一定正好是关键帧。解码器从一个非关键帧开始解没有参考帧就无法还原出完整画面。解决思路有两种在读取循环里检查pkt-flags AV_PKT_FLAG_KEY跳到最近的关键帧位置再给用户反馈。不管 seek 到哪儿解码端都做一次 flush先 avcodec_send_packet(dec_ctx, NULL) 把解码器里的残留帧排空再继续正常喂包。另外还需要注意seek 是多路流同时动作的。只 seek 了视频流音频流还在原来的时间位置音画就会错位。实际项目里要根据目标时间点对每一路流做定位并且核对 packet 的 pts 是否落在目标区间附近。4.3 flush 空包丢失最后几帧的隐藏原因编码器因为 B 帧的原因可能已经接收了最后 N 帧输入但迟迟没有把对应的输出 packet 吐出来。如果你以为“编码器没输出就是结束了”最后几帧会永远丢在编码器内部缓存里。标准做法是发送一个空包触发 flushavcodec_send_packet(enc_ctx, NULL); while (avcodec_receive_packet(enc_ctx, enc_pkt) 0) { // 把最后一个编码包写出去 }解码器也有同样的 flush 操作。之前我遇到“视频结尾黑了几帧少了一段”的问题就是在文件读完后忘了 flush 编码器。加上这段代码问题立刻消失。需要留意的是flush 和解码器内部的 avcodec_flush_buffers 是两个动作。前者把缓存中的帧推出来后者清空解码器的内部状态以便 seek 后重新开始。别混淆也别在 flush 之后不清状态就继续读新位置的数据。4.4 内存持续上涨queue 里的 packet 没 unref做多线程音视频处理时我通常会把读到的 packet 按 stream_index 分发到不同的队列交给后台线程处理。队列本身存的是 AVPacket 结构体看起来一切正常但内存却随着播放时长稳步上涨。后来逐一排查发现是消费者线程从队列里取出 packet 后只 memcpy 走了字段没有在读完数据后调用 av_packet_unref。队列里每个 packet 持有的数据 buffer 从不归还自然越积越多。正常做法是在入队时用 av_packet_move_ref 或 av_packet_ref出队处理完成后立即 unref。这里还想分享一个排查技巧内存上涨问题往往不是一下子就能在代码里看出来的。可以先用谷歌手动方法主观猜再用 AddressSanitizer 这类工具跑一遍长视频报错信息通常会精确指向某个未释放的 buf 来自哪一行。比肉眼盯代码可靠得多。5. 一个最小可跑的转封装循环与演进路径5.1 只做转封装的最简循环理解 AVPacket 最快的项目不是转码而是转封装remux。转封装只操作 packet不做编解码省去了 AVFrame 的大量细节非常适合当作“packet 生命周期练习场”。一个最小转封装循环核心逻辑如下AVPacket *pkt av_packet_alloc(); if (!pkt) return -1; int ret; while ((ret av_read_frame(ifmt_ctx, pkt)) 0) { AVStream *in_stream ifmt_ctx-streams[pkt-stream_index]; AVStream *out_stream ofmt_ctx-streams[pkt-stream_index]; // 假设流顺序一一对应 av_packet_rescale_ts(pkt, in_stream-time_base, out_stream-time_base); pkt-stream_index pkt-stream_index; ret av_interleaved_write_frame(ofmt_ctx, pkt); if (ret 0) { // 写文件失败处理 } av_packet_unref(pkt); } av_packet_free(pkt);有人会问为什么用了 av_interleaved_write_frame 之后还要自己 unref因为写函数内部可能异步保留 packet 引用它处理的是自己的那一份引用调用者手里这份还是要自己清理。这个习惯和解码循环里 send 之后 unref 是一回事。5.2 什么时候需要从 packet 升级到 frame 级处理转封装只动了 AVPacket说明整个流程里没有改变音视频内容的需求。如果你开始做滤镜、缩放、裁剪、混音就必须把 packet 解码成 AVFrame 再编码。这时候你会同时接触 decode 侧和 encode 侧的 packet两个方向的时间基准处理要分开看。一个小建议是先把纯转封装跑通并且确保整个循环零泄漏再往里面加解码器。因为转封装流程简洁更容易判断泄漏来自 packet 还是 frame。一旦出现内存问题可以立刻关掉编码器只保留 read decode receive 流程把范围继续缩小。我在实际项目中最受益的一步就是彻底放弃旧示例里手动 malloc 的方式所有 packet 统一走 av_packet_alloc、av_packet_unref、av_packet_free。那之后内存问题少了一大半时间戳问题也更容易顺着 packet 的字段追根溯源。这篇文章要能帮你少踩一点 AVPacket 的坑就算值了。

相关新闻

Claude Code免费攻略:官方额度与本地模型路线全解析

Claude Code免费攻略:官方额度与本地模型路线全解析

最近在几个开发者社群里反复看到同一个问题:Claude Code 这么火,但用起来到底要不要钱?"free-claude-code" 被当成一个口号在传,好像真存在一个零成本的完美入口。我把两条主流路线都实测了一遍——官方免费额度&#x…

2026/10/16 8:00:16 阅读更多 →
毕业论文AI工具组合实测:从选题到答辩的完整闭环方案

毕业论文AI工具组合实测:从选题到答辩的完整闭环方案

每年三月初,我后台收到最多的私信永远是同一句话:毕业论文写不完怎么办。今年情况有了新变化,大家问的不再是“要不要用AI”,而是“AI工具这么多,到底怎么组合才不会翻车”。这个转变很有意思,说明毕业论文…

2026/10/16 7:59:16 阅读更多 →
直线电机Maxwell仿真全流程:空载反电动势、推力与磁阻力拆解

直线电机Maxwell仿真全流程:空载反电动势、推力与磁阻力拆解

1. 项目概述与仿真目标拆解干电机仿真这行久了,你会发现直线电机的仿真跟旋转电机完全是两个世界。旋转电机里的一些成熟套路——比如磁路法算反电动势、齿槽转矩直接扫角度——搬到直线电机上全得重新琢磨,尤其是端部力、磁阻力这些“直线电机专属”的东…

2026/10/16 7:59:16 阅读更多 →

最新新闻

AI是怎么判断一家店值得推荐的?云南老板看完这篇就懂了

AI是怎么判断一家店值得推荐的?云南老板看完这篇就懂了

在昆明开店这些年,最近经常听同行聊起一件事:客人不刷抖音也不翻百度了,直接打开豆包问一句“附近哪家靠谱”。但很多老板发现,自己的店在AI回答里几乎不出现。 这个问题背后,是一套和传统搜索完全不同的推荐逻辑。AI推…

2026/10/16 8:42:43 阅读更多 →
2026 自建聚合大模型网关实战教程:NewAPI 从零部署到客户端接入全流程

2026 自建聚合大模型网关实战教程:NewAPI 从零部署到客户端接入全流程

想在同一个入口里调用多家大模型,又不依赖别人搭好的服务,基于 NewAPI 自建聚合网关是开发圈里常见的做法。NewAPI 是 One-API 的活跃分支,开源免费、兼容 OpenAI 接口格式,既能当个人统一入口,也能做多团队的分发系统…

2026/10/16 8:42:43 阅读更多 →
RFC 3327 解读:Rust Lang 团队顾问(Lang Team Advisors)子团队的正式化设计

RFC 3327 解读:Rust Lang 团队顾问(Lang Team Advisors)子团队的正式化设计

文档 【免费下载链接】rfcs RFCs for changes to Rust 项目地址: https://gitcode.com/gh_mirrors/rf/rfcs 点击查看 免费下载 导读 本篇文章基于仓库中的 RFC 3327:Lang team advisors RFC,系统解读 Rust 语言团队(lang team&a…

2026/10/16 8:42:43 阅读更多 →
从一篇文章到一镜到底的成片:web-video-presentation 网页视频制作完整指南

从一篇文章到一镜到底的成片:web-video-presentation 网页视频制作完整指南

从一篇文章到一镜到底的成片:web-video-presentation 网页视频制作完整指南 【免费下载链接】garden-skills ConardLis open-source Skills collection, featuring web design, knowledge retrieval, image generation, and more. 项目地址: https://gitcode.com/…

2026/10/16 8:42:43 阅读更多 →
lol-skins 中 Inkshadow Lee Sin 幻化(Chroma)资源集:8 个 Chroma ID 全索引、Zip 包结构与 WAD 文件解析

lol-skins 中 Inkshadow Lee Sin 幻化(Chroma)资源集:8 个 Chroma ID 全索引、Zip 包结构与 WAD 文件解析

【免费下载链接】lol-skins Comprehensive collection of League of Legends skins available for custom use. 项目地址: https://gitcode.com/gh_mirrors/lo/lol-skins 点击查看 免费下载 本文以 Inkshadow Lee Sin Chromas 文档为主体,完整收录墨影李…

2026/10/16 8:42:43 阅读更多 →
OpenClaw 实战演示|文件自动归档、网页批量信息采集方案

OpenClaw 实战演示|文件自动归档、网页批量信息采集方案

📌 说明 本文基于 OpenClaw 版本展开讲解,全程采用图形化、可视化的交互模式。整合包已内置全部运行依赖,普通用户也能轻松复现完整的部署流程。 ✨核心亮点: 全程可视化图形交互界面,自动补齐全部运行依赖&#xff0c…

2026/10/16 8:41:42 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/15 9:49:14 阅读更多 →