面试题手册

梳理高频技术问题,帮助你按主题复习和查漏补缺。

服务端阅读 06月2日 01:14

VSCode 设置优先级怎么算?全局、工作区和文件夹级别配置覆盖规则

VSCode 的设置分三个层级:全局 > 工作区 > 文件夹。优先级从低到高,后者的设置覆盖前者。理解这个层级关系才能避免"明明改了设置为什么不生效"的困惑。三层优先级| 层级 | 存储位置 | 作用范围 | 优先级 ||------|----------|----------|--------|| 全局(User) | ~/.config/Code/User/settings.json | 所有项目 | 最低 || 工作区(Workspace) | .vscode/settings.json | 当前工作区 | 中 || 文件夹(Folder) | .vscode/settings.json(子目录) | 子目录内的文件 | 最高 |打开设置面板(Ctrl+,)时,右上角有个标签页切换:User 是全局设置,Workspace 是项目级设置。同一个设置项在两层都有值时,Workspace 的生效。什么时候用哪一层全局设置:和项目无关的个人偏好——字体大小、主题、终端 Shell、编辑器行为。这些你在任何项目里都希望保持一致。// 全局 settings.json{ "editor.fontSize": 14, "editor.tabSize": 4, "workbench.colorTheme": "One Dark Pro", "terminal.integrated.defaultProfile.osx": "zsh"}工作区设置:项目特定配置——格式化工具、lint 规则、排除了哪些目录。这些设置应该提交到 Git,让团队所有人一致。// .vscode/settings.json(项目级){ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "files.watcherExclude": { "**/node_modules": true, "**/dist": true }, "python.defaultInterpreterPath": "./venv/bin/python"}文件夹设置:多根工作区里不同项目需要不同配置时用。比如一个 monorepo 里前端和后端用不同的格式化配置。远程设置的坑VSCode Remote(SSH/WSL/Container)的设置是独立的两套——本地和远程各自有全局设置。在远程环境打开设置面板改的是远程的全局设置,不是本地的。如果发现远程环境设置不生效,检查是不是改错了位置:Ctrl+Shift+P 输入 Preferences: Open Settings,看标签页是 [Local] 还是 [Remote]。扩展设置的优先级扩展也可以注册设置项,优先级规则相同。但扩展可以设置 scope 限制设置项在哪些层级可用:machine:只能在全局级别设置(如 Python 解释器路径)window:工作区级别resource:文件级别(可以按文件夹覆盖)如果某个设置项在工作区级别改不了,大概率是扩展把它设成了 machine scope。设置冲突排查"改了设置不生效"的排查步骤:Ctrl+Shift+P 输入 Developer: Inspect Editor Tokens and Scopes,看某个设置最终生效的值和来源在设置面板搜索该设置项,右侧会显示 "Modified in Workspace" 或 "Modified in User"如果两个地方都改了,点齿轮图标选 "Reset Setting" 清掉不需要的那层
服务端阅读 06月2日 01:13

VSCode 任务系统怎么用?tasks.json 配置和自动化构建实战

VSCode 的任务系统让你把常用命令(构建、测试、部署)绑定为任务,按 Ctrl+Shift+B 直接运行,不用每次手敲终端命令。最简单的任务// .vscode/tasks.json{ "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "npm run build" } ]}运行:Ctrl+Shift+P 输入 Tasks: Run Task,选择 "build"。或者 Tasks: Run Build Task(Ctrl+Shift+B)直接运行标记为 build group 的任务。常用任务配置{ "version": "2.0.0", "tasks": [ { "label": "dev", "type": "shell", "command": "npm run dev", "isBackground": true, "problemMatcher": [] }, { "label": "build", "type": "shell", "command": "npm run build", "group": { "kind": "build", "isDefault": true }, "problemMatcher": ["$tsc"] }, { "label": "test", "type": "shell", "command": "npm test", "group": { "kind": "test", "isDefault": true } } ]}关键配置项:group: "build":标记为构建任务,Ctrl+Shift+B 直接触发group: "test":标记为测试任务,可以在菜单里一键跑isBackground: true:后台运行(dev server 这种不会自动退出的命令必须加)problemMatcher:解析终端输出中的错误,映射到编辑器的 Problems 面板problemMatcher:自动捕获错误$tsc 是内置的 TypeScript 编译器匹配器,自动把 src/main.ts(10,5): error TS2304 这种输出映射到编辑器的问题面板。自定义匹配器(捕获 ESLint 错误):{ "label": "lint", "type": "shell", "command": "npx eslint src/", "problemMatcher": { "owner": "eslint", "fileLocation": "relative", "pattern": { "regexp": "^(.+):(\d+):(\d+)\s+-\s+(.+)$", "file": 1, "line": 2, "column": 3, "message": 4 } }}正则捕获的文件名、行号、列号映射到编辑器,点击错误直接跳转。任务间依赖多个任务按顺序执行:{ "label": "deploy", "dependsOn": ["build", "test"], "dependsOrder": "sequence"}dependsOrder: "sequence" 串行执行(先 build 再 test),不加则是并行。输入变量任务支持变量替换,不用硬编码路径:{ "label": "run current file", "type": "shell", "command": "python ${file}"}常用变量:${file}(当前文件)、${workspaceFolder}(项目根目录)、${fileBasenameNoExtension}(文件名不含后缀)。preLaunchTask:调试前自动跑任务在 launch.json 里配 preLaunchTask,按 F5 调试时自动先跑构建任务:// .vscode/launch.json{ "configurations": [ { "type": "node", "request": "launch", "name": "Debug", "program": "${workspaceFolder}/dist/index.js", "preLaunchTask": "build" } ]}这样调试时不会遇到"代码改了但跑的是旧构建"的问题。
服务端阅读 06月2日 00:06

VSCode 怎么用 Git?内置 Git 功能和常见操作图文指南

VSCode 内置了 Git 支持,日常的 commit、diff、branch、merge、resolve conflict 都不用离开编辑器。不装任何扩展就能用,大部分情况下不需要命令行。基本操作查看变更左侧栏的 Source Control 图标(分支形状)显示当前仓库状态。点击后能看到所有已修改文件,点击文件名查看 diff(左右对照显示新增/删除的行)。暂存和提交点击文件旁的 + 号暂存(相当于 git add)点击 - 号取消暂存(相当于 git reset HEAD)在输入框写 commit message,按 Ctrl+Enter 提交比命令行快的地方:可以部分暂存——在 diff 视图里选中几行右键 "Stage Selected Ranges",只提交某几行改动而不是整个文件。撤销修改文件旁的回退箭头图标撤销所有未暂存的修改(git checkout)。如果已经暂存了,先取消暂存再撤销。分支管理左下角状态栏显示当前分支名。点击分支名弹出分支列表:切换到已有分支创建新分支(从当前分支或指定分支创建)删除分支合并分支:Ctrl+Shift+P 输入 Git: Merge Branch,选择要合并进来的分支。如果有冲突,VSCode 会标记冲突文件。解决冲突冲突文件会在编辑器里显示三段内容:Current Change(当前分支的版本)Incoming Change(要合并进来的版本)上方有四个按钮:Accept Current / Accept Incoming / Accept Both / Compare点击按钮选择保留哪个版本,或者手动编辑合并后的内容。解决所有冲突后保存文件,暂存并提交。VSCode 的冲突解决界面比 git mergetool 直观很多——两个版本左右对照,选中哪边一目了然。查看历史内置功能比较有限:只能看文件的行级别 blame(鼠标悬停在某行显示最后修改的 commit)。要看完整历史,装 GitLens 扩展——显示每一行的修改者、时间、commit 信息,还能看文件的历史版本和 diff。.gitignore 支持创建 .gitignore 文件后,VSCode 自动忽略匹配的文件。已跟踪的文件如果加入 .gitignore 不会自动取消跟踪,需要先 git rm --cached。忽略文件但不想提交 .gitignore:用全局 gitignore(git config --global core.excludesFile ~/.gitignore_global)。常见问题Source Control 面板不显示:打开的文件夹不是 Git 仓库。Ctrl+Shift+P 输入 Git: Initialize Repository 初始化,或者 Git: Clone 克隆远程仓库。文件修改后没有变化标记:可能是文件编码问题或 .gitignore 规则意外匹配。检查 git status 在终端里是否正常。提交时 husky/pre-commit hook 报错:VSCode 的 Git 集成调用的是系统 git,hook 正常运行。但如果 hook 依赖环境变量(如 PATH 中的 node),VSCode 可能找不到。从终端启动 VSCode(code .)可以继承终端的环境变量。
服务端阅读 06月2日 00:05

VSCode 太卡怎么办?5 个有效的性能优化方法

VSCode 变卡通常是因为扩展太多、大文件处理、或 TypeScript 语言服务过载。按优先级排查:禁用扩展 → 排除大文件夹 → 调整 TypeScript 配置。1. 禁用不需要的扩展扩展是 VSCode 卡顿的头号原因。每个扩展都会在后台运行,有些还监听所有文件变化。快速定位问题扩展:按 Ctrl+Shift+P 输入 Developer: Show Running Extensions,看哪些扩展占用 CPU 高。按工作区禁用:不需要全局禁用。在扩展面板右键选 "Disable (Workspace)",只对当前项目禁用。比如前端项目不需要 C++ 扩展,Python 项目不需要 Java 扩展。高危扩展:这些类型的扩展特别吃性能:实时 lint/formatter(ESLint、Prettier 在每次保存时运行)代码分析工具(SonarLint 扫描整个项目)主题/图标包(某些实现不好的会拖慢渲染)2. 大项目排除不需要的文件夹打开大项目(node_modules 几百 MB、dist 目录几万文件)时,VSCode 的文件监控会卡住。// settings.json{ "files.watcherExclude": { "**/.git/objects/**": true, "**/.git/subtree-cache/**": true, "**/node_modules/**": true, "**/dist/**": true, "**/.next/**": true, "**/build/**": true }, "files.exclude": { "**/.git": true, "**/node_modules": true, "**/dist": true }}watcherExclude 停止文件监控(省 CPU),exclude 从文件树隐藏(省渲染)。两者配合效果最好。改完之后可能需要 Developer: Reload Window 重新加载。3. TypeScript/JavaScript 语言服务优化TypeScript 语言服务是 VSCode CPU 占用的大户——它要分析整个项目的类型关系。// settings.json{ "typescript.tsserver.maxTsServerMemory": 4096, "js/ts.implicitProjectConfig.checkJs": false, "typescript.preferences.importModuleSpecifier": "relative"}maxTsServerMemory: 4096 给 TS 服务器更多内存,避免大项目 OOM 崩溃重启(反复重启本身就是卡顿原因)。如果不做 JS/TS 开发,可以直接禁用内置 TypeScript 扩展。4. 关闭不必要的功能// settings.json{ "editor.minimap.enabled": false, "editor.renderWhitespace": "none", "editor.quickSuggestionsDelay": 200, "workbench.editor.enablePreview": true, "telemetry.telemetryLevel": "off"}minimap:大文件时 minimap 渲染开销不小,关掉立竿见影renderWhitespace:显示空白字符需要额外渲染enablePreview:单击文件只预览不打开新标签页,减少标签页数量5. 大文件用其他编辑器VSCode 对超过 10MB 的文件力不从心——语法高亮变慢、滚动卡顿、内存飙升。这是架构决定的(VSCode 用 TextBuffer 而非传统的行数组)。处理大文件的建议:日志文件:用 less 命令或 Dedicated Log Viewer大 JSON/CSV:用专项工具(jq、bat)超大代码文件:拆分文件才是根本解// settings.json{ "files.maxMemoryForLargeFilesMB": 4096}提高大文件内存上限,但不治本——文件太大时该卡还是卡。检查当前性能按 Ctrl+Shift+P 输入 Developer: Open Process Explorer,看每个进程的 CPU 和内存占用。如果某个扩展进程持续占用 CPU,就是问题根源。
服务端阅读 06月2日 00:05

VSCode 主题怎么换?配色方案、图标主题和自定义颜色 token 详解

VSCode 主题分两种:颜色主题(编辑器配色)和文件图标主题(资源管理器图标)。想更深入,还可以通过 color customization 精细控制每个 UI 元素的颜色。安装主题扩展市场里有上千个主题。Ctrl+Shift+X 打开扩展面板,搜索 "theme" 就能找到。几个口碑好的:One Dark Pro:Atom 风格暗色主题,下载量最高之一Dracula:经典暗色,跨编辑器统一风格GitHub Theme:GitHub 官方亮色/暗色主题Catppuccin:柔和的暖色调暗色主题,2024-2025 年热度上升很快Tokyo Night:偏蓝调暗色主题,和 One Dark Pro 风格接近但更素装完主题后切换:Ctrl+K Ctrl+T,从列表中选择。文件图标主题图标主题控制侧边栏文件树里的图标样式:Material Icon Theme:Google Material 风格,覆盖文件类型最全vscode-icons:VSCode 官方团队出品,辨识度高切换图标主题:Ctrl+Shift+P 输入 File Icon Theme,从列表中选择。图标主题和颜色主题独立,可以混搭。精细自定义:覆盖特定颜色装了主题但想改几个颜色?不用从零写主题,用 workbench.colorCustomizations 覆盖:// settings.json{ "workbench.colorCustomizations": { "editor.background": "#1a1b26", "editor.foreground": "#a9b1d6", "editorCursor.foreground": "#c0caf5", "editor.selectionBackground": "#33467c", "editor.lineHighlightBackground": "#1f2335", "sideBar.background": "#16161e", "activityBar.background": "#16161e" }}这样只改你关心的几个颜色,主题的其他部分保持不变。比从零写主题简单得多。自定义语法高亮颜色语法高亮的颜色由 TextMate token 控制,可以通过 editor.tokenColorCustomizations 覆盖:// settings.json{ "editor.tokenColorCustomizations": { "textMateRules": [ { "scope": "keyword", "settings": { "foreground": "#bb9af7", "fontStyle": "bold" } }, { "scope": ["comment", "punctuation.definition.comment"], "settings": { "foreground": "#565f89", "fontStyle": "italic" } }, { "scope": "string", "settings": { "foreground": "#9ece6a" } } ] }}常见 scope:keyword(关键字)、string(字符串)、comment(注释)、function(函数名)、variable(变量名)、number(数字)。按项目设置不同主题每个项目可以用不同的主题——工作项目用暗色,个人项目用亮色:// .vscode/settings.json(项目级别){ "workbench.colorCustomizations": { "[One Dark Pro]": { "editor.background": "#1e1e2e" }, "[GitHub Dark]": { "editor.background": "#0d1117" } }}[主题名] 语法让定制只在特定主题下生效。创建自己的主题扩展如果改动太多,不如直接打包成主题扩展分享。用 Yoeman 脚手架生成:npm install -g yo generator-codeyo code# 选择 "New Color Theme"生成的项目里有一个 JSON 文件定义所有颜色。改完后 vsce publish 发布到扩展市场。
服务端阅读 06月2日 00:04

VSCode 快捷键怎么改?自定义键绑定和多快捷键方案切换

VSCode 的快捷键可以完全自定义,还能装不同平台的键位方案(Vim、Sublime、IntelliJ)让肌肉记忆无缝迁移。查看和搜索快捷键Ctrl+K Ctrl+S 打开快捷键设置面板。在这里可以:搜索命令名或快捷键组合修改任意命令的绑定查看冲突(同一个快捷键绑定了多个命令)搜索框里输入命令名(如 "format")或快捷键组合(先按 Ctrl+K 再按要搜索的键),快速定位。修改快捷键两种方式:方式一:面板里直接改。在快捷键面板里找到命令,双击或右键选 "Change Keybinding",按下新快捷键组合。方式二:编辑 keybindings.json。点击快捷键面板右上角的文件图标,打开 JSON 配置:// keybindings.json[ { "key": "ctrl+shift+f", "command": "editor.action.formatDocument", "when": "editorHasDocumentFormattingProvider && editorTextFocus" }, { "key": "ctrl+d", "command": "editor.action.copyLinesDownAction", "when": "editorTextFocus" }, { "key": "ctrl+shift+d", "command": "workbench.view.debug" }]when 条件控制快捷键在什么上下文生效——editorTextFocus 只在编辑器有焦点时生效,避免全局快捷键和终端冲突。常用快捷键调整建议格式化代码:默认 Shift+Alt+F,很多人改成 Ctrl+Shift+F 或 Ctrl+S 时自动格式化(配合 editor.formatOnSave: true)。复制当前行:默认 Shift+Alt+Down,改成 Ctrl+D 更顺手(但 Ctrl+D 默认是"添加下一个选中",改之前想清楚)。删除当前行:默认 Ctrl+Shift+K,可以改成 Ctrl+Shift+D 或其他顺手的组合。切换终端:Ctrl+` 比较远,可以加一组 Ctrl+J。装其他编辑器的键位方案不想一个个改?装键位扩展一键迁移:Vim:装 "VSCode Vim" 扩展,完整的 Vim 键位模拟Sublime Text:装 "Sublime Text Keymap" 扩展IntelliJ IDEA:装 "IntelliJ IDEA Keybindings" 扩展Emacs:装 "Emacs Friendly Keymap" 扩展装完扩展后,Ctrl+K Ctrl+S 面板里会显示对应编辑器的键位方案,可以和默认方案混用。when 条件常用值when 是快捷键自定义的关键——它决定快捷键在什么场景下生效:| when 值 | 含义 ||---------|------|| editorTextFocus | 编辑器有焦点 || terminalFocus | 终端有焦点 || resourceLangId == 'python' | 当前文件是 Python || editorHasSelection | 有选中文本 || inDebugMode | 调试模式中 |组合条件用 && 连接:editorTextFocus && resourceLangId == 'python' 表示只在编辑 Python 文件时生效。导出和同步快捷键VSCode Settings Sync(登录 GitHub 或 Microsoft 账号)自动同步快捷键配置到云端,换电脑不用重新配置。如果不想用云同步,手动复制 keybindings.json 文件也行。
服务端阅读 06月2日 00:04

VSCode 内置终端怎么用?分屏、多终端和配置技巧

VSCode 内置终端省去了在编辑器和终端窗口之间来回切换的麻烦。Ctrl+` 一键打开,和编辑器共享同一个窗口,代码和命令行并排操作。基本操作打开/关闭终端:Ctrl+`(反引号)或 View > Terminal新建终端:终端面板右上角的 + 号,或 Ctrl+Shift+`拆分终端:终端面板右上角的拆分图标,或 Ctrl+Shift+5,在同一个终端面板里左右分屏切换终端:终端面板右上角的下拉菜单选择,或 Ctrl+PageUp/PageDown拆分终端比新建标签页更实用——可以同时看着两个终端的输出,比如左边跑服务、右边看日志。终端类型选择VSCode 会自动检测系统上安装的 Shell:macOS:默认 zsh(Catalina 及以后),也可以选 bashLinux:默认 bash,也可以选 zsh/fishWindows:默认 PowerShell,也可以选 CMD 或 Git Bash手动选择默认终端:Ctrl+Shift+P 输入 Terminal: Select Default Profile,从列表中选择。指定特定终端:terminal.integrated.defaultProfile.osx/linux/windows 按平台设置。终端配置技巧// settings.json{ "terminal.integrated.fontSize": 14, "terminal.integrated.cursorStyle": "line", "terminal.integrated.scrollback": 5000, "terminal.integrated.copyOnSelection": true}scrollback: 5000 把回滚缓冲区从默认 1000 行增加到 5000 行,跑大量日志时不会丢失前面的输出。copyOnSelection 选中即复制,不用再 Ctrl+C。终端里的代码操作右键在终端中打开文件:如果终端输出了文件路径(比如编译错误 src/main.js:10:5),按住 Ctrl/Cmd 点击路径可以直接跳转到对应文件的对应行。选中终端文本:和普通终端不同,VSCode 终端选中文字不需要进入复制模式——直接鼠标拖选就行。运行选中代码:选中一段代码后,按 Shift+Enter 或右键选择 Run Selection in Python Terminal(需要 Python 扩展),代码直接在终端里执行。调试小段代码非常方便。任务运行器把常用命令绑定到任务里,不用每次手敲:// .vscode/tasks.json{ "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "npm run build", "group": "build", "problemMatcher": ["$tsc"] }, { "label": "dev", "type": "shell", "command": "npm run dev", "isBackground": true, "group": "none" } ]}Ctrl+Shift+P 输入 Tasks: Run Task 选择运行。problemMatcher 自动解析终端输出中的错误,标记到编辑器的 Problems 面板。常见问题终端字体乱码:Powerline 主题的特殊符号需要安装 Nerd Font。在设置里指定 terminal.integrated.fontFamily 为已安装的 Nerd Font 名称。终端启动慢:可能是 Shell 配置文件(.zshrc/.bashrc)加载太多东西。在终端里跑 time zsh -i -c exit 看启动耗时,超过 1 秒就该优化了。终端里 vim/nano 不能用:VSCode 终端不支持交互式程序的鼠标事件。如果需要在编辑器里用 vim,装 VSCode Vim 扩展而不是在终端里跑 vim。
服务端阅读 06月2日 00:02

VSCode IntelliSense 智能提示怎么用?代码补全、参数提示和自定义配置

IntelliSense 是 VSCode 的智能代码补全系统——输入几个字符就弹出建议列表,显示函数参数、类型信息、文档注释。不是所有语言的 IntelliSense 都一样强:TypeScript/Python 开箱即用,C++/Java 需要装扩展和配置。IntelliSense 提供什么输入代码时自动弹出的建议列表,不只是简单的文本补全,而是基于语义理解的:成员列表:输入 console. 后自动列出 log、error、warn 等方法参数信息:调用函数时显示参数名、类型和默认值,不用跳到定义去看快速信息:鼠标悬停(或按住 Option/Ctrl)显示变量类型、函数签名、文档注释代码片段:输入 for 后选择代码片段,自动生成完整的 for 循环结构触发方式:输入时自动弹出,或手动按 Ctrl+Space(macOS 可能冲突,可以在设置里改)。Ctrl+Shift+Space 手动触发参数提示。不同语言的支持程度开箱即用:TypeScript/JavaScript、Python、HTML/CSS、JSON。VSCode 内置了这些语言的 Language Server,装好就能用。需要装扩展:C/C++(装 Microsoft C/C++ 扩展)、Java(装 Language Support for Java)、Go(装 Go 扩展)、Rust(装 rust-analyzer)。扩展提供 Language Server,IntelliSense 的能力取决于扩展质量。几乎没有:纯文本、Shell 脚本(补全很有限)。这类语言没有类型系统,IntelliSense 能做的不多。让 IntelliSense 更好用调整触发行为// settings.json{ "editor.quickSuggestions": { "other": true, "comments": false, "strings": true }, "editor.suggestOnTriggerCharacters": true, "editor.acceptSuggestionOnCommitCharacter": true, "editor.snippetSuggestions": "top"}strings: true 在字符串里也能触发补全(写 import 路径时有用)。snippetSuggestions: "top" 把代码片段排到建议列表最前面。Tab 补全默认按 Tab 或 Enter 都能接受建议。如果你只想用 Enter 接受,防止误触 Tab:{ "editor.tabCompletion": "off", "editor.acceptSuggestionOnEnter": "on"}建议列表过滤建议列表支持模糊匹配——输入 clg 能匹配到 console.log。输入越具体,过滤越精准,不用滚列表找。常见问题IntelliSense 不工作:99% 的原因是 Language Server 没启动。看右下角状态栏有没有语言模式(比如 TypeScript),Ctrl+Shift+P 输入 Developer: Show Running Extensions 检查扩展是否正常加载。Python 补全慢:换用 Pylance 扩展(VSCode Python 扩展的默认 Language Server),比旧版 Jedi 快很多。在设置里确认 "python.languageServer": "Pylance"。C++ 头文件找不到:需要配置 c_cpp_properties.json,指定 include 路径。按 Ctrl+Shift+P 输入 C/C++: Edit Configurations 自动生成。建议列表太长:输入更具体的前缀过滤,或者在 editor.suggest.showWords 设为 false 关闭纯文本词语建议,只保留语义补全。进阶:GitHub CopilotCopilot 是 IntelliSense 的 AI 增强版——不只补全当前标识符,而是根据上下文生成整段代码。灰色幽灵文本预览建议,按 Tab 接受。和 IntelliSense 不冲突,两者同时工作:IntelliSense 提供精确的类型补全,Copilot 提供意图补全。
服务端阅读 06月2日 00:01

FFmpeg 是什么?能做什么?核心组件和常用命令入门

FFmpeg 是音视频领域的瑞士军刀——转码、剪辑、录屏、推流、截图、质量分析,一条命令搞定。它不是带界面的软件,而是命令行工具集,所有操作都在终端完成。OBS、VLC、YouTube 后台都用到了 FFmpeg。FFmpeg 能做什么转码:AVI 转 MP4、H.264 转 H.265、4K 降 1080p剪辑:截取视频片段、合并多个视频、去掉静音段录屏:录制屏幕和摄像头(macOS/Linux/Windows)推流:RTMP 直播推流、生成 HLS 流媒体截图:截取视频帧、批量生成缩略图分析:用 ffprobe 查看视频信息、用 PSNR/SSIM 评估画质核心组件FFmpeg 项目包含一组命令行工具和底层库:| 工具 | 用途 ||------|------|| ffmpeg | 转码、剪辑、推流(最常用) || ffprobe | 查看音视频文件信息(不转码,只分析) || ffplay | 简易播放器(调试用) |底层库(开发者在自己的程序中调用):| 库 | 功能 ||------|------|| libavformat | 处理封装格式(MP4、MKV、FLV…) || libavcodec | 编解码(H.264、AAC、VP9…) || libavutil | 通用工具函数 || libswscale | 图像缩放和色彩空间转换 || libswresample | 音频重采样 |日常只用 ffmpeg 和 ffprobe 两个命令。库是给开发者写程序用的,普通用户不用管。最常用的 5 条命令1. 格式转换ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp42. 视频剪辑ffmpeg -ss 00:01:00 -i input.mp4 -t 30 -c copy output.mp4从 1 分钟处截取 30 秒,-c copy 不重编码,秒级完成。3. 视频截图ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 screenshot.jpg截取第 5 秒的一帧。4. 查看视频信息ffprobe -v quiet -print_format json -show_format -show_streams input.mp4输出分辨率、码率、时长、编码格式等所有信息,JSON 格式方便脚本解析。5. 压缩视频ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset slow output.mp4CRF 28 比默认的 23 压得更狠,-preset slow 用更多编码时间换取更小的文件。安装# macOSbrew install ffmpeg# Ubuntu/Debiansudo apt install ffmpeg# Windows# 从 ffmpeg.org 下载,解压后把 bin 目录加到 PATH安装后跑 ffmpeg -version 确认可用。注意某些发行版的 FFmpeg 可能缺少某些编码器(如 libx265),需要从第三方源安装或自行编译。命令语法模式FFmpeg 命令的通用结构:ffmpeg [全局选项] [输入选项] -i 输入文件 [输出选项] 输出文件关键概念:选项的位置很重要。-ss 放在 -i 前面是快速跳转(不精确),放在后面是精确跳转(慢)。-c:v 和 -c:a 是输出选项,必须放在输出文件前面。
服务端阅读 06月2日 00:00

FFmpeg 视频转码怎么做?常用格式转换命令和参数详解

视频转码 = 解码 + 重新编码。最简单的形式是换个容器(MP4 转 MKV),最复杂的是同时改编码器、分辨率、码率、帧率。FFmpeg 一条命令搞定。最基本的转码# 让 FFmpeg 自动选择编码器(按输出文件后缀推断)ffmpeg -i input.avi output.mp4这样 FFmpeg 会自动把 AVI 里的 MPEG-4 视频转成 H.264,音频转成 AAC。简单但不可控——你不知道它选了什么参数。明确指定编码器:ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4-c:v 指定视频编码器,-c:a 指定音频编码器。这是转码命令的基本骨架,所有高级参数都加在这个基础上。常见转码场景AVI/MKV 转 MP4(最常见)ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4如果原视频已经是 H.264 编码,不需要重编码视频流,只换个容器:ffmpeg -i input.mkv -c:v copy -c:a aac -b:a 128k output.mp4-c:v copy 直接拷贝视频流,几秒完成。但 MKV 支持的编码器比 MP4 多——如果 MKV 里是 H.265 或 VP9,copy 到 MP4 后部分播放器可能不兼容。转 WebM(网页视频)ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus output.webmVP9 编码必须用 -b:v 0 配合 CRF 模式,否则 CRF 不生效。Opus 是 WebM 的标准音频编码器,音质优于 AAC。转 H.265(省空间)ffmpeg -i input.mp4 -c:v libx265 -crf 28 -c:a aac -b:a 128k output.mp4H.265 的 CRF 28 大约等于 H.264 的 CRF 23,文件小 30-50%。编码慢 3-5 倍,老设备可能播不了。只转视频或只转音频# 只转视频,音频原样拷贝ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy output.mp4# 只转音频,视频原样拷贝ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 128k output.mp4# 去掉视频只保留音频ffmpeg -i input.mp4 -vn -c:a aac -b:a 128k output.aac-vn 去掉视频,-an 去掉音频,-sn 去掉字幕。转码时去掉不需要的流可以节省时间。硬件加速转码CPU 编码太慢?用 GPU 加速:# NVIDIA GPU(NVENC)ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc -preset p4 -cq 23 -c:a aac output.mp4# Intel GPU(QSV)ffmpeg -hwaccel qsv -i input.mp4 -c:v h264_qsv -preset medium -c:a aac output.mp4# Apple Silicon(VideoToolbox)ffmpeg -hwaccel videotoolbox -i input.mp4 -c:v h264_videotoolbox -b:v 5M -c:a aac output.mp4硬件编码速度是 CPU 的 5-10 倍,但同码率下画质略差(约 5-10%)。如果追求极致画质用 CPU libx264,追求速度用 NVENC。-preset p4 是 NVENC 的质量档位,p1 最快 p7 最慢质量最好。转码时调分辨率和帧率# 1080p 转 720pffmpeg -i input.mp4 -vf "scale=1280:720" -c:v libx264 -crf 23 -c:a copy output.mp4# 保持宽高比,只限宽度ffmpeg -i input.mp4 -vf "scale=1280:-2" -c:v libx264 -crf 23 -c:a copy output.mp4# 降帧率 60fps -> 30fpsffmpeg -i input.mp4 -r 30 -c:v libx264 -crf 23 -c:a copy output.mp4-2 让 FFmpeg 自动计算高度保持比例,必须用偶数(有些编码器要求宽高都是偶数)。两遍编码:精确控制文件大小CRF 模式无法精确控制输出文件大小。如果需要视频刚好 100MB:# 第一遍:分析(不输出视频)ffmpeg -i input.mp4 -c:v libx264 -b:v 1500k -pass 1 -an -f null /dev/null# 第二遍:实际编码ffmpeg -i input.mp4 -c:v libx264 -b:v 1500k -pass 2 -c:a aac -b:a 128k output.mp4第一遍分析视频复杂度分布,第二遍据此分配码率。两遍编码比单遍 CRF 质量稍好,但编码时间翻倍。通常只在需要精确文件大小(如 DVD/蓝光)时才用。
服务端阅读 06月2日 00:00

FFmpeg 视频剪辑、合并和截图怎么做?常用命令速查

视频剪辑、合并、截图是 FFmpeg 最高频的日常操作。核心命令不多,但参数位置有讲究——放错位置效果完全不同。视频剪辑:截取片段最常用的剪辑命令# 从第 10 秒开始,截取 30 秒ffmpeg -ss 00:00:10 -i input.mp4 -t 30 -c copy output.mp4# 从 1:30 截到 3:00ffmpeg -ss 00:01:30 -to 00:03:00 -i input.mp4 -c copy output.mp4-c copy 直接拷贝音视频流,不重新编码,速度极快(几秒搞定),但切割点可能不精确——因为视频是按关键帧压缩的,-c copy 只能在关键帧处切开。结果可能是你想从 10 秒切,实际从 8 秒的关键帧开始了。精确剪辑需要精确到帧的剪辑,必须重新编码:ffmpeg -i input.mp4 -ss 00:00:10 -t 30 -c:v libx264 -crf 23 -c:a aac output.mp4去掉 -c copy,让 FFmpeg 重新编码。速度慢很多但切割点精确。-ss 放在 -i 前面还是后面?-ss 在 -i 前面:FFmpeg 先跳到指定时间再开始解码(seek 模式),速度快但可能不精确-ss 在 -i 后面:FFmpeg 从头解码到指定时间,精确但慢最佳实践:先放前面快速定位,再精确微调。对于长视频(>10 分钟),放前面能省很多时间。视频合并:拼接多个片段concat 协议(最快,要求格式完全一致)# 先创建文件列表echo "file 'part1.mp4'" > list.txtecho "file 'part2.mp4'" >> list.txtecho "file 'part3.mp4'" >> list.txt# 合并ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4-c copy 不重编码,秒级完成。但要求所有片段的编码参数(分辨率、帧率、编码器)完全一致,否则合并后可能花屏或播放异常。格式不一致时:先统一再合并# 先把所有片段转成统一格式for f in part*.mp4; do ffmpeg -i "$f" -c:v libx264 -crf 23 -c:a aac -b:a 128k -vf "scale=1920:1080" -r 30 "normalized_$f"done# 再用 concat 合并echo "file 'normalized_part1.mp4'" > list.txtecho "file 'normalized_part2.mp4'" >> list.txtffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4filter 复杂合并(加转场等效果)# 两个视频左右并排ffmpeg -i left.mp4 -i right.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2" output.mp4# 上下并排ffmpeg -i top.mp4 -i bottom.mp4 -filter_complex "[0:v][1:v]vstack=inputs=2" output.mp4filter 合并必须重编码,速度慢但能做各种效果。视频截图# 截取第 5 秒的一帧ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 screenshot.jpg# 每隔 10 秒截一张ffmpeg -i input.mp4 -vf "fps=1/10" screenshot_%04d.jpg# 截取多张(前 60 秒,每秒 1 帧)ffmpeg -i input.mp4 -t 60 -vf "fps=1" frame_%04d.jpgfps=1/10 表示每 10 秒一帧。%04d 是序号占位符,生成 screenshot0001.jpg、screenshot0002.jpg…截图的质量参数:-q:v 2(1 最好,31 最差,2 近乎无损)。ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 -q:v 2 screenshot.jpg实用技巧去除视频静音段:用 silenceremove 滤镜自动剪掉没有声音的部分,适合处理会议录像。加速/减速视频:-vf "setpts=0.5*PTS" 2 倍速,-vf "setpts=2*PTS" 半速。音频也要对应调整:-af "atempo=2.0"(atempo 范围 0.5-2.0,超出需要串联)。旋转视频:-vf "transpose=1" 顺时针 90 度。手机竖拍视频在电脑上横着显示时用这个修正。
服务端阅读 06月1日 23:59

FFmpeg 直播推流怎么配?RTMP 推流和 HLS/DASH 流媒体生成实战

FFmpeg 是直播推流的核心工具——OBS 底层也是调用 FFmpeg 做编码和推流。直接用 FFmpeg 推流更轻量、更灵活,适合服务器端自动化场景。RTMP 推流:最常用的直播协议RTMP 是直播平台(B站、斗鱼、YouTube)的标准推流协议。核心命令:ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key关键参数:-re:按原始帧率读取输入,不加这个 FFmpeg 会以最快速度把文件读完然后全推出去,直播就变成了快进-preset veryfast:实时编码必须用快 preset,slow 的话编码速度跟不上帧率,画面会卡顿-b:v 2500k:固定码率 2.5Mbps,直播平台通常有码率上限(B站 6000k,YouTube 5100k)-f flv:RTMP 推流必须用 FLV 容器格式摄像头实时推流# macOS 摄像头 + 麦克风推流ffmpeg -f avfoundation -i "0:0" -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key# Linux 摄像头推流ffmpeg -f v4l2 -i /dev/video0 -f alsa -i hw:0 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key摄像头推流比推文件更需要注意编码速度——如果 CPU 不够快,需要降低分辨率或码率:-vf "scale=1280:720" 降到 720p。HLS:苹果系的流媒体方案HLS 把视频切成小片段(.ts),通过 .m3u8 播放列表索引。延迟较高(通常 10-30 秒),但兼容性最好——所有浏览器和 iOS 设备都支持。ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f hls -hls_time 6 -hls_list_size 0 -hls_segment_filename "seg_%03d.ts" stream.m3u8关键参数:-hls_time 6:每个切片 6 秒,越短延迟越低但碎片越多-hls_list_size 0:播放列表包含所有切片(0 = 不限制),直播场景可以设成 5-10 只保留最近几个-hls_segment_filename:切片文件命名模板HLS 文件是纯静态文件,用 Nginx 或任何 HTTP 服务器托管就行,不需要专门的流媒体服务器。DASH:开源的流媒体方案DASH 和 HLS 类似,但基于 MPEG 标准,没有苹果的专利限制。浏览器支持不如 HLS(Safari 不原生支持 DASH),但功能更灵活。ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f dash -seg_duration 6 -out output.mpd实际上 DASH 在国内使用较少,大部分场景用 HLS 或 RTMP 就够了。多码率自适应推流给不同网速的用户提供不同清晰度——3G 用户看 480p,WiFi 用户看 1080p。用 -var_stream_map 生成多码率 HLS:ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v:0 5000k -s:v:0 1920x1080 -b:v:1 2500k -s:v:1 1280x720 -b:v:2 1000k -s:v:2 854x480 -c:a aac -b:a 128k -var_stream_map "v:0,a:0 v:1,a:0 v:2,a:0" -f hls -hls_time 6 -master_pl_name master.m3u8 "stream_%v.m3u8"播放器会根据带宽自动切换码率,用户看到的效果就是网速慢时自动降清晰度。常见问题推流中断:网络波动导致 RTMP 连接断开。加 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 让 FFmpeg 自动重连,但不是所有版本都支持。延迟太高:HLS 延迟 10-30 秒是正常的。要低延迟用 RTMP 直推或 WebRTC(FFmpeg 不直接支持 WebRTC,需要 mediamtx 等中间件)。音视频不同步:通常是编码速度跟不上导致帧被丢弃。降低分辨率/码率,或者用更快的 preset。
服务端阅读 06月1日 23:57

FFmpeg 怎么录屏和录制摄像头?macOS/Linux/Windows 命令详解

FFmpeg 可以直接从屏幕或摄像头捕获视频,不需要额外安装录屏软件。命令行录制的好处是可以精确控制编码参数、方便脚本化、资源占用低。坏处是参数复杂,初次配置容易踩坑。macOS 录屏macOS 用 avfoundation 设备采集:# 列出可用设备(先看看屏幕和摄像头编号)ffmpeg -f avfoundation -list_devices true -i ""# 录制整个屏幕(假设屏幕编号是 1)ffmpeg -f avfoundation -i "1" -r 30 -c:v libx264 -preset ultrafast -crf 23 output.mp4# 录制屏幕 + 系统音频ffmpeg -f avfoundation -i "1:0" -r 30 -c:v libx264 -preset ultrafast -crf 23 -c:a aac output.mp4-preset ultrafast 是录屏必备——实时编码用 slow 的话 CPU 扛不住,画面会卡。录完之后如果觉得文件太大,可以再用 slow preset 重新转码一遍。Linux 录屏Linux 用 x11grab 采集 X11 桌面:# 录制 1080p 屏幕ffmpeg -f x11grab -video_size 1920x1080 -framerate 30 -i :0.0 -c:v libx264 -preset ultrafast -crf 23 output.mp4# 录制指定区域(从坐标 100,100 开始,宽 800 高 600)ffmpeg -f x11grab -video_size 800x600 -framerate 30 -i :0.0+100,100 -c:v libx264 -preset ultrafast -crf 23 output.mp4# Wayland 用户用 wf-recorder 更方便,ffmpeg 对 Wayland 支持不完善:0.0 是 DISPLAY 环境变量的值,多显示器时可能需要调整。Wayland 下 x11grab 可能不工作,需要装 xdotool 或者换用 wf-recorder。Windows 录屏Windows 用 gdigrab 或 dshow:# gdigrab 录制整个桌面ffmpeg -f gdigrab -framerate 30 -i desktop -c:v libx264 -preset ultrafast -crf 23 output.mp4# 录制指定窗口ffmpeg -f gdigrab -framerate 30 -i title="Window Title" -c:v libx264 -preset ultrafast -crf 23 output.mp4Windows 10+ 也可以用 -f dshow 配合摄像头设备名录制。摄像头录制# macOS:列出设备后用摄像头编号(通常是 0)ffmpeg -f avfoundation -i "0" -r 30 -c:v libx264 -preset ultrafast -crf 23 output.mp4# Linux:用 v4l2ffmpeg -f v4l2 -video_size 640x480 -framerate 30 -i /dev/video0 -c:v libx264 -preset ultrafast -crf 23 output.mp4# 摄像头 + 麦克风ffmpeg -f avfoundation -i "0:0" -r 30 -c:v libx264 -preset ultrafast -crf 23 -c:a aac -b:a 128k output.mp4摄像头编号需要先 -list_devices true 查一下,不同机器编号可能不同。录屏实战技巧1. 录制时显示光标:默认录屏可能看不到鼠标光标。macOS 下加 -capture_cursor 1,Linux 下 x11grab 默认会包含光标。2. 控制录制时长:-t 60 只录 60 秒。方便做定时录制,不用手动按 Ctrl+C。3. 停止录制:按 Ctrl+C。有时候 ffmpeg 不会正常写入 MP4 尾部,导致文件打不开。解决办法:改用 MKV 容器(output.mkv),MKV 即使没正常关闭也能播放;或者事后修复 MP4:ffmpeg -i broken.mp4 -c copy fixed.mp44. 同时录屏和摄像头画中画:高级场景,用 overlay 滤镜把摄像头画面叠到屏幕录制上。这比纯录屏复杂很多,如果需要画中画效果,OBS 可能更合适。
服务端阅读 06月1日 23:56

FFmpeg 怎么批量转码?Shell 脚本和 Python 并行处理实战

单个文件用一条 ffmpeg 命令就行,但处理几十上百个文件就需要脚本了。批量处理的核心思路:用 Shell 循环遍历文件,用 GNU Parallel 做并行加速,用 Python 处理更复杂的逻辑。Shell 脚本:最简单的批量转码#!/bin/bash# 批量把 AVI 转成 MP4for file in *.avi; do ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac "${file%.avi}.mp4"done${file%.avi} 是 Shell 的字符串截断——去掉 .avi 后缀,换成 .mp4。这个模式够用 80% 的批量场景。递归处理子目录里的文件:find /path/to/videos -name "*.mkv" | while read file; do ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac "${file%.mkv}.mp4"donefind 递归搜索,while read 逐行读取文件路径。比 -exec 更灵活,可以在循环里加更多逻辑。并行加速:别让 CPU 闲着单线程循环太慢——4 核 CPU 只用了 1 核。用 GNU Parallel 让多个 ffmpeg 同时跑:# 4 个 ffmpeg 并行转码find . -name "*.avi" | parallel -j 4 ffmpeg -i {} -c:v libx264 -crf 23 -c:a aac {.}.mp4{} 是输入文件名,{.} 是去掉后缀的文件名。-j 4 限制并发数——设成 CPU 核心数就行,太多会抢 IO 反而变慢。没有 GNU Parallel?用 xargs 也能并行:find . -name "*.avi" | xargs -P 4 -I {} sh -c 'ffmpeg -i "$1" -c:v libx264 -crf 23 -c:a aac "${1%.avi}.mp4"' _ {}-P 4 控制并发数,-I {} 指定占位符。Python:更灵活的批量处理Shell 脚本能做的事 Python 都能做,而且更容易处理错误和复杂逻辑:import subprocess, os, globinput_dir = "raw"output_dir = "compressed"os.makedirs(output_dir, exist_ok=True)for path in glob.glob(f"{input_dir}/*.mp4"): name = os.path.basename(path) output = os.path.join(output_dir, name) cmd = ["ffmpeg", "-i", path, "-c:v", "libx264", "-crf", "23", "-c:a", "aac", "-b:a", "128k", "-movflags", "+faststart", output] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode == 0: print(f"OK {name}") else: print(f"FAIL {name}: {result.stderr[:200]}")Python 的优势:可以记录成功/失败、跳过已处理文件、按条件选不同参数。Shell 脚本做这些需要大量 if-else,可读性差。进阶:按条件选择不同参数不同类型的视频用不同的压缩策略——教学录屏用高 CRF + stillimage,电影用低 CRF + film:#!/bin/bashfor file in *.mp4; do duration=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$file" | cut -d. -f1) if [ "$duration" -lt 300 ]; then ffmpeg -i "$file" -c:v libx264 -crf 28 -tune stillimage -c:a aac "compressed_$file" else ffmpeg -i "$file" -c:v libx264 -crf 23 -tune film -c:a aac "compressed_$file" fidone跳过已处理文件批量中断后重跑,不想重复处理已经转好的文件:for file in *.mp4; do output="output/$file" [ -f "$output" ] && continue ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac "$output"done一行判断搞定断点续传。Python 版可以用 os.path.exists() 做同样的事。
服务端阅读 06月1日 23:26

FFmpeg 视频格式和编解码器怎么选?MP4、MKV、WebM 各适合什么场景?

选视频格式就是选容器(封装格式),选编解码器就是选压缩算法。容器决定兼容性和功能(能不能塞字幕、多音轨),编解码器决定画质和文件大小。两者要分开想。容器格式:MP4、MKV、WebM 怎么选MP4:万能格式,所有设备都能播。缺点是只支持有限的编解码器,多音轨多字幕支持弱。网络视频、手机分享、社交媒体一律选 MP4,不会有兼容性问题。MKV:万能容器,什么编解码器都能塞,支持无限音轨和字幕轨。缺点是某些老旧设备和播放器不支持(特别是智能电视和游戏机)。本地收藏、多语言视频、高清片源选 MKV。WebM:Google 推的 Web 专用格式,基于 VP8/VP9/AV1 编码。所有主流浏览器支持,不需要插件。网页嵌入视频选 WebM,或者直接用 MP4(浏览器也支持)。MOV:Apple 的格式,QuickTime 原生支持。在 Mac 生态里很方便,但 Windows 上不如 MP4 通用。视频剪辑工作流里常见(Final Cut Pro 默认输出 MOV)。编解码器:H.264、H.265、AV1 怎么选H.264(AVC):兼容性之王,所有设备都支持。压缩效率中等,是目前的默认选择。如果你不确定该用什么,用 H.264 不会错。ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac output.mp4H.265(HEVC):比 H.264 同画质小 30-50%,但编码慢 3-5 倍。兼容性不如 H.264——老手机、老浏览器可能播不了。4K 视频和存档用 H.265,因为省的空间很可观。Windows 10+ 和近三年的手机基本都支持了。ffmpeg -i input.mp4 -c:v libx265 -crf 28 -c:a aac output.mp4AV1:新一代编码,比 H.265 还能再省 20-30%。开源免专利费,YouTube 和 Netflix 都在用。但编码极慢(libaom-av1 比 libx265 慢 10 倍以上),播放需要较新的硬件/软件。2025 年的 AV1 已经可以在最新设备上流畅播放,但离全面普及还有距离。如果追求极致压缩且目标平台新,可以试试。ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -c:a libopus output.webm音频编解码器视频里的音频也别忽略:AAC:通用选择,所有设备支持,128kbps 够听Opus:开源编码器,同码率音质优于 AAC,WebM 默认音频编码MP3:老旧但兼容性极好,新项目不需要用了# 视频 H.264 + 音频 AAC(最通用组合)ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4# 只转音频,视频直接拷贝ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 128k output.mp4选择决策流程目标平台是什么?网页 → MP4/WebM,手机分享 → MP4,本地存档 → MKV需要兼容老设备吗?是 → H.264,否 → H.265/AV1对文件大小敏感吗?是 → H.265 CRF 28,否 → H.264 CRF 23需要多音轨/多字幕吗?是 → MKV,否 → MP4最常见组合:H.264 + AAC 封装成 MP4,覆盖 99% 的播放场景。
服务端阅读 06月1日 23:25

FFmpeg 怎么查看视频信息?ffprobe 命令和视频质量分析实战

获取视频信息用 ffprobe(FFmpeg 自带的探测工具),不需要转码,秒出结果。分析视频质量用 PSNR/SSIM 等指标,对比编码前后的画质差异。ffprobe:一行命令看透视频最常用的命令:# 查看所有信息(人类可读)ffprobe input.mp4# JSON 格式输出(方便脚本解析)ffprobe -v quiet -print_format json -show_format -show_streams input.mp4日常只需要几个关键字段:| 字段 | 含义 | 查看命令 ||------|------|----------|| 分辨率 | 视频宽高 | ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 input.mp4 || 时长 | 视频长度(秒) | ffprobe -v error -show_entries format=duration -of csv=p=0 input.mp4 || 码率 | 比特率 | ffprobe -v error -show_entries format=bit_rate -of csv=p=0 input.mp4 || 帧率 | 每秒帧数 | ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of csv=p=0 input.mp4 || 编码器 | 编解码格式 | ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 input.mp4 |这些命令看着长,但本质都是 -show_entries 指定要哪个字段 + -of 指定输出格式。记住模式就行,不用背命令。提取关键信息的快捷脚本# 一行获取:分辨率 帧率 编码 时长 码率ffprobe -v error -select_streams v:0 \ -show_entries stream=width,height,codec_name,r_frame_rate \ -show_entries format=duration,bit_rate \ -of default=noprint_wrappers=1 input.mp4在 Python 里调用 ffprobe:import subprocess, jsondef get_video_info(path): cmd = ["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", path] result = subprocess.run(cmd, capture_output=True, text=True) return json.loads(result.stdout)info = get_video_info("input.mp4")video = info["streams"][0] # 第一个视频流print(f"分辨率: {video["width"]}x{video["height"]}")print(f"编码: {video["codec_name"]}")print(f"时长: {float(info["format"]["duration"]):.1f}秒")视频质量分析:量化编码损失压缩视频后想知道画质损失了多少,用 PSNR 和 SSIM 两个指标。PSNR(峰值信噪比):数值越高画质越好,30dB 以下明显有损,40dB 以上视觉无损。ffmpeg -i original.mp4 -i compressed.mp4 -lavfi psnr -f null -SSIM(结构相似度):0-1 之间,越接近 1 越相似。SSIM 比 PSNR 更接近人眼感知——PSNR 只看像素差异,SSIM 看结构变化。实际评估画质优先看 SSIM。ffmpeg -i original.mp4 -i compressed.mp4 -lavfi ssim -f null -两个命令都会逐帧计算并输出平均值。VMAF 是 Netflix 提出的更先进的质量指标,更接近人类主观评分,但 FFmpeg 原生不支持(需要额外编译 libvmaf)。常见问题排查视频打不开:先跑 ffprobe input.mp4,看报错信息。常见原因:文件损坏、编码不支持、容器格式错误。ffprobe 比任何播放器都能更快定位问题。码率异常:如果视频文件很大但画质一般,用 ffprobe 看码率——可能是编码效率低(用了老编码器)或码率设置过高。转成 H.264/265 + 合理 CRF 通常能大幅缩小。音视频不同步:ffprobe 看 start_time 差异——音频和视频的起始时间不一致就会导致不同步。
服务端阅读 06月1日 23:24

FFmpeg 视频压缩怎么选参数?CRF、preset 和 tune 实战指南

FFmpeg 压缩视频的核心就三个参数:-crf 控制质量,-preset 控制编码速度和压缩率的平衡,-tune 针对特定内容类型优化。理解这三个参数,就能应对 90% 的压缩场景。CRF:画质旋钮CRF(Constant Rate Factor)是 H.264/H.265 的质量控制参数,范围 0-51。数字越小质量越高文件越大,数字越大质量越低文件越小。关键参考值:18:视觉无损,和原片几乎看不出差别,文件很大23:默认值,质量和体积的平衡点,大多数场景够用28:明显有损但能看,适合手机端播放30+:质量较差,只在极端节省空间时使用ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4CRF 是感知质量恒定——运动多的场景自动多分配码率,静态场景少分配。所以同一个 CRF 值,不同视频的文件大小可能差很多。如果需要精确控制文件大小,得用两遍编码(two-pass)或指定码率。Preset:时间换空间Preset 控制编码器用多少计算时间来寻找更优的压缩方案。越慢的 preset 压缩率越高(同画质文件更小),但编码时间越长。| Preset | 编码速度 | 同 CRF 文件大小 | 适用场景 ||--------|----------|-----------------|----------|| ultrafast | 最快 | 最大(约 2x) | 实时流媒体 || veryfast | 很快 | 较大 | 直播推流 || fast | 快 | 中等 | 日常快转 || medium | 中等(默认) | 基准 | 一般用途 || slow | 慢(约 3x 时间) | 较小(约 -15%) | 离线转码 || veryslow | 很慢(约 6x) | 更小(约 -25%) | 归档存储 |实际建议:离线处理用 slow,实时场景用 veryfast,不确定就用 medium。ultraslow 不存在,veryslow 已经是极限了。从 medium 切到 slow,编码时间翻 3 倍但文件只小 15%——值不值看你的需求。# 离线高质量压缩ffmpeg -i input.mp4 -c:v libx264 -crf 20 -preset slow output.mp4# 快速压缩(直播/即时预览)ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset veryfast output.mp4Tune:针对性优化Tune 让编码器针对特定内容类型调整策略:film:电影/真人视频,去胶片颗粒感,优化暗部细节animation:动画片,优化大面积色块和平滑区域stillimage:PPT 录屏/幻灯片,优化静态画面fastdecode:牺牲一点压缩率换取更快解码速度(低端设备播放)zerolatency:零延迟,实时流媒体和直播专用大部分情况不加 tune 就行。加错了反而比不加差——对真人视频用 animation,细节会糊掉。# 压缩电影ffmpeg -i movie.mkv -c:v libx264 -crf 20 -preset slow -tune film output.mp4# 压缩动画ffmpeg -i anime.mkv -c:v libx264 -crf 20 -preset slow -tune animation output.mp4# 压缩录屏教程ffmpeg -i screen.mp4 -c:v libx264 -crf 23 -preset medium -tune stillimage output.mp4H.265 压缩:省空间但要考虑兼容性H.265(HEVC)比 H.264 同画质文件小 30-50%,但编码慢 3-5 倍,且老设备可能不支持播放。如果目标平台是手机/智能电视/浏览器,H.264 兼容性最好。如果目标是存档或只在 PC 上播放,H.265 更划算。ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset slow output.mp4注意 H.265 的 CRF 值不能和 H.264 直接对比——H.265 的 CRF 28 大致对应 H.264 的 CRF 23,因为 H.265 的范围和感知曲线不同。两个常见坑1. 忘了 -movflags +faststart:MP4 文件的元数据(moov atom)默认放在文件末尾,浏览器必须下载完整个文件才能开始播放。加 -movflags +faststart 把元数据移到开头,允许边下载边播放。网络视频必加。2. 音频不要忘:压缩视频时音频默认也会被重编码。如果只是压缩视频不想动音频,加 -c:a copy 直接拷贝音频流。要压缩音频就用 -c:a aac -b:a 128k,128kbps 对大多数内容够用。
服务端阅读 06月1日 23:20

NLP(自然语言处理)是什么?核心技术从规则到 LLM 怎么演变的?

自然语言处理(Natural Language Processing,NLP)是让计算机理解、解释和生成人类语言的技术。你用的搜索引擎、翻译软件、智能客服、ChatGPT,背后都是 NLP。NLP 解决什么问题NLP 的任务可以分两大类:理解(从文本中提取信息)和生成(产出新的文本)。理解类任务:文本分类(这封邮件是不是垃圾邮件)、命名实体识别(提取人名地名)、情感分析(这条评论是正面还是负面)、问答(从文档中找到答案)。这类任务的核心是把非结构化的文本变成结构化的信息。生成类任务:机器翻译、文本摘要、对话生成、代码生成。这类任务不仅要理解输入,还要产出流畅、连贯、准确的新文本。生成比理解难得多——理解只需要判断对错,生成要在一个天文数字的候选空间里选出最好的。NLP 技术的三个时代规则时代(1950s-1990s):手写语法规则和词典。专家系统写几千条 if-else 规则来解析句子。准确率在小领域内还行,但覆盖面极窄——换个领域规则全废,维护成本爆炸。统计机器学习时代(1990s-2012):从数据中自动学习规律。HMM 做词性标注,CRF 做序列标注,SVM 做分类。关键突破是特征表示——词袋模型、TF-IDF、N-gram 把文本变成了数值向量。但特征仍然需要人工设计,模型能力的天花板就是特征工程的质量。深度学习时代(2013-至今):神经网络自动学特征,不需要手工设计。Word2Vec 让词有了语义向量表示("国王" - "男人" + "女人" ≈ "女王"),RNN/LSTM 处理变长序列,CNN 做文本分类。2017 年 Transformer 出现后,NLP 的范式彻底变了——BERT、GPT 用预训练+微调替代了从零训模型,LLM 用提示词替代了微调本身。NLP 的核心 Pipeline传统 NLP 系统的典型流程:文本 → 预处理(清洗、分词)→ 特征提取(词向量、句向量)→ 模型推理 → 后处理。每一步都需要单独优化,错误会在步骤间传播——分词错了,下游全错。LLM 时代 Pipeline 大幅简化:文本 → tokenizer → LLM 推理 → 输出。分词、特征提取、模型推理都压缩进了一个端到端的过程。代价是计算成本更高,但换来的是更少的手工环节和更好的效果。中文 NLP 的特殊挑战中文没有空格分隔词语,分词是所有下游任务的前提。jieba 是最常用的分词工具,但准确率约 90%,专业领域需要自定义词典。另一个问题是中文的指代消解——"他"指谁?"这家公司"指哪家?英文有性别代词做线索,中文的"他/她/它"发音相同,歧义更多。NLP 当前最热的方向RAG(检索增强生成):让 LLM 先检索外部知识库再生成回答,解决幻觉问题。Agent:让 LLM 调用工具、规划步骤、自主执行任务。多模态:同时处理文本、图像、语音。小模型蒸馏:把大模型的能力压缩到小模型里,降低部署成本。这些方向都建立在 Transformer 和 LLM 的基础上——理解了底层原理,上面的应用方向只是组合方式不同。
服务端阅读 06月1日 23:19

Transformer 架构是怎么工作的?自注意力、位置编码和残差连接详解

Transformer 是 2017 年 Google 在《Attention is All You Need》里提出的架构,用纯注意力机制替代了 RNN 和 CNN 做序列建模。它是 BERT、GPT 以及所有现代大语言模型的基础。核心思想:注意力替代递归RNN 处理序列要一步一步来——看第 3 个词之前必须先处理第 1 和第 2 个词。这导致两个问题:无法并行训练,长距离依赖会衰减(梯度消失)。Transformer 的解决方案是:让每个位置直接和所有其他位置交互,一步到位。不需要逐步递归,训练时所有位置可以并行计算——GPU 最擅长这种矩阵运算。自注意力:序列中的每个词和所有词交互对序列中的每个词,自注意力计算它和其他所有词的相关性(注意力权重),然后按权重聚合信息。具体来说:每个词生成三个向量——Query(我在找什么)、Key(我能提供什么)、Value(我的实际内容)。Query 和所有 Key 做点积得到相关性分数,softmax 归一化后对 Value 加权求和。Attention(Q, K, V) = softmax(QK^T / √d_k) V除以 √d_k 是缩放,防止点积太大导致 softmax 输出接近 one-hot(梯度几乎为零)。这个缩放因子是"Scaled Dot-Product Attention"里"Scaled"的由来。多头注意力:同时学多种关系一个注意力头只能学一种关联模式。但语言中有语法关系、语义关系、位置关系等多种层次。多头注意力让每个头独立学习不同的模式——8 个头就学 8 种不同的"怎么看句子"的方式,最后拼接起来。实验上,多头注意力的效果显著优于单头。但头数不是越多越好,通常和模型维度一起调。GPT-3 用了 96 个头,但那是因为模型维度是 12288——每个头的维度是 128,和原始论文一致。位置编码:没有递归,怎么知道词的顺序自注意力本身是排列不变的——打乱输入顺序,输出只是对应的排列,值不变。但"猫吃鱼"和"鱼吃猫"意思完全不同,模型必须知道词的顺序。Transformer 用正弦/余弦函数生成位置编码,和词嵌入相加。为什么用三角函数?因为它有相对位置的性质:PE(pos+k) 可以用 PE(pos) 的线性变换表示,这让模型更容易学习相对位置关系。后来的模型用了可学习的位置编码(BERT、GPT 都是),直接让模型自己学一组位置向量。RoPE(旋转位置编码)是更新的方案,被 LLaMA 等模型采用,能更好地泛化到训练时没见过的序列长度。残差连接和层归一化每个 Transformer 层的输出 = LayerNorm(x + Sublayer(x)),其中 Sublayer 是注意力或前馈网络。残差连接(+x)让梯度可以直接回传,避免深层网络梯度消失。层归一化(LayerNorm)稳定训练,防止每层的输出分布漂移。注意归一化的位置:原始 Transformer 是 Post-LN(先 Sublayer 再 LN),后来发现 Pre-LN(先 LN 再 Sublayer)训练更稳定,GPT 和大多数现代模型都用 Pre-LN。编码器-解码器结构原始 Transformer 用于机器翻译,包含编码器和解码器:编码器:双向自注意力 + 前馈网络,理解源语言解码器:单向自注意力(遮住未来信息)+ 交叉注意力(看编码器输出)+ 前馈网络,生成目标语言但后来的发展证明不需要两者都用:BERT 只用编码器(理解任务),GPT 只用解码器(生成任务),T5 保留了完整的编码器-解码器。2024 年的趋势是纯解码器架构一统天下——解码器通过指令微调也能做理解任务,何必维护两个模块?前馈网络:注意力的补充每层还有一个两层的前馈网络:FFN(x) = W2·ReLU(W1·x)。FFN 的隐藏维度通常是模型维度的 4 倍(如 d_model=768 时 FFN 维度=3072)。自注意力负责词和词之间的关系,FFN 负责每个位置内部的非线性变换。可以理解为:注意力做信息路由(把相关信息拉过来),FFN 做信息加工(把拉过来的信息消化掉)。研究表明 FFN 层存储了大部分的"知识"(事实记忆),而注意力层更多在做"逻辑"(关系推理)。
服务端阅读 06月1日 23:18

BERT 和 GPT 有什么区别?为什么一个擅长理解一个擅长生成?

BERT 用 Transformer 编码器,GPT 用 Transformer 解码器。这一个选择决定了它们的所有差异:BERT 双向看上下文(适合理解),GPT 只看上文(适合生成)。架构选择:编码器 vs 解码器Transformer 原论文有编码器和解码器两部分。编码器的自注意力是双向的——处理"苹果"这个词时,"苹果"前后所有词都能看到。解码器的自注意力是单向的(也叫因果注意力)——只能看到当前词和它之前的词,后面的词被遮住。BERT 选了编码器,因为它要做的是"完形填空":遮住一些词,根据前后文预测。双向注意力让模型能同时利用左右两侧的上下文信息。GPT 选了解码器,因为它要做的是"续写":给定前文,预测下一个词。单向注意力保证训练和推理的一致性——推理时确实只能看到已生成的前文。如果用双向注意力,训练时能看到"未来"但推理时看不到,就会产生不一致。训练目标:MLM vs CLMBERT 的掩码语言模型(MLM):随机遮住 15% 的 token,让模型预测被遮住的词。这就像做完形填空——"The [MASK] sat on the mat",模型要预测 [MASK] 是 "cat"。BERT 还加了一个下一句预测(NSP)任务,判断两个句子是否相邻,但后来的研究表明 NSP 其实没太大用,RoBERTa 去掉 NSP 反而效果更好。GPT 的因果语言模型(CLM):给定前文,预测下一个 token。这天然就是一个生成任务——每个词都是基于前面所有词的概率分布选出来的。GPT 的训练目标简单粗暴,但规模大了之后涌现出了 BERT 做不到的能力:in-context learning(上下文学习)、chain-of-thought reasoning(链式推理)。能力差异的本质BERT 强在理解:文本分类、NER、问答(抽取式)、语义匹配。这些任务不需要生成新文本,只需要对已有文本做判断。双向注意力让 BERT 看到了完整的上下文,判断更准确。GPT 强在生成:对话、翻译、代码生成、创意写作。这些任务需要一步步产出新内容,单向注意力的自回归方式和生成任务天然契合。而且 GPT 的生成能力随规模非线性增长——GPT-2 只能写连贯的短文,GPT-3 能做 few-shot learning,GPT-4 能做复杂推理。这种涌现能力是 BERT 架构做不到的。一句话总结:BERT 是最好的阅读理解者,GPT 是最好的写作高手。2024-2025 的格局BERT 系列在工业界仍然广泛使用——分类、NER 这些任务用 BERT 微调又快又便宜,768 维的 BERT-base 推理一次只要几毫秒。但新项目越来越倾向直接用 LLM API(GPT-4/Claude)+ prompt engineering 替代 BERT 微调,因为省掉了标注数据和训练的成本。GPT 阵营这边,开源模型(LLaMA、Mistral、Qwen、DeepSeek)已经可以在本地跑,7B 参数的模型在一台消费级 GPU 上就能推理。闭源模型(GPT-4o、Claude Sonnet、Gemini)在能力上仍然领先,但差距在缩小。一个值得注意的趋势:编码器-解码器架构(T5、BART)正在被纯解码器架构取代。T5 最初证明了解码器也能做理解任务,后来大家发现直接用 GPT 架构加指令微调就能同时搞定理解和生成,何必用两个模块?