Menu

How to use and optimize videos

本页概述了如何在 Next.js 应用程序中使用视频,展示了如何存储和显示视频文件而不影响性能。

使用 <video><iframe>

视频可以通过 HTML <video> 标签(用于直接视频文件)和 <iframe>(用于外部平台托管的视频)嵌入到页面中。

<video>

HTML <video> 标签可以嵌入自托管或直接提供的视频内容,允许对播放和外观进行完全控制。

app/ui/video.jsx
export function Video() {
  return (
    <video width="320" height="240" controls preload="none">
      <source src="/path/to/video.mp4" type="video/mp4" />
      <track
        src="/path/to/captions.vtt"
        kind="subtitles"
        srcLang="en"
        label="English"
      />
      Your browser does not support the video tag.
    </video>
  )
}

常见的 <video> 标签属性

属性描述示例值
src指定视频文件的源。<video src="/path/to/video.mp4" />
width设置视频播放器的宽度。<video width="320" />
height设置视频播放器的高度。<video height="240" />
controls如果存在,则显示默认的播放控件。<video controls />
autoPlay页面加载时自动开始播放视频。注意:自动播放策略在不同浏览器间有所不同。<video autoPlay />
loop循环播放视频。<video loop />
muted默认静音。通常与 autoPlay 一起使用。<video muted />
preload指定视频如何预加载。值:nonemetadataauto<video preload="none" />
playsInline允许在 iOS 设备上内联播放,这对于在 iOS Safari 中实现自动播放通常是必需的。<video playsInline />

值得注意的是:使用 autoPlay 属性时,重要的是也包含 muted 属性以确保视频在大多数浏览器中自动播放,并包含 playsInline 属性以实现与 iOS 设备的兼容性。

有关视频属性的完整列表,请参阅 MDN 文档

视频最佳实践

  • 备用内容: 使用 <video> 标签时,在标签内包含备用内容,以便不支持视频播放的浏览器显示。
  • 字幕或说明: 为聋人或听力障碍用户提供字幕或说明。在 <video> 元素中使用 <track> 标签来指定字幕文件源。
  • 无障碍控件: 推荐使用标准 HTML5 视频控件,以支持键盘导航和屏幕阅读器兼容性。对于高级需求,可以考虑使用第三方播放器,如 react-playervideo.js,它们提供无障碍控件和一致的浏览器体验。

<iframe>

HTML <iframe> 标签允许你嵌入来自外部平台(如 YouTube 或 Vimeo)的视频。

app/page.jsx
export default function Page() {
  return (
    <iframe src="https://www.youtube.com/embed/19g66ezsKAg" allowFullScreen />
  )
}

常见的 <iframe> 标签属性

属性描述示例值
src要嵌入的页面的 URL。<iframe src="https://example.com" />
width设置 iframe 的宽度。<iframe width="500" />
height设置 iframe 的高度。<iframe height="300" />
allowFullScreen允许 iframe 内容以全屏模式显示。<iframe allowFullScreen />
sandbox对 iframe 内容启用额外的限制集。<iframe sandbox />
loading优化加载行为(例如,懒加载)。<iframe loading="lazy" />
title为 iframe 提供标题以支持无障碍访问。<iframe title="Description" />

有关 iframe 属性的完整列表,请参阅 MDN 文档

选择视频嵌入方法

你可以通过两种方式在 Next.js 应用程序中嵌入视频:

  • 自托管或直接视频文件: 在需要详细控制播放器功能和外观的场景中,使用 <video> 标签嵌入自托管视频。这种在 Next.js 中的集成方法允许对视频内容进行自定义和控制。
  • 使用视频托管服务(YouTube、Vimeo 等): 对于像 YouTube 或 Vimeo 这样的视频托管服务,你将使用 <iframe> 标签嵌入它们基于 iframe 的播放器。虽然这种方法对播放器的控制有限,但它提供了这些平台所提供的易用性和功能。

选择与你的应用程序需求和你希望提供的用户体验相符的嵌入方法。

嵌入外部托管的视频

要嵌入来自外部平台的视频,你可以使用 Next.js 获取视频信息,并使用 React Suspense 处理加载时的回退状态。

1. 创建用于视频嵌入的 Server Component

第一步是创建一个 Server Component,生成适合嵌入视频的 iframe。这个组件将获取视频的源 URL 并渲染 iframe。

app/ui/video-component.jsx
export default async function VideoComponent() {
  const src = await getVideoSrc()
 
  return <iframe src={src} allowFullScreen />
}

2. 使用 React Suspense 流式传输视频组件

创建用于嵌入视频的 Server Component 后,下一步是使用 React Suspense 流式传输组件。

app/page.jsx
import { Suspense } from 'react'
import VideoComponent from '../ui/VideoComponent.jsx'
 
export default function Page() {
  return (
    <section>
      <Suspense fallback={<p>Loading video...</p>}>
        <VideoComponent />
      </Suspense>
      {/* Other content of the page */}
    </section>
  )
}

值得注意的是:在嵌入外部平台的视频时,请考虑以下最佳实践:

  • 确保视频嵌入是响应式的。使用 CSS 使 iframe 或视频播放器适应不同的屏幕尺寸。
  • 根据网络条件实现视频加载策略,特别是对于数据流量有限的用户。

这种方法可以带来更好的用户体验,因为它防止页面阻塞,这意味着用户可以在视频组件流式传输时与页面交互。

为了提供更引人入胜且信息丰富的加载体验,可以考虑使用骨架屏作为回退 UI。因此,不是显示简单的加载消息,而是可以显示一个类似视频播放器的骨架屏,如下所示:

app/page.jsx
import { Suspense } from 'react'
import VideoComponent from '../ui/VideoComponent.jsx'
import VideoSkeleton from '../ui/VideoSkeleton.jsx'
 
export default function Page() {
  return (
    <section>
      <Suspense fallback={<VideoSkeleton />}>
        <VideoComponent />
      </Suspense>
      {/* Other content of the page */}
    </section>
  )
}

自托管视频

出于以下几个原因,自托管视频可能更可取:

  • 完全控制和独立性:自托管让你直接管理视频内容,从播放到外观,确保完全所有权和控制权,不受外部平台限制。
  • 满足特定需求的定制:适合独特需求,比如动态背景视频,它允许按照设计和功能需求进行定制。
  • 性能和可扩展性考虑:选择既高性能又可扩展的存储解决方案,以有效支持不断增加的流量和内容大小。
  • 成本和集成:平衡存储和带宽成本与需要轻松集成到 Next.js 框架和更广泛的技术生态系统的需求。

使用 Vercel Blob 进行视频托管

Vercel Blob 提供了一种高效的方式来托管视频,提供了一个可扩展的云存储解决方案,能够很好地与 Next.js 配合使用。以下是使用 Vercel Blob 托管视频的方法:

1. 将视频上传到 Vercel Blob

在 Vercel 仪表板中,导航到"Storage"选项卡并选择你的 Vercel Blob 存储。在 Blob 表格的右上角,找到并点击"Upload"按钮。然后,选择你希望上传的视频文件。上传完成后,视频文件将出现在 Blob 表格中。

或者,你可以使用服务器操作上传视频。有关详细说明,请参阅 Vercel 关于服务器端上传的文档。Vercel 还支持客户端上传。这种方法可能更适合某些使用场景。

2. 在 Next.js 中显示视频

一旦视频上传并存储好,你就可以在 Next.js 应用程序中显示它。以下是使用 <video> 标签和 React Suspense 实现的示例:

app/page.jsx
import { Suspense } from 'react'
import { list } from '@vercel/blob'
 
export default function Page() {
  return (
    <Suspense fallback={<p>Loading video...</p>}>
      <VideoComponent fileName="my-video.mp4" />
    </Suspense>
  )
}
 
async function VideoComponent({ fileName }) {
  const { blobs } = await list({
    prefix: fileName,
    limit: 1,
  })
  const { url } = blobs[0]
 
  return (
    <video controls preload="none" aria-label="Video player">
      <source src={url} type="video/mp4" />
      Your browser does not support the video tag.
    </video>
  )
}

在这种方法中,页面使用视频的 @vercel/blob URL 通过 VideoComponent 显示视频。React Suspense 用于在获取视频 URL 并准备好显示视频之前显示回退内容。

向视频添加字幕

如果你有视频的字幕,可以使用 <video> 标签内的 <track> 元素轻松添加它们。你可以以与视频文件类似的方式从 Vercel Blob 获取字幕文件。以下是如何更新 <VideoComponent> 以包含字幕。

app/page.jsx
async function VideoComponent({ fileName }) {
  const { blobs } = await list({
    prefix: fileName,
    limit: 2,
  })
  const { url } = blobs[0]
  const { url: captionsUrl } = blobs[1]
 
  return (
    <video controls preload="none" aria-label="Video player">
      <source src={url} type="video/mp4" />
      <track src={captionsUrl} kind="subtitles" srcLang="en" label="English" />
      Your browser does not support the video tag.
    </video>
  )
}

通过遵循这种方法,你可以有效地自托管视频并将其集成到 Next.js 应用程序中。

资源

要继续了解更多关于视频优化和最佳实践的信息,请参考以下资源:

  • 了解视频格式和编解码器:根据你的视频需求,选择合适的格式和编解码器,如 MP4 提供兼容性或 WebM 进行网络优化。有关更多详细信息,请参阅 Mozilla 的视频编解码器指南
  • 视频压缩:使用像 FFmpeg 这样的工具有效压缩视频,平衡质量和文件大小。在 FFmpeg 官方网站了解压缩技术。
  • 分辨率和比特率调整:根据观看平台调整分辨率和比特率,移动设备使用较低的设置。
  • 内容分发网络(CDN):利用 CDN 提高视频传输速度并管理高流量。使用某些存储解决方案时,如 Vercel Blob,CDN 功能会自动处理。了解更多关于 CDN 及其优势。

探索这些视频流媒体平台,将视频集成到你的 Next.js 项目中:

开源 next-video 组件

  • 为 Next.js 提供一个 <Video> 组件,兼容各种托管服务,包括 Vercel Blob、S3、Backblaze 和 Mux。
  • 有关使用 next-video.dev 与不同托管服务的详细文档

Cloudinary 集成

Mux Video API

Fastly

  • 了解更多关于将 Fastly 的点播视频和流媒体解决方案集成到 Next.js 中。

ImageKit.io 集成