Trying to use QML WebEngineView + WebChannel (Qt 5.15), but when running the videoTime script, I get
js: Uncaught ReferenceError: QWebChannel is not defined
Here is a reproducible example
import QtQuick 2.15
import QtQuick.Window 2.15
import QtWebEngine 1.11
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtWebChannel 1.15
Window {
id: root
width: 960
height: 960
visible: true
title: qsTr("webengineexample")
Shortcut {
sequence: StandardKey.Quit
onActivated: {
Qt.quit()
}
}
property string httpAcceptLanguage: "en-US"
QtObject{
id: internals
property string script_videoTime: "
setTimeout(function()
{
var backend;
new QWebChannel(qt.webChannelTransport, function (channel) {
backend = channel.objects.backend;
});
ytplayer = document.getElementById('movie_player');
backend.videoPosition = ytplayer.getCurrentTime();
backend.videoDuration = ytplayer.getDuration();
}, 100);
"
}
QtObject {
id: timePuller
// ID, under which this object will be known at WebEngineView side
WebChannel.id: "backend"
property real videoPosition: 0
property real videoDuration: 0
onVideoDurationChanged: {
console.log("VideoDuration ", videoDuration)
console.log("VideoPosition ", videoPosition)
}
}
WebChannel {
id : web_channel
registeredObjects: [timePuller]
}
WebEngineView {
id: webEngineView
anchors.fill: parent
webChannel: web_channel
userScripts: [
WebEngineScript {
injectionPoint: WebEngineScript.Deferred
name: "QWebChannel"
sourceUrl: "qrc:///qtwebchannel/qwebchannel.js"
}
]
// The following works
profile {
httpAcceptLanguage: root.httpAcceptLanguage
httpCacheType: WebEngineProfile.MemoryHttpCache
cachePath: "/tmp/webengineexample/customprofile/cache"
persistentStoragePath: "/tmp/webengineexample/customprofile/data"
persistentCookiesPolicy: WebEngineProfile.ForcePersistentCookies
storageName: "customprofile"
}
settings {
autoLoadImages: true
dnsPrefetchEnabled: false
}
url: "https://youtube.com"
// url: "https://ping.eu"
}
Button {
id: timeDriver
anchors {
top: parent.top
left: parent.left
}
text: "getTime"
onClicked: {
webEngineView.runJavaScript(internals.script_videoTime)
}
}
}
Not sure what I'm doing wrong, but I found https://forum.qt.io/topic/64638/inject-qwebchannel-into-an-https-page suggesting that it might not work with HTTPS pages. Unfortunately, I don't have a developer-build and I see no such error.
Update: I tested this with a developer build, and i don't get that HTTPS-related error.
Update: I also tried to replace userScripts
with the following, and I'm getting a segfault
userScripts: [
{
name: "QWebChannel",
sourceUrl: Qt.resolvedUrl("qrc:/qtwebchannel/qwebchannel.js"),
injectionPoint: WebEngineScript.DocumentCreation,
worldId: WebEngineScript.MainWorld
}
]
After a lot more googling and poking, the solution seems to be changing the above code with
userScripts: [
WebEngineScript {
injectionPoint: WebEngineScript.DocumentCreation
name: "QWebChannel"
worldId: WebEngineScript.MainWorld // was supposed to be default..
sourceUrl: "qrc:/qtwebchannel/qwebchannel.js"
}
]
And then, the script itself would spit a different error, requiring to be modified as
property string script_videoTime: "
var backend;
new QWebChannel(qt.webChannelTransport, function (channel) {
backend = channel.objects.backend;
});
setTimeout(function()
{
ytplayer = document.getElementById('movie_player');
backend.videoPosition = ytplayer.getCurrentTime();
backend.videoDuration = ytplayer.getDuration();
}, 100);
"
With these two changes the correct values are printed in the console.