跳至内容

视频优化

此页面概述了如何在 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 属性以确保视频在大多数浏览器中自动播放,并为 iOS 设备兼容性包含 playsInline 属性。

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

视频最佳实践

  • 备用内容:使用<video>标签时,在标签内包含备用内容,以供不支持视频播放的浏览器使用。
  • 字幕或隐藏式字幕:为听力障碍用户提供字幕或隐藏式字幕。利用<track>标签以及您的<video>元素来指定字幕文件源。
  • 可访问的控件:建议使用标准的HTML5视频控件,以实现键盘导航和屏幕阅读器兼容性。对于高级需求,可以考虑使用第三方播放器,例如react-playervideo.js,它们提供可访问的控件和一致的浏览器体验。

<iframe>

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

app/page.jsx
export default function Page() {
  return (
    <iframe
      src="https://www.youtube.com/watch?v=gfU1iZnjRZM"
      frameborder="0"
      allowfullscreen
    />
  )
}

常见的<iframe>标签属性

属性描述示例值
src要嵌入的页面的URL。<iframe src="https://example.com" />
width设置iframe的宽度。<iframe width="500" />
height设置iframe的高度。<iframe height="300" />
frameborder指定是否在iframe周围显示边框。<iframe frameborder="0" />
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. 为视频嵌入创建服务器组件

第一步是创建一个服务器组件,用于生成用于嵌入视频的适当iframe。此组件将获取视频的源URL并呈现iframe。

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

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

创建用于嵌入视频的服务器组件后,下一步是使用流式传输组件,并使用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仪表板中,导航到“存储”选项卡并选择您的Vercel Blob存储。在Blob表右上角,找到并点击“上传”按钮。然后,选择要上传的视频文件。上传完成后,视频文件将显示在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 用于 Web 优化。有关更多详细信息,请参阅Mozilla 的视频编解码器指南
  • 视频压缩:使用 FFmpeg 等工具有效地压缩视频,在质量和文件大小之间取得平衡。在FFmpeg 官方网站上了解压缩技术。
  • 分辨率和比特率调整:根据观看平台调整分辨率和比特率,对于移动设备使用较低的设置。
  • 内容分发网络 (CDN):利用 CDN 提高视频交付速度并管理高流量。当使用某些存储解决方案(例如 Vercel Blob)时,CDN 功能会自动为您处理。了解更多有关 CDN 及其优势的信息。

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

开源next-video组件

Cloudinary 集成

Mux 视频 API

Fastly

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

ImageKit.io 集成