Comparar commits
12 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 32468bdce7 | |||
| fbdb3f1ce2 | |||
| 4a62ebb042 | |||
| b87fb3ce32 | |||
| fd50bd0921 | |||
| b65bad8f20 | |||
| e5595b1e38 | |||
| de843affb7 | |||
| 9c99def186 | |||
| 793da0979a | |||
| 540258181c | |||
| 1480018cfb |
@@ -12,6 +12,7 @@
|
||||
"undef" : true,
|
||||
"laxbreak" : true,
|
||||
"esnext" : true,
|
||||
"eqeqeq" : true,
|
||||
"predef" : [
|
||||
"_V_",
|
||||
"goog",
|
||||
|
||||
+13
-8
@@ -1,19 +1,24 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "iojs"
|
||||
- iojs
|
||||
before_script:
|
||||
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then curl https://gist.githubusercontent.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash; fi
|
||||
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then curl https://gist.githubusercontent.com/santiycr/5139565/raw/sauce_connect_setup.sh
|
||||
| bash; fi
|
||||
before_install:
|
||||
- export CHROME_BIN=chromium-browser
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
- export CHROME_BIN=chromium-browser
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
- "chat.freenode.net#videojs"
|
||||
- chat.freenode.net#videojs
|
||||
use_notice: true
|
||||
on_success: never
|
||||
webhooks:
|
||||
- http://pam.videojs.com/savage/travis
|
||||
env:
|
||||
global:
|
||||
- secure: K6JpKwMkfNaJix3Bb0tLjVMzHMJgtBXdd/dvfw1BMb9DCBpd81PqXbDs7yXCddUxnUPTBPxZCrQgWsw71Wn+qEoIG5MU3uOT5A2rBbx/yZonVAGv5ed/9w0xk0OzO383CmPMFqwqtp9YmdmqGjQBkYXVXJjTvNTOAExFSdhO+3U=
|
||||
- secure: GIbhjUJapvC70nIZVlhVyK+3KAD2TVKpiY/q412OO7V2izbvcM1tvU3LBoMZbROzrt5TT84tCoJDvHnrpL0OvxPwrzL5CUU7h4UTxhTOyQkEinbYAnWlW9wdrvtdczsEvANkFPqBZ53B3hVHZHMLOG8QRWaTBicF68vSHEJFqb4=
|
||||
- secure: K6JpKwMkfNaJix3Bb0tLjVMzHMJgtBXdd/dvfw1BMb9DCBpd81PqXbDs7yXCddUxnUPTBPxZCrQgWsw71Wn+qEoIG5MU3uOT5A2rBbx/yZonVAGv5ed/9w0xk0OzO383CmPMFqwqtp9YmdmqGjQBkYXVXJjTvNTOAExFSdhO+3U=
|
||||
- secure: GIbhjUJapvC70nIZVlhVyK+3KAD2TVKpiY/q412OO7V2izbvcM1tvU3LBoMZbROzrt5TT84tCoJDvHnrpL0OvxPwrzL5CUU7h4UTxhTOyQkEinbYAnWlW9wdrvtdczsEvANkFPqBZ53B3hVHZHMLOG8QRWaTBicF68vSHEJFqb4=
|
||||
- secure: gglh7xDnURKfXp9T543DD7NG1pQ8HeWh1XtRspBAwr0H7RqJBVDqqODSYSPRFhfld7M6sYmvQIXgil7XlyefnKNTXqCarvaoTg3lbip8kSltXMiNw2V6AVpsQGuja7+XbaM0do70ETTKjW4Kw6wnxEHb78BvGN/hXIeqizUAjanlDAjd7fouaxpTBIbMESe2rI+WRHPis1cmnv8v70Mrh/8Un/NO4gkebGyvA47LTDNIaVqIVjonsndr8WjMv1/PNxQ8LyCO6D64MufrobS7Sec+VuN30apwEsBw8v82MK/MZ3qXu0lUp4+ERTbuc/rymh2wDFTQeG20Kf/NTauSaH6f414KNzIRFj0/xyLAzVZKIscXM2DKXMuskkZuvHLZvaspnZWcPYTjPZl0P88N0RBqnoLdR80dR5bDljNwU2QnSBeol/q1wXNEr6I1VTRFOB+qsHrD1blVMB1I5W3I0ti1aQ7XtgMOGi1kcPb4oFcJdl+3dLFDnyRyaNfdMOnOZYBBHdQCo19Mj/L+nqPGWeeYiEAM6JsuhNjHn5Za5nGf1ztXTimVPOQjyATin0x9kST3soLWSVmdW2dBHUGDVSMhvoLLR+nKSdNQ0KfpqtgrzeLxoVnRYHVBlih41tapM9IG/6BMYnDMaRcc0i54YeUP4oxlxGSyASIenkAgC6w=
|
||||
- secure: WtIEOSnqDkCZuTlBsxwlVwaRpVTbz7ol8+XSJIZb0aFo1lLisF9cz6s9WrAfX36MaxIcDN9LFZkpXzMvNrNkZWQa1kacGWH1rbx0SiiQ8LMweAcKdnZ5uXlSplBxbJ8bZfXKB1sIHsOsYw/vWhHKkcsDUkAEzQrIiMOhuoUV3s0uKM0knKXIAfNIF0EbDzLIojm+nm+F0n5vM60LRdKesaSt/o2p2LKxdZVoFGrg48D7bdA9VEfMWWRL/evDxJmnX4p+AjBc7mklqZ5F2pYsY6XXQuuS+2Sy+lnxz01kLg+RC4Cpv5dyYfK3h0j8KeyK8IuixycVONWVe9rANq8UaIsMrRN+6uDSC8zXiH4P+h6UDMm3jetc2ZyAfhBA8OyIs5QEShae2Rd7Y3WFJxBp6UVgyj6SkXGxrEdb1ZJgTTl4dyqiP0bYrLePNP2qSJ6OTfNdG791HF077uzXI96ABdMG54Wv9N9T/hmxKwV2Lajx/GZJMmHuwT9tkHKhkcxWea1HYam9QYSFUyJ5THfNk2A9u/r8DkL62MZ85zIQBisrlFjbPAGRejq6qyirBJPAy+FCjhM+oO/i2f2bGkkAfHGT0Og1BcrWVXs54yWdO7UZgie2F+Rmdwinb/GxebZJ+21ZQ4OkVr2t1Skr/PRni9+U7q/6xCLwUJgx45XJ0FE=
|
||||
|
||||
@@ -26,6 +26,9 @@ CHANGELOG
|
||||
* @gkatsev updated the component.js styles to match the new style guide ([view](https://github.com/videojs/video.js/pull/2105))
|
||||
* @gkatsev added error logging for bad JSON formatting ([view](https://github.com/videojs/video.js/pull/2113))
|
||||
* @gkatsev added a sensible toJSON function ([view](https://github.com/videojs/video.js/pull/2114))
|
||||
* @bc-bbay fixed instance where progress bars would go passed 100% ([view](https://github.com/videojs/video.js/pull/2040))
|
||||
* @eXon began Tech 2.0 work, improved how tech events are handled by the player ([view](https://github.com/videojs/video.js/pull/2057))
|
||||
* @gkatsev added get and set global options methods ([view](https://github.com/videojs/video.js/pull/2115))
|
||||
|
||||
--------------------
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "video.js",
|
||||
"description": "An HTML5 and Flash video player with a common API and skin for both.",
|
||||
"version": "5.0.0-9",
|
||||
"version": "5.0.0-13",
|
||||
"main": [
|
||||
"dist/video-js/video.js",
|
||||
"dist/video-js/video-js.css",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "video.js",
|
||||
"description": "An HTML5 and Flash video player with a common API and skin for both.",
|
||||
"version": "5.0.0-9",
|
||||
"version": "5.0.0-13",
|
||||
"keywords": [
|
||||
"videojs",
|
||||
"html5",
|
||||
|
||||
externo
+13411
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
BIN
Arquivo binário não exibido.
externo
+40
@@ -0,0 +1,40 @@
|
||||
<?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">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="VideoJS" horiz-adv-x="512">
|
||||
<font-face units-per-em="512" ascent="480" descent="-32" />
|
||||
<missing-glyph horiz-adv-x="512" />
|
||||
<glyph unicode=" " d="" horiz-adv-x="256" />
|
||||
<glyph unicode="▶" d="M170.667 373.334v-298.666l234.667 149.333z" />
|
||||
<glyph unicode="" d="M405.334 373.334v-298.666h-298.666v298.666h298.666zM405.334 416h-298.666c-23.573 0-42.666-19.094-42.666-42.666v-298.666c0-23.574 19.093-42.666 42.666-42.666h298.666c23.574 0 42.666 19.094 42.666 42.666v298.666c0 23.574-19.094 42.666-42.666 42.666z" />
|
||||
<glyph unicode="" d="M256 330.667c-58.88 0-106.666-47.787-106.666-106.667s47.786-106.666 106.666-106.666 106.666 47.786 106.666 106.666-47.786 106.666-106.666 106.666zM256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM256 53.334c-94.293 0-170.667 76.373-170.667 170.667s76.374 170.667 170.667 170.667 170.667-76.374 170.667-170.667-76.374-170.667-170.667-170.667z" />
|
||||
<glyph unicode="" d="M384 136.853c-16.214 0-30.827-6.293-41.92-16.426l-152 88.64c1.173 4.8 1.92 9.813 1.92 14.934s-0.746 10.133-1.92 14.934l150.4 87.786c11.413-10.666 26.666-17.28 43.52-17.28 35.307 0 64 28.693 64 64s-28.693 64-64 64-64-28.694-64-64c0-5.12 0.747-10.134 1.92-14.934l-150.4-87.786c-11.413 10.666-26.667 17.28-43.52 17.28-35.306 0-64-28.693-64-64s28.694-64 64-64c16.853 0 32.106 6.613 43.52 17.28l152-88.64c-1.067-4.48-1.707-9.173-1.707-13.974 0-34.346 27.84-62.187 62.187-62.187s62.187 27.84 62.187 62.187-27.84 62.187-62.187 62.187z" />
|
||||
<glyph unicode="" d="M149.333 181.334h-42.666v-106.666h106.666v42.666h-64v64zM106.666 266.667h42.666v64h64v42.666h-106.666v-106.666zM362.666 117.334h-64v-42.666h106.666v106.666h-42.666v-64zM298.666 373.334v-42.666h64v-64h42.666v106.666h-106.666z" />
|
||||
<glyph unicode="" d="M106.666 138.666h64v-64h42.666v106.666h-106.666v-42.666zM170.667 309.333h-64v-42.666h106.667v106.666h-42.666v-64zM298.666 74.666h42.666v64h64v42.666h-106.666v-106.666zM341.334 309.333v64h-42.666v-106.666h106.666v42.666h-64z" />
|
||||
<glyph unicode="" d="M376.534 344.534c-30.827 30.933-73.387 50.134-120.534 50.134-94.293 0-170.453-76.374-170.453-170.667s76.16-170.667 170.453-170.667c79.466 0 146.026 54.4 164.906 128h-44.373c-17.6-49.707-64.746-85.334-120.534-85.334-70.72 0-128 57.28-128 128s57.28 128 128 128c35.307 0 66.986-14.72 90.134-37.867l-68.8-68.8h149.334v149.333l-50.134-50.133z" />
|
||||
<glyph unicode="" d="M469.334 224c0-117.82-95.512-213.333-213.334-213.333s-213.333 95.512-213.333 213.333c0 117.821 95.513 213.333 213.333 213.333s213.333-95.512 213.333-213.333z" />
|
||||
<glyph unicode="" d="M256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333z" />
|
||||
<glyph unicode="" d="M256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM256 53.334c-94.080 0-170.667 76.587-170.667 170.667s76.587 170.667 170.667 170.667 170.667-76.587 170.667-170.667-76.587-170.667-170.667-170.667z" />
|
||||
<glyph unicode="" d="M448 416h-384c-23.573 0-42.666-19.094-42.666-42.666v-64h42.666v64h384v-298.666h-149.333v-42.666h149.333c23.574 0 42.666 19.094 42.666 42.666v298.666c0 23.574-19.094 42.666-42.666 42.666zM21.334 96v-64h64c0 35.307-28.694 64-64 64zM21.334 181.334v-42.666c58.88 0 106.666-47.786 106.666-106.666h42.666c0 82.454-66.88 149.334-149.333 149.334zM21.334 266.667v-42.667c106.026 0 192-85.974 192-192h42.666c0 129.6-105.067 234.667-234.667 234.667z" />
|
||||
<glyph unicode="" d="M426.666 394.666h-341.334c-23.573 0-42.666-19.094-42.666-42.666v-256c0-23.574 19.093-42.666 42.666-42.666h341.334c23.574 0 42.666 19.094 42.666 42.666v256c0 23.573-19.094 42.666-42.666 42.666zM85.334 224h85.334v-42.666h-85.334v42.666zM298.666 96h-213.333v42.666h213.333v-42.666zM426.666 96h-85.334v42.666h85.334v-42.666zM426.666 181.334h-213.333v42.666h213.333v-42.666z" />
|
||||
<glyph unicode="" d="M405.334 394.666h-298.666c-23.573 0-42.666-19.094-42.666-42.666v-256c0-23.574 19.093-42.666 42.666-42.666h298.666c23.574 0 42.666 19.094 42.666 42.666v256c0 23.573-19.094 42.666-42.666 42.666zM234.667 245.333h-32v10.667h-42.667v-64h42.666v10.666h32v-21.334c0-11.733-9.494-21.334-21.334-21.334h-64c-11.84 0-21.334 9.6-21.334 21.334v85.334c0 11.733 9.493 21.334 21.334 21.334h64c11.84 0 21.334-9.6 21.334-21.334v-21.334zM384 245.333h-32v10.667h-42.666v-64h42.666v10.666h32v-21.334c0-11.733-9.493-21.334-21.334-21.334h-64c-11.84 0-21.334 9.6-21.334 21.334v85.334c0 11.733 9.493 21.334 21.334 21.334h64c11.84 0 21.334-9.6 21.334-21.334v-21.334z" />
|
||||
<glyph unicode="" d="M85.334 96l181.333 128-181.333 128v-256zM277.334 352v-256l181.334 128-181.333 128z" />
|
||||
<glyph unicode="" d="M234.667 96v256l-181.333-128 181.333-128zM245.333 224l181.333-128v256l-181.333-128z" />
|
||||
<glyph unicode="" d="M405.334 394.666h-298.666c-23.573 0-42.666-19.094-42.666-42.666v-256c0-23.574 19.093-42.666 42.666-42.666h298.666c23.574 0 42.666 19.094 42.666 42.666v256c0 23.573-19.094 42.666-42.666 42.666zM234.667 160h-32v42.666h-42.667v-42.666h-32v128h32v-53.334h42.666v53.334h32v-128zM384 181.334c0-11.733-9.493-21.334-21.334-21.334h-16v-32h-32v32h-16c-11.84 0-21.334 9.6-21.334 21.334v85.334c0 11.733 9.493 21.334 21.334 21.334h64c11.84 0 21.334-9.6 21.334-21.334v-85.334zM309.334 192h42.666v64h-42.666v-64z" />
|
||||
<glyph unicode="" d="M128 74.666h85.334v298.666h-85.334v-298.666zM298.666 373.334v-298.666h85.334v298.666h-85.334z" />
|
||||
<glyph unicode="" d="M256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM234.667 138.666h-42.667v170.666h42.666v-170.666zM320 138.666h-42.666v170.666h42.666v-170.666z" />
|
||||
<glyph unicode="" d="M192 138.666h42.666v170.666h-42.666v-170.666zM256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM256 53.334c-94.080 0-170.667 76.587-170.667 170.667s76.587 170.667 170.667 170.667 170.667-76.587 170.667-170.667-76.587-170.667-170.667-170.667zM277.334 138.666h42.666v170.666h-42.666v-170.666z" />
|
||||
<glyph unicode="" d="M256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM213.333 128v192l128-96-128-96z" />
|
||||
<glyph unicode="" d="M213.333 128l128 96-128 96v-192zM256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM256 53.334c-94.080 0-170.667 76.587-170.667 170.667s76.587 170.667 170.667 170.667 170.667-76.587 170.667-170.667-76.587-170.667-170.667-170.667z" />
|
||||
<glyph unicode="" d="M128 96l181.333 128-181.333 128v-256zM341.334 352v-256h42.666v256h-42.666z" />
|
||||
<glyph unicode="" d="M128 352h42.666v-256h-42.666zM202.667 224l181.333-128v256z" />
|
||||
<glyph unicode="" d="M394.666 224c0 37.654-21.76 70.187-53.334 85.866v-171.84c31.574 15.786 53.334 48.32 53.334 85.974zM106.666 288v-128h85.334l106.666-106.666v341.334l-106.666-106.666h-85.334z" />
|
||||
<glyph unicode="" d="M149.333 288v-128h85.333l106.666-106.666v341.334l-106.666-106.666h-85.334z" />
|
||||
<glyph unicode="" d="M352 224c0 37.654-21.76 70.187-53.334 85.866v-47.146l52.373-52.374c0.64 4.48 0.96 9.067 0.96 13.654zM405.334 224c0-20.053-4.373-38.933-11.52-56.32l32.32-32.32c13.866 26.56 21.866 56.64 21.866 88.64 0 91.307-63.894 167.68-149.333 187.094v-44.053c61.654-18.347 106.666-75.413 106.666-143.040zM91.2 416l-27.2-27.2 100.8-100.8h-100.8v-128h85.334l106.666-106.666v143.466l90.774-90.774c-14.293-10.986-30.4-19.84-48.106-25.173v-44.053c29.334 6.72 56.106 20.16 78.613 38.613l43.52-43.413 27.2 27.2-356.8 356.8zM256 394.666l-44.587-44.587 44.587-44.587v89.173z" />
|
||||
<glyph unicode="" d="M64 288v-128h85.334l106.666-106.666v341.334l-106.666-106.666h-85.334zM352 224c0 37.654-21.76 70.187-53.334 85.866v-171.84c31.574 15.786 53.334 48.32 53.334 85.974zM298.666 411.094v-44.053c61.654-18.347 106.666-75.413 106.666-143.040s-45.014-124.693-106.666-143.040v-44.053c85.44 19.413 149.334 95.68 149.334 187.094s-63.894 167.68-149.333 187.094z" />
|
||||
<glyph unicode="" d="M256 352v-64l85.334 85.334-85.334 85.334v-64c-94.293 0-170.667-76.374-170.667-170.667 0-33.493 9.814-64.534 26.453-90.88l31.147 31.147c-9.494 17.813-14.933 38.080-14.933 59.733 0 70.72 57.28 128 128 128zM400.214 314.88l-31.147-31.147c9.493-17.814 14.933-38.080 14.933-59.733 0-70.72-57.28-128-128-128v64l-85.334-85.334 85.334-85.334v64c94.293 0 170.667 76.374 170.667 170.667 0 33.493-9.813 64.534-26.454 90.88z" />
|
||||
<glyph unicode="" d="M64 202.666h42.666v42.666h-42.666v-42.666zM64 117.334h42.666v42.666h-42.666v-42.666zM64 288h42.666v42.666h-42.666v-42.666zM149.333 202.666h298.667v42.666h-298.666v-42.666zM149.333 117.334h298.667v42.666h-298.666v-42.666zM149.333 330.667v-42.667h298.667v42.666h-298.666z" />
|
||||
<glyph unicode="" d="M414.507 203.2c0.853 6.827 1.493 13.76 1.493 20.8s-0.64 13.974-1.493 20.8l45.12 35.306c4.053 3.2 5.226 8.96 2.56 13.654l-42.666 73.92c-2.666 4.587-8.214 6.507-13.014 4.587l-53.12-21.44c-10.986 8.427-23.040 15.573-36.053 21.014l-8 56.533c-0.96 5.014-5.334 8.96-10.666 8.96h-85.334c-5.333 0-9.707-3.947-10.56-8.96l-8-56.533c-13.013-5.44-25.066-12.48-36.053-21.014l-53.12 21.44c-4.8 1.814-10.347 0-13.013-4.587l-42.666-73.92c-2.666-4.587-1.493-10.346 2.56-13.654l45.014-35.306c-0.853-6.827-1.493-13.76-1.493-20.8s0.64-13.974 1.493-20.8l-45.014-35.306c-4.053-3.2-5.227-8.96-2.56-13.654l42.666-73.92c2.666-4.587 8.213-6.507 13.013-4.587l53.12 21.44c10.987-8.426 23.040-15.574 36.053-21.014l8-56.534c0.853-5.014 5.226-8.96 10.56-8.96h85.334c5.334 0 9.707 3.947 10.56 8.96l8 56.534c13.014 5.44 25.067 12.48 36.053 21.014l53.12-21.44c4.8-1.813 10.346 0 13.014 4.587l42.666 73.92c2.666 4.587 1.493 10.346-2.56 13.654l-45.014 35.307zM256 149.334c-41.28 0-74.666 33.387-74.666 74.666s33.387 74.666 74.666 74.666 74.666-33.387 74.666-74.666-33.387-74.666-74.666-74.666z" />
|
||||
</font></defs></svg>
|
||||
|
Depois Largura: | Altura: | Tamanho: 10 KiB |
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("ar",{
|
||||
"Play": "تشغيل",
|
||||
"Pause": "ايقاف",
|
||||
"Current Time": "الوقت الحالي",
|
||||
"Duration Time": "Dauer",
|
||||
"Remaining Time": "الوقت المتبقي",
|
||||
"Stream Type": "نوع التيار",
|
||||
"LIVE": "مباشر",
|
||||
"Loaded": "تم التحميل",
|
||||
"Progress": "التقدم",
|
||||
"Fullscreen": "ملء الشاشة",
|
||||
"Non-Fullscreen": "غير ملء الشاشة",
|
||||
"Mute": "صامت",
|
||||
"Unmuted": "غير الصامت",
|
||||
"Playback Rate": "معدل التشغيل",
|
||||
"Subtitles": "الترجمة",
|
||||
"subtitles off": "ايقاف الترجمة",
|
||||
"Captions": "التعليقات",
|
||||
"captions off": "ايقاف التعليقات",
|
||||
"Chapters": "فصول",
|
||||
"You aborted the video playback": "لقد ألغيت تشغيل الفيديو",
|
||||
"A network error caused the video download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادم أو الشبكة ، أو فشل بسبب عدم امكانية قراءة تنسيق الفيديو.",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "تم ايقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
|
||||
"No compatible source was found for this video.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("ba",{
|
||||
"Play": "Pusti",
|
||||
"Pause": "Pauza",
|
||||
"Current Time": "Trenutno vrijeme",
|
||||
"Duration Time": "Vrijeme trajanja",
|
||||
"Remaining Time": "Preostalo vrijeme",
|
||||
"Stream Type": "Način strimovanja",
|
||||
"LIVE": "UŽIVO",
|
||||
"Loaded": "Učitan",
|
||||
"Progress": "Progres",
|
||||
"Fullscreen": "Puni ekran",
|
||||
"Non-Fullscreen": "Mali ekran",
|
||||
"Mute": "Prigušen",
|
||||
"Unmuted": "Ne-prigušen",
|
||||
"Playback Rate": "Stopa reprodukcije",
|
||||
"Subtitles": "Podnaslov",
|
||||
"subtitles off": "Podnaslov deaktiviran",
|
||||
"Captions": "Titlovi",
|
||||
"captions off": "Titlovi deaktivirani",
|
||||
"Chapters": "Poglavlja",
|
||||
"You aborted the video playback": "Isključili ste reprodukciju videa.",
|
||||
"A network error caused the video download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "Nije nađen nijedan kompatibilan izvor ovog videa."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("bg",{
|
||||
"Play": "Възпроизвеждане",
|
||||
"Pause": "Пауза",
|
||||
"Current Time": "Текущо време",
|
||||
"Duration Time": "Продължителност",
|
||||
"Remaining Time": "Оставащо време",
|
||||
"Stream Type": "Тип на потока",
|
||||
"LIVE": "НА ЖИВО",
|
||||
"Loaded": "Заредено",
|
||||
"Progress": "Прогрес",
|
||||
"Fullscreen": "Цял екран",
|
||||
"Non-Fullscreen": "Спиране на цял екран",
|
||||
"Mute": "Без звук",
|
||||
"Unmuted": "Със звук",
|
||||
"Playback Rate": "Скорост на възпроизвеждане",
|
||||
"Subtitles": "Субтитри",
|
||||
"subtitles off": "Спряни субтитри",
|
||||
"Captions": "Аудио надписи",
|
||||
"captions off": "Спряни аудио надписи",
|
||||
"Chapters": "Глави",
|
||||
"You aborted the video playback": "Спряхте възпроизвеждането на видеото",
|
||||
"A network error caused the video download to fail part-way.": "Грешка в мрежата провали изтеглянето на видеото.",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "Видеото не може да бъде заредено заради проблем със сървъра или мрежата или защото този формат не е поддържан.",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "Възпроизвеждането на видеото беше прекъснато заради проблем с файла или защото видеото използва опции които браузърът Ви не поддържа.",
|
||||
"No compatible source was found for this video.": "Не беше намерен съвместим източник за това видео."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("ca",{
|
||||
"Play": "Reproducció",
|
||||
"Pause": "Pausa",
|
||||
"Current Time": "Temps reproduït",
|
||||
"Duration Time": "Durada total",
|
||||
"Remaining Time": "Temps restant",
|
||||
"Stream Type": "Tipus de seqüència",
|
||||
"LIVE": "EN DIRECTE",
|
||||
"Loaded": "Carregat",
|
||||
"Progress": "Progrés",
|
||||
"Fullscreen": "Pantalla completa",
|
||||
"Non-Fullscreen": "Pantalla no completa",
|
||||
"Mute": "Silencia",
|
||||
"Unmuted": "Amb so",
|
||||
"Playback Rate": "Velocitat de reproducció",
|
||||
"Subtitles": "Subtítols",
|
||||
"subtitles off": "Subtítols desactivats",
|
||||
"Captions": "Llegendes",
|
||||
"captions off": "Llegendes desactivades",
|
||||
"Chapters": "Capítols",
|
||||
"You aborted the video playback": "Heu interromput la reproducció del vídeo.",
|
||||
"A network error caused the video download to fail part-way.": "Un error de la xarxa ha interromput la baixada del vídeo.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "No s'ha trobat cap font compatible amb el vídeo."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("cs",{
|
||||
"Play": "Přehrát",
|
||||
"Pause": "Pauza",
|
||||
"Current Time": "Aktuální čas",
|
||||
"Duration Time": "Doba trvání",
|
||||
"Remaining Time": "Zbývající čas",
|
||||
"Stream Type": "Stream Type",
|
||||
"LIVE": "ŽIVĚ",
|
||||
"Loaded": "Načteno",
|
||||
"Progress": "Stav",
|
||||
"Fullscreen": "Celá obrazovka",
|
||||
"Non-Fullscreen": "Zmenšená obrazovka",
|
||||
"Mute": "Ztlumit zvuk",
|
||||
"Unmuted": "Přehrát zvuk",
|
||||
"Playback Rate": "Rychlost přehrávání",
|
||||
"Subtitles": "Titulky",
|
||||
"subtitles off": "Titulky vypnuty",
|
||||
"Captions": "Popisky",
|
||||
"captions off": "Popisky vypnuty",
|
||||
"Chapters": "Kapitoly",
|
||||
"You aborted the video playback": "Přehrávání videa je přerušeno.",
|
||||
"A network error caused the video download to fail part-way.": "Video nemohlo být načteno, kvůli chybě v síti.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "Váš prohlížeč nepodporuje formát videa.",
|
||||
"No compatible source was found for this video.": "Špatně zadaný zdroj videa."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("da",{
|
||||
"Play": "Afspil",
|
||||
"Pause": "Pause",
|
||||
"Current Time": "Aktuel tid",
|
||||
"Duration Time": "Varighed",
|
||||
"Remaining Time": "Resterende tid",
|
||||
"Stream Type": "Stream-type",
|
||||
"LIVE": "LIVE",
|
||||
"Loaded": "Indlæst",
|
||||
"Progress": "Status",
|
||||
"Fullscreen": "Fuldskærm",
|
||||
"Non-Fullscreen": "Luk fuldskærm",
|
||||
"Mute": "Uden lyd",
|
||||
"Unmuted": "Med lyd",
|
||||
"Playback Rate": "Afspilningsrate",
|
||||
"Subtitles": "Undertekster",
|
||||
"subtitles off": "Uden undertekster",
|
||||
"Captions": "Undertekster for hørehæmmede",
|
||||
"captions off": "Uden undertekster for hørehæmmede",
|
||||
"Chapters": "Kapitler",
|
||||
"You aborted the video playback": "Du afbrød videoafspilningen.",
|
||||
"A network error caused the video download to fail part-way.": "En netværksfejl fik download af videoen til at fejle.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "Fandt ikke en kompatibel kilde for denne video."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("de",{
|
||||
"Play": "Wiedergabe",
|
||||
"Pause": "Pause",
|
||||
"Current Time": "Aktueller Zeitpunkt",
|
||||
"Duration Time": "Dauer",
|
||||
"Remaining Time": "Verbleibende Zeit",
|
||||
"Stream Type": "Streamtyp",
|
||||
"LIVE": "LIVE",
|
||||
"Loaded": "Geladen",
|
||||
"Progress": "Status",
|
||||
"Fullscreen": "Vollbild",
|
||||
"Non-Fullscreen": "Kein Vollbild",
|
||||
"Mute": "Ton aus",
|
||||
"Unmuted": "Ton ein",
|
||||
"Playback Rate": "Wiedergabegeschwindigkeit",
|
||||
"Subtitles": "Untertitel",
|
||||
"subtitles off": "Untertitel aus",
|
||||
"Captions": "Untertitel",
|
||||
"captions off": "Untertitel aus",
|
||||
"Chapters": "Kapitel",
|
||||
"You aborted the video playback": "Sie haben die Videowiedergabe abgebrochen.",
|
||||
"A network error caused the video download to fail part-way.": "Der Videodownload ist aufgrund eines Netzwerkfehlers fehlgeschlagen.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "Für dieses Video wurde keine kompatible Quelle gefunden."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("es",{
|
||||
"Play": "Reproducción",
|
||||
"Pause": "Pausa",
|
||||
"Current Time": "Tiempo reproducido",
|
||||
"Duration Time": "Duración total",
|
||||
"Remaining Time": "Tiempo restante",
|
||||
"Stream Type": "Tipo de secuencia",
|
||||
"LIVE": "DIRECTO",
|
||||
"Loaded": "Cargado",
|
||||
"Progress": "Progreso",
|
||||
"Fullscreen": "Pantalla completa",
|
||||
"Non-Fullscreen": "Pantalla no completa",
|
||||
"Mute": "Silenciar",
|
||||
"Unmuted": "No silenciado",
|
||||
"Playback Rate": "Velocidad de reproducción",
|
||||
"Subtitles": "Subtítulos",
|
||||
"subtitles off": "Subtítulos desactivados",
|
||||
"Captions": "Subtítulos especiales",
|
||||
"captions off": "Subtítulos especiales desactivados",
|
||||
"Chapters": "Capítulos",
|
||||
"You aborted the video playback": "Ha interrumpido la reproducción del vídeo.",
|
||||
"A network error caused the video download to fail part-way.": "Un error de red ha interrumpido la descarga del vídeo.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "No se ha encontrado ninguna fuente compatible con este vídeo."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("fr",{
|
||||
"Play": "Lecture",
|
||||
"Pause": "Pause",
|
||||
"Current Time": "Temps actuel",
|
||||
"Duration Time": "Durée",
|
||||
"Remaining Time": "Temps restant",
|
||||
"Stream Type": "Type de flux",
|
||||
"LIVE": "EN DIRECT",
|
||||
"Loaded": "Chargé",
|
||||
"Progress": "Progression",
|
||||
"Fullscreen": "Plein écran",
|
||||
"Non-Fullscreen": "Fenêtré",
|
||||
"Mute": "Sourdine",
|
||||
"Unmuted": "Son activé",
|
||||
"Playback Rate": "Vitesse de lecture",
|
||||
"Subtitles": "Sous-titres",
|
||||
"subtitles off": "Sous-titres désactivés",
|
||||
"Captions": "Sous-titres",
|
||||
"captions off": "Sous-titres désactivés",
|
||||
"Chapters": "Chapitres",
|
||||
"You aborted the video playback": "Vous avez interrompu la lecture de la vidéo.",
|
||||
"A network error caused the video download to fail part-way.": "Une erreur de réseau a interrompu le téléchargement de la vidéo.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "Aucune source compatible n'a été trouvée pour cette vidéo."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("hr",{
|
||||
"Play": "Pusti",
|
||||
"Pause": "Pauza",
|
||||
"Current Time": "Trenutno vrijeme",
|
||||
"Duration Time": "Vrijeme trajanja",
|
||||
"Remaining Time": "Preostalo vrijeme",
|
||||
"Stream Type": "Način strimovanja",
|
||||
"LIVE": "UŽIVO",
|
||||
"Loaded": "Učitan",
|
||||
"Progress": "Progres",
|
||||
"Fullscreen": "Puni ekran",
|
||||
"Non-Fullscreen": "Mali ekran",
|
||||
"Mute": "Prigušen",
|
||||
"Unmuted": "Ne-prigušen",
|
||||
"Playback Rate": "Stopa reprodukcije",
|
||||
"Subtitles": "Podnaslov",
|
||||
"subtitles off": "Podnaslov deaktiviran",
|
||||
"Captions": "Titlovi",
|
||||
"captions off": "Titlovi deaktivirani",
|
||||
"Chapters": "Poglavlja",
|
||||
"You aborted the video playback": "Isključili ste reprodukciju videa.",
|
||||
"A network error caused the video download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "Nije nađen nijedan kompatibilan izvor ovog videa."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("hu",{
|
||||
"Play": "Lejátszás",
|
||||
"Pause": "Szünet",
|
||||
"Current Time": "Aktuális időpont",
|
||||
"Duration Time": "Hossz",
|
||||
"Remaining Time": "Hátralévő idő",
|
||||
"Stream Type": "Adatfolyam típusa",
|
||||
"LIVE": "ÉLŐ",
|
||||
"Loaded": "Betöltve",
|
||||
"Progress": "Állapot",
|
||||
"Fullscreen": "Teljes képernyő",
|
||||
"Non-Fullscreen": "Normál méret",
|
||||
"Mute": "Némítás",
|
||||
"Unmuted": "Némítás kikapcsolva",
|
||||
"Playback Rate": "Lejátszási sebesség",
|
||||
"Subtitles": "Feliratok",
|
||||
"subtitles off": "Feliratok kikapcsolva",
|
||||
"Captions": "Magyarázó szöveg",
|
||||
"captions off": "Magyarázó szöveg kikapcsolva",
|
||||
"Chapters": "Fejezetek",
|
||||
"You aborted the video playback": "Leállította a lejátszást",
|
||||
"A network error caused the video download to fail part-way.": "Hálózati hiba miatt a videó részlegesen töltődött le.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "Nincs kompatibilis forrás ehhez a videóhoz."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("it",{
|
||||
"Play": "Play",
|
||||
"Pause": "Pausa",
|
||||
"Current Time": "Orario attuale",
|
||||
"Duration Time": "Durata",
|
||||
"Remaining Time": "Tempo rimanente",
|
||||
"Stream Type": "Tipo del Streaming",
|
||||
"LIVE": "LIVE",
|
||||
"Loaded": "Caricato",
|
||||
"Progress": "Stato",
|
||||
"Fullscreen": "Schermo intero",
|
||||
"Non-Fullscreen": "Chiudi schermo intero",
|
||||
"Mute": "Muto",
|
||||
"Unmuted": "Audio",
|
||||
"Playback Rate": "Tasso di riproduzione",
|
||||
"Subtitles": "Sottotitoli",
|
||||
"subtitles off": "Senza sottotitoli",
|
||||
"Captions": "Sottotitoli non udenti",
|
||||
"captions off": "Senza sottotitoli non udenti",
|
||||
"Chapters": "Capitolo",
|
||||
"You aborted the video playback": "La riproduzione del filmato è stata interrotta.",
|
||||
"A network error caused the video download to fail part-way.": "Il download del filmato è stato interrotto a causa di un problema rete.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "La riproduzione del filmato è stata interrotta a causa di un file danneggiato o per l’utilizzo di impostazioni non supportate dal browser.",
|
||||
"No compatible source was found for this video.": "Non ci sono fonti compatibili per questo filmato."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("ja",{
|
||||
"Play": "再生",
|
||||
"Pause": "一時停止",
|
||||
"Current Time": "現在の時間",
|
||||
"Duration Time": "長さ",
|
||||
"Remaining Time": "残りの時間",
|
||||
"Stream Type": "ストリームの種類",
|
||||
"LIVE": "ライブ",
|
||||
"Loaded": "ロード済み",
|
||||
"Progress": "進行状況",
|
||||
"Fullscreen": "フルスクリーン",
|
||||
"Non-Fullscreen": "フルスクリーン以外",
|
||||
"Mute": "ミュート",
|
||||
"Unmuted": "ミュート解除",
|
||||
"Playback Rate": "再生レート",
|
||||
"Subtitles": "サブタイトル",
|
||||
"subtitles off": "サブタイトル オフ",
|
||||
"Captions": "キャプション",
|
||||
"captions off": "キャプション オフ",
|
||||
"Chapters": "チャプター",
|
||||
"You aborted the video playback": "動画再生を中止しました",
|
||||
"A network error caused the video download to fail part-way.": "ネットワーク エラーにより動画のダウンロードが途中で失敗しました",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "サーバーまたはネットワークのエラー、またはフォーマットがサポートされていないため、動画をロードできませんでした",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "破損の問題、またはお使いのブラウザがサポートしていない機能が動画に使用されていたため、動画の再生が中止されました",
|
||||
"No compatible source was found for this video.": "この動画に対して互換性のあるソースが見つかりませんでした"
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("ko",{
|
||||
"Play": "재생",
|
||||
"Pause": "일시중지",
|
||||
"Current Time": "현재 시간",
|
||||
"Duration Time": "지정 기간",
|
||||
"Remaining Time": "남은 시간",
|
||||
"Stream Type": "스트리밍 유형",
|
||||
"LIVE": "라이브",
|
||||
"Loaded": "로드됨",
|
||||
"Progress": "진행",
|
||||
"Fullscreen": "전체 화면",
|
||||
"Non-Fullscreen": "전체 화면 해제",
|
||||
"Mute": "음소거",
|
||||
"Unmuted": "음소거 해제",
|
||||
"Playback Rate": "재생 비율",
|
||||
"Subtitles": "서브타이틀",
|
||||
"subtitles off": "서브타이틀 끄기",
|
||||
"Captions": "자막",
|
||||
"captions off": "자막 끄기",
|
||||
"Chapters": "챕터",
|
||||
"You aborted the video playback": "비디오 재생을 취소했습니다.",
|
||||
"A network error caused the video download to fail part-way.": "네트워크 오류로 인하여 비디오 일부를 다운로드하지 못 했습니다.",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "비디오를 로드할 수 없습니다. 서버 혹은 네트워크 오류 때문이거나 지원되지 않는 형식 때문일 수 있습니다.",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "비디오 재생이 취소됐습니다. 비디오가 손상되었거나 비디오가 사용하는 기능을 브라우저에서 지원하지 않는 것 같습니다.",
|
||||
"No compatible source was found for this video.": "비디오에 호환되지 않는 소스가 있습니다."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("nl",{
|
||||
"Play": "Afspelen",
|
||||
"Pause": "Pauze",
|
||||
"Current Time": "Huidige Tijd",
|
||||
"Duration Time": "Looptijd",
|
||||
"Remaining Time": "Resterende Tijd",
|
||||
"Stream Type": "Stream Type",
|
||||
"LIVE": "LIVE",
|
||||
"Loaded": "Geladen",
|
||||
"Progress": "Status",
|
||||
"Fullscreen": "Volledig scherm",
|
||||
"Non-Fullscreen": "Geen volledig scherm",
|
||||
"Mute": "Geluid Uit",
|
||||
"Unmuted": "Geluid Aan",
|
||||
"Playback Rate": "Weergave Rate",
|
||||
"Subtitles": "Ondertiteling",
|
||||
"subtitles off": "Ondertiteling uit",
|
||||
"Captions": "Onderschriften",
|
||||
"captions off": "Onderschriften uit",
|
||||
"Chapters": "Hoofdstukken",
|
||||
"You aborted the video playback": "Je hebt de video weergave afgebroken.",
|
||||
"A network error caused the video download to fail part-way.": "De video download is mislukt door een netwerkfout.",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "De video kon niet worden geladen, veroorzaakt door een server of netwerkfout of het formaat word niet ondersteund.",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "De video weergave is afgebroken omdat deze beschadigd is of de video gebruikt functionaliteit die niet door je browser word ondersteund.",
|
||||
"No compatible source was found for this video.": "Voor deze video is geen ondersteunde bron gevonden."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("pt-BR",{
|
||||
"Play": "Tocar",
|
||||
"Pause": "Pause",
|
||||
"Current Time": "Tempo",
|
||||
"Duration Time": "Duração",
|
||||
"Remaining Time": "Tempo Restante",
|
||||
"Stream Type": "Tipo de Stream",
|
||||
"LIVE": "AO VIVO",
|
||||
"Loaded": "Carregado",
|
||||
"Progress": "Progresso",
|
||||
"Fullscreen": "Tela Cheia",
|
||||
"Non-Fullscreen": "Tela Normal",
|
||||
"Mute": "Mudo",
|
||||
"Unmuted": "Habilitar Som",
|
||||
"Playback Rate": "Velocidade",
|
||||
"Subtitles": "Legendas",
|
||||
"subtitles off": "Sem Legendas",
|
||||
"Captions": "Anotações",
|
||||
"captions off": "Sem Anotações",
|
||||
"Chapters": "Capítulos",
|
||||
"You aborted the video playback": "Você parou a execução de vídeo.",
|
||||
"A network error caused the video download to fail part-way.": "Um erro na rede fez o vídeo parar parcialmente.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "Não foi encontrada fonte de vídeo compatível."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("ru",{
|
||||
"Play": "Воспроизвести",
|
||||
"Pause": "Приостановить",
|
||||
"Current Time": "Текущее время",
|
||||
"Duration Time": "Продолжительность",
|
||||
"Remaining Time": "Оставшееся время",
|
||||
"Stream Type": "Тип потока",
|
||||
"LIVE": "ОНЛАЙН",
|
||||
"Loaded": "Загрузка",
|
||||
"Progress": "Прогресс",
|
||||
"Fullscreen": "Полноэкранный режим",
|
||||
"Non-Fullscreen": "Неполноэкранный режим",
|
||||
"Mute": "Без звука",
|
||||
"Unmuted": "Со звуком",
|
||||
"Playback Rate": "Скорость воспроизведения",
|
||||
"Subtitles": "Субтитры",
|
||||
"subtitles off": "Субтитры выкл.",
|
||||
"Captions": "Подписи",
|
||||
"captions off": "Подписи выкл.",
|
||||
"Chapters": "Главы",
|
||||
"You aborted the video playback": "Вы прервали воспроизведение видео",
|
||||
"A network error caused the video download to fail part-way.": "Ошибка сети вызвала сбой во время загрузки видео.",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "Невозможно загрузить видео из-за сетевого или серверного сбоя либо формат не поддерживается.",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "Воспроизведение видео было приостановлено из-за повреждения либо в связи с тем, что видео использует функции, неподдерживаемые вашим браузером.",
|
||||
"No compatible source was found for this video.": "Совместимые источники для этого видео отсутствуют."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("sr",{
|
||||
"Play": "Pusti",
|
||||
"Pause": "Pauza",
|
||||
"Current Time": "Trenutno vrijeme",
|
||||
"Duration Time": "Vrijeme trajanja",
|
||||
"Remaining Time": "Preostalo vrijeme",
|
||||
"Stream Type": "Način strimovanja",
|
||||
"LIVE": "UŽIVO",
|
||||
"Loaded": "Učitan",
|
||||
"Progress": "Progres",
|
||||
"Fullscreen": "Puni ekran",
|
||||
"Non-Fullscreen": "Mali ekran",
|
||||
"Mute": "Prigušen",
|
||||
"Unmuted": "Ne-prigušen",
|
||||
"Playback Rate": "Stopa reprodukcije",
|
||||
"Subtitles": "Podnaslov",
|
||||
"subtitles off": "Podnaslov deaktiviran",
|
||||
"Captions": "Titlovi",
|
||||
"captions off": "Titlovi deaktivirani",
|
||||
"Chapters": "Poglavlja",
|
||||
"You aborted the video playback": "Isključili ste reprodukciju videa.",
|
||||
"A network error caused the video download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video 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 video.": "Nije nađen nijedan kompatibilan izvor ovog videa."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("tr",{
|
||||
"Play": "Oynat",
|
||||
"Pause": "Duraklat",
|
||||
"Current Time": "Süre",
|
||||
"Duration Time": "Toplam Süre",
|
||||
"Remaining Time": "Kalan Süre",
|
||||
"Stream Type": "Yayın Tipi",
|
||||
"LIVE": "CANLI",
|
||||
"Loaded": "Yüklendi",
|
||||
"Progress": "Yükleniyor",
|
||||
"Fullscreen": "Tam Ekran",
|
||||
"Non-Fullscreen": "Küçük Ekran",
|
||||
"Mute": "Ses Kapa",
|
||||
"Unmuted": "Ses Aç",
|
||||
"Playback Rate": "Oynatma Hızı",
|
||||
"Subtitles": "Altyazı",
|
||||
"subtitles off": "Altyazı Kapat",
|
||||
"Captions": "Ek Açıklamalar",
|
||||
"captions off": "Ek Açıklamalar Kapalı",
|
||||
"Chapters": "Bölümler",
|
||||
"You aborted the video playback": "Video oynatmayı iptal ettiniz",
|
||||
"A network error caused the video download to fail part-way.": "Video indirilirken bağlantı sorunu oluştu.",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "Video oynatılamadı, Ağ yada sunucu hattası veya belirtilen format desteklenmiyor.",
|
||||
"The video playback was aborted due to a corruption problem or because the video 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 video.": "Video için kaynak bulunamadı."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("uk",{
|
||||
"Play": "Відтворити",
|
||||
"Pause": "Призупинити",
|
||||
"Current Time": "Поточний час",
|
||||
"Duration Time": "Тривалість",
|
||||
"Remaining Time": "Час, що залишився",
|
||||
"Stream Type": "Тип потоку",
|
||||
"LIVE": "НАЖИВО",
|
||||
"Loaded": "Завантаження",
|
||||
"Progress": "Прогрес",
|
||||
"Fullscreen": "Повноекранний режим",
|
||||
"Non-Fullscreen": "Неповноекранний режим",
|
||||
"Mute": "Без звуку",
|
||||
"Unmuted": "Зі звуком",
|
||||
"Playback Rate": "Швидкість відтворення",
|
||||
"Subtitles": "Субтитри",
|
||||
"subtitles off": "Без субтитрів",
|
||||
"Captions": "Підписи",
|
||||
"captions off": "Без підписів",
|
||||
"Chapters": "Розділи",
|
||||
"You aborted the video playback": "Ви припинили відтворення відео",
|
||||
"A network error caused the video download to fail part-way.": "Помилка мережі викликала збій під час завантаження відео.",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "Неможливо завантажити відео через мережевий чи серверний збій або формат не підтримується.",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "Відтворення відео було припинено через пошкодження або у зв'язку з тим, що відео використовує функції, які не підтримуються вашим браузером.",
|
||||
"No compatible source was found for this video.": "Сумісні джерела для цього відео відсутні."
|
||||
});
|
||||
externo
+26
@@ -0,0 +1,26 @@
|
||||
videojs.addLanguage("vi",{
|
||||
"Play": "Phát",
|
||||
"Pause": "Tạm dừng",
|
||||
"Current Time": "Thời gian hiện tại",
|
||||
"Duration Time": "Độ dài",
|
||||
"Remaining Time": "Thời gian còn lại",
|
||||
"Stream Type": "Kiểu Stream",
|
||||
"LIVE": "TRỰC TIẾP",
|
||||
"Loaded": "Đã tải",
|
||||
"Progress": "Tiến trình",
|
||||
"Fullscreen": "Toàn màn hình",
|
||||
"Non-Fullscreen": "Thoát toàn màn hình",
|
||||
"Mute": "Tắt tiếng",
|
||||
"Unmuted": "Bật âm thanh",
|
||||
"Playback Rate": "Tốc độ phát",
|
||||
"Subtitles": "Phụ đề",
|
||||
"subtitles off": "Tắt phụ đề",
|
||||
"Captions": "Chú thích",
|
||||
"captions off": "Tắt chú thích",
|
||||
"Chapters": "Chương",
|
||||
"You aborted the video playback": "Bạn đã hủy việc phát video.",
|
||||
"A network error caused the video download to fail part-way.": "Một lỗi mạng dẫn đến việc tải video bị lỗi.",
|
||||
"The video 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 video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "Phát video đã bị hủy do một sai lỗi hoặc video sử dụng những tính năng trình duyệt không hỗ trợ.",
|
||||
"No compatible source was found for this video.": "Không có nguồn tương thích cho video này."
|
||||
});
|
||||
externo
+27
@@ -0,0 +1,27 @@
|
||||
videojs.addLanguage("zh-CN",{
|
||||
"Play": "播放",
|
||||
"Pause": "暂停",
|
||||
"Current Time": "当前时间",
|
||||
"Duration Time": "时长",
|
||||
"Remaining Time": "剩余时间",
|
||||
"Stream Type": "媒体流类型",
|
||||
"LIVE": "直播",
|
||||
"Loaded": "加载完毕",
|
||||
"Progress": "进度",
|
||||
"Fullscreen": "全屏",
|
||||
"Non-Fullscreen": "退出全屏",
|
||||
"Mute": "静音",
|
||||
"Unmuted": "取消静音",
|
||||
"Playback Rate": "播放码率",
|
||||
"Subtitles": "字幕",
|
||||
"subtitles off": "字幕关闭",
|
||||
"Captions": "内嵌字幕",
|
||||
"captions off": "内嵌字幕关闭",
|
||||
"Chapters": "节目段落",
|
||||
"You aborted the video playback": "视频播放被终止",
|
||||
"A network error caused the video download to fail part-way.": "网络错误导致视频下载中途失败。",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "视频因格式不支持或者服务器或网络的问题无法加载。",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "由于视频文件损坏或是该视频使用了你的浏览器不支持的功能,播放终止。",
|
||||
"No compatible source was found for this video.": "无法找到此视频兼容的源。",
|
||||
"The video is encrypted and we do not have the keys to decrypt it.": "视频已加密,无法解密。"
|
||||
});
|
||||
externo
+27
@@ -0,0 +1,27 @@
|
||||
videojs.addLanguage("zh-TW",{
|
||||
"Play": "播放",
|
||||
"Pause": "暫停",
|
||||
"Current Time": "目前時間",
|
||||
"Duration Time": "總共時間",
|
||||
"Remaining Time": "剩餘時間",
|
||||
"Stream Type": "串流類型",
|
||||
"LIVE": "直播",
|
||||
"Loaded": "載入完畢",
|
||||
"Progress": "進度",
|
||||
"Fullscreen": "全螢幕",
|
||||
"Non-Fullscreen": "退出全螢幕",
|
||||
"Mute": "靜音",
|
||||
"Unmuted": "取消靜音",
|
||||
"Playback Rate": " 播放速率",
|
||||
"Subtitles": "字幕",
|
||||
"subtitles off": "關閉字幕",
|
||||
"Captions": "內嵌字幕",
|
||||
"captions off": "關閉內嵌字幕",
|
||||
"Chapters": "章節",
|
||||
"You aborted the video playback": "影片播放已終止",
|
||||
"A network error caused the video download to fail part-way.": "網路錯誤導致影片下載失敗。",
|
||||
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "影片因格式不支援或者伺服器或網路的問題無法載入。",
|
||||
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "由於影片檔案損毀或是該影片使用了您的瀏覽器不支援的功能,播放終止。",
|
||||
"No compatible source was found for this video.": "無法找到相容此影片的來源。",
|
||||
"The video is encrypted and we do not have the keys to decrypt it.": "影片已加密,無法解密。"
|
||||
});
|
||||
externo
+10317
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
BIN
Arquivo binário não exibido.
externo
+943
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
BIN
Arquivo binário não exibido.
externo
+15364
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+157
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+22
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "video.js",
|
||||
"description": "An HTML5 and Flash video player with a common API and skin for both.",
|
||||
"version": "5.0.0-9",
|
||||
"version": "5.0.0-13",
|
||||
"copyright": "Copyright Brightcove, Inc. <https://www.brightcove.com/>",
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
|
||||
<!-- Set the location of the flash SWF -->
|
||||
<script>
|
||||
videojs.options.flash.swf = '../build/temp/video-js.swf';
|
||||
videojs.setGlobalOptions({
|
||||
flash: {
|
||||
swf: '../build/temp/video-js.swf'
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ class Button extends Component {
|
||||
// KeyPress (document level) - Trigger click when keys are pressed
|
||||
handleKeyPress(event) {
|
||||
// Check for space bar (32) or enter (13) keys
|
||||
if (event.which == 32 || event.which == 13) {
|
||||
if (event.which === 32 || event.which === 13) {
|
||||
event.preventDefault();
|
||||
this.handleClick();
|
||||
}
|
||||
|
||||
@@ -59,8 +59,7 @@ class Component {
|
||||
// If there was no ID from the options, generate one
|
||||
if (!this.id_) {
|
||||
// Don't require the player ID function in the case of mock players
|
||||
let id = player.id && player.id() || 'no_player';
|
||||
|
||||
let id = player && player.id && player.id() || 'no_player';
|
||||
this.id_ = `${id}_component_${Lib.guid++}`;
|
||||
}
|
||||
|
||||
@@ -1033,7 +1032,7 @@ class Component {
|
||||
*/
|
||||
enableTouchActivity() {
|
||||
// Don't continue if the root player doesn't support reporting user activity
|
||||
if (!this.player().reportUserActivity) {
|
||||
if (!this.player() || !this.player().reportUserActivity) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class PlaybackRateMenuItem extends MenuItem {
|
||||
}
|
||||
|
||||
update() {
|
||||
this.selected(this.player().playbackRate() == this.rate);
|
||||
this.selected(this.player().playbackRate() === this.rate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class LoadProgressBar extends Component {
|
||||
// get the percent width of a time compared to the total end
|
||||
let percentify = function (time, end){
|
||||
let percent = (time / end) || 0; // no NaN
|
||||
return (percent * 100) + '%';
|
||||
return ((percent >= 1 ? 1 : percent) * 100) + '%';
|
||||
};
|
||||
|
||||
// update the width of the progress bar
|
||||
|
||||
@@ -34,7 +34,8 @@ class SeekBar extends Slider {
|
||||
}
|
||||
|
||||
getPercent() {
|
||||
return this.player_.currentTime() / this.player_.duration();
|
||||
let percent = this.player_.currentTime() / this.player_.duration();
|
||||
return percent >= 1 ? 1 : percent;
|
||||
}
|
||||
|
||||
handleMouseDown(event) {
|
||||
@@ -50,7 +51,7 @@ class SeekBar extends Slider {
|
||||
let newTime = this.calculateDistance(event) * this.player_.duration();
|
||||
|
||||
// Don't let video end while scrubbing.
|
||||
if (newTime == this.player_.duration()) { newTime = newTime - 0.1; }
|
||||
if (newTime === this.player_.duration()) { newTime = newTime - 0.1; }
|
||||
|
||||
// Set new time (tell player to seek to new time)
|
||||
this.player_.currentTime(newTime);
|
||||
|
||||
@@ -48,7 +48,7 @@ class ChaptersButton extends TextTrackButton {
|
||||
|
||||
for (let i = 0, l = tracks.length; i < l; i++) {
|
||||
let track = tracks[i];
|
||||
if (track['kind'] == this.kind_) {
|
||||
if (track['kind'] === this.kind_) {
|
||||
if (!track.cues) {
|
||||
track['mode'] = 'hidden';
|
||||
/* jshint loopfunc:true */
|
||||
|
||||
@@ -62,4 +62,4 @@ class TextTrackButton extends MenuButton {
|
||||
}
|
||||
|
||||
MenuButton.registerComponent('TextTrackButton', TextTrackButton);
|
||||
export default TextTrackButton;
|
||||
export default TextTrackButton;
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ var videojs = function(id, options, ready){
|
||||
|
||||
// CDN Version. Used to target right flash swf.
|
||||
videojs.CDN_VERSION = '__VERSION_NO_PATCH__';
|
||||
videojs.ACCESS_PROTOCOL = ('https:' == document.location.protocol ? 'https://' : 'http://');
|
||||
videojs.ACCESS_PROTOCOL = ('https:' === document.location.protocol ? 'https://' : 'http://');
|
||||
|
||||
/**
|
||||
* Full player version
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@ var on = function(elem, type, fn){
|
||||
};
|
||||
}
|
||||
|
||||
if (data.handlers[type].length == 1) {
|
||||
if (data.handlers[type].length === 1) {
|
||||
if (elem.addEventListener) {
|
||||
elem.addEventListener(type, data.dispatcher, false);
|
||||
} else if (elem.attachEvent) {
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ var createEl = function(tagName='div', properties={}){
|
||||
// add the attribute "role". My guess is because it's not a valid attribute in some namespaces, although
|
||||
// browsers handle the attribute just fine. The W3C allows for aria-* attributes to be used in pre-HTML5 docs.
|
||||
// http://www.w3.org/TR/wai-aria-primer/#ariahtml. Using setAttribute gets around this problem.
|
||||
if (propName.indexOf('aria-') !== -1 || propName == 'role') {
|
||||
if (propName.indexOf('aria-') !== -1 || propName === 'role') {
|
||||
el.setAttribute(propName, val);
|
||||
} else {
|
||||
el[propName] = val;
|
||||
@@ -616,10 +616,10 @@ var setLocalStorage = function(key, value){
|
||||
if (!localStorage) { return; }
|
||||
localStorage[key] = value;
|
||||
} catch(e) {
|
||||
if (e.code == 22 || e.code == 1014) { // Webkit == 22 / Firefox == 1014
|
||||
if (e.code === 22 || e.code === 1014) { // Webkit == 22 / Firefox == 1014
|
||||
log('LocalStorage Full (VideoJS)', e);
|
||||
} else {
|
||||
if (e.code == 18) {
|
||||
if (e.code === 18) {
|
||||
log('LocalStorage not allowed (VideoJS)', e);
|
||||
} else {
|
||||
log('LocalStorage Error (VideoJS)', e);
|
||||
|
||||
@@ -105,7 +105,7 @@ class MenuButton extends Button {
|
||||
handleKeyPress(event) {
|
||||
|
||||
// Check for space bar (32) or enter (13) keys
|
||||
if (event.which == 32 || event.which == 13) {
|
||||
if (event.which === 32 || event.which === 13) {
|
||||
if (this.buttonPressed_){
|
||||
this.unpressButton();
|
||||
} else {
|
||||
@@ -113,7 +113,7 @@ class MenuButton extends Button {
|
||||
}
|
||||
event.preventDefault();
|
||||
// Check for escape (27) key
|
||||
} else if (event.which == 27){
|
||||
} else if (event.which === 27){
|
||||
if (this.buttonPressed_){
|
||||
this.unpressButton();
|
||||
}
|
||||
|
||||
+345
-42
@@ -162,6 +162,9 @@ class Player extends Component {
|
||||
this.userActive_ = true;
|
||||
this.reportUserActivity();
|
||||
this.listenForUserActivity();
|
||||
|
||||
this.on('fullscreenchange', this.handleFullscreenChange);
|
||||
this.on('stageclick', this.handleStageClick);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,7 +204,7 @@ class Player extends Component {
|
||||
Lib.obj.each(attrs, function(attr) {
|
||||
// workaround so we don't totally break IE7
|
||||
// http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
|
||||
if (attr == 'class') {
|
||||
if (attr === 'class') {
|
||||
el.className = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
@@ -234,25 +237,7 @@ class Player extends Component {
|
||||
}
|
||||
Lib.insertFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup.
|
||||
|
||||
// The event listeners need to be added before the children are added
|
||||
// in the component init because the tech (loaded with mediaLoader) may
|
||||
// fire events, like loadstart, that these events need to capture.
|
||||
// Long term it might be better to expose a way to do this in component.init
|
||||
// like component.initEventListeners() that runs between el creation and
|
||||
// adding children
|
||||
this.el_ = el;
|
||||
this.on('loadstart', this.handleLoadStart);
|
||||
this.on('waiting', this.handleWaiting);
|
||||
this.on(['canplay', 'canplaythrough', 'playing', 'ended'], this.handleWaitEnd);
|
||||
this.on('seeking', this.handleSeeking);
|
||||
this.on('seeked', this.handleSeeked);
|
||||
this.on('ended', this.handleEnded);
|
||||
this.on('play', this.handlePlay);
|
||||
this.on('firstplay', this.handleFirstPlay);
|
||||
this.on('pause', this.handlePause);
|
||||
this.on('progress', this.handleProgress);
|
||||
this.on('durationchange', this.handleDurationChange);
|
||||
this.on('fullscreenchange', this.handleFullscreenChange);
|
||||
|
||||
return el;
|
||||
}
|
||||
@@ -272,6 +257,7 @@ class Player extends Component {
|
||||
// get rid of the HTML5 video tag as soon as we are using another tech
|
||||
if (techName !== 'Html5' && this.tag) {
|
||||
Component.getComponent('Html5').disposeMediaElement(this.tag);
|
||||
this.tag.player = null;
|
||||
this.tag = null;
|
||||
}
|
||||
|
||||
@@ -280,16 +266,24 @@ class Player extends Component {
|
||||
// Turn off API access because we're loading a new tech that might load asynchronously
|
||||
this.isReady_ = false;
|
||||
|
||||
var techReady = function(){
|
||||
this.player_.triggerReady();
|
||||
};
|
||||
var techReady = Lib.bind(this, function() {
|
||||
this.triggerReady();
|
||||
});
|
||||
|
||||
// Grab tech-specific options from player options and add source and parent element to use.
|
||||
var techOptions = Lib.obj.merge({ 'source': source, 'parentEl': this.el_ }, this.options_[techName.toLowerCase()]);
|
||||
var techOptions = Lib.obj.merge({
|
||||
'source': source,
|
||||
'playerId': this.id(),
|
||||
'textTracks': this.textTracks_
|
||||
}, this.options_[techName.toLowerCase()]);
|
||||
|
||||
if (this.tag) {
|
||||
techOptions.tag = this.tag;
|
||||
}
|
||||
|
||||
if (source) {
|
||||
this.currentType_ = source.type;
|
||||
if (source.src == this.cache_.src && this.cache_.currentTime > 0) {
|
||||
if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
|
||||
techOptions['startTime'] = this.cache_.currentTime;
|
||||
}
|
||||
|
||||
@@ -298,12 +292,61 @@ class Player extends Component {
|
||||
|
||||
// Initialize tech instance
|
||||
let techComponent = Component.getComponent(techName);
|
||||
this.tech = new techComponent(this, techOptions);
|
||||
this.tech = new techComponent(techOptions);
|
||||
|
||||
this.on(this.tech, 'ready', this.handleTechReady);
|
||||
this.on(this.tech, 'usenativecontrols', this.handleTechUseNativeControls);
|
||||
|
||||
// Listen to every HTML5 events and trigger them back on the player for the plugins
|
||||
this.on(this.tech, 'loadstart', this.handleTechLoadStart);
|
||||
this.on(this.tech, 'waiting', this.handleTechWaiting);
|
||||
this.on(this.tech, 'canplay', this.handleTechCanPlay);
|
||||
this.on(this.tech, 'canplaythrough', this.handleTechCanPlayThrough);
|
||||
this.on(this.tech, 'playing', this.handleTechPlaying);
|
||||
this.on(this.tech, 'ended', this.handleTechEnded);
|
||||
this.on(this.tech, 'seeking', this.handleTechSeeking);
|
||||
this.on(this.tech, 'seeked', this.handleTechSeeked);
|
||||
this.on(this.tech, 'play', this.handleTechPlay);
|
||||
this.on(this.tech, 'firstplay', this.handleTechFirstPlay);
|
||||
this.on(this.tech, 'pause', this.handleTechPause);
|
||||
this.on(this.tech, 'progress', this.handleTechProgress);
|
||||
this.on(this.tech, 'durationchange', this.handleTechDurationChange);
|
||||
this.on(this.tech, 'fullscreenchange', this.handleTechFullscreenChange);
|
||||
this.on(this.tech, 'error', this.handleTechError);
|
||||
this.on(this.tech, 'suspend', this.handleTechSuspend);
|
||||
this.on(this.tech, 'abort', this.handleTechAbort);
|
||||
this.on(this.tech, 'emptied', this.handleTechEmptied);
|
||||
this.on(this.tech, 'stalled', this.handleTechStalled);
|
||||
this.on(this.tech, 'loadedmetadata', this.handleTechLoadedMetaData);
|
||||
this.on(this.tech, 'loadeddata', this.handleTechLoadedData);
|
||||
this.on(this.tech, 'timeupdate', this.handleTechTimeUpdate);
|
||||
this.on(this.tech, 'ratechange', this.handleTechRateChange);
|
||||
this.on(this.tech, 'volumechange', this.handleTechVolumeChange);
|
||||
this.on(this.tech, 'texttrackchange', this.onTextTrackChange);
|
||||
|
||||
if (this.controls() && !this.usingNativeControls()) {
|
||||
this.addTechControlsListeners();
|
||||
}
|
||||
|
||||
// Add the tech element in the DOM if it was not already there
|
||||
// Make sure to not insert the original video element if using Html5
|
||||
if (this.tech.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
|
||||
Lib.insertFirst(this.tech.el(), this.el());
|
||||
}
|
||||
|
||||
// Get rid of the original video tag reference after the first tech is loaded
|
||||
if (this.tag) {
|
||||
this.tag.player = null;
|
||||
this.tag = null;
|
||||
}
|
||||
|
||||
this.tech.ready(techReady);
|
||||
}
|
||||
|
||||
unloadTech() {
|
||||
// Save the current text tracks so that we can reuse the same text tracks with the next tech
|
||||
this.textTracks_ = this.textTracks();
|
||||
|
||||
this.isReady_ = false;
|
||||
|
||||
this.tech.dispose();
|
||||
@@ -311,11 +354,72 @@ class Player extends Component {
|
||||
this.tech = false;
|
||||
}
|
||||
|
||||
addTechControlsListeners() {
|
||||
// Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
|
||||
// trigger mousedown/up.
|
||||
// http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
|
||||
// Any touch events are set to block the mousedown event from happening
|
||||
this.on(this.tech, 'mousedown', this.handleTechClick);
|
||||
|
||||
// If the controls were hidden we don't want that to change without a tap event
|
||||
// so we'll check if the controls were already showing before reporting user
|
||||
// activity
|
||||
this.on(this.tech, 'touchstart', this.handleTechTouchStart);
|
||||
this.on(this.tech, 'touchmove', this.handleTechTouchMove);
|
||||
this.on(this.tech, 'touchend', this.handleTechTouchEnd);
|
||||
|
||||
// Turn on component tap events
|
||||
this.tech.emitTapEvents();
|
||||
|
||||
// The tap listener needs to come after the touchend listener because the tap
|
||||
// listener cancels out any reportedUserActivity when setting userActive(false)
|
||||
this.on(this.tech, 'tap', this.handleTechTap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the listeners used for click and tap controls. This is needed for
|
||||
* toggling to controls disabled, where a tap/touch should do nothing.
|
||||
*/
|
||||
removeTechControlsListeners() {
|
||||
// We don't want to just use `this.off()` because there might be other needed
|
||||
// listeners added by techs that extend this.
|
||||
this.off(this.tech, 'tap', this.handleTechTap);
|
||||
this.off(this.tech, 'touchstart', this.handleTechTouchStart);
|
||||
this.off(this.tech, 'touchmove', this.handleTechTouchMove);
|
||||
this.off(this.tech, 'touchend', this.handleTechTouchEnd);
|
||||
this.off(this.tech, 'mousedown', this.handleTechClick);
|
||||
}
|
||||
|
||||
/**
|
||||
* Player waits for the tech to be ready
|
||||
* @private
|
||||
*/
|
||||
handleTechReady() {
|
||||
this.triggerReady();
|
||||
|
||||
// Chrome and Safari both have issues with autoplay.
|
||||
// In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
|
||||
// In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
|
||||
// This fixes both issues. Need to wait for API, so it updates displays correctly
|
||||
if (this.tag && this.options_.autoplay && this.paused()) {
|
||||
delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16.
|
||||
this.play();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the native controls are used
|
||||
* @private
|
||||
*/
|
||||
handleTechUseNativeControls() {
|
||||
this.usingNativeControls(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the user agent begins looking for media data
|
||||
* @event loadstart
|
||||
*/
|
||||
handleLoadStart() {
|
||||
handleTechLoadStart() {
|
||||
// TODO: Update to use `emptied` event instead. See #1277.
|
||||
|
||||
this.removeClass('vjs-ended');
|
||||
@@ -327,10 +431,12 @@ class Player extends Component {
|
||||
// The firstplay event relies on both the play and loadstart events
|
||||
// which can happen in any order for a new source
|
||||
if (!this.paused()) {
|
||||
this.trigger('loadstart');
|
||||
this.trigger('firstplay');
|
||||
} else {
|
||||
// reset the hasStarted state
|
||||
this.hasStarted(false);
|
||||
this.trigger('loadstart');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +462,7 @@ class Player extends Component {
|
||||
* Fired whenever the media begins or resumes playback
|
||||
* @event play
|
||||
*/
|
||||
handlePlay() {
|
||||
handleTechPlay() {
|
||||
this.removeClass('vjs-ended');
|
||||
this.removeClass('vjs-paused');
|
||||
this.addClass('vjs-playing');
|
||||
@@ -364,39 +470,65 @@ class Player extends Component {
|
||||
// hide the poster when the user hits play
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play
|
||||
this.hasStarted(true);
|
||||
|
||||
this.trigger('play');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired whenever the media begins waiting
|
||||
* @event waiting
|
||||
*/
|
||||
handleWaiting() {
|
||||
handleTechWaiting() {
|
||||
this.addClass('vjs-waiting');
|
||||
this.trigger('waiting');
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler for events that signal that waiting has ended
|
||||
* which is not consistent between browsers. See #1351
|
||||
* @private
|
||||
* @event canplay
|
||||
*/
|
||||
handleWaitEnd() {
|
||||
handleTechCanPlay() {
|
||||
this.removeClass('vjs-waiting');
|
||||
this.trigger('canplay');
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler for events that signal that waiting has ended
|
||||
* which is not consistent between browsers. See #1351
|
||||
* @event canplaythrough
|
||||
*/
|
||||
handleTechCanPlayThrough() {
|
||||
this.removeClass('vjs-waiting');
|
||||
this.trigger('canplaythrough');
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler for events that signal that waiting has ended
|
||||
* which is not consistent between browsers. See #1351
|
||||
* @event playing
|
||||
*/
|
||||
handleTechPlaying() {
|
||||
this.removeClass('vjs-waiting');
|
||||
this.trigger('playing');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired whenever the player is jumping to a new time
|
||||
* @event seeking
|
||||
*/
|
||||
handleSeeking() {
|
||||
handleTechSeeking() {
|
||||
this.addClass('vjs-seeking');
|
||||
this.trigger('seeking');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the player has finished jumping to a new time
|
||||
* @event seeked
|
||||
*/
|
||||
handleSeeked() {
|
||||
handleTechSeeked() {
|
||||
this.removeClass('vjs-seeking');
|
||||
this.trigger('seeked');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,7 +540,7 @@ class Player extends Component {
|
||||
*
|
||||
* @event firstplay
|
||||
*/
|
||||
handleFirstPlay() {
|
||||
handleTechFirstPlay() {
|
||||
//If the first starttime attribute is specified
|
||||
//then we will start at the given offset in seconds
|
||||
if(this.options_['starttime']){
|
||||
@@ -416,24 +548,28 @@ class Player extends Component {
|
||||
}
|
||||
|
||||
this.addClass('vjs-has-started');
|
||||
this.trigger('firstplay');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired whenever the media has been paused
|
||||
* @event pause
|
||||
*/
|
||||
handlePause() {
|
||||
handleTechPause() {
|
||||
this.removeClass('vjs-playing');
|
||||
this.addClass('vjs-paused');
|
||||
this.trigger('pause');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired while the user agent is downloading media data
|
||||
* @event progress
|
||||
*/
|
||||
handleProgress() {
|
||||
handleTechProgress() {
|
||||
this.trigger('progress');
|
||||
|
||||
// Add custom event for when source is finished downloading.
|
||||
if (this.bufferedPercent() == 1) {
|
||||
if (this.bufferedPercent() === 1) {
|
||||
this.trigger('loadedalldata');
|
||||
}
|
||||
}
|
||||
@@ -442,7 +578,7 @@ class Player extends Component {
|
||||
* Fired when the end of the media resource is reached (currentTime == duration)
|
||||
* @event ended
|
||||
*/
|
||||
handleEnded() {
|
||||
handleTechEnded() {
|
||||
this.addClass('vjs-ended');
|
||||
if (this.options_['loop']) {
|
||||
this.currentTime(0);
|
||||
@@ -450,13 +586,66 @@ class Player extends Component {
|
||||
} else if (!this.paused()) {
|
||||
this.pause();
|
||||
}
|
||||
|
||||
this.trigger('ended');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the duration of the media resource is first known or changed
|
||||
* @event durationchange
|
||||
*/
|
||||
handleDurationChange() {
|
||||
handleTechDurationChange() {
|
||||
this.updateDuration();
|
||||
this.trigger('durationchange');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a click on the media element to play/pause
|
||||
*/
|
||||
handleTechClick(event) {
|
||||
// We're using mousedown to detect clicks thanks to Flash, but mousedown
|
||||
// will also be triggered with right-clicks, so we need to prevent that
|
||||
if (event.button !== 0) return;
|
||||
|
||||
// When controls are disabled a click should not toggle playback because
|
||||
// the click is considered a control
|
||||
if (this.controls()) {
|
||||
if (this.paused()) {
|
||||
this.play();
|
||||
} else {
|
||||
this.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a tap on the media element. It will toggle the user
|
||||
* activity state, which hides and shows the controls.
|
||||
*/
|
||||
handleTechTap() {
|
||||
this.userActive(!this.userActive());
|
||||
}
|
||||
|
||||
handleTechTouchStart() {
|
||||
this.userWasActive = this.userActive();
|
||||
}
|
||||
|
||||
handleTechTouchMove() {
|
||||
if (this.userWasActive){
|
||||
this.reportUserActivity();
|
||||
}
|
||||
}
|
||||
|
||||
handleTechTouchEnd(event) {
|
||||
// Stop the mouse events from also happening
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the duration of the player using the tech
|
||||
* @private
|
||||
*/
|
||||
updateDuration() {
|
||||
// Allows for caching value instead of asking player each time.
|
||||
// We need to get the techGet response and check for a value so we don't
|
||||
// accidentally cause the stack to blow up.
|
||||
@@ -487,6 +676,107 @@ class Player extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* native click events on the SWF aren't triggered on IE11, Win8.1RT
|
||||
* use stageclick events triggered from inside the SWF instead
|
||||
* @private
|
||||
*/
|
||||
handleStageClick() {
|
||||
this.reportUserActivity();
|
||||
}
|
||||
|
||||
handleTechFullscreenChange() {
|
||||
this.trigger('fullscreenchange');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when an error occurred during the loading of an audio/video
|
||||
* @event error
|
||||
*/
|
||||
handleTechError() {
|
||||
this.error(this.tech.error().code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the browser is intentionally not getting media data
|
||||
* @event suspend
|
||||
*/
|
||||
handleTechSuspend() {
|
||||
this.trigger('suspend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the loading of an audio/video is aborted
|
||||
* @event abort
|
||||
*/
|
||||
handleTechAbort() {
|
||||
this.trigger('abort');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the current playlist is empty
|
||||
* @event emptied
|
||||
*/
|
||||
handleTechEmptied() {
|
||||
this.trigger('emptied');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the browser is trying to get media data, but data is not available
|
||||
* @event stalled
|
||||
*/
|
||||
handleTechStalled() {
|
||||
this.trigger('stalled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the browser has loaded meta data for the audio/video
|
||||
* @event loadedmetadata
|
||||
*/
|
||||
handleTechLoadedMetaData() {
|
||||
this.trigger('loadedmetadata');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the browser has loaded the current frame of the audio/video
|
||||
* @event loaddata
|
||||
*/
|
||||
handleTechLoadedData() {
|
||||
this.trigger('loadeddata');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the current playback position has changed
|
||||
* @event timeupdate
|
||||
*/
|
||||
handleTechTimeUpdate() {
|
||||
this.trigger('timeupdate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the playing speed of the audio/video is changed
|
||||
* @event ratechange
|
||||
*/
|
||||
handleTechRateChange() {
|
||||
this.trigger('ratechange');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the volume has been changed
|
||||
* @event volumechange
|
||||
*/
|
||||
handleTechVolumeChange() {
|
||||
this.trigger('volumechange');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the text track has been changed
|
||||
* @event texttrackchange
|
||||
*/
|
||||
onTextTrackChange() {
|
||||
this.trigger('texttrackchange');
|
||||
}
|
||||
|
||||
/**
|
||||
* Object for cached values.
|
||||
*/
|
||||
@@ -528,7 +818,7 @@ class Player extends Component {
|
||||
Lib.log(`Video.js: ${method} method not defined for ${this.techName} playback technology.`, e);
|
||||
} else {
|
||||
// When a method isn't available on the object it throws a TypeError
|
||||
if (e.name == 'TypeError') {
|
||||
if (e.name === 'TypeError') {
|
||||
Lib.log(`Video.js: ${method} unavailable on ${this.techName} playback technology element.`, e);
|
||||
this.tech.isReady_ = false;
|
||||
} else {
|
||||
@@ -653,7 +943,7 @@ class Player extends Component {
|
||||
}
|
||||
|
||||
if (this.cache_.duration === undefined) {
|
||||
this.handleDurationChange();
|
||||
this.updateDuration();
|
||||
}
|
||||
|
||||
return this.cache_.duration || 0;
|
||||
@@ -1090,7 +1380,7 @@ class Player extends Component {
|
||||
this.techCall('src', source.src);
|
||||
}
|
||||
|
||||
if (this.options_['preload'] == 'auto') {
|
||||
if (this.options_['preload'] === 'auto') {
|
||||
this.load();
|
||||
}
|
||||
|
||||
@@ -1251,14 +1541,27 @@ class Player extends Component {
|
||||
// Don't trigger a change event unless it actually changed
|
||||
if (this.controls_ !== bool) {
|
||||
this.controls_ = bool;
|
||||
|
||||
if (this.usingNativeControls()) {
|
||||
this.techCall('setControls', bool);
|
||||
}
|
||||
|
||||
if (bool) {
|
||||
this.removeClass('vjs-controls-disabled');
|
||||
this.addClass('vjs-controls-enabled');
|
||||
this.trigger('controlsenabled');
|
||||
|
||||
if (!this.usingNativeControls()) {
|
||||
this.addTechControlsListeners();
|
||||
}
|
||||
} else {
|
||||
this.removeClass('vjs-controls-enabled');
|
||||
this.addClass('vjs-controls-disabled');
|
||||
this.trigger('controlsdisabled');
|
||||
|
||||
if (!this.usingNativeControls()) {
|
||||
this.removeTechControlsListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@@ -1419,7 +1722,7 @@ class Player extends Component {
|
||||
let handleMouseMove = function(e) {
|
||||
// #1068 - Prevent mousemove spamming
|
||||
// Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
|
||||
if(e.screenX != lastMoveX || e.screenY != lastMoveY) {
|
||||
if(e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
|
||||
lastMoveX = e.screenX;
|
||||
lastMoveY = e.screenY;
|
||||
handleActivity();
|
||||
|
||||
@@ -211,10 +211,10 @@ class Slider extends Component {
|
||||
}
|
||||
|
||||
handleKeyPress(event) {
|
||||
if (event.which == 37 || event.which == 40) { // Left and Down Arrows
|
||||
if (event.which === 37 || event.which === 40) { // Left and Down Arrows
|
||||
event.preventDefault();
|
||||
this.stepBack();
|
||||
} else if (event.which == 38 || event.which == 39) { // Up and Right Arrows
|
||||
} else if (event.which === 38 || event.which === 39) { // Up and Right Arrows
|
||||
event.preventDefault();
|
||||
this.stepForward();
|
||||
}
|
||||
|
||||
+37
-63
@@ -9,8 +9,8 @@ import * as Lib from '../lib';
|
||||
import FlashRtmpDecorator from './flash-rtmp';
|
||||
import Component from '../component';
|
||||
import window from 'global/window';
|
||||
let navigator = window.navigator;
|
||||
|
||||
let navigator = window.navigator;
|
||||
/**
|
||||
* Flash Media Controller - Wrapper for fallback SWF API
|
||||
*
|
||||
@@ -21,21 +21,13 @@ let navigator = window.navigator;
|
||||
*/
|
||||
class Flash extends Tech {
|
||||
|
||||
constructor(player, options, ready){
|
||||
super(player, options, ready);
|
||||
constructor(options, ready){
|
||||
super(options, ready);
|
||||
|
||||
let { source, parentEl } = options;
|
||||
|
||||
// Create a temporary element to be replaced by swf object
|
||||
let placeHolder = this.el_ = Lib.createEl('div', { id: player.id() + '_temp_flash' });
|
||||
|
||||
// Generate ID for swf object
|
||||
let objId = player.id()+'_flash_api';
|
||||
|
||||
// Store player options in local var for optimization
|
||||
// TODO: switch to using player methods instead of options
|
||||
// e.g. player.autoplay();
|
||||
let playerOptions = player.options_;
|
||||
let objId = options.playerId+'_flash_api';
|
||||
|
||||
// Merge default flashvars with ones passed in to init
|
||||
let flashVars = Lib.obj.merge({
|
||||
@@ -46,25 +38,25 @@ class Flash extends Tech {
|
||||
'errorEventProxyFunction': 'videojs.Flash.onError',
|
||||
|
||||
// Player Settings
|
||||
'autoplay': playerOptions.autoplay,
|
||||
'preload': playerOptions.preload,
|
||||
'loop': playerOptions.loop,
|
||||
'muted': playerOptions.muted
|
||||
'autoplay': options.autoplay,
|
||||
'preload': options.preload,
|
||||
'loop': options.loop,
|
||||
'muted': options.muted
|
||||
|
||||
}, options['flashVars']);
|
||||
}, options.flashVars);
|
||||
|
||||
// Merge default parames with ones passed in
|
||||
let params = Lib.obj.merge({
|
||||
'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance
|
||||
'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading
|
||||
}, options['params']);
|
||||
}, options.params);
|
||||
|
||||
// Merge default attributes with ones passed in
|
||||
let attributes = Lib.obj.merge({
|
||||
'id': objId,
|
||||
'name': objId, // Both ID and Name needed or swf to identify itself
|
||||
'class': 'vjs-tech'
|
||||
}, options['attributes']);
|
||||
}, options.attributes);
|
||||
|
||||
// If source was supplied pass as a flash var.
|
||||
if (source) {
|
||||
@@ -73,35 +65,24 @@ class Flash extends Tech {
|
||||
});
|
||||
}
|
||||
|
||||
// Add placeholder to player div
|
||||
Lib.insertFirst(placeHolder, parentEl);
|
||||
|
||||
// Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
|
||||
// This allows resetting the playhead when we catch the reload
|
||||
if (options['startTime']) {
|
||||
if (options.startTime) {
|
||||
this.ready(function(){
|
||||
this.load();
|
||||
this.play();
|
||||
this['currentTime'](options['startTime']);
|
||||
this.currentTime(options.startTime);
|
||||
});
|
||||
}
|
||||
|
||||
// firefox doesn't bubble mousemove events to parent. videojs/video-js-swf#37
|
||||
// bugzilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=836786
|
||||
if (Lib.IS_FIREFOX) {
|
||||
this.ready(function(){
|
||||
this.on('mousemove', function(){
|
||||
// since it's a custom event, don't bubble higher than the player
|
||||
this.player().trigger({ 'type':'mousemove', 'bubbles': false });
|
||||
});
|
||||
});
|
||||
}
|
||||
window.videojs = window.videojs || {};
|
||||
window.videojs.Flash = window.videojs.Flash || {};
|
||||
window.videojs.Flash.onReady = Flash.onReady;
|
||||
window.videojs.Flash.onEvent = Flash.onEvent;
|
||||
window.videojs.Flash.onError = Flash.onError;
|
||||
|
||||
// native click events on the SWF aren't triggered on IE11, Win8.1RT
|
||||
// use stageclick events triggered from inside the SWF instead
|
||||
player.on('stageclick', player.reportUserActivity);
|
||||
|
||||
this.el_ = Flash.embed(options['swf'], placeHolder, flashVars, params, attributes);
|
||||
this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
|
||||
this.el_.tech = this;
|
||||
}
|
||||
|
||||
play() {
|
||||
@@ -114,7 +95,7 @@ class Flash extends Tech {
|
||||
|
||||
src(src) {
|
||||
if (src === undefined) {
|
||||
return this['currentSrc']();
|
||||
return this.currentSrc();
|
||||
}
|
||||
|
||||
// Setting src through `src` not `setSrc` will be deprecated
|
||||
@@ -128,7 +109,7 @@ class Flash extends Tech {
|
||||
|
||||
// Currently the SWF doesn't autoplay if you load a source later.
|
||||
// e.g. Load player w/ no source, wait 2s, set src.
|
||||
if (this.player_.autoplay()) {
|
||||
if (this.autoplay()) {
|
||||
var tech = this;
|
||||
this.setTimeout(function(){ tech.play(); }, 0);
|
||||
}
|
||||
@@ -282,25 +263,21 @@ Flash.formats = {
|
||||
'video/m4v': 'MP4'
|
||||
};
|
||||
|
||||
Flash['onReady'] = function(currSwf){
|
||||
Flash.onReady = function(currSwf){
|
||||
let el = Lib.el(currSwf);
|
||||
let tech = el && el.tech;
|
||||
|
||||
// get player from the player div property
|
||||
const player = el && el.parentNode && el.parentNode['player'];
|
||||
|
||||
// if there is no el or player then the tech has been disposed
|
||||
// if there is no el then the tech has been disposed
|
||||
// and the tech element was removed from the player div
|
||||
if (player) {
|
||||
// reference player on tech element
|
||||
el['player'] = player;
|
||||
if (tech && tech.el()) {
|
||||
// check that the flash object is really ready
|
||||
Flash['checkReady'](player.tech);
|
||||
Flash.checkReady(tech);
|
||||
}
|
||||
};
|
||||
|
||||
// The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object.
|
||||
// If it's not ready, we set a timeout to check again shortly.
|
||||
Flash['checkReady'] = function(tech){
|
||||
Flash.checkReady = function(tech){
|
||||
// stop worrying if the tech has been disposed
|
||||
if (!tech.el()) {
|
||||
return;
|
||||
@@ -319,22 +296,22 @@ Flash['checkReady'] = function(tech){
|
||||
};
|
||||
|
||||
// Trigger events from the swf on the player
|
||||
Flash['onEvent'] = function(swfID, eventName){
|
||||
let player = Lib.el(swfID)['player'];
|
||||
player.trigger(eventName);
|
||||
Flash.onEvent = function(swfID, eventName){
|
||||
let tech = Lib.el(swfID).tech;
|
||||
tech.trigger(eventName);
|
||||
};
|
||||
|
||||
// Log errors from the swf
|
||||
Flash['onError'] = function(swfID, err){
|
||||
const player = Lib.el(swfID)['player'];
|
||||
Flash.onError = function(swfID, err){
|
||||
const tech = Lib.el(swfID).tech;
|
||||
const msg = 'FLASH: '+err;
|
||||
|
||||
if (err == 'srcnotfound') {
|
||||
player.error({ code: 4, message: msg });
|
||||
if (err === 'srcnotfound') {
|
||||
tech.trigger('error', { code: 4, message: msg });
|
||||
|
||||
// errors we haven't categorized into the media errors
|
||||
} else {
|
||||
player.error(msg);
|
||||
tech.trigger('error', msg);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -358,15 +335,12 @@ Flash.version = function(){
|
||||
};
|
||||
|
||||
// Flash embedding method. Only used in non-iframe mode
|
||||
Flash.embed = function(swf, placeHolder, flashVars, params, attributes){
|
||||
Flash.embed = function(swf, flashVars, params, attributes){
|
||||
const code = Flash.getEmbedCode(swf, flashVars, params, attributes);
|
||||
|
||||
// Get element by embedding code and retrieving created element
|
||||
const obj = Lib.createEl('div', { innerHTML: code }).childNodes[0];
|
||||
|
||||
const par = placeHolder.parentNode;
|
||||
|
||||
placeHolder.parentNode.replaceChild(obj, placeHolder);
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
+22
-104
@@ -17,18 +17,16 @@ import document from 'global/document';
|
||||
*/
|
||||
class Html5 extends Tech {
|
||||
|
||||
constructor(player, options, ready){
|
||||
super(player, options, ready);
|
||||
constructor(options, ready){
|
||||
super(options, ready);
|
||||
|
||||
this.setupTriggers();
|
||||
|
||||
const source = options['source'];
|
||||
const source = options.source;
|
||||
|
||||
// Set the source if one is provided
|
||||
// 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
|
||||
// 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
|
||||
// anyway so the error gets fired.
|
||||
if (source && (this.el_.currentSrc !== source.src || (player.tag && player.tag.initNetworkState_ === 3))) {
|
||||
if (source && (this.el_.currentSrc !== source.src || (options.tag && options.tag.initNetworkState_ === 3))) {
|
||||
this.setSource(source);
|
||||
}
|
||||
|
||||
@@ -42,14 +40,14 @@ class Html5 extends Tech {
|
||||
let node = nodes[nodesLength];
|
||||
let nodeName = node.nodeName.toLowerCase();
|
||||
if (nodeName === 'track') {
|
||||
if (!this['featuresNativeTextTracks']) {
|
||||
if (!this.featuresNativeTextTracks) {
|
||||
// Empty video tag tracks so the built-in player doesn't use them also.
|
||||
// This may not be fast enough to stop HTML5 browsers from reading the tags
|
||||
// so we'll need to turn off any default tracks if we're manually doing
|
||||
// captions and subtitles. videoElement.textTracks
|
||||
removeNodes.push(node);
|
||||
} else {
|
||||
this.remoteTextTracks().addTrack_(node['track']);
|
||||
this.remoteTextTracks().addTrack_(node.track);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +57,7 @@ class Html5 extends Tech {
|
||||
}
|
||||
}
|
||||
|
||||
if (this['featuresNativeTextTracks']) {
|
||||
if (this.featuresNativeTextTracks) {
|
||||
this.on('loadstart', Lib.bind(this, this.hideCaptions));
|
||||
}
|
||||
|
||||
@@ -67,21 +65,10 @@ class Html5 extends Tech {
|
||||
// Our goal should be to get the custom controls on mobile solid everywhere
|
||||
// so we can remove this all together. Right now this will block custom
|
||||
// controls on touch enabled laptops like the Chrome Pixel
|
||||
if (Lib.TOUCH_ENABLED && player.options()['nativeControlsForTouch'] === true) {
|
||||
this.useNativeControls();
|
||||
if (Lib.TOUCH_ENABLED && options.nativeControlsForTouch === true) {
|
||||
this.trigger('usenativecontrols');
|
||||
}
|
||||
|
||||
// Chrome and Safari both have issues with autoplay.
|
||||
// In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
|
||||
// In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
|
||||
// This fixes both issues. Need to wait for API, so it updates displays correctly
|
||||
player.ready(function(){
|
||||
if (this.tag && this.options_['autoplay'] && this.paused()) {
|
||||
delete this.tag['poster']; // Chrome Fix. Fixed in Chrome v16.
|
||||
this.play();
|
||||
}
|
||||
});
|
||||
|
||||
this.triggerReady();
|
||||
}
|
||||
|
||||
@@ -92,8 +79,7 @@ class Html5 extends Tech {
|
||||
}
|
||||
|
||||
createEl() {
|
||||
let player = this.player_;
|
||||
let el = player.tag;
|
||||
let el = this.options_.tag;
|
||||
|
||||
// Check if this browser supports moving the element into the box.
|
||||
// On the iPhone video will break if you move the element,
|
||||
@@ -105,29 +91,27 @@ class Html5 extends Tech {
|
||||
const clone = el.cloneNode(false);
|
||||
Html5.disposeMediaElement(el);
|
||||
el = clone;
|
||||
player.tag = null;
|
||||
} else {
|
||||
el = Lib.createEl('video');
|
||||
|
||||
// determine if native controls should be used
|
||||
let attributes = VjsUtil.mergeOptions({}, player.tagAttributes);
|
||||
if (!Lib.TOUCH_ENABLED || player.options()['nativeControlsForTouch'] !== true) {
|
||||
let tagAttributes = this.options_.tag && Lib.getElementAttributes(this.options_.tag);
|
||||
let attributes = VjsUtil.mergeOptions({}, tagAttributes);
|
||||
if (!Lib.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
|
||||
delete attributes.controls;
|
||||
}
|
||||
|
||||
Lib.setElementAttributes(el,
|
||||
Lib.obj.merge(attributes, {
|
||||
id: player.id() + '_html5_api',
|
||||
id: this.options_.playerId + '_html5_api',
|
||||
class: 'vjs-tech'
|
||||
})
|
||||
);
|
||||
}
|
||||
// associate the player with the new tag
|
||||
el['player'] = player;
|
||||
|
||||
if (player.options_.tracks) {
|
||||
for (let i = 0; i < player.options_.tracks.length; i++) {
|
||||
const track = player.options_.tracks[i];
|
||||
if (this.options_.tracks) {
|
||||
for (let i = 0; i < this.options_.tracks.length; i++) {
|
||||
const track = this.options_.tracks[i];
|
||||
let trackEl = document.createElement('track');
|
||||
trackEl.kind = track.kind;
|
||||
trackEl.label = track.label;
|
||||
@@ -139,8 +123,6 @@ class Html5 extends Tech {
|
||||
el.appendChild(trackEl);
|
||||
}
|
||||
}
|
||||
|
||||
Lib.insertFirst(el, player.el());
|
||||
}
|
||||
|
||||
// Update specific tag settings, in case they were overridden
|
||||
@@ -148,8 +130,8 @@ class Html5 extends Tech {
|
||||
for (let i = settingsAttrs.length - 1; i >= 0; i--) {
|
||||
const attr = settingsAttrs[i];
|
||||
let overwriteAttrs = {};
|
||||
if (typeof player.options_[attr] !== 'undefined') {
|
||||
overwriteAttrs[attr] = player.options_[attr];
|
||||
if (typeof this.options_[attr] !== 'undefined') {
|
||||
overwriteAttrs[attr] = this.options_[attr];
|
||||
}
|
||||
Lib.setElementAttributes(el, overwriteAttrs);
|
||||
}
|
||||
@@ -176,62 +158,6 @@ class Html5 extends Tech {
|
||||
}
|
||||
}
|
||||
|
||||
// Make video events trigger player events
|
||||
// May seem verbose here, but makes other APIs possible.
|
||||
// Triggers removed using this.off when disposed
|
||||
setupTriggers() {
|
||||
for (let i = Html5.Events.length - 1; i >= 0; i--) {
|
||||
this.on(Html5.Events[i], this.eventHandler);
|
||||
}
|
||||
}
|
||||
|
||||
eventHandler(evt) {
|
||||
// In the case of an error on the video element, set the error prop
|
||||
// on the player and let the player handle triggering the event. On
|
||||
// some platforms, error events fire that do not cause the error
|
||||
// property on the video element to be set. See #1465 for an example.
|
||||
if (evt.type == 'error' && this.error()) {
|
||||
this.player().error(this.error().code);
|
||||
|
||||
// in some cases we pass the event directly to the player
|
||||
} else {
|
||||
// No need for media events to bubble up.
|
||||
evt.bubbles = false;
|
||||
|
||||
this.player().trigger(evt);
|
||||
}
|
||||
}
|
||||
|
||||
useNativeControls() {
|
||||
let tech = this;
|
||||
let player = this.player();
|
||||
|
||||
// If the player controls are enabled turn on the native controls
|
||||
tech.setControls(player.controls());
|
||||
|
||||
// Update the native controls when player controls state is updated
|
||||
let controlsOn = function(){
|
||||
tech.setControls(true);
|
||||
};
|
||||
let controlsOff = function(){
|
||||
tech.setControls(false);
|
||||
};
|
||||
player.on('controlsenabled', controlsOn);
|
||||
player.on('controlsdisabled', controlsOff);
|
||||
|
||||
// Clean up when not using native controls anymore
|
||||
let cleanUp = function(){
|
||||
player.off('controlsenabled', controlsOn);
|
||||
player.off('controlsdisabled', controlsOff);
|
||||
};
|
||||
tech.on('dispose', cleanUp);
|
||||
player.on('usingcustomcontrols', cleanUp);
|
||||
|
||||
// Update the state of the player to using native controls
|
||||
player.usingNativeControls(true);
|
||||
}
|
||||
|
||||
|
||||
play() { this.el_.play(); }
|
||||
pause() { this.el_.pause(); }
|
||||
paused() { return this.el_.paused; }
|
||||
@@ -260,7 +186,7 @@ class Html5 extends Tech {
|
||||
height() { return this.el_.offsetHeight; }
|
||||
|
||||
supportsFullScreen() {
|
||||
if (typeof this.el_.webkitEnterFullScreen == 'function') {
|
||||
if (typeof this.el_.webkitEnterFullScreen === 'function') {
|
||||
|
||||
// Seems to be broken in Chromium/Chrome && Safari in Leopard
|
||||
if (/Android/.test(Lib.USER_AGENT) || !/Chrome|Mac OS X 10.5/.test(Lib.USER_AGENT)) {
|
||||
@@ -275,14 +201,11 @@ class Html5 extends Tech {
|
||||
|
||||
if ('webkitDisplayingFullscreen' in video) {
|
||||
this.one('webkitbeginfullscreen', function() {
|
||||
this.player_.isFullscreen(true);
|
||||
|
||||
this.one('webkitendfullscreen', function() {
|
||||
this.player_.isFullscreen(false);
|
||||
this.player_.trigger('fullscreenchange');
|
||||
this.trigger('fullscreenchange');
|
||||
});
|
||||
|
||||
this.player_.trigger('fullscreenchange');
|
||||
this.trigger('fullscreenchange');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -642,14 +565,9 @@ Html5.unpatchCanPlayType = function() {
|
||||
// by default, patch the video element
|
||||
Html5.patchCanPlayType();
|
||||
|
||||
// List of all HTML5 events (various uses).
|
||||
Html5.Events = 'loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange'.split(',');
|
||||
|
||||
Html5.disposeMediaElement = function(el){
|
||||
if (!el) { return; }
|
||||
|
||||
el['player'] = null;
|
||||
|
||||
if (el.parentNode) {
|
||||
el.parentNode.removeChild(el);
|
||||
}
|
||||
|
||||
+98
-156
@@ -18,29 +18,32 @@ import document from 'global/document';
|
||||
*/
|
||||
class Tech extends Component {
|
||||
|
||||
constructor(player, options={}, ready=function(){}){
|
||||
constructor(options={}, ready=function(){}){
|
||||
options = options || {};
|
||||
// we don't want the tech to report user activity automatically.
|
||||
// This is done manually in addControlsListeners
|
||||
options.reportTouchActivity = false;
|
||||
super(player, options, ready);
|
||||
super(null, options, ready);
|
||||
|
||||
this.textTracks_ = options.textTracks;
|
||||
|
||||
// Manually track progress in cases where the browser/flash player doesn't report it.
|
||||
if (!this['featuresProgressEvents']) {
|
||||
if (!this.featuresProgressEvents) {
|
||||
this.manualProgressOn();
|
||||
}
|
||||
|
||||
// Manually track timeupdates in cases where the browser/flash player doesn't report it.
|
||||
if (!this['featuresTimeupdateEvents']) {
|
||||
if (!this.featuresTimeupdateEvents) {
|
||||
this.manualTimeUpdatesOn();
|
||||
}
|
||||
|
||||
this.initControlsListeners();
|
||||
|
||||
if (options['nativeCaptions'] === false || options['nativeTextTracks'] === false) {
|
||||
this['featuresNativeTextTracks'] = false;
|
||||
if (options.nativeCaptions === false || options.nativeTextTracks === false) {
|
||||
this.featuresNativeTextTracks = false;
|
||||
}
|
||||
|
||||
if (!this['featuresNativeTextTracks']) {
|
||||
if (!this.featuresNativeTextTracks) {
|
||||
this.emulateTextTracks();
|
||||
}
|
||||
|
||||
@@ -68,20 +71,6 @@ class Tech extends Component {
|
||||
* any controls will still keep the user active
|
||||
*/
|
||||
initControlsListeners() {
|
||||
let player = this.player();
|
||||
|
||||
let activateControls = function(){
|
||||
if (player.controls() && !player.usingNativeControls()) {
|
||||
this.addControlsListeners();
|
||||
}
|
||||
};
|
||||
|
||||
// Set up event listeners once the tech is ready and has an element to apply
|
||||
// listeners to
|
||||
this.ready(activateControls);
|
||||
this.on(player, 'controlsenabled', activateControls);
|
||||
this.on(player, 'controlsdisabled', this.removeControlsListeners);
|
||||
|
||||
// if we're loading the playback object after it has started loading or playing the
|
||||
// video (often with autoplay on) then the loadstart event has already fired and we
|
||||
// need to fire it manually because many things rely on it.
|
||||
@@ -89,95 +78,18 @@ class Tech extends Component {
|
||||
// that may also have fired.
|
||||
this.ready(function(){
|
||||
if (this.networkState && this.networkState() > 0) {
|
||||
this.player().trigger('loadstart');
|
||||
this.trigger('loadstart');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addControlsListeners() {
|
||||
let userWasActive;
|
||||
|
||||
// Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
|
||||
// trigger mousedown/up.
|
||||
// http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
|
||||
// Any touch events are set to block the mousedown event from happening
|
||||
this.on('mousedown', this.handleClick);
|
||||
|
||||
// If the controls were hidden we don't want that to change without a tap event
|
||||
// so we'll check if the controls were already showing before reporting user
|
||||
// activity
|
||||
this.on('touchstart', function(event) {
|
||||
userWasActive = this.player_.userActive();
|
||||
});
|
||||
|
||||
this.on('touchmove', function(event) {
|
||||
if (userWasActive){
|
||||
this.player().reportUserActivity();
|
||||
}
|
||||
});
|
||||
|
||||
this.on('touchend', function(event) {
|
||||
// Stop the mouse events from also happening
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
// Turn on component tap events
|
||||
this.emitTapEvents();
|
||||
|
||||
// The tap listener needs to come after the touchend listener because the tap
|
||||
// listener cancels out any reportedUserActivity when setting userActive(false)
|
||||
this.on('tap', this.handleTap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the listeners used for click and tap controls. This is needed for
|
||||
* toggling to controls disabled, where a tap/touch should do nothing.
|
||||
*/
|
||||
removeControlsListeners() {
|
||||
// We don't want to just use `this.off()` because there might be other needed
|
||||
// listeners added by techs that extend this.
|
||||
this.off('tap');
|
||||
this.off('touchstart');
|
||||
this.off('touchmove');
|
||||
this.off('touchleave');
|
||||
this.off('touchcancel');
|
||||
this.off('touchend');
|
||||
this.off('click');
|
||||
this.off('mousedown');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a click on the media element. By default will play/pause the media.
|
||||
*/
|
||||
handleClick(event) {
|
||||
// We're using mousedown to detect clicks thanks to Flash, but mousedown
|
||||
// will also be triggered with right-clicks, so we need to prevent that
|
||||
if (event.button !== 0) return;
|
||||
|
||||
// When controls are disabled a click should not toggle playback because
|
||||
// the click is considered a control
|
||||
if (this.player().controls()) {
|
||||
if (this.player().paused()) {
|
||||
this.player().play();
|
||||
} else {
|
||||
this.player().pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a tap on the media element. By default it will toggle the user
|
||||
* activity state, which hides and shows the controls.
|
||||
*/
|
||||
handleTap() {
|
||||
this.player().userActive(!this.player().userActive());
|
||||
}
|
||||
|
||||
/* Fallbacks for unsupported event types
|
||||
================================================================================ */
|
||||
// Manually trigger progress events based on changes to the buffered amount
|
||||
// Many flash players and older HTML5 browsers don't send progress or progress-like events
|
||||
manualProgressOn() {
|
||||
this.on('durationchange', this.onDurationChange);
|
||||
|
||||
this.manualProgress = true;
|
||||
|
||||
// Trigger progress watching when a source begins loading
|
||||
@@ -187,16 +99,18 @@ class Tech extends Component {
|
||||
manualProgressOff() {
|
||||
this.manualProgress = false;
|
||||
this.stopTrackingProgress();
|
||||
|
||||
this.off('durationchange', this.onDurationChange);
|
||||
}
|
||||
|
||||
trackProgress() {
|
||||
this.progressInterval = this.setInterval(function(){
|
||||
this.progressInterval = this.setInterval(Lib.bind(this, function(){
|
||||
// Don't trigger unless buffered amount is greater than last time
|
||||
|
||||
let bufferedPercent = this.player().bufferedPercent();
|
||||
let bufferedPercent = this.bufferedPercent();
|
||||
|
||||
if (this.bufferedPercent_ != bufferedPercent) {
|
||||
this.player().trigger('progress');
|
||||
if (this.bufferedPercent_ !== bufferedPercent) {
|
||||
this.trigger('progress');
|
||||
}
|
||||
|
||||
this.bufferedPercent_ = bufferedPercent;
|
||||
@@ -204,7 +118,40 @@ class Tech extends Component {
|
||||
if (bufferedPercent === 1) {
|
||||
this.stopTrackingProgress();
|
||||
}
|
||||
}, 500);
|
||||
}), 500);
|
||||
}
|
||||
|
||||
onDurationChange() {
|
||||
this.duration_ = this.duration();
|
||||
}
|
||||
|
||||
bufferedPercent() {
|
||||
let bufferedDuration = 0,
|
||||
start, end;
|
||||
|
||||
if (!this.duration_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let buffered = this.buffered();
|
||||
|
||||
if (!buffered || !buffered.length) {
|
||||
buffered = Lib.createTimeRange(0,0);
|
||||
}
|
||||
|
||||
for (var i=0; i<buffered.length; i++){
|
||||
start = buffered.start(i);
|
||||
end = buffered.end(i);
|
||||
|
||||
// buffered end can be bigger than duration by a very small fraction
|
||||
if (end > this.duration_) {
|
||||
end = this.duration_;
|
||||
}
|
||||
|
||||
bufferedDuration += end - start;
|
||||
}
|
||||
|
||||
return bufferedDuration / this.duration_;
|
||||
}
|
||||
|
||||
stopTrackingProgress() {
|
||||
@@ -213,36 +160,38 @@ class Tech extends Component {
|
||||
|
||||
/*! Time Tracking -------------------------------------------------------------- */
|
||||
manualTimeUpdatesOn() {
|
||||
let player = this.player_;
|
||||
|
||||
this.manualTimeUpdates = true;
|
||||
|
||||
this.on(player, 'play', this.trackCurrentTime);
|
||||
this.on(player, 'pause', this.stopTrackingCurrentTime);
|
||||
this.on('play', this.trackCurrentTime);
|
||||
this.on('pause', this.stopTrackingCurrentTime);
|
||||
// timeupdate is also called by .currentTime whenever current time is set
|
||||
|
||||
// Watch for native timeupdate event
|
||||
this.one('timeupdate', function(){
|
||||
// Watch for native timeupdate event only
|
||||
var onTimeUpdate = function(e){
|
||||
if (e.manuallyTriggered) return;
|
||||
|
||||
this.off('timeupdate', onTimeUpdate);
|
||||
|
||||
// Update known progress support for this playback technology
|
||||
this['featuresTimeupdateEvents'] = true;
|
||||
this.featuresTimeupdateEvents = true;
|
||||
// Turn off manual progress tracking
|
||||
this.manualTimeUpdatesOff();
|
||||
});
|
||||
};
|
||||
|
||||
this.on('timeupdate', onTimeUpdate);
|
||||
}
|
||||
|
||||
manualTimeUpdatesOff() {
|
||||
let player = this.player_;
|
||||
|
||||
this.manualTimeUpdates = false;
|
||||
this.stopTrackingCurrentTime();
|
||||
this.off(player, 'play', this.trackCurrentTime);
|
||||
this.off(player, 'pause', this.stopTrackingCurrentTime);
|
||||
this.off('play', this.trackCurrentTime);
|
||||
this.off('pause', this.stopTrackingCurrentTime);
|
||||
}
|
||||
|
||||
trackCurrentTime() {
|
||||
if (this.currentTimeInterval) { this.stopTrackingCurrentTime(); }
|
||||
this.currentTimeInterval = this.setInterval(function(){
|
||||
this.player().trigger('timeupdate');
|
||||
this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
|
||||
}, 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
|
||||
}
|
||||
|
||||
@@ -252,7 +201,7 @@ class Tech extends Component {
|
||||
|
||||
// #1002 - if the video ends right before the next timeupdate would happen,
|
||||
// the progress bar won't make it all the way to the end
|
||||
this.player().trigger('timeupdate');
|
||||
this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
|
||||
}
|
||||
|
||||
dispose() {
|
||||
@@ -266,21 +215,13 @@ class Tech extends Component {
|
||||
|
||||
setCurrentTime() {
|
||||
// improve the accuracy of manual timeupdates
|
||||
if (this.manualTimeUpdates) { this.player().trigger('timeupdate'); }
|
||||
if (this.manualTimeUpdates) { this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); }
|
||||
}
|
||||
|
||||
// TODO: Consider looking at moving this into the text track display directly
|
||||
// https://github.com/videojs/video.js/issues/1863
|
||||
initTextTrackListeners() {
|
||||
let player = this.player_;
|
||||
|
||||
let textTrackListChanges = function() {
|
||||
let textTrackDisplay = player.getChild('textTrackDisplay');
|
||||
|
||||
if (textTrackDisplay) {
|
||||
textTrackDisplay.updateDisplay();
|
||||
}
|
||||
};
|
||||
let textTrackListChanges = Lib.bind(this, function() {
|
||||
this.trigger('texttrackchange');
|
||||
});
|
||||
|
||||
let tracks = this.textTracks();
|
||||
|
||||
@@ -296,12 +237,10 @@ class Tech extends Component {
|
||||
}
|
||||
|
||||
emulateTextTracks() {
|
||||
let player = this.player_;
|
||||
|
||||
if (!window['WebVTT']) {
|
||||
if (!window['WebVTT'] && this.el().parentNode != null) {
|
||||
let script = document.createElement('script');
|
||||
script.src = player.options()['vtt.js'] || '../node_modules/vtt.js/dist/vtt.js';
|
||||
player.el().appendChild(script);
|
||||
script.src = this.options_['vtt.js'] || '../node_modules/vtt.js/dist/vtt.js';
|
||||
this.el().parentNode.appendChild(script);
|
||||
window['WebVTT'] = true;
|
||||
}
|
||||
|
||||
@@ -311,15 +250,17 @@ class Tech extends Component {
|
||||
}
|
||||
|
||||
let textTracksChanges = function() {
|
||||
let textTrackDisplay = player.getChild('textTrackDisplay');
|
||||
let updateDisplay = Lib.bind(this, function() {
|
||||
this.trigger('texttrackchange');
|
||||
});
|
||||
|
||||
textTrackDisplay.updateDisplay();
|
||||
this.trigger('texttrackchange');
|
||||
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
let track = this[i];
|
||||
track.removeEventListener('cuechange', Lib.bind(textTrackDisplay, textTrackDisplay.updateDisplay));
|
||||
track.removeEventListener('cuechange', updateDisplay);
|
||||
if (track.mode === 'showing') {
|
||||
track.addEventListener('cuechange', Lib.bind(textTrackDisplay, textTrackDisplay.updateDisplay));
|
||||
track.addEventListener('cuechange', updateDisplay);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -338,13 +279,13 @@ class Tech extends Component {
|
||||
*/
|
||||
|
||||
textTracks() {
|
||||
this.player_.textTracks_ = this.player_.textTracks_ || new TextTrackList();
|
||||
return this.player_.textTracks_;
|
||||
this.textTracks_ = this.textTracks_ || new TextTrackList();
|
||||
return this.textTracks_;
|
||||
}
|
||||
|
||||
remoteTextTracks() {
|
||||
this.player_.remoteTextTracks_ = this.player_.remoteTextTracks_ || new TextTrackList();
|
||||
return this.player_.remoteTextTracks_;
|
||||
this.remoteTextTracks_ = this.remoteTextTracks_ || new TextTrackList();
|
||||
return this.remoteTextTracks_;
|
||||
}
|
||||
|
||||
addTextTrack(kind, label, language) {
|
||||
@@ -356,7 +297,7 @@ class Tech extends Component {
|
||||
}
|
||||
|
||||
addRemoteTextTrack(options) {
|
||||
let track = createTrackHelper(this, options['kind'], options['label'], options['language'], options);
|
||||
let track = createTrackHelper(this, options.kind, options.label, options.language, options);
|
||||
this.remoteTextTracks().addTrack_(track);
|
||||
return {
|
||||
track: track
|
||||
@@ -388,14 +329,15 @@ Tech.prototype.textTracks_;
|
||||
var createTrackHelper = function(self, kind, label, language, options={}) {
|
||||
let tracks = self.textTracks();
|
||||
|
||||
options['kind'] = kind;
|
||||
options.kind = kind;
|
||||
|
||||
if (label) {
|
||||
options['label'] = label;
|
||||
options.label = label;
|
||||
}
|
||||
if (language) {
|
||||
options['language'] = language;
|
||||
options.language = language;
|
||||
}
|
||||
options['player'] = self.player_;
|
||||
options.tech = self;
|
||||
|
||||
let track = new TextTrack(options);
|
||||
tracks.addTrack_(track);
|
||||
@@ -403,18 +345,18 @@ var createTrackHelper = function(self, kind, label, language, options={}) {
|
||||
return track;
|
||||
};
|
||||
|
||||
Tech.prototype['featuresVolumeControl'] = true;
|
||||
Tech.prototype.featuresVolumeControl = true;
|
||||
|
||||
// Resizing plugins using request fullscreen reloads the plugin
|
||||
Tech.prototype['featuresFullscreenResize'] = false;
|
||||
Tech.prototype['featuresPlaybackRate'] = false;
|
||||
Tech.prototype.featuresFullscreenResize = false;
|
||||
Tech.prototype.featuresPlaybackRate = false;
|
||||
|
||||
// Optional events that we can manually mimic with timers
|
||||
// currently not triggered by video-js-swf
|
||||
Tech.prototype['featuresProgressEvents'] = false;
|
||||
Tech.prototype['featuresTimeupdateEvents'] = false;
|
||||
Tech.prototype.featuresProgressEvents = false;
|
||||
Tech.prototype.featuresTimeupdateEvents = false;
|
||||
|
||||
Tech.prototype['featuresNativeTextTracks'] = false;
|
||||
Tech.prototype.featuresNativeTextTracks = false;
|
||||
|
||||
/**
|
||||
* A functional mixin for techs that want to use the Source Handler pattern.
|
||||
|
||||
@@ -32,6 +32,7 @@ class TextTrackDisplay extends Component {
|
||||
super(player, options, ready);
|
||||
|
||||
player.on('loadstart', Lib.bind(this, this.toggleDisplay));
|
||||
player.on('texttrackchange', Lib.bind(this, this.toggleDisplay));
|
||||
|
||||
// This used to be called during player init, but was causing an error
|
||||
// if a track should show by default and the display hadn't loaded yet.
|
||||
|
||||
@@ -29,8 +29,8 @@ import XHR from '../xhr.js';
|
||||
* };
|
||||
*/
|
||||
let TextTrack = function(options={}) {
|
||||
if (!options['player']) {
|
||||
throw new Error('A player was not provided.');
|
||||
if (!options.tech) {
|
||||
throw new Error('A tech was not provided.');
|
||||
}
|
||||
|
||||
let tt = this;
|
||||
@@ -42,7 +42,7 @@ let TextTrack = function(options={}) {
|
||||
}
|
||||
}
|
||||
|
||||
tt.player_ = options['player'];
|
||||
tt.tech_ = options.tech;
|
||||
|
||||
let mode = TextTrackEnum.TextTrackMode[options['mode']] || 'disabled';
|
||||
let kind = TextTrackEnum.TextTrackKind[options['kind']] || 'subtitles';
|
||||
@@ -69,7 +69,7 @@ let TextTrack = function(options={}) {
|
||||
}
|
||||
});
|
||||
if (mode !== 'disabled') {
|
||||
tt.player_.on('timeupdate', timeupdateHandler);
|
||||
tt.tech_.on('timeupdate', timeupdateHandler);
|
||||
}
|
||||
|
||||
Object.defineProperty(tt, 'kind', {
|
||||
@@ -110,7 +110,7 @@ let TextTrack = function(options={}) {
|
||||
}
|
||||
mode = newMode;
|
||||
if (mode === 'showing') {
|
||||
this.player_.on('timeupdate', timeupdateHandler);
|
||||
this.tech_.on('timeupdate', timeupdateHandler);
|
||||
}
|
||||
this.trigger('modechange');
|
||||
}
|
||||
@@ -137,7 +137,7 @@ let TextTrack = function(options={}) {
|
||||
return activeCues; // nothing to do
|
||||
}
|
||||
|
||||
let ct = this.player_.currentTime();
|
||||
let ct = this.tech_.currentTime();
|
||||
let active = [];
|
||||
|
||||
for (let i = 0, l = this['cues'].length; i < l; i++) {
|
||||
@@ -191,7 +191,7 @@ TextTrack.prototype.allowedEvents_ = {
|
||||
};
|
||||
|
||||
TextTrack.prototype.addCue = function(cue) {
|
||||
let tracks = this.player_.textTracks();
|
||||
let tracks = this.tech_.textTracks();
|
||||
|
||||
if (tracks) {
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import * as Util from './util.js';
|
||||
import Player from './player';
|
||||
import extendsFn from './extends.js';
|
||||
import plugin from './plugins.js';
|
||||
import options from './options.js';
|
||||
|
||||
if (typeof HTMLVideoElement === 'undefined') {
|
||||
document.createElement('video');
|
||||
@@ -42,6 +43,11 @@ videojs.players = Player.players;
|
||||
|
||||
videojs.extends = extendsFn;
|
||||
|
||||
videojs.getGlobalOptions = () => options;
|
||||
videojs.setGlobalOptions = function(newOptions) {
|
||||
Lib.util.mergeOptions(options, newOptions);
|
||||
};
|
||||
|
||||
videojs.plugin = plugin;
|
||||
|
||||
// REMOVING: We probably should not include this in 5.0 thought it would make it
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ var xhr = function(options, callback){
|
||||
|
||||
// XMLHTTPRequest
|
||||
} else {
|
||||
const fileUrl = (urlInfo.protocol == 'file:' || winLoc.protocol == 'file:');
|
||||
const fileUrl = (urlInfo.protocol === 'file:' || winLoc.protocol === 'file:');
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState === 4) {
|
||||
|
||||
@@ -92,6 +92,8 @@ module.exports = function(config) {
|
||||
|
||||
captureTimeout: 60000,
|
||||
|
||||
browserNoActivityTimeout: 60000,
|
||||
|
||||
sauceLabs: {
|
||||
startConnect: true,
|
||||
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
|
||||
|
||||
@@ -146,8 +146,13 @@ test('ready triggering before and after disposing the tech', function() {
|
||||
fixtureDiv.appendChild(playerDiv);
|
||||
|
||||
techEl.id = 'foo1234';
|
||||
|
||||
techEl.tech = {
|
||||
el() { return techEl; }
|
||||
};
|
||||
|
||||
playerDiv['player'] = {
|
||||
tech: {}
|
||||
tech: techEl.tech
|
||||
};
|
||||
|
||||
Flash['onReady'](techEl.id);
|
||||
|
||||
@@ -24,7 +24,7 @@ q.module('HTML5', {
|
||||
addChild: function(){},
|
||||
trigger: function(){}
|
||||
};
|
||||
tech = new Html5(player, {});
|
||||
tech = new Html5({});
|
||||
},
|
||||
'teardown': function() {
|
||||
tech.dispose();
|
||||
@@ -51,13 +51,6 @@ test('should detect whether the volume can be changed', function(){
|
||||
Lib.TEST_VID = testVid;
|
||||
});
|
||||
|
||||
test('should re-link the player if the tech is moved', function(){
|
||||
Html5.movingMediaElementInDOM = false;
|
||||
tech.createEl();
|
||||
|
||||
strictEqual(player, tech.el()['player']);
|
||||
});
|
||||
|
||||
test('test playbackRate', function() {
|
||||
var playbackRate;
|
||||
|
||||
|
||||
+24
-80
@@ -26,48 +26,28 @@ q.module('Media Tech', {
|
||||
});
|
||||
|
||||
test('should synthesize timeupdate events by default', function() {
|
||||
var timeupdates = 0, playHandler, i, tech;
|
||||
tech = new Tech({
|
||||
id: this.noop,
|
||||
on: function(event, handler) {
|
||||
if (event === 'play') {
|
||||
playHandler = handler;
|
||||
}
|
||||
},
|
||||
trigger: function(event) {
|
||||
if (event === 'timeupdate') {
|
||||
timeupdates++;
|
||||
}
|
||||
}
|
||||
});
|
||||
playHandler.call(tech);
|
||||
var timeupdates = 0, tech;
|
||||
|
||||
tech = new Tech();
|
||||
tech.on('timeupdate', function() {
|
||||
timeupdates++;
|
||||
});
|
||||
|
||||
tech.trigger('play');
|
||||
|
||||
this.clock.tick(250);
|
||||
equal(timeupdates, 1, 'triggered one timeupdate');
|
||||
equal(timeupdates, 1, 'triggered at least one timeupdate');
|
||||
});
|
||||
|
||||
test('stops timeupdates if the tech produces them natively', function() {
|
||||
var timeupdates = 0, tech, playHandler, expected;
|
||||
tech = new Tech({
|
||||
id: this.noop,
|
||||
off: this.noop,
|
||||
on: function(event, handler) {
|
||||
if (event === 'play') {
|
||||
playHandler = handler;
|
||||
}
|
||||
},
|
||||
bufferedPercent: this.noop,
|
||||
trigger: function(event) {
|
||||
if (event === 'timeupdate') {
|
||||
timeupdates++;
|
||||
}
|
||||
}
|
||||
var timeupdates = 0, tech, expected;
|
||||
tech = new Tech();
|
||||
tech.on('timeupdate', function() {
|
||||
timeupdates++;
|
||||
});
|
||||
|
||||
playHandler.call(tech);
|
||||
tech.trigger('play');
|
||||
|
||||
// simulate a native timeupdate event
|
||||
tech.trigger('timeupdate');
|
||||
|
||||
@@ -77,51 +57,29 @@ test('stops timeupdates if the tech produces them natively', function() {
|
||||
});
|
||||
|
||||
test('stops manual timeupdates while paused', function() {
|
||||
var timeupdates = 0, tech, playHandler, pauseHandler, expected;
|
||||
tech = new Tech({
|
||||
id: this.noop,
|
||||
on: function(event, handler) {
|
||||
if (event === 'play') {
|
||||
playHandler = handler;
|
||||
} else if (event === 'pause') {
|
||||
pauseHandler = handler;
|
||||
}
|
||||
},
|
||||
bufferedPercent: this.noop,
|
||||
trigger: function(event) {
|
||||
if (event === 'timeupdate') {
|
||||
timeupdates++;
|
||||
}
|
||||
}
|
||||
var timeupdates = 0, tech, expected;
|
||||
tech = new Tech();
|
||||
tech.on('timeupdate', function() {
|
||||
timeupdates++;
|
||||
});
|
||||
playHandler.call(tech);
|
||||
|
||||
tech.trigger('play');
|
||||
this.clock.tick(10 * 250);
|
||||
ok(timeupdates > 0, 'timeupdates fire during playback');
|
||||
|
||||
pauseHandler.call(tech);
|
||||
tech.trigger('pause');
|
||||
timeupdates = 0;
|
||||
this.clock.tick(10 * 250);
|
||||
equal(timeupdates, 0, 'timeupdates do not fire when paused');
|
||||
|
||||
playHandler.call(tech);
|
||||
tech.trigger('play');
|
||||
this.clock.tick(10 * 250);
|
||||
ok(timeupdates > 0, 'timeupdates fire when playback resumes');
|
||||
});
|
||||
|
||||
test('should synthesize progress events by default', function() {
|
||||
var progresses = 0, tech;
|
||||
tech = new Tech({
|
||||
id: this.noop,
|
||||
on: this.noop,
|
||||
bufferedPercent: function() {
|
||||
return 0;
|
||||
},
|
||||
trigger: function(event) {
|
||||
if (event === 'progress') {
|
||||
progresses++;
|
||||
}
|
||||
}
|
||||
});
|
||||
tech = new Tech();
|
||||
tech.on('progress', function() {
|
||||
progresses++;
|
||||
});
|
||||
@@ -131,12 +89,7 @@ test('should synthesize progress events by default', function() {
|
||||
});
|
||||
|
||||
test('dispose() should stop time tracking', function() {
|
||||
var tech = new Tech({
|
||||
id: this.noop,
|
||||
on: this.noop,
|
||||
off: this.noop,
|
||||
trigger: this.noop
|
||||
});
|
||||
var tech = new Tech();
|
||||
tech.dispose();
|
||||
|
||||
// progress and timeupdate events will throw exceptions after the
|
||||
@@ -150,10 +103,6 @@ test('dispose() should stop time tracking', function() {
|
||||
});
|
||||
|
||||
test('should add the source hanlder interface to a tech', function(){
|
||||
var mockPlayer = {
|
||||
off: this.noop,
|
||||
trigger: this.noop
|
||||
};
|
||||
var sourceA = { src: 'foo.mp4', type: 'video/mp4' };
|
||||
var sourceB = { src: 'no-support', type: 'no-support' };
|
||||
|
||||
@@ -168,7 +117,7 @@ test('should add the source hanlder interface to a tech', function(){
|
||||
ok(MyTech.selectSourceHandler, 'added a selectSourceHandler function to the Tech');
|
||||
|
||||
// Create an instance of Tech
|
||||
var tech = new MyTech(mockPlayer);
|
||||
var tech = new MyTech();
|
||||
|
||||
// Check for the expected instance methods
|
||||
ok(tech.setSource, 'added a setSource function to the tech instance');
|
||||
@@ -233,17 +182,12 @@ test('should add the source hanlder interface to a tech', function(){
|
||||
});
|
||||
|
||||
test('should handle unsupported sources with the source hanlder API', function(){
|
||||
var mockPlayer = {
|
||||
off: this.noop,
|
||||
trigger: this.noop
|
||||
};
|
||||
|
||||
// Define a new tech class
|
||||
var MyTech = Tech.extend();
|
||||
// Extend Tech with source handlers
|
||||
Tech.withSourceHandlers(MyTech);
|
||||
// Create an instance of Tech
|
||||
var tech = new MyTech(mockPlayer);
|
||||
var tech = new MyTech();
|
||||
|
||||
var usedNative;
|
||||
MyTech.nativeSourceHandler = {
|
||||
|
||||
@@ -10,8 +10,8 @@ import Component from '../../src/js/component.js';
|
||||
*/
|
||||
class MediaFaker extends Tech {
|
||||
|
||||
constructor(player, options, handleReady){
|
||||
super(player, options, handleReady);
|
||||
constructor(options, handleReady){
|
||||
super(options, handleReady);
|
||||
this.triggerReady();
|
||||
}
|
||||
|
||||
@@ -20,12 +20,10 @@ class MediaFaker extends Tech {
|
||||
className: 'vjs-tech'
|
||||
});
|
||||
|
||||
if (this.player().poster()) {
|
||||
/*if (this.player().poster()) {
|
||||
// transfer the poster image to mimic HTML
|
||||
el.poster = this.player().poster();
|
||||
}
|
||||
|
||||
Lib.insertFirst(el, this.player_.el());
|
||||
}*/
|
||||
|
||||
return el;
|
||||
}
|
||||
@@ -34,6 +32,8 @@ class MediaFaker extends Tech {
|
||||
poster() { return this.el().poster; }
|
||||
setPoster(val) { this.el().poster = val; }
|
||||
|
||||
setControls(val) {}
|
||||
|
||||
currentTime() { return 0; }
|
||||
seeking() { return false; }
|
||||
src() { return 'movie.mp4'; }
|
||||
@@ -41,7 +41,7 @@ class MediaFaker extends Tech {
|
||||
muted() { return false; }
|
||||
pause() { return false; }
|
||||
paused() { return true; }
|
||||
play() { this.player().trigger('play'); }
|
||||
play() { this.trigger('play'); }
|
||||
supportsFullScreen() { return false; }
|
||||
buffered() { return {}; }
|
||||
duration() { return {}; }
|
||||
|
||||
+34
-36
@@ -233,7 +233,7 @@ test('should hide the poster when play is called', function() {
|
||||
player.play();
|
||||
equal(player.hasStarted(), true, 'the show poster flag is false after play');
|
||||
|
||||
player.trigger('loadstart');
|
||||
player.tech.trigger('loadstart');
|
||||
equal(player.hasStarted(),
|
||||
false,
|
||||
'the resource selection algorithm sets the show poster flag to true');
|
||||
@@ -278,7 +278,7 @@ test('should be able to initialize player twice on the same tag using string ref
|
||||
});
|
||||
|
||||
test('should set controls and trigger events', function() {
|
||||
expect(6);
|
||||
//expect(6);
|
||||
|
||||
var player = TestHelpers.makePlayer({ 'controls': false });
|
||||
ok(player.controls() === false, 'controls set through options');
|
||||
@@ -297,9 +297,9 @@ test('should set controls and trigger events', function() {
|
||||
ok(true, 'disabled fired once');
|
||||
});
|
||||
player.controls(false);
|
||||
player.controls(true);
|
||||
//player.controls(true);
|
||||
// Check for unnecessary events
|
||||
player.controls(true);
|
||||
//player.controls(true);
|
||||
|
||||
player.dispose();
|
||||
});
|
||||
@@ -441,10 +441,10 @@ test('should not add multiple first play events despite subsequent loads', funct
|
||||
ok(true, 'First play should fire once.');
|
||||
});
|
||||
|
||||
// Checking to make sure handleLoadStart removes first play listener before adding a new one.
|
||||
player.trigger('loadstart');
|
||||
player.trigger('loadstart');
|
||||
player.trigger('play');
|
||||
// Checking to make sure onLoadStart removes first play listener before adding a new one.
|
||||
player.tech.trigger('loadstart');
|
||||
player.tech.trigger('loadstart');
|
||||
player.tech.trigger('play');
|
||||
});
|
||||
|
||||
test('should fire firstplay after resetting the player', function() {
|
||||
@@ -456,14 +456,14 @@ test('should fire firstplay after resetting the player', function() {
|
||||
});
|
||||
|
||||
// init firstplay listeners
|
||||
player.trigger('loadstart');
|
||||
player.trigger('play');
|
||||
player.tech.trigger('loadstart');
|
||||
player.tech.trigger('play');
|
||||
ok(fpFired, 'First firstplay fired');
|
||||
|
||||
// reset the player
|
||||
player.trigger('loadstart');
|
||||
player.tech.trigger('loadstart');
|
||||
fpFired = false;
|
||||
player.trigger('play');
|
||||
player.tech.trigger('play');
|
||||
ok(fpFired, 'Second firstplay fired');
|
||||
|
||||
// the play event can fire before the loadstart event.
|
||||
@@ -471,8 +471,8 @@ test('should fire firstplay after resetting the player', function() {
|
||||
player.tech.paused = function(){ return false; };
|
||||
fpFired = false;
|
||||
// reset the player
|
||||
player.trigger('loadstart');
|
||||
// player.trigger('play');
|
||||
player.tech.trigger('loadstart');
|
||||
// player.tech.trigger('play');
|
||||
ok(fpFired, 'Third firstplay fired');
|
||||
});
|
||||
|
||||
@@ -481,14 +481,14 @@ test('should remove vjs-has-started class', function(){
|
||||
|
||||
var player = TestHelpers.makePlayer({});
|
||||
|
||||
player.trigger('loadstart');
|
||||
player.trigger('play');
|
||||
player.tech.trigger('loadstart');
|
||||
player.tech.trigger('play');
|
||||
ok(player.el().className.indexOf('vjs-has-started') !== -1, 'vjs-has-started class added');
|
||||
|
||||
player.trigger('loadstart');
|
||||
player.tech.trigger('loadstart');
|
||||
ok(player.el().className.indexOf('vjs-has-started') === -1, 'vjs-has-started class removed');
|
||||
|
||||
player.trigger('play');
|
||||
player.tech.trigger('play');
|
||||
ok(player.el().className.indexOf('vjs-has-started') !== -1, 'vjs-has-started class added again');
|
||||
});
|
||||
|
||||
@@ -497,18 +497,18 @@ test('should add and remove vjs-ended class', function() {
|
||||
|
||||
var player = TestHelpers.makePlayer({});
|
||||
|
||||
player.trigger('loadstart');
|
||||
player.trigger('play');
|
||||
player.trigger('ended');
|
||||
player.tech.trigger('loadstart');
|
||||
player.tech.trigger('play');
|
||||
player.tech.trigger('ended');
|
||||
ok(player.el().className.indexOf('vjs-ended') !== -1, 'vjs-ended class added');
|
||||
|
||||
player.trigger('play');
|
||||
player.tech.trigger('play');
|
||||
ok(player.el().className.indexOf('vjs-ended') === -1, 'vjs-ended class removed');
|
||||
|
||||
player.trigger('ended');
|
||||
player.tech.trigger('ended');
|
||||
ok(player.el().className.indexOf('vjs-ended') !== -1, 'vjs-ended class re-added');
|
||||
|
||||
player.trigger('loadstart');
|
||||
player.tech.trigger('loadstart');
|
||||
ok(player.el().className.indexOf('vjs-ended') === -1, 'vjs-ended class removed');
|
||||
});
|
||||
|
||||
@@ -576,20 +576,18 @@ test('Data attributes on the video element should persist in the new wrapper ele
|
||||
});
|
||||
|
||||
test('should restore attributes from the original video tag when creating a new element', function(){
|
||||
var player, html5Mock, el;
|
||||
|
||||
player = TestHelpers.makePlayer();
|
||||
html5Mock = { player_: player };
|
||||
var tag, html5Mock, el;
|
||||
|
||||
// simulate attributes stored from the original tag
|
||||
player.tagAttributes = {
|
||||
'preload': 'auto',
|
||||
'autoplay': true,
|
||||
'webkit-playsinline': true
|
||||
};
|
||||
tag = Lib.createEl('video');
|
||||
tag.setAttribute('preload', 'auto');
|
||||
tag.setAttribute('autoplay', '');
|
||||
tag.setAttribute('webkit-playsinline', '');
|
||||
|
||||
html5Mock = { options_: { tag: tag } };
|
||||
|
||||
// set options that should override tag attributes
|
||||
player.options_['preload'] = 'none';
|
||||
html5Mock.options_.preload = 'none';
|
||||
|
||||
// create the element
|
||||
el = Html5.prototype.createEl.call(html5Mock);
|
||||
@@ -677,7 +675,7 @@ test('pause is called when player ended event is fired and player is not paused'
|
||||
player.pause = function() {
|
||||
pauses++;
|
||||
};
|
||||
player.trigger('ended');
|
||||
player.tech.trigger('ended');
|
||||
equal(pauses, 1, 'pause was called');
|
||||
});
|
||||
|
||||
@@ -691,7 +689,7 @@ test('pause is not called if the player is paused and ended is fired', function(
|
||||
player.pause = function() {
|
||||
pauses++;
|
||||
};
|
||||
player.trigger('ended');
|
||||
player.tech.trigger('ended');
|
||||
equal(pauses, 0, 'pause was not called when ended fired');
|
||||
});
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ test('trigger "change" event when "modechange" is fired on a track', function()
|
||||
|
||||
test('trigger "change" event when mode changes on a TextTracl', function() {
|
||||
var tt = new TextTrack({
|
||||
player: {
|
||||
tech: {
|
||||
on: noop
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -3,7 +3,7 @@ import window from 'global/window';
|
||||
import TestHelpers from '../test-helpers.js';
|
||||
|
||||
var noop = Function.prototype;
|
||||
var defaultPlayer = {
|
||||
var defaultTech = {
|
||||
textTracks: noop,
|
||||
on: noop,
|
||||
off: noop,
|
||||
@@ -12,12 +12,12 @@ var defaultPlayer = {
|
||||
|
||||
q.module('Text Track');
|
||||
|
||||
test('text-track requires a player', function() {
|
||||
test('text-track requires a tech', function() {
|
||||
window.throws(function() {
|
||||
new TextTrack();
|
||||
},
|
||||
new Error('A player was not provided.'),
|
||||
'a player is required for text track');
|
||||
new Error('A tech was not provided.'),
|
||||
'a tech is required for text track');
|
||||
});
|
||||
|
||||
test('can create a TextTrack with various properties', function() {
|
||||
@@ -27,7 +27,7 @@ test('can create a TextTrack with various properties', function() {
|
||||
id = '1',
|
||||
mode = 'disabled',
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
kind: kind,
|
||||
label: label,
|
||||
language: language,
|
||||
@@ -44,7 +44,7 @@ test('can create a TextTrack with various properties', function() {
|
||||
|
||||
test('defaults when items not provided', function() {
|
||||
var tt = new TextTrack({
|
||||
player: defaultPlayer
|
||||
tech: defaultTech
|
||||
});
|
||||
|
||||
equal(tt.kind, 'subtitles', 'kind defaulted to subtitles');
|
||||
@@ -55,7 +55,7 @@ test('defaults when items not provided', function() {
|
||||
|
||||
test('kind can only be one of several options, defaults to subtitles', function() {
|
||||
var tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
kind: 'foo'
|
||||
});
|
||||
|
||||
@@ -63,35 +63,35 @@ test('kind can only be one of several options, defaults to subtitles', function(
|
||||
notEqual(tt.kind, 'foo', 'the kind is set to subtitles, not foo');
|
||||
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
kind: 'subtitles'
|
||||
});
|
||||
|
||||
equal(tt.kind, 'subtitles', 'the kind is set to subtitles');
|
||||
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
kind: 'captions'
|
||||
});
|
||||
|
||||
equal(tt.kind, 'captions', 'the kind is set to captions');
|
||||
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
kind: 'descriptions'
|
||||
});
|
||||
|
||||
equal(tt.kind, 'descriptions', 'the kind is set to descriptions');
|
||||
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
kind: 'chapters'
|
||||
});
|
||||
|
||||
equal(tt.kind, 'chapters', 'the kind is set to chapters');
|
||||
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
kind: 'metadata'
|
||||
});
|
||||
|
||||
@@ -100,7 +100,7 @@ test('kind can only be one of several options, defaults to subtitles', function(
|
||||
|
||||
test('mode can only be one of several options, defaults to disabled', function() {
|
||||
var tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
mode: 'foo'
|
||||
});
|
||||
|
||||
@@ -108,21 +108,21 @@ test('mode can only be one of several options, defaults to disabled', function()
|
||||
notEqual(tt.mode, 'foo', 'the mode is set to disabld, not foo');
|
||||
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
mode: 'disabled'
|
||||
});
|
||||
|
||||
equal(tt.mode, 'disabled', 'the mode is set to disabled');
|
||||
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
mode: 'hidden'
|
||||
});
|
||||
|
||||
equal(tt.mode, 'hidden', 'the mode is set to hidden');
|
||||
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
mode: 'showing'
|
||||
});
|
||||
|
||||
@@ -136,7 +136,7 @@ test('kind, label, language, id, cue, and activeCues are read only', function()
|
||||
id = '1',
|
||||
mode = 'disabled',
|
||||
tt = new TextTrack({
|
||||
player: defaultPlayer,
|
||||
tech: defaultTech,
|
||||
kind: kind,
|
||||
label: label,
|
||||
language: language,
|
||||
@@ -161,7 +161,7 @@ test('kind, label, language, id, cue, and activeCues are read only', function()
|
||||
|
||||
test('mode can only be set to a few options', function() {
|
||||
var tt = new TextTrack({
|
||||
player: defaultPlayer
|
||||
tech: defaultTech,
|
||||
});
|
||||
|
||||
tt.mode = 'foo';
|
||||
@@ -186,7 +186,7 @@ test('mode can only be set to a few options', function() {
|
||||
|
||||
test('cues and activeCues return a TextTrackCueList', function() {
|
||||
var tt = new TextTrack({
|
||||
player: defaultPlayer
|
||||
tech: defaultTech,
|
||||
});
|
||||
|
||||
ok(tt.cues.getCueById, 'cues are a TextTrackCueList');
|
||||
@@ -195,7 +195,7 @@ test('cues and activeCues return a TextTrackCueList', function() {
|
||||
|
||||
test('cues can be added and removed from a TextTrack', function() {
|
||||
var tt = new TextTrack({
|
||||
player: defaultPlayer
|
||||
tech: defaultTech,
|
||||
}),
|
||||
cues;
|
||||
|
||||
@@ -224,7 +224,7 @@ test('fires cuechange when cues become active and inactive', function() {
|
||||
changes = 0,
|
||||
cuechangeHandler,
|
||||
tt = new TextTrack({
|
||||
player: player,
|
||||
tech: player.tech,
|
||||
mode: 'showing'
|
||||
});
|
||||
|
||||
@@ -241,19 +241,19 @@ test('fires cuechange when cues become active and inactive', function() {
|
||||
tt.oncuechange = cuechangeHandler;
|
||||
tt.addEventListener('cuechange', cuechangeHandler);
|
||||
|
||||
player.currentTime = function() {
|
||||
player.tech.currentTime = function() {
|
||||
return 2;
|
||||
};
|
||||
|
||||
player.trigger('timeupdate');
|
||||
player.tech.trigger('timeupdate');
|
||||
|
||||
equal(changes, 2, 'a cuechange event trigger addEventListener and oncuechange');
|
||||
|
||||
player.currentTime = function() {
|
||||
player.tech.currentTime = function() {
|
||||
return 7;
|
||||
};
|
||||
|
||||
player.trigger('timeupdate');
|
||||
player.tech.trigger('timeupdate');
|
||||
|
||||
equal(changes, 4, 'a cuechange event trigger addEventListener and oncuechange');
|
||||
});
|
||||
|
||||
@@ -119,7 +119,7 @@ test('listen to remove and add track events in native text tracks', function() {
|
||||
player.player_ = player;
|
||||
player.options_ = options = {};
|
||||
|
||||
html = new Html5(player, options);
|
||||
html = new Html5(options);
|
||||
|
||||
ok(events['removetrack'], 'removetrack listener was added');
|
||||
ok(events['addtrack'], 'addtrack listener was added');
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário