Is there an "onClose" event for the fullscreen video player on iPhone? - html

I am using an html5 video player on a website.
When the user starts playing it, the player goes into fullscreen mode and plays the video.
When the video has ended, I catch the ended event and close the video player via myvideo.webkitExitFullScreen();.
Now, I need another event when the player actually gets closed either if the user taps the "done" button in top bar or if the player gets closed via video.webkitExitFullScreen();.
Is there a way to do this?

Updated Answer
You can use the webkitendfullscreen and webkitenterfullscreen events:
var vid = document.getElementById("some-vid");
vid.addEventListener('webkitendfullscreen', function (e) {
// handle end full screen
});
vid.addEventListener('webkitenterfullscreen', function (e) {
// handle enter full screen
});
Previous Answer
A similar question was asked here: How do I capture keyboard events while watching an HTML5 video in fullscreen mode? - not sure how to link these 2 questions.
I'm just going to assume you use jQuery for ease of writing this code. You just need to know when the video has changed modes from full-screen to not-full-screen... so on Resize you can check the video.webkitDisplayingFullscreen; property.
var isVideoFullscreen = video.webkitDisplayingFullscreen;
$(window).bind("resize", function (e) {
// check to see if your browser has exited fullscreen
if (isVideoFullscreen != video.webkitDisplayingFullscreen) { // video fullscreen mode has changed
isVideoFullscreen = video.webkitDisplayingFullscreen;
if (isVideoFullscreen) {
// you have just ENTERED full screen video
} else {
// you have just EXITED full screen video
}
}
});
Hope this helps or points you in the right direction

$('video').bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', function(e) {
var state = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
var event = state ? 'FullscreenOn' : 'FullscreenOff';
// Now do something interesting
alert('Event: ' + event);
});

Related

How to change a video based on the time another video is paused at in HTML

I'm trying to figure out how I would switch to another video if the current video is paused within a specific range (Ex. pausing the video between 2-4 secs will change the video)
I'm assuming I have to implement the played property in some way here
You don't need to know the played ranges to know when the video was paused. Use currentTime, and check it when the pause event fires:
vid.addEventListener('pause', (e) => {
if (e.currentTarget.currentTime > 2 && e.currentTarget.currentTime < 4) {
vid.src = 'something-else.mkv';
}
});

browser response on dragover - html5 drag and drop

I am using html5 drag and drop.
When I drag an image or link from any given webpage, the browser-window is recognizing the dragover event.
For example dragging an image over a browser tab, makes the browser switching the window. Same works for example with dragging links to bookmarks.
Now when I drag my custom draggable element, there is no reaction from the browser. Is there a way to change this behavior?
I don't understand what you want to achieve, but it seems that you want to make something happens when you move your custom element outside the document or the window.
You should try binding a handler with a dragleave or something like that. Here is an example from another question:
var dropTarget = $('.dropTarget'),
html = $('html'),
showDrag = false,
timeout = -1;
html.bind('dragenter', function () {
dropTarget.addClass('dragging');
showDrag = true;
});
html.bind('dragover', function(){
showDrag = true;
});
html.bind('dragleave', function (e) {
showDrag = false;
clearTimeout( timeout );
timeout = setTimeout( function(){
if( !showDrag ){ dropTarget.removeClass('dragging'); }
}, 200 );
});
I think that could work for you, but for further help you should extend your issue's description.
Also I ll leave some HTML5 drag and drop docs here

HTML5 Audio stop function

I am playing a small audio clip on click of each link in my navigation
HTML Code:
<audio tabindex="0" id="beep-one" controls preload="auto" >
<source src="audio/Output 1-2.mp3">
<source src="audio/Output 1-2.ogg">
</audio>
JS code:
$('#links a').click(function(e) {
e.preventDefault();
var beepOne = $("#beep-one")[0];
beepOne.play();
});
It's working fine so far.
Issue is when a sound clip is already running and i click on any link nothing happens.
I tried to stop the already playing sound on click of link, but there is no direct event for that in HTML5's Audio API
I tried following code but it's not working
$.each($('audio'), function () {
$(this).stop();
});
Any suggestions please?
Instead of stop() you could try with:
sound.pause();
sound.currentTime = 0;
This should have the desired effect.
first you have to set an id for your audio element
in your js :
var ply = document.getElementById('player');
var oldSrc = ply.src;// just to remember the old source
ply.src = "";// to stop the player you have to replace the source with nothing
I was having same issue. A stop should stop the stream and onplay go to live if it is a radio. All solutions I saw had a disadvantage:
player.currentTime = 0 keeps downloading the stream.
player.src = '' raise error event
My solution:
var player = document.getElementById('radio');
player.pause();
player.src = player.src;
And the HTML
<audio src="http://radio-stream" id="radio" class="hidden" preload="none"></audio>
Here is my way of doing stop() method:
Somewhere in code:
audioCh1: document.createElement("audio");
and then in stop():
this.audioCh1.pause()
this.audioCh1.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAVFYAAFRWAAABAAgAZGF0YQAAAAA=';
In this way we don`t produce additional request, the old one is cancelled and our audio element is in clean state (tested in Chrome and FF) :>
This method works:
audio.pause();
audio.currentTime = 0;
But if you don't want to have to write these two lines of code every time you stop an audio you could do one of two things. The second I think is the more appropriate one and I'm not sure why the "gods of javascript standards" have not made this standard.
First method: create a function and pass the audio
function stopAudio(audio) {
audio.pause();
audio.currentTime = 0;
}
//then using it:
stopAudio(audio);
Second method (favoured): extend the Audio class:
Audio.prototype.stop = function() {
this.pause();
this.currentTime = 0;
};
I have this in a javascript file I called "AudioPlus.js" which I include in my html before any script that will be dealing with audio.
Then you can call the stop function on audio objects:
audio.stop();
FINALLY CHROME ISSUE WITH "canplaythrough":
I have not tested this in all browsers but this is a problem I came across in Chrome. If you try to set currentTime on an audio that has a "canplaythrough" event listener attached to it then you will trigger that event again which can lead to undesirable results.
So the solution, similar to all cases when you have attached an event listener that you really want to make sure it is not triggered again, is to remove the event listener after the first call. Something like this:
//note using jquery to attach the event. You can use plain javascript as well of course.
$(audio).on("canplaythrough", function() {
$(this).off("canplaythrough");
// rest of the code ...
});
BONUS:
Note that you can add even more custom methods to the Audio class (or any native javascript class for that matter).
For example if you wanted a "restart" method that restarted the audio it could look something like:
Audio.prototype.restart= function() {
this.pause();
this.currentTime = 0;
this.play();
};
It doesn't work sometimes in chrome,
sound.pause();
sound.currentTime = 0;
just change like that,
sound.currentTime = 0;
sound.pause();
From my own javascript function to toggle Play/Pause - since I'm handling a radio stream, I wanted it to clear the buffer so that the listener does not end up coming out of sync with the radio station.
function playStream() {
var player = document.getElementById('player');
(player.paused == true) ? toggle(0) : toggle(1);
}
function toggle(state) {
var player = document.getElementById('player');
var link = document.getElementById('radio-link');
var src = "http://192.81.248.91:8159/;";
switch(state) {
case 0:
player.src = src;
player.load();
player.play();
link.innerHTML = 'Pause';
player_state = 1;
break;
case 1:
player.pause();
player.currentTime = 0;
player.src = '';
link.innerHTML = 'Play';
player_state = 0;
break;
}
}
Turns out, just clearing the currentTime doesn't cut it under Chrome, needed to clear the source too and load it back in. Hope this helps.
As a side note and because I was recently using the stop method provided in the accepted answer, according to this link:
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events
by setting currentTime manually one may fire the 'canplaythrough' event on the audio element. In the link it mentions Firefox, but I encountered this event firing after setting currentTime manually on Chrome. So if you have behavior attached to this event you might end up in an audio loop.
shamangeorge wrote:
by setting currentTime manually one may fire the 'canplaythrough' event on the audio element.
This is indeed what will happen, and pausing will also trigger the pause event, both of which make this technique unsuitable for use as a "stop" method. Moreover, setting the src as suggested by zaki will make the player try to load the current page's URL as a media file (and fail) if autoplay is enabled - setting src to null is not allowed; it will always be treated as a URL. Short of destroying the player object there seems to be no good way of providing a "stop" method, so I would suggest just dropping the dedicated stop button and providing pause and skip back buttons instead - a stop button wouldn't really add any functionality.
This approach is "brute force", but it works assuming using jQuery is "allowed". Surround your "player" <audio></audio> tags with a div (here with an id of "plHolder").
<div id="plHolder">
<audio controls id="player">
...
</audio>
<div>
Then this javascript should work:
function stopAudio() {
var savePlayer = $('#plHolder').html(); // Save player code
$('#player').remove(); // Remove player from DOM
$('#FlHolder').html(savePlayer); // Restore it
}
I was looking for something similar due to making an application that could be used to layer sounds with each other for focus. What I ended up doing was - when selecting a sound, create the audio element with Javascript:
const audio = document.createElement('audio') as HTMLAudioElement;
audio.src = getSoundURL(clickedTrackId);
audio.id = `${clickedTrackId}-audio`;
console.log(audio.id);
audio.volume = 20/100;
audio.load();
audio.play();
Then, append child to document to actually surface the audio element
document.body.appendChild(audio);
Finally, when unselecting audio, you can stop and remove the audio element altogether - this will also stop streaming.
const audio = document.getElementById(`${clickedTrackId}-audio`) as HTMLAudioElement;
audio.pause();
audio.remove();
If you have several audio players on your site and you like to pause all of them:
$('audio').each( function() {
$(this)[0].pause();
});
I believe it would be good to check if the audio is playing state and reset the currentTime property.
if (sound.currentTime !== 0 && (sound.currentTime > 0 && sound.currentTime < sound.duration) {
sound.currentTime = 0;
}
sound.play();
for me that code working fine. (IE10+)
var Wmp = document.getElementById("MediaPlayer");
Wmp.controls.stop();
<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6"
standby="Loading áudio..." style="width: 100%; height: 170px" id="MediaPlayer">...
Hope this help.
What I like to do is completely remove the control using Angular2 then it's reloaded when the next song has an audio path:
<audio id="audioplayer" *ngIf="song?.audio_path">
Then when I want to unload it in code I do this:
this.song = Object.assign({},this.song,{audio_path: null});
When the next song is assigned, the control gets completely recreated from scratch:
this.song = this.songOnDeck;
The simple way to get around this error is to catch the error.
audioElement.play() returns a promise, so the following code with a .catch() should suffice manage this issue:
function playSound(sound) {
sfx.pause();
sfx.currentTime = 0;
sfx.src = sound;
sfx.play().catch(e => e);
}
Note: You may want to replace the arrow function with an anonymous function for backward compatibility.
In IE 11 I used combined variant:
player.currentTime = 0;
player.pause();
player.currentTime = 0;
Only 2 times repeat prevents IE from continuing loading media stream after pause() and flooding a disk by that.
What's wrong with simply this?
audio.load()
As stated by the spec and on MDN, respectively:
Playback of any previously playing media resource for this element stops.
Calling load() aborts all ongoing operations involving this media element

How can I get the size of the webcam image with getUserMedia?

I'm trying to find out what will be the size of the image I get from the webcam using getUserMedia.
Right now, in my Macbook, I have supposedly a 720p camera, but the image I'm getting is 640x480. I'm assuming this won't always be the case, though, and I'd like to be able to handle as many cameras as possible. (I care way more about aspect ratio than size itself, I just want to make sure pictures don't show up stretched)
Is it possible to do this?
Thank you!
Daniel
You should be able to use videoWidth and videoHeight attributes, like this:
// Check camera stream is playing by getting its width
video.addEventListener('playing', function() {
if (this.videoWidth === 0) {
console.error('videoWidth is 0. Camera not connected?');
}
}, false);
UPDATE: Actually, this works in Opera but doesn't seem to be supported in Chrome any more and hasn't been implemented in Firefox (at least not for video streams). It's in the HTML5 spec, though, so hopefully is on the roadmap for these browsers.
UPDATE 2: This does work, but the event to listen for is "playing" and not "play" (fixed in the code above). The "play" event is fired when the play() method is returned, whereas the "playing" event is fired when playback has actually started. Tested in Opera, Chrome and Firefox.
UPDATE 3: Firefox 18 seems to fire the "playing" event repeatedly, meaning the browser could grind to a halt if you're executing a lot of code within the listener. Better to remove the listener after it's fired, like so:
var videoWidth, videoHeight;
var getVideoSize = function() {
videoWidth = video.videoWidth;
videoHeight = video.videoHeight;
video.removeEventListener('playing', getVideoSize, false);
};
video.addEventListener('playing', getVideoSize, false);
Hooking into the playing event does not work in Firefox (at least in Firefox 26.0 on Ubuntu 12.04 LTS I use). The playing event fires once or twice after the video starts playing. videoWidth and videoHeight are either 0 or undefined when the playing event fires. A more reliable way to detect videoWidth and videoHeight is pausing and playing the video, that seems to work always. The code snippet below worked for me:
//Detect camera resolution using pause/play loop.
var retryCount = 0;
var retryLimit = 25;
var video = $('.video')[0]; //Using jquery to get the video element.
video.onplaying = function(e) {
var videoWidth = this.videoWidth;
var videoHeight = this.videoHeight;
if (!videoWidth || !videoHeight) {
if (retryCount < retryLimit) {
retryCount++;
window.setTimeout(function() {
video.pause();
video.play();
}, 100);
}
else {
video.onplaying = undefined; //Remove event handler.
console.log('Failed to detect camera resolution after ' + retryCount + ' retries. Giving up!');
}
}
else {
video.onplaying = undefined; //Remove event handler.
console.log('Detected camera resolution in ' + retryCount + ' retries.');
console.log('width:' + videoWidth + ', height:' + videoHeight);
}
};

AudioElement resume playback stutters for a second and stops

I'm trying to use html5 audio with Dart and Chrome, and I'm going the easy way of using AudioElement as much as possible. I want to be able to pause sound and resume it later. I have:
startSound() {
audioElement.src = "foo";
audioElement.load();
audioElement.play();
}
pause() {
this.time = audioElement.currentTime;
audioElement.pause();
}
unpause() {
audioElement.currentTime = this.time;
audioElement.play();
}
These are hooked up to event handlers, so when someone clicks the 'pause' button, playback stops. When they hit the 'resume' button, though, playback resumes for only about half a second before stopping again.
How do I get audio to resume properly?
There appears to be a timing issue in Chrome. You need to tell Chrome to play, then pause again, then play again, with a short delay between each.
A working version of the unpause method is:
unpause() {
var fn = () {
audioElement.currentTime = this.time;
audioElement.play();
};
fn();
window.setTimeout(() => audioElement.pause(), 25);
window.setTimeout(fn, 50);
}
I had a similar problem with Chrome. It stuttered before playing when I "resumed" the audio element, and I didn't have the same problem in Safari. It turned out, however, that Chrome was somehow not happy with my mp3 format. Adding an ogg version of the file to the sources in my tag solved the problem.