diff --git a/NEWS.md b/NEWS.md index cc4eea5e..34dd755d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,16 @@ +2016-08-23 +========== + +A few weeks ago, the previous Google Drive player stopped working. This is +nothing new; Google Drive has consistently broken a few times a year ever since +support for it was added. However, it's becoming increasingly difficult and +complicated to provide good support for Google Drive, so I've made the decision +to phase out the native player and require a userscript for it, in order to +bypass CORS and allow each browser to request the video stream itself. + +See [the updated documentation](docs/gdrive-userscript-serveradmins.md) for +details on how to enable this for your users. + 2016-04-27 ========== diff --git a/build-player.js b/build-player.js index d02f3536..8ea29dc8 100644 --- a/build-player.js +++ b/build-player.js @@ -8,6 +8,7 @@ var order = [ 'youtube.coffee', 'dailymotion.coffee', 'videojs.coffee', + 'gdrive-player.coffee', 'raw-file.coffee', 'soundcloud.coffee', 'embed.coffee', @@ -19,6 +20,7 @@ var order = [ 'ustream.coffee', 'imgur.coffee', 'gdrive-youtube.coffee', + 'hls.coffee', 'update.coffee' ]; diff --git a/docs/gdrive-userscript-serveradmins.md b/docs/gdrive-userscript-serveradmins.md new file mode 100644 index 00000000..3f4b19a6 --- /dev/null +++ b/docs/gdrive-userscript-serveradmins.md @@ -0,0 +1,24 @@ +# Google Drive Userscript Setup + +In response to increasing difficulty and complexity of maintaining Google Drive +support, the native player is being phased out in favor of requiring a +userscript to allow each client to fetch the video stream links for themselves. +Users will be prompted with a link to `/google_drive_userscript`, which explains +the situation and instructs how to install the userscript. + +As a server admin, you must generate the userscript from the template by using +the following command: + +```sh +npm run generate-userscript [...] +``` + +The first argument is the site name as it will appear in the userscript title. +The remaining arguments are the URL patterns on which the script will run. For +example, for cytu.be I use: + +```sh +npm run generate-userscript CyTube http://cytu.be/r/* https://cytu.be/r/* +``` + +This will generate `www/js/cytube-google-drive.user.js`. diff --git a/gdrive-userscript/cytube-google-drive.user.js b/gdrive-userscript/cytube-google-drive.user.js new file mode 100644 index 00000000..d8fa6655 --- /dev/null +++ b/gdrive-userscript/cytube-google-drive.user.js @@ -0,0 +1,210 @@ +// ==UserScript== +// @name Google Drive Video Player for {SITENAME} +// @namespace gdcytube +// @description Play Google Drive videos on {SITENAME} +// {INCLUDE_BLOCK} +// @grant unsafeWindow +// @grant GM_xmlhttpRequest +// @connect docs.google.com +// @run-at document-end +// @version 1.1.0 +// ==/UserScript== + +try { + function debug(message) { + if (!unsafeWindow.enableCyTubeGoogleDriveUserscriptDebug) { + return; + } + + try { + unsafeWindow.console.log(message); + } catch (error) { + unsafeWindow.console.error(error); + } + } + + var ITAG_QMAP = { + 37: 1080, + 46: 1080, + 22: 720, + 45: 720, + 59: 480, + 44: 480, + 35: 480, + 18: 360, + 43: 360, + 34: 360 + }; + + var ITAG_CMAP = { + 43: 'video/webm', + 44: 'video/webm', + 45: 'video/webm', + 46: 'video/webm', + 18: 'video/mp4', + 22: 'video/mp4', + 37: 'video/mp4', + 59: 'video/mp4', + 35: 'video/flv', + 34: 'video/flv' + }; + + function getVideoInfo(id, cb) { + var url = 'https://docs.google.com/file/d/' + id + '/get_video_info'; + debug('Fetching ' + url); + + GM_xmlhttpRequest({ + method: 'GET', + url: url, + onload: function (res) { + try { + debug('Got response ' + res.responseText); + var data = {}; + var error; + res.responseText.split('&').forEach(function (kv) { + var pair = kv.split('='); + data[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); + }); + + if (data.status === 'fail') { + error = new Error('Google Docs request failed: ' + + 'metadata indicated status=fail'); + error.response = res.responseText; + error.reason = 'RESPONSE_STATUS_FAIL'; + return cb(error); + } + + if (!data.fmt_stream_map) { + error = new Error('Google Docs request failed: ' + + 'metadata lookup returned no valid links'); + error.response = res.responseText; + error.reason = 'MISSING_LINKS'; + return cb(error); + } + + data.links = {}; + data.fmt_stream_map.split(',').forEach(function (item) { + var pair = item.split('|'); + data.links[pair[0]] = pair[1]; + }); + data.videoMap = mapLinks(data.links); + + cb(null, data); + } catch (error) { + unsafeWindow.console.error(error); + } + }, + + onerror: function () { + var error = new Error('Google Docs request failed: ' + + 'metadata lookup HTTP request failed'); + error.reason = 'HTTP_ONERROR'; + return cb(error); + } + }); + } + + function mapLinks(links) { + var videos = { + 1080: [], + 720: [], + 480: [], + 360: [] + }; + + Object.keys(links).forEach(function (itag) { + itag = parseInt(itag, 10); + if (!ITAG_QMAP.hasOwnProperty(itag)) { + return; + } + + videos[ITAG_QMAP[itag]].push({ + itag: itag, + contentType: ITAG_CMAP[itag], + link: links[itag] + }); + }); + + return videos; + } + + /* + * Greasemonkey 2.0 has this wonderful sandbox that attempts + * to prevent script developers from shooting themselves in + * the foot by removing the trigger from the gun, i.e. it's + * impossible to cross the boundary between the browser JS VM + * and the privileged sandbox that can run GM_xmlhttpRequest(). + * + * So in this case, we have to resort to polling a special + * variable to see if getGoogleDriveMetadata needs to be called + * and deliver the result into another special variable that is + * being polled on the browser side. + */ + + /* + * Browser side function -- sets gdUserscript.pollID to the + * ID of the Drive video to be queried and polls + * gdUserscript.pollResult for the result. + */ + function getGoogleDriveMetadata_GM(id, callback) { + debug('Setting GD poll ID to ' + id); + unsafeWindow.gdUserscript.pollID = id; + var tries = 0; + var i = setInterval(function () { + if (unsafeWindow.gdUserscript.pollResult) { + debug('Got result'); + clearInterval(i); + var result = unsafeWindow.gdUserscript.pollResult; + unsafeWindow.gdUserscript.pollResult = null; + callback(result.error, result.result); + } else if (++tries > 100) { + // Took longer than 10 seconds, give up + clearInterval(i); + } + }, 100); + } + + /* + * Sandbox side function -- polls gdUserscript.pollID for + * the ID of a Drive video to be queried, looks up the + * metadata, and stores it in gdUserscript.pollResult + */ + function setupGDPoll() { + unsafeWindow.gdUserscript = cloneInto({}, unsafeWindow); + var pollInterval = setInterval(function () { + if (unsafeWindow.gdUserscript.pollID) { + var id = unsafeWindow.gdUserscript.pollID; + unsafeWindow.gdUserscript.pollID = null; + debug('Polled and got ' + id); + getVideoInfo(id, function (error, data) { + unsafeWindow.gdUserscript.pollResult = cloneInto({ + error: error, + result: data + }, unsafeWindow); + }); + } + }, 1000); + } + + function isRunningTampermonkey() { + try { + return GM_info.scriptHandler === 'Tampermonkey'; + } catch (error) { + return false; + } + } + + if (isRunningTampermonkey()) { + unsafeWindow.getGoogleDriveMetadata = getVideoInfo; + } else { + debug('Using non-TM polling workaround'); + unsafeWindow.getGoogleDriveMetadata = exportFunction( + getGoogleDriveMetadata_GM, unsafeWindow); + setupGDPoll(); + } + + unsafeWindow.console.log('Initialized userscript Google Drive player'); + unsafeWindow.hasDriveUserscript = true; +} catch (error) { + unsafeWindow.console.error(error); +} diff --git a/gdrive-userscript/generate-userscript.js b/gdrive-userscript/generate-userscript.js new file mode 100644 index 00000000..33b297e5 --- /dev/null +++ b/gdrive-userscript/generate-userscript.js @@ -0,0 +1,19 @@ +var fs = require('fs'); +var path = require('path'); + +var sitename = process.argv[2]; +var includes = process.argv.slice(3).map(function (include) { + return '// @include ' + include; +}).join('\n'); + +var lines = String(fs.readFileSync( + path.resolve(__dirname, 'cytube-google-drive.user.js'))).split('\n'); +lines.forEach(function (line) { + if (line.match(/\{INCLUDE_BLOCK\}/)) { + console.log(includes); + } else if (line.match(/\{SITENAME\}/)) { + console.log(line.replace(/\{SITENAME\}/, sitename)); + } else { + console.log(line); + } +}); diff --git a/package.json b/package.json index 21813f9a..698ae34c 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,8 @@ "build-player": "$npm_node_execpath build-player.js", "build-server": "babel -D --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/", "postinstall": "./postinstall.sh", - "server-dev": "babel -D --watch --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/" + "server-dev": "babel -D --watch --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/", + "generate-userscript": "$npm_node_execpath gdrive-userscript/generate-userscript $@ > www/js/cytube-google-drive.user.js" }, "devDependencies": { "coffee-script": "^1.9.2" diff --git a/player/gdrive-player.coffee b/player/gdrive-player.coffee new file mode 100644 index 00000000..026216bb --- /dev/null +++ b/player/gdrive-player.coffee @@ -0,0 +1,22 @@ +window.GoogleDrivePlayer = class GoogleDrivePlayer extends VideoJSPlayer + constructor: (data) -> + if not (this instanceof GoogleDrivePlayer) + return new GoogleDrivePlayer(data) + + super(data) + + load: (data) -> + if typeof window.getGoogleDriveMetadata is 'function' + window.getGoogleDriveMetadata(data.id, (error, metadata) => + if error + console.error(error) + alertBox = window.document.createElement('div') + alertBox.className = 'alert alert-danger' + alertBox.textContent = error.message + document.getElementById('ytapiplayer').appendChild(alertBox) + else + data.meta.direct = metadata.videoMap + super(data) + ) + else + super(data) diff --git a/player/gdrive-youtube.coffee b/player/gdrive-youtube.coffee index c7461c03..bb463150 100644 --- a/player/gdrive-youtube.coffee +++ b/player/gdrive-youtube.coffee @@ -7,6 +7,7 @@ window.GoogleDriveYouTubePlayer = class GoogleDriveYouTubePlayer extends Player @init(data) init: (data) -> + window.promptToInstallDriveUserscript() embed = $('').attr( type: 'application/x-shockwave-flash' src: "https://www.youtube.com/get_player?docid=#{data.id}&ps=docs\ @@ -102,3 +103,30 @@ window.GoogleDriveYouTubePlayer = class GoogleDriveYouTubePlayer extends Player cb(@yt.getVolume() / 100) else cb(VOLUME) + +window.promptToInstallDriveUserscript = -> + if document.getElementById('prompt-install-drive-userscript') + return + alertBox = document.createElement('div') + alertBox.id = 'prompt-install-drive-userscript' + alertBox.className = 'alert alert-info' + alertBox.innerHTML = """ +Due to continual breaking changes making it increasingly difficult to +maintain Google Drive support, you can now install a userscript that +simplifies the code and has better compatibility. In the future, the +old player will be removed.""" + alertBox.appendChild(document.createElement('br')) + infoLink = document.createElement('a') + infoLink.className = 'btn btn-info' + infoLink.href = '/google_drive_userscript' + infoLink.textContent = 'Click here for details' + infoLink.target = '_blank' + alertBox.appendChild(infoLink) + + closeButton = document.createElement('button') + closeButton.className = 'close pull-right' + closeButton.innerHTML = '×' + closeButton.onclick = -> + alertBox.parentNode.removeChild(alertBox) + alertBox.insertBefore(closeButton, alertBox.firstChild) + document.getElementById('videowrap').appendChild(alertBox) diff --git a/player/hls.coffee b/player/hls.coffee new file mode 100644 index 00000000..6b9c5c9f --- /dev/null +++ b/player/hls.coffee @@ -0,0 +1,23 @@ +window.HLSPlayer = class HLSPlayer extends VideoJSPlayer + constructor: (data) -> + if not (this instanceof HLSPlayer) + return new HLSPlayer(data) + + @setupMeta(data) + super(data) + + load: (data) -> + @setupMeta(data) + super(data) + + setupMeta: (data) -> + data.meta.direct = + # Quality is required for data.meta.direct processing but doesn't + # matter here because it's dictated by the stream. Arbitrarily + # choose 480. + 480: [ + { + link: data.id + contentType: 'application/x-mpegURL' + } + ] diff --git a/player/update.coffee b/player/update.coffee index 41a1c66a..1dde4123 100644 --- a/player/update.coffee +++ b/player/update.coffee @@ -2,7 +2,7 @@ TYPE_MAP = yt: YouTubePlayer vi: VimeoPlayer dm: DailymotionPlayer - gd: GoogleDriveYouTubePlayer + gd: GoogleDrivePlayer gp: VideoJSPlayer fi: FilePlayer jw: FilePlayer @@ -15,6 +15,7 @@ TYPE_MAP = us: UstreamPlayer im: ImgurPlayer vm: VideoJSPlayer + hl: HLSPlayer sb: VideoJSPlayer window.loadMediaPlayer = (data) -> @@ -29,6 +30,14 @@ window.loadMediaPlayer = (data) -> window.PLAYER = new VideoJSPlayer(data) catch e console.error e + else if data.type is 'gd' + try + if data.meta.html5hack or window.hasDriveUserscript + window.PLAYER = new GoogleDrivePlayer(data) + else + window.PLAYER = new GoogleDriveYouTubePlayer(data) + catch e + console.error e else if data.type of TYPE_MAP try window.PLAYER = TYPE_MAP[data.type](data) diff --git a/player/videojs.coffee b/player/videojs.coffee index e73473e6..9a3820af 100644 --- a/player/videojs.coffee +++ b/player/videojs.coffee @@ -43,8 +43,7 @@ window.VideoJSPlayer = class VideoJSPlayer extends Player if not (this instanceof VideoJSPlayer) return new VideoJSPlayer(data) - @setMediaProperties(data) - @loadPlayer(data) + @load(data) loadPlayer: (data) -> waitUntilDefined(window, 'videojs', => @@ -53,14 +52,15 @@ window.VideoJSPlayer = class VideoJSPlayer extends Player .attr(width: '100%', height: '100%') removeOld(video) - sources = sortSources(data.meta.direct) - if sources.length == 0 + @sources = sortSources(data.meta.direct) + if @sources.length == 0 console.error('VideoJSPlayer::constructor(): data.meta.direct has no sources!') @mediaType = null return - sources.forEach((source) -> + @sourceIdx = 0 + @sources.forEach((source) -> $('').attr( src: source.src type: source.type @@ -84,6 +84,18 @@ window.VideoJSPlayer = class VideoJSPlayer extends Player @player = videojs(video[0], autoplay: true, controls: true) @player.ready(=> + @player.on('error', => + err = @player.error() + if err and err.code == 4 + console.error('Caught error, trying next source') + @sourceIdx++ + if @sourceIdx < @sources.length + @player.src(@sources[@sourceIdx]) + else + console.error('Out of sources, video will not play') + if @mediaType is 'gd' and not window.hasDriveUserscript + window.promptToInstallDriveUserscript() + ) @setVolume(VOLUME) @player.on('ended', -> if CLIENT.leader @@ -114,12 +126,13 @@ window.VideoJSPlayer = class VideoJSPlayer extends Player # not to run until the ready() function returns. setTimeout(-> $('#ytapiplayer .vjs-subtitles-button .vjs-menu-item').each((i, elem) -> - if elem.textContent == localStorage.lastSubtitle + textNode = elem.childNodes[0] + if textNode.textContent == localStorage.lastSubtitle elem.click() elem.onclick = -> - if elem.attributes['aria-selected'].value == 'true' - localStorage.lastSubtitle = elem.textContent + if elem.attributes['aria-checked'].value == 'true' + localStorage.lastSubtitle = textNode.textContent ) , 1) ) diff --git a/src/channel/playlist.js b/src/channel/playlist.js index 6a023f71..71198070 100644 --- a/src/channel/playlist.js +++ b/src/channel/playlist.js @@ -675,7 +675,7 @@ PlaylistModule.prototype.handlePlayNext = function (user) { title = this.current.media.title; } - this.channel.logger.log("[playlist] " + user.getName() + " skipped" + title); + this.channel.logger.log("[playlist] " + user.getName() + " skipped " + title); this._playNext(); }; diff --git a/src/config.js b/src/config.js index e3d0ca82..e328a34a 100644 --- a/src/config.js +++ b/src/config.js @@ -120,6 +120,9 @@ var defaults = { "service-socket": { enabled: false, socket: "service.sock" + }, + "google-drive": { + "html5-hack-enabled": false } }; diff --git a/src/get-info.js b/src/get-info.js index c27ee2c5..08621176 100644 --- a/src/get-info.js +++ b/src/get-info.js @@ -12,6 +12,7 @@ var YouTube = require("cytube-mediaquery/lib/provider/youtube"); var Vimeo = require("cytube-mediaquery/lib/provider/vimeo"); var Vidme = require("cytube-mediaquery/lib/provider/vidme"); var Streamable = require("cytube-mediaquery/lib/provider/streamable"); +var GoogleDrive = require("cytube-mediaquery/lib/provider/googledrive"); /* * Preference map of quality => youtube formats. @@ -458,6 +459,13 @@ var Getters = { callback(false, media); }, + /* HLS stream */ + hl: function (id, callback) { + var title = "Livestream"; + var media = new Media(id, title, "--:--", "hl"); + callback(false, media); + }, + /* imgur.com albums */ im: function (id, callback) { /** @@ -493,6 +501,7 @@ var Getters = { /* google docs */ gd: function (id, callback) { + GoogleDrive.setHTML5HackEnabled(Config.get("google-drive.html5-hack-enabled")); var data = { type: "googledrive", kind: "single", diff --git a/src/media.js b/src/media.js index a07416e2..eeeed5c0 100644 --- a/src/media.js +++ b/src/media.js @@ -38,7 +38,8 @@ Media.prototype = { bitrate: this.meta.bitrate, scuri: this.meta.scuri, embed: this.meta.embed, - gdrive_subtitles: this.meta.gdrive_subtitles + gdrive_subtitles: this.meta.gdrive_subtitles, + html5hack: this.meta.html5hack } }; }, diff --git a/src/utilities.js b/src/utilities.js index 1e039426..5ca45a1c 100644 --- a/src/utilities.js +++ b/src/utilities.js @@ -119,7 +119,7 @@ }); } - return result.join(":"); + return result.join(":"); }, root.formatTime = function (sec) { @@ -242,6 +242,8 @@ return id; case "hb": return "http://hitbox.tv/" + id; + case "hl": + return id; case "sb": return "https://streamable.com/" + id; default: @@ -259,6 +261,7 @@ case "im": case "jw": case "hb": + case "hl": return true; default: return false; @@ -294,8 +297,6 @@ var accumulator = ""; parts = parts.map(function (segment, i) { - if (i < 2) return segment; - var part = iphash(accumulator + segment + i, 3); accumulator += segment; return part; @@ -311,8 +312,6 @@ var accumulator = ""; parts = parts.map(function (segment, i) { - if (i < 2) return segment; - var part = iphash(accumulator + segment + i, 4); accumulator += segment; return part; diff --git a/src/web/pug.js b/src/web/pug.js index 60815539..b944ed0b 100644 --- a/src/web/pug.js +++ b/src/web/pug.js @@ -36,6 +36,9 @@ function getBaseUrl(res) { * Renders and serves a pug template */ function sendPug(res, view, locals) { + if (!locals) { + locals = {}; + } locals.loggedIn = locals.loggedIn || !!res.user; locals.loginName = locals.loginName || res.user ? res.user.name : false; locals.superadmin = locals.superadmin || res.user ? res.user.global_rank >= 255 : false; diff --git a/src/web/routes/google_drive_userscript.js b/src/web/routes/google_drive_userscript.js new file mode 100644 index 00000000..72515bb9 --- /dev/null +++ b/src/web/routes/google_drive_userscript.js @@ -0,0 +1,7 @@ +import { sendPug } from '../pug'; + +export default function initialize(app) { + app.get('/google_drive_userscript', (req, res) => { + return sendPug(res, 'google_drive_userscript') + }); +} diff --git a/src/web/webserver.js b/src/web/webserver.js index e34a2caf..8093fa2e 100644 --- a/src/web/webserver.js +++ b/src/web/webserver.js @@ -178,6 +178,7 @@ module.exports = { require('./account').init(app); require('./acp').init(app); require('../google2vtt').attach(app); + require('./routes/google_drive_userscript')(app); app.use(serveStatic(path.join(__dirname, '..', '..', 'www'), { maxAge: webConfig.getCacheTTL() })); diff --git a/templates/channel.pug b/templates/channel.pug index e9b491dd..c1dd7d2b 100644 --- a/templates/channel.pug +++ b/templates/channel.pug @@ -249,3 +249,4 @@ html(lang="en") script(defer, src="/js/sc.js") script(defer, src="/js/froogaloop.min.js") script(defer, src="/js/video.js") + script(defer, src="/js/videojs-contrib-hls.min.js") diff --git a/templates/google_drive_userscript.pug b/templates/google_drive_userscript.pug new file mode 100644 index 00000000..f0744431 --- /dev/null +++ b/templates/google_drive_userscript.pug @@ -0,0 +1,74 @@ +doctype html +html(lang="en") + head + include head + +head() + body + #wrap + nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation") + include nav + +navheader() + #nav-collapsible.collapse.navbar-collapse + ul.nav.navbar-nav + +navdefaultlinks("/google_drive_userscript") + +navloginlogout("/google_drive_userscript") + section#mainpage + .container + .col-md-8.col-md-offset-2 + h1 Google Drive Userscript + h2 Why? + p. + Since Google Drive support was launched in early 2014, it has broken + at least 4-5 times, requiring increasing effort to get it working again + and disrupting many channels. This is because there is no official API + for it like there is for YouTube videos, which means support for it + relies on undocumented tricks. In August 2016, the decision was made + to phase out the native support for Google Drive and instead require + users to install a userscript, which allows to bypass certain browser + restrictions and make the code easier, simpler, and less prone to failure + (it could still break due to future Google Drive changes, but is less + likely to be difficult to fix). + h2 How It Works + p. + The userscript is a short script that you can install using a browser + extension such as Greasemonkey or Tampermonkey that runs on the page + and provides additional functionality needed to play Google Drive + videos. + h2 Installation + ul + li + strong Chrome + | —Install Tampermonkey. + li + strong Firefox + | —Install Tampermonkey + | or Greasemonkey. + li + strong Other Browsers + | —Install the appropriate userscript plugin for your browser. + | Tampermonkey supports many browsers besides Chrome. + p. + Once you have installed the userscript manager addon for your browser, + you can + install the userscript. If this link 404s, it means the administrator + of this server hasn't generated it yet. + p. + You can find a guide with screenshots of the installation process + on GitHub. + + include footer + +footer() + script(type="text/javascript"). + function showEmail(btn, email, key) { + email = unescape(email); + key = unescape(key); + var dest = new Array(email.length); + for (var i = 0; i < email.length; i++) { + dest[i] = String.fromCharCode(email.charCodeAt(i) ^ key.charCodeAt(i % key.length)); + } + email = dest.join(""); + $("").attr("href", "mailto:" + email) + .text(email) + .insertBefore(btn); + $(btn).remove(); + } diff --git a/www/css/video-js.css b/www/css/video-js.css index 6c57fefb..5678e588 100644 --- a/www/css/video-js.css +++ b/www/css/video-js.css @@ -1,18 +1,21 @@ -.video-js .vjs-big-play-button:before, .video-js .vjs-control:before { +@charset "UTF-8"; +.video-js .vjs-big-play-button:before, .video-js .vjs-control:before, .video-js .vjs-modal-dialog, .vjs-modal-dialog .vjs-modal-dialog-content { position: absolute; top: 0; left: 0; width: 100%; - height: 100%; + height: 100%; } + +.video-js .vjs-big-play-button:before, .video-js .vjs-control:before { text-align: center; } @font-face { font-family: VideoJS; - src: url('font/VideoJS.eot?') format('eot'); } + src: url("../font/2.0.0/VideoJS.eot?#iefix") format("eot"); } @font-face { font-family: VideoJS; - src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff'), url(data:application/x-font-ttf;charset=utf-8;base64,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) format('truetype'); + src: url(data:application/font-woff;charset=utf-8;base64,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) format("woff"), url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAKAIAAAwAgT1MvMlGRXgQAAAEoAAAAVmNtYXDiLxC2AAAB+AAAAUpnbHlm5X8X/gAAA4QAAA7kaGVhZArGdn0AAADQAAAANmhoZWEOogcfAAAArAAAACRobXR40gAAAAAAAYAAAAB4bG9jYTDILUIAAANEAAAAPm1heHABLwB5AAABCAAAACBuYW1l1cf1oAAAEmgAAAIKcG9zdL2sAHoAABR0AAABeQABAAAHAAAAAKEHAAAAAAAHAAABAAAAAAAAAAAAAAAAAAAAHgABAAAAAQAAEXIS2l8PPPUACwcAAAAAANJUFcAAAAAA0lQVwAAAAAAHAAcAAAAACAACAAAAAAAAAAEAAAAeAG0ABwAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQcAAZAABQAIBHEE5gAAAPoEcQTmAAADXABXAc4AAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA8QHxHQcAAAAAoQcAAAAAAAABAAAAAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAAAAAAAwAAAAMAAAAcAAEAAAAAAEQAAwABAAAAHAAEACgAAAAGAAQAAQACAADxHf//AAAAAPEB//8AAA8AAAEAAAAAAAAAAAEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AUABmALIAxgDmAR4BSAF0AZwB8gIuAo4CugMKA44DsAPqBDgEfAS4BOgFDAWiBegGNgZsBtoHcgAAAAEAAAAABYsFiwACAAABEQECVQM2BYv76gILAAADAAAAAAZrBmsAAgAOABoAAAkCEwQAAxIABSQAEwIAASYAJzYANxYAFwYAAusBwP5Alf7D/loICAGmAT0BPQGmCAj+Wv7D/f6uBgYBUv39AVIGBv6uAjABUAFQAZsI/lr+w/7D/loICAGmAT0BPQGm+sgGAVL9/QFSBgb+rv39/q4AAAACAAAAAAVABYsAAwAHAAABIREpAREhEQHAASv+1QJVASsBdQQW++oEFgAAAAQAAAAABiAGIAAGABMAJAAnAAABLgEnFRc2NwYHFz4BNSYAJxUWEgEHASERIQERAQYHFT4BNxc3AQcXBNABZVW4A7sCJ3ElKAX+3+Wlzvu3XwFh/p8BKwF1AT5MXU6KO5lf/WCcnAOAZJ4rpbgYGGpbcUacVPQBYziaNP70Aetf/p/+QP6LAfb+wjsdmhJEMZhfBJacnAAAAQAAAAAEqwXWAAUAAAERIQERAQILASoBdv6KBGD+QP6LBKr+iwAAAAIAAAAABWYF1gAGAAwAAAEuAScRPgEBESEBEQEFZQFlVFRl/BEBKwF1/osDgGSeK/2mK54BRP5A/osEqv6LAAADAAAAAAYgBg8ABQAMABoAABMRIQERAQUuAScRPgEDFRYSFwYCBxU2ADcmAOABKwF1/osCxQFlVVVluqXOAwPOpeUBIQUF/t8EYP5A/osEqv6L4GSeK/2mK54C85o0/vS1tf70NJo4AWL19QFiAAAABAAAAAAFiwWLAAUACwARABcAAAEjESE1IwMzNTM1IQEjFSERIwMVMxUzEQILlgF24JaW4P6KA4DgAXaW4OCWAuv+ipYCCuCW/ICWAXYCoJbgAXYABAAAAAAFiwWLAAUACwARABcAAAEzFTMRIRMjFSERIwEzNTM1IRM1IxEhNQF14Jb+iuDgAXaWAcCW4P6KlpYBdgJV4AF2AcCWAXb76uCWAcDg/oqWAAAAAAIAAAAABdYF1gAPABMAAAEhDgEHER4BFyE+ATcRLgEDIREhBUD8gD9VAQFVPwOAP1UBAVU//IADgAXVAVU//IA/VQEBVT8DgD9V++wDgAAABgAAAAAGawZrAAcADAATABsAIAAoAAAJASYnDgEHASUuAScBBSEBNhI3JgUBBgIHFhchBR4BFwEzARYXPgE3AQK+AWROVIfwYQESA4416aH+7gLl/dABelxoAQH8E/7dXGgBAQ4CMP3kNemhARJ4/t1OVIfwYf7uA/ACaBIBAVhQ/id3pfY+/idL/XNkAQGTTU0B+GT+/5NNSEul9j4B2f4IEgEBWFAB2QAAAAUAAAAABmsF1gAPABMAFwAbAB8AAAEhDgEHER4BFyE+ATcRLgEBIRUhASE1IQUhNSE1ITUhBdX7VkBUAgJUQASqQFQCAlT7FgEq/tYC6v0WAuoBwP7WASr9FgLqBdUBVT/8gD9VAQFVPwOAP1X9rJX+1ZWVlZaVAAMAAAAABiAF1gAPACcAPwAAASEOAQcRHgEXIT4BNxEuAQEjNSMVMzUzFRQGByMuAScRPgE3Mx4BFQUjNSMVMzUzFQ4BByMuATURNDY3Mx4BFwWL++o/VAICVD8EFj9UAgJU/WtwlZVwKiDgICoBASog4CAqAgtwlZVwASog4CAqKiDgICoBBdUBVT/8gD9VAQFVPwOAP1X99yXgJUogKgEBKiABKiAqAQEqIEol4CVKICoBASogASogKgEBKiAAAAYAAAAABiAE9gADAAcACwAPABMAFwAAEzM1IxEzNSMRMzUjASE1IREhNSERFSE14JWVlZWVlQErBBX76wQV++sEFQM1lv5AlQHAlf5Alv5AlQJVlZUAAAABAAAAAAYgBmwALgAAASIGBwE2NCcBHgEzPgE3LgEnDgEHFBcBLgEjDgEHHgEXMjY3AQYHHgEXPgE3LgEFQCtKHv3sBwcCDx5OLF9/AgJ/X19/Agf98R5OLF9/AgJ/XyxOHgIUBQEDe1xcewMDewJPHxsBNxk2GQE0HSACf19ffwICf18bGf7NHCACf19ffwIgHP7KFxpcewICe1xdewAAAgAAAAAGWQZrAEMATwAAATY0Jzc+AScDLgEPASYvAS4BJyEOAQ8BBgcnJgYHAwYWHwEGFBcHDgEXEx4BPwEWHwEeARchPgE/ATY3FxY2NxM2JicFLgEnPgE3HgEXDgEFqwUFngoGB5YHGQ26OkQcAxQP/tYPFAIcRTm6DRoHlQcFC50FBZ0LBQeVBxoNujlFHAIUDwEqDxQCHEU5ug0aB5UHBQv9OG+UAgKUb2+UAgKUAzckSiR7CRoNAQMMCQVLLRzGDhEBAREOxhwtSwUJDP79DBsJeyRKJHsJGg3+/QwJBUstHMYOEQEBEQ7GHC1LBQkMAQMMGwlBApRvb5QCApRvb5QAAAAAAQAAAAAGawZrAAsAABMSAAUkABMCACUEAJUIAaYBPQE9AaYICP5a/sP+w/5aA4D+w/5aCAgBpgE9AT0BpggI/loAAAACAAAAAAZrBmsACwAXAAABBAADEgAFJAATAgABJgAnNgA3FgAXBgADgP7D/loICAGmAT0BPQGmCAj+Wv7D/f6uBgYBUv39AVIGBv6uBmsI/lr+w/7D/loICAGmAT0BPQGm+sgGAVL9/QFSBgb+rv39/q4AAAMAAAAABmsGawALABcAIwAAAQQAAxIABSQAEwIAASYAJzYANxYAFwYAAw4BBy4BJz4BNx4BA4D+w/5aCAgBpgE9AT0BpggI/lr+w/3+rgYGAVL9/QFSBgb+rh0Cf19ffwICf19ffwZrCP5a/sP+w/5aCAgBpgE9AT0BpvrIBgFS/f0BUgYG/q79/f6uAk9ffwICf19ffwICfwAAAAQAAAAABiAGIAAPABsAJQApAAABIQ4BBxEeARchPgE3ES4BASM1IxUjETMVMzU7ASEeARcRDgEHITczNSMFi/vqP1QCAlQ/BBY/VAICVP1rcJVwcJVwlgEqICoBASog/tZwlZUGIAJUP/vqP1QCAlQ/BBY/VPyClZUBwLu7ASog/tYgKgFw4AACAAAAAAZrBmsACwAXAAABBAADEgAFJAATAgATBwkBJwkBNwkBFwEDgP7D/loICAGmAT0BPQGmCAj+Wjhp/vT+9GkBC/71aQEMAQxp/vUGawj+Wv7D/sP+WggIAaYBPQE9Aab8EWkBC/71aQEMAQxp/vUBC2n+9AABAAAAAAXWBrYAFgAAAREJAREeARcOAQcuAScjFgAXNgA3JgADgP6LAXW+/QUF/b6+/QWVBgFR/v4BUQYG/q8FiwEq/ov+iwEqBP2/vv0FBf2+/v6vBgYBUf7+AVEAAAABAAAAAAU/BwAAFAAAAREjIgYdASEDIxEhESMRMzU0NjMyBT+dVjwBJSf+/s7//9Ctkwb0/vhISL3+2P0JAvcBKNq6zQAAAAAEAAAAAAaOBwAAMABFAGAAbAAAARQeAxUUBwYEIyImJyY1NDY3NiUuATU0NwYjIiY1NDY3PgEzIQcjHgEVFA4DJzI2NzY1NC4CIyIGBwYVFB4DEzI+AjU0LgEvASYvAiYjIg4DFRQeAgEzFSMVIzUjNTM1MwMfQFtaQDBI/uqfhOU5JVlKgwERIB8VLhaUy0g/TdNwAaKKg0pMMUVGMZImUBo1Ij9qQCpRGS8UKz1ZNjprWzcODxMeChwlThAgNWhvUzZGcX0Da9XVadTUaQPkJEVDUIBOWlN6c1NgPEdRii5SEipAKSQxBMGUUpo2QkBYP4xaSHNHO0A+IRs5ZjqGfVInITtlLmdnUjT8lxo0Xj4ZMCQYIwsXHTgCDiQ4XTtGazsdA2xs29ts2QADAAAAAAaABmwAAwAOACoAAAERIREBFgYrASImNDYyFgERIRE0JiMiBgcGFREhEhAvASEVIz4DMzIWAd3+tgFfAWdUAlJkZ6ZkBI/+t1FWP1UVC/63AgEBAUkCFCpHZz+r0ASP/CED3wEySWJik2Fh/N39yAISaXdFMx4z/dcBjwHwMDCQIDA4H+MAAAEAAAAABpQGAAAxAAABBgcWFRQCDgEEIyAnFjMyNy4BJxYzMjcuAT0BFhcuATU0NxYEFyY1NDYzMhc2NwYHNgaUQ18BTJvW/tKs/vHhIyvhsGmmHyEcKypwk0ROQk4seQFbxgi9hoxgbWAlaV0FaGJFDhyC/v3ut22RBIoCfWEFCxexdQQmAyyOU1hLlbMKJiSGvWYVOXM/CgAAAAEAAAAABYAHAAAiAAABFw4BBwYuAzURIzU+BDc+ATsBESEVIREUHgI3NgUwUBewWWitcE4hqEhyRDAUBQEHBPQBTf6yDSBDME4Bz+0jPgECOFx4eDoCINcaV11vVy0FB/5Y/P36HjQ1HgECAAEAAAAABoAGgABKAAABFAIEIyInNj8BHgEzMj4BNTQuASMiDgMVFBYXFj8BNjc2JyY1NDYzMhYVFAYjIiY3PgI1NCYjIgYVFBcDBhcmAjU0EiQgBBIGgM7+n9FvazsTNhRqPXm+aHfijmm2f1srUE0eCAgGAgYRM9Gpl6mJaz1KDgglFzYyPlYZYxEEzv7OAWEBogFhzgOA0f6fziBdR9MnOYnwlnLIfjpgfYZDaJ4gDCAfGAYXFD1al9mkg6ruVz0jdVkfMkJyVUkx/l5Ga1sBfOnRAWHOzv6fAAAHAAAAAAcABM8ADgAXACoAPQBQAFoAXQAAARE2HgIHDgEHBiYjJyY3FjY3NiYHERQFFjY3PgE3LgEnIwYfAR4BFw4BFxY2Nz4BNy4BJyMGHwEeARcUBhcWNjc+ATcuAScjBh8BHgEXDgEFMz8BFTMRIwYDJRUnAxyEzZRbCA2rgketCAEBqlRoCglxYwF+IiEOIysBAkswHQEECiQ0AgE+YyIhDiIsAQJLMB4BBQokNAE/YyIhDiIsAQJLMB4BBQokNAEBPvmD7kHhqs0s0gEnjgHJAv0FD2a9gIrADwUFAwPDAlVMZ3MF/pUHwgc1HTyWV325PgsJED+oY3G9TAc1HTyWV325PgsJED+oY3G9TAc1HTyWV325PgsJED+oY3G9UmQBZQMMR/61g/kBAAAAAAAQAMYAAQAAAAAAAQAHAAAAAQAAAAAAAgAHAAcAAQAAAAAAAwAHAA4AAQAAAAAABAAHABUAAQAAAAAABQALABwAAQAAAAAABgAHACcAAQAAAAAACgArAC4AAQAAAAAACwATAFkAAwABBAkAAQAOAGwAAwABBAkAAgAOAHoAAwABBAkAAwAOAIgAAwABBAkABAAOAJYAAwABBAkABQAWAKQAAwABBAkABgAOALoAAwABBAkACgBWAMgAAwABBAkACwAmAR5WaWRlb0pTUmVndWxhclZpZGVvSlNWaWRlb0pTVmVyc2lvbiAxLjBWaWRlb0pTR2VuZXJhdGVkIGJ5IHN2ZzJ0dGYgZnJvbSBGb250ZWxsbyBwcm9qZWN0Lmh0dHA6Ly9mb250ZWxsby5jb20AVgBpAGQAZQBvAEoAUwBSAGUAZwB1AGwAYQByAFYAaQBkAGUAbwBKAFMAVgBpAGQAZQBvAEoAUwBWAGUAcgBzAGkAbwBuACAAMQAuADAAVgBpAGQAZQBvAEoAUwBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAACAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4EcGxheQtwbGF5LWNpcmNsZQVwYXVzZQt2b2x1bWUtbXV0ZQp2b2x1bWUtbG93CnZvbHVtZS1taWQLdm9sdW1lLWhpZ2gQZnVsbHNjcmVlbi1lbnRlcg9mdWxsc2NyZWVuLWV4aXQGc3F1YXJlB3NwaW5uZXIJc3VidGl0bGVzCGNhcHRpb25zCGNoYXB0ZXJzBXNoYXJlA2NvZwZjaXJjbGUOY2lyY2xlLW91dGxpbmUTY2lyY2xlLWlubmVyLWNpcmNsZQJoZAZjYW5jZWwGcmVwbGF5CGZhY2Vib29rBWdwbHVzCGxpbmtlZGluB3R3aXR0ZXIGdHVtYmxyCXBpbnRlcmVzdBFhdWRpby1kZXNjcmlwdGlvbgAAAAAA) format("truetype"); font-weight: normal; font-style: normal; } @@ -21,195 +24,253 @@ font-weight: normal; font-style: normal; } .vjs-icon-play:before, .video-js .vjs-big-play-button:before, .video-js .vjs-play-control:before { - content: '\f101'; } + content: ""; } .vjs-icon-play-circle { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-play-circle:before { - content: '\f102'; } + content: ""; } .vjs-icon-pause, .video-js .vjs-play-control.vjs-playing { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-pause:before, .video-js .vjs-play-control.vjs-playing:before { - content: '\f103'; } + content: ""; } -.vjs-icon-volume-mute, .video-js .vjs-mute-control.vjs-vol-0, .video-js .vjs-volume-menu-button.vjs-vol-0 { +.vjs-icon-volume-mute, .video-js .vjs-mute-control.vjs-vol-0, +.video-js .vjs-volume-menu-button.vjs-vol-0 { font-family: VideoJS; font-weight: normal; font-style: normal; } - .vjs-icon-volume-mute:before, .video-js .vjs-mute-control.vjs-vol-0:before, .video-js .vjs-volume-menu-button.vjs-vol-0:before { - content: '\f104'; } + .vjs-icon-volume-mute:before, .video-js .vjs-mute-control.vjs-vol-0:before, + .video-js .vjs-volume-menu-button.vjs-vol-0:before { + content: ""; } -.vjs-icon-volume-low, .video-js .vjs-mute-control.vjs-vol-1, .video-js .vjs-volume-menu-button.vjs-vol-1 { +.vjs-icon-volume-low, .video-js .vjs-mute-control.vjs-vol-1, +.video-js .vjs-volume-menu-button.vjs-vol-1 { font-family: VideoJS; font-weight: normal; font-style: normal; } - .vjs-icon-volume-low:before, .video-js .vjs-mute-control.vjs-vol-1:before, .video-js .vjs-volume-menu-button.vjs-vol-1:before { - content: '\f105'; } + .vjs-icon-volume-low:before, .video-js .vjs-mute-control.vjs-vol-1:before, + .video-js .vjs-volume-menu-button.vjs-vol-1:before { + content: ""; } -.vjs-icon-volume-mid, .video-js .vjs-mute-control.vjs-vol-2, .video-js .vjs-volume-menu-button.vjs-vol-2 { +.vjs-icon-volume-mid, .video-js .vjs-mute-control.vjs-vol-2, +.video-js .vjs-volume-menu-button.vjs-vol-2 { font-family: VideoJS; font-weight: normal; font-style: normal; } - .vjs-icon-volume-mid:before, .video-js .vjs-mute-control.vjs-vol-2:before, .video-js .vjs-volume-menu-button.vjs-vol-2:before { - content: '\f106'; } + .vjs-icon-volume-mid:before, .video-js .vjs-mute-control.vjs-vol-2:before, + .video-js .vjs-volume-menu-button.vjs-vol-2:before { + content: ""; } -.vjs-icon-volume-high, .video-js .vjs-mute-control, .video-js .vjs-volume-menu-button { +.vjs-icon-volume-high, .video-js .vjs-mute-control, +.video-js .vjs-volume-menu-button { font-family: VideoJS; font-weight: normal; font-style: normal; } - .vjs-icon-volume-high:before, .video-js .vjs-mute-control:before, .video-js .vjs-volume-menu-button:before { - content: '\f107'; } + .vjs-icon-volume-high:before, .video-js .vjs-mute-control:before, + .video-js .vjs-volume-menu-button:before { + content: ""; } .vjs-icon-fullscreen-enter, .video-js .vjs-fullscreen-control { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-fullscreen-enter:before, .video-js .vjs-fullscreen-control:before { - content: '\f108'; } + content: ""; } .vjs-icon-fullscreen-exit, .video-js.vjs-fullscreen .vjs-fullscreen-control { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-fullscreen-exit:before, .video-js.vjs-fullscreen .vjs-fullscreen-control:before { - content: '\f109'; } + content: ""; } .vjs-icon-square { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-square:before { - content: '\f10a'; } + content: ""; } .vjs-icon-spinner { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-spinner:before { - content: '\f10b'; } + content: ""; } .vjs-icon-subtitles, .video-js .vjs-subtitles-button { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-subtitles:before, .video-js .vjs-subtitles-button:before { - content: '\f10c'; } + content: ""; } .vjs-icon-captions, .video-js .vjs-captions-button { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-captions:before, .video-js .vjs-captions-button:before { - content: '\f10d'; } + content: ""; } .vjs-icon-chapters, .video-js .vjs-chapters-button { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-chapters:before, .video-js .vjs-chapters-button:before { - content: '\f10e'; } + content: ""; } .vjs-icon-share { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-share:before { - content: '\f10f'; } + content: ""; } .vjs-icon-cog { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-cog:before { - content: '\f110'; } + content: ""; } .vjs-icon-circle, .video-js .vjs-mouse-display, .video-js .vjs-play-progress, .video-js .vjs-volume-level { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-circle:before, .video-js .vjs-mouse-display:before, .video-js .vjs-play-progress:before, .video-js .vjs-volume-level:before { - content: '\f111'; } + content: ""; } .vjs-icon-circle-outline { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-circle-outline:before { - content: '\f112'; } + content: ""; } .vjs-icon-circle-inner-circle { font-family: VideoJS; font-weight: normal; font-style: normal; } .vjs-icon-circle-inner-circle:before { - content: '\f113'; } + content: ""; } -.vjs-icon-audio-description { +.vjs-icon-hd { font-family: VideoJS; font-weight: normal; font-style: normal; } - .vjs-icon-audio-description:before { - content: '\f114'; } + .vjs-icon-hd:before { + content: ""; } + +.vjs-icon-cancel, .video-js .vjs-control.vjs-close-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-cancel:before, .video-js .vjs-control.vjs-close-button:before { + content: ""; } + +.vjs-icon-replay { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-replay:before { + content: ""; } + +.vjs-icon-facebook { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-facebook:before { + content: ""; } + +.vjs-icon-gplus { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-gplus:before { + content: ""; } + +.vjs-icon-linkedin { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-linkedin:before { + content: ""; } + +.vjs-icon-twitter { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-twitter:before { + content: ""; } + +.vjs-icon-tumblr { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-tumblr:before { + content: ""; } + +.vjs-icon-pinterest { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-pinterest:before { + content: ""; } + +.vjs-icon-audio-description, .video-js .vjs-descriptions-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-audio-description:before, .video-js .vjs-descriptions-button:before { + content: ""; } .video-js { - /* display:inline-block would be closer to the video el's display:inline - * but it results in flash reloading when going into fullscreen [#2205] - */ display: block; - /* Make video.js videos align top when next to video elements */ vertical-align: top; box-sizing: border-box; color: #fff; background-color: #000; position: relative; padding: 0; - /* Start with 10px for base font size so other dimensions can be em based and - easily calculable. */ font-size: 10px; line-height: 1; - /* Provide some basic defaults for fonts */ font-weight: normal; font-style: normal; - /* Avoiding helvetica: issue #376 */ font-family: Arial, Helvetica, sans-serif; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; - user-select: none; - /* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when - checking fullScreenEnabled. */ } + user-select: none; } .video-js:-moz-full-screen { position: absolute; } .video-js:-webkit-full-screen { width: 100% !important; height: 100% !important; } -/* All elements inherit border-box sizing */ -.video-js *, .video-js *:before, .video-js *:after { +.video-js *, +.video-js *:before, +.video-js *:after { box-sizing: inherit; } -/* List style reset */ .video-js ul { font-family: inherit; font-size: inherit; line-height: inherit; list-style-position: outside; - /* Important to specify each */ margin-left: 0; margin-right: 0; margin-top: 0; margin-bottom: 0; } -/* Fill the width of the containing element and use padding to create the - desired aspect ratio. Default to 16x9 unless another ratio is given. */ -/* Not including a default AR in vjs-fluid because it would override - the user set AR injected into the header. */ -.video-js.vjs-fluid, .video-js.vjs-16-9, .video-js.vjs-4-3 { +.video-js.vjs-fluid, +.video-js.vjs-16-9, +.video-js.vjs-4-3 { width: 100%; max-width: 100%; height: 0; } @@ -224,8 +285,6 @@ width: 100%; height: 100%; } -/* Playback technology elements expand to the width/height of the containing div -