Don't call tech.paused() in the requestVideoFrameCallback fallback if the tech is not ready. I've seen this is an issue in the Flash tech, as its methods are set up after the swf loads. Yes, Flash, it's 2022, but in theory another tech could be impacted if it's also async.
Safari's requestVideoFrameCallback is (intentionally?) broken when DRM is playing, so in that case use the fallback with requestAnimationFrame instead.
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.
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.
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.
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.
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.
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.
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.
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.
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.
We added a feature so that remote text tracks can auto-removed when a source changes. However, in 6.x we changed the source behavior to be asynchronous meaning that some text tracks were accidentally being removed when they weren't supposed to be.
For example:
```js
var player = videojs('my-player');
player.src({src: 'video.mp4', type: 'video/mp4'});
// set second arg to false so that they get auto-removed on source change
player.addRemoteTextTrack({kind: 'captions', src: 'text.vtt', srclang: 'en'}, false);
```
Now when the player loads, this captions track is actually missing because it was removed.
Instead of adding auto-removal tracks immediately to the list, wait until we've selected a source before adding them in.
Fixes#4403 and #4315.
Video.js players can accept a number of standard <video> element options (autoplay, muted, loop, etc), but not currently playsinline, which is now part of the [HTML spec](https://html.spec.whatwg.org/multipage/embedded-content.html#attr-video-playsinline). We should add it to the list of <video> attributes that can be provided to the player as options.
Android Chrome now supports playbackRate properly, so removes the blacklist added in #3246 for newer Chrome versions.
Adds `browser.CHROME_VERSION` as a necessary evil.
No longer blacklists for Chrome 58+ -- this could possibly be fixed since 52, but 58 is all I've been able to test on and most users should keep Chrome up to date.
Previously timeupdate would fire before the video was playing, and the tech was not ready. This caused issues when preload was set to auto, because cuechange would fire before the video was even started for cues with a startTime of 0.
Wait for tech to be ready before watching for timeupdate
update unit tests to use TechFaker
Add a unit test to verify that we wait for Tech to be ready.
* Fixes#3986
* update `techOptions` to look for `TitleCase`/`camelCase` user tech options
* remove deprecated usage of Tech as Component
* add a unit test to verify that registerTech works
* change defaultTech_ to defaultTechOrder_
IE8 can't run the html5 tech and the mute toggle tests rely on a working
volume and mute functionality which tech faker does not have. Instead of
implementing it in tech faker, skip it on non-html5 environments.
Middleware registration now only accept a factory method which takes a player reference and returns some object that represents the middleware with the various methods on it.
Also, add a use to register a middleware for all types.
Add middleware support. Middleware can function as go-between between the player and the tech. For example, it can modify the duration that the tech returns to the player. In addition, middleware allow for supporting custom video sources and types.
Currently, middleware can only intercept timeline methods like duration, currentTime, and setCurrentTime.
For example,
```js
videojs.use('video/foo', {
setSource(src, next) {
next(null, {
src: 'http://example.com/video.mp4',
type: 'video/mp4'
});
}
});
```
Will allow you to set a source with type `video/foo` which will play back `video.mp4`.
This makes setting the source asynchronous, which aligns it with the spec a bit more. Methods like play can still be called synchronously on the player after setting the source and the player will play once the source has loaded.
`sourceOrder` option was removed as well and it will now always use source ordering.
BREAKING CHANGE: setting the source is now asynchronous. `sourceOrder` option removed and made the default.
* Switch to es3 preset for babel so that it runs last. Plugins run before presets and presets run in reverse order. Also, we ran into a weird bug in babel that causes `default` not to be quoted in some cases (https://github.com/babel/babel/issues/4799) which we've worked around here.
* Restore the es-shims for tests and the ie8 fallback script.
* Do a null-check around `Player.players`.
* use more round fractions (like 0.5 and 1) to avoid rounding issues.
This is both a change as well as a bug fix. We tried to have better awareness of when the underlying video element changed underneath us so we can dispose of the source handler but that broke some use cases of MSE. Given that we weren't able to fix it in a reasonable non-breaking and non-invasive solution, we're taking it out.
BREAKING CHANGE: remove the double loadstart handlers that dispose the tech/source handlers if a secondary loadstart event is heard.