How to Integrate YouTube video in Blazor WebAssembly (wasm) using Video.js

In this post, we are going to look into how we can integrate YouTube video for playback in Blazor WebAssembly application using the popular Video.js JavaScript library.

Blazor lets you add interactivity to your website using C#, Razor, HTML and CSS instead of the defacto JavaScript. It encourages code reusability by allowing you share code on both client and server side. With the rich amount of JavaScript libraries out there, we sometimes feel the need to make use of those libraries instead of re-inventing the wheel.

Video.js is a JavaScript library for video and audio with great amount of features. In this post, we will be working with this library in Blazor wasm with JSInterop.

Let's Get Started

Let's create a new Blazor wasm project with the dotnet cli

dotnet new blazorwasm -o BlazorVideoJs

After the project is done creating, open it in your preferred IDE. I will be using Visual Studio Code. We're going to add the video.js required scripts and stylesheet to the index.html. Open wwwroot/index.html. First, we're going to add the stylesheet. Add the below code before the the <head/> element.

1<link href="https://vjs.zencdn.net/7.10.2/video-js.css" rel="stylesheet" />

Next, add the following script files after the blazor.webassembly.js script file.

1<script src="https://vjs.zencdn.net/7.10.2/video.js"></script>
2
3<!-- video.js plugin for YouTube support -->
4<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-youtube/2.6.1/Youtube.min.js"></script>

Our next action is to create a new js file inside the wwwroot folder, name it whatever you like, I'll name mine player.js. We'll write a wrapper function to initialize the Video.js player. Copy and paste the code below into the js file you created.

1function loadPlayer(id, options) {
2  videojs(id, options);
3}

You might wonder why write a wrapper function, why not call the function videojs(id, options) directly from IJSRuntime invoke method?. Unfortunately, going that route didn't work for me. Blazor seems to have rendering issues when called that way.

Add player.js before the <body/> tag of wwwroot/index.html file

Your index.html should look like this.

 1<!DOCTYPE html>
 2<html>
 3  <head>
 4    <meta charset="utf-8" />
 5    <meta
 6      name="viewport"
 7      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
 8    />
 9    <title>BlazorVideoJs</title>
10    <base href="/" />
11    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
12    <link href="css/app.css" rel="stylesheet" />
13    <link href="BlazorVideoJs.styles.css" rel="stylesheet" />
14    <link href="https://vjs.zencdn.net/7.10.2/video-js.css" rel="stylesheet" />
15  </head>
16
17  <body>
18    <div id="app">Loading...</div>
19
20    <div id="blazor-error-ui">
21      An unhandled error has occurred.
22      <a href="" class="reload">Reload</a>
23      <a class="dismiss">🗙</a>
24    </div>
25    <script src="_framework/blazor.webassembly.js"></script>
26    <script src="https://vjs.zencdn.net/7.10.2/video.js"></script>
27
28    <!-- video.js plugin for YouTube support -->
29    <script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-youtube/2.6.1/Youtube.min.js"></script>
30    <script src="./player.js"></script>
31  </body>
32</html>

Create a new Blazor component in Pages/Player.razor. As the name suggests, our player component will be created here. Replace the Player.razor code with the following

 1@page "/player" @inject IJSRuntime jsRuntime
 2
 3<h3>Player</h3>
 4
 5<div class="row align-items-center">
 6  <div class="col-8">
 7    <video id="my-player" controls class="video-js"></video>
 8  </div>
 9</div>
10
11@code { }

Our major point of interest in the markup above is the video element. This is where our YouTube video will be displayed when we initialized Video.js

Video.js supports all attributes of the <video> element (such as controls, preload, etc), but it also supports its own options. There are two ways to create a Video.js player and pass it options, but they both start with a standard <video> element with the attribute class="video-js"

Paste the code below inside the Player.razor code block

 1protected override async Task OnAfterRenderAsync(bool firstRender)
 2    {
 3        if (firstRender)
 4        {
 5            await jsRuntime.InvokeVoidAsync("loadPlayer", "my-player", new
 6            {
 7                controls = true,
 8                autoplay = false,
 9                preload = "auto",
10                width = 560,
11                height = 264,
12                techOrder = new[] { "youtube" },
13                sources = new[] {
14                        new { type =  "video/youtube", src = "https://www.youtube.com/watch?v=xjS6SftYQaQ"}
15                }
16            });
17        }
18    }

In the code above, we're using the manual setup to initialize the Video.js player for the specified YouTube video inside Blazor's OnAfterRenderAsync(bool firstRender) lifecycle.

Our application is ready for a test drive. Run the application and navigate to {baseUrl}/player. If everything works out good, you should be able to play the video on the page and your page should look like this.

Video.js YouTube Player in Blazor

The example project for this post is available here

comments powered by Disqus