Skip to content

多媒体(Multimedia)面试题

本题库共收录 56 道面试题(基础 12 / 进阶 17 / 深入 20 / 架构 7)。 本文件收录前端多媒体相关面试题,目标题量 30 道。 题型覆盖:概念题、代码分析题、手写代码题、场景设计题、系统设计题、性能优化题、综合开放题。 难度覆盖:基础、进阶、深入、架构。 每道题除标准参考答案外,另附口头回答版,便于面试时快速组织语言。

目录


基础题(8 道)

FB-51-CO-B-001:视频编码和封装有什么区别?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:51 Multimedia 标签:视频编码、封装格式、音视频基础、MP4、H.264 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请解释视频编码(Codec)和封装(Container)的区别,并各举两个常见格式。

参考答案

视频编码和封装是多媒体处理中的两个不同层次。

  • 编码(Codec):负责把原始音视频数据压缩成更小的码流。它决定视频的画质、码率和兼容性。

    • 常见视频编码:H.264 / AVC、H.265 / HEVC、AV1、VP9。
    • 常见音频编码:AAC、MP3、Opus。
  • 封装(Container):负责把编码后的音视频轨道、字幕、元数据等打包成一个文件。它决定文件结构和播放时的解复用方式。

    • 常见封装格式:MP4、MKV、WebM、MOV、FLV、TS。

以 MP4 文件为例:

text
MP4 文件(容器)
├── 视频轨道(H.264 编码)
├── 音频轨道(AAC 编码)
├── 字幕轨道(WebVTT / mov_text)
└── 元数据(时长、分辨率、旋转角度等)

关系类比:

维度编码封装
作用压缩数据组织数据
类比压缩算法(如 zip)文件夹 + 目录
关注点压缩率、画质、解码性能轨道管理、兼容性、元数据

最佳实践:

  • Web 场景优先使用 H.264 + AAC 封装为 MP4,兼容性最好。
  • 直播场景常用 H.264 + AAC 封装为 TS 分片,配合 HLS 播放。

评分维度

  • 能区分编码和封装的作用(40%)
  • 能各举出至少 2 个常见格式(30%)
  • 能说明容器内可以包含多个轨道(30%)

常见错误

  • 把 MP4 当成视频编码格式。
  • 认为 H.264 是封装格式。
  • 忽略音频编码和字幕轨道也属于容器内容。

延伸追问

  • 为什么 HLS 直播常用 TS 而不是 MP4 作为分片?
  • WebM 和 MP4 在浏览器中的兼容性有什么差异?

相关题目

参考资源

口头回答版

编码和封装是两回事。编码负责把音视频原始数据压缩,比如 H.264、H.265、AAC、Opus 这些都是编码格式。封装则是把压缩后的音视频轨道、字幕、元数据打包成一个文件,比如 MP4、WebM、MKV、TS。MP4 不是编码格式,它是一个容器,里面可以放 H.264 视频和 AAC 音频。


FB-51-CO-B-002:HLS 和 DASH 流媒体协议的基本原理是什么?

题型:概念题 难度:🟢 基础 岗位层级:初级 / 高级 面试知识域:51 Multimedia 标签:HLS、DASH、流媒体、自适应码率、M3U8 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请解释 HLS 和 DASH 两种流媒体协议的基本原理,并说明它们各自的特点。

参考答案

HLS(HTTP Live Streaming)和 DASH(Dynamic Adaptive Streaming over HTTP)都是基于 HTTP 的自适应码率流媒体协议。

HLS

  • 由 Apple 提出,最初用于 iOS 生态。
  • 服务器把视频切分成多个小 TS 分片,生成一个索引文件 .m3u8
  • 播放器下载 m3u8 后,根据带宽动态选择不同码率的分片播放。
  • 天然兼容 Safari、iOS,延迟通常在 10-30 秒。

DASH

  • 由 MPEG 制定的国际标准,也叫 MPEG-DASH。
  • 使用 .mpd(Media Presentation Description)作为索引文件。
  • 分片格式更灵活,常用 .m4s(fragmented MP4)。
  • 各浏览器支持较好,但 Safari 对 DASH 支持不如 HLS 原生。

对比:

维度HLSDASH
索引文件.m3u8.mpd
分片格式TS / fMP4fMP4 为主
发起方AppleMPEG
Safari 兼容性原生支持需 polyfill / 第三方库
低延迟扩展LL-HLSLL-DASH
标准开放性相对封闭开放标准

最佳实践:

  • 如果目标用户主要是 iOS / Safari,优先使用 HLS。
  • 如果需要跨平台统一方案,可用 DASH 或双协议兼容。

评分维度

  • 能说明 HLS 基于 m3u8 + TS 分片(35%)
  • 能说明 DASH 基于 mpd + fMP4 分片(35%)
  • 能对比两者在 Safari 兼容性和标准开放性上的差异(30%)

常见错误

  • 认为 HLS 和 DASH 都需要特殊流媒体服务器(实际上基于 HTTP 即可)。
  • 混淆索引文件和分片文件的作用。
  • 认为 HLS 只能在 Apple 设备上使用。

延伸追问

  • 为什么直播场景下 HLS 延迟比 WebRTC 高?
  • LL-HLS 通过哪些机制降低延迟?

相关题目

参考资源

口头回答版

HLS 是苹果推出的流媒体协议,把视频切成很多小 TS 文件,用一个 m3u8 索引文件告诉播放器按顺序下载。DASH 是国际标准的 MPEG-DASH,用 mpd 文件做索引,分片通常是 fMP4。两者都能根据网速自动切换清晰度。HLS 在 Safari 和 iOS 上原生支持最好,DASH 更开放、跨平台更统一。


FB-51-CO-B-003:如何使用 getUserMedia 获取摄像头和麦克风?

题型:概念题 / 手写代码题 难度:🟢 基础 岗位层级:初级 面试知识域:51 Multimedia 标签:getUserMedia、MediaStream、摄像头、麦克风、权限 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请写出使用 navigator.mediaDevices.getUserMedia 获取摄像头和麦克风的基本代码,并说明需要注意的权限和兼容性问题。

参考答案

getUserMedia 是 WebRTC 相关 API 的一部分,用于获取用户本地的音视频媒体流。

基本用法:

javascript
async function getMedia() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      video: true,
      audio: true,
    });
    const videoElement = document.getElementById('localVideo');
    videoElement.srcObject = stream;
  } catch (err) {
    console.error('获取媒体失败:', err.name, err.message);
  }
}

常用约束配置:

javascript
const constraints = {
  video: {
    width: { ideal: 1280 },
    height: { ideal: 720 },
    facingMode: 'user', // 前置摄像头
  },
  audio: {
    echoCancellation: true,
    noiseSuppression: true,
  },
};

注意事项:

  • HTTPS 环境getUserMedia 必须在安全上下文(HTTPS 或 localhost)中使用。
  • 用户授权:浏览器会弹出权限提示,用户拒绝后会抛出 NotAllowedError
  • 设备枚举:可通过 navigator.mediaDevices.enumerateDevices() 获取可用设备列表。
  • 释放资源:停止使用时需要调用 stream.getTracks().forEach(track => track.stop()) 释放摄像头和麦克风。

最佳实践:

  • 在页面 unload 或组件卸载时停止轨道,避免摄像头指示灯常亮。
  • 使用 ideal 而非 exact 约束,提高获取成功率。

评分维度

  • 能写出 getUserMedia 基本调用(40%)
  • 能说明 HTTPS 和用户授权要求(30%)
  • 能说明如何停止轨道释放资源(30%)

常见错误

  • 在 HTTP 环境下调用导致 API 不可用。
  • 用户拒绝后没有错误处理。
  • 忘记停止 track,导致摄像头麦克风持续占用。

延伸追问

  • 如何切换前置和后置摄像头?
  • getUserMedia 和 getDisplayMedia 有什么区别?

相关题目

参考资源

口头回答版

getUserMedia 用来获取用户的摄像头和麦克风。调用时传一个约束对象,比如 { video: true, audio: true },返回的是一个 MediaStream。拿到 stream 后赋给 video 标签的 srcObject 就能预览。要注意必须在 HTTPS 或 localhost 下使用,还要用户授权。用完一定要调用 stream.getTracks().forEach(track => track.stop()) 释放设备,不然摄像头灯会一直亮。


FB-51-CO-B-004:Canvas 上绘制视频帧的基本步骤是什么?

题型:概念题 / 手写代码题 难度:🟢 基础 岗位层级:初级 面试知识域:51 Multimedia 标签:Canvas、video、drawImage、视频帧、图像处理 出现频率:中频 预计回答时长:3-5 分钟

题目描述: 请说明如何在 HTMLCanvasElement 上绘制 <video> 标签当前帧的内容,并写出关键代码。

参考答案

在 Canvas 上绘制视频帧的核心是使用 CanvasRenderingContext2D.drawImage(),把 video 元素作为图像源传入。

基本步骤:

  1. 创建 <video><canvas> 元素。
  2. 加载视频并播放。
  3. 使用 requestAnimationFrame 循环调用 ctx.drawImage(video, 0, 0, width, height)

代码示例:

html
<video id="video" src="example.mp4" crossOrigin="anonymous" controls></video>
<canvas id="canvas" width="640" height="360"></canvas>
javascript
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

function renderFrame() {
  if (!video.paused && !video.ended) {
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  }
  requestAnimationFrame(renderFrame);
}

video.addEventListener('play', renderFrame);

关键说明:

  • drawImage 可以把 <video><img><canvas>、ImageBitmap 等作为源。
  • 如果视频是跨域资源,需要设置 crossOrigin="anonymous",否则调用 toDataURLgetImageData 会报错。
  • requestAnimationFrame 中绘制,帧率和显示器刷新率同步,避免过度绘制。

最佳实践:

  • 仅在视频播放时绘制,暂停时停止绘制以节省性能。
  • 如需截图,可调用 canvas.toDataURL('image/png')

评分维度

  • 能写出 drawImage 绘制 video 的核心代码(50%)
  • 能说明 requestAnimationFrame 的使用(30%)
  • 能提到跨域问题和 crossOrigin(20%)

常见错误

  • 在视频还没准备好时就调用 drawImage,导致绘制失败。
  • 忘记处理跨域,导致 toDataURL 抛出安全错误。
  • 不使用 requestAnimationFrame,导致不必要的重绘。

延伸追问

  • 如何用 Canvas 给视频添加水印?
  • Canvas 截图时如何保持原始视频分辨率?

相关题目

参考资源

口头回答版

在 Canvas 上画视频帧很简单,用 ctx.drawImage(video, 0, 0, width, height) 就行,video 元素可以直接作为图像源。通常放在 requestAnimationFrame 里循环绘制,这样和屏幕刷新率同步。要注意如果视频跨域,要给 video 标签加 crossOrigin="anonymous",不然截图或取像素会报安全错误。


FB-51-CO-B-005:Web Audio API 中的 AudioContext 是什么?

题型:概念题 难度:🟢 基础 岗位层级:初级 / 高级 面试知识域:51 Multimedia 标签:Web Audio、AudioContext、音频图、音频节点 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请解释 Web Audio API 中 AudioContext 的作用,并说明如何播放一个音频文件。

参考答案

AudioContext 是 Web Audio API 的核心对象,代表一个音频处理图。所有音频操作都在这个上下文中进行。

主要作用:

  • 管理音频节点的创建和连接。
  • 控制音频的播放、暂停、恢复。
  • 提供高精度的时间调度能力。
  • 作为音频渲染的终点(destination)。

播放音频文件的基本流程:

javascript
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

async function playSound(url) {
  const response = await fetch(url);
  const arrayBuffer = await response.arrayBuffer();
  const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);

  const source = audioCtx.createBufferSource();
  source.buffer = audioBuffer;
  source.connect(audioCtx.destination);
  source.start(0);
}

音频图示意:

text
AudioBufferSourceNode -> AudioContext.destination

关键说明:

  • AudioContext 创建后可能处于 suspended 状态,需要在用户交互后调用 audioCtx.resume()
  • Safari 需要使用 webkitAudioContext 前缀。
  • 节点通过 connect() 方法连接,形成处理链。

最佳实践:

  • 一个页面通常只创建一个 AudioContext,避免资源浪费。
  • 在页面可见性变化或用户离开时考虑 suspend / close。

评分维度

  • 能说明 AudioContext 是音频处理上下文(40%)
  • 能写出加载、解码、播放音频的基本代码(40%)
  • 能提到用户交互后才能 resume 的约束(20%)

常见错误

  • 每次播放都创建新的 AudioContext。
  • 在 AudioContext 处于 suspended 状态时直接播放,导致没有声音。
  • 混淆 Web Audio API 和 HTMLAudioElement。

延伸追问

  • Web Audio API 和 HTMLAudioElement 有什么区别?
  • 如何实现音频的可视化?

相关题目

参考资源

口头回答版

AudioContext 是 Web Audio API 的核心,相当于一个音频处理的环境。你要播放声音,就先创建一个 AudioContext,然后创建音频节点,比如 BufferSource,把音频数据解码成 AudioBuffer 赋给它,再连接到 destination 也就是扬声器。要注意的是,AudioContext 刚创建时可能是 suspended 状态,必须在用户点击等交互之后调用 resume 才能出声。


FB-51-PE-B-006:video 标签的 preload 和 autoplay 属性有什么作用?

题型:性能优化题 难度:🟢 基础 岗位层级:初级 面试知识域:51 Multimedia 标签:video、preload、autoplay、首帧、性能优化 出现频率:高频 预计回答时长:2-3 分钟

题目描述: 请说明 <video> 标签的 preloadautoplay 属性的作用,以及它们对性能和用户体验的影响。

参考答案

preload

  • 控制浏览器在页面加载时预加载多少视频数据。
  • 取值:
    • none:不预加载,点击播放后再加载。
    • metadata:只加载元数据(时长、尺寸、首帧等)。
    • auto:由浏览器决定是否预加载较多数据。

autoplay

  • 控制视频是否在加载后自动播放。
  • 现代浏览器通常只允许静音自动播放(muted autoplay),带声音的自动播放会被阻止。

对性能和体验的影响:

属性优点缺点
preload="none"节省带宽和内存点击播放后可能需要等待缓冲
preload="metadata"平衡,能显示首帧和时长仍会有少量请求
preload="auto"播放更流畅消耗更多带宽,可能影响首屏
autoplay自动吸引注意力带声音自动播放被浏览器阻止,且可能浪费流量

最佳实践:

  • 首屏非核心视频使用 preload="none"preload="metadata"
  • 需要自动播放的静音视频使用 autoplay muted playsinline
  • 移动端注意 playsinline 属性,避免视频全屏播放打断体验。

评分维度

  • 能说明 preload 三个取值的含义(40%)
  • 能说明 autoplay 的浏览器限制(30%)
  • 能根据场景给出合理建议(30%)

常见错误

  • 认为 preload="auto" 一定会预加载完整视频。
  • 认为设置 autoplay 就能在所有浏览器自动带声音播放。
  • 忽略移动端 playsinline 的使用。

延伸追问

  • 如何检测浏览器是否阻止了自动播放?
  • 预加载策略和 CDN 流量成本如何平衡?

相关题目

参考资源

口头回答版

preload 控制视频预加载多少数据,none 是不预加载,metadata 只加载元数据,auto 让浏览器自己决定。autoplay 是自动播放,但现代浏览器基本只允许静音自动播放。所以要做自动播放,通常要写 autoplay muted playsinline。首屏不重要的视频我建议 preload="metadata",能省带宽又能显示首帧。


FB-51-CO-B-007:字幕文件 WebVTT 和 SRT 有什么区别?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:51 Multimedia 标签:字幕、WebVTT、SRT、多语言、无障碍 出现频率:中频 预计回答时长:2-3 分钟

题目描述: 请对比 WebVTT 和 SRT 两种字幕文件格式,并说明前端如何为 video 标签添加字幕。

参考答案

SRT(SubRip Subtitle)

  • 最古老的纯文本字幕格式之一。
  • 结构简单:序号、时间码(00:00:01,000 --> 00:00:03,000)、字幕文本。
  • 不支持样式、定位和元数据扩展。
  • 浏览器原生不支持,需要前端解析后渲染。

WebVTT(Web Video Text Tracks)

  • W3C 标准,专为 Web 设计。
  • 时间码使用点号分隔毫秒(00:00:01.000 --> 00:00:03.000)。
  • 支持 v 标识说话人、<c> 样式类、line / position 定位、region 区域等。
  • 浏览器原生支持,可通过 <track> 标签直接加载。

对比:

维度SRTWebVTT
浏览器原生支持不支持支持
样式与定位不支持支持
时间码分隔符逗号点号
适用场景简单字幕、离线编辑Web 播放、复杂样式

前端添加字幕:

html
<video controls>
  <source src="movie.mp4" type="video/mp4" />
  <track kind="subtitles" src="subtitle.vtt" srclang="zh" label="中文" default />
  <track kind="subtitles" src="subtitle-en.vtt" srclang="en" label="English" />
</video>

最佳实践:

  • Web 场景优先使用 WebVTT,减少前端解析成本。
  • 提供多语言字幕时,通过 srclanglabel 区分。
  • 使用 kind="captions" 表示带音效说明的字幕,提升无障碍体验。

评分维度

  • 能对比两种格式的时间码和样式支持(40%)
  • 能说明 WebVTT 是浏览器原生标准(30%)
  • 能写出 track 标签的基本用法(30%)

常见错误

  • 把 SRT 直接作为 track 标签的 src,期望浏览器原生渲染。
  • 混淆 kind="subtitles"kind="captions"
  • 忽略 default 属性的使用。

延伸追问

  • 如何自定义字幕样式?
  • 如何实现字幕的实时翻译或双语显示?

相关题目

参考资源

口头回答版

SRT 和 WebVTT 都是字幕格式。SRT 结构简单,但浏览器不原生支持,也不支持样式和定位。WebVTT 是 W3C 标准,浏览器原生支持,能写样式、定位和区域。前端用 track 标签加载 WebVTT 就行,比如 <track kind="subtitles" src="subtitle.vtt" srclang="zh" label="中文" default />


FB-51-CO-B-008:多媒体内容的无障碍访问需要注意什么?

题型:概念题 难度:🟢 基础 岗位层级:初级 / 高级 面试知识域:51 Multimedia 标签:无障碍、a11y、字幕、键盘、屏幕阅读器 出现频率:中频 预计回答时长:3-5 分钟

题目描述: 请说明在网页中提供音视频内容时,应如何保障无障碍访问(Accessibility)。

参考答案

多媒体无障碍的核心是让听障、视障、运动障碍用户都能感知和操作内容。

主要注意点:

  1. 字幕(Captions)

    • 为所有有意义的音频内容提供同步字幕。
    • 使用 <track kind="captions"> 而非仅 subtitles,captions 包含音效说明。
  2. 键盘可操作

    • 播放、暂停、音量、进度条等控件必须可用键盘操作。
    • 自定义播放器要管理好 tabindex 和焦点状态。
  3. 屏幕阅读器支持

    • 使用语义化标签和 ARIA 属性,如 aria-labelaria-pressedrole="slider"
    • 视频状态变化时通过 aria-live 区域通知用户。
  4. 高对比度与可缩放

    • 控件颜色对比度符合 WCAG 标准。
    • 字幕和控件字体大小应支持缩放。
  5. 减少自动播放

    • 避免带声音的自动播放,尊重用户偏好。
    • 提供明显的播放/暂停控制。
  6. 手势替代

    • 移动端触摸操作应提供键盘或语音替代方式。

示例:

html
<video controls crossOrigin="anonymous">
  <source src="movie.mp4" type="video/mp4" />
  <track kind="captions" src="captions.vtt" srclang="zh" label="中文字幕" default />
</video>

最佳实践:

  • 优先使用浏览器原生 <video controls>,它自带无障碍支持。
  • 自定义播放器时,参考 WAI-ARIA 媒体播放器规范。

评分维度

  • 能提到字幕和 track 的使用(30%)
  • 能提到键盘操作和焦点管理(30%)
  • 能提到屏幕阅读器和 ARIA(20%)
  • 能提到对比度和自动播放(20%)

常见错误

  • 只加 subtitles 不加 captions,忽略音效说明。
  • 自定义播放器完全不用键盘事件。
  • 认为原生 video 标签已经满足所有无障碍需求,忽略业务自定义控件的测试。

延伸追问

  • 如何测试自定义播放器的无障碍性?
  • 语音朗读视频内容有哪些方案?

相关题目

参考资源

口头回答版

多媒体无障碍主要是让所有人都能用。要给视频加同步字幕,最好是用 kind="captions" 这样还能描述音效;播放控件要能用键盘操作;自定义控件要加 ARIA 标签让屏幕阅读器能读;颜色对比度要够;不要自动播放带声音的视频。优先用浏览器原生 video controls,它自带很多无障碍支持。


进阶题(8 道)

FB-51-CO-A-009:HLS 的 m3u8 文件结构是怎样的?TS 分片的优势是什么?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:51 Multimedia 标签:HLS、m3u8、TS、流媒体、自适应码率 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明 HLS 中 m3u8 索引文件的基本结构,并解释为什么直播场景常用 TS 作为分片格式。

参考答案

m3u8 基本结构

text
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:9.009,
segment_0.ts
#EXTINF:9.009,
segment_1.ts
#EXTINF:9.009,
segment_2.ts
#EXT-X-ENDLIST

关键标签说明:

标签含义
#EXTM3U文件头,表明是 m3u8 文件
#EXT-X-VERSIONHLS 协议版本
#EXT-X-TARGETDURATION最大分片时长(秒)
#EXT-X-MEDIA-SEQUENCE第一个分片的序号,直播时随时间递增
#EXTINF当前分片的精确时长
#EXT-X-ENDLIST点播文件结束标记,直播通常没有

主播放列表(多码率):

text
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
low.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720
high.m3u8

TS 分片的优势

  1. 自包含:每个 TS 分片都包含完整的 PES 包头和音视频数据,可以从任意分片开始独立解码。
  2. 容错性好:某个分片损坏只影响该分片,不会导致后续无法播放。
  3. 与广播标准兼容:TS(Transport Stream)是 DVB/ATSC 数字电视标准,生态成熟。
  4. 适合直播:分片边界清晰,服务器可以边生成边下发。

现代演进:

  • LL-HLS 开始使用 fMP4(fragmented MP4)分片以降低延迟。
  • HLS CMAF 规范允许同一分片同时服务 HLS 和 DASH。

评分维度

  • 能说明 m3u8 基本标签含义(40%)
  • 能解释多码率主播放列表的作用(20%)
  • 能说明 TS 自包含、容错、适合直播的优势(40%)

常见错误

  • 认为 m3u8 本身包含视频数据(它只包含索引)。
  • 混淆 #EXT-X-TARGETDURATION 和实际分片时长。
  • 认为 HLS 只能用 TS,不知道 fMP4 也可以。

延伸追问

  • 直播 m3u8 和点播 m3u8 有什么区别?
  • CMAF 如何统一 HLS 和 DASH 的分片?

相关题目

参考资源

口头回答版

m3u8 是 HLS 的索引文件,里面用 #EXTM3U 开头,#EXT-X-TARGETDURATION 表示最大分片时长,#EXT-X-MEDIA-SEQUENCE 表示第一个分片序号,#EXTINF 是每个分片的时长,#EXT-X-ENDLIST 表示点播结束。多码率时还有一个主播放列表,用 #EXT-X-STREAM-INF 列出不同码率的 m3u8。TS 分片的好处是自包含,每个分片都能独立解码,某个分片坏了不影响后面,所以特别适合直播。


FB-51-PE-A-010:视频播放卡顿如何排查和优化?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:51 Multimedia 标签:卡顿、缓冲、性能优化、CDN、码率、缓冲区 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请描述视频播放卡顿的常见原因,以及前端可以从哪些方面进行排查和优化。

参考答案

视频卡顿通常发生在下载、解码或渲染三个阶段。

常见原因

  1. 网络带宽不足

    • 码率超过可用带宽,导致下载速度跟不上播放速度。
    • CDN 节点距离远或回源慢。
  2. 缓冲区耗尽

    • buffered 区间不足以支撑后续播放。
    • 首屏缓冲时间太短就强行播放。
  3. 解码性能不足

    • 高分辨率或高码率视频在低端设备上软解压力大。
    • 浏览器不支持硬解,占用 CPU。
  4. 渲染卡顿

    • 页面 JS 执行阻塞主线程。
    • 自定义播放器 UI 过度重绘。

排查方法

javascript
const video = document.querySelector('video');

// 查看已缓冲区间
console.log(video.buffered);

// 查看当前播放位置
console.log(video.currentTime);

// 查看网络状态
console.log(video.networkState);
console.log(video.readyState);

// 监听缓冲和等待事件
video.addEventListener('waiting', () => console.log('缓冲中,即将卡顿'));
video.addEventListener('stalled', () => console.log('下载停滞'));
video.addEventListener('playing', () => console.log('恢复播放'));

优化方案

方向措施
网络CDN 就近分发、P2P 加速、多码率自适应
码率根据带宽动态切换清晰度
预加载合理设置 preload,保证足够缓冲
解码提供多种编码格式,优先使用设备硬解支持的格式
渲染避免主线程阻塞,复杂 UI 用 requestAnimationFrame
监控采集 waiting、stalled、error 事件做埋点

最佳实践:

  • 对长视频采用自适应码率(ABR)策略,如 BOLA、Throughput-based。
  • 设置最小缓冲阈值,低于阈值时降级清晰度或暂停加载。

评分维度

  • 能从网络、缓冲、解码、渲染四个维度分析原因(40%)
  • 能说出至少 3 种排查方法或事件(30%)
  • 能给出具体优化措施(30%)

常见错误

  • 只关注网络,忽略解码和渲染瓶颈。
  • 盲目提高预加载,导致首屏和流量成本增加。
  • 不采集用户端真实数据,只依赖本地测试。

延伸追问

  • 如何设计自适应码率切换策略?
  • 低端设备上如何降级视频清晰度?

相关题目

参考资源

口头回答版

视频卡顿一般有三个层面:网络下载慢、解码性能不够、渲染阻塞。排查时可以看 video.buffered 缓冲区、监听 waiting 和 stalled 事件。优化可以从 CDN 分发、多码率自适应、合理预加载、优先使用硬解格式、避免主线程阻塞这些方面入手。长视频最好用 ABR 自动根据带宽切换清晰度。


FB-51-CO-A-011:WebRTC 建立连接的基本流程是什么?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:51 Multimedia 标签:WebRTC、RTC、P2P、信令、ICE、SDP 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请简述 WebRTC 建立点对点连接的主要流程,并说明信令服务器的作用。

参考答案

WebRTC 建立连接主要分为三个步骤:媒体协商、网络发现和连接建立、数据传输。

1. 获取本地媒体流

javascript
const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
localStream.getTracks().forEach(track => pc.addTrack(track, localStream));

2. 创建 RTCPeerConnection

javascript
const pc = new RTCPeerConnection({
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
});

3. 交换 SDP(媒体协商)

  • 一方创建 Offer,设置本地描述(setLocalDescription)。
  • 通过信令服务器发送 Offer 给对方。
  • 对方设置远端描述(setRemoteDescription),创建 Answer。
  • Answer 通过信令服务器返回,双方完成 SDP 交换。

4. ICE 候选交换和网络穿透

  • 双方通过 ICE 框架收集候选地址(host、srflx、relay)。
  • STUN 用于获取公网地址,TURN 用于中继。
  • 候选地址交换后,选择最优路径建立连接。

5. 连接建立并传输数据

  • 完成连接后,音视频数据通过 RTP/RTCP 传输。
  • 数据通道(DataChannel)通过 SCTP 传输任意数据。

信令服务器的作用:

  • 转发 Offer / Answer / ICE candidate。
  • 本身不传输媒体数据,只负责协商阶段的消息中转。
  • 常用 WebSocket 或 SSE 实现。

连接流程图:

text
A                     信令服务器                     B
| createOffer          |                            |
| setLocalDescription  |                            |
|--------------------->|        offer               |
|                      |--------------------------->|
|                      |                            | setRemoteDescription
|                      |                            | createAnswer
|                      |        answer              |
|                      |<---------------------------|
| setRemoteDescription |                            |
| ICE candidate        |                            |
|--------------------->|      candidate             |
|                      |--------------------------->|
|                      |     candidate              |
|                      |<---------------------------|
|              建立 P2P 连接,直接传输媒体数据         |

最佳实践:

  • 生产环境部署 TURN 服务器,保证对称型 NAT 也能连通。
  • 使用 trickle ICE 实时交换候选,缩短连接建立时间。

评分维度

  • 能说明 SDP Offer/Answer 交换流程(35%)
  • 能说明 ICE/STUN/TURN 的作用(35%)
  • 能说明信令服务器只负责协商不传输媒体(30%)

常见错误

  • 认为信令服务器也传输媒体数据。
  • 忽略 TURN 服务器在对称 NAT 下的必要性。
  • 混淆 SDP 和 ICE candidate 的作用。

延伸追问

  • Trickle ICE 和 Vanilla ICE 有什么区别?
  • WebRTC 如何保证音视频同步?

相关题目

参考资源

口头回答版

WebRTC 建立连接分几步:先 getUserMedia 拿到本地媒体流,加到 RTCPeerConnection 里;然后一方创建 Offer,通过信令服务器发给对方,对方回 Answer;同时双方收集 ICE candidate 也经信令交换。SDP 负责媒体协商,ICE 负责找网络通路,STUN 拿公网地址,TURN 做中继。最后媒体数据走 P2P 直连。信令服务器只传控制消息,不传媒体。


FB-51-CD-A-012:用 Canvas 实现视频截图功能

题型:手写代码题 难度:🟡 进阶 岗位层级:高级 面试知识域:51 Multimedia 标签:Canvas、视频截图、drawImage、toDataURL、crossOrigin 出现频率:中频 预计回答时长:5-10 分钟

题目描述: 请手写一个函数,接收 video 元素和期望的输出格式,返回当前帧的 Base64 图片数据。注意处理跨域和分辨率问题。

参考答案

javascript
function captureFrame(video, options = {}) {
  const {
    type = 'image/png',
    quality = 0.92,
    width = video.videoWidth,
    height = video.videoHeight,
  } = options;

  // 创建离屏 canvas
  const canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = height;
  const ctx = canvas.getContext('2d');

  // 绘制当前帧
  ctx.drawImage(video, 0, 0, width, height);

  // 输出 Base64
  return canvas.toDataURL(type, quality);
}

使用示例:

javascript
const video = document.querySelector('video');

// 按原始分辨率截图
const full = captureFrame(video);

// 输出压缩后的 JPEG
const compressed = captureFrame(video, {
  type: 'image/jpeg',
  quality: 0.8,
  width: 640,
  height: 360,
});

跨域处理:

html
<video src="https://cdn.example.com/video.mp4" crossOrigin="anonymous" controls></video>

如果视频资源没有配置 CORS,toDataURL 会抛出安全错误:

text
SecurityError: The operation is insecure.

增强版:支持下载和 Blob 输出

javascript
async function captureFrameAsBlob(video, options = {}) {
  const dataUrl = captureFrame(video, options);
  const res = await fetch(dataUrl);
  return res.blob();
}

function downloadFrame(video, filename = 'screenshot.png') {
  const dataUrl = captureFrame(video, { type: 'image/png' });
  const a = document.createElement('a');
  a.href = dataUrl;
  a.download = filename;
  a.click();
}

最佳实践:

  • 截图前检查 video.readyState >= 2(HAVE_CURRENT_DATA),确保有可用帧。
  • 高清截图使用原始 videoWidth/videoHeight,避免被 CSS 尺寸影响。
  • 跨域视频务必配置 CORS 并使用 crossOrigin="anonymous"

评分维度

  • 能写出 drawImage + toDataURL 核心逻辑(40%)
  • 能处理分辨率参数(20%)
  • 能说明跨域问题和解决方案(20%)
  • 能补充下载或 Blob 输出(20%)

常见错误

  • 使用 CSS 宽高设置 canvas,导致截图变形。
  • 忽略跨域,导致安全错误。
  • 在视频尚未加载完成时调用截图。

延伸追问

  • 如何截出不带控件和叠加层的纯净视频帧?
  • 如果需要批量截图,如何优化性能?

相关题目

参考资源

口头回答版

视频截图就是创建一个 canvas,把 video 当前帧 drawImage 上去,然后调用 canvas.toDataURL 拿到 Base64。要注意 canvas 的宽高用 video.videoWidth 和 video.videoHeight,保证分辨率正确。如果视频跨域,要给 video 标签加 crossOrigin="anonymous",并且 CDN 要配 CORS,否则 toDataURL 会报安全错误。还可以封装成下载功能。


FB-51-CO-A-013:MediaRecorder API 如何录制音视频?

题型:概念题 / 手写代码题 难度:🟡 进阶 岗位层级:高级 面试知识域:51 Multimedia 标签:MediaRecorder、录制、Blob、MediaStream、WebM 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明 MediaRecorder API 的基本用法,并写出从 MediaStream 录制音视频并导出 Blob 的代码。

参考答案

MediaRecorder 用于将 MediaStream 录制成 Blob 数据,常用于前端录制摄像头、屏幕或音频。

基本流程:

javascript
let mediaRecorder;
let recordedChunks = [];

async function startRecording() {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true,
  });

  mediaRecorder = new MediaRecorder(stream, {
    mimeType: 'video/webm;codecs=vp9,opus',
  });

  mediaRecorder.ondataavailable = (event) => {
    if (event.data.size > 0) {
      recordedChunks.push(event.data);
    }
  };

  mediaRecorder.onstop = () => {
    const blob = new Blob(recordedChunks, { type: 'video/webm' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'recording.webm';
    a.click();
    URL.revokeObjectURL(url);
  };

  mediaRecorder.start(1000); // 每秒触发一次 ondataavailable
}

function stopRecording() {
  mediaRecorder.stop();
  mediaRecorder.stream.getTracks().forEach(track => track.stop());
}

常用事件:

事件触发时机
ondataavailable有数据可用时触发
onstop录制停止时触发
onpause / onresume暂停/恢复录制
onerror录制出错

常用 MIME Type:

  • video/webm;codecs=vp9,opus
  • video/webm;codecs=vp8,opus
  • video/mp4(部分浏览器支持)

可通过 MediaRecorder.isTypeSupported() 检测支持情况:

javascript
if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9,opus')) {
  // 使用 VP9
}

最佳实践:

  • 录制前调用 isTypeSupported 做兼容性降级。
  • 根据场景选择合理的 timeslice,避免内存中堆积过多数据。
  • 停止录制后释放所有 track,关闭摄像头/麦克风。

评分维度

  • 能写出 MediaRecorder 创建和事件处理(40%)
  • 能说明 ondataavailable 和 onstop 的作用(30%)
  • 能提到 mimeType 兼容性和 isTypeSupported(30%)

常见错误

  • 不释放 stream track,导致设备持续占用。
  • 使用浏览器不支持的 mimeType 直接 new MediaRecorder。
  • 把每次 ondataavailable 的数据都转成 Blob,导致性能问题。

延伸追问

  • 如何实现录制暂停和恢复?
  • MediaRecorder 和 Canvas 录制有什么区别?

相关题目

参考资源

口头回答版

MediaRecorder 用来把 MediaStream 录成 Blob。用法是先拿到 getUserMedia 的 stream,然后 new MediaRecorder(stream, { mimeType: 'video/webm;codecs=vp9,opus' })。监听 ondataavailable 收集数据块,onstop 时把所有块合并成 Blob,再用 URL.createObjectURL 生成下载链接。要注意浏览器支持哪些 mimeType,可以用 MediaRecorder.isTypeSupported 检测。录完一定要停止 track 释放设备。


FB-51-CO-A-014:Web Audio API 如何处理音频可视化?

题型:概念题 / 手写代码题 难度:🟡 进阶 岗位层级:高级 面试知识域:51 Multimedia 标签:Web Audio、可视化、AnalyserNode、FFT、频谱 出现频率:中频 预计回答时长:5-8 分钟

题目描述: 请说明如何使用 Web Audio API 获取音频的频率数据,并在 Canvas 上绘制频谱图。

参考答案

音频可视化的核心是使用 AnalyserNode 提取时域或频域数据,然后在 Canvas 上绘制。

基本流程:

javascript
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const audioElement = document.querySelector('audio');

// 创建源节点
const source = audioCtx.createMediaElementSource(audioElement);

// 创建分析节点
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 256;

// 连接:源 -> 分析器 -> 输出
source.connect(analyser);
analyser.connect(audioCtx.destination);

绘制频谱:

javascript
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const bufferLength = analyser.frequencyBinCount; // fftSize / 2
const dataArray = new Uint8Array(bufferLength);

function draw() {
  requestAnimationFrame(draw);

  analyser.getByteFrequencyData(dataArray);

  ctx.fillStyle = '#000';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  const barWidth = (canvas.width / bufferLength) * 2.5;
  let barHeight;
  let x = 0;

  for (let i = 0; i < bufferLength; i++) {
    barHeight = dataArray[i] / 255 * canvas.height;
    ctx.fillStyle = `rgb(${barHeight + 100}, 50, 50)`;
    ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
    x += barWidth + 1;
  }
}

audioElement.addEventListener('play', () => {
  audioCtx.resume();
  draw();
});

关键 API:

方法说明
getByteFrequencyData获取频域数据,范围 0-255
getFloatFrequencyData获取频域数据,单位为 dB
getByteTimeDomainData获取时域波形数据
getFloatTimeDomainData获取时域波形浮点数据

fftSize 说明:

  • 值越大,频谱分辨率越高,但时间精度越低。
  • 必须是 2 的幂次方,如 256、512、1024、2048。
  • frequencyBinCount = fftSize / 2

最佳实践:

  • requestAnimationFrame 中绘制,和屏幕刷新同步。
  • 音频播放前需要用户交互恢复 AudioContext。
  • 低频到高频的数据按 index 递增,可据此做分频色彩映射。

评分维度

  • 能写出 AnalyserNode 创建和连接(40%)
  • 能用 getByteFrequencyData 获取数据(30%)
  • 能在 Canvas 上绘制频谱(30%)

常见错误

  • 忘记调用 audioCtx.resume(),导致没有声音。
  • fftSize 设置不是 2 的幂次方。
  • 没有连接 analyser 到 destination,导致只有可视化没有声音。

延伸追问

  • 如何实现波形图而不是频谱图?
  • 可视化性能差时如何优化?

相关题目

参考资源

口头回答版

音频可视化要用 AnalyserNode。先创建 AudioContext,把 audio 元素用 createMediaElementSource 接到分析节点上,再连到 destination。分析节点设置 fftSize 决定频谱精度,然后用 getByteFrequencyData 拿到 0 到 255 的频率数据,在 requestAnimationFrame 里用 Canvas 画成柱状图。记得用户交互后调用 audioCtx.resume(),不然没声音。


FB-51-CO-A-015:内容保护 DRM 在前端有哪些常见方案?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:51 Multimedia 标签:DRM、内容保护、Widevine、FairPlay、PlayReady 出现频率:中频 预计回答时长:5-8 分钟

题目描述: 请说明前端视频内容保护中 DRM 的基本概念,以及常见的浏览器端 DRM 方案。

参考答案

DRM(Digital Rights Management,数字版权管理)用于保护数字内容不被未授权复制、传播或播放。前端 DRM 的核心是加密视频流,并通过许可证服务器控制解密密钥的分发。

浏览器端 DRM 标准:

EME(Encrypted Media Extensions)

  • W3C 标准 API,允许 Web 应用与内容解密模块(CDM)交互。
  • navigator.requestMediaKeySystemAccess() 用于检测和选择 CDM。
  • 不直接处理解密,由浏览器内置的 CDM 完成。

常见 DRM 方案:

方案厂商支持平台关键系统
WidevineGoogleChrome、Firefox、AndroidWidevine CDM
FairPlayAppleSafari、iOS、tvOSFairPlay Streaming
PlayReadyMicrosoftEdge、Windows、XboxPlayReady CDM

前端基本流程:

javascript
const config = [{
  initDataTypes: ['cenc'],
  audioCapabilities: [{ contentType: 'audio/mp4;codecs="mp4a.40.2"' }],
  videoCapabilities: [{ contentType: 'video/mp4;codecs="avc1.42E01E"' }],
}];

const access = await navigator.requestMediaKeySystemAccess('com.widevine.alpha', config);
const keys = await access.createMediaKeys();

加密流程:

text
原始视频 -> 加密打包(CENC/Common Encryption)-> 分发加密流
播放器请求许可证 -> 许可证服务器验证用户权限 -> 返回解密密钥
CDM 解密 -> 解码渲染

最佳实践:

  • 使用 DASH / HLS 配合 CENC 通用加密,实现一套内容多 DRM 分发。
  • 对许可证请求做用户身份校验和防止共享。
  • 结合 HTTPS、CORS、Token 验证增强安全性。

评分维度

  • 能说明 DRM 通过加密和许可证保护内容(30%)
  • 能列举 Widevine/FairPlay/PlayReady 三种方案及平台(40%)
  • 能说明 EME API 的作用(30%)

常见错误

  • 认为前端 JS 直接持有解密密钥。
  • 混淆 DRM 和简单防盗链(Referer、Token)。
  • 认为一种 DRM 可以覆盖所有浏览器。

延伸追问

  • DRM 和 CENC 通用加密有什么关系?
  • 如何防止录屏和浏览器开发者工具抓取?

相关题目

参考资源

口头回答版

DRM 就是数字版权管理,保护视频不被随便下载或传播。浏览器里通过 EME 标准和 CDM 内容解密模块来工作。常见的方案有 Google 的 Widevine 支持 Chrome 和 Android,Apple 的 FairPlay 支持 Safari 和 iOS,Microsoft 的 PlayReady 支持 Edge 和 Windows。视频流是加密的,播放器通过许可证服务器拿到密钥才能解密播放,密钥不会直接暴露给前端 JS。


FB-51-CO-A-016:Web Codecs API 解决了什么问题?

题型:概念题 难度:🟡 进阶 岗位层级:高级 / 专家 面试知识域:51 Multimedia 标签:Web Codecs、编解码、VideoFrame、EncodedVideoChunk、低延迟 出现频率:中频 预计回答时长:5-8 分钟

题目描述: 请解释 Web Codecs API 的作用,以及它相比传统 video 标签和 MSE 的优势。

参考答案

Web Codecs API 是一组浏览器底层 API,允许 Web 应用直接访问系统的音视频编解码器,进行编码、解码、图像格式转换等操作。

核心接口:

接口作用
VideoDecoder解码压缩视频帧为 VideoFrame
VideoEncoderVideoFrame 编码为压缩数据
AudioDecoder / AudioEncoder音频编解码
EncodedVideoChunk / EncodedAudioChunk表示已编码的数据块
VideoFrame表示一帧解码后的图像,可绘制到 Canvas

相比 <video> 和 MSE 的优势:

  1. 低延迟

    • 不经过播放器缓冲和 demuxer 的完整管线,可直接控制每一帧。
    • 适合云游戏、视频编辑、实时处理。
  2. 细粒度控制

    • 可以逐帧解码、编码、处理。
    • 支持把 VideoFrame 直接传入 WebGL、Canvas、WebRTC。
  3. 灵活性

    • 不依赖容器格式,可直接处理裸码流。
    • 支持自定义协议和私有封装。

基本解码示例:

javascript
const decoder = new VideoDecoder({
  output: (frame) => {
    ctx.drawImage(frame, 0, 0);
    frame.close();
  },
  error: (e) => console.error(e),
});

decoder.configure({ codec: 'avc1.42E01E' });
decoder.decode(new EncodedVideoChunk({
  type: 'key',
  timestamp: 0,
  data: encodedData,
}));

最佳实践:

  • 使用 VideoFrame.close() 及时释放资源,避免内存泄漏。
  • 生产环境注意浏览器支持度,Chrome 86+ 开始支持。
  • 结合 WebTransport 或 WebRTC 可实现超低延迟传输。

评分维度

  • 能说明 Web Codecs 提供底层编解码能力(35%)
  • 能列举 VideoDecoder/VideoEncoder 等核心接口(35%)
  • 能对比 video/MSE 说明低延迟和细粒度控制优势(30%)

常见错误

  • 认为 Web Codecs 可以替代 video 标签的所有场景。
  • 忘记关闭 VideoFrame 导致内存泄漏。
  • 忽略浏览器兼容性和安全上下文要求。

延伸追问

  • Web Codecs 和 WebAssembly 软解相比有什么优劣?
  • Web Codecs 在云游戏场景如何配合 WebTransport 使用?

相关题目

参考资源

口头回答版

Web Codecs API 让前端可以直接调用系统的音视频编解码器,比如 VideoDecoder、VideoEncoder。相比 video 标签和 MSE,它能逐帧控制解码和编码,延迟更低,适合云游戏、视频编辑这些场景。解码出来的 VideoFrame 可以直接画到 Canvas 或 WebGL 上。用完记得 close 释放,不然容易内存泄漏。


深入题(8 道)

FB-51-FS-P-017:HLS 直播低延迟优化方案(LL-HLS)的原理是什么?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:51 Multimedia 标签:LL-HLS、低延迟直播、HLS、fMP4、CMAF 出现频率:高频 预计回答时长:8-15 分钟

题目描述: 请解释 HLS 直播延迟高的原因,以及 LL-HLS 如何通过协议优化降低延迟。

参考答案

传统 HLS 直播延迟高的原因

  1. 分片时长较大

    • 传统 HLS 推荐分片时长 6-10 秒。
    • 播放器通常需要缓存 3 个分片才开始播放,延迟可达 18-30 秒。
  2. 分片完全生成后才能下载

    • 播放器必须等待整个 TS 分片生成并上传到 CDN 后才能下载。
    • 这个等待时间直接累加到延迟中。
  3. m3u8 更新频率低

    • 播放器按固定间隔轮询 m3u8,新分片信息不能即时获取。

LL-HLS(Low-Latency HLS)优化原理

  1. 更短的分片 / 部分分片(Partial Segment)

    • 分片可以继续细分为多个 Partial Segment,每个约 200ms-1s。
    • 播放器无需等待完整分片生成,可以边生成边下载。
  2. 阻塞式 m3u8 加载(Blocking Playlist Reload)

    • 播放器请求 m3u8 时,服务器保持连接阻塞,直到有新分片信息才返回。
    • 减少轮询空转,更快拿到最新分片。
  3. 预加载提示(Preload Hints)

    • m3u8 中通过 #EXT-X-PRELOAD-HINT 预告即将生成的分片。
    • 播放器可以提前发起 HTTP 请求,分片一生成即可下载。
  4. 报道分片(Report)

    • 服务器主动推送分片生成事件,减少轮询延迟。
  5. 使用 fMP4 替代 TS

    • fMP4 更适合低延迟场景,与 CMAF 标准兼容,可同时服务 HLS 和 DASH。

LL-HLS m3u8 示例片段:

text
#EXTM3U
#EXT-X-VERSION:10
#EXT-X-TARGETDURATION:4
#EXT-X-PART-INF:PART-TARGET=0.5

#EXT-X-PART:DURATION=0.5,URI="segment0_part0.m4s"
#EXT-X-PART:DURATION=0.5,URI="segment0_part1.m4s"
#EXTINF:1.0,
segment0.m4s

#EXT-X-PRELOAD-HINT:TYPE=PART,URI="segment0_part2.m4s"

延迟对比:

方案典型延迟
传统 HLS10-30 秒
LL-HLS2-8 秒
WebRTC / WebTransport< 1 秒

最佳实践:

  • 对端侧播放器使用支持 LL-HLS 的库,如 hls.js 1.0+、Video.js 7+。
  • 服务端需要支持阻塞加载和快速生成 Partial Segment。
  • 极低延迟场景考虑 WebRTC 或 WebTransport 替代 HLS。

评分维度

  • 能分析传统 HLS 延迟高的原因(30%)
  • 能说明 Partial Segment、Blocking Reload、Preload Hint 三个核心机制(40%)
  • 能对比 LL-HLS 和其他低延迟方案的延迟量级(30%)

常见错误

  • 认为 LL-HLS 只是缩短分片时长。
  • 忽略服务端需要支持阻塞加载和新 m3u8 语义。
  • 认为 LL-HLS 可以替代 WebRTC 做超低延迟互动直播。

延伸追问

  • LL-HLS 和 LL-DASH 有什么异同?
  • 阻塞式 m3u8 加载对服务端连接数有什么影响?

相关题目

参考资源

口头回答版

传统 HLS 延迟高主要是因为分片长,播放器要等 3 个分片才开始播,而且必须等整个分片生成好才能下载。LL-HLS 把分片再切成 Partial Segment,大概几百毫秒一个,播放器不用等完整分片;同时用阻塞式 m3u8 加载,服务器有新分片再返回,减少轮询;还有 Preload Hint 让播放器提前请求。配合 fMP4 可以把延迟降到 2 到 8 秒。但要超低延迟,比如互动直播,还是 WebRTC 更合适。


FB-51-PE-P-018:WebRTC 中的延迟、抖动和拥塞控制如何实现?

题型:性能优化题 难度:🔴 深入 岗位层级:专家 面试知识域:51 Multimedia 标签:WebRTC、延迟、抖动、拥塞控制、JitterBuffer、GCC 出现频率:高频 预计回答时长:8-15 分钟

题目描述: 请深入说明 WebRTC 中影响实时音视频质量的关键因素(延迟、抖动、丢包),以及前端/端侧如何配合进行拥塞控制和优化。

参考答案

WebRTC 实时音视频质量主要受三个网络指标影响:

  1. 延迟(Latency)

    • 端到端音频/视频传输时间。
    • 目标通常 < 400ms,互动场景 < 200ms。
  2. 抖动(Jitter)

    • 数据包到达时间的不稳定。
    • 需要通过 Jitter Buffer 吸收抖动,平滑播放。
  3. 丢包(Packet Loss)

    • 网络拥塞或链路质量差导致数据包丢失。
    • WebRTC 使用 NACK、FEC、PLC 等机制恢复。

关键技术机制

Jitter Buffer(抖动缓冲区)

  • 接收端缓存一定数量的音频/视频包,等齐后再播放。
  • 缓冲越大,抗抖动能力越强,但延迟越大。
  • WebRTC 会动态调整 Jitter Buffer 大小。

拥塞控制(Congestion Control)

  • WebRTC 使用 GCC(Google Congestion Control)算法。
  • 结合延迟梯度(delay-based)和丢包(loss-based)两种信号估计带宽。
  • 根据带宽动态调整编码码率和分辨率。
text
发送端 -> 探测网络 -> 接收端反馈 TMMBR/REMB/Transport-CC -> 发送端调整码率

前向纠错 FEC 与丢包重传 NACK

  • FEC:发送冗余数据,少量丢包可自行恢复。
  • NACK:接收端发现丢包后请求重传。
  • PLC(Packet Loss Concealment):音频丢包时插值补偿。

前端可做的优化

方向措施
采集降低分辨率、帧率,减少上行码率
编码使用动态码率,配合拥塞控制反馈
渲染合理设置 Jitter Buffer,平衡延迟与流畅
网络部署边缘 TURN,优化路由
体验弱网时降级为音频优先、降低分辨率

最佳实践:

  • 使用 RTCRtpSender.setParameters 动态调整编码参数。
  • 通过 getStats() 获取实时统计信息,监控延迟、抖动、丢包。
javascript
const stats = await pc.getStats();
stats.forEach(report => {
  if (report.type === 'inbound-rtp') {
    console.log('packetLoss:', report.packetsLost / report.packetsReceived);
    console.log('jitter:', report.jitter);
  }
});

评分维度

  • 能分析延迟、抖动、丢包的影响(30%)
  • 能说明 Jitter Buffer 和 GCC 拥塞控制原理(35%)
  • 能列举 FEC/NACK/PLC 等恢复机制(20%)
  • 能通过 getStats 做监控(15%)

常见错误

  • 认为 WebRTC 的延迟只由网络决定,忽略编解码和缓冲区延迟。
  • 把 Jitter Buffer 调得过大,导致延迟增加。
  • 弱网时不做任何降级,导致卡顿和花屏。

延伸追问

  • SVC(可伸缩视频编码)在 WebRTC 弱网中有什么作用?
  • Simulcast 和单流自适应有什么区别?

相关题目

参考资源

口头回答版

WebRTC 里影响质量的主要有三个:延迟、抖动、丢包。延迟是端到端传输时间;抖动是包到达时间不稳定,需要用 Jitter Buffer 吸收;丢包要靠 FEC 冗余、NACK 重传、PLC 插值来恢复。拥塞控制主要用 GCC 算法,结合延迟变化和丢包情况估计带宽,然后动态调整码率。前端可以通过 getStats 监控这些指标,弱网时降分辨率、降帧率,甚至优先保音频。


FB-51-CO-P-019:Widevine、FairPlay、PlayReady 三种 DRM 方案有什么区别?

题型:概念题 难度:🔴 深入 岗位层级:专家 面试知识域:51 Multimedia 标签:DRM、Widevine、FairPlay、PlayReady、EME、CDM 出现频率:中频 预计回答时长:5-8 分钟

题目描述: 请对比 Widevine、FairPlay、PlayReady 三种主流 DRM 方案,包括支持平台、安全级别和前端接入方式。

参考答案

三种 DRM 分别对应 Google、Apple、Microsoft 的生态系统,浏览器端都通过 EME 与 CDM 交互。

维度WidevineFairPlayPlayReady
厂商GoogleAppleMicrosoft
主要平台Chrome、Firefox、Android、Android TVSafari、iOS、macOS、tvOSEdge、Windows、Xbox、部分 Smart TV
EME Key Systemcom.widevine.alphacom.apple.fps.1_0com.microsoft.playready
CDMWidevine CDMFairPlay StreamingPlayReady CDM
安全级别L1(硬件解密)、L2(软件解密)、L3硬件安全 + SPC 证书SL2000、SL3000 等
流媒体格式DASH / HLS + CENCHLS + SAMPLE-AESDASH / HLS + CENC
许可证服务器自建或第三方Apple FPS Server自建或 Azure

安全级别说明

  • Widevine L1:解密和渲染都在 TEE(可信执行环境)中,安全性最高。
  • Widevine L2:解密在 TEE,渲染在普通环境。
  • Widevine L3:纯软件解密,安全性最低,但兼容性最好。

前端接入差异

Widevine

  • 使用标准 EME 流程。
  • 许可证请求直接发往许可证服务器。
javascript
const access = await navigator.requestMediaKeySystemAccess('com.widevine.alpha', config);
const keys = await access.createMediaKeys();

FairPlay

  • 需要额外处理 SPC(Server Playback Context)和 CKC(Content Key Context)。
  • 需要向 Apple 申请 FPS 证书。
  • 通常配合 HLS + SAMPLE-AES。

PlayReady

  • Edge 原生支持 PlayReady。
  • 许可证请求格式为 PlayReady Object。
  • 常与 Windows / Xbox 生态结合。

最佳实践:

  • 商业视频平台通常同时集成三种 DRM,根据浏览器选择对应方案。
  • 使用 Shaka Player、Bitmovin、THEOplayer 等播放器简化多 DRM 接入。
  • 对 L3 设备进行风险提示或限制高清内容播放。

评分维度

  • 能对应三个方案到各自厂商和主要平台(30%)
  • 能说明 Key System 和安全级别差异(30%)
  • 能说明 FairPlay 需要额外证书和 SPC/CKC 流程(20%)
  • 能给出多 DRM 同时接入的建议(20%)

常见错误

  • 认为只要集成一种 DRM 就能覆盖所有浏览器。
  • 混淆 CENC 通用加密和各家 DRM 的关系。
  • 忽略不同安全级别对高清内容的限制。

延伸追问

  • 如何判断当前浏览器支持哪种 DRM?
  • DRM 和 ClearKey 有什么区别?

相关题目

参考资源

口头回答版

三种 DRM 分别对应三个大厂。Widevine 是 Google 的,支持 Chrome、Firefox、Android;FairPlay 是 Apple 的,支持 Safari、iOS、tvOS;PlayReady 是微软的,支持 Edge、Windows、Xbox。浏览器里都通过 EME 和各自的 CDM 交互。Widevine 分 L1、L2、L3 安全级别,L1 是硬件解密最安全。FairPlay 接入最麻烦,要向 Apple 申请证书,处理 SPC 和 CKC。商业平台一般要三种都接,根据浏览器自动选择。


FB-51-CD-P-020:如何用 requestVideoFrameCallback 实现精确的视频帧处理?

题型:手写代码题 难度:🔴 深入 岗位层级:专家 面试知识域:51 Multimedia 标签:requestVideoFrameCallback、RVFC、帧同步、Canvas、性能优化 出现频率:中频 预计回答时长:5-10 分钟

题目描述: 请说明 requestVideoFrameCallback(RVFC)的作用,并写出用它实现视频帧精准同步绘制的代码。

参考答案

requestVideoFrameCallback<video> 元素的专用回调,它在视频帧实际提交给合成器时触发,比 requestAnimationFrame 更准确。

requestAnimationFrame 的区别:

维度requestAnimationFramerequestVideoFrameCallback
触发时机显示器刷新视频帧提交
同步对象显示器视频帧率
回调参数DOMHighResTimeStampmetadata(含 mediaTime、presentedFrames 等)
丢帧感知可获取 presentedFrames、expectedDisplayTime
适用场景一般动画视频帧处理、特效、字幕同步

基本用法:

javascript
const video = document.querySelector('video');
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

function drawFrame(now, metadata) {
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

  // 精准字幕同步:metadata.mediaTime 表示当前帧的媒体时间
  renderSubtitle(metadata.mediaTime);

  // 继续请求下一帧
  video.requestVideoFrameCallback(drawFrame);
}

video.requestVideoFrameCallback(drawFrame);

metadata 字段:

javascript
{
  mediaTime: 12.345,        // 当前帧媒体时间
  presentedFrames: 370,     // 已呈现帧数
  expectedDisplayTime: ..., // 预计显示时间
  width: 1920,              // 帧宽
  height: 1080,             // 帧高
}

结合 Canvas 做滤镜处理:

javascript
function processFrame(now, metadata) {
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

  // 获取像素数据做处理
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  applyGrayscale(imageData.data);
  ctx.putImageData(imageData, 0, 0);

  video.requestVideoFrameCallback(processFrame);
}

最佳实践:

  • 视频帧处理优先使用 RVFC,避免 rAF 和视频帧率不匹配导致的重复绘制或丢帧。
  • 对像素级处理使用 WebGL / WebGPU 比 2D Canvas getImageData 性能更好。
  • 注意浏览器支持度:Chrome 83+、Edge 83+、部分 Firefox。

评分维度

  • 能说明 RVFC 相比 rAF 的帧同步优势(30%)
  • 能写出 requestVideoFrameCallback 循环绘制(40%)
  • 能利用 metadata.mediaTime 做同步处理(30%)

常见错误

  • 在 rAF 中做视频帧处理,导致和实际视频帧不同步。
  • 忽略 RVFC 的浏览器兼容性。
  • 在回调中做大量同步计算,阻塞下一帧。

延伸追问

  • RVFC 和 HTMLVideoElement.requestVideoFrameCallback 与 Web Codecs 的 VideoFrame 如何配合?
  • 如何检测和处理 RVFC 丢帧?

相关题目

参考资源

口头回答版

requestVideoFrameCallback 是 video 元素专用的回调,比 requestAnimationFrame 更准,因为它是在视频帧真正要显示的时候触发,回调里还能拿到 metadata,比如 mediaTime 当前帧时间、presentedFrames 已显示帧数。用它来做 Canvas 绘制、字幕同步、滤镜处理都很合适。用法就是 video.requestVideoFrameCallback(drawFrame),在回调里继续请求下一帧。


FB-51-PE-P-021:图片和视频的前端压缩方案对比?

题型:性能优化题 难度:🔴 深入 岗位层级:专家 面试知识域:51 Multimedia 标签:图片压缩、视频压缩、Canvas、WebP、ffmpeg.wasm、上传优化 出现频率:中频 预计回答时长:5-8 分钟

题目描述: 请对比前端图片压缩和视频压缩的常见方案,说明各自的实现方式、优缺点和适用场景。

参考答案

图片压缩方案

方案实现方式优点缺点
Canvas 压缩drawImage 后 toBlob/toDataURL浏览器原生,兼容好格式受限,质量不可控
WebP 编码canvas.toBlob('image/webp')压缩率高部分浏览器不支持
第三方库compressorjs、browser-image-compression功能丰富增加包体积
Web Worker在 Worker 中处理不阻塞主线程通信有开销

Canvas 压缩示例:

javascript
function compressImage(file, maxWidth = 1280, quality = 0.8) {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => {
      const canvas = document.createElement('canvas');
      const scale = Math.min(1, maxWidth / img.width);
      canvas.width = img.width * scale;
      canvas.height = img.height * scale;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      canvas.toBlob(resolve, 'image/jpeg', quality);
    };
    img.src = URL.createObjectURL(file);
  });
}

视频压缩方案

方案实现方式优点缺点
Canvas + MediaRecorder抽帧后用 Canvas 绘制再录制纯前端画质损失大、速度慢
ffmpeg.wasmWebAssembly 版 FFmpeg功能强大、格式多包体积大、性能有限
服务端压缩上传到服务端转码质量高、性能好依赖后端、上传耗时
WebCodecs浏览器原生编解码速度快兼容性和功能有限

ffmpeg.wasm 压缩示例:

javascript
const { FFmpeg } = FFmpegWASM;
const ffmpeg = new FFmpeg();
await ffmpeg.load();

await ffmpeg.writeFile('input.mp4', await fetchFile(file));
await ffmpeg.exec(['-i', 'input.mp4', '-vcodec', 'libx264', '-crf', '28', 'output.mp4']);
const data = await ffmpeg.readFile('output.mp4');

对比总结:

  • 图片压缩:前端方案成熟,Canvas 压缩足够应对大多数上传场景。
  • 视频压缩:前端压缩能力有限,简单场景可用 Canvas + MediaRecorder,高质量压缩建议后端处理或 ffmpeg.wasm。
  • 通用原则:压缩前尽量读取文件元数据,避免无效处理;大文件使用分片上传和断点续传。

最佳实践:

  • 图片上传前先压缩和转换格式(如 JPEG、WebP)。
  • 视频压缩考虑服务端预转码 + 多码率自适应。
  • 压缩任务尽量放在 Web Worker 或 WASM 中,避免阻塞 UI。

评分维度

  • 能对比图片压缩的 Canvas、WebP、第三方库方案(35%)
  • 能对比视频压缩的 Canvas+MediaRecorder、ffmpeg.wasm、服务端方案(35%)
  • 能根据场景给出选型建议(30%)

常见错误

  • 用 Canvas 压缩视频期望达到专业转码质量。
  • 不考虑 Web Worker,导致压缩时页面卡顿。
  • 对所有文件使用同一压缩参数,忽略文件大小和分辨率差异。

延伸追问

  • 如何在压缩过程中显示进度?
  • 如何在前端判断文件是否还需要压缩?

相关题目

参考资源

口头回答版

图片压缩前端比较成熟,常用 Canvas 画小之后 toBlob 输出 JPEG 或 WebP,也可以用 compressorjs 这类库。视频压缩就复杂一些,简单压缩可以抽帧到 Canvas 再 MediaRecorder 录制,但质量一般;专业一点用 ffmpeg.wasm,在浏览器里跑 FFmpeg,功能强但包大、慢;高质量还是建议传服务端转码。压缩任务最好放 Worker 里,别卡主线程。


FB-51-SC-P-022:如何实现一个支持多音轨切换的视频播放器?

题型:场景设计题 难度:🔴 深入 岗位层级:专家 面试知识域:51 Multimedia 标签:多音轨、音频切换、MSE、HLS、DASH、MediaSource 出现频率:中频 预计回答时长:8-15 分钟

题目描述: 请设计一个支持多音轨切换的网页视频播放器,说明前端如何实现音轨列表获取、切换和无缝衔接。

参考答案

多音轨切换常见于多语言影视、导演评论、不同解说版本等场景。

整体方案

  1. 内容准备阶段

    • 视频使用 HLS 或 DASH 封装,每个音轨作为独立 media playlist(HLS)或 Adaptation Set(DASH)。
    • 或者使用 MSE 手动管理多个音频 SourceBuffer。
  2. 音轨列表获取

    • 解析 m3u8 中的 #EXT-X-MEDIA 标签(HLS)。
    • 解析 mpd 中的 <AdaptationSet>(DASH)。

HLS 多音轨示例:

text
#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="中文",DEFAULT=YES,URI="audio_cn.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="English",URI="audio_en.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=2800000,AUDIO="audio"
video.m3u8
  1. 切换实现
    • 使用播放器库(hls.js、shaka-player、dash.js)时,调用其音频 track API。
    • 自定义 MSE 实现时,切换音频 SourceBuffer 的内容。

hls.js 切换示例:

javascript
hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
  const audioTracks = hls.audioTracks;
  console.log(audioTracks); // [{ id, name, lang, default }, ...]
});

// 切换到第二个音轨
hls.audioTrack = 1;
  1. 无缝衔接

    • 以当前视频时间戳为基准,从对应位置加载新音轨数据。
    • 使用 MSE 的 appendWindowStart / appendWindowEndtimestampOffset 对齐时间线。
    • 保持旧音频 buffer 到当前播放位置,新音轨从下一分片开始填充。
  2. UI 交互

    • 提供音轨选择菜单,显示语言名称和当前选中状态。
    • 切换时给出短暂 loading 提示,避免用户误以为卡顿。

最佳实践:

  • 优先使用成熟播放器库处理多音轨,避免自己解析 m3u8 / mpd。
  • 切换音轨时保持视频连续播放,只替换音频轨道。
  • 考虑无障碍,给音轨菜单加 ARIA 属性和键盘操作。

评分维度

  • 能说明 HLS/DASH 中多音轨的封装方式(30%)
  • 能说明如何获取和切换音轨(30%)
  • 能说明无缝衔接的时间对齐策略(25%)
  • 能考虑 UI 和无障碍(15%)

常见错误

  • 重新加载整个视频来切换音轨,导致播放中断。
  • 忽略音视频时间戳对齐,导致音画不同步。
  • 音轨切换后没有更新 UI 状态。

延伸追问

  • 多音轨和字幕轨道切换在实现上有什么异同?
  • 如果播放器使用 MSE,切换音轨时 SourceBuffer 怎么管理?

相关题目

参考资源

口头回答版

多音轨切换首先要内容层支持,比如 HLS 用 #EXT-X-MEDIA 声明多个音频,DASH 用多个 Adaptation Set。前端解析 manifest 拿到音轨列表,用户切换时只换音频轨道,不换视频。成熟播放器像 hls.js 有 audioTracks 和 audioTrack API 可以直接切。无缝衔接的关键是时间戳对齐,新音轨要从当前播放位置开始加载,可以用 MSE 的 timestampOffset 对齐。最好保持视频连续,只替换音频 buffer。


FB-51-FS-P-023:Web Audio 中的 AudioWorklet 和 ScriptProcessorNode 有什么区别?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:51 Multimedia 标签:Web Audio、AudioWorklet、ScriptProcessorNode、实时音频、Worker 出现频率:中频 预计回答时长:5-8 分钟

题目描述: 请对比 Web Audio API 中 AudioWorklet 和 ScriptProcessorNode 两种自定义音频处理节点,说明它们的优缺点和迁移建议。

参考答案

两者都用于自定义音频处理,但实现机制有本质区别。

维度ScriptProcessorNodeAudioWorklet
执行线程主线程独立的音频渲染线程(AudioWorkletGlobalScope)
延迟高(128-2048 样本缓冲)低(固定 128 样本)
性能主线程阻塞会导致爆音、卡顿不阻塞主线程,更稳定
现代性已废弃,不推荐使用现代标准推荐方案
状态共享可与主线程直接共享数据通过 MessagePort 通信
浏览器支持广泛但已废弃Chrome 66+、Edge、Firefox 76+

ScriptProcessorNode 的问题

  • 运行在主线程,主线程繁忙时无法及时生成音频,导致爆音(glitch)。
  • 缓冲区大小不固定,延迟不可控。
  • Web Audio 规范已将其标记为 deprecated。

AudioWorklet 的优势

  • 在独立的音频渲染线程执行,和主线程解耦。
  • 固定 128 样本的处理块,保证低延迟。
  • 可以自定义 AudioParam、多输入输出、共享缓冲区。

AudioWorklet 基本用法:

javascript
// 注册 processor
await audioCtx.audioWorklet.addModule('noise-processor.js');

const noiseNode = new AudioWorkletNode(audioCtx, 'noise-processor');
noiseNode.connect(audioCtx.destination);

noise-processor.js

javascript
class NoiseProcessor extends AudioWorkletProcessor {
  process(inputs, outputs, parameters) {
    const output = outputs[0];
    for (let channel = 0; channel < output.length; channel++) {
      const channelData = output[channel];
      for (let i = 0; i < channelData.length; i++) {
        channelData[i] = Math.random() * 2 - 1;
      }
    }
    return true; // 保持节点活跃
  }
}

registerProcessor('noise-processor', NoiseProcessor);

迁移建议:

  • 新项目直接使用 AudioWorklet。
  • 旧项目中的 ScriptProcessorNode 应逐步迁移。
  • 需要与主线程通信时,使用 AudioWorkletNode.port.postMessage。

评分维度

  • 能从线程模型对比两者(35%)
  • 能说明延迟和性能差异(30%)
  • 能写出 AudioWorklet 基本代码(20%)
  • 能给出迁移建议(15%)

常见错误

  • 在新项目中继续使用 ScriptProcessorNode。
  • 认为 AudioWorklet 也运行在主线程。
  • 在 process 方法中做耗时同步计算,导致音频线程阻塞。

延伸追问

  • AudioWorklet 如何与 WebAssembly 配合做高性能音频处理?
  • AudioWorklet 中如何处理 AudioParam 的参数渐变?

相关题目

参考资源

口头回答版

ScriptProcessorNode 是在主线程跑自定义音频处理的,主线程一卡就会爆音,已经被废弃了。AudioWorklet 是在独立的音频渲染线程里跑,延迟低、不卡主线程,是现在推荐的方式。用法是先用 audioCtx.audioWorklet.addModule 注册一个 processor 文件,然后创建 AudioWorkletNode。process 方法里处理 inputs 和 outputs,返回 true 表示保持活跃。新项目都应该用 AudioWorklet。


FB-51-CP-P-024:MSE(Media Source Extensions)在流媒体播放器中的作用是什么?

题型:综合开放题 难度:🔴 深入 岗位层级:专家 面试知识域:51 Multimedia 标签:MSE、MediaSource、SourceBuffer、流媒体、HLS、DASH 出现频率:高频 预计回答时长:8-15 分钟

题目描述: 请深入说明 MSE 的作用和工作原理,并解释为什么 hls.js、dash.js 等播放器库需要依赖 MSE。

参考答案

MSE 的作用

MSE(Media Source Extensions)是 W3C 标准,允许 JavaScript 动态构建媒体流并喂给 <video> 标签播放。它把传统 <video src="..."> 的被动播放模式,转变为由 JS 主动控制数据推送的模式。

核心对象:

对象作用
MediaSource媒体数据源,可以附加到 video 标签
SourceBuffer实际接收和解析媒体片段的缓冲区
URL.createObjectURL(mediaSource)生成 MediaSource 的 blob URL

基本流程:

javascript
const video = document.querySelector('video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);

mediaSource.addEventListener('sourceopen', () => {
  const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"');

  fetch('segment1.m4s')
    .then(res => res.arrayBuffer())
    .then(data => {
      sourceBuffer.appendBuffer(data);
    });
});

为什么 hls.js / dash.js 依赖 MSE

  1. 浏览器原生不支持 HLS/DASH

    • 除了 Safari 原生支持 HLS,Chrome、Firefox、Edge 需要 JS 层解析 m3u8 / mpd。
    • MSE 提供了把解析后的分片喂给 video 的入口。
  2. 自适应码率(ABR)

    • MSE 允许 JS 根据网络状况动态切换不同码率的分片。
    • 通过切换 SourceBuffer 中的数据实现无缝清晰度切换。
  3. DRM 解密

    • MSE 配合 EME,可以在 JS 层处理许可证请求后,把解密数据送入 SourceBuffer。
  4. 动态内容拼接

    • 可以在播放过程中动态插入广告、精彩片段回看等内容。

SourceBuffer 管理要点:

操作说明
addSourceBuffer(mimeType)添加视频或音频 SourceBuffer
appendBuffer(data)追加媒体数据
remove(start, end)移除已播放数据,控制内存
timestampOffset调整时间戳,实现拼接
abort()取消当前 append 操作

最佳实践:

  • SourceBuffer 的 update 状态是异步的,append 和 remove 必须串行执行。
  • 定期 remove 已播放内容,避免内存无限增长。
  • 使用 sourceBuffers[0].buffered 监控当前缓冲区。

评分维度

  • 能说明 MSE 让 JS 动态喂数据给 video(30%)
  • 能写出 MediaSource 和 SourceBuffer 基本用法(30%)
  • 能解释播放器库依赖 MSE 的原因(25%)
  • 能说明 SourceBuffer 状态管理和内存控制(15%)

常见错误

  • 在 sourceopen 事件外提前操作 SourceBuffer。
  • 并发调用 appendBuffer 导致错误。
  • 忘记 remove 旧数据,导致内存泄漏。

延伸追问

  • MSE 和 Web Codecs 有什么互补关系?
  • 多音轨切换时 SourceBuffer 如何管理?

相关题目

参考资源

口头回答版

MSE 是浏览器标准,让 JavaScript 可以动态把媒体数据喂给 video 标签播放。核心是用 MediaSource 生成一个 blob URL 给 video.src,然后在 sourceopen 后用 addSourceBuffer 创建 SourceBuffer,用 appendBuffer 塞分片数据。hls.js、dash.js 这些库依赖 MSE 是因为除了 Safari,其他浏览器不原生支持 HLS/DASH,需要 JS 解析 m3u8/mpd 后再通过 MSE 播放。MSE 还能做 ABR 自适应码率、DRM 解密、动态插广告等。


架构题(32 道)

FB-51-SD-R-025:设计一个支持 HLS/DASH/WebRTC 的多协议播放器架构

题型:系统设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:51 Multimedia 标签:播放器、HLS、DASH、WebRTC、MSE、架构设计 出现频率:高频 预计回答时长:15-30 分钟

题目描述: 请设计一个网页端视频播放器 SDK,要求同时支持 HLS、DASH、WebRTC 三种协议,并说明核心模块划分和协议切换策略。

参考答案

整体架构分层

text
┌─────────────────────────────────────────┐
│           Player UI / Controls          │
├─────────────────────────────────────────┤
│           Player Core API               │
│  (load, play, pause, seek, switchStream)│
├─────────────────────────────────────────┤
│  Protocol Adapters  │  DRM / EME Module │
│  HLS  DASH  WebRTC  │  Widevine/FairPlay│
├─────────────────────────────────────────┤
│      Buffer Manager  │  ABR Controller   │
├─────────────────────────────────────────┤
│      MSE Manager     │  MediaSource      │
├─────────────────────────────────────────┤
│      <video> Element / WebRTC Peer      │
└─────────────────────────────────────────┘

核心模块

  1. Player Core API

    • 统一对外接口:load(url)play()pause()seek(time)destroy()
    • 内部根据 URL 或配置选择对应 Protocol Adapter。
  2. Protocol Adapter

    • HLS Adapter:解析 m3u8,管理 TS/fMP4 分片下载。
    • DASH Adapter:解析 mpd,管理 fMP4 分片下载。
    • WebRTC Adapter:管理 RTCPeerConnection、信令、音视频轨。
    • 每个 Adapter 实现统一的 IMediaAdapter 接口,返回标准化的媒体段和时间线。
  3. MSE Manager

    • 负责创建 MediaSource、SourceBuffer。
    • 处理 append、remove、timestampOffset 等操作。
    • WebRTC 不经过 MSE,直接渲染 MediaStream。
  4. ABR Controller(自适应码率)

    • 收集带宽、缓冲区、设备性能数据。
    • 决策切换清晰度,HLS/DASH 生效。
  5. Buffer Manager

    • 维护当前缓冲区范围。
    • 预加载策略、追帧策略、seek 后重新加载。
  6. DRM / EME Module

    • 根据平台和内容选择 Widevine / FairPlay / PlayReady。
    • 处理许可证请求和密钥更新。
  7. UI / Controls

    • 自定义播放控件、字幕、音轨选择、画质菜单。
    • 与 Core 通过事件通信,保持解耦。

协议切换策略

协议适用场景延迟
HLS点播、直播、Safari/iOS10-30 秒
DASH点播、直播、跨平台10-30 秒
WebRTC互动直播、连麦、超低延迟< 1 秒
  • 根据业务 URL scheme 自动选择:webrtc://.m3u8.mpd
  • 允许业务通过配置强制指定协议。
  • WebRTC 失败时降级为 LL-HLS/DASH。

最佳实践:

  • Adapter 层完全抽象,新增协议只需实现接口。
  • 核心状态机管理播放生命周期,避免多协议状态混乱。
  • 统一埋点,记录不同协议的播放成功率和质量指标。

评分维度

  • 能合理划分核心模块(30%)
  • 能说明 Adapter 抽象和统一 API 设计(25%)
  • 能说明 MSE 和 WebRTC 的渲染差异(20%)
  • 能给出协议选型和降级策略(15%)
  • 能考虑埋点和可观测性(10%)

常见错误

  • 把三种协议的实现耦合在一个大文件里。
  • 忽略 WebRTC 和 HLS/DASH 在延迟和缓冲策略上的本质差异。
  • 不做协议降级,导致 WebRTC 失败时直接播放失败。

延伸追问

  • 如果业务要求同一播放器内从 WebRTC 平滑切换到 HLS,应如何设计?
  • 如何在 SDK 中支持插件化扩展?

相关题目

参考资源

口头回答版

我会把播放器 SDK 分成几层:最上面是 UI 控件,中间是统一的核心 API 层,下面是协议适配器,每个协议一个 Adapter,比如 HLS Adapter 解析 m3u8,DASH Adapter 解析 mpd,WebRTC Adapter 管 RTCPeerConnection。HLS 和 DASH 通过 MSE 喂给 video 标签,WebRTC 直接渲染 MediaStream。还有 ABR 控制器、Buffer Manager、DRM 模块。协议切换可以根据 URL 自动判断,比如 .m3u8 走 HLS,.mpd 走 DASH,webrtc:// 走 WebRTC。WebRTC 失败可以降级到 LL-HLS。核心是用统一接口抽象,新增协议只加 Adapter 就行。


FB-51-SD-R-026:设计一个低延迟直播系统的前端方案

题型:系统设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:51 Multimedia 标签:低延迟直播、WebRTC、LL-HLS、WebTransport、实时音视频 出现频率:高频 预计回答时长:15-30 分钟

题目描述: 请设计一个低延迟直播系统的前端方案,要求延迟在 1-3 秒内,支持万人以上同时观看,并说明技术选型和关键优化点。

参考答案

延迟与方案选型

方案典型延迟适用规模复杂度
传统 HLS/DASH10-30s大规模
LL-HLS / LL-DASH2-8s大规模
WebRTC<1s小房间
WebTransport + WebCodecs<1s中等规模
SRT/RTMP + 边缘转 WebRTC1-3s大规模

对于万人以上、1-3 秒延迟的场景,推荐 分层混合方案

1. 主播端

  • 使用 OBS / 专业推流工具,RTMP/SRT 推流到 CDN 或直播服务器。
  • 或使用浏览器 WebRTC 直接推流。

2. 服务端

  • 边缘节点接收 RTMP/SRT,快速转封装为 WebRTC、LL-HLS、DASH。
  • 对首屏要求极高的用户走 WebRTC。
  • 对并发要求极高的用户走 LL-HLS / LL-DASH。

3. 前端播放器

  • 优先尝试 WebRTC,失败或超量时降级到 LL-HLS。
  • 播放器内部维护协议降级状态机。

前端关键模块

text
┌────────────────────────────────────┐
│         LowLatencyPlayer           │
├────────────────────────────────────┤
│  Connection Manager                │
│  WebRTC -> LL-HLS -> HLS fallback  │
├────────────────────────────────────┤
│  Latency Controller                │
│  目标延迟、追帧、倍速播放            │
├────────────────────────────────────┤
│  Jitter / Buffer Manager           │
│  动态缓冲、卡顿预测                  │
├────────────────────────────────────┤
│  Metrics & Analytics               │
│  端到端延迟、首帧、卡顿率            │
└────────────────────────────────────┘

关键优化点

  1. 目标延迟控制

    • 根据当前缓冲和网速,动态控制目标延迟。
    • 延迟过大时通过快进、跳帧追赶;过小时增加缓冲。
  2. 首帧优化

    • 服务端缓存最新 GOP,播放器接入时直接下发关键帧。
    • WebRTC 通过 ICE 快速建连,LL-HLS 使用 Preload Hint 快速起播。
  3. 弱网降级

    • WebRTC 自动降码率、分辨率。
    • LL-HLS 自动降清晰度。
    • 极端弱网只保留音频。
  4. 大规模并发

    • WebRTC 用 SFU/MCU 架构,观众多时切换到 LL-HLS。
    • CDN 分发 LL-HLS 分片,支持海量并发。
  5. 延迟度量

    • 播放器发送 UTC 时间戳,服务端回传接收时间,计算端到端延迟。
    • 通过 video.currentTime 与 UTC 时间差估算播放延迟。

最佳实践:

  • 采用多协议自动降级,避免单点失败。
  • 对实时互动场景用 WebRTC,对大规模观看用 LL-HLS。
  • 埋点监控端到端延迟、卡顿率、协议分布。

评分维度

  • 能根据延迟和规模选择合理技术栈(25%)
  • 能设计协议降级和连接管理(25%)
  • 能说明延迟控制和首帧优化(20%)
  • 能说明弱网和大规模并发策略(20%)
  • 能说明延迟度量方案(10%)

常见错误

  • 想用单一协议同时满足超低延迟和超大规模。
  • 忽略 WebRTC 在万人场景下的服务器和带宽成本。
  • 只做播放器优化,不和服务端协同设计。

延伸追问

  • 如果要求延迟 < 500ms,方案会有什么变化?
  • 万人直播间如何保证音画同步?

相关题目

参考资源

口头回答版

万人以上、1 到 3 秒延迟,我建议分层混合方案。主播推流用 RTMP 或 SRT 到服务端,服务端边缘转成 WebRTC、LL-HLS、DASH。前端播放器优先 WebRTC,失败或人太多就降级到 LL-HLS。关键要做一个连接管理器做协议降级,一个延迟控制器动态追帧,一个 Jitter Buffer 管理器动态调缓冲。还要和服务端一起做首帧优化,比如缓存最新 GOP。大规模并发主要靠 LL-HLS 走 CDN,WebRTC 只给首屏要求高的用户。延迟度量可以通过 UTC 时间戳对时。


FB-51-SD-R-027:设计一个浏览器端音视频剪辑工具的技术架构

题型:系统设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:51 Multimedia 标签:音视频剪辑、WebCodecs、ffmpeg.wasm、时间线、Web Worker 出现频率:中频 预计回答时长:15-30 分钟

题目描述: 请设计一个可在浏览器中运行的音视频剪辑工具,支持素材导入、时间线编辑、实时预览、导出渲染,说明核心技术选型和性能优化策略。

参考答案

功能模块划分

text
┌─────────────────────────────────────────┐
│         Timeline UI / 交互层             │
│  轨道、剪辑、转场、特效、字幕              │
├─────────────────────────────────────────┤
│         Preview Engine 预览引擎          │
│  Canvas / WebGL 实时合成                   │
├─────────────────────────────────────────┤
│         Composition Model 合成模型        │
│  时间线、片段、属性、关键帧                 │
├─────────────────────────────────────────┤
│         Decoder 解码层                    │
│  WebCodecs / VideoDecoder / AudioDecoder │
├─────────────────────────────────────────┤
│         Encoder 编码层                    │
│  WebCodecs / ffmpeg.wasm                 │
├─────────────────────────────────────────┤
│         Storage 存储层                    │
│  IndexedDB / OPFS / 服务端                │
└─────────────────────────────────────────┘

核心技术选型

功能推荐方案备选方案
素材解码WebCodecs VideoDecoder/AudioDecoderffmpeg.wasm
预览渲染Canvas 2D / WebGL纯 CSS 不可行
音频处理Web Audio API + AudioWorkletScriptProcessorNode
视频编码导出ffmpeg.wasmWebCodecs VideoEncoder
存储Origin Private File System (OPFS)IndexedDB
大文件上传分片上传 + 断点续传整文件上传

实时预览方案

  1. 解码

    • 使用 WebCodecs 按时间线需要的片段逐帧解码。
    • 预解码关键帧附近的数据,放入帧缓存池。
  2. 合成

    • 在时间轴当前位置,根据所有可见轨道计算合成帧。
    • 使用 WebGL 做多图层混合、缩放、旋转、滤镜。
    • 音频用 Web Audio Graph 实时混音。
  3. 同步

    • 以时间轴时钟驱动渲染,不依赖原视频播放。
    • 拖动时间线时直接seek到对应帧。

导出渲染方案

text
Composition Model
      |
      v
逐帧合成 (Canvas/WebGL)
      |
      v
VideoEncoder 编码 / ffmpeg.wasm 封装
      |
      v
MP4/WebM 文件输出

性能优化策略:

  1. Web Worker

    • 解码、编码、文件读写放 Worker,不阻塞 UI。
  2. 帧缓存池

    • 缓存关键帧和附近帧,避免频繁 seek 解码。
    • 使用 LRU 策略管理内存。
  3. 代理剪辑(Proxy Editing)

    • 编辑时使用低分辨率代理文件,导出时用原始高分辨率素材。
  4. 增量渲染

    • 只渲染时间线变化的部分,静态片段可复用。
  5. OPFS

    • 大文件素材直接写入 Origin Private File System,避免内存占用。

最佳实践:

  • 优先使用 WebCodecs 做解码,性能优于 ffmpeg.wasm。
  • 导出任务复杂或浏览器不支持时, fallback 到服务端渲染。
  • 自动保存时间线状态,防止崩溃丢失。

评分维度

  • 能合理划分功能模块(25%)
  • 能给出解码、渲染、编码、存储的技术选型(30%)
  • 能说明实时预览和导出渲染流程(25%)
  • 能提出至少 3 项性能优化策略(20%)

常见错误

  • 试图用 video 标签播放多个片段来做剪辑预览,无法精确同步。
  • 所有处理放在主线程,导致 UI 卡顿。
  • 高清素材全部加载到内存,导致浏览器崩溃。

延伸追问

  • 如何实现多轨道音频的实时混音?
  • 如果浏览器不支持 WebCodecs,如何优雅降级?

相关题目

参考资源

口头回答版

浏览器端剪辑工具我会分成:时间线 UI 层、预览引擎、合成模型、解码层、编码层、存储层。解码用 WebCodecs 的 VideoDecoder/AudioDecoder,预览用 Canvas 或 WebGL 做实时合成,音频用 Web Audio 混音。导出时可以用 WebCodecs VideoEncoder 或 ffmpeg.wasm 编码封装。性能方面,解码和编码放 Web Worker,用帧缓存池避免反复 seek,大文件用 OPFS 存本地,编辑时先用低分辨率代理文件。这样能保证实时预览不卡,导出质量也高。


FB-51-SC-R-028:如何实现跨浏览器的统一媒体录制方案?

题型:场景设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:51 Multimedia 标签:MediaRecorder、跨浏览器、录制、兼容性、降级方案 出现频率:中频 预计回答时长:8-15 分钟

题目描述: 请设计一个跨浏览器统一的音视频录制方案,覆盖桌面端 Chrome/Edge/Firefox/Safari,说明如何检测能力、处理格式差异和保证录制质量。

参考答案

浏览器能力检测层

javascript
function getSupportedMimeTypes() {
  const types = [
    'video/webm;codecs=vp9,opus',
    'video/webm;codecs=vp8,opus',
    'video/webm',
    'video/mp4',
  ];
  return types.filter(type => MediaRecorder.isTypeSupported(type));
}

主要浏览器录制支持:

浏览器推荐格式备注
Chrome / Edgewebm (VP8/VP9 + Opus)功能完整
Firefoxwebm (VP8/VP9 + Opus)支持良好
Safarimp4 (H.264 + AAC)对 webm 支持有限

统一录制 SDK 架构

text
┌─────────────────────────────────────┐
│         Record SDK API              │
│  start / stop / pause / resume      │
├─────────────────────────────────────┤
│      Capability Detection           │
│  isTypeSupported / feature test     │
├─────────────────────────────────────┤
│      Format Adapter                 │
│  WebM Adapter  │  MP4 Adapter       │
├─────────────────────────────────────┤
│      MediaRecorder / CanvasRecord   │
├─────────────────────────────────────┤
│      Output Normalization           │
│  统一输出 Blob + metadata            │
└─────────────────────────────────────┘

关键设计点

  1. 能力检测

    • 使用 MediaRecorder.isTypeSupported() 检测浏览器支持的 MIME 类型。
    • 对不支持 MediaRecorder 的旧浏览器,提示升级或使用插件。
  2. 格式选择策略

    • Safari 优先选择 video/mp4
    • Chrome/Firefox 优先选择 video/webm;codecs=vp9,opus
    • 统一降级到最基础的支持格式。
  3. Canvas 录制兜底

    • 当需要录制复杂合成内容时,使用 canvas.captureStream() + MediaRecorder。
    • 注意帧率限制和性能开销。
  4. 质量与性能平衡

    • 根据设备性能动态选择分辨率、帧率、码率。
    • 高端设备用 1080p 30fps,低端设备降级到 720p 15fps。
  5. 输出归一化

    • 不同浏览器输出格式不同,但 SDK 对外返回统一的 { blob, mimeType, duration } 结构。
    • 后续服务端统一转码为 MP4/WebM。
  6. 异常处理

    • 监听 onerroronwarning
    • 录制失败时自动重试或降级格式。

最佳实践:

  • 录制前做权限和设备检测,避免中途失败。
  • 长时间录制时定期触发 ondataavailable,分片保存数据。
  • 提供服务端转码兜底,统一最终输出格式。

评分维度

  • 能检测浏览器录制能力并选择格式(30%)
  • 能说明不同浏览器格式差异(20%)
  • 能设计统一 SDK 架构和输出归一化(25%)
  • 能给出质量和异常处理策略(25%)

常见错误

  • 所有浏览器强制使用 webm,导致 Safari 无法播放或录制。
  • 不做能力检测,直接 new MediaRecorder。
  • 忽略 MediaRecorder 不同浏览器对 timeslice 和行为的支持差异。

延伸追问

  • 如何在录制过程中实时上传分片?
  • 录制失败后如何恢复未保存的数据?

相关题目

参考资源

口头回答版

跨浏览器录制要先做能力检测,用 MediaRecorder.isTypeSupported 看支持哪些格式。Chrome 和 Firefox 支持 webm,Safari 更偏向 mp4。我会设计一个 SDK,里面有 Capability Detection、Format Adapter,根据浏览器自动选格式,对外统一返回 Blob 和 metadata。如果录制复杂内容,可以用 canvas.captureStream 兜底。还要注意不同设备的性能差异,动态降分辨率帧率。最后输出格式不统一的话,可以让服务端再转码一次。


FB-51-SD-R-029:设计一个支持 DRM 的商业视频播放器安全架构

题型:系统设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:51 Multimedia 标签:DRM、安全架构、EME、许可证、防盗录、内容保护 出现频率:中频 预计回答时长:15-30 分钟

题目描述: 请设计一个支持 DRM 的商业视频播放器安全架构,包括内容加密、许可证获取、播放解密、防盗录和防篡改等关键环节。

参考答案

整体安全架构

text
                    内容分发网络 CDN

              加密视频流(CENC / SAMPLE-AES)

        ┌──────────────────┼──────────────────┐
        │                  │                  │
    许可证服务器        业务鉴权服务          播放器 SDK
        │                  │                  │
        └──────────────────┼──────────────────┘

                    用户设备 + CDM

关键环节设计

  1. 内容加密

    • 使用 CENC(Common Encryption)对视频进行通用加密。
    • 同一加密内容可同时用于 Widevine、PlayReady、FairPlay。
    • 密钥(Key)不随内容分发,只存在许可证服务器。
  2. 许可证服务器

    • 接收播放器发起的许可证请求。
    • 验证用户 Token、设备信息、权限。
    • 返回仅对当前会话有效的解密密钥。
    • 记录许可证发放日志,用于审计和风控。
  3. 播放器 SDK

    • 通过 EME requestMediaKeySystemAccess 选择合适 CDM。
    • 处理 license 请求,附加用户凭证和设备信息。
    • 不直接持有密钥,解密由浏览器 CDM 完成。
  4. 业务鉴权

    • 播放前校验用户登录态、会员权限、地域限制。
    • 使用短期 Token,过期后需重新获取。
    • 防止 Token 共享和重放攻击。
  5. 防盗录

    • 使用 DRM 的 HDCP(High-bandwidth Digital Content Protection)输出保护。
    • 检测到录屏软件时提示或停止播放(部分平台支持)。
    • 在画面上叠加用户唯一水印,用于溯源。
  6. 防篡改

    • 播放器 JS 做代码混淆和完整性校验。
    • 关键 API 调用做签名验证。
    • 检测到开发者工具或模拟器时降级或阻止播放。
  7. HTTPS 与 CORS

    • 所有请求走 HTTPS,防止中间人攻击。
    • 许可证接口严格限制 CORS 来源。

最佳实践:

  • 采用多 DRM 方案覆盖不同平台。
  • 许可证请求做限频和设备绑定。
  • 安全策略分层:内容加密 + 传输安全 + 客户端防护 + 业务风控。

评分维度

  • 能说明 CENC 通用加密和多 DRM 分发(25%)
  • 能设计许可证服务器和鉴权流程(25%)
  • 能说明 EME/CDM 解密流程(20%)
  • 能提出防盗录和防篡改措施(20%)
  • 能考虑 HTTPS/CORS 等传输安全(10%)

常见错误

  • 认为前端 JS 可以直接拿到解密密钥。
  • 只做 DRM 加密,忽略业务鉴权和 Token 安全。
  • 过度依赖前端防录屏,忽略水印等溯源手段。

延伸追问

  • 如何防止用户通过浏览器开发者工具下载加密分片?
  • 多设备登录共享账号时,DRM 和业务层如何协同限制?

相关题目

参考资源

口头回答版

商业 DRM 播放器安全要分多层。内容层用 CENC 通用加密,一套加密内容可以分发到 Widevine、FairPlay、PlayReady。许可证服务器负责验证用户和设备,返回解密密钥,密钥不直接给前端 JS,解密在浏览器 CDM 里完成。播放前业务层要鉴权,发短期 Token。还要做防盗录,比如 HDCP、用户水印、检测到录屏提示;前端 JS 做混淆和完整性校验,防止篡改。所有请求走 HTTPS,许可证接口严格限制 CORS。


FB-51-SD-R-030:如何评估和监控一个多媒体前端平台的质量?

题型:系统设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:51 Multimedia 标签:多媒体监控、QoE、QoS、可观测性、埋点、质量评估 出现频率:中频 预计回答时长:15-30 分钟

题目描述: 请设计一套多媒体前端平台的质量评估与监控体系,覆盖播放体验、性能、稳定性、无障碍等多个维度。

参考答案

质量指标体系

text
┌─────────────────────────────────────────────────┐
│              多媒体平台质量指标                  │
├───────────────┬─────────────────────────────────┤
│   QoS 指标     │  首帧时间、卡顿率、失败率、码率  │
├───────────────┼─────────────────────────────────┤
│   QoE 指标     │  清晰度、延迟、音画同步、交互响应 │
├───────────────┼─────────────────────────────────┤
│   稳定性指标   │  崩溃率、异常率、错误恢复成功率   │
├───────────────┼─────────────────────────────────┤
│   性能指标     │  CPU/GPU、内存、电量、网络消耗   │
├───────────────┼─────────────────────────────────┤
│   无障碍指标   │  字幕覆盖率、键盘可操作率         │
└───────────────┴─────────────────────────────────┘

核心监控项

  1. 播放质量(QoE/QoS)

    • 首帧时间(TTFB、TTFP)。
    • 卡顿次数、卡顿时长、卡顿率。
    • 播放失败率、错误码分类。
    • 清晰度分布和切换次数。
    • 端到端延迟(直播场景)。
  2. 技术实现指标

    • 协议分布:HLS/DASH/WebRTC 占比。
    • DRM 触发率和许可证成功率。
    • MSE Buffer 长度、SourceBuffer append 耗时。
    • WebRTC 丢包、抖动、RTT。
  3. 性能与资源

    • CPU / GPU 占用。
    • 内存占用和增长趋势。
    • 移动设备电量消耗和发热。
    • 网络流量消耗。
  4. 稳定性

    • JS 错误、Promise 异常。
    • 播放器 SDK 崩溃和自动恢复。
    • 浏览器兼容性分布。
  5. 无障碍

    • 字幕开关率、字幕正确率。
    • 键盘操作路径覆盖率。
    • 屏幕阅读器兼容性。

监控架构

text
播放器 SDK 埋点

      v
边缘日志网关 -> 消息队列 Kafka

        ┌───────────┼───────────┐
        v           v           v
    实时计算    离线数仓      告警平台
        │           │           │
        v           v           v
    实时监控看板   质量报告     异常告警

关键实现方式

javascript
// 播放器事件埋点
video.addEventListener('waiting', () => report('buffer_stall', { currentTime }));
video.addEventListener('error', (e) => report('playback_error', { code: e.target.error.code }));
video.addEventListener('loadeddata', () => report('first_frame', { ttfp }));

// 定时采样性能
setInterval(() => {
  report('performance', {
    buffered: video.buffered.length,
    currentTime: video.currentTime,
    memory: performance.memory?.usedJSHeapSize,
  });
}, 5000);

质量评估方法

  1. 健康分模型

    • 综合首帧、卡顿、失败、延迟等指标,计算 0-100 的健康分。
    • 按地区、运营商、设备、版本下钻分析。
  2. A/B 实验

    • 对比不同播放器版本、不同协议、不同缓冲策略的效果。
  3. 用户反馈闭环

    • 收集用户上报的播放问题,与监控数据关联定位。

最佳实践:

  • 埋点要轻量,避免影响播放性能。
  • 关键指标实时告警,如失败率突增、卡顿率异常。
  • 建立 SLA,如 99.9% 播放成功率、P99 首帧 < 2s。

评分维度

  • 能建立 QoS/QoE/稳定性/性能/无障碍多维指标体系(30%)
  • 能说明关键监控项和采集方式(25%)
  • 能设计监控架构和数据链路(20%)
  • 能提出健康分模型和 SLA(15%)
  • 能考虑埋点性能开销(10%)

常见错误

  • 只关注播放成功率,忽略用户体验指标。
  • 埋点过多或采样不当,影响播放性能。
  • 监控数据没有按维度下钻,难以定位问题。

延伸追问

  • 如何区分网络问题和服务端问题导致的卡顿?
  • 如何建立播放器 SDK 的版本灰度监控?

相关题目

参考资源

口头回答版

多媒体平台质量监控要从几个维度建指标体系:QoS 看首帧、卡顿、失败率;QoE 看清晰度、延迟、音画同步;稳定性看崩溃和异常;性能看 CPU、内存、电量;还要看无障碍。播放器 SDK 里埋点采集这些事件和定时性能数据,经过日志网关到 Kafka,再做实时计算和离线分析。可以做一个健康分模型综合评估,按地区、运营商、版本下钻。关键指标要设 SLA 和实时告警,比如播放成功率 99.9%、P99 首帧小于 2 秒。埋点要轻量,别影响播放。


FB-51-CP-R-031:多媒体前端技术未来 3-5 年的演进趋势是什么?

题型:综合开放题 难度:⚫ 架构 岗位层级:架构师 面试知识域:51 Multimedia 标签:多媒体趋势、WebCodecs、WebTransport、AI、AV1、云游戏 出现频率:低频 预计回答时长:8-15 分钟

题目描述: 请谈谈你对多媒体前端技术未来 3-5 年演进趋势的看法,以及这些趋势对前端架构师的能力要求。

参考答案

主要演进趋势

  1. 浏览器原生多媒体能力增强

    • WebCodecs 成熟,前端可直接编解码,推动云端渲染、云游戏、视频编辑。
    • WebTransport 提供低延迟可靠/不可靠传输,替代 WebRTC DataChannel 部分场景。
    • WebGPU 用于高性能视频处理和 AI 推理。
  2. 新编码格式普及

    • AV1、H.266/VVC 逐渐落地,同等画质下码率更低。
    • 浏览器对 AV1 硬解支持持续提升,前端需做 fallback 策略。
  3. 低延迟直播常态化

    • WebRTC、LL-HLS、LL-DASH、WebTransport 多协议并存。
    • 互动直播、电商直播、云游戏对延迟要求越来越高。
  4. AI 与多媒体结合

    • 实时字幕、翻译、智能剪辑、画质增强。
    • WebNN / ONNX Runtime Web 让前端能跑轻量 AI 模型。
    • AIGC 内容生成和审核需求增加。
  5. 沉浸式体验

    • WebXR 与 360 视频、VR/AR 直播结合。
    • 空间音频、光场视频等新技术逐步进入 Web。
  6. 隐私和安全强化

    • DRM 方案更复杂,隐私计算与内容保护结合。
    • 浏览器对指纹、摄像头、麦克风权限更严格。

对前端架构师的能力要求

能力说明
多媒体底层原理深入理解编解码、流媒体协议、传输协议
性能工程能从端到端角度优化延迟、卡顿、功耗
跨平台架构设计 Web/小程序/桌面/移动端统一方案
AI 集成能力了解模型部署、推理优化、AI 与媒体结合点
安全合规DRM、隐私、内容审核、数据合规
可观测性建立多维质量监控和快速定位能力

前端架构师应对建议

  • 持续跟进 W3C 多媒体相关标准和 Chrome 实验性功能。
  • 在业务中逐步引入 WebCodecs、WebTransport 等新技术做 POC。
  • 建立多媒体技术中台,沉淀播放器、录制、剪辑、直播等能力。
  • 培养团队对 FFmpeg、GStreamer 等底层工具的理解。

评分维度

  • 能提到 WebCodecs、WebTransport、AV1、AI 等至少 3 个趋势(40%)
  • 能分析趋势对业务的影响(25%)
  • 能说明对前端架构师的能力要求(25%)
  • 能给出具体落地建议(10%)

常见错误

  • 只谈技术概念,不谈业务价值和落地路径。
  • 过度追新,忽略浏览器兼容性和稳定性。
  • 忽视安全和隐私趋势。

延伸追问

  • 如何在现有业务中渐进式引入 WebCodecs?
  • 云游戏前端架构和普通视频播放器有什么本质区别?

相关题目

参考资源

口头回答版

未来 3 到 5 年,多媒体前端会有几个明显趋势:一是浏览器原生能力越来越强,WebCodecs 让前端能直接编解码,WebTransport 提供更低延迟传输;二是 AV1 这些新编码格式会普及,同等画质更省码率;三是低延迟直播会变成常态,WebRTC、LL-HLS、WebTransport 并用;四是 AI 和多媒体结合更紧密,比如实时字幕、翻译、智能剪辑;五是 WebXR 带来沉浸式体验。对架构师来说,不能只懂前端框架,要懂编解码、协议、性能工程、AI 部署、安全合规,还要能建立多媒体中台和监控体系。

FB-51-CO-A-017:HTML5 音频和视频标签有哪些常用属性?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:HTML5、audio、video、媒体属性 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明 HTML5 <audio><video> 标签的常用属性。

参考答案: HTML5 媒体标签常用属性:

属性说明
src媒体资源地址
controls显示播放控件
autoplay自动播放
loop循环播放
muted静音
preload预加载策略(none/metadata/auto)
postervideo 封面图
width/heightvideo 尺寸
playsinlineiOS 内联播放
crossorigin跨域配置

常用 JavaScript API:

  • play() / pause()
  • currentTime:当前播放位置
  • duration:总时长
  • volume:音量
  • playbackRate:播放速度
  • paused / ended / readyState

事件:

  • loadedmetadatacanplayplaypauseendedtimeupdatevolumechange

注意:

  • 自动播放受浏览器策略限制,通常需要用户交互或静音。
  • 移动端注意全屏和内联播放行为。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

HTML5 audio/video 常用属性有 src、controls、autoplay、loop、muted、preload、poster、playsinline 等。JS API 有 play/pause、currentTime、duration、volume、playbackRate,事件有 canplay、timeupdate、ended 等。


FB-51-CO-A-018:如何实现自定义视频播放器控件?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:视频播放器、自定义控件、HTML5、video 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明实现一个自定义视频播放器控件的关键步骤。

参考答案: 自定义视频播放器步骤:

  1. 隐藏默认控件

    • <video controls="false"> 或不写 controls。
  2. 自定义 UI

    • 播放/暂停按钮。
    • 进度条/拖拽条。
    • 音量控制。
    • 全屏按钮。
    • 时间显示。
    • 倍速、画质、字幕选择。
  3. 绑定事件

    • 播放/暂停:video.play() / video.pause()
    • 进度:video.currentTime = value
    • 音量:video.volume = value
    • 全屏:requestFullscreen()
  4. 同步状态

    • 监听 timeupdate 更新进度条。
    • 监听 playpauseended 更新按钮状态。
    • 监听 loadedmetadata 获取时长。
  5. 进度条交互

    • 点击跳转、拖拽预览。
    • 注意 seek 时暂停更新避免抖动。
  6. 缓冲显示

    • 监听 waitingplayingprogress 显示 loading。
  7. 响应式布局

    • 控件适配不同屏幕尺寸。
  8. 可访问性

    • 键盘快捷键、ARIA 属性、焦点管理。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

自定义播放器要隐藏默认控件,做自定义 UI,绑定 play/pause/seek/volume/fullscreen 事件,同步 timeupdate 和状态,处理进度条交互、缓冲、响应式、可访问性。


FB-51-CO-A-019:浏览器中的 Media Source Extensions(MSE)是什么?有什么作用?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:MSE、Media Source Extensions、流媒体、DASH、HLS 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请解释 MSE 的概念及其在流媒体播放中的作用。

参考答案: MSE(Media Source Extensions):

  • 是浏览器提供的 API,允许 JavaScript 动态构建媒体流并喂给 <video><audio>
  • 让浏览器可以播放自定义协议或自适应码率的流媒体。

作用:

  1. 自适应码率(ABR)

    • 根据网络状况切换不同码率片段。
    • DASH、HLS 的核心技术之一。
  2. 自定义加载逻辑

    • 控制缓冲策略、预加载、seek 行为。
  3. 加密内容

    • 配合 EME(Encrypted Media Extensions)播放 DRM 内容。
  4. 直播低延迟

    • 通过控制 buffer 实现低延迟直播。

核心对象:

  • MediaSource:媒体源。
  • SourceBuffer:存储媒体片段(video/audio)。

基本流程:

js
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
  const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"');
  fetchSegment(url).then(buf => sourceBuffer.appendBuffer(buf));
});

注意:

  • MSE 需要服务器支持 range 请求或分片。
  • 要处理 buffer 更新、append 队列、codec 切换。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

MSE 允许 JS 动态构建媒体流给 video/audio,用于自适应码率、自定义加载、DRM、低延迟直播。核心是 MediaSource 和 SourceBuffer,要处理 buffer 更新和 append 队列。


FB-51-CO-A-020:HLS 和 DASH 有什么区别?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:HLS、DASH、流媒体、协议 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明 HLS 和 DASH 两种流媒体协议的区别。

参考答案: HLS vs DASH:

特性HLSDASH
发起方AppleMPEG 标准
索引格式m3u8 文本MPD XML
默认切片格式TSfMP4
编码H.264/H.265/AV1灵活
浏览器原生支持Safari 原生需 MSE
DRMFairPlayWidevine/PlayReady
低延迟LL-HLSLL-DASH

HLS:

  • 苹果生态支持好。
  • Safari 原生播放,无需 MSE。
  • 移动端兼容性好。

DASH:

  • 更灵活,跨平台。
  • 通常需要 MSE 或播放器库(如 dash.js、Shaka Player)。
  • 更适合 Web 端。

实际应用:

  • 同时提供 HLS 和 DASH,根据浏览器选择。
  • 直播常用 HLS(兼容移动端),点播可用 DASH。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

HLS 是苹果提出的,m3u8 索引,Safari 原生支持好;DASH 是 MPEG 标准,MPD XML 索引,更灵活跨平台,通常需 MSE。实际常同时提供两种。


FB-51-CO-A-021:WebRTC 的核心组件有哪些?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:WebRTC、RTCPeerConnection、RTCDataChannel、实时通信 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明 WebRTC 的核心组件及其作用。

参考答案: WebRTC 核心组件:

  1. getUserMedia

    • 获取摄像头、麦克风等媒体流。
    • navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  2. RTCPeerConnection

    • 建立点对点连接。
    • 处理音视频传输、编解码、网络穿透。
  3. RTCDataChannel

    • 在 peer connection 上传输任意数据。
    • 支持可靠和不可靠传输。
  4. RTCSessionDescription

    • SDP(Session Description Protocol)描述。
    • 包含媒体能力、编解码、网络信息。
  5. ICE(Interactive Connectivity Establishment)

    • 通过 STUN/TURN 服务器建立连接。
    • 处理 NAT 穿透。
  6. 信令服务器(Signaling Server)

    • 交换 SDP 和 ICE candidate。
    • WebRTC 本身不定义信令协议,需自己实现。

建立连接流程:

  1. A 创建 offer,设置 local description。
  2. 通过信令服务器发送 offer 给 B。
  3. B 设置 remote description,创建 answer。
  4. B 通过信令服务器发送 answer 给 A。
  5. 交换 ICE candidate。
  6. 建立 P2P 连接。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

WebRTC 核心有 getUserMedia 获取媒体、RTCPeerConnection 建立连接、RTCDataChannel 传数据、SDP 描述、ICE 穿透、信令服务器交换信息。连接通过 offer/answer/ICE 完成。


FB-51-CO-B-009:浏览器如何捕获屏幕或摄像头?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:多媒体 标签:屏幕捕获、getDisplayMedia、getUserMedia、MediaStream 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明浏览器中获取摄像头画面和屏幕共享的方法。

参考答案: 浏览器媒体捕获:

  1. 摄像头/麦克风

    js
    const stream = await navigator.mediaDevices.getUserMedia({
      video: { width: 1280, height: 720 },
      audio: true
    });
    videoElement.srcObject = stream;
  2. 屏幕共享

    js
    const stream = await navigator.mediaDevices.getDisplayMedia({
      video: true,
      audio: true
    });
  3. 枚举设备

    js
    const devices = await navigator.mediaDevices.enumerateDevices();
  4. 切换设备

    • 通过 deviceId 选择特定摄像头或麦克风。
  5. 权限处理

    • 需要用户授权。
    • HTTPS 或 localhost 环境。
  6. 停止流

    js
    stream.getTracks().forEach(track => track.stop());

注意:

  • 屏幕共享通常不能获取系统音频(取决于浏览器)。
  • 移动端对 getDisplayMedia 支持有限。
  • 要处理设备权限被拒绝的情况。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

浏览器用 getUserMedia 捕获摄像头麦克风,getDisplayMedia 屏幕共享,enumerateDevices 枚举设备,通过 deviceId 切换,记得 stop tracks。


FB-51-CO-B-010:Canvas 如何实现视频帧处理?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:多媒体 标签:Canvas、video、帧处理、图像处理 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明如何使用 Canvas 对视频帧进行处理。

参考答案: Canvas 视频帧处理:

  1. 绘制视频帧到 Canvas

    js
    ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
  2. 获取像素数据

    js
    const imageData = ctx.getImageData(0, 0, width, height);
    const pixels = imageData.data; // Uint8ClampedArray
  3. 处理像素

    • 遍历 pixels 数组,修改 RGBA 值。
    • 可实现滤镜、灰度、模糊、边缘检测等。
  4. 写回 Canvas

    js
    ctx.putImageData(imageData, 0, 0);
  5. 性能优化

    • 使用 Web Worker 处理像素,避免阻塞主线程。
    • 使用 WebGL/WebGPU 做 GPU 加速处理。
    • 降低处理分辨率。
  6. 实时处理

    • requestAnimationFrame 循环中逐帧处理。
  7. 跨域限制

    • 视频跨域时 canvas 会被污染,无法 getImageData。
    • 需要视频设置 crossOrigin="anonymous" 且服务器支持 CORS。

注意:

  • CPU 处理高分辨率视频帧很耗时。
  • 生产环境建议用 WebGL/WebGPU。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

Canvas 处理视频帧:drawImage 绘制,getImageData 获取像素,修改 pixels,putImageData 写回。可放 Worker,或用 WebGL/WebGPU 加速,注意跨域限制。


FB-51-CO-B-011:什么是 Web Audio API?它有哪些应用场景?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:多媒体 标签:Web Audio API、音频处理、可视化、合成 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明 Web Audio API 的概念和常见应用场景。

参考答案: Web Audio API:

  • 是浏览器提供的高级音频处理 API。
  • 基于音频图(Audio Graph)模型,节点连接处理音频。

核心节点:

  • AudioContext:音频上下文。
  • AudioBufferSourceNode:播放音频 buffer。
  • MediaElementAudioSourceNode:从 audio/video 元素获取音频。
  • GainNode:音量控制。
  • AnalyserNode:音频分析,获取时域/频域数据。
  • BiquadFilterNode:滤波器。
  • ConvolverNode:混响。
  • PannerNode:3D 音频定位。
  • DynamicsCompressorNode:压缩。

应用场景:

  1. 音频可视化

    • 用 AnalyserNode 获取频谱数据,绘制波形图/频谱图。
  2. 音频处理

    • 实时均衡、滤波、混响、降噪。
  3. 游戏音频

    • 3D 音效、音频合成。
  4. 音乐应用

    • 在线 DAW、合成器、节拍器。
  5. 语音处理

    • 变声、回声消除、音量归一化。

示例:

js
const audioCtx = new AudioContext();
const oscillator = audioCtx.createOscillator();
oscillator.connect(audioCtx.destination);
oscillator.start();

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

Web Audio API 基于音频图模型,核心节点有 AudioContext、Source、Gain、Analyser、Filter、Panner 等。应用包括音频可视化、实时处理、游戏音频、音乐应用、语音处理。


FB-51-CP-P-025:如何实现音频可视化效果?

题型:综合开放题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:音频可视化、Web Audio API、Canvas、频谱 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明实现音频可视化(波形图/频谱图)的思路。

参考答案: 音频可视化实现思路:

  1. 创建 AudioContext 和 AnalyserNode

    js
    const audioCtx = new AudioContext();
    const analyser = audioCtx.createAnalyser();
    analyser.fftSize = 256;
  2. 连接音频源

    • 从 audio/video 元素:audioCtx.createMediaElementSource(audioEl)
    • 从麦克风:audioCtx.createMediaStreamSource(stream)
  3. 获取数据

    js
    const dataArray = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(dataArray); // 频域
    // 或 analyser.getByteTimeDomainData(dataArray); // 时域
  4. 绘制可视化

    • 频谱图:每个 frequency bin 对应一个矩形条。
    • 波形图:每个采样点对应一个点或线。
    • 使用 Canvas 或 WebGL 绘制。
  5. 动画循环

    • 在 requestAnimationFrame 中持续获取数据并重绘。
  6. 优化

    • 减少 fftSize 可降低延迟和 CPU。
    • 使用 WebGL 绘制大量条形。
    • 对频谱取对数更符合人耳感知。
  7. 响应式设计

    • 根据容器大小调整可视化条数和间距。

示例:

js
function draw() {
  requestAnimationFrame(draw);
  analyser.getByteFrequencyData(dataArray);
  // 用 Canvas 绘制频谱条
}
draw();

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

音频可视化用 AudioContext + AnalyserNode 连接音频源,getByteFrequencyData 获取频域数据,在 requestAnimationFrame 中用 Canvas/WebGL 绘制频谱条或波形。


FB-51-CP-P-026:如何实现浏览器端录音并导出音频文件?

题型:综合开放题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:录音、MediaRecorder、音频、导出 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明浏览器端录音并导出为音频文件的方案。

参考答案: 浏览器端录音方案:

  1. 获取麦克风权限

    js
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  2. 使用 MediaRecorder

    js
    const mediaRecorder = new MediaRecorder(stream);
    const chunks = [];
    mediaRecorder.ondataavailable = e => chunks.push(e.data);
    mediaRecorder.onstop = () => {
      const blob = new Blob(chunks, { type: 'audio/webm' });
      const url = URL.createObjectURL(blob);
    };
    mediaRecorder.start();
  3. 控制录音

    • start()stop()pause()resume()
  4. 导出格式

    • MediaRecorder 支持 webm、ogg 等。
    • 导出 MP3/WAV 需要额外库(如 Recorder.js、lamejs)。
  5. 实时音频处理

    • 可用 Web Audio API 添加降噪、增益等。
  6. 可视化反馈

    • 录音时显示音量大小。
  7. 注意

    • 录音需要 HTTPS/localhost。
    • 要处理权限拒绝和设备不可用。
    • 长录音注意内存占用。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

浏览器录音用 getUserMedia 获取麦克风,MediaRecorder 录制数据,stop 后合成 Blob 导出。要导出 MP3/WAV 用额外库,可配合 Web Audio 做实时处理。


FB-51-CP-P-027:如何实现视频转码或格式转换?

题型:综合开放题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:视频转码、ffmpeg、wasm、格式转换 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明浏览器端实现视频转码的方案。

参考答案: 浏览器端视频转码方案:

  1. ffmpeg.wasm

    • FFmpeg 编译为 WebAssembly。
    • 功能强大,支持几乎所有格式。
    • 但体积大、性能受限。
  2. WebCodecs API

    • 浏览器原生视频编解码 API。
    • 可访问底层编码器/解码器。
    • 性能高,但 API 较底层。
  3. MediaRecorder

    • 浏览器原生录制。
    • 支持 webm/ogg,格式有限。
  4. Canvas + MediaRecorder

    • 通过 Canvas 处理视频帧后录制。
    • 可实现简单滤镜和格式输出。
  5. WebRTC 的 Insertable Streams

    • 实时处理编码后的视频帧。

实现流程(ffmpeg.wasm):

js
const ffmpeg = createFFmpeg({ log: true });
await ffmpeg.load();
ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(file));
await ffmpeg.run('-i', 'input.mp4', 'output.webm');
const data = ffmpeg.FS('readFile', 'output.webm');

优化:

  • 大文件分片处理。
  • 使用 Web Worker 避免阻塞 UI。
  • 进度条反馈。

注意:

  • 浏览器端转码性能有限,适合小文件或简单处理。
  • 复杂转码建议在服务端完成。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

浏览器端转码可用 ffmpeg.wasm、WebCodecs API、MediaRecorder。ffmpeg.wasm 功能全但体积大,WebCodecs 性能高但底层。大文件建议服务端处理。


FB-51-CP-P-028:如何实现视频直播的低延迟播放?

题型:综合开放题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:直播、低延迟、WebRTC、HLS、DASH 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明实现低延迟视频直播的技术方案。

参考答案: 低延迟直播方案:

  1. WebRTC

    • 端到端延迟可低于 500ms。
    • 适合互动直播、连麦。
    • 技术复杂,需要 SFU/MCU 服务器。
  2. LL-HLS(Low-Latency HLS)

    • 苹果低延迟 HLS。
    • 延迟约 2-3 秒。
    • 兼容性好。
  3. LL-DASH(Low-Latency DASH)

    • MPEG 低延迟 DASH。
    • 延迟约 2-3 秒。
  4. SRT/RTMP over WebSocket

    • 通过 WebSocket 传输 FLV。
    • 延迟约 1-3 秒。
  5. 优化方向

    • 减少 GOP 大小。
    • 降低 buffer 长度。
    • 使用 CDN 边缘节点。
    • 优化网络传输和重传策略。
  6. 取舍

    • 低延迟通常牺牲流畅度和抗弱网能力。
    • 根据场景选择合适的延迟目标。

示例场景:

  • 互动直播/连麦:WebRTC。
  • 体育赛事直播:LL-HLS/LL-DASH。
  • 监控:WebRTC 或 WebSocket FLV。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

低延迟直播方案:WebRTC 延迟最低适合互动,LL-HLS/LL-DASH 延迟 2-3 秒兼容好,WebSocket FLV 也可。要减少 GOP、降低 buffer、用边缘节点,但低延迟可能牺牲流畅度。


FB-51-CP-P-029:浏览器端如何实现视频剪辑功能?

题型:综合开放题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:视频剪辑、浏览器、Canvas、ffmpeg、时间轴 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明浏览器端实现基础视频剪辑功能的技术方案。

参考答案: 浏览器端视频剪辑方案:

  1. 视频预览

    • 用 video 元素加载视频。
    • Canvas 绘制当前帧,实现逐帧预览。
  2. 时间轴

    • 展示视频轨道、音频轨道。
    • 支持拖拽裁剪范围、分割、拼接。
  3. 帧截取

    • drawImage(video, ...) 到 canvas 生成封面和缩略图。
  4. 剪辑逻辑

    • 记录入点、出点、片段顺序。
    • 简单的片段拼接可服务端完成。
  5. 实时预览

    • 对裁剪片段用 video 的播放范围预览。
    • 复杂效果用 Canvas/WebGL 实时渲染。
  6. 导出处理

    • 简单裁剪可只上传时间范围给服务端。
    • 复杂剪辑可用 ffmpeg.wasm 在浏览器端合成。
  7. 性能优化

    • 缩略图生成放 Web Worker。
    • 大视频分段加载。
  8. 用户体验

    • 波形图展示音频。
    • 磁吸对齐、撤销重做。

注意:

  • 浏览器端剪辑能力有限,复杂合成建议服务端。
  • 大文件上传耗时,可考虑云剪辑。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

浏览器端视频剪辑用 video + Canvas 预览,时间轴管理片段,Canvas 截帧,记录入点出点,简单裁剪传服务端,复杂用 ffmpeg.wasm。注意性能,缩略图放 Worker。


FB-51-CP-P-030:如何实现 360 度全景视频播放?

题型:综合开放题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:全景视频、VR、WebGL、Three.js、Equirectangular 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明浏览器端实现 360 度全景视频播放的方案。

参考答案: 全景视频播放方案:

  1. 视频源

    • Equirectangular(等距圆柱投影)格式最常见。
    • 也可使用立方体贴图(Cubemap)。
  2. WebGL/Three.js 渲染

    • 将球体或立方体内部作为视频纹理。
    • 相机位于中心,用户拖动改变视角。
  3. Three.js 实现

    js
    const geometry = new THREE.SphereGeometry(500, 60, 40);
    geometry.scale(-1, 1, 1); // 内部可见
    const video = document.createElement('video');
    video.src = 'panorama.mp4';
    video.crossOrigin = 'anonymous';
    video.play();
    const texture = new THREE.VideoTexture(video);
    const material = new THREE.MeshBasicMaterial({ map: texture });
    const sphere = new THREE.Mesh(geometry, material);
    scene.add(sphere);
  4. 交互控制

    • 鼠标/触摸拖拽旋转视角。
    • 陀螺仪(DeviceOrientation)支持 VR。
  5. VR 模式

    • WebXR API 实现 VR 头显支持。
    • 左右眼分屏渲染。
  6. 性能优化

    • 视频分辨率根据设备性能选择。
    • 使用硬件解码。
  7. 格式支持

    • 注意浏览器对高分辨率视频解码的支持。

注意:

  • 全景视频文件通常很大,需要流式加载。
  • 移动端发热和耗电明显。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

全景视频常用 Equirectangular 格式,用 WebGL/Three.js 将球体反向后贴视频纹理,相机在中心,支持鼠标拖拽和陀螺仪,VR 模式用 WebXR。注意大文件流式加载和移动端耗电。


FB-51-CP-P-031:多媒体前端开发中如何处理不同浏览器的格式兼容性?

题型:综合开放题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:多媒体、兼容性、格式、canPlayType、降级 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明浏览器中视频/音频格式兼容性的处理策略。

参考答案: 格式兼容性处理策略:

  1. canPlayType 检测

    js
    const video = document.createElement('video');
    const canPlay = video.canPlayType('video/mp4; codecs="avc1.42E01E"');
  2. 多源格式

    html
    <video>
      <source src="video.mp4" type="video/mp4">
      <source src="video.webm" type="video/webm">
    </video>
  3. 格式转码服务

    • 服务端同时提供 MP4、WebM、HLS、DASH 等格式。
    • 前端根据环境选择。
  4. Codec 选择

    • H.264:兼容性最好。
    • VP8/VP9:WebM,开源。
    • AV1:新一代,压缩率高但解码要求高。
    • HEVC:苹果生态支持好。
  5. 降级策略

    • 不支持时降级为图片、提示升级浏览器、转码后重试。
  6. 移动端特殊处理

    • iOS 对格式和全屏播放有特殊要求。
    • Android 碎片化严重,需多测试。
  7. 特性检测

    • MSE、WebRTC、Web Audio、WebCodecs 等特性需分别检测。
  8. 监控

    • 收集播放失败率和格式分布,持续优化。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

多媒体兼容性用 canPlayType 检测,提供多源格式,服务端转码多格式,选择合适 codec,做好降级,移动端特殊处理,特性检测,监控失败率。


FB-51-FS-P-024:如何实现图片/视频的懒加载和预加载策略?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:懒加载、预加载、图片、视频、性能 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明多媒体资源懒加载和预加载的实现方法。

参考答案: 懒加载和预加载策略:

  1. 图片懒加载

    • 使用 loading="lazy" 原生属性。
    • 或用 IntersectionObserver 监听进入视口。
    • 占位图/骨架屏过渡。
  2. 视频懒加载

    • 延迟加载 video 的 src 和 poster。
    • 进入视口后再设置真实 src。
    • 非首屏视频不预加载:preload="none"
  3. 预加载关键资源

    • <link rel="preload"> 预加载首屏图片/字体/视频。
    • 对即将进入视口的资源提前加载。
  4. 预测预加载

    • 根据用户行为预测下一步要看的视频/图片。
    • 如轮播图下一张、视频下一集。
  5. 优先级管理

    • 首屏资源高优先级。
    • 非首屏低优先级或懒加载。
  6. 响应式图片

    • srcsetsizes 加载合适分辨率。
    • 避免移动端加载大图。
  7. 视频预加载策略

    • preload="metadata":只加载元数据。
    • preload="auto":自动预加载。
    • 根据网络和设备选择。
  8. 取消加载

    • 离开视口或切换时取消未完成请求。
    • 避免浪费带宽。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

多媒体懒加载用 loading=lazy、IntersectionObserver、延迟设置 src;预加载用 link preload、预测加载、响应式 srcset、合理设置 video preload,注意取消不再需要的加载。


FB-51-FS-P-025:浏览器端如何处理大文件上传?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:大文件上传、分片、断点续传、Blob 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明浏览器端大文件(如视频)上传的方案。

参考答案: 大文件上传方案:

  1. 分片上传

    • 使用 Blob.slice 将文件切成多个 chunk。
    • 每个 chunk 单独上传。
  2. 断点续传

    • 记录已上传的 chunk 索引。
    • 失败时只重传失败分片。
  3. 并发控制

    • 限制同时上传的 chunk 数量。
    • 避免过多连接占用带宽。
  4. 进度显示

    • 计算已上传字节数 / 总字节数。
    • 实时更新进度条。
  5. MD5/Hash 校验

    • 每个 chunk 计算 hash,服务端校验完整性。
    • 秒传:服务端已有相同文件时直接返回成功。
  6. 服务端合并

    • 所有 chunk 上传完成后,服务端按顺序合并。
  7. 取消和暂停

    • 使用 AbortController 取消上传。
    • 支持暂停后继续。

示例:

js
const chunkSize = 1024 * 1024; // 1MB
const chunks = Math.ceil(file.size / chunkSize);
for (let i = 0; i < chunks; i++) {
  const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
  await uploadChunk(chunk, i);
}

注意:

  • 大文件 hash 计算较耗时,可抽样计算。
  • 网络波动时要有重试机制。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

大文件上传要分片、断点续传、并发控制、进度显示、hash 校验、服务端合并、支持取消暂停。用 Blob.slice 切分,AbortController 取消。


FB-51-PE-A-011:多媒体前端开发中如何进行性能优化?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:多媒体、性能优化、加载、渲染、内存 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明多媒体前端应用的整体性能优化方向。

参考答案: 多媒体前端性能优化:

  1. 加载优化

    • 懒加载、预加载、CDN、压缩、缓存。
    • 使用合适格式和分辨率。
  2. 渲染优化

    • 视频用硬件加速解码。
    • Canvas/WebGL 处理时用 requestAnimationFrame。
    • 避免在主线程做大量像素处理。
  3. 内存优化

    • 及时释放不再使用的 video、audio、canvas。
    • 控制同时播放的视频数量。
    • 大图片使用纹理压缩和分级加载。
  4. 网络优化

    • 自适应码率。
    • 分片加载、P2P 加速。
    • HTTP/2、CDN、Quic。
  5. CPU 优化

    • 复杂计算放 Web Worker 或 Wasm。
    • 使用 GPU 加速图像处理。
  6. 电池和发热

    • 移动端避免长时间高码率播放。
    • 适当降低帧率和分辨率。
  7. 用户体验

    • 首帧快速显示。
    • 流畅的 seek 和切换。
    • 弱网降级策略。
  8. 监控

    • 播放成功率、卡顿率、加载时长、错误率。
    • 根据数据持续优化。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

多媒体性能优化包括加载优化、渲染用硬件加速、内存及时释放、网络自适应码率、CPU 用 Worker/Wasm/GPU、注意移动端耗电、提升用户体验、监控关键指标。


FB-51-CO-B-012:HLS 和 DASH 两种流媒体协议有什么区别?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:多媒体 标签:HLS、DASH、流媒体、协议 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请比较 HLS 和 DASH 两种自适应流媒体协议的异同。

参考答案: HLS vs DASH:

特性HLSDASH
出品方AppleMPEG
切片格式TS 或 fMP4fMP4
索引文件M3U8MPD
编解码支持H.264/H.265,AAC更灵活,可支持 VP9、AV1 等
延迟通常 10-30 秒可配置,LL-DASH 更低
浏览器支持Safari 原生,其他需 hls.js需 dash.js 等库
使用场景直播、点播,移动生态跨平台点播、低延迟直播

相同点:

  • 都基于 HTTP 分段传输。
  • 都支持多码率自适应。
  • 都通过 CDN 分发。

选择建议:

  • 苹果生态优先 HLS。
  • 需要跨平台和灵活编解码选 DASH。
  • 低延迟直播可考虑 LL-HLS 或 LL-DASH。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

HLS 是苹果出的,用 M3U8 索引,TS 或 fMP4 切片;DASH 是 MPEG 标准,用 MPD 索引,fMP4 切片,编解码更灵活。都支持自适应码率和 CDN。苹果生态用 HLS,跨平台用 DASH。


FB-51-PE-A-012:前端如何实现视频预加载策略?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:视频、预加载、性能、策略 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明前端视频预加载的常见策略及适用场景。

参考答案: 视频预加载策略:

  1. preload 属性

    • none:不预加载,节省流量。
    • metadata:只加载元数据(时长、尺寸)。
    • auto:浏览器决定预加载多少。
  2. 首帧海报

    • 使用 poster 属性或预加载第一帧作为封面。
    • 比黑屏提升用户体验。
  3. 分段预加载

    • HLS/DASH 中预加载前几个分片。
    • 不一次性下载整个视频。
  4. 可视区域检测

    • 只有视频进入 viewport 附近才开始预加载。
    • 用 Intersection Observer 实现。
  5. 网络感知

    • 根据连接类型(4G/WiFi)决定是否预加载。
    • 使用 Network Information API。
  6. 预加载取消

    • 用户离开或切换视频时及时取消预加载。
    • 避免浪费带宽。

注意:

  • 预加载会消耗带宽和内存,移动端要谨慎。
  • 平衡首屏体验和资源消耗。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

视频预加载有 preload 属性、首帧海报、分段预加载、可视区域检测、网络感知、预加载取消。移动端要谨慎,平衡体验和资源。


FB-51-CO-P-020:什么是音视频同步(A/V Sync)?前端如何保证?

题型:概念题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:音视频同步、A/V Sync、多媒体 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请解释音视频同步的概念及前端保证同步的方法。

参考答案: A/V Sync 概念:

  • 音频和视频的播放时间戳(PTS)保持一致。
  • 不同步会导致口型对不上、声音提前/滞后。

原因:

  • 音频和视频解码、渲染耗时不同。
  • 网络抖动导致某一路数据延迟。
  • 播放器缓冲策略不一致。

前端保证方法:

  1. 统一时间基准

    • 以音频时钟为主,视频帧根据音频时间调整。
    • 或以外部系统时钟为基准。
  2. PTS/DTS 对齐

    • 解码时按显示时间戳排序和渲染。
    • 丢弃或重复视频帧以追赶音频。
  3. 缓冲控制

    • 动态调整音视频缓冲大小。
    • 当差异超过阈值时触发同步校正。
  4. WebCodecs 应用

    • 使用 WebCodecs 精确控制解码和渲染时机。
    • 在 Worker 中处理解码,主线程同步渲染。
  5. 监控

    • 实时计算 A/V 差值。
    • 超过 40ms 用户可感知,需告警。

注意:

  • 直播场景同步要求更高。
  • 不同浏览器解码行为可能有差异,要做兼容性测试。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

音视频同步是音频视频 PTS 一致。前端可以音频时钟为主,按 PTS 对齐,动态缓冲,WebCodecs 精确控制,实时监控 A/V 差值。


FB-51-SC-A-001:如何处理直播中的网络抖动和卡顿?

题型:场景设计题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:直播、网络抖动、卡顿、优化 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明前端如何处理直播流中的网络抖动和卡顿问题。

参考答案: 处理直播网络抖动和卡顿:

  1. 缓冲策略

    • 设置合理的缓冲区大小,吸收网络抖动。
    • 动态调整:网络差时增大缓冲,网络好时减小缓冲。
  2. 码率自适应

    • 实时监测带宽,切换到低码率流。
    • HLS/DASH 支持多码率版本。
  3. 前向纠错(FEC)

    • 增加冗余数据,丢包时可恢复。
    • 适合 UDP/WebRTC 场景。
  4. 快启动

    • 首次播放时先加载低码率流,保证快速起播。
    • 稳定后再切换到高码率。
  5. 卡顿降级

    • 长时间卡顿时提示用户或自动暂停重连。
    • 避免持续缓冲导致体验恶化。
  6. 统计与上报

    • 收集卡顿率、缓冲次数、缓冲时长。
    • 用于优化 CDN 调度和码率配置。
  7. WebRTC 特有

    • 使用 NACK/PLC 处理丢包。
    • 动态调整编码码率和分辨率。

注意:

  • 直播延迟和流畅度是 trade-off。
  • 要根据业务场景选择合适策略。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

处理直播抖动用缓冲吸收、码率自适应、FEC、快启动、卡顿降级、统计上报。WebRTC 用 NACK/PLC。延迟和流畅度要权衡。


FB-51-CD-A-013:前端如何生成视频缩略图(thumbnail)?

题型:手写代码题 难度:🟡 进阶 岗位层级:高级 面试知识域:多媒体 标签:视频缩略图、Canvas、前端 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明前端生成视频缩略图的方案。

参考答案: 生成视频缩略图方案:

  1. Video + Canvas

    js
    const video = document.createElement('video');
    video.src = url;
    video.currentTime = 5;
    video.onseeked = () => {
      const canvas = document.createElement('canvas');
      canvas.width = video.videoWidth / 4;
      canvas.height = video.videoHeight / 4;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
      const thumb = canvas.toDataURL('image/jpeg');
    };
  2. WebCodecs

    • 解码视频帧后绘制到 canvas。
    • 更精确控制截取帧,适合批量处理。
  3. 服务端生成

    • 上传后由服务端用 FFmpeg 生成缩略图。
    • 质量更高,不消耗客户端资源。
  4. 预生成雪碧图

    • 服务端生成 storyboard/sprite。
    • 前端显示对应时间点的缩略图区域。
  5. 注意事项

    • 跨域视频需要 CORS。
    • 大视频seek可能耗时,可预加载关键帧。
    • 缩略图尺寸和压缩要平衡清晰度与体积。

适用场景:

  • 视频封面、进度条预览、视频列表。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

前端可用 video 加 canvas 截图,或用 WebCodecs 精确解码。也可以服务端 FFmpeg 生成或预生成雪碧图。注意跨域、seek 耗时、尺寸压缩。


FB-51-CO-P-021:什么是 CMAF?它如何统一 HLS 和 DASH?

题型:概念题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:CMAF、HLS、DASH、统一 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请解释 CMAF 的作用及其对前端的意义。

参考答案: CMAF(Common Media Application Format):

  • 由 MPEG 和 Apple 共同制定。
  • 目标是用同一套媒体文件同时服务 HLS 和 DASH。

统一方式:

  • 媒体片段使用 fMP4 格式。
  • HLS 用 M3U8 索引指向 fMP4 片段。
  • DASH 用 MPD 索引指向同一批 fMP4 片段。

优势:

  1. 存储和分发成本降低

    • 无需为 HLS 和 DASH 各存一套 TS/fMP4。
    • CDN 缓存命中率提升。
  2. 延迟降低

    • fMP4 切片可以更小,支持低延迟。
  3. 前端简化

    • 同一套媒体源适配不同平台。
    • 播放器逻辑可统一。
  4. DRM 统一

    • CMAF 支持 Common Encryption(CENC)。
    • 同一加密内容可被不同 DRM(Widevine、FairPlay)解密。

挑战:

  • 旧版 Safari 对 fMP4 HLS 支持有限。
  • 音轨、字幕等元数据格式需要兼容处理。

前端意义:

  • 减少转码和存储成本。
  • 更容易实现跨平台一致性。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

CMAF 用 fMP4 统一 HLS 和 DASH 的媒体片段,HLS 用 M3U8、DASH 用 MPD 索引同一套文件。好处是降低成本、提升缓存、支持低延迟、统一 DRM。


FB-51-SC-P-023:如何在 Web 端实现音视频剪辑功能?

题型:场景设计题 难度:🔴 深入 岗位层级:专家 面试知识域:多媒体 标签:音视频剪辑、WebCodecs、前端 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请设计一个 Web 端音视频剪辑方案。

参考答案: Web 端音视频剪辑方案:

  1. 文件上传与解析

    • 使用 MediaInfo.js 或自定义解析获取轨道信息。
    • 用 WebCodecs 解码音视频帧。
  2. 时间轴编辑

    • 前端用 Canvas/WebGL 渲染视频帧预览。
    • 音频用 Web Audio API 可视化波形。
    • 支持拖拽裁剪、分割、合并、调速。
  3. 剪辑操作

    • 记录用户的 in/out 点、轨道顺序、滤镜参数。
    • 不直接修改原始文件,而是生成编辑决策表(EDL)。
  4. 实时预览

    • 在 canvas 上按时间线组合帧。
    • 音轨用 Web Audio 同步播放。
  5. 导出

    • 简单场景:拼接原始片段的 URL/时间范围,服务端合成。
    • 复杂场景:用 WebCodecs 编码,在浏览器端生成 MP4/WebM。
    • 服务端兜底:FFmpeg 合成。
  6. 性能优化

    • 解码在 Worker 中进行。
    • 使用帧缓存和 LRU 策略。
    • 大文件用分段处理。

注意:

  • WebCodecs 兼容性有限,需要降级方案。
  • 浏览器端编码性能和内存是瓶颈。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

Web 剪辑可上传解析、时间轴编辑、记录 EDL、实时预览、服务端或 WebCodecs 导出。优化用 Worker、缓存、分段处理。


基于 MIT 协议发布