Search Unity

Feedback Video Player, HTML5/WebGL, and the Browser AutoPlay Setting

Discussion in 'Web' started by zenasprime, Oct 19, 2019.

  1. zenasprime

    zenasprime

    Joined:
    Mar 31, 2010
    Posts:
    166
    It seems that browsers, and more specifically Safari, are causing a project we are working on for a client some headaches. We are using the Video Player component to play video on awake but it seems that these videos will not play in our WebGL build unless a user goes into their settings and sets the option to "Allow All Auto-Play" for the hosting site (or for all sites).

    Is there anything we can do internally to override this setting or are we at the mercy of our users ability to set this up for themselves?
     
  2. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
  3. zenasprime

    zenasprime

    Joined:
    Mar 31, 2010
    Posts:
    166
    These new autoplay policies from the browser developers seem to be incompatible with unity's HTML5/WebGL implementation. Unless I'm misunderstanding the meaning of the following: "We only allow a site to play audio or video aloud via the HTMLMediaElement API once a web page has had user interaction to initiate the audio, such as the user clicking on a “play” button."

    This policy is all fine with video/audio players, that have a defined button that web developers can present to the user but it doesn't seem that "clicking a button" in the context of a Unity web build means the same. For example, even when a user "clicks a button" that calls VideoPlayer.Play() video and audio will not play so long as the user has their the browser auto play feature set to "Do not allow".

    Am I just SoL or is there a solution that I'm not finding?
     
  4. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    With Unity, "clicking a button" equates to clicking once on the canvas. After one clicks on the canvas, audio/video playback should be able to start. That does mean that projects that want to immediately play back a video at page load, will have trouble. (they will need to implement some kind of video play restart scheme, or play-on-click scheme)
     
  5. Scrapemist

    Scrapemist

    Joined:
    May 16, 2015
    Posts:
    16
    I wish that was true..
    My button plays a video, but in safari its just black. Only when I mute the audio it will play.
     
  6. Kloper

    Kloper

    Joined:
    Jan 28, 2014
    Posts:
    93
    I got my video in safari to work by making a button in my index.html file that plays a simple mp3 and then loads the unity app. It seems that clicking inside the app didnt unlocks safari.. but the button click from the index.html did.
    Maybe thats just my app.. no idea.
     
  7. kartoonist435

    kartoonist435

    Joined:
    Feb 14, 2015
    Posts:
    73
    Has anyone else tried this idea? I have buttons to click before the video and nothing starts my video. A fix for this would be amazing.
     
  8. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    The problem i've seen here is that the actual input events (click, mouseup, etc) are coming straight from the HTML event handlers but rather from Unity internal loop. Safari is picky about that where other browsers are not and to overcome this you will have to defer those events to html events and that will work anywhere.
    What i've done in my project was to create jslib plugin for WebGL where i defer the `onmouseup`:
    Code (CSharp):
    1. var WebGLUtils = {
    2.   $JsCall: {},
    3.   InputListener_: function(callback) {
    4.     console.log("Input received from Unity");
    5.     JsCallCs.callback = callback;
    6.     document.onmouseup = function() {
    7.       document.onmouseup = null;
    8.       console.log("Input onmouseup sent from javascript");
    9.       Runtime.dynCall('v', JsCall.callback, 0);
    10.     }
    11.   }
    12. };
    13.  
    14. autoAddDeps(LibraryJsCallCsTest, '$JsCall');
    15. mergeInto(LibraryManager.library, WebGLUtils);
    And in Unity:
    Code (CSharp):
    1. public static class WebGLUtils {
    2.  
    3.   [DllImport("__Internal")]
    4.   static extern void InputListener_(Action callback);
    5.  
    6.   public static void InputListener(Action callback) {
    7.     InputListener_(callback);
    8.   }
    9. }
    Then your button OnClick listener should call this WebGLUtils.InputListener().
    Since you can only have static callback from WebGL you also need to have a static instance of your monobehaviour.
    I haven't tried with SendMessage but i assume it will be the same procedure.
     
    Last edited: Apr 28, 2021
    ROBYER1 likes this.
  9. EthanMichalicek

    EthanMichalicek

    Joined:
    Mar 25, 2019
    Posts:
    6
    Thanks for this, this helped a lot.

    I have a question regarding the event being passed through to Unity. Could you point me in the right direction to pass the onmouseup event to Unity's VideoPlayer.Play(); function call? Or do you use a completely different method to start the video playback?

    Edit: For more clarification, I am still a bit lost on how the user event traverses down to playing the video. How does the browser know, from the context of my code in my Unity project, that the event originated from the user and isn't just another "autoplay" request?
     
  10. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    fuzzy3d likes this.
  11. mhab

    mhab

    Joined:
    Jul 9, 2019
    Posts:
    3
    sgt3v and yty like this.
  12. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    It is a problem completely unrelated with the button events being triggered or not.
    The problem with Safari iOS seems to be that the video never loads and isPrepared and prepareCompleted are never true and triggered.
     
  13. mhab

    mhab

    Joined:
    Jul 9, 2019
    Posts:
    3
    Sounds likely. Video on Safari on iOS is a hassle. It was mostly in reference to the README.md:

    Video Player on Unity

    This repo holds the source for a working video player under any WebGL browser. Play and pause buttons are extended from UI button and use deferred input events in WebGL to bypass security restriction that make it possible to play media in all browsers, namely Safari
     
  14. justinduy

    justinduy

    Joined:
    Dec 26, 2016
    Posts:
    7
    i downloaded project and it's not working on ios 13
     
    yty likes this.
  15. justinduy

    justinduy

    Joined:
    Dec 26, 2016
    Posts:
    7
    any luck to make it works :(
     
  16. TadeuszKantor

    TadeuszKantor

    Joined:
    Jul 28, 2019
    Posts:
    4
    Thank you so much this looks amazing ! I've tried on Unity it works well, i just wonder how did you host your video ? Could i host it on youtube for example ? thanks !
     
  17. yty

    yty

    Joined:
    Aug 10, 2009
    Posts:
    82
  18. inkletom

    inkletom

    Joined:
    Oct 13, 2016
    Posts:
    63
    Any updates from the Unity team regarding Safari (desktop)? Encouraging users to click before playing video is doable for Chrome but it doesn't seem to work on latest Safari as others have flagged.
    If the solution is something akin to GilCat's plugin then it'd be great to hear the official word :)
     
  19. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Thanks for pinging on this. Did not have a chance to read through the whole thread before. It looks like there is an autoplay unlock related issue in Unity - would someone be able to report this as a bug along with a test project and steps on how to reproduce? That way our QA will have an exact hold of the issue.
     
  20. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    @inkletom The link for the WebGL player is down but you can build a WebGL Player from the git repo in there and host it for testing.
    I will host another Demo Player somewhere later today.
    When you build your player just make sure you set a valid URL to a video on the CanvasVideoPlayer Prefab and that the server where that video is hosted has CORS enabled otherwise the video wont play due to security restrictions. If you host the video on the same domain of the WebGL it should be just fine.
     
  21. d_grass

    d_grass

    Joined:
    Mar 6, 2018
    Posts:
    45
    Hi jukka_j,
    would appreciate a solution also alot. Currently developing for a client a crossplatform-app and are now in the last steps and the video on ios webgl is not playing :/. Would also be thankfull if you could provide a temp workaround for now?
     
  22. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Sorry, I do not know of a workaround at the moment. A bug report would be much appreciated, that is the best way to get things sped up.
     
  23. d_grass

    d_grass

    Joined:
    Mar 6, 2018
    Posts:
    45
    Hi @jukka_j I uploaded a bug report on your request. The case is 1288692.

    Could it please be possible for you in the foreseeable future to take a closer look at the problem or the case? I also uploaded the project a minimal case to reproduce.

    If you will invest a little time, I would like to thank you for it in advance.
     
  24. inkletom

    inkletom

    Joined:
    Oct 13, 2016
    Posts:
    63
    Thanks everyone, for now we're going to explore Gilcat's solution but fingers crossed for a fix!
     
  25. d_grass

    d_grass

    Joined:
    Mar 6, 2018
    Posts:
    45
    @GilCat 's Solution is also not working on Safari/iOS even his hosted demo.
    @inkletom how did you got it work? Edit: oh I missunderstood you will explore it and have not yet:)
     
    ROBYER1 likes this.
  26. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    No my solution won't work on iOS
     
    Last edited: Oct 30, 2020
  27. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Perfect, thank you so much for taking the time to post the bug report! We'll look for a workaround, and let you know if there is one that can be applied.
     
    d_grass likes this.
  28. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    287
    I don't have an iOS device.
    I made a WebGL build with a workaround applied.
    (The workaround is the same as @ GilCat's)
    Someone please visit this page.
    First click the small Start button at the bottom left.
    WebGLTestPage
    (I'm using a short video.)
     
  29. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Thanks for the test! With a quick test, unfortunately it does look like execution aborts in a JS exception on my iPhone Xs at least. Don't have time tonight to attach Safari Web Inspector from MacBook to it to look if there are any clues in the logs.

    After a brief look earlier yesterday on 1288692, it did not seem to me that the root cause would have been due to an autoplay issue, but not 100% sure.
     
  30. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    @jukka_j I have gone trough that process and attached Safari inspector but there was no error there and no clue that indicates what the problem is.
    It also doesn't seem to me that the problem is not related to security (no more than is in Safari Mac). There must be some internal problem that is not being exposed.
    @jukka_j is there any relevant flag that we can set in Emscripten for outputting something more than we have right now?
     
  31. Firewalker

    Firewalker

    Joined:
    Mar 30, 2012
    Posts:
    39
    Just to report the findings.. tried GilCats solution.. it worked for half a day. Yes, you read it right... it worked for half a day and then it stopped working. Code was not charged, build was not changed.. it just stopped working and we were back to square one. I don't even know how this is possible.

    Then we implemented silent audio in HTML.

    Code (html):
    1.  
    2. <audio id="audio" src="TemplateData/silent.mp3"></audio>
    3.  
    Code (JavaScript):
    1.     const playSilentSound = () => {
    2.         audio.play();
    3.         document.removeEventListener("keydown", playSilentSound)
    4.         document.removeEventListener("mousedown", playSilentSound)
    5.     }
    6.     document.addEventListener("keydown", playSilentSound)
    7.     document.addEventListener("mousedown", playSilentSound)
    It worked like a charm, and there is no need for a start button.
     
    ROBYER1 and Dirrogate like this.
  32. d_grass

    d_grass

    Joined:
    Mar 6, 2018
    Posts:
    45
    Hi @jukka_j,
    I dont really want to bother you more but are there any progress concerning case 1288692 ?
    The Status of the bug report is still open and I hoped that it could be solved in the near future even if it would be a complicated workaround.
     
  33. d_grass

    d_grass

    Joined:
    Mar 6, 2018
    Posts:
    45
    sgt3v, Sprenger and GilCat like this.
  34. sgt3v

    sgt3v

    Joined:
    Feb 19, 2017
    Posts:
    28
    Having the same issue. On top of this I had some issues in Android using StreamingAssets folder too, first video plays then others always got stuck. Better file a report for that one too.
     
  35. Dirrogate

    Dirrogate

    Joined:
    Feb 18, 2014
    Posts:
    157
    tried @Firewalker 's solution. no luck on Chrome latest browser on android (samsung s8 phone)
    The only way Unity video player plays (when set to play on awake) is if you click with your finger on the unity canvas loading bar *before* it finishes loading. Strange behavior this.
     
  36. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    Wow! That is really weird. Did you examine javascript console on the browser developer tools? There might be hints on what might be happening.
    You solution falls on the traditional way of playing media described on the Web Api, but when we want that media (specially video) blended into the game experience it is not feasible most of the times.
    The sample player i have hosted should tell if it works or not. Right now it only fails to play on Safari on iOS devices.
     
  37. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    270
    You cannot autoplay audio or video in Chrome or Safari, period full stop.

    A user created event with the property `trusted = true` (which of course you cannot overwrite) must be on the stack when a media element's `play()` is called. When this occurs in the context of a Unity WebGL player build, it is often by a twisted accident - for example, Dirrogate is observing that there is an event on the stack from `ontouchmove` while Unity is loading, enabling the video to successfully load.
     
  38. Perridot

    Perridot

    Joined:
    Jan 15, 2018
    Posts:
    4
    So what you're saying is as long as trusted is set to true before the play function is called the video should play even on iOS Safari? Because I was still having trouble getting it to work on iOS even when following the suggestions of others.
     
  39. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    270
    You cannot set trusted to true, it is read only. The only way you can get videos to play on iOS is the way I described. They will never consistently work using Unity's media player in WebGL, because you will never be able to ensure the trusted event is used to run the player.
     
  40. RichTufty

    RichTufty

    Joined:
    Jul 12, 2012
    Posts:
    23
    Any solutions? hacks? workarounds yet? for getting the video player to work on iOS Safari?
     
  41. soleron

    soleron

    Joined:
    Apr 21, 2013
    Posts:
    580
    For me, not just the video player, I have none in my scene, but the scene does not load at all.

    The same happens with gtk2k's scene until I click on the start button.

    That is on a PC, using any browser.
     
  42. dblaw

    dblaw

    Joined:
    Oct 16, 2020
    Posts:
    9
    I was having the same issues as everyone else. Just to clarify, even just having a video was broken in WebGL MacOS Safari. I wasn't trying to autoplay, and by the time the user would have encountered the video, they will have had clicked the WebGL canvas element plenty of times. The offered jslib solution didn't work for me, nor did the silent mp3 method.

    However

    I had been looking for good WebGL export templates and found this one:
    https://seansleblanc.itch.io/better-minimal-webgl-template

    Pretty nice template, does what it says and has some nice options. Then I ran it in Safari just to see... and the video issues were gone. Video plays just fine. I'm building with Unity 2019.4.1f1, and I used the 2019 option in the template downloads.

    I don't know what specific kind of sorcery is going on under the hood to produce such auto-magical results. But the template has some fun javascript happening. Not too much though, so maybe playing around with what is there could help people with their issues. Also, maybe Unity should take a look at what this guy has done and roll in his solutions into the official WebGL export template.

    (Also, there is a Paypal donation option for this work. Def a lifesaver for me and will be throwing some cash this dev's way, perhaps consider doing the same)
     
  43. Perridot

    Perridot

    Joined:
    Jan 15, 2018
    Posts:
    4
    Hey, were you able to get this solution to work for Safari on iOS? Was able to get video to work on mac but not my iPhone.
     
  44. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    This issue landed on my work desk back in late November, and I had one patch in landing pattern to fix autoplaying of muted videos, but had to take some time off due to some recurring health issues. Now back to work, and looking to complete the patch and resume the investigation.

    After that patch, the issue will still persist that playing videos with audio won't work, we'll need to defer the playback until an user interaction, like people have already noted in this thread.
     
  45. dblaw

    dblaw

    Joined:
    Oct 16, 2020
    Posts:
    9
    No, unfortunately. I think this might be a bigger issue, as the work I'm doing doesn't seem to run very well on mobile web. That being said, mobile web isn't officially supported with the WebGL HTML5 export, anyways. So perhaps that is to be expected. Though, if you do find a way to make this work let me know!
     
  46. pierresusset

    pierresusset

    Joined:
    Feb 7, 2009
    Posts:
    60
    Hello,

    I'm also struggling around the WebGL IOS video playback issue.
    I manage to get a video to play on iOS with the following modifications :
    -First, in the video.js script (under WebGL playback engine), add the following line after the video object creation:
    Code (JavaScript):
    1. video.setAttribute('playsinline', 'playsinline');
    - Then, the video play action must be invoked by a user input on the HTML template. Unfortunately, Gilcat plugin isn't enough. On my side, I use a transparent button on top of the game canvas. This button is activated on demand thanks to a JS call from C# and the action on the button send a message back to the C# script to launch the video.

    You can avoid this second step if the video has no sound and the VideoPlayer audioOutputMode is set to null.

    I hope this can help for your projects and also Unity Team to find a better solution to this problem as soon as possible.
     
  47. JTSenneker

    JTSenneker

    Joined:
    Jan 18, 2019
    Posts:
    2
    Hi there,

    I've tried this method on a project that I'm working on for a client, and it still fails to work for me on iOS. I'm not sure which step I missed in the process. I have a button that appears over the canvas that sends a message back to my C# script that calls the videoplayer's play function. I've noticed that if I send the message to show the play button on the prepareCompleted callback, the play button is never displayed. Could that be an issue?
     
  48. pierresusset

    pierresusset

    Joined:
    Feb 7, 2009
    Posts:
    60
  49. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    546
    ROBYER1 likes this.
  50. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,454
    Not tried this yet but I assume it then allows playing of the unity video player component with Audio in Safari on macs when the user wants to untoggle mute or clicks a button we have made that plays the video?