I am attempting to play a video into a RenderTexture more than once and it does not seem to work in WebGL/WASM. I have a UI Panel which includes a Raw Image and a Video Player component. The Video Player has a valid URL on it. I then have the following script attached in the scene as well: Code (CSharp): public class VideoStuff : MonoBehaviour { public VideoPlayer vidPlayer; RenderTexture renderTexture; void PlayVideo() { if (renderTexture==null) renderTexture = new RenderTexture(350, 300, 24); RawImage img = vidPlayer.gameObject.GetComponent<RawImage>(); img.texture = renderTexture; vidPlayer.renderMode = UnityEngine.Video.VideoRenderMode.RenderTexture; vidPlayer.targetTexture = renderTexture; vidPlayer.Play(); } // Update is called once per frame void Update () { if (Input.GetKeyDown(KeyCode.V)) PlayVideo(); if (Input.GetKeyDown(KeyCode.S)) vidPlayer.Stop(); } } As you can see, a RenderTexture is dynamically created and then reused on subsequent playing of the video. This works fine in the editor and it works great in WebGL, once. If the video is started again, the RenderTexture doesn't change (it's as if the video is paused but the audio plays correctly). I have also tried creating a NEW RenderTexture each time and this simply renders a black screen where the video should be. Any ideas? Thanks much.
This solved my problem with the video player + webgl - I tested this and it works - https://forum.unity.com/threads/videoplayer-webgl-url-not-working.467391/ Place an htaccess file with the code as described in the link above next to the video on the server
Thanks but this is not a server or CORS issue. The video plays fine once (thus its not an access problem). It is on any subsequent plays when the problem occurs. I have discovered that it works fine if the Video Player is destroyed and then recreated (.Stop() doesnt cut it). However, I have still had some strange errors doing so in WebAssembly. Im working on a simple, reproducible case to submit as a bug report. But still, we shouldnt have to recreate a Video Player each time, should we?
Hi sirrus, did you find a solution? My project in Unity 2018.2.0f2 is showing the same issue: the video plays fine once, then a black screen is shown (only in WebGL build not in EDITOR)
I'm afraid it looks like a Unity bug: https://issuetracker.unity3d.com/is...and-subsequent-times-the-screen-doesnt-render My solution was to build a YouTube player overlay in HTML.
To hopefully add more light, we seem to encounter this issue or at least one similar in Edge 40, not Firefox or Chrome which play our videos fine. The .mp4 video is in the StreamingAssets folder on the same server as our content.
Make a script that does, Destroy(videoPlayerComponent) -> AddComponent<VideoPlayer> -> configure it to your needs -> Play() Unity's VideoPlayer component has been quite an annoyance to work with since it was implemented(5.6), so many bugs in there.
Here's some plugin (jslib) code. It requires that you have a DOM element called "vid_overlay" that is styled to be positioned in front of the Unity player canvas. Code (JavaScript): /* A pretty basic JS plugin for handling a YouTube video overlay in WebGL. It requires a div (or iframe) element called "vid_overlay" that is positioned in front of the Unity canvas. */ var YouTubeVideoInteraction = { LoadYouTubeAPI__deps: ['onYouTubePlayerAPIReady'], LoadYouTubeAPI: function () { // Load the IFrame Player API code asynchronously. var tag = document.createElement('script'); tag.src = "https://www.youtube.com/player_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); this.ytPlayer = null; }, // register the callbacks as dependencies for emscripten ShowVideo__deps: ['onPlayerReady', 'onPlayerStateChange', 'OnVideoComplete','checkVideoCompletion'], ShowVideo: function (video_id, video_length) { var videoIdAsString = Pointer_stringify(video_id); // hide your unity canvas here // hideUnity(); this.videoId = videoIdAsString; this.videoLength = video_length; this.checkedTime = false; if (this.ytPlayer != null) { document.getElementById('vid_overlay').style.display = 'block'; this.ytPlayer.loadVideoById({ videoId: videoIdAsString, endSeconds: video_length }); } else // new player this.ytPlayer = new YT.Player('vid_overlay', { height: 700, width: 600, playerVars: { 'autoplay': 1, 'controls': 0, 'color': 'white', 'showinfo': 0, 'rel': 0, 'end': video_length }, events: { 'onStateChange': _onPlayerStateChange, 'onReady': _onPlayerReady }, videoId: videoIdAsString }); }, onYouTubePlayerAPIReady: function () { // console.log('yt api ready'); }, onPlayerReady: function (e) { // show the video overlay element document.getElementById('vid_overlay').style.display = 'block'; }, onPlayerStateChange: function (e) { if (e.data) { var duration = this.ytPlayer.getCurrentTime(); var endTime = this.videoLength > 0 ? this.videoLength : this.ytPlayer.getDuration(); // since the YouTube API doesn't always register a "video end" event, we have to routinely check to see if the video is over if (e.data == 1) { if (!this.checkedTime) if (this.videoLength == 0) // no end time defined { setTimeout(_checkVideoCompletion, 1000); this.checkedTime = true; } } if (e.data == 0) _OnVideoComplete(); else if (duration > 0 && endTime > 0 && duration >= endTime) _OnVideoComplete(); } }, checkVideoCompletion: function () { var duration = this.ytPlayer.getCurrentTime(); var endTime = this.videoLength > 0 ? this.videoLength : this.ytPlayer.getDuration(); if (duration > 0 && endTime > 0 && duration >= endTime) _OnVideoComplete(); else setTimeout(_checkVideoCompletion, 1000); }, OnVideoComplete: function () { // hide the video overlay element and reshow the Unity canvas document.getElementById('vid_overlay').style.display = 'none'; // showUnity(); // send message back to Unity player here } }; mergeInto(LibraryManager.library, YouTubeVideoInteraction); Then in some video player component: Code (CSharp): public class VideoThing : MonoBehaviour { [DllImport("__Internal")] private static extern void LoadYouTubeAPI(); [DllImport("__Internal")] private static extern void ShowVideo(string video_id, int video_length); void Awake() { LoadYouTubeAPI(); } void PlayVideo() { ShowVideo("youtubevideocode",0); } } When the video completes, youll still need a SendMessage back into Unity. Hope that helps.
Here is the YouTube API reference doc BTW: https://developers.google.com/youtube/iframe_api_reference
It was my similar solution too. I added jPlayer script in my WebGL template but my hope was replace this behavior with a Unity native VideoPlayer one. Unity please fix it!
I used the web URL as the video address. The Unity editor can play the video, but webGL can't when packaged.
I use this API but there is nothing to show how to play video and don't show youtube player at WebGL but player component added