Im writing a simple Youtube Viewer in Windows Forms C#. I load the page with this.webVideo.DocumentText = html;
in a WebBrowser Component and the page looks fine. I need to inform my app if the video is playing or paused, but the events of the Youtube Embed API don’t fire.
The html should be correct, as it works, when I just open the file in a normal browser.
What did i do:
1: I created a custom UserControl with a Webbrowser and added that to the Form.
2: When the UserControl loads i load the html from a file and manipulate it.
string html = Resources.videoViewer;
html = html.Replace("$VIDEO_ID$", videoId);
html = html.Replace("$VIDEO_WIDTH$", this.webVideo.Width.ToString());
html = html.Replace("$VIDEO_HEIGHT$", this.webVideo.Height.ToString());
html = html.Replace("$WS_PORT$", MyConfig.Port.ToString());
html = html.Replace("$WS_STATE_ROUTE$", WebSocketController.RouteState);
this.webVideo.DocumentText = html;
3: This html is really close to the example https://developers.google.com/youtube/iframe_api_reference?hl=en#Getting_Started.
My modifications were the addition of a WebSocket and the function of the events.
<html>
<head>
<meta content='IE=Edge' http-equiv='X-UA-Compatible' />
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
const serverAddress = "ws://127.0.0.1:5000/videoState";
const socket = new WebSocket(serverAddress);
socket.onopen = function () {
socket.send("{'state': -1}");
}
socket.onmessage = function (event) {
alert(event.data);
}
</script>
<style>
body {
overflow: hidden;
}
</style>
</head>
<body>
<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: '400',
width: '600',
videoId: 'f_qddfYFpQM',
playerVars: {
'playsinline': 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
alert("ready");
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.
function onPlayerStateChange(event) {
socket.send("{'state': " + event.data + "}");
}
</script>
</body>
</html>
When I start my application everything seems to work. The Video gets embedded and the websocket connects, but the onPlayerReady
and onPlayerStateChange
never get called. I tried putting this html in a file and just running that in a normal browser and it works there. I even tried it in an old Internet Explorer i had flying around and it worked there.
The Reference said that there is a requirement that the method postMessage needs to exist, so i tried to check if it exists with alert(postMessage);
and i got function postMessage() { [native code] }
so it does exist in some shape or form.
I also tried adding the eventListeners Manually like player.addEventListener('onStateChange', onPlayerStateChange)
but that didnt work either in Forms, but they did in the normal Browser. Adding a normal EventListener for clicks to a button worked in the WebBrowser Component, too, so im fairly Certain that these Events just dont fire for some reason or that the WebBrowser Component blocks them.
Im fairly new to WindowsForms and C# in general, so I would appreciate any pointers on what could solve this issue. If need be i’d even listen in to alternative ways to embed the video.