How to pause a video when mouse is taken off? - html

I was messing around to find a way to pause or mute a video, if we take off our cursor from it with using HTML5 and CSS3 only.But i was unable to find a way.
Is there any way to achieve this ?

If you're using jQuery and HTML5 video, you could do something like:
var vid = $(".myVideo");
vid.mouseleave(function() {
vid.pause()
});
Then, when you want to play again,
vid.mouseenter(function() {
vid.play()
});
The functions vid.play() and vid.pause() are built in so this shouldn't give you any trouble.

Your HTML:
<div id="video-wrapper">
<video id="v" src="video.mp4" controls></video>
</div>
Getting video element using jQuery:
var v = $("#v");
Check if video is ready to play:
$(v).on('canplay', function(){
$(v).mouseenter(function(){
$(this).get(0).play();
}).mouseleave(function(){
$(this).get(0).pause();
})
});

Related

How to bind the paused attribute of video element in vue.js to a function which can display/hide play button

We need to display the play button on video window if video is paused even if video buffer has enough data (this will happen in safari browser as Safari doesn't allow to play the videos without user intervention). I added event listener for pause event. The code is as given below (please note that this is .vue file)
<template>
<div id="app" #keydown="handleKey($event)">
<video ref="videoRef" src="" id="videoID" width="100%" v-on:pause="onVideoPause"></video>
<div id="videoCC"></div>
<button type="button" id="playVideo" v-on:click="onClickCallback"><img :src="require('#/assets/playVideo.png')"></button>
<router-view tabindex="1"></router-view>
</div>
</template>
export default {
name: 'app',
methods: {
onClickCallback: function () {
console.log('onClickPlayback is called')
let videoPlayer = player.instance()
videoPlayer.play()
videoPlayer.setLogLevel(4) // Set Log level to debug
let playVideoBtn = document.getElementById('playVideo')
// Video is playing. Hide the play button
if (playVideoBtn.style.display === 'block') {
playVideoBtn.style.display = 'none'
}
},
onVideoPause: function () {
console.log('video is paused')
let videoEl = document.getElementById('videoID')
if ((videoEl.readyState > 2) && (videoEl.ended === false)) {
console.log('video buffer has the data and video is not ended')
document.getElementById('playVideo').style.display = 'block'
}
}
}
Basically when video is paused, onVideoPause() is getting called and if video is not ended, I am displaying the play button. In the click handler of the play button, I am playing the video and hiding the play button, But we faced below problem while testing with javascript console as below.
Video is playing. Used pause() from javascript console.
document.getElementById('video').pause()
Play button displayed but when we play() now from console, the button is not getting hidden as we are hiding the play button in click function of play button only. When I suggested we will add event listener for play also on video element, my reviewer suggested me to evaluate if we can do v-bind for the 'paused' attribute of video element.
If we can bind the paused attribute and if we can call a function when ever the value changes, we can do the hiding and display in that function. I am not able to figure out how can we bind the attribute and call the function whenever the value changes as v-bind only works with single expression. I am new to vue.js. Can any one please help me if this is possible with v-bind or with any other Vue directives?
my reviewer suggested me to evaluate if we can do v-bind for the
'paused' attribute of video element
The answer to that question is "no". The video element is not a Vue instance, so its properties are not reactive. You must rely on events to detect changes. I demonstrated a two-way binding in my other answer. Here is another approach that is a little simpler in terms of coding.
new Vue({
el: 'main',
data: {
videoElement: null,
paused: null
},
methods: {
updatePaused(event) {
this.videoElement = event.target;
this.paused = event.target.paused;
},
play() {
this.videoElement.play();
},
pause() {
this.videoElement.pause();
}
},
computed: {
playing() { return !this.paused; }
}
});
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<main>
<video id="videoElement" controls poster="velocity-thumbnail.jpg"
#canplay="updatePaused" #playing="updatePaused" #pause="updatePaused">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/Velocity-Mobile.mp4" type="video/mp4" media="all and (max-width:680px)">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/Velocity-Mobile.webm" type="video/webm" media="all and (max-width:680px)">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/Velocity-SD.mp4" type="video/mp4">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/Velocity-SD.webm" type="video/webm">
<p>Sorry, there's a problem playing this video. Please try using a different browser.</p>
</video>
<div class="controls">
<button v-show="paused" #click="play">▶</button>
<button v-show="playing" #click="pause">⏸</button>
</div>
</main>
The general technique for two-way binding is:
in the bind phase, you install event listeners on the element to update the bound value
in the update phase, you move your bound value into the element.
In your case, you want to listen for the playing and pause events, and set a single playing variable appropriately. (paused is just !playing)
In the example below, I leave the controls on the video player and also add my own. You can use either control, and they stay in sync. (You should also remove the event listeners in the unbind phase. I didn't do that, because it's a little messy, and I wanted to keep the example short and simple.)
new Vue({
el: 'main',
data: {
playing: false
},
computed: {
paused() {
return !this.playing;
}
},
directives: {
play: {
bind(el, binding, vnode) {
el.addEventListener('playing', () => {
vnode.context[binding.expression] = !el.paused;
});
el.addEventListener('pause', () => {
vnode.context[binding.expression] = !el.paused;
});
vnode.context[binding.expression] = !el.paused;
},
update(el, binding) {
if (el.paused) {
if (binding.value) {
el.play();
}
} else if (!binding.value) {
el.pause();
}
}
}
},
methods: {
play() {
this.playing = true;
},
pause() {
this.playing = false;
}
}
});
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<main>
<video id="videoElement" controls poster="velocity-thumbnail.jpg" v-play="playing">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/Velocity-Mobile.mp4" type="video/mp4" media="all and (max-width:680px)">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/Velocity-Mobile.webm" type="video/webm" media="all and (max-width:680px)">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/Velocity-SD.mp4" type="video/mp4">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/Velocity-SD.webm" type="video/webm">
<p>Sorry, there's a problem playing this video. Please try using a different browser.</p>
</video>
<div class="controls">
<button v-show="paused" #click="play">▶</button>
<button v-show="playing" #click="pause">⏸</button>
</div>
</main>

Angularjs + HTML play youtube on mouse over

I want to play a movie once the mouse is hovering over it. Just like facebook.
<div class="col-sm-12">
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="//www.youtube.com/embed/pQIXz-uhjIk">
</iframe>
</div>
</div>
The site is built with angularjs and html.
(Im quite new so please if possible also explain the solution not just paste code)
Br
Build up a solution "like" facebook in this plunker
To dynamically run the player, you'll have to integrate the ifram api.
You have to add this into your index.html
<script src="https://www.youtube.com/iframe_api"></script>
Then you need to handle the asynchronous load of their API (dunno why they did that) like this in your controller:
//i create a promise to wait for the YT.loaded to be true
var defered = $q.defer();
var promise = defered.promise;
//i launch this function until the YT.loaded is true
var interval = $interval(function(){
if(YT.loaded){
//if the YT api is loaded, i cancel the interval and resolve the promise
defered.resolve();
$interval.cancel(interval);
}
})
Now i can create a player when the YT api is ready :
var videoId = "pQIXz-uhjIk";
//when the API is ready
promise.then(function(){
//i create an Iframe player in the div with the "ytplayer" id
$scope.ytplayer = new YT.Player('ytplayer', {
height: '200',
width: '300',
videoId: videoId
}) ;
});
Now i have a full control on the player with the $scope.ytplayer object.
I prepare two function to start and pause a player :
$scope.startPlayer = function(player){
player.playVideo();
};
$scope.pausePlayer = function(player){
player.pauseVideo();
}
Now let see the HTML and the mouse tricks :
<div ng-show="ytplayer" ng-mouseenter="startPlayer(ytplayer)" ng-mouseleave="pausePlayer(ytplayer)" class="embed-responsive embed-responsive-16by9">
<div id="ytplayer"></div>
</div>
I show my div only if ytplayer is set. When i enter the div i run startPlayer() on the player ytplayer. When i leave the div i run pausePlayer() on the ytplayer.
The embed-responsive class is an inline-block to wrap the player
... And that's pretty much all.
Michelem's solutionis probably the best option and easiest option if you only have to start the player on mouseenter. But if you need more control on the player keep in mind my solution (even if it's a bit tricky).
Hope it helped.
This could be a solution you can play with:
JSFiddle
HTML:
<div ng-app="myApp" ng-controller="dummy">
<div class="col-sm-12">
<div class="embed-responsive embed-responsive-16by9">
<div ng-hide="url" ng-mouseenter="url = 'http:////www.youtube.com/embed/pQIXz-uhjIk?autoplay=1'">OVERME</div>
<iframe ng-show="url" class="embed-responsive-item" ng-src="{{trustSrc(url)}}"></iframe>
</div>
</div>
</div>
JS:
angular.module('myApp', [])
.controller('dummy', ['$scope', '$sce', function ($scope, $sce) {
$scope.trustSrc = function (src) {
return $sce.trustAsResourceUrl(src);
}
}]);

HTML5 video playlist with MobileJQuery will not play first video

I have the following HTML5 and Java Script code.
PROBLEM: This code will not display the first video clip at index 0.
The code plays all the remaining video clips (from index 1 on-wards) as normal.
The code is available live at
http://mvl.ecs.soton.ac.uk:8080/JustPlayList.jsp
This code will obviously run in HTML5 enabled browsers.
Any help about how to play the first video clip will be really appreciated.
Many thanks,
<div id="VideoContainer"></div>
<div id="num"></div> <script>
var URLArray = new Array();
URLArray[0] = "/VideoContents/AtomVideo/AtomPart1/AtomPart1C.mp4";
URLArray[1] = "/VideoContents/AtomVideo/AtomPart2/AtomPart2C.mp4";
URLArray[2] = "/VideoContents/AtomVideo/AtomPart4/AtomPart4C.mp4";
URLArray[3] = "/VideoContents/AtomVideo/AtomPart5/AtomPart5C.mp4";
URLArray[4] = "/VideoContents/AtomVideo/AtomPart6/AtomPart6C.mp4";
URLArray[5] = "/VideoContents/AtomVideo/AtomPart7/AtomPart7C.mp4";
</script>
<script>
$(document).ready(function()
{
NextFrag();
});
var index=0;
function NextFrag(){
if (index < URLArray.length)
{
alert("Index Value is :" + index);
$("#VideoContainer").html('<video id="video1" controls autoplay > "<source src= "'+ URLArray[index]+ '" type="video/mp4"></source> </video>' );
$("#num").html('Displaying Part : ' +(index+1) + ' ' );
index++;
$("#video1").bind( "ended", NextFrag);
}
}
</script>
There does not appear to be anything wrong with your code, but I think you are getting a weird interaction with jQuery mobile. So the fix seems to be the following. Wrap your HTML in a <div data-role="page"> to tell jQM that this is a mobile page and then put the code in pageinit instead of document.ready. Here is a working demo: http://jsfiddle.net/ezanker/Ep52A/
<div data-role="page">
<div data-role="content">
<center>
<h1>Test Page</h1><h3>Test Page</h3><br /><br />
<div id="VideoContainer"></div>
<div id="num"></div>
<button>Go to Previous Part</button>
<button>Go to Next Part</button>
</center>
</div>
</div>
Here is the code that calls nextFrag:
var index = 0;
$(document).on("pageinit", function(){
NextFrag();
});
UPDATE: jQM Doc explains the problem: http://view.jquerymobile.com/1.3.2/dist/demos/widgets/pages/
Also Note: If your body contains no data-role="page" divs, jQuery Mobile wraps the entire contents of the body within a page div as explained above. jQuery Mobile is using jQuery's wrapAll() method to do this which looks for any script tags inside the content being wrapped, and loads each script source via XHR. If scripts are present in the body, the browser ends up loading them twice. We therefore strongly recommend that jQuery Mobile documents with scripts in their body also contain a div with data-role="page".
So your script in the page was being loaded twice upon initialization calling NextFrag twice and ending up on the second fragment instead of the first.

How do I play a sound with 360player (soundmanager2)?

I've set up soundmanager:
soundManager.setup({
And I've created a sound:
soundManager.createSound({
From the console I also have threeSixtyPlayer:
threeSixtyPlayer.init()
threeSixtyPlayer.init(): Found 0 relevant items.
So how do I make the 360player play the sound? And how do I detect that it is finished playing so that I can create and play the next one after that?
The docs lack information regarding 360ui but from what I've tried:
HTML code needed:
<div id="sm2-container"></div>
<div class="ui360 ui360-vis">
<a id="song_link" class="sm2_link" href="asfgasg.mp3"></a>
</div>
JS:
soundManager.setup({
url: 'inc/soundmanager/',
flashVersion: 9,
useFlashBlock: true,
onready: function() {
soundManager.createSound('someSongId_', selectedSong);
},
ontimeout: function() {
// Error msg
}
});
You also need the files (depending on the theme you want):
flashblock.css
360player.css
360player-visualization.css
berniecode-animator.js
360-button-vis-play-light.png
360-button-vis-pause-light.png
After that there should be a div with a "play" image.
To play you can use soundManager.getSoundById('myId') and chain it with the onfinish event. Example at the doc:
soundManager.play('myId',{
onfinish: function() {
alert('The sound '+this.id+' finished playing.');
}
});
Hope it helps...

How to disable default controls on a full screen HTML5 video?

I have a video of a specified width and height, double clicking on which makes it go full screen using videoElement.webkitRequestFullScreen().
By default the video does not have any controls. But for some reason, on going full screen, the default controls pop up. Here is what I'm doing :
<video id="videoId" width="320" height="240" autoplay="autoplay" ondblclick="enterFullScreen('videoId')" src="Blah.mp4"></video>
And the enterFullScreen(...) function is defined as :
function enterFullScreen(elementId) {
var element = document.getElementById(elementId);
element.webkitRequestFullScreen();
element.removeAttribute("controls");
}
As you can see, I've already tried removing the controls in the function. But to no avail.
Could someone tell me how to prevent this auto insertion of default controls from happening?
This is possible to solve with CSS, as described here: HTML5 video does not hide controls in fullscreen mode in Chrome
video::-webkit-media-controls {
display:none !important;
}
Finally, I found a way around this.
As Alexander Farkas suggested, I wrapped the video in another div, and I set this parent div to go full screen, after which I set the height and width of the video to screen.height and screen.width respectively. And I restored the original properties of both the divs on exiting full screen.
Pseudo Code :
HTML :
<div id="videoContainer" style="position:absolute;background-color:black;">
<video id="videoId" style="height:240;width:320;" ondblclick="enterFullScreen('videoId')" src="movie.mp4"></video>
</div>
JavaScript :
function enterFullScreen(id) {
var element = document.getElementById(id);
element.parentNode.webkitRequestFullScreen();
element.style.height = screen.height;
element.style.width = screen.width;
}
document.addEventListener("webkitfullscreenchange", function () {
if(!document.webkitIsFullScreen) {
// Restore CSS properties here which in this case is as follows :
var element = document.getElementById('videoId');
element.style.height=240;
element.style.width=320;
}
}, false);
If a video goes fullscreen, the user agent should show the controls, also if controls attribute is absent.
Newer user agents also support fullscreen API on any element. Therefore you can try the following:
element.parentNode.webkitRequestFullScreen();
You can find the id of div containing the controls and disable it using javascript.
e.g if id of div that is containing the controls is "controldiv"
then in your function you can write
var ctrls = document.getElementById("controldiv");
ctrls.disabled="true";
Normally the following should work:
var videoPlayer = document.getElementById('videoId');
videoPlayer.controls = false;
But I'm not sure if jumping into full screen mode will override it.
A CSS only solution:
video::-webkit-media-controls-fullscreen-button {
pointer-events: none;
opacity: .5;
}