Set up video playback

We use the Electra Media Player plugin for media playback. Electra is Epic's native, cross-platform media player that supports local file playback of .mp4, .mkv, and .mov files as well as internet streaming - with no additional transcoding tools required.

Read more about Electra Media Playerhttps://dev.epicgames.com/documentation/en-us/unreal-engine/electra-media-player-in-unreal-engine

Electra supports a range of codecs, and we encourage testing different options to find the right balance of performance, file size, and load time for your specific use case. The table below summarises the supported codecs and their characteristics.

Format

Container

Alpha support

Notes

HAP

.mov

No

GPU-decoded, intra-frame. Best overall performance for large files based on Pixotope testing

HAP Alpha

.mov

Yes

GPU-decoded, intra-frame. Best overall performance for large files based on Pixotope testing. This variation supports Alpha channel.

Apple ProRes 444

.mov

Yes

Intra-frame with alpha. High quality but higher decode cost than HAP Alpha

Apple ProRes 422 HQ

.mov

No

Intra-frame, high quality. Good performance, larger files than HAP

H.264 / AVC

.mp4

No

Inter-frame (GOP). Higher decode cost; much higher compression (smaller files) than Intra-frame codecs, but heavier decode cost

H.265 / HEVC

.mp4

No

Inter-frame (GOP). Smaller files than H.264 but heavier decode cost

Pixotope recommendation: Based on our extensive testing, HAP and HAP Alpha deliver the best playback performance when loading and playing larger files in real-time virtual production contexts. HAP is GPU-decoded and uses intra-frame compression, which eliminates GOP overhead and offloads decode work from the CPU - resulting in lower latency and more headroom for the rest of the Pixotope pipeline.

We recommend starting with HAP and benchmarking against your specific content before selecting a final codec.

For best real-time performance with any intra-frame codec, store video files on a fast local NVMe drive to sustain the required read throughput.

Enable the required plugins

The following Engine plugins are required depending on the codec you intend to use. All ship with Pixotope Engine and need to be enabled in your project.

  1. Open the Pixotope project in the Unreal Editor

  2. Go to Edit > Plugins

  3. Search for and enable the relevant plugins:

Plugin

Required for

Electra Media Player

All codecs - core media player enabling local file and streaming playback

HAP Decoder for Electra

HAP and HAP Alpha playback

Apple ProRes Decoder for Electra

ProRes 422 HQ and ProRes 4444 playback

D3D12 Hardware Accelerated Video Decoding for Electra

All codecs - offloads video decoding to the GPU via D3D12 for improved real-time performance

  1. Restart the Editor when prompted

Screenshot 2026-06-29 at 14.35.46.png

The D3D12 hardware decoding plugin requires a compatible GPU and Windows 10 or later. If decoding issues occur, disable this plugin and fall back to software decoding.

Create a File Media Source asset

The File Media Source asset tells the Engine where to find the video file at runtime.

  1. Right-click inside the Content Browser

  2. Navigate to Media > File Media Source and create a new asset - name it, for example, FMS_MyVideo

  3. Open the asset and set

    1. Player Overrides > Windows > Electra Player

    2. File Path to the full system path of your video file, e.g.: D:\Media\Videos\MyVideo.mov

Screenshot 2026-06-29 at 14.39.48.png
Screenshot 2026-06-29 at 14.41.54.png

You can also change the file path at runtime via Blueprint, which makes it easy to swap video sources without modifying the asset. See the Load a video file at runtime section below.

Create a Media Player asset

  1. Right-click inside the Content Browser

  2. Navigate to Media > Media Player and create a new asset - name it, for example, MP_MyVideo

  3. In the creation dialog, make sure Create Media Texture is checked - this will automatically generate a linked MP_MyVideo_Video Media Texture asset. We recommend to rename this to MT_MyVideo

  4. Open the Media Player asset

  5. Enable Play on Open if you want the video to start automatically when the source is opened

  6. Enable Loop if the video should repeat

  7. To test the media player, double-click on the File Media Source created in the previous step, FMS_MyVideo in the browser at the bottom of the Media Player window

Screenshot 2026-06-29 at 14.43.12.png
Screenshot 2026-06-29 at 14.43.22.png
Screenshot 2026-06-29 at 14.45.29.png
Screenshot 2026-06-29 at 14.48.43.png

You need one Media Player asset per video stream.

Visualize video playback in the virtual scene

The Media Texture linked to a Media Player asset contains the decoded video frames and can be applied to any element in the virtual scene. It is most commonly used to simulate virtual monitors by applying it to a Plane actor, but it works on any mesh or surface.

There are two ways to display the video in the scene, each with different visual characteristics. Choose the one that best fits how the virtual monitor will appear in your shots.


Material

Media Input component

Anti-Aliasing (TAA)

Affected

Not affected

Depth of Field

Affected — focuses and defocuses with the rest of the scene according to lens information

Not affected

Best for

Virtual monitors that need to integrate naturally into the scene, matching the lens behaviour of surrounding elements

Virtual monitors where fidelity to the original recorded image is the priority

💡 If the virtual monitor will be positioned so that it naturally focuses and defocuses with the rest of the scene, the Material approach will give the most seamless integration. If the monitor is always in focus or in the foreground and reproducing the original recorded image accurately is the priority, use the Media Input component.

Option 1 — Use the Media Texture in a Material

This approach integrates the video into the standard Unreal rendering pipeline. The virtual monitor will be affected by Anti-Aliasing and Depth of Field, making it behave like any other element in the scene. This is the best choice when the monitor needs to feel naturally embedded in the virtual environment.

  1. Locate the Media Texture asset linked to your Media Player (e.g. MT_MyVideo)

  2. Open an existing material or create a new one and add a Texture Sample node

  3. Assign MT_MyVideo to the Texture Sample node

  4. Drag a Material Function node into the Material Graph and set it to ExposureCompensate3

  5. Connect the RGB output of the Texture Sample into the input pin of ExposureCompensate3

  6. Connect the Result output of ExposureCompensate3 into the Emissive Color input pin of the Material node

  7. Click on the Material node and, in the Details panel on the bottom left, find Shading Model and set it to Unlit

  8. Apply the material to your Plane actor or mesh in the scene

  9. Adjust the scale of the mesh to match the video's aspect ratio

Screenshot 2026-07-03 at 14.49.00.png

Option 2 — Use a Media Input component

This approach bypasses the standard rendering pipeline for the video surface, giving the video higher fidelity by avoiding Anti-Aliasing processing. The trade-off is that the virtual monitor will not be affected by Depth of Field. This is the best choice when reproducing the original recorded image as accurately as possible is the priority — for example, for a monitor that is always in focus and in the foreground.

  1. Select the Plane actor (or preferred mesh) in the scene

  2. In the Details panel, click Add and search for Media Input — add the Media Input component to the actor

Screenshot 2026-07-03 at 18.31.44.png
  1. Select the Media Input component in the Details panel

  2. Under Source Selection, choose Debug

  3. In the Debug Texture property that appears, drag and drop the MT_MyVideo Media Texture asset

  4. If the mesh is a flat surface (e.g. a Plane), enable the Unjittered Projection checkbox

Screenshot 2026-07-03 at 18.31.24.png

Create a Blueprint to control playback

  1. Right-click in the Content Browser, select Blueprint Class, choose Actor as the parent class, and name it - for example, BP_VideoPlayer

  2. Inside the Blueprint, create a Media Player Object Reference variable:

    • Click + in the My Blueprint panel to add a new variable

    • Set the variable type to Media Player > Object Reference

    • Name it MediaPlayer

    • Click the eye icon to make it instance-editable, then Compile

  3. Create a File Media Source Object Reference variable the same way - name it MediaSource

  4. Create a String variable and name it FilePath. This will allow you to set a different path to a file externally and load that file from the blueprint

  5. Drag the Blueprint into the level, select it, and in the Details panel assign:

    • Your MP_MyVideo Media Player asset to the MediaPlayer variable

    • Your FMS_MyVideo File Media Source asset to the MediaSource variable

Screenshot 2026-06-29 at 15.04.12.png
Screenshot 2026-06-29 at 15.05.01.png

Add Blueprint events

Load a video file at runtime

The LoadFile custom event allows you to change the video file being played at runtime without stopping or restarting the Media Player. It takes a file path as input, updates the Media Source asset with the new path, and then opens it asynchronously - ensuring the source is fully ready before playback begins.

This is the recommended way to switch video files dynamically, for example when driven by a Dropdown or Playlist widget in the Control panel.

Create the event

  1. In the Event Graph, right-click and add a Custom Event - name it LoadFile

Set the file path on the Media Source

  1. Drag your MediaSource variable into the graph to get a reference to it

  2. Drag off the MediaSource pin and search for Set File Path

  3. Connect the LoadFile execution pin to Set File Path

  4. Wire the File Path input parameter to the Path pin on Set File Path

Open the source asynchronously

  1. Drag your MediaPlayer variable into the graph to get a reference to it

  2. Drag off the Set File Path execution pin and search for Open Source Latent

  3. Wire the MediaSource variable to the Media Source pin on Open Source Latent

  4. Wire the MediaPlayer variable to the Target pin on Open Source Latent

  5. In the Open Source Latent node, configure the options:

    • Options Play on OpenDisabled - the video will not start automatically after loading; trigger playback separately using your Play custom event

    • Options LoopEnabled - the video will loop continuously once playback starts

Screenshot 2026-06-29 at 15.25.08.png

How to use it

Once the Blueprint is compiled and placed in the level, you can drive LoadFile from the Control panel by selecting BP_VideoPlayer in the Engine browser tab and dragging the LoadFile function onto the canvas.

Play and Pause custom events

  1. Right-click in the graph, add a Custom Event and name it Play - wire it to a Play node targeting MediaPlayer

  2. Add another Custom Event named Pause - wire it to a Pause node targeting MediaPlayer

Screenshot 2026-06-29 at 15.57.28.png

Example blueprints for more advanced controls

Use these patterns for more advanced controls like playing from a specific time or changing the video source at runtime.

Play from a specific time
  1. Add a Custom Event named PlayFromTime with a Float input parameter named TimeInSeconds

  2. Wire it to Seek (target: MediaPlayer) followed by Play

  3. Use a From Seconds node to convert TimeInSeconds into a Timespan value and wire it to the Time input in the Seek node.

Screenshot 2026-06-29 at 15.57.33.png

Control the video playback via a control panel

  1. Create a new control panel

  2. Select the BP_VideoPlayer object in the Engine Browser tab

  3. Drag the functions (custom events) created in the previous section onto the canvas and select the desired widgets for each of them

Screenshot 2026-06-29 at 16.04.10.png

Set up synchronized video playback

Learn more about how to Set up synchronized video playback