Considering the limitations imposed by iOS Safari about the play/load call on a video element I use to initiate it at the first user touchend with a preplay action (play() followed by pause()). From that time I can play with the video as I want (this solution is partially described here).
The problem I encountered is a failed preplay (any next call to play() will be ignored) when the first touchend follows a swipe/drag interaction.
There is a way to let it works also with a swipe? or there is a reliable way to detect if the preplay was succeeded?
Related
When showing a camera feed through a <video> tag, I observe different behavior between Firefox and Chrome when suspending the operating system (i.e. closing/clamshelling the laptop on my Macbook). Afterwards, when resuming the OS:
on Firefox, the camera feed is immediately re-established
on Chrome, the camera feed goes black
As an aside, I've also noticed that the suspend event behaves differently:
on Firefox, it is sent when the camera feed is first connected to the video tag (i.e. nothing to do with OS suspend/resume, as far as I can tell)
on Chrome, it is sent when the OS resumes (i.e. after re-opening the laptop)
I'd like to have Chrome match Firefox's behavior, i.e. show the video feed after resuming from a suspend situation. Is this possible?
While I don't understand the underlying difference between browsers, I have a workaround:
Ignore any "suspend" event if it happens immediately after the video component is mounted. However, if a "suspend" event is received thereafter, do the following:
Wait at least 2 seconds (any sooner and it seems an error will occur when re-querying for permission; another strategy could be to "keep trying" until success)
Re-query for permission to use the camera/audio (Chrome will automatically grant it)
Re-mount the video & audio tags, and establish a video stream again.
The camera stream will show in the video tag again.
When playing a live audio stream, like web radio, through <audio> or Audio(), the pause event can fire in (at least) three ways:
user clicks on the pause button (with <audio controls>)
user clicks the browsers global audio controls
iOS: Control Center
Android: browser's notification drawer (at least Chrome, Opera, Firefox)
Desktop: Media Session API controls, but uninitialized, without explicit setActionHandler (might be hidden behind a flag as of now)
a buffer underrun caused by various network conditions
Is it possible to distinguish between 1/2 and 3?
Ideally, there would be an event property like isTrusted, which I am missing
I have tried to guess, looking esp. at readyState and networkState, but both are very inconclusive, especially across browsers (e.g. the interpretation/semantics of HAVE_FUTURE_DATA vs HAVE_ENOUGH_DATA)
I have shied away from making a "decaying state machine", juggling other events. A buffer underrun is often preceded by stalled events, and sometimes followed by ended events. A cross-browser implementation seems crazy complex and the danger of false positives very high.
Am I out of luck until Media Session lands everywhere?
Note: this question looks like a solution, but unfortunately isn't -- browsers handle live streams' "ends" differently and inconsistently.
The waiting event should fit your needs.
You can try this demo while you simulate bad network with the dropdown in Chrome's Network tab (e.g: Slow 3G)
const video = document.getElementById('mwe_player_0');
video.onwaiting = function() { console.log('onwaiting'); };
<video id="mwe_player_0" controls="" preload="none" style="width:800px;height:450px"><source src="https://upload.wikimedia.org/wikipedia/commons/2/22/Volcano_Lava_Sample.webm" type="video/webm; codecs="vp8, vorbis""></video>
Note that this demo works with HTMLAudioElement as well (because it inherits HTMLMediaElement). The video demo is just easier to test.
If you want to start an event when the user pauses the audio then this snippet will do the job. I didn't test it on mobile in the notification drawer but I think it'll work.
const video = document.querySelector('video');
video.addEventListener('pause', (event) => {
console.log('The Boolean paused property is now true. Either the ' +
'pause() method was called or the autoplay attribute was toggled.');
});
resource: audio element events
resource: pause event
I also found a helpful answer to what you are trying to do 2 (at least from what I understand) and why it's a bad technique. Link to question
3 Events: stalled / waiting check the events resource
My goal is to present clients with a video from youtube (iframe api) that cannot be skipped or seeked forward. On all platforms but iOS this is simple. But I'm having problems with Apple's fullscreen player.
Once playback on a video has started, you are transported to Apple's iOS video player, with it's standard controls. What I have been unable to find is if you can hide/disable these controls in the fullscreen layout.
Alternatively, if I can capture events from the iOS player and merely detect when a user is trying to skip would work as well. I've attached events in accordance with the HTMLMediaElement specs, but none of them fire. Nor do any of youtube's events fire.
I am tracking the console through Safari from the iOS simulator, which could be a problem on it's own.
Any help would be appreciated. I've gone through every SO post on the subject.
While I was unable to find anyway to hide the iOS default viewer (I believe it's impossible), I was able to get the youtube events to fire. With keeping an interval, and checking that against the video's time each time an event is fired, I can figure out if a user has skipped.
Flicks are gestures that can be triggered with a stylus or finger to go back, forward, scroll down or up in an app in windows.
http://windows.microsoft.com/en-us/windows7/what-are-flicks
In my web app, I am using an HTML5 canvas to capture mouse events to draw. In a Microsoft Surface (where flicks are enabled), because of flicks, the mousedown event is delayed and several mousemoves plain ignored and not transferred to the web app. Furthermore, sometimes, the user goes back/forward/scrolls up/down because of the flick actions.
Here's a repro/description/screenshot of this issue:
https://github.com/jogonzal/MinimalisticFlickDelayRepro
The fix is to disable flick gestures in Chrome or Firefox - this means a code change in Firefox/Chrome windows apps to either:
Turn this off completely (preferred, this is what IE and Edge do)
Allow the developer to turn this off via CSS/Javascript
Option 1 Use TABLET_DISABLE_FLICKS (recommended, plenty of examples on github, this is how IE and Edge do it)
(C++):
Disable flicks as described in this article:
https://msdn.microsoft.com/en-us/library/dd562171(v=VS.85).aspx
Code sample
https://github.com/jonathanhook/Waves/blob/bc5a3c9a8a2c8574b28174e25650753237bc8cd2/Source/MultiTouchEvents/WMTouchEventSource.cpp
(C#):
Code example
https://github.com/leowangzi/DanielLib/blob/6aaae88bd9ec9ae91da35fa3bdcd280f2c701e64/DanielLib.TouchAppTemplate/Touchtech.Surface.Community/TabletUtil.cs
Option 2 Respond to WM_TABLET_QUERY_SYSTEM_GESTURE_STATUS
https://msdn.microsoft.com/en-us/library/windows/desktop/ms699430(v=vs.85).aspx
I'm currently implementing HowlerJS and I got it working. But the following happens on Safari using El Capitan:
Open Safari and enter HowlerJS and click play, and it starts loading.
For several of the machines it never plays
Refresh page, click play, it works.
Close open Safari, happens again.
And it is also happening on iOS. Now I've seen that you need to wait for a user click to play audio, which is what I'm doing.
On click of the button it loads and plays the audio. Has anyone faced this problem? I'm using the stable version 1.1.28.
Safari 9 has started to suspend audio on initial page load. In addition to all the other song and dance you usually have to do, now we have to instruct the AudioContext to resume and defer our business logic until that promise resolves. You'll probably want this check just inside a click handler.
if(Howler.ctx && Howler.ctx.state && Howler.ctx.state == "suspended") {
Howler.ctx.resume().then(function() {
console.log("AudioContext resumed!");
// fire your callback here
});
}
Howler 2.0 has supposedly already fixed this, but no such luck as of 1.1.28 for us stable users >_>