Gamesmithing: Getting Unity's VideoPlayer to work in WebGL builds

An image of the author.

Welcome to another edition of Gamesmithing! Today I'm breaking down a problem that's plagued me for the past week: the video file I was trying to play in a WebGL build wasn't working. It was just displaying a sad black square. It worked perfectly fine from the editor, but did not play once you deployed to a local or remote host.

(Side tip: if you want to run a local server to test one of Unity's WebGL build, it's very simple with python. Launch a commnad prompt from the build folder you choose in Unity. Use the command "python -m http.server <PORT_NUMBER>" and then go to the address "localhost:<PORT_NUMBER>/index.html" in your browser. Easy peasy.)

Since this isn't a post that's SEO'ed to oblivion, I’m immediately revealing the trick that worked for me: under the VideoPlayer object, change the RenderMode attribute from "Camera Far Plane" to "Render Texture". Props to Threattec on this comment thread for keying me into the answer.

Now, some background info. This was using Unity 2020.3.23f1 in the WebGL build form. The video was already hosted online at a static address as a .m4v file by Armor Games. I didn't have control over the video-hosting or over the (eventual) hosting of this build of my game. I had previously set up an "attract mode" for a convention demo - think of an arcade "Insert Coin to Start" screen with a preview playing in the background and you won't be far off. I already had VideoRenderTexture and VideoPlayer objects ready and working because of that.

When I was looking online for solutions to the problems, it seemed like this issue has plagued a lot of people. There’s a lot of reasons why it broke for different people. To be helpful, I'm listing off things that other people suggested but didn’t work for me. Maybe one will help you out.

1) Press F12 in the browser to open the developer console. I didn't get any errors in the debug console, but I did get two warnings: "WebGL warning: tex(Sub)Image[23]D: Resource has no data (yet?). Uploading zeros." and "WebGL warning: drawElementsInstanced: TEXTURE_2D at unit 0 is incomplete: The dimensions of `level_base` are not all positive." You can also see if the HTTP requests come back with any errors from here.
2) Try it out in different browsers: Chrome, Firefox, and Edge
3) Upgrade your version of Unity. I went from 2019.3.0f6 to 2020.3.23f1
4) I originally had the video as an asset in my project and the Source attribute of my VideoPlayer set to "Video Clip". I moved the video file into a new folder named StreamingAssets and changed the VideoPlayer.Source to URL and set the VideoPlayer.URL to Path.Combine(Application.streamingAssetsPath, "intro.m4v") in a script. No bueno. Changing the URL to the static URL address was needed to get it working.
5) Transcoding the video to different encodings (.ogg or .webm) within Unity when it was a a project asset (instead of a remote URL).
6) I read up on CORS errors [link: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin], but concluded they shouldn't affect me. Even when the game was uploaded to the same site that hosted the intro video, I still ran into problems.
7) Added a "Click to start" screen to the game. Browsers these days don't take kindly to websites sneakily autoplaying videos, so they require the user to click on the video element before starting to play the video. (If you mute the video before playing, most browsers allow the autoplay.) I did need to include this screen in my eventual solution, as my video needed to play sound.

It's a short article, and certainly a very specific one. However, I spent a week figuring this out. I feel better if this saves at least one other game dev some debugging time.