This commit is contained in:
Kasper Moskwiak 2015-10-18 23:07:55 +02:00
parent f59827fdc4
commit d186332975
44 changed files with 4089 additions and 19070 deletions

View file

@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="node_modules/video.js/dist/video-js.min.css" rel="stylesheet">
<link href="node_modules/videojs-resolution-switcher/lib/videojs-resolution-switcher.css" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href="style.css" rel="stylesheet">
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
@ -34,38 +35,149 @@
</div>
</div>
<div class="example">
<div class="info">
<p>
Set sources dynamically
</p>
<div class="container-fluid section">
<div class="row">
<div class="col-md-12">
<h1>
Set sources dynamically
</h1>
</div>
</div>
<div class="row">
<div class="col-md-6">
<pre>
videojs('video', {
controls: true,
plugins: {
videoJsResolutionSwitcher: {
default: 'low', // Default resolution [{Number}, 'low', 'high'],
dynamicLabel: true
}
}
}, function(){
var player = this;
window.player = player
player.updateSrc([
{
src: 'https://vjs.zencdn.net/v/oceans.mp4?SD',
type: 'video/mp4',
label: 'SD',
res: 360
},
{
src: 'https://vjs.zencdn.net/v/oceans.mp4?HD',
type: 'video/mp4',
label: 'HD',
res: 720
}
])
player.on('resolutionchange', function(){
console.info('Source changed to %s', player.src())
})
})
</pre>
</div>
<div class="col-md-6">
<video id='video' class="video-js vjs-default-skin"></video>
</div>
</div>
</div>
<div class="container-fluid section">
<div class="row">
<div class="col-md-12">
<h1>
Set sources inside <code>&ltvideo&gt</code> tag
</h1>
</div>
</div>
<div class="row">
<div class="col-md-6">
<pre>
&lt;video id=&quot;video_1&quot; class=&quot;video-js vjs-default-skin&quot; controls data-setup='{}' &gt;
&lt;source src=&quot;https://vjs.zencdn.net/v/oceans.mp4?sd&quot; type='video/mp4' label='SD' res='480' /&gt;
&lt;source src=&quot;https://vjs.zencdn.net/v/oceans.mp4?hd&quot; type='video/mp4' label='HD' res='1080'/&gt;
&lt;source src=&quot;https://vjs.zencdn.net/v/oceans.mp4?phone&quot; type='video/mp4' label='phone' res='144'/&gt;
&lt;source src=&quot;https://vjs.zencdn.net/v/oceans.mp4?4k&quot; type='video/mp4' label='4k' res='2160'/&gt;
&lt;/video&gt;
</pre>
</div>
<div class="col-md-6">
<video id="video_1" class="video-js vjs-default-skin" fluid="true" controls data-setup='{}' >
<source src="https://vjs.zencdn.net/v/oceans.mp4?sd" type='video/mp4' label='SD' res='480' />
<source src="https://vjs.zencdn.net/v/oceans.mp4?hd" type='video/mp4' label='HD' res='1080'/>
<source src="https://vjs.zencdn.net/v/oceans.mp4?phone" type='video/mp4' label='phone' res='144'/>
<source src="https://vjs.zencdn.net/v/oceans.mp4?4k" type='video/mp4' label='4k' res='2160'/>
</video>
</div>
</div>
</div>
<div class="container-fluid section">
<div class="row">
<div class="col-md-12">
<h1>
Use flash tech
</h1>
</div>
</div>
<div class="row">
<div class="col-md-6">
<pre>
videojs('video', {
controls: true,
techOrder: ['flash'],
preload: 'auto',
plugins: {
videoJsResolutionSwitcher: {
default: 'low', // Default resolution [{Number}, 'low', 'high'],
dynamicLabel: true
}
}
}, function(){
var player = this;
window.player = player
player.updateSrc([
{
src: 'https://vjs.zencdn.net/v/oceans.mp4?SD',
type: 'video/mp4',
label: 'SD',
res: 360
},
{
src: 'https://vjs.zencdn.net/v/oceans.mp4?HD',
type: 'video/mp4',
label: 'HD',
res: 720
}
])
player.on('resolutionchange', function(){
console.info('Source changed to %s', player.src())
})
})
</pre>
</div>
<div class="col-md-6">
<div class="embed-responsive embed-responsive-16by9">
<video id='video_flash' class="video-js vjs-default-skin embed-responsive-item"></video>
</div>
</div>
</div>
<video id='video' class="video-js vjs-default-skin"></video>
</div>
<div class="example">
<div class="info">
<p>
Set sources inside <code>&ltvideo&gt</code> tag
</p>
<div class="footer">
<a class='kspr' href="https://kspr.pl">kspr</a>
</div>
<video id="video_1" class="video-js vjs-default-skin" width="1000" controls fluid='true' data-setup='{}' >
<source src="https://vjs.zencdn.net/v/oceans.mp4?sd" type='video/mp4' label='SD' res='480' />
<source src="https://vjs.zencdn.net/v/oceans.mp4?hd" type='video/mp4' label='HD' res='1080'/>
<source src="https://vjs.zencdn.net/v/oceans.mp4?phone" type='video/mp4' label='phone' res='144'/>
<source src="https://vjs.zencdn.net/v/oceans.mp4?4k" type='video/mp4' label='4k' res='2160'/>
</video>
</div>
<script src="node_modules/video.js/dist/video.js"></script>
<script src="node_modules/videojs-resolution-switcher/lib/videojs-resolution-switcher.js"></script>
<script>
// fire up the plugin
videojs('video', {
controls: true,
muted: true,
width: 1000,
fluid: true,
plugins: {
videoJsResolutionSwitcher: {
@ -94,6 +206,41 @@
console.info('Source changed to %s', player.src())
})
})
// flash tech
videojs('video_flash', {
controls: true,
techOrder: ['flash'],
preload: 'auto',
plugins: {
videoJsResolutionSwitcher: {
default: 'low', // Default resolution [{Number}, 'low', 'high'],
dynamicLabel: true
}
}
}, function(){
var player = this;
window.player = player
player.updateSrc([
{
src: 'https://vjs.zencdn.net/v/oceans.mp4?SD',
type: 'video/mp4',
label: 'SD',
res: 360
},
{
src: 'https://vjs.zencdn.net/v/oceans.mp4?HD',
type: 'video/mp4',
label: 'HD',
res: 720
}
])
player.on('resolutionchange', function(){
console.info('Source changed to %s', player.src())
})
})
</script>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
<?xml version="1.0" standalone="no"?>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<defs>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

File diff suppressed because one or more lines are too long

View file

@ -23,4 +23,4 @@ videojs.addLanguage("ar",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادم أو الشبكة ، أو فشل بسبب عدم امكانية قراءة تنسيق الفيديو.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم ايقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
"No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("ba",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
"No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("bg",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Видеото не може да бъде заредено заради проблем със сървъра или мрежата или защото този формат не е поддържан.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Възпроизвеждането на видеото беше прекъснато заради проблем с файла или защото видеото използва опции които браузърът Ви не поддържа.",
"No compatible source was found for this media.": "Не беше намерен съвместим източник за това видео."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("ca",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "No s'ha pogut carregar el vídeo perquè el servidor o la xarxa han fallat, o bé perquè el seu format no és compatible.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducció de vídeo s'ha interrumput per un problema de corrupció de dades o bé perquè el vídeo demanava funcions que el vostre navegador no ofereix.",
"No compatible source was found for this media.": "No s'ha trobat cap font compatible amb el vídeo."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("cs",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video nemohlo být načteno, buď kvůli chybě serveru nebo sítě nebo proto, že daný formát není podporován.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Váš prohlížeč nepodporuje formát videa.",
"No compatible source was found for this media.": "Špatně zadaný zdroj videa."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("da",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke indlæses, enten fordi serveren eller netværket fejlede, eller fordi formatet ikke er understøttet.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoafspilningen blev afbrudt på grund af ødelagte data eller fordi videoen benyttede faciliteter som din browser ikke understøtter.",
"No compatible source was found for this media.": "Fandt ikke en kompatibel kilde for denne media."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("de",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Das Video konnte nicht geladen werden, da entweder ein Server- oder Netzwerkfehler auftrat oder das Format nicht unterstützt wird.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Die Videowiedergabe wurde entweder wegen eines Problems mit einem beschädigten Video oder wegen verwendeten Funktionen, die vom Browser nicht unterstützt werden, abgebrochen.",
"No compatible source was found for this media.": "Für dieses Video wurde keine kompatible Quelle gefunden."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("es",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "No se ha podido cargar el vídeo debido a un fallo de red o del servidor o porque el formato es incompatible.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducción de vídeo se ha interrumpido por un problema de corrupción de datos o porque el vídeo precisa funciones que su navegador no ofrece.",
"No compatible source was found for this media.": "No se ha encontrado ninguna fuente compatible con este vídeo."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("fi",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videon lataus ei onnistunut joko palvelin- tai verkkovirheestä tai väärästä formaatista johtuen.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videon toisto keskeytyi, koska media on vaurioitunut tai käyttää käyttää toimintoja, joita selaimesi ei tue.",
"No compatible source was found for this media.": "Tälle videolle ei löytynyt yhteensopivaa lähdettä."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("fr",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Cette vidéo n'a pas pu être chargée, soit parce que le serveur ou le réseau a échoué ou parce que le format n'est pas reconnu.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La lecture de la vidéo a été interrompue à cause d'un problème de corruption ou parce que la vidéo utilise des fonctionnalités non prises en charge par votre navigateur.",
"No compatible source was found for this media.": "Aucune source compatible n'a été trouvée pour cette vidéo."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("hr",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
"No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("hu",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "A videó nem tölthető be hálózati vagy kiszolgálói hiba miatt, vagy a formátuma nem támogatott.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A lejátszás adatsérülés miatt leállt, vagy a videó egyes tulajdonságait a böngészője nem támogatja.",
"No compatible source was found for this media.": "Nincs kompatibilis forrás ehhez a videóhoz."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("it",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Il filmato non può essere caricato a causa di un errore nel server o nella rete o perché il formato non viene supportato.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La riproduzione del filmato è stata interrotta a causa di un file danneggiato o per lutilizzo di impostazioni non supportate dal browser.",
"No compatible source was found for this media.": "Non ci sono fonti compatibili per questo filmato."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("ja",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "サーバーまたはネットワークのエラー、またはフォーマットがサポートされていないため、動画をロードできませんでした",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "破損の問題、またはお使いのブラウザがサポートしていない機能が動画に使用されていたため、動画の再生が中止されました",
"No compatible source was found for this media.": "この動画に対して互換性のあるソースが見つかりませんでした"
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("ko",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "비디오를 로드할 수 없습니다. 서버 혹은 네트워크 오류 때문이거나 지원되지 않는 형식 때문일 수 있습니다.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "비디오 재생이 취소됐습니다. 비디오가 손상되었거나 비디오가 사용하는 기능을 브라우저에서 지원하지 않는 것 같습니다.",
"No compatible source was found for this media.": "비디오에 호환되지 않는 소스가 있습니다."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("nl",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "De media kon niet worden geladen, veroorzaakt door een server of netwerkfout of het formaat word niet ondersteund.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "De media weergave is afgebroken omdat deze beschadigd is of de media gebruikt functionaliteit die niet door je browser word ondersteund.",
"No compatible source was found for this media.": "Voor deze media is geen ondersteunde bron gevonden."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("pt-BR",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "O vídeo não pode ser carregado, ou porque houve um problema com sua rede ou pelo formato do vídeo não ser suportado.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A Execução foi interrompida por um problema com o vídeo ou por seu navegador não dar suporte ao seu formato.",
"No compatible source was found for this media.": "Não foi encontrada fonte de vídeo compatível."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("ru",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Невозможно загрузить видео из-за сетевого или серверного сбоя либо формат не поддерживается.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Воспроизведение видео было приостановлено из-за повреждения либо в связи с тем, что видео использует функции, неподдерживаемые вашим браузером.",
"No compatible source was found for this media.": "Совместимые источники для этого видео отсутствуют."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("sr",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
"No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("sv",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Det gick inte att ladda videon, antingen på grund av ett server- eller nätverksfel, eller för att formatet inte stöds.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Uppspelningen avbröts på grund av att videon är skadad, eller också för att videon använder funktioner som din webbläsare inte stöder.",
"No compatible source was found for this media.": "Det gick inte att hitta någon kompatibel källa för den här videon."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("tr",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video oynatılamadı, ağ ya da sunucu hatası veya belirtilen format desteklenmiyor.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Tarayıcınız desteklemediği için videoda hata oluştu.",
"No compatible source was found for this media.": "Video için kaynak bulunamadı."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("uk",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Неможливо завантажити відео через мережевий чи серверний збій або формат не підтримується.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Відтворення відео було припинено через пошкодження або у зв'язку з тим, що відео використовує функції, які не підтримуються вашим браузером.",
"No compatible source was found for this media.": "Сумісні джерела для цього відео відсутні."
});
});

View file

@ -23,4 +23,4 @@ videojs.addLanguage("vi",{
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video không tải được, mạng hay server có lỗi hoặc định dạng không được hỗ trợ.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Phát media đã bị hủy do một sai lỗi hoặc media sử dụng những tính năng trình duyệt không hỗ trợ.",
"No compatible source was found for this media.": "Không có nguồn tương thích cho media này."
});
});

View file

@ -24,4 +24,4 @@ videojs.addLanguage("zh-CN",{
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由于视频文件损坏或是该视频使用了你的浏览器不支持的功能,播放终止。",
"No compatible source was found for this media.": "无法找到此视频兼容的源。",
"The media is encrypted and we do not have the keys to decrypt it.": "视频已加密,无法解密。"
});
});

View file

@ -24,4 +24,4 @@ videojs.addLanguage("zh-TW",{
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由於影片檔案損毀或是該影片使用了您的瀏覽器不支援的功能,播放終止。",
"No compatible source was found for this media.": "無法找到相容此影片的來源。",
"The media is encrypted and we do not have the keys to decrypt it.": "影片已加密,無法解密。"
});
});

Binary file not shown.

BIN
node_modules/video.js/dist/video-js-5.0.0.zip generated vendored Normal file

Binary file not shown.

View file

@ -30,11 +30,11 @@
.vjs-icon-play-circle:before {
content: '\f102'; }
.vjs-icon-pause, .video-js.vjs-playing .vjs-play-control {
.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-playing .vjs-play-control:before {
.vjs-icon-pause:before, .video-js .vjs-play-control.vjs-playing:before {
content: '\f103'; }
.vjs-icon-volume-mute, .video-js .vjs-mute-control.vjs-vol-0, .video-js .vjs-volume-menu-button.vjs-vol-0 {
@ -86,11 +86,11 @@
.vjs-icon-square:before {
content: '\f10a'; }
.vjs-icon-spinner, .vjs-loading-spinner {
.vjs-icon-spinner {
font-family: VideoJS;
font-weight: normal;
font-style: normal; }
.vjs-icon-spinner:before, .vjs-loading-spinner:before {
.vjs-icon-spinner:before {
content: '\f10b'; }
.vjs-icon-subtitles, .video-js .vjs-subtitles-button {
@ -128,11 +128,11 @@
.vjs-icon-cog:before {
content: '\f110'; }
.vjs-icon-circle, .video-js .vjs-play-progress, .video-js .vjs-volume-level {
.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-play-progress:before, .video-js .vjs-volume-level:before {
.vjs-icon-circle:before, .video-js .vjs-mouse-display:before, .video-js .vjs-play-progress:before, .video-js .vjs-volume-level:before {
content: '\f111'; }
.vjs-icon-circle-outline {
@ -171,6 +171,7 @@
/* 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;
@ -192,18 +193,31 @@
.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. */
.video-js.vjs-fluid, .video-js.vjs-16-9 {
/* 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 {
width: 100%;
max-width: 100%;
height: 0;
height: 0; }
.video-js.vjs-16-9 {
padding-top: 56.25%; }
.video-js.vjs-4-3 {
width: 100%;
max-width: 100%;
height: 0;
padding-top: 75%; }
.video-js.vjs-fill {
@ -270,7 +284,7 @@ about what's required to play video. */
margin: 0px auto; }
.vjs-no-js a, .vjs-no-js a:visited {
color: #F4A460; }
color: #66A8CC; }
.video-js .vjs-big-play-button {
font-size: 3em;
@ -285,10 +299,10 @@ about what's required to play video. */
padding: 0;
cursor: pointer;
opacity: 1;
border: 2px solid #fff;
border: 0.06666em solid #fff;
/* Need a slightly gray bg so it can be seen on black backgrounds */
background-color: #000;
background-color: rgba(0, 0, 0, 0.8);
background-color: #2B333F;
background-color: rgba(43, 51, 63, 0.7);
-webkit-border-radius: 0.3em;
-moz-border-radius: 0.3em;
border-radius: 0.3em;
@ -297,39 +311,158 @@ about what's required to play video. */
-o-transition: all 0.4s;
transition: all 0.4s; }
.video-js.vjs-big-play-centered .vjs-big-play-button {
.vjs-big-play-centered .vjs-big-play-button {
top: 50%;
left: 50%;
margin-top: -0.75em;
margin-left: -1.5em; }
.video-js.vjs-controls-disabled .vjs-big-play-button, .video-js.vjs-has-started .vjs-big-play-button, .video-js.vjs-using-native-controls .vjs-big-play-button {
display: none; }
.video-js:hover .vjs-big-play-button, .video-js .vjs-big-play-button:focus {
outline: 0;
border-color: #fff;
background-color: #595959;
background-color: rgba(89, 89, 89, 0.75);
background-color: #73859f;
background-color: rgba(115, 133, 159, 0.5);
-webkit-transition: all 0s;
-moz-transition: all 0s;
-o-transition: all 0s;
transition: all 0s; }
.vjs-error .vjs-big-play-button {
.vjs-controls-disabled .vjs-big-play-button, .vjs-has-started .vjs-big-play-button, .vjs-using-native-controls .vjs-big-play-button, .vjs-error .vjs-big-play-button {
display: none; }
.video-js button {
background: none;
border: none;
color: #fff;
color: inherit;
display: inline-block;
overflow: visible;
font-size: inherit;
line-height: inherit;
text-transform: none;
text-decoration: none;
transition: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none; }
.vjs-menu-button {
cursor: pointer; }
.vjs-menu .vjs-menu-content {
display: block;
padding: 0;
margin: 0;
overflow: auto; }
/* prevent menus from opening while scrubbing (FF, IE) */
.vjs-scrubbing .vjs-menu-button:hover .vjs-menu {
display: none; }
.vjs-menu li {
list-style: none;
margin: 0;
padding: 0.2em 0;
line-height: 1.4em;
font-size: 1.2em;
text-align: center;
text-transform: lowercase; }
.vjs-menu li:focus, .vjs-menu li:hover {
outline: 0;
background-color: #73859f;
background-color: rgba(115, 133, 159, 0.5); }
.vjs-menu li.vjs-selected, .vjs-menu li.vjs-selected:focus, .vjs-menu li.vjs-selected:hover {
background-color: #fff;
color: #2B333F; }
.vjs-menu li.vjs-menu-title {
text-align: center;
text-transform: uppercase;
font-size: 1em;
line-height: 2em;
padding: 0;
margin: 0 0 0.3em 0;
font-weight: bold;
cursor: default; }
.vjs-menu-button-popup .vjs-menu {
display: none;
position: absolute;
bottom: 0;
width: 10em;
left: -3em;
/* (Width of vjs-menu - width of button) / 2 */
height: 0em;
margin-bottom: 1.5em;
border-top-color: rgba(43, 51, 63, 0.7);
/* Same as ul background */ }
/* Button Pop-up Menu */
.vjs-menu-button-popup .vjs-menu ul {
background-color: #2B333F;
background-color: rgba(43, 51, 63, 0.7);
position: absolute;
width: 100%;
bottom: 1.5em;
/* Same bottom as vjs-menu border-top */
max-height: 15em; }
.vjs-menu-button-popup:hover .vjs-menu, .vjs-menu-button-popup .vjs-menu.vjs-lock-showing {
display: block; }
.video-js .vjs-menu-button-inline {
-webkit-transition: all 0.4s;
-moz-transition: all 0.4s;
-o-transition: all 0.4s;
transition: all 0.4s;
overflow: hidden; }
.video-js .vjs-menu-button-inline:before {
width: 2.222222222em; }
.video-js .vjs-menu-button-inline:hover, .video-js .vjs-menu-button-inline:focus, .video-js .vjs-menu-button-inline.vjs-slider-active, .video-js.vjs-no-flex .vjs-menu-button-inline {
width: 12em; }
.video-js .vjs-menu-button-inline.vjs-slider-active {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none; }
.vjs-menu-button-inline .vjs-menu {
opacity: 0;
height: 100%;
width: auto;
position: absolute;
left: 2.2222222em;
top: 0;
padding: 0;
margin: 0;
-webkit-transition: all 0.4s;
-moz-transition: all 0.4s;
-o-transition: all 0.4s;
transition: all 0.4s; }
.vjs-menu-button-inline:hover .vjs-menu, .vjs-menu-button-inline:focus .vjs-menu, .vjs-menu-button-inline.vjs-slider-active .vjs-menu {
display: block;
opacity: 1; }
.vjs-no-flex .vjs-menu-button-inline .vjs-menu {
display: block;
opacity: 1;
position: relative;
width: auto; }
.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu, .vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu, .vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu {
width: auto; }
.vjs-menu-button-inline .vjs-menu-content {
width: auto;
height: 100%;
margin: 0;
overflow: hidden; }
.video-js .vjs-control-bar {
display: none;
width: 100%;
@ -339,9 +472,9 @@ about what's required to play video. */
right: 0;
height: 3em;
background-color: #2B333F;
background-color: rgba(43, 51, 63, 0.5); }
background-color: rgba(43, 51, 63, 0.7); }
.video-js.vjs-has-started .vjs-control-bar {
.vjs-has-started .vjs-control-bar {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
@ -353,7 +486,7 @@ about what's required to play video. */
-o-transition: visibility 0.1s, opacity 0.1s;
transition: visibility 0.1s, opacity 0.1s; }
.video-js.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
visibility: hidden;
opacity: 0;
-webkit-transition: visibility 1s, opacity 1s;
@ -361,10 +494,11 @@ about what's required to play video. */
-o-transition: visibility 1s, opacity 1s;
transition: visibility 1s, opacity 1s; }
.video-js.video-js.video-js.vjs-controls-disabled .vjs-control-bar, .video-js.video-js.video-js.vjs-using-native-controls .vjs-control-bar, .video-js.video-js.video-js.vjs-error .vjs-control-bar {
display: none; }
.vjs-controls-disabled .vjs-control-bar, .vjs-using-native-controls .vjs-control-bar, .vjs-error .vjs-control-bar {
/* !important is ok in this context. */
display: none !important; }
.video-js.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
opacity: 1;
visibility: visible; }
@ -374,11 +508,11 @@ fonts to show/hide properly.
- Found in XP IE8 from http://modern.ie. Does not show up in "IE8 mode" in IE9
*/
@media \0screen {
.video-js.vjs-user-inactive.vjs-playing .vjs-control-bar :before {
.vjs-user-inactive.vjs-playing .vjs-control-bar :before {
content: ""; } }
/* IE 8 + 9 Support */
.video-js.vjs-has-started.vjs-no-flex .vjs-control-bar {
.vjs-has-started.vjs-no-flex .vjs-control-bar {
display: table; }
.video-js .vjs-control {
@ -449,6 +583,9 @@ fonts to show/hide properly.
-ms-flex-align: center;
align-items: center; }
.vjs-live .vjs-progress-control {
display: none; }
/* Box containing play and load progresses. Also acts as seek scrubber. */
.video-js .vjs-progress-holder {
-webkit-box-flex: auto;
@ -467,7 +604,7 @@ fonts to show/hide properly.
font-size: 1.6666666667em; }
/* Also show the current time tooltip */
.video-js .vjs-progress-control:hover .vjs-play-progress:after {
.video-js .vjs-progress-control:hover .vjs-mouse-display:after, .video-js .vjs-progress-control:hover .vjs-play-progress:after {
display: block;
/* If we let the font size grow as much as everything else, the current time tooltip ends up
ginormous. If you'd like to enable the current time tooltip all the time, this should be disabled
@ -487,17 +624,18 @@ fonts to show/hide properly.
left: 0;
top: 0; }
.video-js .vjs-mouse-display:before {
display: none; }
.video-js .vjs-play-progress {
background-color: #fff; }
.video-js .vjs-play-progress:before {
position: absolute;
top: -0.3333333333em;
right: -0.5em;
font-size: 0.9em;
height: 1em;
line-height: 1em; }
font-size: 0.9em; }
.video-js .vjs-play-progress:after {
.video-js .vjs-mouse-display:after, .video-js .vjs-play-progress:after {
/* By default this is hidden and only shown when hovering over the progress control */
display: none;
position: absolute;
@ -513,27 +651,64 @@ fonts to show/hide properly.
-moz-border-radius: 0.3em;
border-radius: 0.3em; }
.video-js .vjs-play-progress:before, .video-js .vjs-play-progress:after {
z-index: 1; }
.video-js .vjs-load-progress {
background: #646464;
/* IE8- Fallback */
background: rgba(255, 255, 255, 0.2); }
/* For IE8 we'll lighten the color */
background: ligthen(#73859f, 25%);
/* Otherwise we'll rely on stacked opacities */
background: rgba(115, 133, 159, 0.5); }
/* there are child elements of the load progress bar that represent the
specific time ranges that have been buffered */
.video-js .vjs-load-progress div {
background: rgba(89, 89, 89, 0.1); }
/* For IE8 we'll lighten the color */
background: ligthen(#73859f, 50%);
/* Otherwise we'll rely on stacked opacities */
background: rgba(115, 133, 159, 0.75); }
.video-js.vjs-no-flex .vjs-progress-control {
width: auto; }
.video-js .vjs-progress-control .vjs-mouse-display {
display: none;
position: absolute;
width: 1px;
height: 100%;
background-color: #000;
z-index: 1; }
.vjs-no-flex .vjs-progress-control .vjs-mouse-display {
z-index: 0; }
.video-js .vjs-progress-control:hover .vjs-mouse-display {
display: block; }
.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display, .video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display:after {
visibility: hidden;
opacity: 0;
-webkit-transition: visibility 1s, opacity 1s;
-moz-transition: visibility 1s, opacity 1s;
-o-transition: visibility 1s, opacity 1s;
transition: visibility 1s, opacity 1s; }
.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display, .video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display:after {
display: none; }
.video-js .vjs-progress-control .vjs-mouse-display:after {
color: #fff;
background-color: #000;
background-color: rgba(0, 0, 0, 0.8); }
.video-js .vjs-slider {
outline: 0;
position: relative;
cursor: pointer;
padding: 0;
margin: 0 0.45em 0 0.45em;
background-color: #595959;
background-color: rgba(89, 89, 89, 0.9); }
background-color: #73859f;
background-color: rgba(115, 133, 159, 0.5); }
.video-js .vjs-slider:focus {
text-shadow: 0em 0em 1em white;
@ -568,11 +743,11 @@ specific time ranges that have been buffered */
.video-js .vjs-volume-bar {
margin: 1.35em; }
.video-js .vjs-volume-bar.vjs-slider-horizontal {
.vjs-volume-bar.vjs-slider-horizontal {
width: 5em;
height: 0.3em; }
.video-js .vjs-volume-bar.vjs-slider-vertical {
.vjs-volume-bar.vjs-slider-vertical {
width: 0.3em;
height: 5em; }
@ -585,23 +760,23 @@ specific time ranges that have been buffered */
position: absolute;
font-size: 0.9em; }
.video-js .vjs-slider-vertical .vjs-volume-level {
.vjs-slider-vertical .vjs-volume-level {
width: 0.3em; }
.video-js .vjs-slider-vertical .vjs-volume-level:before {
.vjs-slider-vertical .vjs-volume-level:before {
top: -0.5em;
left: -0.3em; }
.video-js .vjs-slider-horizontal .vjs-volume-level {
.vjs-slider-horizontal .vjs-volume-level {
height: 0.3em; }
.video-js .vjs-slider-horizontal .vjs-volume-level:before {
.vjs-slider-horizontal .vjs-volume-level:before {
top: -0.3em;
right: -0.5em; }
/* Assumes volume starts at 1.0. */
.video-js .vjs-volume-bar.vjs-slider-vertical .vjs-volume-level {
.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level {
height: 100%; }
.video-js .vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level {
.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level {
width: 100%; }
/* The volume menu button is like menu buttons (captions/subtitles) but works
@ -609,146 +784,36 @@ a little differently. It needs to be possible to tab to the volume slider
without hitting space bar on the menu button. To do this we're not using
display:none to hide the slider menu by default, and instead setting the
width and height to zero. */
.video-js .vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu {
.vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu {
display: block;
width: 0;
height: 0;
border-top-color: transparent; }
.video-js .vjs-volume-menu-button.vjs-volume-menu-button-vertical .vjs-menu {
.vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu {
left: 0.5em; }
.video-js .vjs-volume-menu-button-popup.vjs-volume-menu-button-horizontal .vjs-menu {
.vjs-menu-button-popup.vjs-volume-menu-button-horizontal .vjs-menu {
left: -2em; }
.video-js .vjs-menu-button.vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu .vjs-menu-content {
.vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu-content {
height: 0;
width: 0;
overflow-x: hidden;
overflow-y: hidden; }
.video-js .vjs-volume-menu-button.vjs-volume-menu-button-vertical:hover .vjs-menu .vjs-menu-content, .video-js .vjs-volume-menu-button.vjs-volume-menu-button-vertical .vjs-menu.vjs-lock-showing .vjs-menu-content {
.vjs-volume-menu-button-vertical:hover .vjs-menu-content, .vjs-volume-menu-button-vertical .vjs-lock-showing .vjs-menu-content {
height: 8em;
width: 2.9em; }
.video-js .vjs-volume-menu-button.vjs-volume-menu-button-horizontal:hover .vjs-menu .vjs-menu-content, .video-js .vjs-volume-menu-button.vjs-volume-menu-button-horizontal .vjs-menu.vjs-lock-showing .vjs-menu-content {
.vjs-volume-menu-button-horizontal:hover .vjs-menu-content, .vjs-volume-menu-button-horizontal .vjs-lock-showing .vjs-menu-content {
height: 2.9em;
width: 8em; }
.video-js .vjs-mute-control, .video-js .vjs-volume-control {
display: none; }
.video-js .vjs-menu-button {
cursor: pointer; }
.video-js .vjs-menu .vjs-menu-content {
display: block;
padding: 0;
margin: 0;
overflow: auto; }
/* prevent menus from opening while scrubbing (FF, IE) */
.video-js.vjs-scrubbing .vjs-menu-button:hover .vjs-menu {
display: none; }
.video-js .vjs-menu ul li {
list-style: none;
margin: 0;
padding: 0.2em 0;
line-height: 1.4em;
font-size: 1.2em;
text-align: center;
text-transform: lowercase; }
.video-js .vjs-menu ul li.vjs-selected {
background-color: #000; }
.video-js .vjs-menu ul li:focus, .video-js .vjs-menu ul li:hover, .video-js .vjs-menu ul li.vjs-selected:focus, .video-js .vjs-menu ul li.vjs-selected:hover {
outline: 0;
color: #000;
background-color: #fff;
background-color: rgba(255, 255, 255, 0.75); }
.video-js .vjs-menu ul li.vjs-menu-title {
text-align: center;
text-transform: uppercase;
font-size: 1em;
line-height: 2em;
padding: 0;
margin: 0 0 0.3em 0;
font-weight: bold;
cursor: default; }
.video-js .vjs-menu-button-popup .vjs-menu {
display: none;
position: absolute;
bottom: 0;
left: -3em;
/* (Width of vjs-menu - width of button) / 2 */
width: 0em;
height: 0em;
margin-bottom: 1.5em;
border-top-color: rgba(7, 40, 50, 0.5);
/* Same as ul background */ }
/* Button Pop-up Menu */
.video-js .vjs-menu-button-popup .vjs-menu-content {
background-color: #000;
background-color: rgba(0, 0, 0, 0.7); }
.video-js .vjs-menu-button-popup .vjs-menu .vjs-menu-content {
position: absolute;
width: 10em;
bottom: 1.5em;
/* Same bottom as vjs-menu border-top */
max-height: 15em; }
.video-js .vjs-menu-button.vjs-menu-button-popup:hover .vjs-menu, .video-js .vjs-menu-button-popup .vjs-menu.vjs-lock-showing {
display: block; }
.video-js .vjs-menu-button-inline {
-webkit-transition: all 0.4s;
-moz-transition: all 0.4s;
-o-transition: all 0.4s;
transition: all 0.4s;
overflow: hidden; }
.video-js .vjs-menu-button.vjs-menu-button-inline:before {
width: 2.222222222em; }
.video-js .vjs-menu-button-inline .vjs-menu {
opacity: 0;
height: 100%;
width: auto;
position: absolute;
left: 2.2222222em;
top: 0;
padding: 0;
margin: 0;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s; }
.video-js.vjs-no-flex .vjs-menu-button-inline .vjs-menu {
position: relative;
width: 0; }
.video-js.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu {
width: auto; }
.video-js .vjs-menu-button-inline .vjs-menu .vjs-menu-content {
width: auto;
height: 100%;
margin: 0;
overflow: hidden; }
.video-js .vjs-menu-button-inline:hover {
width: 10em; }
.video-js .vjs-menu-button.vjs-menu-button-inline:hover .vjs-menu, .video-js .vjs-menu-button-inline .vjs-menu.vjs-lock-showing {
display: block;
opacity: 1; }
.vjs-volume-menu-button.vjs-menu-button-inline .vjs-menu-content {
/* An inline volume should never have a menu background color.
This protects it from external changes to background colors. */
background-color: transparent !important; }
.vjs-poster {
display: inline-block;
@ -766,6 +831,7 @@ width and height to zero. */
left: 0;
height: 100%; }
/* Used for IE8 fallback */
.vjs-poster img {
display: block;
vertical-align: middle;
@ -775,30 +841,44 @@ width and height to zero. */
width: 100%; }
/* Hide the poster after the video has started playing */
.video-js.vjs-has-started .vjs-poster {
.vjs-has-started .vjs-poster {
display: none; }
/* Don't hide the poster if we're playing audio */
.video-js.vjs-audio.vjs-has-started .vjs-poster {
.vjs-audio.vjs-has-started .vjs-poster {
display: block; }
/* Hide the poster when controls are disabled because it's clickable
and the native poster can take over */
.video-js.vjs-controls-disabled .vjs-poster {
.vjs-controls-disabled .vjs-poster {
display: none; }
/* Hide the poster when native controls are used otherwise it covers them */
.video-js.vjs-using-native-controls .vjs-poster {
display: none; }
.video-js.vjs-live .vjs-time-control, .video-js.vjs-live .vjs-time-divider, .video-js.vjs-live .vjs-progress-control {
.vjs-using-native-controls .vjs-poster {
display: none; }
.video-js .vjs-live-control {
display: none;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: flex-start;
-webkit-align-items: flex-start;
-ms-flex-align: flex-start;
align-items: flex-start;
-webkit-box-flex: auto;
-moz-box-flex: auto;
-webkit-flex: auto;
-ms-flex: auto;
flex: auto;
font-size: 1em;
line-height: 3em; }
.vjs-no-flex .vjs-live-control {
display: table-cell;
width: auto;
text-align: left; }
.video-js .vjs-time-control {
-webkit-box-flex: none;
-moz-box-flex: none;
@ -808,17 +888,23 @@ and the native poster can take over */
font-size: 1em;
line-height: 3em; }
/* We need the extra specificity that referencing .vjs-no-flex provides. */
.video-js .vjs-current-time, .video-js.vjs-no-flex .vjs-current-time {
.vjs-live .vjs-time-control {
display: none; }
.video-js .vjs-duration, .video-js.vjs-no-flex .vjs-duration {
/* We need the extra specificity that referencing .vjs-no-flex provides. */
.video-js .vjs-current-time, .vjs-no-flex .vjs-current-time {
display: none; }
.video-js .vjs-duration, .vjs-no-flex .vjs-duration {
display: none; }
.vjs-time-divider {
display: none;
line-height: 3em; }
.vjs-live .vjs-time-divider {
display: none; }
.video-js .vjs-play-control {
cursor: pointer;
-webkit-box-flex: none;
@ -827,7 +913,7 @@ and the native poster can take over */
-ms-flex: none;
flex: none; }
.video-js .vjs-text-track-display {
.vjs-text-track-display {
position: absolute;
bottom: 3em;
left: 0;
@ -848,11 +934,11 @@ and the native poster can take over */
background-color: #000;
background-color: rgba(0, 0, 0, 0.5); }
.video-js .vjs-subtitles {
.vjs-subtitles {
color: #fff;
/* Subtitles are white */ }
.video-js .vjs-captions {
.vjs-captions {
color: #fc6;
/* Captions are yellow */ }
@ -869,7 +955,7 @@ and the native poster can take over */
flex: none; }
/* Switch to the exit icon when the player is in fullscreen */
.video-js .vjs-playback-rate .vjs-playback-rate-value {
.vjs-playback-rate .vjs-playback-rate-value {
font-size: 1.5em;
line-height: 2;
position: absolute;
@ -879,13 +965,9 @@ and the native poster can take over */
height: 100%;
text-align: center; }
.video-js .vjs-playback-rate .vjs-menu {
left: 0em; }
.video-js .vjs-playback-rate.vjs-menu-button .vjs-menu .vjs-menu-content {
.vjs-playback-rate .vjs-menu {
width: 4em;
left: 0;
list-style: none; }
left: 0em; }
.vjs-error-display {
display: none; }
@ -902,7 +984,7 @@ and the native poster can take over */
content: 'X';
font-family: Arial, Helvetica, sans-serif;
font-size: 4em;
color: #595959;
color: #fff;
/* In order to center the play icon vertically we need to set the line height
to the same as the button height */
line-height: 1;
@ -928,82 +1010,101 @@ and the native poster can take over */
background-color: rgba(0, 0, 0, 0.5); }
.vjs-error-display a, .vjs-error-display a:visited {
color: #F4A460; }
color: #66A8CC; }
.vjs-loading-spinner {
display: none;
position: absolute;
top: 50%;
left: 50%;
font-size: 4em;
line-height: 1;
width: 1em;
height: 1em;
margin-left: -0.5em;
margin-top: -0.5em;
opacity: 0.75; }
margin: -25px 0 0 -25px;
opacity: 0.85;
/* Need to fix centered page layouts */
text-align: left;
border: 6px solid rgba(43, 51, 63, 0.7);
box-sizing: border-box;
background-clip: padding-box;
width: 50px;
height: 50px;
border-radius: 25px; }
/* Show the spinner when waiting for data and seeking to a new time */
.vjs-waiting .vjs-loading-spinner, .vjs-seeking .vjs-loading-spinner {
display: block;
/* only animate when showing because it can be processor heavy */
-webkit-animation: spin 1.5s infinite linear;
-moz-animation: spin 1.5s infinite linear;
-o-animation: spin 1.5s infinite linear;
animation: spin 1.5s infinite linear; }
.vjs-seeking .vjs-loading-spinner, .vjs-waiting .vjs-loading-spinner {
display: block; }
/* Errors are unrecoverable without user interaction so hide the spinner */
.vjs-error .vjs-loading-spinner {
display: none;
/* ensure animation doesn't continue while hidden */
-webkit-animation: none;
-moz-animation: none;
-o-animation: none;
animation: none; }
.video-js .vjs-loading-spinner:before {
.vjs-loading-spinner:before, .vjs-loading-spinner:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 1em;
height: 1em;
text-align: center;
text-shadow: 0em 0em 0.1em #000; }
margin: -6px;
box-sizing: inherit;
width: inherit;
height: inherit;
border-radius: inherit;
/* Keep 100% opacity so they don't show through each other */
opacity: 1;
border: inherit;
border-color: transparent;
border-top-color: white; }
@-moz-keyframes spin {
/* only animate when showing because it can be processor heavy */
.vjs-seeking .vjs-loading-spinner:before, .vjs-seeking .vjs-loading-spinner:after, .vjs-waiting .vjs-loading-spinner:before, .vjs-waiting .vjs-loading-spinner:after {
-webkit-animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite;
animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite; }
.vjs-seeking .vjs-loading-spinner:before, .vjs-waiting .vjs-loading-spinner:before {
border-top-color: white; }
.vjs-seeking .vjs-loading-spinner:after, .vjs-waiting .vjs-loading-spinner:after {
border-top-color: white;
-webkit-animation-delay: 0.44s;
animation-delay: 0.44s; }
@keyframes vjs-spinner-spin {
100% {
transform: rotate(360deg); } }
@-webkit-keyframes vjs-spinner-spin {
100% {
-webkit-transform: rotate(360deg); } }
@keyframes vjs-spinner-fade {
0% {
-moz-transform: rotate(0deg); }
border-top-color: #73859f; }
20% {
border-top-color: #73859f; }
35% {
border-top-color: white; }
60% {
border-top-color: #73859f; }
100% {
-moz-transform: rotate(359deg); } }
border-top-color: #73859f; } }
@-webkit-keyframes spin {
@-webkit-keyframes vjs-spinner-fade {
0% {
-webkit-transform: rotate(0deg); }
border-top-color: #73859f; }
20% {
border-top-color: #73859f; }
35% {
border-top-color: white; }
60% {
border-top-color: #73859f; }
100% {
-webkit-transform: rotate(359deg); } }
border-top-color: #73859f; } }
@-o-keyframes spin {
0% {
-o-transform: rotate(0deg); }
.vjs-chapters-button .vjs-menu {
left: -10em;
/* (Width of vjs-menu - width of vjs-control) / 2 */
width: 0; }
100% {
-o-transform: rotate(359deg); } }
@keyframes spin {
0% {
transform: rotate(0deg); }
100% {
transform: rotate(359deg); } }
.video-js .vjs-chapters-button.vjs-menu-button .vjs-menu {
left: 2em; }
.video-js .vjs-chapters-button.vjs-menu-button .vjs-menu .vjs-menu-content {
width: 24em;
left: -12em; }
.vjs-chapters-button .vjs-menu ul {
width: 24em; }
.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-custom-control-spacer {
-webkit-box-flex: auto;
@ -1025,13 +1126,12 @@ and the native poster can take over */
.vjs-caption-settings {
position: relative;
top: 1em;
background-color: #000;
opacity: 0.75;
background-color: #2B333F;
background-color: rgba(43, 51, 63, 0.75);
color: #fff;
margin: 0 auto;
padding: 0.5em;
height: 15em;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
width: 40em; }

File diff suppressed because one or more lines are too long

2475
node_modules/video.js/dist/video.js generated vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -23,7 +23,6 @@
.vjs-resolution-button ul.vjs-menu-content {
width: 4em !important;
right: -7em !important;
}
.vjs-resolution-button .vjs-menu {

View file

@ -1,12 +1,115 @@
/*! videojs-resolution-switcher - v0.0.0 - 2015-7-26
* Copyright (c) 2015 Kasper Moskwiak
* Modified by Pierre Kraft
* Licensed under the Apache-2.0 license. */
(function(window, videojs) {
/* jshint eqnull: true*/
'use strict';
var defaults = {},
videoJsResolutionSwitcher,
groupedSrc;
videoJsResolutionSwitcher;
function setSourcesSanitized(player, sources) {
return player.src(sources.map(function(src) {
return {src: src.src, type: src.type, res: src.res};
}));
}
/*
* Resolution menu item
*/
var MenuItem = videojs.getComponent('MenuItem');
var ResolutionMenuItem = videojs.extend(MenuItem, {
constructor: function(player, options, onClickListener, label){
this.onClickListener = onClickListener;
this.label = label;
// Sets this.player_, this.options_ and initializes the component
MenuItem.call(this, player, options);
this.src = options.src;
this.on('click', this.onClick);
this.on('touchstart', this.onClick);
if (options.initialySelected) {
this.showAsLabel();
this.selected(true);
}
},
showAsLabel: function() {
// Change menu button label to the label of this item if the menu button label is provided
if(this.label) {
this.label.innerHTML = this.options_.label;
}
},
onClick: function(){
this.onClickListener(this);
// Hide bigPlayButton
this.player_.bigPlayButton.hide();
// Remember player state
var currentTime = this.player_.currentTime();
var isPaused = this.player_.paused();
this.showAsLabel();
// Change player source and wait for loadeddata event, then play video
// loadedmetadata doesn't work right now for flash.
// Probably because of https://github.com/videojs/video-js-swf/issues/124
setSourcesSanitized(this.player_, this.src).one('loadeddata', function() {
this.player_.currentTime(currentTime);
if(!isPaused){
// Start playing and hide loadingSpinner (flash issue ?)
this.player_.play().handleTechSeeked_();
}
this.player_.trigger('resolutionchange');
});
}
});
/*
* Resolution menu button
*/
var MenuButton = videojs.getComponent('MenuButton');
var ResolutionMenuButton = videojs.extend(MenuButton, {
constructor: function(player, options, settings, label){
this.sources = options.sources;
this.label = label;
this.label.innerHTML = options.initialySelectedLabel;
// Sets this.player_, this.options_ and initializes the component
MenuButton.call(this, player, options);
this.controlText('Quality');
if(settings.dynamicLabel){
this.el().appendChild(label);
}else{
var staticLabel = document.createElement('span');
staticLabel.classList.add('vjs-resolution-button-staticlabel');
this.el().appendChild(staticLabel);
}
},
createItems: function(){
var menuItems = [];
var labels = (this.sources && this.sources.label) || {};
var onClickUnselectOthers = function(clickedItem) {
menuItems.map(function(item) {
item.selected(item === clickedItem);
});
};
for (var key in labels) {
if (labels.hasOwnProperty(key)) {
menuItems.push(new ResolutionMenuItem(
this.player_,
{
label: key,
src: labels[key],
initialySelected: key === this.options_.initialySelectedLabel
},
onClickUnselectOthers,
this.label));
}
}
return menuItems;
}
});
/**
* Initialize the plugin.
@ -17,91 +120,25 @@
player = this,
label = document.createElement('span');
label.classList.add('vjs-resolution-button-label')
/*
* Resolution menu item
*/
var MenuItem = videojs.getComponent('MenuItem')
var ResolutionMenuItem = videojs.extends(MenuItem, {
constructor: function(player, options){
MenuItem.call(this, player, options);
this.src = options.src;
this.type = options.type;
this.on('click', this.onClick)
this.on('touchstart', this.onClick)
},
onClick: function(){
// Hide bigPlayButton
player.bigPlayButton.hide()
// Remember player state
var currentTime = player.currentTime()
var isPaused = player.paused()
// Change menu button label
label.innerHTML = this.options_.label;
// Change player source and wait for loadedmetadata event, then play video
player.src({src: this.src, type: this.type}).one( 'loadedmetadata', function() {
player.currentTime(currentTime)
if(!isPaused){ player.play() }
player.trigger('resolutionchange')
})
}
})
/*
* Resolution menu button
*/
var MenuButton = videojs.getComponent('MenuButton')
var ResolutionMenuButton = videojs.extends(MenuButton, {
constructor: function(player, options){
this.sources = options.sources;
MenuButton.call(this, player, options);
this.controlText('Quality');
if(settings.dynamicLabel){
this.el().appendChild(label)
}else{
var staticLabel = document.createElement('span')
staticLabel.classList.add('vjs-resolution-button-staticlabel')
this.el().appendChild(staticLabel)
}
},
createItems: function(){
var sources = this.sources;
var menuItems = [];
for(var i = 0; i < sources.length; i++){
menuItems.push(new ResolutionMenuItem(player, {
label: sources[i].label,
src: sources[i].src,
type: sources[i].type
}))
}
return menuItems;
}
})
label.classList.add('vjs-resolution-button-label');
player.updateSrc = function(src){
//Return current src if src is not given
if(!src){ return player.src() }
if(!src){ return player.src(); }
// Dispose old resolution menu button before adding new sources
if(player.controlBar.resolutionSwitcher){
player.controlBar.resolutionSwitcher.dispose()
delete player.controlBar.resolutionSwitcher
player.controlBar.resolutionSwitcher.dispose();
delete player.controlBar.resolutionSwitcher;
}
//Sort sources
src = src.sort(compareResolutions)
groupedSrc = bucketSources(src)
var menuButton = new ResolutionMenuButton(player, { sources: src });
menuButton.el().classList.add('vjs-resolution-button')
player.controlBar.resolutionSwitcher = player.controlBar.addChild(menuButton)
var newSource = chooseSrc(src)
label.innerHTML = newSource.label
player.src(newSource);
}
src = src.sort(compareResolutions);
var groupedSrc = bucketSources(src);
var choosen = chooseSrc(groupedSrc, src);
var menuButton = new ResolutionMenuButton(player, { sources: groupedSrc, initialySelectedLabel: choosen.label , initialySelectedRes: choosen.res}, settings, label);
menuButton.el().classList.add('vjs-resolution-button');
player.controlBar.resolutionSwitcher = player.controlBar.addChild(menuButton);
return setSourcesSanitized(player, choosen.sources);
};
/**
* Method used for sorting list of sources
@ -110,47 +147,72 @@
* @returns {Number} result of comparation
*/
function compareResolutions(a, b){
if(!a.res || !b.res) return 0;
if(!a.res || !b.res){ return 0; }
return (+b.res)-(+a.res);
}
/**
* Group sources by label, resolution and type
* @param {Array} src Array of sources
* @returns {Object} grouped sources: { label: {}, res: {}, type: {} }
* @returns {Object} grouped sources: { label: { key: [] }, res: { key: [] }, type: { key: [] } }
*/
function bucketSources(src){
var resolutions = {
label: {},
res: {},
type: {}
};
src.map(function(source) {
initResolutionKey(resolutions, 'label', source);
initResolutionKey(resolutions, 'res', source);
initResolutionKey(resolutions, 'type', source);
appendSourceToKey(resolutions, 'label', source);
appendSourceToKey(resolutions, 'res', source);
appendSourceToKey(resolutions, 'type', source);
});
return resolutions;
}
function initResolutionKey(resolutions, key, source) {
if(resolutions[key][source[key]] == null) {
resolutions[key][source[key]] = [];
}
for(var i = 0; i<src.length; i++){
resolutions.label[src[i].label] = resolutions.label[src[i].label] || []
resolutions.res[src[i].res] = resolutions.res[src[i].res] || []
resolutions.type[src[i].type] = resolutions.type[src[i].type] || []
resolutions.label[src[i].label].push(src[i])
resolutions.res[src[i].res].push(src[i])
resolutions.type[src[i].type].push(src[i])
}
return resolutions
}
function appendSourceToKey(resolutions, key, source) {
resolutions[key][source[key]].push(source);
}
/**
* Choose src if option.default is specified
* @param {Array} src Array of sources
* @returns {Object} source object
* @param {Object} groupedSrc {res: { key: [] }}
* @param {Array} src Array of sources sorted by resolution used to find high and low res
* @returns {Object} {res: string, sources: []}
*/
function chooseSrc(src){
if(settings.default === 'low'){ return src[src.length - 1] }
if(settings.default === 'high'){ return src[0] }
if(groupedSrc.res[settings.default]){ return groupedSrc.res[settings.default][0] }
return src[src.length - 1]
function chooseSrc(groupedSrc, src){
var selectedRes = settings.default;
var selectedLabel = '';
if (selectedRes === 'high') {
selectedRes = src[0].res;
selectedLabel = src[0].label;
} else if (selectedRes === 'low' || selectedRes == null) {
// Select low-res if default is low or not set
selectedRes = src[src.length - 1].res;
selectedLabel = src[src.length -1].label;
} else if (groupedSrc.res[selectedRes]) {
selectedLabel = groupedSrc.res[selectedRes][0].label;
}
if(selectedRes === undefined){
return {res: selectedRes, label: selectedLabel, sources: groupedSrc.label[selectedLabel]};
}
return {res: selectedRes, label: selectedLabel, sources: groupedSrc.res[selectedRes]};
}
// Create resolution switcher for videos form <source> tag inside <video>
if(player.options_.sources.length > 1){
player.updateSrc(player.options_.sources)
player.updateSrc(player.options_.sources);
}
};

View file

@ -17,6 +17,7 @@
},
"homepage": "https://github.com/kmoskwiak/videojs-resolution-switcher#readme",
"dependencies": {
"video.js": "^5.0.0",
"videojs-resolution-switcher": "git+https://github.com/kmoskwiak/videojs-resolution-switcher.git"
}
}

View file

@ -5,33 +5,66 @@ body {
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
background: #eee;
}
a {
color: aliceblue;
}
a:hover {
color: aliceblue;
}
.header {
background: #00aad3;
background: #0082d3;
padding: 50px 50px 0px 50px;
color: #fff;
box-shadow: 0 0 20px -5px #000;
}
.example {
margin: 50px 0;
padding: 0 50px;
}
code {
color: #007f90
}
.info {
font-size: 1.2em;
}
.social {
text-align: center;
padding: 20px;
}
pre {
font-size: 0.8em;
}
.section {
border-bottom: 1px solid #ccc;
padding-bottom: 50px;
padding-top: 30px;
}
.footer {
color: #fff;
padding: 20px 50px;
text-align: center;
}
.kspr {
display: inline-block;
width: 50px;
line-height: 50px;
background: #0082d3;
border-radius: 100%;
text-align: center;
color: #fff;
text-decoration: none;
font-family: monospace;
box-shadow: 2px 2px 10px -5px #000;
}
.kspr:hover {
text-decoration: none;
color: #fff;
}