Developer Docs - Mobile Docs - Media Player

Mv6.0 Cv12.4

Inherits from Maui.CommunityToolkit.MediaElement

This versatile control lets you play audio and video files natively within your app. It offers a wide range of properties to customize the playback experience and includes expected OS-level features like fullscreen, picture-in-picture, TV casting, captions (when available), and more.

Elevate your content experience by integrating with Rock’s Media Accounts. When powered by a Media Element, the associated watch map unlocks features like analytics and cross-platform watch history—so users can start playback on one device and pick up right where they left off on another, as long as they're signed in.

When playing videos, it's recommended to provide the HLS format over a fixed resolution. This allows the player to determine the appropriate resolution based on network speed, so people with a slower connection aren't forced to buffer a high resolution video.

YouTube

You might assume you can use the native Media Player to play videos uploaded to YouTube, but that’s not possible due to platform restrictions. YouTube doesn’t provide the direct video source required by our player, as they maintain full control over playback through their own interface.

Uploading media content to YouTube is a great strategy for the audience there, however it's recommended to host videos elsewhere for the best integration with your digital platforms. If you sync these into Rock as Media Elements, you'll gain access to the analytics that Rock provides.

⚠️ YouTube Embeds and HTTP Referrer Requirement

As of October 2025, YouTube now requires an HTTP referrer for all embedded video playback.

Apps that embed YouTube videos directly in a WebView without a hosting context will experience blocked playback. This includes using <WebView Source="{{ videoUrl }}" /> with direct YouTube links. When the referrer is missing, YouTube will block playback and show Error 153.

This change is required by YouTube and cannot be bypassed with client-side logic. Any future YouTube embeds in Rock Mobile should use the pattern below to ensure consistent playback.

Solution

Hosted Page Example


  
  
    
  

Now, link to your hosted page instead of the video embed URL:
<WebView Source="https://yourdomain.com/embed.html" />

Properties

The Media Player received major updates in v6. While all existing properties from earlier versions should still function, they’re now considered deprecated.

Watch Map Properties

Mv2.0 Cv12.4

The easiest way to get data needed for a Watch Map is to use the AppendWatches filter.

Inherited Properties

These properties are inherited from the control we built on top of. You can view a full list of the supported properties here, although we've trimmed down this documentation to only have the ones of interest.  

Examples

A simple player with Source defined:


Inclusion of the WatchMap object and some properties:


  
      
  

This example shows how to pull the Watch Map data directly via SQL, if the AppendWatches filter in Lava isn't a good fit (uncommon).


    {% mediaelement id:'1' %}
        {% assign interactionGuid = null %}
        {% assign watchMap = null %}
        {% if CurrentPerson and CurrentPerson != null %}
            {% sql personId:'{{ CurrentPerson.Id }}' mediaId:'{{ mediaelement.Id }}' %}
SELECT TOP 1
[I].[Guid],
[I].[InteractionData]
FROM [Interaction] AS [I]
INNER JOIN [InteractionComponent] AS [IComp] ON [IComp].[Id] = [I].[InteractionComponentId]
INNER JOIN [InteractionChannel] AS [IChan] ON [IChan].[Id] = [IComp].[InteractionChannelId]
INNER JOIN [PersonAlias] AS [PA] ON [PA].[Id] = [I].[PersonAliasId]
WHERE [IChan].[Guid] = 'D5B9BDAF-6E52-40D5-8E74-4E23973DF159'
  AND [PA].[PersonId] = @personId
  AND [IComp].[EntityId] = @mediaId
  AND [I].[InteractionDateTime] >= DATEADD(DAY, -7, GETDATE())
ORDER BY [I].[InteractionDateTime] DESC
            {% endsql %}
            {% assign result = results | First %}
            {% if result != null %}
                {% assign interactionGuid = result.Guid %}
                {% assign watchMap = result.InteractionData | FromJSON | Property:'WatchMap' %}
            {% endif %}
        {% endif %}
        
            
                
            
        
    {% endmediaelement %}