Skip to main content

解决自动播放问题

浏览器对在没有用户互动的情况下播放音频的网站施加限制。 继续阅读,了解如何正确使用 Remotion 播放器,以避免遇到浏览器政策问题。

🌐 Browsers place restrictions on websites that play audio without user interaction.
Read on how to properly use the Remotion Player so you don't run into a browser policy.

最严格的浏览器是 Mobile Safari
如果你的作品在那里运行良好,其他地方应该也没有问题。

🌐 The most strict browser is Mobile Safari.
If your composition plays well there, you should have no problems elsewhere.

从用户事件触发播放

🌐 Trigger the play from a user event

如果你在网站加载时自动播放音频(通过 <Audio><Html5Audio><Video><OffthreadVideo><Html5Video> 标签),浏览器会阻止音频播放。

🌐 If you autoplay audio (through an <Audio>, <Html5Audio>, <Video>, <OffthreadVideo>, or <Html5Video> tag) on site load, browsers will block the audio.

因此,如果你的视频包含任何音频,不建议使用 <Player>autoPlay 属性。

🌐 The autoPlay prop of the <Player> is therefore discouraged if your video contains any audio.

显示一个 播放按钮 或者使用 controls 属性。

🌐 Display a play button instead or use the controls prop.

将事件传递给 play()toggle() 方法

🌐 Pass the event to the play() or toggle() method

如果你不使用默认控件,请确保对 .play() 的调用是由用户操作初始化的,例如鼠标点击。 你应该能从中获取一个 Javascript 事件,例如 MouseEvent。 将此事件传递给 play()toggle() 函数,以便音频可以自动播放。

🌐 If you don't use the default controls, make sure the call to .play() is initialized from a user gesture, for example a mouse click.
You should get a Javascript event like a MouseEvent from it.
Pass this event to the play() or toggle() function so audio may play automatically.

import {PlayerRef} from '@remotion/player';
import {useRef} from 'react';

export const App: React.FC = () => {
  const ref = useRef<PlayerRef>(null);

  return (
    <button
      onClickCapture={(e) => {
        const {current} = ref;
        // Pass the event to .play() or .toggle()
        current?.play(e);
      }}
    >
      Play
    </button>
  );
};
note

在 Safari 中,为了让事件传播正常工作,应该优先使用 onClickCapture 事件而不是 onClick 事件。

在开始后进入视频的媒体

🌐 Media that enters the video after the start

包含音频并能在无需用户互动的情况下播放的媒体需要特别注意。
请考虑以下情景:

🌐 Media that contains audio and that plays without user interaction requires special attention.
Consider the following scenario:

export const MyComp = () => {
  return (
    <AbsoluteFill>
      <Html5Audio src={staticFile('audio.mp3')} />
      <Sequence from={120}>
        <Html5Audio src={staticFile('audio2.mp3')} />
      </Sequence>
      <Sequence from={120}>
        <OffthreadVideo src={staticFile('video.mp4')} />
      </Sequence>
    </AbsoluteFill>
  );
};

这里有三种不同的情况:

🌐 There are three different cases here:

一个立即播放的 <Html5Audio> 标签。 ✅ 这是可以的,因为我们有用户互动。

一个在 120 帧后播放的 <Html5Audio> 标签。 ⚠️ 可能受浏览器自动播放政策影响,但有解决方法 → 使用 numberOfSharedAudioTags 属性

一个在 120 帧后播放的 <OffthreadVideo> 标签。 ⛔ 可能受浏览器自动播放政策限制,这可能会阻止带声音的视频播放 → 处理自动播放失败

使用 numberOfSharedAudioTags 属性

🌐 Using the numberOfSharedAudioTags prop

默认情况下,Remotion 将挂载 5 个辅助 <audio> 标签,这些标签会在第一次用户互动时“预热”。 如果在第一次用户互动后播放 <Html5Audio> 标签,它将被挂载到其中一个辅助标签中,并被允许播放。

🌐 By default, Remotion will mount 5 auxiliary <audio> tags that will "warm" up with the first user interaction.
If an <Html5Audio> tag is played after the first user interaction, it will be mounted into one of the auxiliary tags and will be allowed to play.

如果你同时播放超过 5 个 <Html5Audio> 标签,你可以通过向 <Player> 传递 numberOfSharedAudioTags 属性来增加辅助标签的数量,否则将会抛出错误。

🌐 If you have more than 5 <Html5Audio> tags that play at the same time, you can increase the number of auxiliary tags by passing the numberOfSharedAudioTags prop to the <Player>, because otherwise an error will be thrown.

处理自动播放失败v4.0.187

🌐 Dealing with an autoplay failurev4.0.187

如果浏览器因为视频有声音且没有由用户操作启动而阻止自动播放:

🌐 If the browser blocks a video from being autoplayed due to it having sound and not being started from a user interaction:

默认情况下:视频将被静音播放,不会有声音。控制台将打印一条消息。

自定义行为:你可以使用 <OffthreadVideo><Video>onAutoPlayError 属性来处理自动播放失败:

import {OffthreadVideo, staticFile} from 'remotion';
import type {PlayerRef} from '@remotion/player';

export const MyComp: React.FC<{
  playerRef: React.RefObject<PlayerRef>;
}> = ({playerRef}) => {
  return (
    <OffthreadVideo
      src={staticFile('video.mp4')}
      onAutoPlayError={() => {
        playerRef.current?.pause();
      }}
    />
  );
};

在此示例中,播放器只是暂停。 如果用户再次按下播放,视频可能会再次开始播放音频,因为它是通过用户交互启动的。

🌐 In this example, the Player is simply paused.
If the user presses Play again, the video may then start playing with audio again due to it being started with user interaction.

你可以展示一个带有提示的海报——例如“点击继续”。

🌐 You may show a poster with a hint - for example "Tap to resume".

浏览器什么时候会限制自动播放?

🌐 When will a browser restrict autoplay?

它并非完全确定性。

🌐 It is not entirely deterministic.

在使用用户手势播放视频之后,Safari 将允许在一段时间内播放更多媒体。 然而,WebKit 代码显示,这也取决于设备的省电模式或热量压力。

🌐 After playing a video with user gesture, Safari will allow more media to be played for some amount of time.
However, the WebKit code shows that it is also dependent on battery saver mode or thermal pressure on the device.

因此,最好尝试播放带有音频的视频,并优雅地处理失败情况。

🌐 Therefore, it is better to attempt to play the video with audio and handle the failure gracefully.