Custom Image for embedded YouTube video

Hi there,

I have embedded a video within a project and was hoping that there might be a way which I could have a custom image displayed over the top until the video is clicked and played.

The image would have a custom designed play button so it is still obvious it is a video. Then when the image is clicked it reveals and plays the YouTube video which is embedded.

Thanks for any help on this.

Not sure of your setup so can’t say if this is definitely a solution but I would have an image overlaid on top of the embedded video and then have a Mouse Click action that hides the image plus the play button (probably grouped), either using a timeline of a Javascript function. Probably Javascript because then I could call play() on the youtube video.

Thanks @DBear for that suggestion, I think that will work best.

Following on from you mentioning the use of javascript would there be an additional bit of code which could be used so when the video is finished it returns to the cover image.

Thanks again

Certainly, on using the method ended() or an event “ended” (most video api’s have this) you could then do some action. Consider the following pseudo code (not actual usable code) in a Javascript function on a Mouse Click:

var myVideo = DOM.videoElement;
var myImage = DOM.imageElement;

myImage.hide();
myVideo.play();

myVideo.on("video has ended", function(){
    myImage.show();
})

This is the logic I would use.

Here is a nice link on HTML5 video and how to manipulate it.

https://www.w3schools.com/tags/av_event_ended.asp

Hype has it’s own API to manipulate elements in the document. So you can use code to change the opacity of an element.

hypeDocument.setElementProperty(element, "opacity", 0)
hypeDocument.setElementProperty(element, "opacity", 1)

or make it disappear / appear completely

element.style.display = "none";
element.style.display = "inline";

etc.

Great! I’m glad this can be achieved.

I have taken a look at the link you provided, however I have to admit the coding side of things is not a strong point for me.

I currently have a group containing a cover image and a play button. This group has been set which when clicked fades out / becomes hidden using a timeline.

With the concept you have mentioned above, the best outcome would be to have the cover image and play button fade out and plays the embedded video once clicked and then when the video is finished the cover image and play button fade back in again. Is this best controlled with the timeline or via some code?

All your help @DBear has greatly appreciated!

Thanks.

How are you embedding the video? If it is using Hype then you could add a second action on the same Mouse Click action on your group that has this:

var video = hypeDocument.getElementById("ID of your video in the inspector");
video.play();

video.onended = function(){
    hypeDocument.startTimelineNamed("YOUR TIMELINE FOR THE IMAGE", hypeDocument.kDirectionReverse)
}

If you are embedding in another way then it may be more difficult

I am currently using YouTube to embed the video from as after much thought it seems the best way to keep the quality and reliability across all platforms and browsers.

This is the code which I have been using with a html widget within hype.

<iframe width="560" height="315" src="https://www.youtube.com/embed/s8xqJHJIyfw?rel=0&amp;controls=0&amp;showinfo=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

Thanks

It becomes a lot more difficult when using external API’s :smiley: but I’ll try to make it straight forward.

First, it’s best not to use the HTML widget as it creates more complications. Change your HTML widget to a Rectangle element. Same dimensions but just an empty rectangle element and then give it an ID (example “myVid” doesn’t matter what it’s called as long as it is consistent throughout the following code).

So, with your document setup place this in the Head HTML (Document Panel 1 “edit Head HTML…”)

<script src="https://www.youtube.com/iframe_api"></script>

Then, in the Scene inspector (Panel 2) click the plus next to the On Scene Load and choose Run Javascript for the action and New Function for the Function. In the following pop up put in this code (remember your ID)

if (window.YT) {
    // Apparently, the API was ready before this script was executed.
    // Manually invoke the function
    my = {};
    onYouTubePlayerAPIReady();
}

function onYouTubePlayerAPIReady(){
	my.player = new YT.Player('myVid', {
		height: '315',
		width: '560',
		videoId: 's8xqJHJIyfw',
		events: {
			'onReady': onPlayerReady,
			'onStateChange': onPlayerStateChange
		}
	})
}

function onPlayerReady(event) {
	// event.target is the iframe and div created from the code above
	event.target.stopVideo();
}

function onPlayerStateChange(event) {
	if (event.data == YT.PlayerState.ENDED) {
		hypeDocument.startTimelineNamed('YOUR TIMELINE FOR IMAGE COVER', hypeDocument.kDirectionReverse)
		console.log("video ended")
	}
}

This will place your youtube video into the rectangle element and create a variable “player” to reference it should you need to. The “events” in this example are onPlayerReady and onPlayerStateChange. The change one is what listens for the end and as you can see I’ve place code there to call a timeline using Hype’s API. Should be self explanatory.

For playing the video when you click your cover group then you would create a function (as explained above) and place this in it.

my.player.playVideo();

Further reading:

4 Likes

@DBear Thank you so much for your help on this, I have now got it all working just how I first imagined it to be!

Again I really appreciate your help, and as you mentioned if there is any related questions to follow I shall dm you.

Thank you!