Search code examples
javascriptdelphiyoutube-apidelphi-7

Javascript and youtube api in delphi


I'm trying to execute a javascript that has youtube api to the WebBrowser1.

procedure TForm1.FormCreate(Sender: TObject);
begin
  WebBrowser1.Navigate(ExtractFilePath(ParamStr(0)) + 'test.html');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Doc: IHTMLDocument2;      // current HTML document
  HTMLWindow: IHTMLWindow2; // parent window of current HTML document
  JSFn: string;
begin
  // Get reference to current document
  Doc := WebBrowser1.Document as IHTMLDocument2;
  if not Assigned(Doc) then
    Exit;
  // Get parent window of current document
  HTMLWindow := Doc.parentWindow;
  if not Assigned(HTMLWindow) then
    Exit;
  // Run JavaScript
  try
    JSFn := 'onYouTubePlayerAPIReady()';
    HTMLWindow.execScript(JSFn, 'JavaScript');
  except
    on E : Exception do
      ShowMessage(E.ClassName+' error raised, with message : '+E.Message);  //error EOleException, 80020101
  end;
end;

but this raised an error : EOleException, 80020101

Here is my test.html

<div id="player"></div>
<script src="http://www.youtube.com/player_api"></script>
<script>

        // create youtube player
        var player;
        function onYouTubePlayerAPIReady() {
            player = new YT.Player('player', { //<-- error
              height: '390',
              width: '640',
              videoId: '0Bmhjf0rKe8',
              events: {
                  'onReady': onPlayerReady
                  }
            });
        }


        // autoplay video
        function onPlayerReady(event) {
            event.target.playVideo();
        }

</script>

Here I want to embed the video to WebBrowser1 and then auto play it using the javascript that has youtube api.

Is this possible to make this work ?


Solution

  • You are using the Youtube javascript player API, which is deprecated. You must use the Youtube Iframe player API. If you have the HTML under control, then there is no need for special code on the delphi side.

    Here is a complete and working example:

    HTML code (is the same code from the YT API reference page, I just added the autoplay variable):

    <!DOCTYPE html>
    <html>
    <head>
    <!-- // this is needed to force our embedded browser to run in EDGE mode -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    </head>
      <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: '390',
              width: '640',
              videoId: 'M7lc1UVf-VE',
              playerVars: { 'autoplay': 1, 'controls': 0 }, // this is essential for autoplay
              events: {
                'onReady': onPlayerReady,
                'onStateChange': onPlayerStateChange
              }
            });
          }
    
          // 4. The API will call this function when the video player is ready.
          function onPlayerReady(event) {
            event.target.playVideo();
          }
    
          // 5. The API calls this function when the player's state changes.
          //    The function indicates that when playing a video (state=1),
          //    the player should play for six seconds and then stop.
          var done = false;
          function onPlayerStateChange(event) {
            if (event.data == YT.PlayerState.PLAYING && !done) {
              setTimeout(stopVideo, 6000);
              done = true;
            }
          }
          function stopVideo() {
            player.stopVideo();
          }
        </script>
      </body>
    </html>
    

    Delphi code:

    unit u_frm_main;
    
    interface
    
    uses
      MsHtml,
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.OleCtrls, SHDocVw;
    
    type
      TForm1 = class(TForm)
        WebBrowser1: TWebBrowser;
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      WebBrowser1.Navigate(ExtractFilePath(ParamStr(0)) + 'test.html');
    end;
    
    end.