Mapping the promise returned from the helpers to the executor's resolve, and reject
methods. We also need to catch the error in the promise chain that's
created inside exitFullscreenHelper_.
Fixes#7298.
Previously, when autoplay was set to any or muted, we would accidentally swallow the autoplay rejection when we reset the muted state back to what it was. Instead, we want to re-throw the error.
To get it working, we also had to update our tests to try/catch in our fake promise.
iPhone's native fullscreen isn't always desirable as you can't overlay controls or anything else. Adds an option to prefer "full window" mode over the video el's fullscreen.
If the preferFullWindow option is set to true, on a browser that does not support the proper fullscreen API but does support fullscreen on the video element (i.e. iPhone), then requestFullscreenHelper_() should call enterFullWindow() instead of fullscreen on the tech.
This PR adds a new option to treat autoplay: true the same as autoplay: 'play'. In general we want video.js to handle as much of the autoplay logic itself as possible, since the browser's treatment of the video element's autoplay attribute is less predictable. For now the default option value is false, but it may be made the default behavior in a future major version.
Adds a new playbackRates() method that takes an Array of numbers
representing the rates that are wanted to show up in the playback rates
menu. When new rates are given, a playbackrateschange event will trigger, which
will be used by the PlaybackRatesMenuButton to update itself.
An empty array will hide the menu. No value will return the currently
set playback rates. Other values will be ignored.
Fixes#7198
Menus with one item are hidden if they have a title, because adding the title increments the hide threshold, but the title is not counted as an item. e.g. the chapters menu if there is a single chapter.
Add a `retryOnError` option. When set, during source selection, if a source fails to load, we will retry the next item in the sources list. In the future, we may enable this by default.
A source that fails during playback will *not* trigger this behavior.
Fixes#1805.
When preloadTextTracks option is set to false, it still preloads the default text track. This leads to duplicate tracks once the mode changes to showing and the track is loaded a second time. This includes the default text track in the behavior defined by the preloadTextTracks option.
Fixes#7019
Follow up from #6982. We previously threw an error, but we've seen it
happen unexpectedly. Instead, we should log an error.
We will still throw an error if the event is undefined or null.
Here, if we have a `log` object on the current object, we should use it,
otherwise, we use a default `log` object.
Fixes an issue in native Safari and Android HLS playback where liveCurrentTime returns Infinity (as we don't have a seekableEnd or seekableEnd is actually Infinity). Which causes the new live ui to show up when we don't really have a live window.
Instead of returning Infinity when liveCurrentTime is Infinity, return 0. So that everything knows that we do not have a seekable window of live playback.
The video dimensions aren't necessarily known at loadedmetadata particularly with native playback on iOS. In fluid mode, the player defaults to 16:9 and does not update once the dimensions are known.
- Updates player styles on resize events.
- Fixes arguments passed to addEventedCallback so the callbacks are executed.
Fixes#6939
Allows the editing of a track's label after its creation. Menu buttons will listen for the labelchange event and update their content accordingly.
This is technically divergent from the spec, which says it's readonly, but it can be useful for Video.js users.
Co-authored-by: Claudia Hinkle <chinkle@chinkle-mn1.linkedin.biz>
This uses offsetX and offsetY on the MouseEvents which helps account for transforms on the player. Unfortunately, this isn't available on TouchEvents, so, while this helps desktop devices with using a mouse, it doesn't help mobile devices using touch.
Fixes#6726, fixes#1102.
When `debug(true)` is called, it will fire a `debugon` event that plugins and components can then use to do extra logging or anything else that's helpful to for debugging. It will also set the log level to debug.
When `debug(false)` is called, it will fire a `debugoff` event that plugins and components can then use to stop doing extra logging or helpful debugging. It will reset the log level to whatever it was previously.
Co-authored-by: ipadilla4 <ipadilla@brightcove.com>
The requestPictureInPicture API and button currently assume thta if the browser supports the PIP API, the tech supports it. This results in a broken button with certain techs, such as youtube or HTML5 with an audio el.
Checks if disablePictureInPicture is exactly false. If true it's disabled and if undefined the tech does not support it.
Fixes#6398.
The fix in #6297 doesn't work where the child to insert before is an element rather than a component, e.g. the video element.
Check if the child to insert before is an element, as well as checking if it has an el_
In the cases where the player isn't ready, or we are in the middle of changing sources, we will wait for `canplay` and then seek to the provided time without requiring Video.js users to handle this themselves.
Co-authored-by: Marco Garay <mgaray@brightcove.com>
It seems we have never triggered change events on remoteTextTrack when we were using native text tracks. This was a problem for VHS, which exclusively uses text tracks.
This makes it so we do trigger the event. Main issue with this change is that it creates a potential for a false positive where a change event was triggered from a non-remote text track but the remoteTextTrack list still received a change event. This issue is mitigated by best practices of looping through the list looking for the modes that you care about.
Co-authored-by: Kevin Kipp <kevin.kipp@gmail.com>
Co-authored-by: Kyle Boutette <kyleveB@gmail.com>
When a player is created without an id on the embed code, Video.js automatically assigns it one based on an auto-incrementing number (a.k.a. a GUID). For the longest time, this has happened to result in the default id of the first player being vjs_video_3.
It was never intended for users to rely on this value being consistent, but users do strange and inadvisable things.
PR #6103 had an unintended side effect in that it changed the default id to vjs_video_2, which we worry could affect some users of Video.js.
The WICG spec calls out only two events, enterpictureinpicture and
leavepictureinpicture. We should try and only use those.
If pictureinpicturechange is still necessary, it can be re-added at a
later date.
Video.js checks whether sources are playable and both displays a message to the user and logs an error to the console. In Google's mobile friendly test and related tools, this message and error is triggered because their test browser's video element does not support any video formats. Some Video.js users are concerned about the æsthetics of the rendered preview within the tools and whether this might have an SEO impact.
Adds a suppressNotSupportedError option, defaulting to false. If set to true, if no sources are playable the error is deferred to the first human interaction (click or touchstart) but cleared if a loadstart occurs.
Adds a new PictureInPictureToggle component in the controls bar of the player. It depends on videojs-font 3.2.0 (videojs/font#41) for icons.
Final spec piece from #5824.
On browsers that implement the Unprefixed Fullscreen API, pass a FullscreenOptions dictionary to requestFullscreen.
Add `fullscreenOptions` option with default value of `{navigationUI: 'hide'}` to player.
See https://fullscreen.spec.whatwg.org/#dictdef-fullscreenoptions
This new events function allows you to listen to a list of events and know that only one handler will ever be called for the group. With just one event, it'll function similarly to `.one`.
Examples:
Single event
```
const player = videojs('some-player-id');
player.any('a', (e) => console.log(e.type + ' triggered');
player.trigger('a');
// logs 'a triggered'
player.trigger('a');
// logs nothing as the listener has been removed.
```
Multiple Events
```
const player = videojs('some-player-id');
player.any(['a', 'b', 'c', 'd'], (e) => console.log(e.type + ' triggered');
player.trigger('d');
// logs 'd triggered'
player.trigger('a');
player.trigger('b');
player.trigger('c');
player.trigger('d');
// all triggers above log nothing as the listener is removed after the first 'd' trigger.
```
Allow middleware to handle volume setter and getter. This supports things like ducking the playback volume programmatically, without affecting the player's UI volume control.
Calling video.load while the video is trying to play (that is between play and playing event) throws an error. Instead, just wait for playback to happen before resetting.
Fixes#5875
1. We were not always able to clean up `resize` on the `ResizeManager`, as the iframe
contentWindow can disappear before dispose
2. Native Tracks on Safari do not have an `off` so we have to deal with
event listeners manually
Fixes#5878
The resetProgressBar_ method was calling 'updateContent' on the durationDisplay and remainingTimeDisplay controls without checking to make sure they exist
Fixes#5838
In Safari, if we call play early and we are going to be waiting till
loadstart, it's possible this will take too long for the user activition
flag to still be available. In this case, we should call load() on the
player to prime the video element so for when loadstart happens.
The ResizeManager's iframe element is able to be focused via tabbing, which results in a bad user experience for users that rely on a screen reader to navigate the video and its sibling elements. The fix is to set the tabIndex to "-1", and the aria-hidden property to true for good measure.
A child component may have been assigned to another
parent before assigning that child component to the
new parent via "addChild" method. In this case, the
original parent should remove the child then it can
be safely added back to the new parent. This commit
will keep the parent's "children_" and its DOM
element's child nodes in the consistent state.
`loadMedia` accepts a MediaObject and an optional ready handler. It'll reset the player -- including text tracks, poster, and source -- before setting the new provided media, which include sources, poster, text tracks.
`getMedia` will return either the provided media object or the currently set values for sources, text tracks, and poster.
Fixes#4342
Listen to 'mouseenter' and 'mouseleave' events when triggered in the control-bar and temporarily sets inactivity timeout to zero before restoring it.
Closes#5258
- Make sure that we seek to live playback on the first timeupdate
- Do not report that we are not live before playback has started (a timeupdate has been seen)
- Prevent negative seekable increments
- We can seek past the seekable value in the video element, so we use that to seek to live, rather than waiting for a seekable end change.
When liveui is enabled, allow seeking during the live window, add button that allows you to seek to the live edge and that indicates whether you are at the live edge or not.
This is a follow-up to this fix in VHS, after which default in-manifest subtitles were still not being correctly enabled. The reason is because Video.js's text track preselection logic was running before the media groups were set up in VHS.
Text track preselection should happen on `loadedmetadata` instead of `loadstart`. According to the HTML spec, text track data is available on `loadedmetadata`, so we should be waiting until then to make preselection decisions.
Disable running tests in Firefox on Travis for regular PRs as it wasn't the case previously and is broken for some reason. We'll follow up in the future in #5626.
Update .travis.yml based on their latest infrastructure and new npm caching method.
Silence logging of sourceset test sources.
Closes#5616
When preselecting a new track based on user preference, make sure that the language is actually set and that the track we're testing is either a captions or a subtitles track.
Fixes#5553
The `PlayToggle` has one option `replay` which can show or hide replay icon. This can be set by passing `{replay: false}` as the default behavior replay icon is shown after video end playback.
Example of how to hide a replay icon
```js
let player = videojs('myplayer', {
controlBar: {
playToggle: {
replay: false
}
}
});
```
Fixes#4802
Sometimes the vjs-waiting class is removed prematurely after the player gets into a waiting state. This removes the graphic waiting spinner while the player is still waiting. Instead, we should make sure that the currentTime has updated before removing the spinner.