Search code examples
javascriptvb.netyoutubegeckofx

Embedding youtube videos with geckofx in vb.net using javascript


I am trying to embed a youtube and twitch player (only one at a time) in my vb.net application using geckofx. While it worked perfectly with the twitch player, i can't interact with the youtube player the same way - using the javascript calls.

I am using these documentations:
- GeckoFX-45.0 source tests
- YouTube Player API Reference for iframe Embeds
- Twitch Embedding Video and Clips
(sry, i am not yet allowed to link all of these)

I have installed "geckofx-45 windows 32bit" via nuget and initialize it as shown here.
Even though this is in C# it can be easily ported to VB.

After creating the geckoBrowser i embed the player using
geckoBrowser.LoadHtml("<html></html>",Nothing).
There seems to be two ways to build your HTML though, which both did not work for me:

  1. Embed the video using the jsapi:

    <!DOCTYPE html>
    <html>
      <body>
        <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
        <div id="player"></div>
    
        <script>
          // 2. This code loads the IFrame Player API code asynchronously.
          var tag = document.createElement('script');
    
          tag.src = "https://www.youtube.com/iframe_api";
          var firstScriptTag = document.getElementsByTagName('script')[0];
          firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    
          // 3. This function creates an <iframe> (and YouTube player)
          //    after the API code downloads.
          var player;
          function onYouTubeIframeAPIReady() {
            player = new YT.Player('player', {
              height: '360',
              width: '640',
              videoId: 'mcixldqDIEQ',
              events: {
                'onReady': onPlayerReady
              }
            });
          }
    
          // 4. The API will call this function when the video player is ready.
          function onPlayerReady(event) {
            event.target.playVideo();
          }
    	  
        </script>
      </body>
    </html>

  1. Embed the video using an iframe:

<!DOCTYPE html>
<html>
  <body>
    <iframe id="player" type="text/html" width="640" height="390"
      src="http://www.youtube.com/embed/mcixldqDIEQ?enablejsapi=1"
      frameborder="0"></iframe>
    
    <script>
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        var player;
        function onYouTubeIframeAPIReady() {
            player = new YT.Player('player', {
              events: {
                'onReady': onPlayerReady
              }
            });
        }
    	  
    	function onPlayerReady(event) {
    		event.target.playVideo();
    	}
    </script>
  </body>
</html>

Either way successfully loads and starts the video.
Though when calling a js-function on the player with

Using jscontext As New AutoJSContext(geckoBrowser.Window)  
    jscontext.EvaluateScript("player.pauseVideo()")  
End Using  

it allways ends with a System.AccessViolationException.

Does anyone know why i can't access the player?
Or is there another (potential easier way) to embed these players in vb.net?


Solution

  • I found a workaround to access the player. I 'inject' my command to the player with this:

    <script>
    		var result;
    		function runCode(code){
    		var JS= document.createElement('script');
    		JS.text= "result = " + code;
    		document.body.appendChild(JS);
    		return result;
    		}
    </script>

    I then call it inside my application:

    Dim result As String = Nothing
    Using jscontext As New AutoJSContext(geckoBrowser.Window)
        jscontext.EvaluateScript("addCode('player.getVolume();')", result)
    End Using
    MsgBox(result)  
    

    The call is bidirectional, so you get the returning value as well.

    This approach is not perfect, but it works. I suspect the javascript origin is the problem here. Though i was not able to figure it out.

    Maybe this will help others.