I embed the YouTube player on my site. Is there a way using JS or the YouTube API to know when a user has clicked on the video itself, which takes him to YouTube? I can't find a good way to differentiate Flash clicks that play/stop the video vs. clicks that cause the user to go to YouTube.
If you suscribe to the onStateChange event then you can be notified when the player state changes.
function onYouTubePlayerReady(playerId) {
var player = document.getElementById("YTplayer");
player.addEventListener("onStateChange", "onplayerStateChange");
}
Then in the onplayerStateChange You can check for a "5" value which is issued when the video is ready to be "played" for the first time or when the user clicks the video to open a new Youtube window. You should save the old value of the player state to distinguish the two cases.
function onplayerStateChange(newState) {
if (newState == 5) {
if (oldState == -1) {
// First time the video loads
} else {
// User has just opened a new youtube window
}
}
oldState = newState;
}
Related
For tracks that the localParticipant constructs and publishes manually, enabling/disabling those tracks apparently has no effect on remote participants. So for example, if a localParticipant wanted to mute their audio, the remote participant will continue to receive that localParticipant's audio.
I found at least 2 ways to reproduce this error:
When a participant first connects to a room, if the participant constructs their own tracks object and passes it in as a connect option like so:
Twilio.Video.connect(twilioToken, {
name: roomName,
tracks: [LocalTrack|MediaStreamTrack] // The tracks array is constructed by converting from a MediaStream object containing 1 audio and 1 video track
})
Those tracks will get published successfully but not register their enable/disable events.
However, if the participant connects to the room like so:
Twilio.Video.connect(twilioToken, {
name: roomName,
video: true,
audio: true,
})
the track enable/disable events fire for those tracks and the remote participant will be notified when the localPartipants disables any tracks.
When a localParticipant publishes a new track constructed manually, the new track's enable/disable events will not fire off to remoteParticipants.
const newLocalAudioTrack = new Twilio.Video.LocalAudioTrack(newAudioTrack); //newAudioTrack is a MediaStreamTrack object
localParticipant.publishTrack(newLocalAudioTrack); // track gets successfully published
// Trying to disable track after track has been published and registered by the remoteParticipant
localParticipant.audioTracks.forEach((publication) => { publication.track.disable(); }); // This will not work and remote Participant will continue to receive audio, no disable event is registered by any remoteParticipants
Project Environment: Node.js, Twilio-video#2.12.0, Twilio#3.56.0
Please let me know if you need any other details.
function roomJoined(room) {
$('#call-microphone').click(function ()
{
console.log('MICROPHONE MUTED');
if (microphone) {
room.localParticipant.audioTracks.forEach(function (audioTrack) {
console.log("audioTrack-- "+audioTrack);
audioTrack.disable();
});
microphone = false;
$('#call-microphone').html('<span class="fa fa-microphone"></span> ');
console.log('MICROPHONE MUTED', 'control', 'bg-warning');
} else {
room.localParticipant.audioTracks.forEach(function (audioTrack) {
console.log("audioTrack-- "+audioTrack);
audioTrack.enable();
});
microphone = true;
$('#call-microphone').html('<span class="fa fa-microphone-slash"></span> ');
console.log('MICROPHONE ON', 'control', 'bg-info');
}
});
}
I would like to use the YouTube API to make sure the video was watched till end, maybe an event or so?
You need to use onStateChange event, which will give you 0 when ended. This event fires whenever the player's state changes. The value that the API passess to your event listener function will specify an integer that corresponds to the new player state.
Here's a sample code snippet to get notified when the player's state changes:
player.addEventListener("onStateChange", function(state){
if(state === 0){
// the video is end, do something here.
}
});
Here's another way to get notified when state changes:
function onYouTubePlayerReady(playerId) {
ytplayer = document.getElementById("myytplayer");
ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
}
function onytplayerStateChange(newState) {
alert("Player's new state: " + newState);
}
Is there any way to play one youtube video after another, or better yet, play a sequence of videos one after another with no breaks inbetween? I'm unsure how to do this using the youtube API, but I know it can be done somehow.
The easiest way is using Youtube API method to specify a playlist (check the docs). The harder way is to play the videos yourself, listening for the Video End event, then playing the next one.
About no breaks, that depends on a lot of things:
The speed of the internet connection
wether the videos have ads or not
If the videos have no ads, and you are not satisfied with the breaks you are getting, you might try to cue the next video say 5 seconds before the former video ends, then when you get the Video Finish event, just send a play to the next video. To do this, you have to sequence the videos yourself.
This is simple. I am assuming you have an array of video IDs you want to play. In your onStageChange function, listen for video ended state and once that happens, pick next video from array and start playing it. To play the next video, you need to call loadVideoById function followed by playVideo() call. Hope this helped.
And as #rupps said, whether your videos will run without any breaks one after another depends on factors like internet speed. You cannot buffer all videos of a playlist beforehand.
Visit this post to view the sample - Play a 2nd youtube video after first one has finished playing
I am having an array of video IDs that want to play. In your onStageChange function, on the video ended state, pick next video from array and start playing it. At the end of all array videos it will start again from initial.
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var videoId = ['gCFpK_z0Y1o', '2XXzYCfBiAg', 'H-N2SynCSEs', '6PDBRoRFYvo'];
var player; currentVideoId = 0;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
playerVars: {
autoplay: 1,
// loop: 1,
// rel: 0,
// showinfo: 0,
// autohide: 0,
// modestbranding: 1,
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
event.target.loadVideoById(videoId[currentVideoId]);
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
currentVideoId++;
if (currentVideoId < videoId.length) {
player.loadVideoById(videoId[currentVideoId]);
} else {
currentVideoId = 0;
event.target.loadVideoById(videoId[currentVideoId]);
}
}
}
I have the following code, where I hoped to be able to console.log out the list of videos in the playlist:
function onYouTubePlayerReady(playerId) {
ytplayer = document.getElementById("myytplayer");
ytplayer.cuePlaylist({
list:"PLf71xE2jRgTXB_LeUJkXxFwCc4r1z5if3"
});
console.log(ytplayer.getPlaylist());
}
But the getPlayList() method just returns an empty array.
When playing around with it if I call getPlaylist() from outside of this function it does return the correct array. Why is this method returning an empty array here? And how can I get the playlist array?
Many thanks.
Just stumbled across this problem myself. The issue seems to be a quirk with the player, and how YouTube (google) have defined "ready"
It seems that the onReady function of the player fires when the "chrome" for the player has finished rendering (i.e. it's tied the HTML document). The actual player data (video or playlist) is loaded asynchronously, so is ready at some arbitrary point after.
I put a simple work-around in place that looks at the state-change event of the player
var firstLoad = true;
function onPlayerStateChange(e) {
if (firstLoad && e.data == YT.PlayerState.CUED) {
//First Cued event - playlist is now available
firstLoad = false
myPlaylistFunction(player.getPlaylist());
}
}
I have a web page that plays an embedded sound. If I "close" the browser on the iPad while the sound is playing, the sound does not stop. How can I make the sound stop playing when the browser is not visible?
Thought I'd let you know, since I just managed to find a solution.
Code like this, should work:
var lastSeen;
var loop = function (){
lastSeen = Date.now();
setTimeout(loop, 50);
};
loop();
var music = document.getElementById('music');
music.addEventListener('timeupdate', function (){
if(Date.now() - exports.lastSeen > 100){
this.pause();
}
}, false);