原生JavaScript实现简易网易云音乐播放器:核心功能与实战解析
写这个“简易网易云音乐播放器”项目的时候我其实挺感慨的。很多人一上来就琢磨怎么对接官方接口、怎么搞会员歌曲解析结果要么碰壁要么直接放弃。其实把播放器的核心骨架搭出来——本地音频加载、播放控制、列表管理、进度同步再把UI做得有质感一些这个项目就已经能学到很多东西了。它适合刚入门前端、想做点完整作品的人也适合想练手桌面应用开发的朋友。这篇文章我就把自己实操过程中踩过的坑、做过的取舍、觉得值得参考的实现方案从头到尾梳理一遍。1. 内容整体设计与思路拆解1.1 先搞清楚“简易播放器”到底要做什么很多人做播放器项目第一步就跑偏了。脑子里想的全是“我要复刻整个网易云”结果做着做着发现功能越加越多代码越堆越乱。我给自己定的目标很明确做一个本地优先的音频播放器核心体验向网易云靠拢——有精美的唱片旋转动画、有播放列表、有歌词展示但所有数据都来自本地文件或自己模拟的数据源。为什么要这样定位因为版权和接口限制决定了你不可能在个人项目里真正接入完整的流媒体服务。与其跟接口较劲不如把精力花在播放器的核心能力上音频的加载与播放控制、播放状态的准确管理、进度条和时间的同步更新、列表的增删切歌逻辑。这些能力是通用的以后你去接任何真实的音乐API代码架构都不用大改。1.2 模块划分和架构选择我把整个项目划分成四个模块播放核心、列表管理、界面渲染、工具函数。播放核心负责音频元素的控制和状态维护列表管理负责歌曲数据的组织与切换界面渲染管DOM更新和动画效果工具函数放时间格式化、随机算法这类纯逻辑。这里有一个关键的设计决策不把播放状态分散在各个组件里而是用一个中心的播放器对象统一管理。所有界面元素都是这个中心对象的“订阅者”状态变了就通知界面去更新。这样做的原因是播放器的状态联动太频繁了——播放、暂停、切歌、进度跳转每一个动作都会同时影响播放按钮、进度条、唱片动画、歌词滚动等多处UI。如果每个组件各管各的状态很容易出现按钮显示在播放、但唱片却没转起来这种不同步的bug。1.3 为什么选择原生技术栈技术选型上我没有引入任何前端框架直接用的原生HTML、CSS、JavaScript。有人可能会问现在谁还用原生写这种项目我的想法是这种偏重交互状态管理的项目恰恰是练原生JS逻辑的好材料。播放器的状态切换链条长、交互密集用原生写一遍你对事件监听、状态同步、DOM操作的理解会深很多。而且没有框架的额外抽象层调试起来更容易看清问题本质。CSS部分我认真做了方案——唱片用圆形旋转动画、进度条用渐变填充、歌词逐行高亮滚动。网易云的音乐播放页视觉上最有辨识度的就是那个旋转唱片和黑胶纹理我用纯CSS就实现了相似效果。2. 核心细节解析与实操要点2.1 音频加载与播放控制机制Audio元素是整个播放器的基石。很多人对audio标签的理解停留在“放个mp3进去就能响”但真正做播放器你会发现它的生命周期管理才是关键。我用的是new Audio()的方式动态创建音频对象而不是在HTML里写死标签。这样做的好处是切歌时可以直接替换audio.src不需要重新渲染DOM节点。加载音频后需要监听一组核心事件loadedmetadata获取音频时长、timeupdate播放中持续触发用于更新进度条、ended播完自动切下一首。这里有一个需要特别注意的地方timeupdate事件大约每250毫秒触发一次如果你在里面直接操作DOM更新进度条性能开销会很大。我的做法是只在事件回调里更新当前时间变量然后通过requestAnimationFrame统一渲染进度条。这样即使快速拖动进度条界面也不会出现卡顿。// 播放核心的简化版 class MusicPlayer { constructor() { this.audio new Audio() this.playlist [] this.currentIndex 0 this.isPlaying false this.audio.addEventListener(timeupdate, () { this.currentTime this.audio.currentTime this.updateProgress() }) this.audio.addEventListener(ended, () { this.next() }) } loadAndPlay(song) { this.audio.src song.url this.audio.play() } }2.2 播放列表的数据结构与排序策略播放列表的数据结构我选择了简单的数组加当前索引的方式没有用复杂的链表。因为播放器的核心操作是“按索引取歌”和“切下一首/上一首”数组的随机访问特性天然适合。当前索引越界的情况要多留意比如删除当前播放的歌曲后索引需要自动修正。顺序播放、随机播放、单曲循环这三种模式我用一个playMode变量控制。随机播放的算法有讲究最简单的做法是Math.floor(Math.random() * playlist.length)但这样容易连续随机到同一首体验不好。我维护了一个随机历史栈每次随机时排除最近三首已播放的歌曲这样随机效果更自然。2.3 进度条与时间显示的联动进度条是播放器里细节最多的地方。我把它分成两层一层是已播放的渐变背景一层是实际可拖动的滑块。点击进度条跳转的交互需要计算点击位置相对于进度条宽度的百分比然后乘以音频总时长得到目标时间点。这里有个容易踩的坑进度条的外层容器如果有padding或者border直接拿click.clientX除以容器宽度会算出偏差。正确的做法是先通过getBoundingClientRect()拿容器的实际位置和尺寸再做差值计算。const seek (event) { const rect progressBar.getBoundingClientRect() const ratio (event.clientX - rect.left) / rect.width const targetTime ratio * player.audio.duration player.audio.currentTime targetTime }拖动过程中的时间显示要跟着变但音频还在继续播放这里我用了一个isDragging标志。拖动时暂停进度条的自动更新松手后再把音频的currentTime跳转过去。如果不加这个标志你拖到一半进度条会被timeupdate拉回去体验非常割裂。2.4 歌词解析与逐行高亮歌词这块我用的LRC格式解析逻辑不复杂但很实用。LRC的格式是[分钟:秒.毫秒]歌词内容一行行拆分后用正则提取时间和文本存成一个对象数组。逐行高亮的核心是监听timeupdate找到当前时间对应的高亮索引把上一条的高亮清除、给当前条加上高亮类名然后用scrollIntoView让歌词行滚动到可视区域。解析正则有个细节要注意LRC里有的时间戳会精确到百分之一秒格式是[01:23.45]秒后面有一个小数点。如果正则写得不严谨会把第一遍匹配到的分秒截断。我用的正则长这样/\[(\d{1,2}):(\d{2})\.(\d{1,2})\]/g分别捕获分、秒、百分秒。3. 实操过程与核心环节实现3.1 搭建基础界面骨架界面布局我参考了网易云的播放页左侧是黑胶唱片和歌曲信息右侧是歌词滚动区。整体配色用的深灰加红心点缀营造那种沉浸式听歌的氛围感。HTML结构相对简单关键是要把播放列表、播放控制栏、歌词区域划分清楚。播放控制栏放在底部固定左边是歌曲封面和歌名歌手中间是播放控制和进度条右边是播放模式、音量控制和播放列表按钮。这种三段式布局在响应式下也比较好处理——小屏幕时隐藏左侧的封面信息只保留核心控制按钮。唱片旋转动画用的是CSS关键帧旋转中心点在圆心。唱片中间我还放了一个固定的小圆点模拟唱片标签。为了让唱片看起来更有质感我叠加了一个径向渐变模拟光线反射转速设置成30s匀速旋转一周。切歌的时候要重置rotation角度否则专辑间切换会有动画突变。.record-disc { width: 200px; height: 200px; border-radius: 50%; background: radial-gradient(circle at 30% 30%, #444, #111); animation: spin 30s linear infinite; animation-play-state: paused; } .record-disc.playing { animation-play-state: running; } keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }3.2 播放列表的实现与交互播放列表我做成侧滑面板从右侧滑出。列表项包含封面缩略图、歌名、歌手和时长。当前播放的那一项会有高亮背景和跳动的音量条动画。点击项就可以一键切换播放双击可以编辑歌词这个功能是我后来加的方便手动调整歌词偏移。列表数据我用了一个模拟接口来获取写了一个getPlaylist()函数模拟异步请求。这样做的好处是UI开发时可以完全不受真实数据格式的限制把数据结构定好之后后面接真实接口只需要改这一个函数。歌曲信息对象的标准化字段 - id唯一标识 - title歌曲名称 - artist歌手 - url音频文件地址 - cover封面图片地址 - duration音频总时长3.3 完整的事件流串联很多教程只教你写代码不教你理解事件流。播放器里最重要的一个事件流是“用户点击播放→音频加载→开始播放→UI同步更新→进度推进→播放完成”。我把每个环节都打了日志在控制台能看到完整的链路。这个习惯在排bug时帮了大忙——有一次切歌后播放按钮状态异常通过日志发现play()方法返回的Promise被reject了原因是切换源太快旧音频还在加载中。解决方法是每次切歌前先取消旧的监听器或者用一个sequence令牌来屏蔽过期回调。类似这种状态竞态问题是播放器开发的高频坑。我推荐一个简单的解决方案维护一个requestVersion计数器每次加载新歌时自增异步回调里判断版本号是否匹配不匹配就直接忽略。十几行代码省掉了很多隐性问题。4. 常见问题与排查技巧实录4.1 音频跨域与资源加载问题开发时如果直接用file://协议打开HTML文件音频加载会受到浏览器安全策略的限制。我本地测试时用的是本地开发服务器比如npx serve部署时放在静态资源服务器上没有遇到过跨域阻塞。但如果你后续接第三方音频链接就得注意跨域策略了。一个方便的做法是给音频元素设置crossOriginanonymous并在服务端配合正确的CORS头。如果音频资源不允许跨域可以做同源代理转发。这个知识点是播放器项目里隐藏的必修课很多人等到部署上线才会被这个问题教训一遍。4.2 播放器音画不同步的调试方法我遇到过好几次播放进度和音频实际播放位置不一致的情况尤其是快速切换歌曲后。排查思路是这样的先确认audio元素的currentTime和我在UI上显示的时间是否一致再检查timeupdate事件回调里是否加了额外延迟最后看requestAnimationFrame渲染时是否拿的是旧数据。这里有一个容易被忽视的细节audio.play()是异步方法它返回的Promise在播放真正开始时才会resolve。如果你在调play()之后立刻读取currentTime拿到的可能是0。需要等timeupdate第一帧触发后才认为音频真的在播放了。4.3 列表删除和切歌的边界情况列表操作里最容易出bug的是“删除当前播放歌曲后再切歌”。如果当前索引已经指向删除项的下一个位置再调用next()会直接跳过一首歌。我做的处理是删除歌曲时如果被删除项索引小于当前索引就把当前索引减一如果删除项就是当前项则立即加载新索引对应的歌曲并保持播放状态。类似的边界情况还有列表为空或只剩一首时切歌按钮应该变成禁用状态播放模式为单曲循环时ended事件应该重新从头播放而不是切下一首。这些都是用户真正会碰到的场景代码里不处理就会在别人试用时直接暴露。4.4 常见问题速查表现象排查方向解决方案播放按钮点击无反应音频URL是否有效、是否是HTTPS协议确认资源可访问性检查控制台错误进度条不走timeupdate事件是否绑定成功确认audio元素非null重新绑定监听唱片不旋转animation-play-state是否切换检查是否添加playing类名切歌后进度条残留新歌元数据未加载完成在loadedmetadata回调中重置进度歌词一直停在第一行歌词时间是否解析正确在控制台打印解析后的歌词数组随机模式连续重复随机算法没有去重用历史记录排除最近歌曲4.5 与真实API对接时的适配层设计前面提到我的数据层是模拟的但代码里我特意预留了一个适配层接口。dataSource对象暴露了fetchPlaylist()和searchSongs()两个方法内部实现可以随时替换。真实对接API时只需要把返回的数据映射到我的标准化字段上即可。我在项目里写了两套数据源一套是本地写死的数据另一套是从JSON文件加载的。切换数据源只需要改配置。这样做的意义在于你的播放器架构本身是完整的只需要在数据入口做转换而不是推倒重来。做技术方案的时候一定要给自己留好这样的扩展位。5. 交互体验的细节打磨5.1 音量控制与静音切换音量控制我用了一个垂直方向的滑块点击喇叭图标可以快速静音/恢复。这里有一个实用的逻辑静音前记住当前音量值取消静音时恢复而不是直接回到最大音量。这个小细节很多人会忽略但实际使用中非常影响体验。音量滑块的控制方式和进度条类似计算滑块轨道内的点击位置百分比映射到0到1的音频音量区间。我还在音量变化时播放一个极短的提示音让用户有更直观的反馈——其实这不算必须但能让整个交互显得更“精致”。5.2 歌曲切歌时的过渡动画直接硬切歌曲会显得很生硬我加了一个淡入淡出的过渡效果切歌前先把音量在300毫秒内衰减到0加载新歌并开始播放后再把音量恢复到原值。实现方法是用requestAnimationFrame逐帧调节音量。注意不能直接设置audio.volume 0然后立刻播放新歌因为Audio元素的音量变化是实时的但在某些浏览器里Volume的衰减可能会有延迟。我的做法是使用一个fadeTimer管理动画帧切歌时先取消旧的动画帧避免并发冲突。5.3 移动端适配的取舍移动端的核心问题是屏幕空间有限。我的适配方案是小屏下隐藏歌词区域只展示唱片动画和播放控制播放列表改成全屏遮罩从底部弹出而非侧边滑出。本来还考虑加手势滑动切歌后来觉得时间成本不划算保留按钮点击即可。我测试的时候发现移动端safari有一个老毛病——音频播放需要用户手势触发否则play()会被拒绝。因此首屏设计了一个“点击进入播放器”的引导页既解决了手势限制也顺便做了一个简单开屏效果。5.4 个性化扩展点这个播放器做了一些个性化的小功能成本低但很提升好感度。比如背景色会根据当前播放歌曲的封面主色渐变用的是封面图取色的方案再比如播放次数统计每次播放完一首歌就累加一次形成简单的个人听歌报告。这些功能都属于“锦上添花”但能让你的项目在展示时更有记忆点。6. 项目的扩展方向与实战建议6.1 从本地播放器到在线服务的升级路径如果你想让这个播放器从demo级别变成真正能上线服务的内容核心要解决的是数据源问题。当前版本的数据是本地模拟的要接真实服务至少需要三个接口歌曲列表接口、歌词接口、搜索接口。这三个接口的数据结构和我的标准化字段不完全一样需要在数据适配层做字段映射。举个例子我的播放器预期的歌曲字段是title、artist、url真实接口返回的可能是songName、singer、audioUrl。解决方式是在适配层写一个转换方法把外部数据结构转换成内部统一结构。内部代码完全不用改动这个项目的架构优势就能体现出来。6.2 增加本地缓存能力在线播放的场景下缓存是提升体验的重要手段。我在项目里预留了缓存接口可以用localStorage保存歌曲描述信息和播放记录用IndexedDB存储大体积的音频blob。实现上不难——拿到音频数据之后转成blob存起来下次播放时先查缓存命中就直接读缓存。有一点要留意IndexedDB的异步API很容易写出回调地狱建议先封装一个Promise风格的存储工具类再在播放器里调用。存储大对象时记得设定合理的过期策略避免存储空间被占满。6.3 播放器的工程化改造如果你不满足于“写完了能跑”还想进一步打磨工程能力我建议做三件事引入模块打包工具比如Vite、使用TypeScript重写类型声明、给播放核心的每个状态机写单元测试。这三件事做完这个小项目就能作为面试作品或简历里的项目经验含金量会高不少。TypeScript这块我尝过甜头尤其是给播放模式定义联合类型、给歌曲对象定义接口的时候编译期就能拦截很多粗心错误。单元测试方面重点测三个纯函数歌词时间解析器、随机播放的去重算法、时间格式化工具这三个逻辑是播放器里最容易回归出错的地方。6.4 基于云服务搭建真实数据层的方案更进一步设想你可以把播放器的数据源换成真实的云存储把歌曲文件放在对象存储中用内容分发网络加速访问歌词和歌单数据放在轻量级的文档数据库里。播放器代码不需要大改只需要重写数据适配层的方法实现。这样这个简易播放器就可以从纯前端的demo升级成一个小型但完整的全栈应用。我个人觉得这类项目最值得学习的不是某个具体功能而是这种“先骨架后血肉”的开发思路。先定好模块边界和数据格式再逐个实现细节功能整个过程会非常顺畅不太会出现写到一半要推翻重来的窘境。最后分享一个自己在实际过程中总结的经验——播放器项目调试时一定要善用浏览器的Media Session API。这个API能让你的播放器对接系统级媒体控制中心在锁屏界面显示歌曲信息、支持耳机线控切歌。接入成本不到十行代码但带来的体验提升是肉眼可见的。哪怕你不做移动端只做桌面浏览器适配这个API也能让你的标题栏上的媒体菜单里出现你正在播放的歌曲和操作按钮。这是我在做这个项目时最后加上来的一个彩蛋也是一次比较有价值的探索。

相关新闻

学成在线PSD前端练手:从设计稿到HTML/CSS完整还原流程

学成在线PSD前端练手:从设计稿到HTML/CSS完整还原流程

简介:一套面向网页设计入门与前端开发初学者的学成在线案例资源,源自黑马程序员及Pink老师课程体系,将PSD设计稿与HTML/CSS实现打包到一起。设计稿涵盖首页、课程列表页、课程介绍页、职业规划页等典型页面,适合用于训练从设计图到…

2026/10/17 22:10:11 阅读更多 →
Windows下MySQL ODBC数据源配置:从驱动安装到DSN排错

Windows下MySQL ODBC数据源配置:从驱动安装到DSN排错

简介:这是一份面向数据库应用开发与运维人员的操作指南,重点讲解如何将MySQL数据库配置为ODBC数据源,从而让不同应用程序或系统通过标准接口连接并共享数据。内容覆盖从下载安装MySQL ODBC驱动、在控制面板创建系统DSN,到填写服务…

2026/10/17 22:10:11 阅读更多 →
数据中心智能化运维:从监控指标采集到告警降噪的落地实践

数据中心智能化运维:从监控指标采集到告警降噪的落地实践

简介:一份围绕数据中心智能化运维的DOCX文档,面向数据中心运维工程师、IT管理人员及系统学习者,系统梳理智能化运维的核心策略。内容涵盖智能化设备管理、资源调度、任务分配、监控报警四类关键手段,既说明借助传感器、物联网与人…

2026/10/17 22:10:11 阅读更多 →

最新新闻

Linux源码编译安装libcurl库:从configure到静态链接全攻略

Linux源码编译安装libcurl库:从configure到静态链接全攻略

1. 换一条路装库:为什么有时候必须用源码压缩包说起Linux下安装第三方库,很多人第一反应是apt install或者yum install。这确实是最省事的方案,但我在做项目时,经常发现包管理器这条路走不通,最后不得不老老实实下载源…

2026/10/17 23:04:59 阅读更多 →
HashMap 1.7源码深度解析:put、resize与多线程死循环原理

HashMap 1.7源码深度解析:put、resize与多线程死循环原理

1. 为什么“撕源码”不是炫技,而是理解HashMap 1.7的唯一路径你有没有在面试时被问到:“HashMap在JDK 1.7里是怎么扩容的?”答:“哦,它会rehash,把老数组里的Entry一个个挪到新数组里。”面试官点点头&…

2026/10/17 23:04:59 阅读更多 →
2026最新GPT-5.5深度评测:Agent架构解析与API选型

2026最新GPT-5.5深度评测:Agent架构解析与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/17 23:03:58 阅读更多 →
Oracle Procedure 返回数据集:TaoToken 场景下的 Ref Cursor 与临时表选型小结

Oracle Procedure 返回数据集:TaoToken 场景下的 Ref Cursor 与临时表选型小结

/* 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 23:03:58 阅读更多 →
2026就业新赛道:一人如何利用AI智能体制作漫剧?五大主流工具深度测评与TaoToken统一接入实践

2026就业新赛道:一人如何利用AI智能体制作漫剧?五大主流工具深度测评与TaoToken统一接入实践

/* 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 23:03:58 阅读更多 →
openclaw工作区workspace文件配置与管理完全指南:从目录结构到TaoToken统一Key接入

openclaw工作区workspace文件配置与管理完全指南:从目录结构到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 23:03:58 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 21:54:38 阅读更多 →
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/16 14:23:36 阅读更多 →