从零部署开源流媒体下载工具 FlowPick:Nuxt 4 项目本地跑起来 + 二次开发实战

一、前言:为什么值得自己部署一套

FlowPick 是一个隐私优先 的流媒体下载工具,同时提供浏览器扩展和在线网页两种形态,支持 HLS(.m3u8)和 DASH(.mpd)协议的视频流、音频、图片的嗅探、下载、合并与转码。它的核心设计是:所有媒体处理都在浏览器内用 FFmpeg WASM 完成,文件不落第三方服务器。

正因为开源、本地处理、可改可部署,很多团队会把它改造成内部工具(比如合规的网课归档、素材采集)。本文以FlowPick官方仓库为例,带你把项目在本地跑起来,并给出二次开发和上线的实操要点。


二、环境准备

依赖 版本建议 说明
Node.js 20 LTS 及以上 Nuxt 4 的运行要求
包管理器 pnpm 仓库脚本基于 pnpm;npm/yarn 亦可但需自行对齐 lockfile
Git 任意新版 拉取源码

确认环境:

bash 复制代码
node -v   # 建议 v20.x 或更高
pnpm -v

三、克隆与依赖安装

以官方仓库为例(若你已 fork,替换成自己的地址即可):

bash 复制代码
git clone https://github.com/ezwebtools/flowpick.git
cd flowpick
pnpm install

注意:package.json 里配了 postinstall 自动执行 nuxt prepare,会生成类型声明和路由清单,首次安装稍慢属正常。如果中途中断,可手动补一次 pnpm exec nuxt prepare。


四、本地启动与调试

启动开发服务器:

bash 复制代码
pnpm dev

默认监听 http://localhost:3000。几个常用入口:

  • / ------ 落地页
  • /m3u8-downloader ------ HLS 下载器
  • /dash-downloader ------ DASH 下载器
  • /docs ------ 文档站(基于 @nuxt/content)
  • /blog ------ 博客

调试下载逻辑时建议直接开 /m3u8-downloader 或 /dash-downloader 页面,粘贴流地址即可,比扩展更方便。


五、构建与本地预览

生产构建:

bash 复制代码
pnpm build
pnpm preview

pnpm build 产物在 .output/(Nitro 预设为 cloudflare-pages-static,输出的是静态资源)。本地预览用 pnpm preview 验证产物是否符合预期。

要跑类型检查或 lint:

bash 复制代码
pnpm typecheck
pnpm lint

六、项目结构速览

bash 复制代码
app/
├── pages/                # 路由页:index / m3u8-downloader / dash-downloader / docs / blog ...
├── composables/          # 核心逻辑
│   ├── useStreamMerge.ts # 切片下载、解密、合并、写入(下载引擎核心)
│   └── useFFmpeg.ts      # FFmpeg WASM 加载与转码
├── components/           # UI 组件(Nuxt UI)
content/                  # 文档/博客/多语言落地页(yml + md,Zod 校验)
nuxt.config.ts            # 模块、i18n、路由头、runtimeConfig

下载引擎的两个 composable 是二次开发的重点,对外暴露的接口很清晰,例如:

typescript 复制代码
// useStreamMerge.ts 核心入参
export interface StreamMergeOptions {
  segments: ArrayBuffer[] | AsyncGenerator<ArrayBuffer>
  totalSegments: number
  filename: string
  outputFormat?: 'mp4' | 'ts'
  onProgress?: (progress: StreamMergeProgress) => void
  signal?: AbortSignal
}

七、二次开发实战

1. 改文案 / 文档(零代码)

content/ 下是 Markdown 与 YAML,落地页、文档、博客都在这。改完即生效(dev 热更新),且字段受 content.config.ts 里的 Zod schema 约束,写错会在构建时报出来。比如想加一个中文使用场景文档,直接在 content/zh-Hans/1.docs/ 下新建 .md 并在对应 .navigation.yml 登记即可。

2. 调下载引擎参数

打开 app/composables/useStreamMerge.ts:

  • 并发数:默认 2,范围 1--8,可按网络调;
  • 重试策略:指数退避,最多 3 次(仅对网络级临时失败重试,4xx 不重试);
  • 三层写入降级:FSA → StreamSaver → Blob,自动按浏览器能力和文件大小选择;
  • AES-128 解密:走 Web Crypto API,密钥不外传。

想换默认输出格式(MP4/TS)或加自定义合并逻辑,改这里最直接。

3. 改配置(nuxt.config.ts)

  • 多语言 :i18n.locales 已内置 en / zh-Hans / zh-Hant / ja / ko,增减语言在此;
  • 统计/埋点 :runtimeConfig.public 有 clarityId、gaId,对应环境变量 NUXT_PUBLIC_CLARITY_ID、NUXT_PUBLIC_GA_ID,不想接就留空;
  • 路由头 :下载器路由配了 Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp,这是刻意开启 cross-origin isolation 的,目的见下一节。

八、部署上线要点

默认 Nitro 预设是 cloudflare-pages-static,构建出静态产物,可直接推到 Cloudflare Pages,也能放 Vercel / Netlify / 任意静态托管。

如果要自托管 Node 服务 ,把 nuxt.config.ts 里 nitro.preset 改为 node-server 再构建,用 node .output/server/index.mjs 起服务即可。

环境变量示例(部署平台的环境变量面板配置):

bash 复制代码
NUXT_PUBLIC_GA_ID=G-XXXXXXXXXX
NUXT_PUBLIC_CLARITY_ID=xxxxxxxx

九、避坑提示

  1. 千万别删 COOP/COEP 头 。下载器路由的 require-corp 决定了 cross-origin isolation 是否生效------它同时影响两件事:FFmpeg WASM 能否跑多线程(依赖 SharedArrayBuffer),以及大文件能否走 StreamSaver 跨源流式写入。删了头,大文件下载会退化甚至失败。
  2. FFmpeg WASM 首次加载约 8MB,属正常,后续有缓存。
  3. DRM 内容解不了(如 Widevine),这是设计边界,不是 bug。
  4. Node 版本别太低,Nuxt 4 在 Node 18 及以下会直接起不来。

相关推荐
ppo_wu14 小时前
解决夸克网盘自动修改PDF打开方式的方法
经验分享·安全·网络安全
孟郎郎17 小时前
打造一切(Craft Anything)——克隆构造世间万物
人工智能·ai·github·软件构建·开源软件
迪康coolmu20 小时前
出差终端数据安全落地实战:基于迪康端点安全一体化管理系统的四道防线实践
运维·服务器·经验分享·笔记·其他·安全·php
深圳智根网络程序开发1 天前
WP做外贸站,Yoast和RankMath到底选哪个?
经验分享
系统集成-鹰翔1 天前
ERP单据已作废为什么商品仍不能删除,引用检查与软删除怎么查
javascript·经验分享·后端
聪明的笨猪猪1 天前
政务知识库AI架构选型:强合规约束下的架构决策与落地路径
经验分享·架构·ai编程·政务
艺杯羹2 天前
Windows原生软件锁设计:从暴力杀进程丢数据到零轮询事件驱动架构
windows·系统架构·开源·开源软件·内存管理·开源协议
成都蜀味缘餐饮技术培训学校2 天前
手撕烤兔技术培训实战指南,秘制腌料配方比例与调制手法
大数据·经验分享·笔记·其他·微信公众平台
聪明的笨猪猪2 天前
AI应用架构选型:架构师的核心决策困境与权衡
经验分享·面试·架构
我qq不是451516523 天前
WorkBuddy下载体验
人工智能·经验分享·ai·workbuddy