Fetch youtube video completion response while playing it in IFrame based on youtube video id


Once the video in Iframe finish playing i need the particular topics checkbox to become True if not completed then it will remain False. and it is an youtube video in Iframe. How can i achieve this? I have also created API for this.

This one is a bit tricky since you will need some js

First you'll need to import the youtube api:

You will have to create an "injectables" folder here and put this text file in it. (adjust for install folder ofc)

head_top.txt (58 Bytes)

"C:\Program Files\Inductive Automation\Ignition\data\modules\com.inductiveautomation.perspective\injectables\head_top.txt"

Than you will need some markdown with some code:
Replace the binding value to the video id
You will also have to add an domId to an element which will become the player.
The scripts write to a custom property to say its done. you will have to handle your event on an onchange script on it or something. (dont forget to turn the boolean back off)
Here is a sample :slight_smile:

Summary
	frameId = 'player' 
	propName = 'isYoutubeDone'
	code =  """<img style='display:none' src='/favicon.ico' onload=\"		    
			var player;
	    	const view = [...window.__client.page.views._data.values()].find(view => view.value.mountPath == this.parentNode.parentNode.parentNode.getAttributeNode('data-component-path').value.split('.')[0]).value; 
			function onYouTubePlayerAPIReady() {
	            player = new YT.Player('"""+frameId+"""', {
	              width: '100%',
	              height: '100%',
	              videoId: '"""+value+"""',
	              events: {
	                onReady: onPlayerReady,
	                onStateChange: onPlayerStateChange
	              }
	            });	            
	        }
	        function onPlayerReady(event) {
	            event.target.playVideo();
	        }
	        function onPlayerStateChange(event) {        
	            if(event.data === 0) {          
	                console.log('done');
	                view.custom.write('"""+propName+"""', true);
	            }
	        }
	        onYouTubePlayerAPIReady();	
	    \"></img>""".replace("\n", "").replace("\t", "")
	return code
		

youtube_api.zip (5.2 KB)

(onPlayerReady autoplays the video, you can remove this if not wanted)

Do note that once you run this code, the designer might give you some trouble moving the components, so be sure to put the element in a seperate container first

2 Likes


I was trying in this form will this not work? but after fetching duration I am not getting how to compare it to get video status

No that wont be enough, python has no access to the status of iframe.

I do see the video player has a status property, idk if you can link youtube vids in those? or if you can download the video and just use this instead.

Yes but to a video player i cannot fetch video from Youtube it will only access downloaded videos.

I tried adding youtube_api.zip and head_top.txt and it worked perfectly. Nicely done.

1 Like

So I was trying to add how you had told before but I am not getting what has to be assigned for frameId.

Hey may I know how you did it?

download youtube_api.zip don't unzip it.
In Designer press file > Import and import the youtube_api.zip
It will bring in a view called 'youtube' within that view there is a coordinate view and inner label, this will become your player. There is also a markdown with an expression, if you edit the expression you can set your videoId in the top section. This markdown is what injects the js and sets the isYoutubeDone custom param to True.

Now you need to import the head_top.txt.
Go to your ignition install location then /data/modules/com.inductiveautomation.perspective/
create a folder here called injectables, open and put the head_top.txt file here.

Naviagate to the 'youtube' view from a perspective session and tada! Should be working.

1 Like

I got this but in my view the Youtube video links YouTube are dynamically passed by fetching it from database that is where I am confused.

In that case you just need to update the binding on the markdown to a database query and then pass that result on to the reset of the markdown code. All it needs is the video_id, you can get it there through any way you would normally move data around in Ignition.

you can not pass variables with {} in like that, just use the """+ like i did else it just gonna mess up with some js codes

The frameID need to be meta.domId, this is a property you have to add manualy. to the target component.
image

and the propname needs to be a the name to the property not the property value. This needs to be a view custom property, not one on self

i can't see everything but idk why you would use value = currentValue, i think thats wrong

Hi,
I am passing the video ids dynamically but it is playing only 1 video in the label rest just i am able to see that the id is changing in Markdown based on selection of topic but video is not coming in label. I need to pass videos dynamically from database. How can I do this ?

Could you provide the view, with the bindings towards your database disabled

Training_App_2024-09-09_Youtube dynamic backup.zip (28.3 KB)
I have attached the backup here Kindly check.

Eh that view is quite the mess tbh
You also did not disable all the bindings. but ahwelh

You are making things a lot harder than they should be.

Anyways it does seems like its the youtube API that is causing issues with the delayed data... or if the url changes after loading.

But i kinda found a way to ignore this but its not super pretty.
Instead of using embded views, you gotta use a repeater (or canvas). and delete all instances between changing url.

Ofc you will have to do that in a script or something.

I added in 2 other sample views. do not touch the youtube view, you only have to copy flex repeater into your own view and setup a mechanic to delete the instace and pass in the url afterwards.

use bindings to the isDone[0] and store than somewhere else. use this somewhere else to add an onchange script. dont add onchance script on the instances of the flexrepeater

youtubeembed.zip (36.6 KB)