We had to turn off strict mode (#4551) in Video.js due to a change in vtt.js. That has now been fixed in videojs/vtt.js#40 and released as part of 0.15.2 which will be available via #6333.
Fixesvideojs/vtt.js#15
Any programmatic call to focus when playing back DRMed content on IE/Edge causes the video element to turn black. Instead, don't call focus() in those cases.
Fixes#6270.
iPadOS defaults to desktop mode unless Safari is opened in split screen mode. The only way to detect it is to assume that Safari with Touch enabled is iPad. This is good enough until and if a better way to detect it is made available.
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.
Reimplementation of https://github.com/videojs/video.js/pull/2192
on current code. Seems to work but has not been carefully tested,
especially on conditions such as slow networks and complex tracks.
For https://github.com/videojs/video.js/issues/5252
A `preloadTextTracks` tech option is added, set to true by default,
to keep current behavior intact. Alternate behavior can be enabled
by setting this to false.
This delays loading of the VTT cue files until they are selected.
For sites like Wikipedia that tend to have large numbers of
crowdsourced subtitles and can show many files together on one
page, this saves a lot of unnecessary network transfer and API
hits.
Does mean there may be dropped cues while switching to a track
that requires on-demand loading.
Example usage:
videojs(element, {
html5: {
preloadTextTracks: false
}
};
On iOS, when disconnecting the headphones, we may receive a stalled or suspend event. In those case, we may actually still have buffer available for us to play through rather than actually having stalled or suspended. In those cases, we should pause the player to prevent playback issues.
This will prevent a null exception when a video.js is implemented in a 'display:none' iframe on Firefox (<62).
This is a fix in continuation of the PR #3664 regarding a bug in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=548397
PR #5083 introduces a fix to #5624, an issue with click events when
Polymer's tap gesture is being used. However, this causes an issue where
`player.on('click')` no longer triggers from the play toggle. Thus, we
revert the change. In addition, looking at Polymer 2 and 3, they
recommend against using the tap gesture.
Fixes#6092
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.
This splits up the `update` method into two methods: `update` and `write`. The new write method is only responsible for updating the text content of the tooltips. This is useful if you wan't to be able to override the behavior in some way but still wanted all the behavior in `update` and not take a double dom modification hit.
This allows the user to display multiple tracks when
`allowMultipleShowingTracks` is passed to the `TextTrackDisplay`.
Currently, multiple tracks must be shown programmatically and cannot be
done via the subtitles menus.
In addition, this adds two new classes to cue elements:
`vjs-text-track-cue` and `vjs-text-track-cue-${track.language}`. This
allows easier targetting with CSS.
Example usage:
```js
var player = videojs('example-video', {
textTrackDisplay: {
allowMultipleShowingTracks: true
}
});
```
Fixes#5798.
The play button stops working when recent versions of Google's Polymer is in use on the page because of the way Polymer synthesizes 'tap' events on non-touch devices. The Polymer tap code thinks the click event was ignored unless the DOM event's stopPropagation method is
called.
In chrome 70 the small play/pause control doesn't work with Polymer 1.x Gestures tap is used on document. Demo of issue: https://codepen.io/mscalora/pen/mQzQmpFixes#5624.
This is a rebased and updated PR of #5841.
We wanted to use the sass package as that's what the docs recommend. We also wanted to disable source maps that CDN-linked code won't try to download it.
Fixes#5841, fixes#5826.
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.
```
Following #5824, this PR adds support for some Picture-in-Picture methods described in the spec and article. It also makes sure that we can listen to the enterpictureinpicture and leavepictureinpicture events on the player.
This player behavior is very useful for accessibility because the user can cancel the action by clicking outside the button area. It is recommended by the WCAG 2.1 "2.5.2 Pointer Cancellation" spec.
The fullscreen API now returns a promise. If the player is inside an
iframe that doesn't allow fullscreen, the promise will reject and cause
an error to be logged. Instead, we should silence this promise.
Fixes#5918
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
Disable the live tracker on IE11 when the document is hidden to fix the slow down and eventual crashing of web pages on IE11.
After #5879 was completed, we noticed that live streams still have an issue. This is because the live tracker we have also uses setInterval. Unfortunately, just disabling setInterval in the live tracker was not enough. Instead, we decided the best course of action is to just disable the live tracker altogether.
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 seek bar updates on a 30ms interval to have a nice, smooth transition as time ticks forward. Unfortunately, IE11 has some performance issues with interval when the document is hidden. This doesn't appear to be an issue when using setTimeout but using a setTimeout was causing the play progress to appear very jerky in comparison.
Instead, we should just not update the play progress when the document is hidden. Besides solving the issue in IE11, it makes sense to do as no one could be seeing the progress bar. In addition, update() is now a no-op if the seek-bar element isn't visible.
Fixes#5575
Issue #5831 made the not-in-DOM warning work with elements from other
documents. This works in modern browsers but IE11 doesn't include a
contains method on the document. Instead, we should check to see if the
body contains the element.
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.
Extend keyboard support for the SeekBar, and pass unhandled keydown events from components back to the player.
Switch from raw keycodes to the keycode module.
Using `userActions.hotkeys`, which can either be a function to match the hotkeys plugin, or an object with properties like `fullscreenKey`, see the documentation for more info.
This is currently off by default, we will consider turning it on by default in the future, see #5765.
Fixes#4048, fixes#3022.
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.
This reverts the previous fix (2bc90a1)
and also simplifies handling. Seems like this works a lot better while
also ensuring that the vjs-fullscreen class is still on the player.
Fixes#5685, fixes#5745
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.
This was done to make the behavior on Android with HLS live streams better but the it's opening us up to too many potential issues, like a user not being able to properly disable the control bar, that we should just back it out.
Before the fullscreen API was un-prefixed, we listened to triggered a
`fullscreenchange` event on the player manually. This worked fine
because a prefixed `fullscreenchange` event was triggered on the player
element itself. But when it was unprefixed, we ended up with two events
now, the unprefixed event and the one we triggered.
Instead, we should listen the event the browser supports and re-trigger
it as the unprefixed event as necessary.
We also make sure that the handler gets calls when the document level
fullscreenchange handler gets called so that it is cancelled properly.
Fixes#5685.
`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
To make the seek-to-live component more accessible, we hide the text that says "LIVE" from screen readers and make it be purely for sighted users. Then set the control text to be either "Seek to live, currently playing live" or "Seek to live, currently behind live" to indicate what this control does and be informative around whether we are at edge or not. Then use aria-disabled on control if we are at edge.
- Update the Control Text in the load-progress-bar during loading, remove unnecessary Control Text from the play-progress-bar, and hide the time-tooltip feature from Assistive Technology using ARIA.
- Add a span around the vjs-control-text-loaded-percentage in load-progress-bar, and use that for the text to update.
- Hide the time-tooltip feature from Assistive Technology using ARIA
Fixes#5251
The desired behavior when navigating any of the TimeDisplay components (current time, duration, remaining time) with the arrow keys with a screen reader is for the singular parent div to receive focus, and the reader should announce the text of each child span in order, ex. "Current Time 0:17" and "Duration 1:10". This is how it works when using JAWS. However, with VoiceOver each individual child span element receives focus and the contents are announced separately.
According to the ARIA spec (see [here](https://www.w3.org/TR/html-aam-1.0/#details-id-124) and [example 8](https://www.w3.org/TR/wai-aria-1.1/#presentation)), there is no implicit role for span elements, so the contents should be exposed but the elements themselves should be invisible to screen readers. In other words, <span> Sample Content </span> should be the same as <span role="presentation"> Sample Content </span>. But this is not the case with VoiceOver. As far as I can tell, the desired behavior is only achieved with VoiceOver if each child span is explicitly made presentational, either by assigning each of them the presentation role, or by assigning the parent div a role that makes its children presentational (although there doesn't seem to be a role whose semantics fit the purpose of that div)
The first ARIA doc link above shows the Mac OS X Accessibility Protocol mapping for span elements is to the group role. I don't know enough about accessibility API mapping to confidently draw conclusions about root cause, but this seems like a possible explanation.
Changes:
* add role="presentation" to each of the two span elements inside TimeDisplay divs
* add aria-hidden="true to the TimeDivider (tangential improvement)
* fix inaccurate description of the TimeDisplay component (tangential improvement)
- 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.
When responsive mode is set, make the caption settings dialog be more responsive to the size of the player.
Make whitespace and sizing a bit more consistent across elements.
This allows the duration NaN or 0 to update the duration display.
This also resets the duration display when a new media item is loaded with `preload` set to 'none'.
Fixes#5347
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.
Instead of checking for blob urls in the generic updateSourceCaches method, check for blob urls inside of handleTechSourceset before updating the source cache.
Fixes#5504.
Add support for focus-visible so that mouse-users don't need to see focus outlines but keyboard and Screen Reader users still do. It includes both the standard selector and the selector intended to work with the polyfill: https://github.com/WICG/focus-visible.
The polyfill is *not* included in Video.js and must be included on the page separately.
Fixes#5474.
Move the ResizeManager behind the video element with negative z-index and remove visibility: hidden. This fixes issue where right click event wasn't triggered on the correct element and resize was not happening on firefox.
The default button type is "submit" which triggers a form submit. Thus
if videojs is embedded in a form element the button triggers a form
submit.
This is the same problem with same solution as discussed in https://github.com/videojs/video.js/issues/2470
Follow-up for #5471
This makes the breakpoints option and `breakpoints()` method clearer and introduces the responsive option and `responsive()` method, which will turn on the breakpoints.
The return value of `currentBreakpoint()` was simplified to only ever return a string (empty if none).
Also, added convenience methods: `responsive()`, `getBreakpointClass()`, and `currentBreakpointClass()`.
This adds a breakpoints option. By default, this option is false meaning this is an opt-in feature.
When passing true, it will use a default set of breakpoints. Or custom breakpoints can be passed if users do not like our breakpoints (or previously-existing style decisions).
- Add breakpoints option.
- Adds some new (currently unused) classes: vjs-layout-medium, vjs-layout-large, vjs-layout-x-large, and vjs-layout-huge.
- Add updateCurrentBreakpoint and currentBreakpoint methods to the player.
- Update css/components/_adaptive.scss
- Add sandbox/responsive.html.example
Closesvideojs/video.js#4371
Like fluid mode, you can enable it with the class or by calling the fill
method. Calling fill() will turn off fluid mode and calling fluid() will
turn off fill mode.
Fluid mode takes precedence over fill mode.
Create a new createLogger module for better debugging. Each logger has its own log level and its own createLogger that will nest logs underneath them. `player.log` is also included, which logs the player id as part of the log statement. The history API also got a filter method.
For example:
```js
var log = videojs.log.createLogger('foo');
log('hello');
// > VIDEOJS: foo: hello
```
On mobile devices, when changing orientation, or if the player gets resized, the captions won't update to reflect the new orientation or player size. However, they do get updated the next time they are redrawn. Instead, we should redraw the captions whenever `orientationchange` and `playerresize` get triggered.
It's possible that ResizeManager will trigger its debounce handler but
then get disposed before the handler runs. This can cause tests to fail,
so, instead, we should cancel the debounce when ResizeManager is
disposed.
If Promise is available or if Promise is polyfilled, then we'll return a new Promise from `play()` that will get fulfilled with the value returned from the `play()` method. This means that on IE11, this promise will get resolved when we call `play()` even if play doesn't succeed. We will have a follow-on PR to polyfill this behavior and resolve or reject the promise for browsers like IE11 that don't return a promise from `play()`.
Because we add Touch Activity in the parent class and those don't actually get removed in Resize Manager we leak on every dispose. Calling super.dispose() cleans them up because we remove our list of handlers via a call to DomData.removeData
Fixes#5339
It's possible for us to get a blob url for sourceset, but when we do, we
shouldn't update the source caches with that information.
blob urls can arise when playback is done via Media Source Extension (MSE) such as m3u8 sources with @videojs/http-streaming (VHS).
Angular CLI, and potentially other projects, may use the "pure_getters" compression option of uglify which will end up removing the getter line we use for side-effects to update the active cues. This update makes sure that the line doesn't get removed.
Fixes#5131
Trigger the change event on the next tick. This means that multiple changes to a track's mode will only result in a single change event on its associated TextTrackList rather than 3 events as it may be currently.
Fixes#5159
setSource is useful if you care to be fiddling with the source or doing some work depending on what source is set. However, sometimes, you don't need a setSource and want the middleware to always be selected.
Now, if setSource is missing, it will implicitly be included in the middleware chain.
Our setTimeout and requestAnimationFrame methods added dispose handlers so that they get cancelled if the component is disposed before they get a chance to run. However, we were only clearing out these dispose handlers if we cleared the timeout or the rAF manually. Instead make sure that we remove the dispose handler when it is no longer needed.
Fixes#5199.
If the source is not loaded, `player.play();` returns `undefined` on Firefox and Edge, which causes exception.
With this fix, player will not make exception and the fallback (`player.play()` execution after loading video) will be enabled.
Currently, VideoJS combines volume control with muted support, and these actions aren't actually the same. Muting/unmuting volume work independently from the volume control. For example, iOS doesn't support controlling volume programmatically but allows muting/unmuting volume.
This change will display the volume control panel and mute toggle button if the tech supports muting volume. The volume slider will continue to be hidden if the platform doesn't allow programmatically control volume. If neither muting nor control volume is supported, volume panel will not be displayed.
Fixes#4478.
This PR extends the `autoplay` to the player with a few options that should hopefully make working with browsers that disable unmuted autoplay by default easier.
The current boolean option will match current behavior and any unknown option will be treated as it does now. The new options are the string values `muted`, `play`, and `any`.
- `muted` will mute the element and call `play()` on `loadstart`,
- `play` will call `play()` on `loadstart()`, this is similar to the `autoplay` attribute
- `any` will call `play()` on `loadstart()` but if it fails it will try muting the video and calling `play()` again.
When providing the TextTrackDisplay component with track settings overrides, currently colour codes with only three digits are supported. This updates it so that 6 digit hex codes are also accepted.
the bug is that objects using the new-ish evented mixin cannot listen to the window object, preventing things like:
```
component.on(window, 'scroll', throttledListener);
```
This fixes that so anything that's a native EventTarget works.
The changes to source caching in #5156 introduced a regression where the source options were no longer available to plugins. This PR makes sure the cached source object retains any source options passed along.
Currently, if longer captions labels are used the SubsCaps menu gets all messed up in IE11/Edge. This occurs due to the menu size is not adjusted correctly not taking into consideration the CC icon. This, as a result, causes the captions items not to fit in the menu and because they end up too wide and the menu has overflow: auto style, the horizontal scrollbars show up and cause the menu not to render correctly. Therefore, don't position the caption label absolutely.
Fix#4758.
Instead of calling preventDefault() on touchstart in Chrome, set touch-action: none style on progress control to prevent unintended scrolling.
Fixes#4650.
Change most menu items to an ARIA role of "menuitemradio" when only one item can be selected (i.e. in the Captions, Subtitles, Descriptions, Chapters, Audio Tracks, and Rate menus).
Fixes#5136
When having a video-js embed with a class attribute, as part of the
changes to remove old IE support (#5041), we overwrote our addition of
the video-js class when it was missing. Instead, we want to make sure
that we don't override the class names again since they are already set
up correctly.
Fixesvideojs/http-streaming#100
Restore hidden label text for screen readers that describes what the button control does.
Renames the Duration Time language item to Duration.
Deprecate controlText_ property.
Fix a typo in translations-needed.md.
Add a space in the hidden label for live-display, so that it doesn't run together with the visible "LIVE" indication.
Fixes#5135
There doesn't seem to be any point in indicating the Control Bar as a separate object - it's all just part of the video player. Perhaps in the future, if there's content which isn't part of the control bar that needs to be clearly distinguishable from the control bar, then it would make sense, but right now you don't interact with the control bar and it doesn't convey any concept of grouping.
Fixes#5134
Move the aria-live attribute to the control text element within buttons, rather than on the whole button, so it is not affected by the change of the title attribute, only by the change of the control text.
It seems like having aria-live on the button itself means that JAWS and NVDA announce the button both when the button text changes and when the title attribute changes. NVDA speaks the new label more times because it announces the button text as the label and the title as the description, so it says, for example, "pause button pause". JAWS doesn't appear to do this, so it doesn't repeat it as many times.
Partially addresses #5023
* We now trigger `sourceset` any time a `<source>` element is appended to a mediaEl with no source.
* `load` should always fire a `sourceset`
* `sourceset` should always be the absolute url.
Makes it easier to extend the seekbar and change the default event handlers. If you extend the seekbar component you can choose to override setEventHandlers_ or keep it default. If you do override setEventHandlers_ and call super() in the constructor, you get your own event handlers + the functionality provided by Slider.
There is no need to listen for user activity until a play is requested on the player and it just adds an extra timer for a player that hasn't started playing yet. Instead, just wait till the first `play` event.
Closes#5076.
SourceHandlers that use MSE have a problem: if they push a segment into a SourceBuffer and then seek close to the end, playback will stall and/or there will be a massive downswitch in quality. The general approach to fixing this that was discussed on slack was by setting the playback rate of the player to zero, buffering all that was required, and then restoring the previous playback rate. In my implementation, I've done this in the source handler (see: videojs/videojs-contrib-hls#1374).
From the video.js perspective, it should ensure that the UI reflects the buffering status and that the player API behaves like you'd expect -- that is to say, that it will fire seeking immediately after a call to currentTime, and it will fire seeked, canplay, canplaythrough, and playing when everything is buffered.
In Chrome/Firefox/Safari appending a <source> element when the media element has no source, causes what we think of as a `sourceset`. These changes make our code actual fire that event.
This was found due to the work done in #4660. Basically we reload the video element twice on every source with preload set to auto. This can potentially cause the same data to be downloaded twice.
This PR is to add HLS playback support built into video.js for 7.0 via videojs-http-streaming (shorthand VHS). VHS is the next major version of videojs-contrib-hls that removes HLS Flash playback and includes some experimental DASH support (hence the rename). The purpose is to improve the out-of-the-box experience for video.js and allow cross browser HLS compatibility.
The proposed changes are to have the standard video.js browser and module scripts contain VHS and provide an alternate video.js browser script that does not contain VHS.
A video.js/core export is provided for importing without VHS.
If .load() is called, we don't know what the new source will be because of the asynchronous nature of the resource selection algorithm. However, we can know if the src attribute is set on the video element because that's what will be chosen. So, set the src property on the event object to be the src attribute or be the empty string. This matches how currentSrc works where it is an empty string when no source is set. So, when sourceset is triggered and src is "" in the event object, it means that the source is changing.
In addition, we're going to be releasing sourceset as an experimental feature so we could improve the API and make changes in minor releases.
This reverts commit 6fe7a9a.
The PR #4804, which fixes#4720, causes a regression #5005. When testing for the regression, the original issue is no longer reproducible so the fix should be backed out. If someone is still using the old version of chrome and seeing the behavior of #4720, they can continue using the versions of Video.js that contain the fixed made in #4804: 6.5.2, 6.6x, 6.7.x.
Fixes#5005.
If CSS Grid is available, the Captions Settings Dialog will use it for the layout to begin making it more responsive.
It will fallback to the current layout method if CSS Grid isn't available.
Add setFormatTime for Video.js to allow users to change the time format. Example usage:
```js
videojs.setFormatTime((seconds, guide) => `${seconds}, ${guide}`));
```
Add resetFormatTime to reset the time format to the default.
Fixes#2931
The option for the player techCanOverridePoster is introduced in this commit. It allows techs to update the post whenever they like. isPosterFromTech_ is introduced as a private player field in order to track when a poster was set by a tech. This allows us to clear the poster whenever the tech is disposed of by the player.
Additionally, attempting to set the same poster more than once will have no effect / no changes will be made, since the poster is the same. This was done in order to stop triggering multiple posterchange events when calling player.poster(aPoster) with techCanOverridePoster set to true.
When a tech is disposed and a poster was set by it, unset the poster.
Pass a `canOverridePoster` option to techs to know whether techCanOverridePoster was set.
Fixes#4910.
Trigger a sourceset event whenever the source is set in the Html5 tech, including initial source. We override the video element's src and setAttribute methods so that we can trigger the sourceset event when people change the src with both the video element and our API methods.
The event object for sourceset will contain the src string that was provided at the time the sourceset was triggered. This is mostly important if a source is being set while a tech is changing.
A Tech has a featuresSourceset option that it can set to for sourceset handling. It can then call the helper triggerSourceset(src) to trigger the sourceset.
If a user disabled the text track setting component, trying to play emulated captions would crash. Add a null check before applying the text track settings.
Fixes#4964.
This is a first in a few changes related to #4902. This just adds a text alternative to the loading spinner. In future PRs, we would make it alert to screen readers and potentially have a generic alerting mechanism.
Scrubbing inside the seekbar paused the player properly but scrubbing inside the progress control outside the seekbar, the player never paused. This meant that when you scrubbed, if you kept the mouse down but lingered for a moment, the player would continue playing until the mouse moved again.
This fixes it so that the seekbar mousedown and mouseup handlers are called when the progress control mousedown and mouseup handlers are triggered.
Middleware factories currently get run each time a source is set. Because middleware are assocated with a player, the factories should only run once per player.
This PR fixes it so that we associate a middleware instance with a middleware factory per player.
Each time a player is disposed, we will clear the cache of the middleware instances for that player.
Fixes#4677.
These changes address an issue where screen readers may repeatedly and redundantly read TextTrackMenuItem's control text on every texttrackchange event in some browsers.
The source of the problem is in the handleTracksChange() method of TextTrackMenuItem and its subclass OffTextTrackMenuItem, in which this.selected(true/false) gets called even if the selected state has not changed since its previous invocation.
Use ResizeObserver when available for better and more performant resizing information, otherwise, fall back to a throttled resize event on an iframe that's the size of the player.
Allows a video.js user to disable this by setting resizeManager: false as an option since the component will not be initialized.
Add a debounce util.
This reverts #4800 (e0ed0b5) because we end up getting two playerresize events with the dimension methods now.
This will allow middleware to interact with calls to play() from the tech. This will require a method of indicating to middleware previously run that a middleware down the chain has terminated or stopped execution.
* Adds middleware mediator method that runs middleware from the player to the tech and a second time back up to the player. This category was created because play is both a setter(changes the playback state) and a getter(gets a native play promise if available). This also has the ability to tell whether a middleware has terminated before reaching the tech.
* Adds a middleware.TERMINATOR sentinel value that is available on the videojs object
* Adds play to the allowedMediators
* Adds paused to the allowedGetters
* Adds a sandbox example of a play mediator middleware
Chrome has started pausing autoplaying video elements when they are
moved in the DOM. Here we need to make sure that if the video started
autoplaying, after we move the element in the DOM we call play again.
Fixes#4720.