{"record":{"id":"930345a2aa6108c4","repo":"remotion-dev/remotion","slug":"usemediaplayback-must-be-used-inside-a-bufferingc","errorCode":null,"errorMessage":"useMediaPlayback must be used inside a <BufferingContext>","messagePattern":"useMediaPlayback must be used inside a <BufferingContext>","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/core/src/use-media-playback.ts","lineNumber":70,"sourceCode":"\tpauseWhenBuffering: boolean;\n\tisPremounting: boolean;\n\tisPostmounting: boolean;\n\tonAutoPlayError: null | (() => void);\n}) => {\n\tconst {playbackRate: globalPlaybackRate} = usePlaybackRate();\n\tconst frame = useCurrentFrame();\n\tconst absoluteFrame = useTimelinePosition();\n\tconst [playing] = usePlayingState();\n\tconst buffering = useContext(BufferingContextReact);\n\tconst {fps} = useVideoConfig();\n\tconst mediaStartsAt = useMediaStartsAt();\n\tconst lastSeekDueToShift = useRef<number | null>(null);\n\tconst lastSeek = useRef<number | null>(null);\n\tconst logLevel = useLogLevel();\n\tconst mountTime = useMountTime();\n\n\tif (!buffering) {\n\t\tthrow new Error(\n\t\t\t'useMediaPlayback must be used inside a <BufferingContext>',\n\t\t);\n\t}\n\n\tconst isVariableFpsVideoMap = useRef<Record<string, boolean>>({});\n\n\tconst onVariableFpsVideoDetected = useCallback(() => {\n\t\tif (!src) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (isVariableFpsVideoMap.current[src]) {\n\t\t\treturn;\n\t\t}\n\n\t\tLog.verbose(\n\t\t\t{logLevel, tag: null},\n\t\t\t`Detected ${src} as a variable FPS video. Disabling buffering while seeking.`,","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/use-media-playback.ts#L52-L88","documentation":"useMediaPlayback reads the BufferingContextReact context and throws if it is null. The provider is installed by Remotion's internal <BufferingContext> wrapper (set up by wrap-remotion-context / the Player and Studio trees). Seeing this means an Audio/Video media component is rendering outside that provider tree — typically because useMediaPlayback was called directly, or a media tag was rendered without the Remotion context wrapper.","triggerScenarios":"Calling the internal useMediaPlayback hook directly in user code; rendering <AudioForPreview>/<VideoForPreview> (or Audio/Video in preview mode) without the buffering provider; multiple Remotion versions so the provider from one version does not satisfy the consumer from another; unit tests mounting media components without the test harness providers.","commonSituations":"Duplicate @remotion/core installations (context identity mismatch); importing internal preview components and using them standalone; test setups missing <RemotionRoot>/buffering providers; bundler misconfiguration that splits Remotion into two copies.","solutions":["Do not call useMediaPlayback directly — use the public <Audio>/<Video> components, which set up the provider themselves.","Deduplicate Remotion: run `npm ls @remotion/core` and ensure a single resolved version; add an override/resolutions field if needed.","In tests, wrap the component under test in the Remotion test providers (see packages/core/src/test helpers using BufferingProvider).","If you forked a preview component, re-wrap it in <BufferingContextReact.Provider>."],"exampleFix":"// before (test)\nrender(<Video src={url} />);\n\n// after\nrender(\n  <BufferingProvider>\n    <Video src={url} />\n  </BufferingProvider>\n);","handlingStrategy":"validation","validationCode":"// Do not call useMediaPlayback directly. Use the public <Audio>/<Video> components.\n// If testing, ensure a single Remotion version is installed:\n// `npm ls @remotion/core` should list one resolved version.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat useMediaPlayback as internal — never import it from user code.","Keep a single @remotion/core version across the whole monorepo (use package overrides/resolutions).","In tests, use the Remotion test wrappers (BufferingProvider) rather than mounting media components bare."],"tags":["remotion","context","buffering","media","version-mismatch"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}