Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Getting Javascript Vars
#1
Hi, I am facing an issue fetching the value of the pages Java variables.

I am able to send commands to start, stop, change volume and seek just fine. The below is an example on how I am changing the play position:

EdgeWebBrowser.ExecuteScript “player.currentTime(" & mySlider.Value & ")"


I can’t however read the current values of whereyouat or lengthOfVideo. It keeps returning an empty string when using document.OnRequestElementValueById or document.OnRequestElementValueByName

 
I don’t think the getcurrenthtml is an option, as I don’t see it pulling any of the video player variables.
 
The HTML that I am using is below.

Code:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link href="css/style.css" rel="stylesheet" type="text/css">
</head>

<body>

    <div class="container">

        <link href="../videojs/skins/nuevo/videojs.min.css" rel="stylesheet"
              type="text/css" />
        <script src="../videojs/video.min.js"></script>
        <script src="../videojs/nuevo.min.js"></script>

        <div class="media-parent">
            <div class="media-child">
               
                <video id="player" class="video-js vjs-fluid" controls preload="auto" playsinline
                    poster="{THUMB}" type="video/mp4" >
                </video>

            </div>
        </div>
        <script>
            var player = videojs('player');
            player.src({ type: 'video/mp4', src:'{URL}'})
            player.nuevo({
                                                                contextMenu: false,
                                                                controlbar: false,
            });
        </script>

                <script>
               
                // Variables
                var elem = document.getElementById("player");
                var whereYouAt = player.currentTime();
                var lengthOfVideo = player.duration();
               
                function openFullscreen() {
                                if (elem.requestFullscreen) {
                                                elem.requestFullscreen();
                                } else if (elem.webkitRequestFullscreen) { /* Safari */
                                                elem.webkitRequestFullscreen();
                                } else if (elem.msRequestFullscreen) { /* IE11 */
                                                elem.msRequestFullscreen();
                                }
                                }
                </script>

    </div>

</body>

</html>



If you can point me in the right direction, that would be great.
Reply
#2
Hi Maddire,

You can’t read the values of whereyouat and lengthOfVideo via the Document interface functions OnRequestElementValueById and OnRequestElementValueByName methods as they are javascript variables, not forms.
Those methods are specificly for reading from form data.
There’s no document interface for reading out global variables.

That doesn’t mean you can’t get at that data, but that you should use another method.
Initially I was thinking via webmessage, but that means you would need a user actions such as a click on a button and it seems you want to read out a status.
So in that case you need a bit of custom javascript and run that via anonymous script (actually you can also use executescript, but the anonymous script has some advantages over passing variables and such)

Here’s an example I wrote for a customer, but translated into VB.

Code:
Private Sub readAppStyleVariable()
  Dim Script As String
  Dim Params As Variant
 
  Script = " () => {" & vbCrLf
  Script = Script & "  let appStyle = '';" & vbCrLf
  Script = Script & "  let app = document.getElementById('cip-hosted-payments-app');" & vbCrLf
  Script = Script & "  if (app !== null) {" & vbCrLf
  Script = Script & "    appStyle = app.style.display;" & vbCrLf
  Script = Script & "    if (appStyle !== null) {" & vbCrLf
  Script = Script & "        return appStyle;" & vbCrLf
  Script = Script & "    } else {" & vbCrLf
  Script = Script & "      return 'null';" & vbCrLf
  Script = Script & "    }" & vbCrLf
  Script = Script & "  } else {" & vbCrLf
  Script = Script & "    return '1';" & vbCrLf
  Script = Script & "  }" & vbCrLf
  Script = Script & "}" & vbCrLf
  ' connect document
  Document.BrowserDispatch (EdgeWebBrowser.Dispatch)
  ' run the above as anonymous function 1
  Document.RunAnonymousFunction 1, Params, Script
End Sub
And you then get the results like this:
Code:
Private Sub Document_OnRunAnonymousFunction(ByVal Id As Long, ByVal Params As Variant, ByVal Data As String, ByVal Error As Long)
  If Id = 1 Then
    Debug.Print "AppStyle = " & Data
  End If
End Sub

So if I would apply that to your example code then it could look like:
Code:
Private Sub readPlayerCurrentTime()
  Dim Script As String
  Dim Params As Variant
 
  Script = " () => {" & vbCrLf
  Script = Script & "  let playerTime = '';" & vbCrLf
  Script = Script & "  let app = document.getElementById('player');" & vbCrLf
  Script = Script & "  if (app !== null) {" & vbCrLf
  Script = Script & "    playerTime = app.currentTime();" & vbCrLf
  Script = Script & "    if (playerTime !== null) {" & vbCrLf
  Script = Script & "        return playerTime;" & vbCrLf
  Script = Script & "    } else {" & vbCrLf
  Script = Script & "      return 'null';" & vbCrLf
  Script = Script & "    }" & vbCrLf
  Script = Script & "  } else {" & vbCrLf
  Script = Script & "    return '1';" & vbCrLf
  Script = Script & "  }" & vbCrLf
  Script = Script & "}" & vbCrLf
  ' connect document
  Document.BrowserDispatch (EdgeWebBrowser.Dispatch)
  ' run the above as anonymous function 2
  Document.RunAnonymousFunction 2, Params, Script
End Sub
and
Code:
Private Sub Document_OnRunAnonymousFunction(ByVal Id As Long, ByVal Params As Variant, ByVal Data As String, ByVal Error As Long)
  If Id = 1 Then
    Debug.Print "AppStyle = " & Data
  End If
  If Id = 2 Then
    Debug.Print "PlayerTime = " & Data
  End If
End Sub

Attached is the test code I used (which doesn't have your control, but it does fire the event and returns "1" because it couldn't find the player.)

Hope this helps,
--
Wil


Attached Files
.zip   frmDocument.zip (Size: 2.72 KB / Downloads: 1)
Reply
#3
Hi Wil,

Thanks. I managed to test this, and the OnRunAnonymousFunction event only fires when the video is not playing. Could there be a reason to this?
Reply
#4
Hi,

I'm wondering if it has to do with the single threaded nature of javascript.

When you asked the question I had taken a look at the javascript player you are using and it seems like there is no demo available for download. I have to buy in order to try, which complicates testing this issue myself. Will see if I can adapt one of their online examples...

This is beyond my javascript expertise so I will ask our in house javascript expert to see if she can figure out what the problem is.

--
Wil
Reply
#5
(2022-04-20, 11:33:07)wila Wrote: Hi,

I'm wondering if it has to do with the single threaded nature of javascript.

When you asked the question I had taken a look at the javascript player you are using and it seems like there is no demo available for download. I have to buy in order to try, which complicates testing this issue myself. Will see if I can adapt one of their online examples...

This is beyond my javascript expertise so I will ask our in house javascript expert to see if she can figure out what the problem is.

--
Wil

No worries. I have sent you the demo plugin that I got when I registered. Hopefully can pinpoint a solution Smile
Reply
#6
This was handled by email.

For the rest reading along, it was a script error in the anonymous function.

So how does one figure that out?

The WebView2 control that the AntView control hosts is a full browser, it does come with a debugger.
As long as the developer tools haven't been disabled, you can use those debugging features for your benefit.
Right click on the rendered html and click "inspect" from the context menu. (Another way to invoke the debugger is to press F12 after clicking on the AntView control)

The next thing you should know is that the anonymous function is executed in the browser as a function "AntAnonymousFunction".
With those 2 tricks on your sleeve, you can now put a breakpoint.

First make sure the anonymous function was run at least once already (in our case we clicked the button that invoked the RunAnonymousFunction method that we want to debug)

Now type AntAnonymousFunction in the debug console, like so

   

double click on the function content and it opens a new tab.
   

This then is the debugger tab and you can put a breakpoint. I did put one on the "app" line and noticed that when I stepped over the function - after triggering it from VB6 - that it went into the void on the line "PlayerTime = "

After seeing that I triggered it again and now instead of stepping over the line I went to the console tab and tried it there.
   

This means that app.currentTime is not a function, but a variable!

By changing our script in the VB6 anonymous function to take that into account,

   

we now have it working without having to resort to async await or timers or anything else...

   

Hoping that this fixes it on your end as well.

--
Wil
Reply
#7
Yes, this now works! thanks
Reply
#8
Just wanted to post an update as I came across an issue. The above method only works once media is playing. If I try and run an anonymous function before media is loaded, it will completely crash VB. This is the case with both the built in JSPlayer and the Nuevo player.

Is there an event that can be raised to confirm it's safe to start sending requests?
Reply
#9
Hi,

I'm not able to reproduce this.

FWIW, I have the following code:



Code:
Option Explicit

Public WithEvents Document As AntviewAx.AntViewDocument



Private Sub Command1_Click()
  '
  Document.RequestCurrentHtml
  ' the result comes back via the Document_OnRequestHtml event below
End Sub

Private Sub Document_OnRunAnonymousFunction(ByVal Id As Long, ByVal Params As Variant, ByVal Data As String, ByVal Error As Long)
  If Id = 1 Then
    Debug.Print "AppStyle = " & Data
  End If
  If Id = 2 Then
    Debug.Print "PlayerTime = " & Data
  End If
End Sub


Private Sub EdgeWebBrowser_OnCreateWebviewCompleted(ByVal HResult As Long)
  MapLocalFolderToHostName
End Sub


Private Sub Document_OnRequestCurrentHtml(ByVal Html As String)
  MsgBox Html
End Sub

' show how-to read appStyle using anonymous functions
Private Sub readAppStyleVariable()
  Dim Script As String
  Dim Params As Variant
 
  Script = " () => {" & vbCrLf
  Script = Script & "  let appStyle = '';" & vbCrLf
  Script = Script & "  let app = document.getElementById('cip-hosted-payments-app');" & vbCrLf
  Script = Script & "  if (app !== null) {" & vbCrLf
  Script = Script & "    appStyle = app.style.display;" & vbCrLf
  Script = Script & "    if (appStyle !== null) {" & vbCrLf
  Script = Script & "        return appStyle;" & vbCrLf
  Script = Script & "    } else {" & vbCrLf
  Script = Script & "      return 'null';" & vbCrLf
  Script = Script & "    }" & vbCrLf
  Script = Script & "  } else {" & vbCrLf
  Script = Script & "    return '1';" & vbCrLf
  Script = Script & "  }" & vbCrLf
  Script = Script & "}" & vbCrLf
  ' connect document
  Document.BrowserDispatch (EdgeWebBrowser.Dispatch)
  ' run the above as anonymous function 1
  Document.RunAnonymousFunction 1, Params, Script
End Sub

' read Player timer
Private Sub readPlayerCurrentTime()
  Dim Script As String
  Dim Params As Variant
 
  Script = " () => {" & vbCrLf
  Script = Script & "  let playerTime = '';" & vbCrLf
  Script = Script & "  let app = document.getElementById('veoplayer_html5_api');" & vbCrLf
  Script = Script & "  if (app !== null) {" & vbCrLf
  Script = Script & "    playerTime = app.currentTime;" & vbCrLf
  Script = Script & "    if (playerTime !== null) {" & vbCrLf
  Script = Script & "        return playerTime;" & vbCrLf
  Script = Script & "    } else {" & vbCrLf
  Script = Script & "      return 'null';" & vbCrLf
  Script = Script & "    }" & vbCrLf
  Script = Script & "  } else {" & vbCrLf
  Script = Script & "    return '1';" & vbCrLf
  Script = Script & "  }" & vbCrLf
  Script = Script & "}" & vbCrLf
  ' connect document
  Document.BrowserDispatch (EdgeWebBrowser.Dispatch)
  ' run the above as anonymous function 2
  Document.RunAnonymousFunction 2, Params, Script
End Sub


Private Sub Form_Initialize()
  Debug.Print "Form initialize"

  Set Document = CreateObject("AntViewAx.AntViewDocument", "")
  Document.BrowserDispatch (EdgeWebBrowser.Dispatch)
 
  EdgeWebBrowser.UnlockControl "ExampleCompany", "WI5PO2-2KSU3Q-HWFXFU-IUMU2V-QF8P2F"
End Sub

Private Sub MapLocalFolderToHostName()
  Dim Path As String
  Dim HostName As String

  Path = "C:\testantview\LeadVault"
  HostName = "localhost.local"
  EdgeWebBrowser.SetVirtualHostNameToFolderMapping HostName, Path, hrakAllow
  EdgeWebBrowser.UserDataFolder = Path
End Sub

Private Sub Form_Load()
  EdgeWebBrowser.CreateWebView
End Sub



Private Sub Form_Unload(Cancel As Integer)
  EdgeWebBrowser.CloseBrowserProcess
  EdgeWebBrowser.CloseWebView
End Sub

Private Sub GoButton_Click()
  EdgeWebBrowser.Navigate "https://localhost.local/full-player.html"
  Debug.Print EdgeWebBrowser.LastErrorCode
End Sub

Private Sub PlayerTimeButton_Click()
  readPlayerCurrentTime
End Sub

Pressing the PlayerTimeButton will always return a debugPrint of "1" which makes sense as the object isn't created.

If you can't fix it, then please give me a way to reproduce your problem (aka.. zip your frm/frx in a minimal reproducable case)
--
Wil
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)