Embedding a <Player> into an <iframe>
info
Credit to @marcusstenbeck for creating this snippet.
This snippet is useful if you want to isolate the global styles of your homepage from the global styles of the <Player>.
Usagediff- import { Player } from '@remotion/player';+ import { IframePlayer } from 'path/to/IframePlayer';- <Player {/* ... */} />+ <IframePlayer {/* ... */} />
IframePlayer.tsxtsximport { Player, PlayerProps, PlayerRef } from"@remotion/player";import React, { forwardRef, useEffect, useRef, useState } from"react";import ReactDOM from"react-dom";import { AnyZodObject } from"zod";constclassName="__player";constborderNone:React.CSSProperties= {border: "none",};constIframePlayerWithoutRef= <TextendsRecord<string, unknown>>(props:PlayerProps<AnyZodObject, T>,ref:React.Ref<PlayerRef>) => {const [contentRef, setContentRef] =useState<HTMLIFrameElement|null>(null);constresizeObserverRef=useRef<ResizeObserver|null>(null);constmountNode= contentRef?.contentDocument?.body;useEffect(() => {if (!contentRef ||!contentRef.contentDocument) return;// Remove margin and padding so player fits snuglycontentRef.contentDocument.body.style.margin ="0";contentRef.contentDocument.body.style.padding ="0";// When player div is resized also resize iframeresizeObserverRef.current =newResizeObserver(([playerEntry]) => {constplayerRect= playerEntry.contentRect;contentRef.width =String(playerRect.width);contentRef.height =String(playerRect.height);});// The remotion player elementconstplayerElement= contentRef.contentDocument.querySelector("."+ className);if (!playerElement) {thrownewError('Player element not found. Add a "'+className +'" class to the <Player>.');}// Watch the player element for size changesresizeObserverRef.current.observe(playerElement asElement);return () => {// ContentRef changed: unobserve!(resizeObserverRef.current asResizeObserver).unobserve(playerElement asElement);};}, [contentRef]);constcombinedClassName=`${className} ${props.className??""}`.trim();return (// eslint-disable-next-line @remotion/warn-native-media-tag<iframeref={setContentRef} style={borderNone}>{mountNode &&ReactDOM.createPortal(// @ts-expect-error PlayerProps are incorrectly typed<Player<AnyZodObject, T>{...props}ref={ref}className={combinedClassName}/>,mountNode)}</iframe>);};exportconstIframePlayer=forwardRef(IframePlayerWithoutRef);