【SwiftUI提高练中学】第16课 音频与视频:AVFoundation 进阶与底层机制
主要目标系统掌握 AVFoundation 进阶能力深入理解 AVAudioEngine 的节点图架构、AVAudioSession 的深度管理、AVAudioConverter 的格式转换机制、以及 AVMutableComposition 的视频合成与导出流程。第一部分 深度精讲一、AVAudioEngine音频节点图架构1.1 AVAudioEngine 的核心定位AVAudioEngine是 AVFoundation 中用于实时和离线音频处理的核心类。它管理一个音频节点图audio node graph支持播放、录制、混音、效果处理和 3D 空间化。与AVAudioPlayer的简单播放不同AVAudioEngine提供可编程的音频路由能力开发者可以创建节点、连接节点、在节点之间插入效果器构建任意复杂的音频处理管线。1.2 三种核心节点类型AVAudioEngine 的节点图由三种核心节点类型构成节点类型代表类职责输出节点outputNode将音频发送到硬件输出扬声器混音器节点mainMixerNode、AVAudioMixerNode混合多路音频信号支持音量控制播放器节点AVAudioPlayerNode播放音频文件或缓冲区此外还有输入节点inputNode麦克风输入和效果节点AVAudioUnitEffect的子类如混响、延迟、失真。1.3 节点图的连接规则节点之间的连接是 AVAudioEngine 的核心操作。connect(_:to:format:)方法建立从源节点输出总线到目标节点输入总线的连接importAVFoundationletengineAVAudioEngine()letplayerAVAudioPlayerNode()letreverbAVAudioUnitReverb()engine.attach(player)engine.attach(reverb)// 连接player → reverb → mainMixerNode → outputNodeengine.connect(player,to:reverb,format:nil)engine.connect(reverb,to:engine.mainMixerNode,format:nil)关键细节mainMixerNode是引擎自动创建的无需手动 attach。当向mainMixerNode发起连接时引擎会自动配置outputNode的连接。format参数设为nil表示使用默认格式。1.4 多通道处理AVAudioEngine 支持多通道音频处理。对于多通道输入如 4 通道 USB 音频接口可以通过AVAudioConnectionPoint将一个多通道源连接到多个目标// 将 4 通道输入分发到 4 条独立的效果链letinputNodeengine.inputNodeletinputFormatinputNode.outputFormat(forBus:0)varconnectionPoints:[AVAudioConnectionPoint][]foriin0..4{letmixerAVAudioMixerNode()engine.attach(mixer)connectionPoints.append(AVAudioConnectionPoint(node:mixer,bus:0))}engine.connect(inputNode,to:connectionPoints,fromBus:0,format:inputFormat)需要注意AVAudioMixerNode的channelMap属性无法直接实现通道分离——混音器的channelMap仅能重映射声道不能将多通道总线拆分为多个单通道总线。真正的通道分离需要 Matrix Mixer 音频单元。1.5 Swift Concurrency 下的音频引擎管理在 Swift 6 中AVAudioEngine的节点操作需要在正确的 Actor 上执行。推荐使用MainActor隔离管理 UI 交互将音频处理保持在引擎的实时渲染线程上MainActorfinalclassAudioEngineManager{privateletengineAVAudioEngine()privateletplayerAVAudioPlayerNode()funcstart()throws{engine.attach(player)engine.connect(player,to:engine.mainMixerNode,format:nil)tryengine.start()}funcplay(buffer:AVAudioPCMBuffer){player.scheduleBuffer(buffer)player.play()}}重要提醒当引擎正在运行时动态 attach/detach 节点可能导致爆音或崩溃。应在引擎停止状态下修改节点图修改完成后再重新启动。二、AVAudioSession深度配置与管理2.1 音频会话的职责边界AVAudioSession是 App 与系统音频硬件之间的中介。它负责描述 App 的音频行为类别和模式、管理音频路由变化、处理音频中断、协调多 App 的音频竞争。2.2 类别与模式的完整选择类别静音拨片后台播放混合录音.playback忽略支持否否.ambient遵循否是否.record—否否是.playAndRecord遵循是可选是.multiRoute忽略否否可选模式进一步细化行为.moviePlayback、.spokenAudio、.voiceChat、.measurement、.gameChat。2.3 路由变化处理Apple 官方文档明确指出“应用程序应尊重此隐含的隐私请求并在用户断开耳机时自动暂停播放”。路由变化通知包含原因信息.newDeviceAvailable新设备可用如插入耳机.oldDeviceUnavailable旧设备不可用如拔出耳机funcobserveRouteChanges(){NotificationCenter.default.addObserver(forName:AVAudioSession.routeChangeNotification,object:AVAudioSession.sharedInstance(),queue:.main){notificationinguardletuserInfonotification.userInfo,letreasonValueuserInfo[AVAudioSessionRouteChangeReasonKey]as?UInt,letreasonAVAudioSession.RouteChangeReason(rawValue:reasonValue)else{return}ifreason.oldDeviceUnavailable{// 耳机被拔出——暂停播放}}}2.4 prefersInterruptionOnRouteDisconnectiOS 17从 iOS 17 开始AVAudioSession新增了prefersInterruptionOnRouteDisconnect属性。该属性默认为true表示当活动路由断开时系统会中断音频会话。这意味着 App 无需手动监听路由变化来暂停播放——系统会自动中断会话App 只需处理中断通知即可。三、AVAudioConverter音频格式转换3.1 AVAudioConverter 的核心能力AVAudioConverter用于在音频格式和编码之间转换。支持的转换类型包括PCM 浮点/整数/位深转换、PCM 采样率转换、PCM 交错/去交错、PCM 编码为压缩格式、压缩格式解码为 PCM。单个转换器实例可以同时执行多种转换。3.2 转换的基本流程importAVFoundationfuncconvertAudio(inputURL:URL,outputFormat:AVAudioFormat)throws{letinputFiletryAVAudioFile(forReading:inputURL)letinputFormatinputFile.processingFormatguardletconverterAVAudioConverter(from:inputFormat,to:outputFormat)else{throwConversionError.cannotCreateConverter}letoutputBufferAVAudioPCMBuffer(pcmFormat:outputFormat,frameCapacity:AVAudioFrameCount(outputFormat.sampleRate*1.0))!varinputBuffer:AVAudioPCMBuffer?AVAudioPCMBuffer(pcmFormat:inputFormat,frameCapacity:AVAudioFrameCount(inputFormat.sampleRate*1.0))// 使用 convert(to:error:withInputFrom:) 进行流式转换varerror:NSError?letstatusconverter.convert(to:outputBuffer,error:error){_,outStatusinifletbufferinputBuffer{inputBufferniloutStatus.pointee.haveDatareturnbuffer}else{outStatus.pointee.endOfStreamreturnnil}}// 处理 status 和 error}关键细节convert(to:error:withInputFrom:)方法通过 input block 按需拉取输入数据适合流式转换。AVAudioConverterInputStatus和AVAudioConverterOutputStatus枚举定义了转换状态。3.3 通道映射与混音AVAudioConverter提供channelMap属性用于指定输出通道与输入通道的映射关系。当需要将立体声降为单声道时设置downmix true让框架混合通道而非简单丢弃。3.4 采样率转换质量sampleRateConverterQuality属性控制采样率转换的算法质量。对于实时场景如音频播放较低的 quality 值可以减少 CPU 占用对于离线转换可以使用最高质量。四、AVMutableComposition视频合成与导出4.1 AVMutableComposition 的核心能力AVMutableComposition用于从已有资源创建新的合成媒体。它支持添加和移除轨道、添加和移除时间范围、缩放时间范围。主要操作包括方法用途insertTimeRange(_:of:at:)将资源的时间范围插入合成removeTimeRange(_:)移除指定时间范围scaleTimeRange(_:toDuration:)缩放时间范围调速insertEmptyTimeRange(_:)插入空白时间范围removeTrack(_:)移除轨道4.2 视频合成的基本流程funcmergeVideoAndAudio(videoURL:URL,audioURL:URL)asyncthrows-AVAsset{letcompositionAVMutableComposition()// 加载资源letvideoAssetAVURLAsset(url:videoURL)letaudioAssetAVURLAsset(url:audioURL)// 添加视频轨道guardletvideoTracktryawaitvideoAsset.loadTracks(withMediaType:.video).firstelse{throwCompositionError.noVideoTrack}letcompositionVideoTrackcomposition.addMutableTrack(withMediaType:.video,preferredTrackID:kCMPersistentTrackID_Invalid)trycompositionVideoTrack?.insertTimeRange(CMTimeRange(start:.zero,duration:videoAsset.duration),of:videoTrack,at:.zero)// 添加音频轨道guardletaudioTracktryawaitaudioAsset.loadTracks(withMediaType:.audio).firstelse{throwCompositionError.noAudioTrack}letcompositionAudioTrackcomposition.addMutableTrack(withMediaType:.audio,preferredTrackID:kCMPersistentTrackID_Invalid)trycompositionAudioTrack?.insertTimeRange(CMTimeRange(start:.zero,duration:audioAsset.duration),of:audioTrack,at:.zero)returncomposition}4.3 AVAssetExportSession导出合成结果AVAssetExportSession将合成后的资源导出为指定格式。推荐使用新的异步导出方法export(to:as:)iOS 13funcexportComposition(_composition:AVAsset,to outputURL:URL)asyncthrows{guardletexportSessionAVAssetExportSession(asset:composition,presetName:AVAssetExportPresetHighestQuality)else{throwExportError.cannotCreateSession}// 使用新的异步导出 APItryawaitexportSession.export(to:outputURL,as:.mp4)}关键细节export(to:as:)方法会抛出错误如果导出被取消或指定的文件类型不在supportedFileTypes中。可以通过states(updateInterval:)方法监控导出进度。4.4 导出预设的选择预设适用场景AVAssetExportPresetLowQuality低质量预览AVAssetExportPresetMediumQuality中等质量AVAssetExportPresetHighestQuality最高质量AVAssetExportPresetHEVCHighestQualityHEVC 编码最高质量五、本课小结AVAudioEngine节点图架构支持任意复杂的音频处理管线。三种核心节点类型输出节点、混音器节点、播放器节点通过connect(_:to:format:)连接。多通道处理需通过AVAudioConnectionPoint分发。AVAudioSession类别和模式决定 App 的音频行为。路由变化需观察routeChangeNotificationoldDeviceUnavailable时应暂停播放。iOS 17 的prefersInterruptionOnRouteDisconnect简化了路由断开处理。AVAudioConverter支持 PCM 位深、采样率、交错/去交错、编码/解码转换。convert(to:error:withInputFrom:)提供流式转换能力channelMap和downmix控制通道映射。AVMutableComposition AVAssetExportSession视频合成通过insertTimeRange(_:of:at:)插入轨道片段scaleTimeRange(_:toDuration:)调速。导出使用export(to:as:)异步方法。第二部分 习题与答案解读每题后紧跟答案和解读共15题。习题1【单选】AVAudioEngine 的三种核心节点类型以下哪项不是 AVAudioEngine 的核心节点类型A. 输出节点outputNodeB. 混音器节点AVAudioMixerNodeC. 播放器节点AVAudioPlayerNodeD. 编解码节点AVAudioCodecNode答案D解读AVAudioEngine 的三种核心节点类型是输出节点、混音器节点和播放器节点。AVAudioCodecNode不是标准节点类型。编解码通过 AVAudioConverter 或 AVAudioUnit 子类处理。习题2【判断】mainMixerNode 需要手动 attach 到引擎答案错误解读mainMixerNode是引擎自动创建的无需手动 attach。当向mainMixerNode发起连接时引擎会自动配置outputNode的连接。习题3【多选】AVAudioConverter 支持哪些转换类型A. PCM 浮点/整数位深转换B. PCM 采样率转换C. PCM 交错/去交错D. 音频特效处理E. PCM 编码为压缩格式答案A、B、C、E解读AVAudioConverter 支持 PCM 位深转换、采样率转换、交错/去交错、编码和解码。D 错误——音频特效处理属于 AVAudioUnitEffect 的范畴不是格式转换。习题4【单选】路由变化时暂停播放的正确原因值当用户拔出耳机时路由变化通知中的原因值是什么A..newDeviceAvailableB..oldDeviceUnavailableC..categoryChangeD..override答案B解读当用户移除设备时原因为.oldDeviceUnavailable。Apple 官方文档明确指出应用程序应在用户断开耳机时自动暂停播放尊重用户的隐私请求。习题5【简答】AVAudioEngine 的节点图连接规则是什么答案节点之间的连接通过connect(_:to:format:)方法建立。mainMixerNode是引擎自动创建的无需手动 attach。连接时需要先用attach(_:)将节点添加到引擎然后建立连接。format参数设为nil表示使用默认格式。引擎停止状态下修改节点图更安全运行时动态修改可能导致爆音或崩溃。习题6【多选】以下哪些是 AVMutableComposition 支持的操作A.insertTimeRange(_:of:at:)插入资源时间范围B.removeTimeRange(_:)移除时间范围C.scaleTimeRange(_:toDuration:)缩放时间范围D.export(to:as:)导出合成结果E.insertEmptyTimeRange(_:)插入空白时间范围答案A、B、C、E解读AVMutableComposition 支持插入、移除、缩放时间范围和插入空白时间范围。D 错误——export(to:as:)是 AVAssetExportSession 的方法不是 AVMutableComposition 的。习题7【代码补全】连接 AVAudioEngine 节点补全代码将播放器节点连接到混响效果器再连接到主混音器。letengineAVAudioEngine()letplayerAVAudioPlayerNode()letreverbAVAudioUnitReverb()engine.attach(player)engine.attach(reverb)engine.connect(player,to:__________,format:nil)engine.connect(reverb,to:__________,format:nil)答案engine.connect(player,to:reverb,format:nil)engine.connect(reverb,to:engine.mainMixerNode,format:nil)解读节点连接的方向是从源节点到目标节点。player 的输出连接到 reverb 的输入reverb 的输出连接到 mainMixerNode。习题8【简答】prefersInterruptionOnRouteDisconnect的作用是什么答案从 iOS 17 开始AVAudioSession新增了prefersInterruptionOnRouteDisconnect属性。该属性默认为true表示当活动路由断开时如拔出耳机系统会中断音频会话。这意味着 App 无需手动监听路由变化来暂停播放——系统会自动中断会话App 只需处理中断通知即可。习题9【判断】AVAudioConverter 的 downmix 属性用于通道映射答案错误解读downmix属性用于让框架混合通道如将立体声降为单声道而非通道映射。通道映射通过channelMap属性实现它指定输出通道与输入通道的映射关系。习题10【代码补全】使用 AVAssetExportSession 导出补全代码将合成后的资源导出为 MP4 文件。guardletexportSessionAVAssetExportSession(asset:composition,presetName:__________)else{throwExportError.cannotCreateSession}tryawaitexportSession.export(to:outputURL,as:__________)答案presetName:AVAssetExportPresetHighestQuality// ...tryawaitexportSession.export(to:outputURL,as:.mp4)解读AVAssetExportPresetHighestQuality是最高质量的导出预设。export(to:as:)是 iOS 13 引入的异步导出方法as参数指定输出文件类型。习题11【多选】以下关于 AVAudioSession 类别选择的说法哪些正确A..playback类别忽略静音拨片B..ambient类别遵循静音拨片C..record类别支持后台播放D..playAndRecord类别支持录音和播放E..multiRoute类别支持混合其他音频答案A、B、D解读.playback忽略静音拨片且支持后台播放。.ambient遵循静音拨片且可混合。.record不支持后台播放。.playAndRecord支持录音和播放。.multiRoute用于高级音频路由不自动支持混合。习题12【简答】AVAudioEngine 在多通道处理中如何将多通道输入分发到多个效果链答案使用AVAudioConnectionPoint将一个多通道源连接到多个目标。每个AVAudioConnectionPoint指定目标节点和总线号。需要注意AVAudioMixerNode的channelMap无法实现通道分离——真正的通道分离需要使用 Matrix Mixer 音频单元。varconnectionPoints:[AVAudioConnectionPoint][]foriin0..4{letmixerAVAudioMixerNode()engine.attach(mixer)connectionPoints.append(AVAudioConnectionPoint(node:mixer,bus:0))}engine.connect(inputNode,to:connectionPoints,fromBus:0,format:inputFormat)习题13【代码补全】处理路由变化补全代码在耳机被拔出时暂停播放。NotificationCenter.default.addObserver(forName:AVAudioSession.__________,object:AVAudioSession.sharedInstance(),queue:.main){notificationinguardletuserInfonotification.userInfo,letreasonValueuserInfo[AVAudioSessionRouteChangeReasonKey]as?UInt,letreasonAVAudioSession.RouteChangeReason(rawValue:reasonValue)else{return}ifreason.__________{// 耳机被拔出——暂停播放}}答案forName:AVAudioSession.routeChangeNotification// ...ifreason.oldDeviceUnavailable{解读routeChangeNotification是路由变化通知的名称。oldDeviceUnavailable表示旧设备如耳机不可用此时应暂停播放。习题14【简答】AVAudioConverter 的采样率转换质量属性有什么作用答案sampleRateConverterQuality属性控制采样率转换的算法质量。值越高转换质量越好但 CPU 占用也越高。对于实时场景如音频播放可以使用较低的质量值减少 CPU 占用对于离线转换如导出音频文件可以使用最高质量确保输出品质。习题15【综合论述】如何构建一个完整的音频处理管线答案构建完整的音频处理管线需要整合以下能力1. 引擎与节点配置。使用 AVAudioEngine 创建引擎实例通过attach(_:)添加节点通过connect(_:to:format:)建立连接。三种核心节点类型输出节点、混音器节点、播放器节点构成基础架构。2. 效果处理。在节点之间插入AVAudioUnitEffect子类混响、延迟、失真构建效果链。多通道场景使用AVAudioConnectionPoint分发。3. 会话管理。使用 AVAudioSession 配置类别和模式监听路由变化和中断通知确保音频行为符合用户预期。4. 格式转换。使用 AVAudioConverter 处理采样率、位深、编码格式的转换确保输入输出格式兼容。5. 并发管理。在 Swift 6 中节点操作在MainActor上执行音频处理保持在实时渲染线程。避免在引擎运行时动态修改节点图。核心原则音频处理管线的稳定性取决于对节点图连接规则、音频会话生命周期和并发边界的精确管理。第三部分 知识点总结1. AVAudioEngine 节点图节点类型代表类职责输出节点outputNode发送音频到硬件输出混音器节点mainMixerNode、AVAudioMixerNode混合多路音频信号播放器节点AVAudioPlayerNode播放音频文件或缓冲区效果节点AVAudioUnitEffect子类混响、延迟、失真等输入节点inputNode麦克风输入2. AVAudioSession 类别选择类别静音拨片后台播放混合录音.playback忽略支持否否.ambient遵循否是否.record—否否是.playAndRecord遵循是可选是3. AVAudioConverter 转换能力转换类型说明位深转换PCM 浮点/整数转换采样率转换质量由sampleRateConverterQuality控制交错/去交错PCM 交错格式转换编码/解码PCM ↔ 压缩格式通道映射channelMap和downmix4. AVMutableComposition 操作方法用途insertTimeRange(_:of:at:)插入资源时间范围removeTimeRange(_:)移除时间范围scaleTimeRange(_:toDuration:)缩放时间范围调速insertEmptyTimeRange(_:)插入空白时间范围5. 常见陷阱在引擎运行时动态 attach/detach 节点导致爆音或崩溃混淆AVAudioMixerNode.channelMap与通道分离无法将多通道拆分为多个单通道在 App 启动时立即激活音频会话应延迟到播放开始不处理路由变化耳机拔出时音频外放侵犯用户隐私使用已弃用的exportAsynchronously而非export(to:as:)6. 行动清单使用 AVAudioEngine 构建音频处理管线注意节点连接规则在引擎停止状态下修改节点图使用 AVAudioConnectionPoint 实现多通道分发配置 AVAudioSession 类别和模式监听路由变化和中断使用 iOS 17 的prefersInterruptionOnRouteDisconnect简化路由断开处理使用 AVAudioConverter 处理格式转换注意采样率质量设置使用 AVMutableComposition 合成媒体注意时间范围操作使用 AVAssetExportSession 的export(to:as:)异步导出在 Swift 6 中使用MainActor管理引擎生命周期为音频处理管线添加完整的错误处理

相关新闻

PCA9422与STM32F417ZG电源管理方案实战:寄存器配置与调试要点

PCA9422与STM32F417ZG电源管理方案实战:寄存器配置与调试要点

不必从零开始摸索完整电源管理方案。我直接把基于 PCA9422 和 STM32F417ZG 的整套实现思路、寄存器配置、初始化代码和踩坑记录整理出来,给正在做便携设备、手持终端或电池供电产品的工程师一个可直接落地的参考。1. 整体方案设计:为什么是 PCA9422 STM…

2026/10/9 12:10:18 阅读更多 →
Go语言net包TCP服务端优雅关闭与SO_REUSEADDR实战

Go语言net包TCP服务端优雅关闭与SO_REUSEADDR实战

Go语言net包TCP服务端优雅关闭与SO_REUSEADDR实战 导语 在生产环境中,TCP服务的启停是高频操作。一个设计良好的TCP服务端应该支持优雅关闭(Graceful Shutdown),即在收到停止信号时,不再接受新连接,但会等待…

2026/10/9 12:10:18 阅读更多 →
时钟概念引入

时钟概念引入

引言你有没有想过:你的 ARM-CPU 能从 Flash 上读取代码并执行,可是是谁让 ARM-CPU 读取指令的?你的 ARM-CPU 能一直从 Flash 上读取代码并执行,可是是谁一直让 ARM-CPU 读取指令的?事实上任何计算机系统,包…

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

最新新闻

SpringBoot+MyBatis-Plus多数据源实战:从配置到踩坑

SpringBoot+MyBatis-Plus多数据源实战:从配置到踩坑

如果你跟我一样在业务增长比较快的团队里做后端,大概率早晚会遇到同一个SpringBoot项目连两个甚至多个数据库的需求。我最早碰多数据源是在订单和报表分库的时候,主库扛写入,报表库跑复杂查询,两边数据要在一个服务里同时访问。当…

2026/10/9 12:45:12 阅读更多 →
大屏开发必备:89字节最短CSS性能优化实践

大屏开发必备:89字节最短CSS性能优化实践

1. 为什么“最短CSS”在大数据演示屏里不是炫技,而是刚需你有没有见过那种大屏项目:前端同事写完一版,部署到LED拼接屏上,CPU占用率直接飙到95%,动画卡成PPT,运维半夜被报警电话叫醒?我去年参与…

2026/10/9 12:45:12 阅读更多 →
iOS NSData 源码实战:二进制数据处理与避坑指南

iOS NSData 源码实战:二进制数据处理与避坑指南

简介:这份资源是面向iOS开发初学者与进阶者的NSData实战源码包,聚焦Objective-C中Foundation框架核心类NSData的数据处理能力。内容围绕二进制数据存储、文件读写、JSON序列化与归档、Base64编码、AES加密、网络请求体封装及图片数据转换等典型场景展开&…

2026/10/9 12:45:12 阅读更多 →
JSONP跨域请求原理详解与实战实现方案

JSONP跨域请求原理详解与实战实现方案

1. 跨域请求的痛点与 JSONP 的诞生逻辑前后端分离开发的日常里,跨域几乎是绕不开的一道坎。前端页面跑在http://localhost:8080,后端接口部署在http://api.example.com,浏览器控制台立刻甩出一行红字:Access-Control-Allow-Origin…

2026/10/9 12:45:12 阅读更多 →
HTTP为何能靠TCP“躺赢”?从协议栈分工到工业排障全解析

HTTP为何能靠TCP“躺赢”?从协议栈分工到工业排障全解析

把Wireshark打开,盯一条HTTP请求的完整生命周期走一遍,你大概率会得出跟我一样的结论:HTTP跑起来实在是太省心了。丢包重传、乱序重组、连接建立与释放、流量与拥塞控制,这些又脏又累的活,统统被TCP协议扛在了自己肩上…

2026/10/9 12:45:12 阅读更多 →
TX1串口调试实战:ttyTHS1与ttyTHS2区别、配置与避坑指南

TX1串口调试实战:ttyTHS1与ttyTHS2区别、配置与避坑指南

1. 从一块开发板的调试口说起:tx1串口到底特殊在哪很多人第一次接触tx1的串口,都是因为系统起不来、网络不通、或者想进控制台看看内核打印。这块板子的串口不像普通单片机那样随便找个UART就能用,它的调试串口和通用串口在设备树里是分开配置…

2026/10/9 12:44:11 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 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/8 21:13:17 阅读更多 →
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/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练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/9 6:17:20 阅读更多 →