Skip to main content

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>.

Usage
diff
- import { Player } from '@remotion/player';
+ import { IframePlayer } from 'path/to/IframePlayer';
- <Player {/* ... */} />
+ <IframePlayer {/* ... */} />
IframePlayer.tsx
tsx
import { 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 snugly
contentRef.contentDocument.body.style.margin ="0";
contentRef.contentDocument.body.style.padding ="0";
// When player div is resized also resize iframe
resizeObserverRef.current =newResizeObserver(([playerEntry]) => {
constplayerRect= playerEntry.contentRect;
contentRef.width =String(playerRect.width);
contentRef.height =String(playerRect.height);
});
// The remotion player element
constplayerElement= contentRef.contentDocument.querySelector(
"."+ className
);
if (!playerElement) {
thrownewError(
'Player element not found. Add a "'+
className +
'" class to the <Player>.'
);
}
// Watch the player element for size changes
resizeObserverRef.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);

See also

AltStyle によって変換されたページ (->オリジナル) /