Video.js Blog

Matthew McClure2014-10-02

Video.js 4.9 - Now <audio> can join the party!

HTML5 Audio support

A common request weve seen is to be able to use Video.js with an <audio> tag, and now you can! Usage is almost identical, you can just include a data-setup={} attribute on an <audio> tag or initialize via Javascript.

<audio
  id="audio_example"
  class="video-js vjs-default-skin"
  controls
  preload="auto"
  width="600"
  height="600"
  poster="/img/awesome-album-art.png"
  data-setup="{}"
>
  <source src="/audio/awesome-music.mp3" type="audio/mp3" />
</audio>

The only differences in behavior are that the poster image and controls are never hidden. This allows you to keep up something like album art during playback rather than a black video element. Since theres no interesting content to hide (other than the poster image), we leave the controls showing to mimic a familiar audio player experience.

Audio Screenshot

Note: The Flash fallback still doesnt support audio-only sources, but wed like to add that in the future. In the meantime, audio playback with MP3 and Ogg sources should work fine in any (modern) browser thats not IE8, so enjoy!

More translations!

Weve been really excited by the continued support in terms of new translations. This release contains Brazilian Portuguese, Japanese, Italian, French, and Korean, as well as some improvements to the previous Spanish translation. Wed love to see the trend continue, so if youre fluent in a language please consider submitting improvements or whole new localizations!

Video.js in the wild

Coursera is an education platform that offers free courses online from some of the worlds top institutions. Theyve built great tools for video interaction on top of Video.js, and are even going to talk about some of the work theyre doing at Octobers SF Video Meetup.

Coursera Screenshot

New Plugins

videojs-wavesurfer - Adds a navigable waveform for audio files, using the excellent wavesurfer.js library.

Full list of changes

  • @deedos added a Brazilian Portuguese translation (view)
  • @baloneysandwiches added a hasClass method (view)
  • @mynameisstephen fixed an issue where slider event listeners were not being cleaned up (view)
  • @alexrqs cleaned up the Spanish translation (view)
  • @t2y added a Japanese translation (view)
  • @chikathreesix fixed an issue where data-setup options could be missed (view)
  • @seniorflexdeveloper added new translations and translation updates (view)
  • @chikathreesix exported the videojs.Flash.embed method (view)
  • @doublex fixed an issue with IE7 backwards compatibility (view)
  • @mmcc made it possible to override the font-size of captions and subtitles (view)
  • @philipgiuliani added an Italian translation (view)
  • @twentyrogersc fixed the return value when setting the poster source (view)
  • @heff updated to swf v4.5.0 to fix event issues (view)
  • @rpless made the VolumeMenuButton volume more accesible via tab navigation (view)
  • @mmcc added support for audio tags (html5 audio only) (view)

Matthew McClure2014-09-03

Video.js 4.8.0 released...Prost!

This isnt the flashiest minor release ever, but its hot off the press and ready for use. As mentioned in the last (few) release posts, were making a concerted effort to be more consistent with releases, so hopefully the trend of bite-sized, scheduled releases will continue.

Translations

We only just released localization with version 4.7, but weve already had two pull-requests for new translations! The German translation is included with this release, and youll find the French translation in the next patch release. If youre fluent in another language, you can help Video.js be even more internationally accessible by submitting a pull request translating just 24 words / phrases. </shameless_plug>

Video.js in the wild

Heavybit Industries has a speaker series they host at their office, and theyve been kind enough to start posting these sessions online in their library. The experience theyve built using Video.js is impressive, including syncing the video progress with a transcript below the player.

Heavybit Screenshot

New plugins

Full list of changes

  • @andekande added a German translation (view)
  • @mattosborn fixed a bug where getting the video element src would overwrite it (view)
  • @songpete fixed a bug where keyboard events were bubbling and causing additional actions (view)
  • @knabar made the inactivity timeout configurable (view)
  • @seniorflexdeveloper added language files to the distribution for including specific languages (view)
  • @gkatsev improved handling of null and NaN dimension values (view)
  • @gkatsev fixed an issue where the controls would break if Flash was initialized too quickly (view)
  • @mmcc fixed an issue where if no playback tech was supported the error could not be caught (view)

Steve Heffernan2014-08-06

Video.js v4.7.0 - Built mostly by NEW contributors! Also Google chooses Video.js

Were continuing to work hard on improving the contributor experience around the Video.js project and its paying off. Over half of the changelog is thanks to brand new contributors! Issues and pull requests are getting addressed faster than ever, and I was even allowed to give a talk at OSCON on some of the strategies were using. If youre instersted in getting involved, join the #videojs IRC room or post an issue to let us know.

Google Chooses Video.js for Google Media Framework

Google recently announced a new framework for building video experiences and monetization. There are versions of the framework for native iOS and Android apps, and for the browser they chose to use Video.js. Check out their video.js plugin, and as it says in their announcement, Stay tuned as well for a deeper dive into Video.js with IMA soon!

Localization

In this release weve built the infrastructure for displaying text in other languages. Examples of text include error messages and text used for accessibility. This feature can extend to plugins as well.

Today you can include other languages by including the JSON translations object from the language you want with the player, like in this example for Spanish (es).

videojs.options.languages['es'] = { [translations object] }

You can find translations files in the lang folder of the project. We dont have many translations yet, but were looking for translators if youd like to help!

Multiple buffered regions

With HTML5 video you can skip ahead in the video and the browser will start downloading the part of the file needed for the new position, which is different from how Flash video works by default. Flash will download from the start to the end of the file so you can only skip ahead once it has download that part of the video.

In the HTML5 video API were given the buffered property which returns a list of time ranges that the browser has downloaded data for. Early on in HTML5 video, browsers only ever reported one time range, but now we have a direct view of whats been downloaded.

In the newest version of the video.js skin you can see the specific regions.

Weve kept it subtle so its not too big of a change. Wed love to hear your thoughts on it.

DASH Everywhere-ish

If you havent seen it yet, check out the post on Tom Johsons work getting DASH supported in Video.js, using Flash or the new Media Source Extensions. MPEG-DASH is an adaptive streaming format that Netflix and YouTube are using to stream video to cutting-edge browsers. It has the potential to replace Apples HTTP Live Streaming format as the main format used for adaptive streaming.

Video.js on Conan!

Conan O'Briens TeamCoco site is using Video.js with a nicely customized skin and ads integration. Check it out!

New Skin by Cabin

The team at Cabin put together a simple and clean new skin for video.js.

New Plugins

A lot of great new plugins have been released!

  • videojs-ima: Easily integrate the Google IMA SDK into Video.js to enable advertising on your video content.
  • videojs-brightcoveAnyaltics: Allow tracking of views/impressions & engagement data in videojs for Brightcove videos
  • videojs-logobrand: Add a logo/brand image to the player that appears/disappears with the controls. (also useful as a basic plugin template for learning how Video.JS plugins work.)
  • videojs-seek: Seeks to a specific time point specified by a query string parameter.
  • videojs-preroll: Simple preroll plugin that displays an advertisement before the main video
  • videojs-framebyframe: Adds buttons for stepping through a video frame by frame
  • videojs-loopbutton: Adds a loop button to the player
  • videojs-ABdm: Use CommentCoreLibrary to show comments (which is called as DanMu) during playing.
  • videojs-hotkeys: A plugin for Video.js that enables keyboard hotkeys when the player has focus.

New Release Schedule

As part of improving the contributor experience were moving to scheduled releases. Well now put out a release every other Tuesday as long as theres new changes to release. This will help give everyone a better idea of when specific features and fixes will become available.

Full list from the change log

  • Added cross-browser isArray for cross-frame support. fixes #1195 (view)
  • Fixed support for webvtt chapters. Fixes #676. (view)
  • Fixed issues around webvtt cue time parsing. Fixed #877, fixed #183. (view)
  • Fixed an IE11 issue where clicking on the video wouldnt show the controls (view)
  • Added a composer.json for PHP packages (view)
  • Exposed the vertical option for slider controls (view)
  • Fixed an error when disposing a tech using manual timeupdates (view)
  • Exported missing Player API methods (remainingTime, supportsFullScreen, enterFullWindow, exitFullWindow, preload) (view)
  • Added a base for running saucelabs tests from grunt (view)
  • Added additional browsers for saucelabs testing (view)
  • Added support for listening to multiple events through a types array (view)
  • Exported the vertical option for the volume slider (view)
  • Fixed Component trigger function arguments and docs (view)
  • Now copying all attributes from the original video tag to the generated video element (view)
  • Added files to be ignored in the bower.json (view)
  • Fixed an error that could happen if Flash was diposed before the ready callback was fired (view)
  • The up and down arrows can now be used to control sliders in addition to left and right (view)
  • Added a player.currentType() function to get the MIME type of the current source (view)
  • Fixed a potential conflict with other event listener shims (view)
  • Added support for multiple time ranges in the load progress bar (view)
  • Added vjs-waiting and vjs-seeking css classnames and updated the spinner to use them (view)
  • Now restoring the original video tag attributes on a tech change to support webkit-playsinline (view)
  • Fixed an issue where the user was unable to scroll/zoom page if touching the video (view)
  • Added sliding class for when slider is sliding to help with handle styling (view)

Cheers,

-heff

Discuss on Twitter | Discuss on Hacker News

Steve Heffernan2014-07-22

DASH Everywhere-ish (hack project)

A couple of times a year Brightcove has an internal hackweek where engineers work on any project theyd like. In the latest hackweek (2014-07-14) Tom Johnson decided to see if he could get DASH supported in as many places as possible, by combining a few of the existing DASH player implementations with Video.js.

MPEG-DASH (Dynamic Adaptive Streaming over HTTP) is a streaming format similar to Apples HTTP Live Streaming (HLS). It allows you to provide multiple versions of a video at different bitrates, and then the player can switch between those versions depending on the users bandwidth (which is more complicated than you might think).

The two DASH playback implementations used were Dash.js and Dash.as. They were combined using video.jss playback tech architecture, which means you can include plugins and custom skins and theyll work the same with either playback method.

See the results.

Browser/Device Coverage

Using a combination of DASH.AS and DASH.JS will give us the following browser/device coverage:

DASH.JS (media source extensions support)

  • Internet Explorer: 11+
  • Chrome: 23+
  • FireFox: 25+ (upcoming version)
  • Safari (Desktop): 8+ (OSX Yosemite - Fall 2014)
  • iOS: No
  • Android: 4.2+ (Chrome)

DASH.AS

Fallback to any environment that supports Flash Player 10.3

iOS

As you can see, the one remaining holdout is iOS and theres currently no word when or if that will happen. Seeing media source extensions support in Safari 8 gives some hope, but my understanding is the requirements for getting support built into iOS are much more significant. My guess is it will happen eventually, but not for a while (and hopefully in-line playback + the fullscreen API will be supported at the same time).

Today, to provide adaptive streaming everywhere, you still need either DASH + HLS, or just HLS (you can use the video.js HLS plugin to support HLS in more browsers).

Toms Notes

The demo shows that for environments which support Media Source Extensions (MSE) we use a full Javscript implementation via Dash.js and as a fallback we use Flash built around OSMF and Dash.as, an open-source plugin provided by Castlabs.

Tom has been working on videojs-osmf on the side, which helped make this possible.

DASH.AS Requirements

Player

  • Environment must support Flash Player 10.3+
  • Video.js OSMF Tech (videojs-osmf)
  • CastLabs Dash.AS plugin for OSMF (dash.as)

Server/Host

  • Since the requests are fired from within Flash, a crossdomain.xml file is required.* Ability to serve byte range requests via query string (myFile.mp4?range=0-1000 || myFile.m4s?bytes=0-1000) is necessary because Flash Player restricts use of the ‘Range’ request header. Castlabs has an .htaccess file which uses mod_rewrite to achieve this. Akamai edge servers accept the bytes query string var as well.

Notes

  • Something we may want to modify is handling the request/response portions of the workload outside of the Flash Player similar to the Video.js HLS solution. This would remove the need for having a crossdomain.xml, which cannot be normally expected to exist in a DASH focused environment.
  • Akamai edgesuite appear to be an exception to the above rule, as those domains do in fact have the crossdomain from it’s use as a serving platform under Akamai HD. The Akamai param syntax is ‘myFile.m4s?bytes=XXXX-YYYY’.
  • In it’s current form the Dash.AS manifest parser is very rigid. We may want to look into implementing a version of the DASH.JS manifest parsing on the AS side, as it is a lot more flexible in terms of structure recognition.
  • Deeper class inspection shows that the Dash.AS plugin is based on using Netstream in data generation mode, similar to our HLS solution. There may be better way to share the codebase between the two to reduce code duplication.

DASH.JS Requirements

Player

Server/Host

  • Open CORS headers: Access-Control-Allow-Origin: *
  • Accept use of the Range request header: Access-Control-Allow-Headers:Range, Options

Notes

  • Dash.js MPD parsing is significantly more robust in comparison to the Dash.AS solution.
  • Most streams tested are Akamai based, we should probably try more local and non-Akamai hosted options moving forward.* In my testing I did see a Youtube DASH/MSE example, and those streams were confirmed to work within Dash.JS as well.
  • Dash.JS streaming lifecycle and segment loading lifecycle tend to be directly coupled and don’t necessarily fire the element media events at the time expected. For example is duration. While known at the parse complete stage of the manifest load cycle, is not reported to the player until the first of the segments is received.

Tech Compatibility

The independant techs work well together. A slight modification had to be made to the Dash.AS library to insure that it only checked for resources which 1. had a URL and 2. url contained the file extension of either ‘mpd’ or ‘m4s’ for DASH manifests/segments.

NOTE: Dash.JS tech should be loaded into DOM prior to OSMF tech to insure the OSMF tech is the fallback scenario for DASH playback.

Steve Heffernan2014-05-20

Video.js version 4.6.0 released! It's been a productive month.

The video.js community has been in full force lately and its resulted in a lot of great features and fixes, including UI updates, better error messages, and even a Video.js Polymer element built by Addy Osmani himself.

New Live UI

Video.js has supported different forms of live video for a while, but a recent update has made the user experience a little clearer. Specifically, a LIVE badge is added to the controls and the seek bar is hidden when seeking isnt permitted.

Clearer Errors

A big effort went into improving error situations that developers and viewers might encounter. In cases where the viewers browser supports neither JavaScript nor HTML5 Video, a more helpful message is shown that informs the viewer how they can support video playback.

In cases where a common media error occurs (e.g. the file doesnt exist or the network fails), an X icon is displayed showing that playback cant continue, and a message is shown describing the issue. Additionally an error message is logged to the javascript console.

For developers, better logging functions have been added including videojs.log.error(), and theyre being used throughout the code base to provide better information and help track down issues.

IE11 Fullscreen

Video.js relies on native browser fullscreen even when Flash is used. IE11 is the first version of Internet Explorer to support native browser fullscreen, and video.js has now been updated to take advantage of that feature and provide a better fullscreen experience for those users.

Playback Rate Switching

If you ever wanted to speed up or slow down the rate of a video, now you can! HTML5 video browsers have been adding support for playback rate switching, and video.js now has an optional UI component that will let you select the speed. Flash however does not support playback rate switching, so unfortunately its not a feature that users on older browsers (e.g. IE8) can use.

See a demo.

New community plugins

The latest plugins to be added to the video.js plugins list.

  • videojs-vr: Project video onto different geometric shapes (Sphere, Cube, Cylinder) and view in 3d with optional Oculus Rift support
  • video-speed: Adds customizable video-speed control
  • OpenVideoAnnotation - create annotations in video-js using annotator
  • videojs-overlay: display simple HTML overlays during video playback
  • video.js-polymer: A video.js element for the Polymer web components framework

If youd like a head-start on the scaffolding for a new video.js plugin, check out the Yeoman video.js plugin generator.

Full list from the change log

  • Updated the UI to support live video (view)
  • The UI now resets after a source change (view)
  • Now assuming smart CSS defaults for sliders to prevent reflow on player init (view)
  • Fixed the title element placement in menus (view)
  • Fixed title support for menu buttons (view)
  • Fixed extra mousemove events on Windows caused by certain apps, not users (view)
  • Fixed error due to undefined tech when no source is supported (view)
  • Fixed the progress bar not finishing when manual timeupdate events are used (view)
  • Added a more informative and styled fallback message for non-html5 browsers (view)
  • Added the option to provide an array of child components instead of an object (view)
  • Fixed casing on webkitRequestFullscreen (view)
  • Made tap events on mobile less sensitive to touch moves (view)
  • Fixed the default flag for captions/subtitles tracks (view)
  • Fixed compilation failures with LESS v1.7.0 and GRUNT v0.4.4 (view)
  • Added better error handling across the library (view)
  • Updated captions/subtiles file fetching to support cross-origin requests in older IE browsers (view)
  • Added support for playback rate switching (view)
  • Fixed an issue with the loadstart event order that caused the big play button to not hide (view)
  • Modernized the fullscreen API and added support for IE11 (view)
  • Added cross-browser testing with SauceLabs, and added Karma as the default test runner (view)
  • Fixed saucelabs integration to run on commits in TravisCI (view)
  • Added a clearer error message when a tech is undefined (view)
  • Added a cog icon to the font icons (view)
  • Added a player option to offset the subtitles/captions timing (view)

The new version is available on videojs.com and has been added to the CDN.

Cheers,

-heff

Steve Heffernan2014-03-27

Video.js version 4.5.0 released! Nothing to see here, move along

Well, sort of… this release is the result of a lot of hard work to speed up the version release process, meaning theyll be coming a lot faster now with smaller sets of changes.

In this release weve added support for the Component(1) package manager, fixed the captions positioning when the controls are hidden, and helped Android devices know when they can support HLS. ;-) There were a few other changes as well but a lot of the work this round was done on the processes around the project. If youve spent time in the github issues, youll hopefully notice an improvement in the response rate on issues and the speed in which bugs get fixed.

New plugins

  • videojs-vast: A VideoJS plugin to play pre-roll videos from a VAST feed
  • videojs-comscore: Reports to comScore using their latest Streaming Tag SDK

Video.js in the wild

Toyota Europe! (click a video on that page) I was in Paris a few weeks ago and stopped by the Toyota store on Champs-Elysées. Next to the cars are multimedia touch screens that tell you details and allow you to watch videos. The video player looked kind of familiar, and sure enough it was video.js with a very nice custom skin. It turns out the Toyota Europe website uses video.js as well. Very cool.

If you find video.js on an interesting site somewhere, let us know in the comments.

Full list from the change log

  • Added component(1) support (view)
  • Captions now move down when controls are hidden (view)
  • Added the .less source file to the distribution files (view)
  • Changed src() to return the current selected source (view)
  • Added a grunt task for opening the next issue that needs addressing (view)
  • Fixed Android 4.0+ devices check for HLS support (view)

The new version is available on videojs.com and has been added to the CDN.

Cheers,

-heff

Steve Heffernan2014-02-19

Video.js version 4.4.0 released - Now supporting RequireJS and Browserify

Version 4.4.0 is here with over 20 updates and fixes. The most notable addition may be support for AMD and CommonJS module loaders, meaning you can now include Video.js using RequireJS or Browserify. Video.js can be installed through npm already, and well soon add support for bower and component(1) as well.

New plugins

The plugin list continues to grow, with more in the works. Checkout the new endcard plugin built by The Onion.

Video.js in the wild

The Brightcove Play 2014 website recently went live with Video.js as the player. Were also hard at work building Brightcoves next-gen player with Video.js at the core, so stay tuned.

Full list from the changelog

  • Made the poster updateable after initialization (view)
  • Exported more textTrack functions (view)
  • Moved player ID generation to support video tags with no IDs (view)
  • Moved to using QUnit as a dependency (view)
  • Added the util namespace for public utility functions (view)
  • Fixed an issue with calling duration before Flash is loaded (view)
  • Added player methods to externs so they can be overridden (view)
  • Fixed html5 playback when switching between media techs (view)
  • Fixed Firefox+Flash mousemove events so controls dont hide permanently (view)
  • Fixed a test for touch detection (view)
  • Updated the src file list for karma tests (view)
  • Added more tests for API properties after minification (view)
  • Updated projet to use npm version of videojs-swf (view)
  • Added support for dist zipping on windows (view)
  • Fixed iOS fullscreen issue (view)
  • Fixed touch event bubbling (view)
  • Fixed ARIA role attribute for button and slider (view)
  • Fixed and issue where a components dispose event would bubble up (view)
  • Quieted down deprecation warnings (view)
  • Update seek handle to display the current time (view)
  • Added requirejs and browserify support (UMD) (view)

The new version is available on videojs.com and has been added to the CDN.

Cheers,

-heff

Steve Heffernan2013-11-05

Video.js version 4.3.0 released w/ shiny new API docs

The biggest change in this update is actually an overhaul of the API docs. The best example of the new docs is the Player doc, which is the API most video.js users will work with.

The new docs are now automatically generated from the code and code comments, making it easier to keep them up to date with whats currently in the codebase.

One interesting note about the doc-generator is that it uses esprima, a tool that reads javascript files and gives back the abstract syntax tree of the code.

For the following javascript:

var hi;

Esprima would generate:

{
    "type": "Program",
    "body": [
        {
            "type": "VariableDeclaration",
            "declarations": [
                {
                    "type": "VariableDeclarator",
                    "id": {
                        "type": "Identifier",
                        "name": "hi"
                    },
                    "init": null
                }
            ],
            "kind": "var"
        }
    ]
}

Were using the AST of the video.js codebase to generate the majority of the information in the docs, which means it requires fewer comments and less work to keep the docs really great as we continue to build. If youre interested in seeing how were handling that, check out the doc-generator repo (its currently only useful with the video.js codebase, but it could be extended to support more).

New CSS Options

Additional updates include new loading spinner icon options, and a new class for centering the big play button.

Many users have been clear that theyd prefer the big play button in the center of the video. While we feel the trend is still moving towards getting the play button out of the way of the content, we wanted to make this feature easier to customize. You can now use the vjs-big-play-centered class on your video tag to center the play button.

To try the new spinner icon options, check out the designer and change the icon name used by the spinner class.

Even more plugins!

Finally, the most exciting developments are actually happening in the video.js community, with more and more plugins being built. Were up to 26 in the plugins list, with more on the way.

If you have some code youve built on top of video.js that you think might be valuable to others, please share it on the plugins list, or post an issue on the video.js repo if you have questions about the plugin process.

Full list from the changelog

  • Added Karma for cross-browser unit testing (view)
  • Unmuting when the volume is changed (view)
  • Fixed an accessibility issue with the big play button (view)
  • Exported user activity methods (view)
  • Added a classname to center the play button and new spinner options (view)
  • Added API doc generation (view)
  • Added support for codecs in Flash mime types (view)

The new version is available on videojs.com and has been added to the CDN.

Cheers,

-heff

Matthew McClure2013-11-05

The Guardian uses Video.js in feature article

Its always nice to find Video.js in the wild, but this article from The Guradian is an especially cool use case. Most of the players dont use controls at all, but rather play/pause based on the user scrolling the page. The ones that do use controls are styled with a white on light gray theme that matches the rest of the page really well.

The article begins with a full-width video that includes controls.

Big Player

Most of the videos are short dialogs that are triggered based on scrolling to a certain point in the page. These have no controls other than an external play/pause button.

No Controls

Smaller player with controls.

Small Player

Steve Heffernan2013-10-15

4.2.2 Patch Release

Two bugs have been squashed with this patch:

  • An issue most commonly seen in Firefox where video playback would break when a race condition would occur during video loading (#756)
  • An issue where the duration would get stuck at 0:00 when loading the player dynamically (#775)

See the changes made

This version can be downloaded on videojs.com, is available on the CDN, and the existing /4.2/ CDN version has been updated to 4.2.2. (may take time to propagate to your area)

Cheers,

-heff