Embed rework
103
CMakeLists.txt
|
@ -370,22 +370,19 @@ add_executable(MistOutHTTP
|
||||||
src/output/output_http.cpp
|
src/output/output_http.cpp
|
||||||
src/output/output_http_internal.cpp
|
src/output/output_http_internal.cpp
|
||||||
src/io.cpp
|
src/io.cpp
|
||||||
generated/silverlight.js.h
|
generated/player.js.h
|
||||||
generated/embed.js.h
|
|
||||||
generated/html5.js.h
|
generated/html5.js.h
|
||||||
generated/flash_strobe.js.h
|
generated/flash_strobe.js.h
|
||||||
generated/theoplayer.js.h
|
|
||||||
generated/jwplayer.js.h
|
|
||||||
generated/polytrope.js.h
|
|
||||||
generated/dashjs.js.h
|
generated/dashjs.js.h
|
||||||
generated/videojs.js.h
|
generated/videojs.js.h
|
||||||
generated/img.js.h
|
generated/webrtc.js.h
|
||||||
generated/playerdash.js.h
|
generated/player_dash.js.h
|
||||||
generated/playerdashlic.js.h
|
generated/player_dash_lic.js.h
|
||||||
generated/playervideo.js.h
|
generated/player_video.js.h
|
||||||
generated/playerhlsvideo.js.h
|
generated/player_webrtc.js.h
|
||||||
generated/core.js.h
|
generated/skin_default.css.h
|
||||||
generated/mist.css.h
|
generated/skin_dev.css.h
|
||||||
|
generated/skin_videojs.css.h
|
||||||
)
|
)
|
||||||
set_target_properties(MistOutHTTP
|
set_target_properties(MistOutHTTP
|
||||||
PROPERTIES COMPILE_DEFINITIONS "OUTPUTTYPE=\"output_http_internal.h\""
|
PROPERTIES COMPILE_DEFINITIONS "OUTPUTTYPE=\"output_http_internal.h\""
|
||||||
|
@ -445,69 +442,61 @@ endif()
|
||||||
########################################
|
########################################
|
||||||
# Embed Code #
|
# Embed Code #
|
||||||
########################################
|
########################################
|
||||||
add_custom_command(OUTPUT generated/silverlight.js.h
|
# main
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/silverlight.js silverlight_js generated/silverlight.js.h
|
add_custom_command(OUTPUT generated/player.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/silverlight.js
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/min/player.js player_js generated/player.js.h
|
||||||
)
|
DEPENDS sourcery ${SOURCE_DIR}/embed/min/player.js
|
||||||
add_custom_command(OUTPUT generated/embed.js.h
|
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/src/embed.js embed_js generated/embed.js.h
|
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/src/embed.js
|
|
||||||
)
|
)
|
||||||
|
# wrappers
|
||||||
add_custom_command(OUTPUT generated/html5.js.h
|
add_custom_command(OUTPUT generated/html5.js.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/html5.js html5_js generated/html5.js.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/min/wrappers/html5.js html5_js generated/html5.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/html5.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/min/wrappers/html5.js
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/flash_strobe.js.h
|
add_custom_command(OUTPUT generated/flash_strobe.js.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/flash_strobe.js flash_strobe_js generated/flash_strobe.js.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/min/wrappers/flash_strobe.js flash_strobe_js generated/flash_strobe.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/flash_strobe.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/min/wrappers/flash_strobe.js
|
||||||
)
|
|
||||||
add_custom_command(OUTPUT generated/theoplayer.js.h
|
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/theoplayer.js theoplayer_js generated/theoplayer.js.h
|
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/theoplayer.js
|
|
||||||
)
|
|
||||||
add_custom_command(OUTPUT generated/jwplayer.js.h
|
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/jwplayer.js jwplayer_js generated/jwplayer.js.h
|
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/jwplayer.js
|
|
||||||
)
|
|
||||||
add_custom_command(OUTPUT generated/polytrope.js.h
|
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/polytrope.js polytrope_js generated/polytrope.js.h
|
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/polytrope.js
|
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/dashjs.js.h
|
add_custom_command(OUTPUT generated/dashjs.js.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/dashjs.js dash_js generated/dashjs.js.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/min/wrappers/dashjs.js dash_js generated/dashjs.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/dashjs.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/min/wrappers/dashjs.js
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/videojs.js.h
|
add_custom_command(OUTPUT generated/videojs.js.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/videojs.js video_js generated/videojs.js.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/min/wrappers/videojs.js video_js generated/videojs.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/videojs.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/min/wrappers/videojs.js
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/img.js.h
|
add_custom_command(OUTPUT generated/webrtc.js.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/wrappers/img.js img_js generated/img.js.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/min/wrappers/webrtc.js webrtc_js generated/webrtc.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/wrappers/img.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/min/wrappers/webrtc.js
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/playerdashlic.js.h
|
# players
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/players/dash.js.license.js playerdashlic_js generated/playerdashlic.js.h
|
add_custom_command(OUTPUT generated/player_dash_lic.js.h
|
||||||
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/players/dash.js.license.js player_dash_lic_js generated/player_dash_lic.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/players/dash.js.license.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/players/dash.js.license.js
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/playerdash.js.h
|
add_custom_command(OUTPUT generated/player_dash.js.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/players/dash.all.min.js playerdash_js generated/playerdash.js.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/players/dash.all.min.js player_dash_js generated/player_dash.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/players/dash.all.min.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/players/dash.all.min.js
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/playervideo.js.h
|
add_custom_command(OUTPUT generated/player_video.js.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/players/video.min.js playervideo_js generated/playervideo.js.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/players/video.min.js player_video_js generated/player_video.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/players/video.min.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/players/video.min.js
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/playerhlsvideo.js.h
|
add_custom_command(OUTPUT generated/player_webrtc.js.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/players/videojs-contrib-hls.min.js playerhlsvideo_js generated/playerhlsvideo.js.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/players/webrtc.js player_webrtc_js generated/player_webrtc.js.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/players/videojs-contrib-hls.min.js
|
DEPENDS sourcery ${SOURCE_DIR}/embed/players/webrtc.js
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/core.js.h
|
# css
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/core.js core_js generated/core.js.h
|
add_custom_command(OUTPUT generated/skin_default.css.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/core.js
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/min/skins/default.css skin_default_css generated/skin_default.css.h
|
||||||
|
DEPENDS sourcery ${SOURCE_DIR}/embed/min/skins/default.css
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT generated/mist.css.h
|
add_custom_command(OUTPUT generated/skin_dev.css.h
|
||||||
COMMAND ./sourcery ${SOURCE_DIR}/embed/mist.css mist_css generated/mist.css.h
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/min/skins/dev.css skin_dev_css generated/skin_dev.css.h
|
||||||
DEPENDS sourcery ${SOURCE_DIR}/embed/mist.css
|
DEPENDS sourcery ${SOURCE_DIR}/embed/min/skins/dev.css
|
||||||
|
)
|
||||||
|
add_custom_command(OUTPUT generated/skin_videojs.css.h
|
||||||
|
COMMAND ./sourcery ${SOURCE_DIR}/embed/skins/video-js.css skin_videojs_css generated/skin_videojs.css.h
|
||||||
|
DEPENDS sourcery ${SOURCE_DIR}/embed/skins/video-js.css
|
||||||
)
|
)
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
|
|
122
embed/controls.js
vendored
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
function MistUI(MistVideo,structure) {
|
||||||
|
MistVideo.UI = this;
|
||||||
|
this.elements = [];
|
||||||
|
|
||||||
|
this.buildStructure = function(structure){
|
||||||
|
if (typeof structure == "function") { structure = structure.call(MistVideo); }
|
||||||
|
|
||||||
|
if ("if" in structure) {
|
||||||
|
var result = false;
|
||||||
|
if (structure.if.call(MistVideo,structure)) {
|
||||||
|
result = structure.then;
|
||||||
|
}
|
||||||
|
else if ("else" in structure) {
|
||||||
|
result = structure.else;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) { return; }
|
||||||
|
|
||||||
|
//append the result with structure options
|
||||||
|
for (var i in structure) {
|
||||||
|
if (["if","then","else"].indexOf(i) < 0) {
|
||||||
|
if (i in result) {
|
||||||
|
if (!(result[i] instanceof Array)) {
|
||||||
|
result[i] = [result[i]];
|
||||||
|
}
|
||||||
|
result[i] = result[i].concat(structure[i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result[i] = structure[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.buildStructure(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("type" in structure) {
|
||||||
|
if (structure.type in MistVideo.skin.blueprints) {
|
||||||
|
|
||||||
|
//create the element; making sure to pass "this" to blueprint function
|
||||||
|
var container = MistVideo.skin.blueprints[structure.type].call(MistVideo,structure);
|
||||||
|
if (!container) { return; }
|
||||||
|
MistUtil.class.add(container,"mistvideo-"+structure.type);
|
||||||
|
|
||||||
|
if ("css" in structure) {
|
||||||
|
var uid = MistUtil.createUnique();
|
||||||
|
structure.css = [].concat(structure.css); //convert to array; should be in string format with colors already applied
|
||||||
|
|
||||||
|
for (var i in structure.css) {
|
||||||
|
var style = MistUtil.css.createStyle(structure.css[i],uid);
|
||||||
|
container.appendChild(style);
|
||||||
|
}
|
||||||
|
MistUtil.class.add(container,uid);
|
||||||
|
container.uid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("classes" in structure) {
|
||||||
|
for (var i in structure.classes) {
|
||||||
|
MistUtil.class.add(container,structure.classes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("title" in structure) {
|
||||||
|
container.title = structure.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("style" in structure) {
|
||||||
|
for (var i in structure.style) {
|
||||||
|
container.style[i] = structure.style[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("children" in structure) {
|
||||||
|
for (var i in structure.children) {
|
||||||
|
var child = this.buildStructure(structure.children[i]);
|
||||||
|
if (child) {
|
||||||
|
container.appendChild(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//save the returned element so they can be killed on unload
|
||||||
|
MistVideo.UI.elements.push(container);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
this.build = function(){
|
||||||
|
return this.buildStructure(structure ? structure : MistVideo.skin.structure.main);
|
||||||
|
};
|
||||||
|
|
||||||
|
var container = this.build();
|
||||||
|
|
||||||
|
//apply skin CSS
|
||||||
|
var uid = MistUtil.createUnique();
|
||||||
|
var toload = MistVideo.skin.css.length;
|
||||||
|
if (toload) { container.style.opacity = "0"; }
|
||||||
|
for (var i in MistVideo.skin.css) {
|
||||||
|
var style = MistVideo.skin.css[i];
|
||||||
|
style.callback = function(css) {
|
||||||
|
this.textContent = MistUtil.css.prependClass(css,uid,true);
|
||||||
|
toload--;
|
||||||
|
if (toload <= 0) {
|
||||||
|
container.style.opacity = "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (style.textContent != "") {
|
||||||
|
//it has already loaded
|
||||||
|
style.callback(style.textContent);
|
||||||
|
}
|
||||||
|
container.appendChild(style);
|
||||||
|
}
|
||||||
|
MistUtil.class.add(container,uid);
|
||||||
|
|
||||||
|
//add browser class
|
||||||
|
var browser = MistUtil.getBrowser();
|
||||||
|
if (browser) {
|
||||||
|
MistUtil.class.add(container,"browser-"+browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
1501
embed/core.js
|
@ -1 +1,13 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg3937" height="45" width="45"><defs id="defs3939" /><metadata id="metadata3942"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><g transform="translate(0,-1007.3622)" id="layer1"><g transform="translate(0,-1.109375)" id="g4563"><g id="g4558"><path id="rect3945" transform="translate(0,1007.3622)" d="M 5.15625,10 C 3.6913461,10 2.5,11.191346 2.5,12.65625 l 0,19.6875 C 2.5,33.808654 3.6913461,35 5.15625,35 l 34.6875,0 C 41.308654,35 42.5,33.808654 42.5,32.34375 l 0,-19.6875 C 42.5,11.191346 41.308654,10 39.84375,10 L 5.15625,10 z M 5,12.53125 l 35,0 0,20 -35,0 0,-20 z" style="fill:#fff;fill-opacity:1;stroke:none" /><rect ry="0" y="1019.8622" x="5" height="20" width="35" id="rect3947" style="fill:#fff;fill-opacity:0.39215686;stroke:none" /><path id="path3949" transform="translate(0,1007.3622)" d="m 18.78125,35.40625 c -1.53661,0.379809 -2.971465,0.991557 -4.28125,1.8125 l 15.65625,0 c -1.313005,-0.822961 -2.762825,-1.432953 -4.3125,-1.8125 l -7.0625,0 z" style="fill:#fff;fill-opacity:1;stroke:none" /></g><g id="g4007" transform="matrix(2.0353985,0,0,1.1630828,-99.321734,-141.54581)" style="fill:#000"><path id="rect3958" d="m 65.533646,1001.4758 -2.032932,0 0.662913,0.6629 -2.253903,2.2539 0.707107,0.7071 2.253903,-2.2539 0.662912,0.6629 0,-2.0329 z" style="fill:#fff;fill-opacity:1;stroke:none" /><path id="rect3958-5" d="m 65.533646,1012.84 0,-2.033 -0.662836,0.6629 -2.253901,-2.2539 -0.707104,0.7071 2.253902,2.2539 -0.662906,0.6629 2.032845,1e-4 z" style="fill:#fff;fill-opacity:1;stroke:none" /><path id="rect3958-51" d="m 54.16943,1001.4758 2.032932,0 -0.662913,0.6629 2.253903,2.2539 -0.707107,0.7071 -2.253903,-2.2539 -0.662912,0.6629 0,-2.0329 z" style="fill:#fff;fill-opacity:1;stroke:none" /><path id="rect3958-5-7" d="m 54.16943,1012.84 0,-2.033 0.662836,0.6629 2.253901,-2.2539 0.707104,0.7071 -2.253902,2.2539 0.662906,0.6629 -2.032845,1e-4 z" style="fill:#fff;fill-opacity:1;stroke:none" /></g></g></g></svg>
|
<svg width="45" height="45" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="#fff">
|
||||||
|
<path d="m5.1562 8.8906c-1.4649 0-2.6562 1.1913-2.6562 2.6562v19.688c0 1.4649 1.1913 2.6562 2.6562 2.6562h34.688c1.4649 0 2.6562-1.1913 2.6562-2.6562v-19.688c0-1.4649-1.1913-2.6562-2.6562-2.6562h-34.688m-0.15625 2.5312h35v20h-35v-20"/>
|
||||||
|
<rect transform="translate(0 -1008.5)" x="5" y="1019.9" width="35" height="20" ry="0" fill-opacity=".39216"/>
|
||||||
|
<path d="m18.781 34.297c-1.5366 0.37981-2.9715 0.99156-4.2812 1.8125h15.656c-1.313-0.82296-2.7628-1.433-4.3125-1.8125h-7.0625"/>
|
||||||
|
<g>
|
||||||
|
<path d="m34.065 14.782h-4.1378l1.3493 0.77101-4.5876 2.6215 1.4392 0.82242 4.5876-2.6215s1.3493 0.77101 1.3493 0.77101v-2.3644"/>
|
||||||
|
<path d="m34.065 27.999v-2.3645s-1.3491 0.77101-1.3491 0.77101l-4.5876-2.6215-1.4392 0.82242 4.5876 2.6215-1.3493 0.77101 4.1376 1.1631e-4"/>
|
||||||
|
<path d="m10.935 14.782h4.1378l-1.3493 0.77101 4.5876 2.6215-1.4392 0.82242-4.5876-2.6215s-1.3493 0.77101-1.3493 0.77101v-2.3644"/>
|
||||||
|
<path d="m10.935 27.999v-2.3645s1.3491 0.77101 1.3491 0.77101l4.5876-2.6215s1.4392 0.82242 1.4392 0.82242l-4.5876 2.6215 1.3493 0.77101-4.1376 1.1631e-4"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.2 KiB |
3
embed/imgs/fullscreen_plain_.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="45" height="45" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m2.5 10.928v8.5898l4.9023-2.8008 9.6172 5.7832-9.6172 5.7832-4.9023-2.8008v8.5898h15.031l-4.9004-2.8008 9.8691-5.6387 9.8691 5.6387-4.9004 2.8008h15.031v-8.5898l-4.9023 2.8008-9.6172-5.7832 9.6172-5.7832 4.9023 2.8008v-8.5898h-15.033l4.9023 2.8008-9.8691 5.6387-9.8691-5.6387 4.9023-2.8008z" fill="#fff"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 402 B |
61
embed/imgs/gear.svg
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4659"
|
||||||
|
height="45"
|
||||||
|
width="45"
|
||||||
|
sodipodi:docname="gear.svg"
|
||||||
|
inkscape:version="0.92.2 5c3e80d, 2017-08-06">
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#4cc5a0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1868"
|
||||||
|
inkscape:window-height="1049"
|
||||||
|
id="namedview8"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:zoom="6.675088"
|
||||||
|
inkscape:cx="62.439695"
|
||||||
|
inkscape:cy="43.399157"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg4659"
|
||||||
|
inkscape:snap-page="true" />
|
||||||
|
<defs
|
||||||
|
id="defs4661" />
|
||||||
|
<metadata
|
||||||
|
id="metadata4664">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<path
|
||||||
|
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.50001693;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
d="m 24.139007,3.834512 -1.477875,4.3213185 c -1.101822,0.0088 -2.274313,0.1330197 -3.204775,0.3369163 L 17.128868,4.5441522 C 15.631516,4.9971895 14.196746,5.635837 12.858006,6.4452068 l 1.34441,4.3668912 c -0.878085,0.62225 -1.683392,1.341293 -2.400733,2.14357 L 7.6056909,11.132739 c -0.9476032,1.24558 -1.7355288,2.604902 -2.3453935,4.046251 l 3.6523686,2.739277 c -0.3489484,1.021477 -0.5815406,2.079062 -0.6933641,3.15269 L 3.7661466,22.05892 c -0.00716,0.146959 -0.012582,0.293997 -0.016276,0.441084 0.00628,1.417863 0.173364,2.830439 0.4980503,4.21064 l 4.5703436,0.06998 c 0.3217092,1.027112 0.7579402,2.014774 1.3004645,2.944356 l -3.0387575,3.435896 c 0.8950189,1.282782 1.947035,2.448529 3.1315315,3.470075 l 3.735377,-2.628599 c 0.86307,0.64582 1.796153,1.192348 2.781594,1.629243 l -0.436201,4.539419 c 1.475447,0.52082 3.010282,0.854908 4.568716,0.994474 l 1.477875,-4.321319 c 0.05369,0.003 0.107408,0.0057 0.161134,0.0082 1.023951,-0.0061 2.044309,-0.121786 3.043641,-0.345054 l 2.327489,3.948594 c 1.497352,-0.453037 2.932122,-1.091685 4.270862,-1.901055 l -1.34441,-4.366891 c 0.878085,-0.622249 1.683392,-1.341292 2.400733,-2.14357 l 4.195992,1.82293 c 0.947603,-1.245581 1.735529,-2.604903 2.345394,-4.046252 l -3.652368,-2.739276 c 0.348948,-1.021478 0.58154,-2.079063 0.693363,-3.152691 l 4.453156,-0.987963 c 0.0072,-0.146984 0.01258,-0.294022 0.01628,-0.441108 -0.0062,-1.417863 -0.173364,-2.83044 -0.49805,-4.210641 l -4.570344,-0.06998 c -0.321709,-1.027116 -0.75794,-2.014777 -1.300465,-2.94436 l 3.038754,-3.435928 C 37.025006,10.556342 35.97299,9.3905941 34.788493,8.3690481 L 31.053116,10.997647 C 30.190046,10.351826 29.256963,9.8052988 28.271521,9.3684038 L 28.707723,4.8289849 C 27.232276,4.308166 25.697441,3.9740781 24.139007,3.834512 Z"
|
||||||
|
id="path4541"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccc" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
3
embed/imgs/gear_plain.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="45" height="45" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m24.139 3.834-1.4785 4.3223c-1.1018 0.0088-2.2727 0.13204-3.2031 0.33594l-2.3281-3.9473c-1.4974 0.45304-2.9327 1.091-4.2715 1.9004l1.3457 4.3672c-0.87808 0.62225-1.685 1.3403-2.4023 2.1426l-4.1953-1.8223c-0.9476 1.2456-1.7358 2.6055-2.3457 4.0469l3.6523 2.7383c-0.34895 1.0215-0.58154 2.0787-0.69336 3.1523l-4.4531 0.98828c-0.00716 0.14696-0.011931 0.29432-0.015625 0.44141 0.00628 1.4179 0.17336 2.8307 0.49805 4.2109l4.5703 0.070312c0.32171 1.0271 0.75826 2.0138 1.3008 2.9434l-3.0391 3.4355c0.89502 1.2828 1.9464 2.4492 3.1309 3.4707l3.7363-2.6289c0.86307 0.64582 1.7958 1.192 2.7812 1.6289l-0.43555 4.541c1.4754 0.52082 3.0099 0.85458 4.5684 0.99414l1.4766-4.3223c0.05369 3e-3 0.10838 0.005313 0.16211 0.007812 1.024-0.0061 2.0436-0.12048 3.043-0.34375l2.3281 3.9473c1.4974-0.45304 2.9327-1.091 4.2715-1.9004l-1.3457-4.3672c0.87808-0.62225 1.685-1.3403 2.4023-2.1426l4.1953 1.8223c0.9476-1.2456 1.7358-2.6055 2.3457-4.0469l-3.6523-2.7383c0.34895-1.0215 0.58154-2.0787 0.69336-3.1523l4.4531-0.98828c0.0072-0.14698 0.011925-0.29432 0.015625-0.44141-0.0062-1.4179-0.17336-2.8307-0.49805-4.2109l-4.5703-0.070312c-0.32171-1.0271-0.75826-2.0138-1.3008-2.9434l3.0391-3.4355c-0.89502-1.2828-1.9464-2.4492-3.1309-3.4707l-3.7363 2.6289c-0.86307-0.64582-1.7958-1.192-2.7812-1.6289l0.43555-4.541c-1.4754-0.52082-3.0099-0.85457-4.5684-0.99414zm-1.6387 7.8789a10.786 10.786 0 0 1 10.787 10.787 10.786 10.786 0 0 1-10.787 10.787 10.786 10.786 0 0 1-10.787-10.787 10.786 10.786 0 0 1 10.787-10.787z" fill="#fff"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
embed/imgs/loading.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="100%" width="100%"><path d="m49.998 8.7797e-4c-0.060547 0.0018431-0.12109 0.0037961-0.18164 0.0058593-0.1251 0.0015881-0.25012 0.0061465-0.375 0.013672h-0.001954c-27.388 0.30599-49.432 22.59-49.439 49.98 0.020074 2.6488 0.25061 5.292 0.68945 7.904 3.8792-24.231 24.77-42.065 49.311-42.096v-0.0058582h0.001954c4.3638 3.0803e-4 7.9013-3.5366 7.9021-7.9002 1.474e-4 -2.0958-0.83235-4.106-2.3144-5.5879-1.482-1.482-3.492-2.3145-5.5879-2.3144-6.5007e-4 -7.9369e-8 -0.0013001-7.9369e-8 -0.001954 0" class="semiFill"/></svg>
|
After Width: | Height: | Size: 580 B |
|
@ -11,8 +11,9 @@
|
||||||
id="svg3937"
|
id="svg3937"
|
||||||
height="45"
|
height="45"
|
||||||
width="45"
|
width="45"
|
||||||
inkscape:version="0.91 r13725"
|
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||||
sodipodi:docname="loop.svg">
|
sodipodi:docname="loop.svg"
|
||||||
|
viewBox="0 0 45 45">
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
pagecolor="#8bff39"
|
pagecolor="#8bff39"
|
||||||
bordercolor="#666666"
|
bordercolor="#666666"
|
||||||
|
@ -22,8 +23,8 @@
|
||||||
guidetolerance="10"
|
guidetolerance="10"
|
||||||
inkscape:pageopacity="1"
|
inkscape:pageopacity="1"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:window-width="1920"
|
inkscape:window-width="1868"
|
||||||
inkscape:window-height="1055"
|
inkscape:window-height="1049"
|
||||||
id="namedview3591"
|
id="namedview3591"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
showguides="true"
|
showguides="true"
|
||||||
|
@ -40,37 +41,17 @@
|
||||||
inkscape:snap-smooth-nodes="true"
|
inkscape:snap-smooth-nodes="true"
|
||||||
inkscape:snap-midpoints="true"
|
inkscape:snap-midpoints="true"
|
||||||
inkscape:zoom="14.833529"
|
inkscape:zoom="14.833529"
|
||||||
inkscape:cx="30.216329"
|
inkscape:cx="21.722684"
|
||||||
inkscape:cy="21.135445"
|
inkscape:cy="25.7616"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="0"
|
inkscape:window-y="0"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="svg3937">
|
inkscape:current-layer="svg3937"
|
||||||
<sodipodi:guide
|
fit-margin-top="0"
|
||||||
position="0,0"
|
fit-margin-left="0"
|
||||||
orientation="0,45"
|
fit-margin-right="0"
|
||||||
id="guide3615" />
|
fit-margin-bottom="0"
|
||||||
<sodipodi:guide
|
scale-x="1" />
|
||||||
position="45,0"
|
|
||||||
orientation="-45,0"
|
|
||||||
id="guide3617" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="45,45"
|
|
||||||
orientation="0,-45"
|
|
||||||
id="guide3619" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="0,45"
|
|
||||||
orientation="45,0"
|
|
||||||
id="guide3621" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="0,0"
|
|
||||||
orientation="-0.70710678,0.70710678"
|
|
||||||
id="guide3624" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="0,45"
|
|
||||||
orientation="0.70710678,0.70710678"
|
|
||||||
id="guide4491" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<defs
|
<defs
|
||||||
id="defs3939" />
|
id="defs3939" />
|
||||||
<metadata
|
<metadata
|
||||||
|
@ -86,11 +67,8 @@
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
<path
|
<path
|
||||||
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
style="opacity:1;fill:none;fill-opacity:0.8584475;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.50002718;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
d="M 0 0 L 0 45 L 45 45 L 45 0 L 0 0 z M 22.5 11.25 A 11.25 11.25 0 0 1 33.75 22.5 A 11.25 11.25 0 0 1 22.5 33.75 A 11.25 11.25 0 0 1 14.550781 30.449219 L 12.714844 32.285156 L 12.714844 25.785156 L 19.214844 25.785156 L 17.376953 27.623047 A 7.25 7.25 0 0 0 22.5 29.75 A 7.25 7.25 0 0 0 29.75 22.5 A 7.25 7.25 0 0 0 22.5 15.25 A 7.25 7.25 0 0 0 17.376953 17.376953 L 14.550781 14.550781 A 11.25 11.25 0 0 1 22.5 11.25 z "
|
d="M 21.279283,3.749797 A 18.750203,18.750203 0 0 0 8.0304417,9.2511582 L 12.740779,13.961496 A 12.083464,12.083464 0 0 1 21.279283,10.416536 12.083464,12.083464 0 0 1 33.362748,22.5 12.083464,12.083464 0 0 1 21.279283,34.583464 12.083464,12.083464 0 0 1 12.740779,31.038504 l 3.063185,-3.063185 H 4.9705135 V 38.80877 L 8.0304417,35.748842 A 18.750203,18.750203 0 0 0 21.279283,41.250203 18.750203,18.750203 0 0 0 40.029486,22.5 18.750203,18.750203 0 0 0 21.279283,3.749797 Z"
|
||||||
id="rect4511" />
|
id="path4495"
|
||||||
<path
|
inkscape:connector-curvature="0" />
|
||||||
style="opacity:1;fill:none;fill-opacity:0.8584475;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="M 22.5 11.25 A 11.25 11.25 0 0 0 14.550781 14.550781 L 17.376953 17.376953 A 7.25 7.25 0 0 1 22.5 15.25 A 7.25 7.25 0 0 1 29.75 22.5 A 7.25 7.25 0 0 1 22.5 29.75 A 7.25 7.25 0 0 1 17.376953 27.623047 L 19.214844 25.785156 L 12.714844 25.785156 L 12.714844 32.285156 L 14.550781 30.449219 A 11.25 11.25 0 0 0 22.5 33.75 A 11.25 11.25 0 0 0 33.75 22.5 A 11.25 11.25 0 0 0 22.5 11.25 z "
|
|
||||||
id="path4495" />
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 2.8 KiB |
7
embed/imgs/muted_plain.svg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<svg width="45" height="45" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path class="stroke semiFill toggle" d="m25.587 5.2036c-1.8324-1.1012-4.2007-0.8622-5.7719 0.77112 0 0-7.7388 8.0444-7.7388 8.0444h-3.418c-1.9537 0-3.547 1.6562-3.547 3.6869v9.5864c0 2.0309 1.5933 3.6871 3.547 3.6871h3.418s7.7388 8.0447 7.7388 8.0447c1.5721 1.634 3.9389 1.8747 5.7719 0.77076v-34.591" fill="none" stroke="#000"/>
|
||||||
|
<g fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.4142">
|
||||||
|
<path d="m30.032 27.86 9.8517-9.8517"/>
|
||||||
|
<path d="m30.032 18.008 9.8517 9.8517"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 590 B |
|
@ -1 +1 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg2" height="45" width="45"><defs id="defs4" /><metadata id="metadata7"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><g transform="translate(0,-1007.3622)" id="layer1"><g style="fill:#fff" transform="translate(3.0304575,47.729705)" id="g3779"><path id="path3823-7" d="m 4.4695429,998.16377 a 4.0011916,4.0011916 0 0 0 3.749999,3.96873 l 2.2812501,0 a 4.0011916,4.0011916 0 0 0 3.96875,-3.75003 l 0,-32.28123 a 4.0011916,4.0011916 0 0 0 -3.75,-3.96875 l -2.2812501,0 a 4.0011916,4.0011916 0 0 0 -3.968749,3.75 l 0,32.28128 z" style="fill:#fff;fill-opacity:1;stroke:none" /><path id="path3823-7-4" d="m 24.469542,998.1638 a 4.0011916,4.0011916 0 0 0 3.75,3.9687 l 2.28125,0 a 4.0011916,4.0011916 0 0 0 3.96875,-3.75 l 0,-32.28126 a 4.0011916,4.0011916 0 0 0 -3.75,-3.96875 l -2.28125,0 a 4.0011916,4.0011916 0 0 0 -3.96875,3.75 l 0,32.28131 z" style="fill:#fff;fill-opacity:1;stroke:none" /></g></g></svg>
|
<svg width="25" height="25" version="1.1" viewBox="0 0 25 25" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.55556 0 0 .55556 0 -559.65)"><g transform="translate(3.0305 47.73)" fill="#fff"><path d="m4.4695 998.16a4.0012 4.0012 0 0 0 3.75 3.9687h2.2813a4.0012 4.0012 0 0 0 3.9688-3.75v-32.281a4.0012 4.0012 0 0 0-3.75-3.9688h-2.2813a4.0012 4.0012 0 0 0-3.9687 3.75z"/><path d="m24.47 998.16a4.0012 4.0012 0 0 0 3.75 3.9687h2.2812a4.0012 4.0012 0 0 0 3.9688-3.75v-32.281a4.0012 4.0012 0 0 0-3.75-3.9688h-2.2812a4.0012 4.0012 0 0 0-3.9688 3.75z"/></g></g></svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 569 B |
|
@ -13,10 +13,8 @@
|
||||||
height="45"
|
height="45"
|
||||||
id="svg2"
|
id="svg2"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
inkscape:version="0.48.4 r9939"
|
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||||
sodipodi:docname="New document 1">
|
sodipodi:docname="play.svg">
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
id="base"
|
id="base"
|
||||||
pagecolor="#000000"
|
pagecolor="#000000"
|
||||||
|
@ -39,28 +37,34 @@
|
||||||
inkscape:snap-page="true"
|
inkscape:snap-page="true"
|
||||||
inkscape:object-nodes="true"
|
inkscape:object-nodes="true"
|
||||||
inkscape:snap-nodes="false"
|
inkscape:snap-nodes="false"
|
||||||
inkscape:window-width="981"
|
inkscape:window-width="1868"
|
||||||
inkscape:window-height="709"
|
inkscape:window-height="1049"
|
||||||
inkscape:window-x="856"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="240"
|
inkscape:window-y="0"
|
||||||
inkscape:window-maximized="0">
|
inkscape:window-maximized="0">
|
||||||
<sodipodi:guide
|
<sodipodi:guide
|
||||||
position="0,0"
|
inkscape:locked="false"
|
||||||
|
id="guide3785"
|
||||||
orientation="0,45"
|
orientation="0,45"
|
||||||
id="guide3785" />
|
position="0,0" />
|
||||||
<sodipodi:guide
|
<sodipodi:guide
|
||||||
position="45,0"
|
inkscape:locked="false"
|
||||||
|
id="guide3787"
|
||||||
orientation="-45,0"
|
orientation="-45,0"
|
||||||
id="guide3787" />
|
position="45,0" />
|
||||||
<sodipodi:guide
|
<sodipodi:guide
|
||||||
position="45,45"
|
inkscape:locked="false"
|
||||||
|
id="guide3789"
|
||||||
orientation="0,-45"
|
orientation="0,-45"
|
||||||
id="guide3789" />
|
position="45,45" />
|
||||||
<sodipodi:guide
|
<sodipodi:guide
|
||||||
position="0,45"
|
inkscape:locked="false"
|
||||||
|
id="guide3791"
|
||||||
orientation="45,0"
|
orientation="45,0"
|
||||||
id="guide3791" />
|
position="0,45" />
|
||||||
</sodipodi:namedview>
|
</sodipodi:namedview>
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata7">
|
id="metadata7">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
|
@ -69,22 +73,17 @@
|
||||||
<dc:format>image/svg+xml</dc:format>
|
<dc:format>image/svg+xml</dc:format>
|
||||||
<dc:type
|
<dc:type
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
<dc:title></dc:title>
|
<dc:title />
|
||||||
</cc:Work>
|
</cc:Work>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
<g
|
<g
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
id="layer1"
|
||||||
transform="translate(0,-1007.3622)">
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1">
|
||||||
<path
|
<path
|
||||||
sodipodi:type="inkscape:offset"
|
d="M6.26004984594 3.0550109625C5.27445051914 3.68940862462 4.67905105702 4.78142391497 4.67968264562 5.95354422781C4.67968264562 5.95354422781 4.70004942312 39.0717540916 4.70004942312 39.0717540916C4.70302341604 40.3033886636 5.36331656075 41.439734231 6.43188211452 42.0521884912C7.50044766829 42.6646427515 8.81469531629 42.6600161659 9.87892235656 42.0400537716C9.87892235656 42.0400537716 38.5612768409 25.4802882606 38.5612768409 25.4802882606C39.6181165777 24.8606067582 40.2663250096 23.7262617523 40.2636734301 22.5011460995C40.2610218505 21.2760304467 39.6079092743 20.1445019555 38.5483970356 19.5294009803C38.5483970356 19.5294009803 9.84567577375 2.9709566275 9.84567577375 2.9709566275C8.72898008118 2.32550764609 7.34527425735 2.35794451351 6.26004984594 3.0550109625C6.26004984594 3.0550109625 6.26004984594 3.0550109625 6.26004984594 3.0550109625"
|
||||||
inkscape:radius="0"
|
|
||||||
inkscape:original="M 10.3125 -6.34375 A 2.9416186 2.9416186 0 0 0 7.90625 -4.875 L -6.21875 19.625 A 2.9416186 2.9416186 0 0 0 -3.65625 24.03125 L 24.625 24.03125 A 2.9416186 2.9416186 0 0 0 27.15625 19.625 L 13 -4.875 A 2.9416186 2.9416186 0 0 0 10.3125 -6.34375 z "
|
|
||||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
|
||||||
id="path3809"
|
id="path3809"
|
||||||
d="M 10.3125,-6.34375 A 2.9416186,2.9416186 0 0 0 7.90625,-4.875 l -14.125,24.5 a 2.9416186,2.9416186 0 0 0 2.5625,4.40625 l 28.28125,0 A 2.9416186,2.9416186 0 0 0 27.15625,19.625 L 13,-4.875 a 2.9416186,2.9416186 0 0 0 -2.6875,-1.46875 z"
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||||
transform="matrix(1.0141827,-0.58553867,0.58553867,1.0141827,-0.48419831,1022.8893)" />
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3.3 KiB |
3
embed/imgs/popout.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="45" height="45" version="1.1" viewBox="0 0 45 45" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m24.721 11.075c-12.96 0.049575-32.113 15.432-10.336 28.834-7.6763-7.9825-2.4795-21.824 10.336-22.19v5.5368l15.276-8.862-15.276-8.86v5.5419" fill="none" stroke="#000" stroke-width="1.4142"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 306 B |
|
@ -1,6 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
@ -9,49 +7,38 @@
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
id="svg4659"
|
|
||||||
version="1.1"
|
version="1.1"
|
||||||
inkscape:version="0.91 r13725"
|
id="svg4659"
|
||||||
sodipodi:docname="speaker.svg">
|
height="45"
|
||||||
<defs
|
width="45"
|
||||||
id="defs4661" />
|
sodipodi:docname="speaker.svg"
|
||||||
|
inkscape:version="0.92.2 5c3e80d, 2017-08-06">
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
id="base"
|
pagecolor="#4cc5a0"
|
||||||
pagecolor="#de43da"
|
|
||||||
bordercolor="#666666"
|
bordercolor="#666666"
|
||||||
borderopacity="1.0"
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
inkscape:pageopacity="0"
|
inkscape:pageopacity="0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="19.289873"
|
inkscape:window-width="1868"
|
||||||
inkscape:cx="-2.0603844"
|
inkscape:window-height="1049"
|
||||||
inkscape:cy="14.079113"
|
id="namedview8"
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:window-width="1918"
|
fit-margin-top="0"
|
||||||
inkscape:window-height="1040"
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:zoom="13.350176"
|
||||||
|
inkscape:cx="0.054475841"
|
||||||
|
inkscape:cy="20.133193"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="19"
|
inkscape:window-y="0"
|
||||||
inkscape:window-maximized="0">
|
inkscape:window-maximized="0"
|
||||||
<sodipodi:guide
|
inkscape:current-layer="svg4659" />
|
||||||
position="0,0"
|
<defs
|
||||||
orientation="0,25"
|
id="defs4661" />
|
||||||
id="guide4151" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="25,0"
|
|
||||||
orientation="-25,0"
|
|
||||||
id="guide4153" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="25,25"
|
|
||||||
orientation="0,-25"
|
|
||||||
id="guide4155" />
|
|
||||||
<sodipodi:guide
|
|
||||||
position="0,25"
|
|
||||||
orientation="25,0"
|
|
||||||
id="guide4157" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata4664">
|
id="metadata4664">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
|
@ -65,19 +52,18 @@
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
<g
|
<g
|
||||||
inkscape:label="Layer 1"
|
transform="matrix(1.8,0,0,1.8,0,-1849.252)"
|
||||||
inkscape:groupmode="layer"
|
id="layer1">
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
<path
|
||||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
id="rect4139"
|
||||||
d="M 0 0 L 0 25 L 25 25 L 25 0 L 0 0 z M 16.955078 2.5175781 C 17.381507 2.5360023 17.80574 2.6612 18.1875 2.890625 L 18.1875 22.109375 C 17.169206 22.722675 15.85386 22.587487 14.980469 21.679688 L 10.681641 17.210938 L 8.7832031 17.210938 C 7.6978331 17.210938 6.8125 16.290409 6.8125 15.162109 L 6.8125 9.8359375 C 6.8125 8.7077375 7.6978331 7.7890625 8.7832031 7.7890625 L 10.681641 7.7890625 L 14.980469 3.3183594 C 15.526019 2.7512344 16.244363 2.4868711 16.955078 2.5175781 z "
|
|
||||||
transform="translate(0,1027.3622)"
|
transform="translate(0,1027.3622)"
|
||||||
id="rect4139" />
|
d="M 0,0 V 25 H 25 V 0 Z M 16.955078,2.5175781 C 17.381507,2.5360023 17.80574,2.6612 18.1875,2.890625 v 19.21875 c -1.018294,0.6133 -2.33364,0.478112 -3.207031,-0.429687 l -4.298828,-4.46875 H 8.7832031 c -1.08537,0 -1.9707031,-0.920529 -1.9707031,-2.048829 V 9.8359375 c 0,-1.1282 0.8853331,-2.046875 1.9707031,-2.046875 h 1.8984379 l 4.298828,-4.4707031 c 0.54555,-0.567125 1.263894,-0.8314883 1.974609,-0.8007813 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
<path
|
<path
|
||||||
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 18.187674,1030.2531 c -1.018026,-0.6118 -2.333715,-0.479 -3.206595,0.4284 l -4.299344,4.4691 -1.8988757,0 c -1.0853708,0 -1.9705331,0.9201 -1.9705331,2.0483 l 0,5.3258 c 0,1.1283 0.8851623,2.0484 1.9705331,2.0484 l 1.8988757,0 4.299344,4.4693 c 0.873391,0.9078 2.188301,1.0415 3.206595,0.4282 l 0,-19.2175 z"
|
|
||||||
id="rect4574"
|
id="rect4574"
|
||||||
|
d="m 18.187674,1030.2531 c -1.018026,-0.6118 -2.333715,-0.479 -3.206595,0.4284 l -4.299344,4.4691 H 8.7828593 c -1.0853708,0 -1.9705331,0.9201 -1.9705331,2.0483 v 5.3258 c 0,1.1283 0.8851623,2.0484 1.9705331,2.0484 h 1.8988757 l 4.299344,4.4693 c 0.873391,0.9078 2.188301,1.0415 3.206595,0.4282 z"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
inkscape:connector-curvature="0" />
|
inkscape:connector-curvature="0" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.2 KiB |
59
embed/imgs/speaker_.svg
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4659"
|
||||||
|
height="45"
|
||||||
|
width="45"
|
||||||
|
sodipodi:docname="speaker_.svg"
|
||||||
|
inkscape:version="0.92.2 5c3e80d, 2017-08-06">
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#4cc5a0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1868"
|
||||||
|
inkscape:window-height="1049"
|
||||||
|
id="namedview8"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:zoom="6.675088"
|
||||||
|
inkscape:cx="-34.245466"
|
||||||
|
inkscape:cy="20.740429"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg4659" />
|
||||||
|
<defs
|
||||||
|
id="defs4661" />
|
||||||
|
<metadata
|
||||||
|
id="metadata4664">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:3.81837654;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 32.737813,5.2037363 c -1.832447,-1.10124 -4.200687,-0.8622 -5.771871,0.77112 0,0 -7.738819,8.0443797 -7.738819,8.0443797 0,0 -3.417976,0 -3.417976,0 -1.953668,0 -3.54696,1.65618 -3.54696,3.68694 0,0 0,9.58644 0,9.58644 0,2.03094 1.593292,3.68712 3.54696,3.68712 0,0 3.417976,0 3.417976,0 0,0 7.738819,8.04474 7.738819,8.04474 1.572104,1.63404 3.938942,1.8747 5.771871,0.77076 0,0 0,-34.5914997 0,-34.5914997 z"
|
||||||
|
id="rect4574-3" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -1 +1 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg4659" height="25" width="25"> <defs id="defs4661" /> <metadata id="metadata4664"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g transform="translate(0,-1027.3622)" id="layer1"> <path id="rect4139" transform="translate(0,1027.3622)" d="M 0 0 L 0 25 L 25 25 L 25 0 L 0 0 z M 16.955078 2.5175781 C 17.381507 2.5360023 17.80574 2.6612 18.1875 2.890625 L 18.1875 22.109375 C 17.169206 22.722675 15.85386 22.587487 14.980469 21.679688 L 10.681641 17.210938 L 8.7832031 17.210938 C 7.6978331 17.210938 6.8125 16.290409 6.8125 15.162109 L 6.8125 9.8359375 C 6.8125 8.7077375 7.6978331 7.7890625 8.7832031 7.7890625 L 10.681641 7.7890625 L 14.980469 3.3183594 C 15.526019 2.7512344 16.244363 2.4868711 16.955078 2.5175781 z " style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> <path id="rect4574" d="m 18.187674,1030.2531 c -1.018026,-0.6118 -2.333715,-0.479 -3.206595,0.4284 l -4.299344,4.4691 -1.8988757,0 c -1.0853708,0 -1.9705331,0.9201 -1.9705331,2.0483 l 0,5.3258 c 0,1.1283 0.8851623,2.0484 1.9705331,2.0484 l 1.8988757,0 4.299344,4.4693 c 0.873391,0.9078 2.188301,1.0415 3.206595,0.4282 l 0,-19.2175 z" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g></svg>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg4659" height="25" width="25"> <defs id="defs4661" /> <metadata id="metadata4664"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <path d="m 32.737813,5.2037363 c -1.832447,-1.10124 -4.200687,-0.8622 -5.771871,0.77112 0,0 -7.738819,8.0443797 -7.738819,8.0443797 0,0 -3.417976,0 -3.417976,0 -1.953668,0 -3.54696,1.65618 -3.54696,3.68694 0,0 0,9.58644 0,9.58644 0,2.03094 1.593292,3.68712 3.54696,3.68712 0,0 3.417976,0 3.417976,0 0,0 7.738819,8.04474 7.738819,8.04474 1.572104,1.63404 3.938942,1.8747 5.771871,0.77076 0,0 0,-34.5914997 0,-34.5914997 z" class="stroke semiFill toggle"></path></svg>
|
||||||
|
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1 KiB |
4
embed/imgs/switchvideo.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="45" height="45" version="1.1" viewBox="0 0 45 45" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m8.4925 18.786c-3.9578 1.504-6.4432 3.632-6.4434 5.9982 2.183e-4 4.1354 7.5562 7.5509 17.399 8.1467v4.7777l10.718-6.2573-10.718-6.2529v4.5717c-6.9764-0.4712-12.229-2.5226-12.227-4.9859 6.693e-4 -0.72127 0.45868-1.4051 1.2714-2.0267zm28.015 0v3.9715c0.81164 0.62126 1.2685 1.3059 1.2692 2.0267-0.0014 1.4217-1.791 2.75-4.8021 3.6968-2.0515 0.82484-0.93693 3.7696 1.2249 2.9659 5.3088-1.8593 8.7426-3.8616 8.7514-6.6627-1.26e-4 -2.3662-2.4856-4.4942-6.4434-5.9982z"/>
|
||||||
|
<rect x="10.166" y="7.7911" width="24.668" height="15.432" fill="none" stroke="#000" stroke-linecap="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 694 B |
19
embed/imgs/timeout.svg
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<svg width="25" height="25" version="1.1" viewBox="0 0 25 25" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<mask id="a">
|
||||||
|
<rect x="0" y="0" width="25" height="25" fill="#fff"/>
|
||||||
|
<rect x="-5" y="-5" width="17.5" height="35" fill="#000" transform="rotate(180,12.5,12.5)">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" from="0,12.5,12.5" to="180,12.5,12.5" dur="5" repeatCount="1"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="0" y="0" width="12.5" height="25" fill="#fff"/>
|
||||||
|
<rect x="-5" y="-5" width="17.5" height="35" fill="#000" transform="rotate(360,12.5,12.5)">
|
||||||
|
<animate attributeType="CSS" attributeName="opacity" from="0" to="1" dur="10" calcMode="discrete" repeatCount="1" />
|
||||||
|
<animateTransform attributeName="transform" type="rotate" from="180,12.5,12.5" to="360,12.5,12.5" begin="5" dur="5" repeatCount="1"/>
|
||||||
|
</rect>
|
||||||
|
<circle cx="12.5" cy="12.5" r="8" fill="#000"/>
|
||||||
|
</mask>
|
||||||
|
</defs>
|
||||||
|
<g mask="url(#a)">
|
||||||
|
<circle cx="12.5" cy="12.5" r="12.5" class="fill"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1 KiB |
|
@ -9,14 +9,25 @@
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="30"
|
width="65.000015"
|
||||||
height="65"
|
height="30"
|
||||||
id="svg3937"
|
id="svg3937"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
inkscape:version="0.91 r13725"
|
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||||
sodipodi:docname="volume.svg">
|
sodipodi:docname="volume.svg">
|
||||||
<defs
|
<defs
|
||||||
id="defs3939" />
|
id="defs3939">
|
||||||
|
<mask
|
||||||
|
maskUnits="userSpaceOnUse"
|
||||||
|
id="mask4516">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4518"
|
||||||
|
d="m -14.830002,1027.1553 58.614316,-18.8626 c 1.795162,-0.5777 3.231854,0.5139 3.231854,2.1982 v 19.0111 c 0,1.3165 -1.098401,2.3764 -2.462782,2.3764 h -59.106775 c -2.946621,0 -3.449835,-3.6727 -0.276613,-4.7231 z"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.96767992;stroke-opacity:1"
|
||||||
|
sodipodi:nodetypes="cccsscc" />
|
||||||
|
</mask>
|
||||||
|
</defs>
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
id="base"
|
id="base"
|
||||||
pagecolor="#dc39f7"
|
pagecolor="#dc39f7"
|
||||||
|
@ -24,16 +35,16 @@
|
||||||
borderopacity="1.0"
|
borderopacity="1.0"
|
||||||
inkscape:pageopacity="0"
|
inkscape:pageopacity="0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="4"
|
inkscape:zoom="14.580651"
|
||||||
inkscape:cx="-36.653402"
|
inkscape:cx="30.208524"
|
||||||
inkscape:cy="38.029112"
|
inkscape:cy="17.533448"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:snap-bbox="true"
|
inkscape:snap-bbox="true"
|
||||||
inkscape:bbox-paths="false"
|
inkscape:bbox-paths="false"
|
||||||
inkscape:window-width="1920"
|
inkscape:window-width="1868"
|
||||||
inkscape:window-height="1055"
|
inkscape:window-height="1049"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="0"
|
inkscape:window-y="0"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
|
@ -41,7 +52,13 @@
|
||||||
inkscape:object-paths="true"
|
inkscape:object-paths="true"
|
||||||
inkscape:snap-page="true"
|
inkscape:snap-page="true"
|
||||||
inkscape:snap-global="true"
|
inkscape:snap-global="true"
|
||||||
borderlayer="true" />
|
borderlayer="true"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true" />
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata3942">
|
id="metadata3942">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
|
@ -50,7 +67,7 @@
|
||||||
<dc:format>image/svg+xml</dc:format>
|
<dc:format>image/svg+xml</dc:format>
|
||||||
<dc:type
|
<dc:type
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
<dc:title />
|
<dc:title></dc:title>
|
||||||
</cc:Work>
|
</cc:Work>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -58,16 +75,20 @@
|
||||||
inkscape:label="Layer 1"
|
inkscape:label="Layer 1"
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer1"
|
id="layer1"
|
||||||
transform="translate(0,-987.3622)">
|
transform="translate(17.50001,-1004.8622)">
|
||||||
<path
|
<path
|
||||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
inkscape:connector-curvature="0"
|
||||||
d="m 0,1052.3622 0,-65 5,0 c -0.172588,0 -0.337256,0.0295 -0.5,0.0625 -0.489111,0.1 -0.942345,0.31725 -1.28125,0.65625 -0.226206,0.2262 -0.404743,0.5135 -0.53125,0.8125 -0.126507,0.2991 -0.1875,0.62365 -0.1875,0.96875 0,0 0.075978,0.44705 0.1875,0.78125 l 19.84375,59.49995 c 0.142777,1.2451 1.185414,2.2188 2.46875,2.2188 l -25,0 z m 25,0 c 0.877549,0 1.647663,-0.441 2.09375,-1.125 0.06381,-0.098 0.1062,-0.2046 0.15625,-0.3125 0.02962,-0.062 0.06926,-0.1225 0.09375,-0.1875 0.04501,-0.1212 0.06741,-0.2459 0.09375,-0.375 0.009,-0.044 0.02457,-0.08 0.03125,-0.125 0.01878,-0.1235 0.03125,-0.2462 0.03125,-0.375 l 0,-60 c 0,-1.385 -1.114999,-2.5 -2.5,-2.5 l 5,0 0,65 -5,0 z"
|
id="path4505"
|
||||||
id="rect4674"
|
d="m -14.830002,1027.1553 58.614316,-18.8626 c 1.795162,-0.5777 3.231854,0.5139 3.231854,2.1982 v 19.0111 c 0,1.3165 -1.098401,2.3764 -2.462782,2.3764 h -59.106775 c -2.946621,0 -3.449835,-3.6727 -0.276613,-4.7231 z"
|
||||||
inkscape:connector-curvature="0" />
|
style="fill:none;fill-opacity:1;stroke:#fdfdfd;stroke-width:0.96767992;stroke-opacity:1"
|
||||||
<path
|
sodipodi:nodetypes="cccsscc" />
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
<rect
|
||||||
d="m 25,1052.3617 c -1.283336,0 -2.325973,-0.9737 -2.46875,-2.2187 L 2.6875,990.6429 C 2.575978,990.3087 2.5,989.8617 2.5,989.8617 c 0,-0.3451 0.060993,-0.6697 0.1875,-0.9688 0.126507,-0.299 0.305044,-0.5863 0.53125,-0.8125 0.338905,-0.339 0.792139,-0.5562 1.28125,-0.6562 0.162744,-0.033 0.327412,-0.062 0.5,-0.062 l 20,0 c 1.385001,0 2.5,1.115 2.5,2.5 l 0,60 c 0,0.1288 -0.01247,0.2515 -0.03125,0.375 -0.0067,0.045 -0.02225,0.081 -0.03125,0.125 -0.02634,0.1292 -0.04874,0.2538 -0.09375,0.375 -0.02449,0.065 -0.06413,0.1252 -0.09375,0.1875 -0.05005,0.1079 -0.09244,0.2145 -0.15625,0.3125 -0.446087,0.684 -1.216201,1.125 -2.09375,1.125 z m 0,-1.2187 c 0.474106,0 0.864734,-0.2114 1.09375,-0.5625 -0.02112,0.032 -0.0059,-0.01 0.0625,-0.1563 a 1.204452,1.204452 0 0 1 0,-0.031 c 0.0235,-0.049 0.05198,-0.052 0.0625,-0.062 0.0055,-0.016 0.0094,-0.035 0,-0.031 0.0017,-0.01 0.0055,-0.061 0.03125,-0.1875 0.008,-0.039 0.02555,-0.039 0.03125,-0.062 0.0098,-0.066 0.0055,-0.1027 0,-0.094 -0.0016,-0.03 0,-0.068 0,-0.094 l 0,-60 c 0,-0.7386 -0.542617,-1.2813 -1.28125,-1.2813 l -20,0 c -0.035353,0 -0.105322,0 -0.25,0.031 -0.296863,0.061 -0.546343,0.1713 -0.6875,0.3125 -0.089394,0.089 -0.205263,0.258 -0.28125,0.4375 -0.055315,0.1308 -0.058661,0.2832 -0.0625,0.4687 -2.52e-4,0.012 0,0.019 0,0.031 0.027982,0.1353 0.082499,0.2789 0.125,0.4062 l 19.84375,59.5005 a 1.204452,1.204452 0 0 1 0.03125,0.25 c 0.07527,0.6564 0.607054,1.125 1.28125,1.125 z"
|
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.60986549;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
id="path4697-6"
|
id="rect4507"
|
||||||
inkscape:connector-curvature="0" />
|
width="33.400429"
|
||||||
|
height="30"
|
||||||
|
x="-17.50001"
|
||||||
|
y="1004.8622"
|
||||||
|
mask="url(#mask4516)" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.3 KiB |
|
@ -1,38 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg width="100" height="45" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
<svg
|
<defs>
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
<mask id="a" maskUnits="userSpaceOnUse">
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
<rect width="57.288" height="30" fill="#fff" fill-opacity=".74439"/>
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
</mask>
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
</defs>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<path d="m6.202 33.254 86.029-28.394c2.6348-0.86966 4.7433 0.77359 4.7433 3.3092v28.617c0 1.9819-1.6122 3.5773-3.6147 3.5773h-86.75c-4.3249 0-5.0634-5.5287-0.40598-7.1098" fill="none" stroke="#fdfdfd" stroke-width="6.0417"/>
|
||||||
version="1.1"
|
<g transform="translate(16.609 9.9991)" fill="#fff" mask="url(#a)">
|
||||||
id="svg3937"
|
<path d="m4.2605 21.935 55.47-18.308c1.6989-0.56074 3.0584 0.4988 3.0584 2.1337v18.452c0 1.2779-1.0395 2.3066-2.3307 2.3066h-55.935c-2.7886 0-3.2648-3.5648-0.26177-4.5843" fill="#fff"/>
|
||||||
height="65"
|
|
||||||
width="30">
|
|
||||||
<defs
|
|
||||||
id="defs3939" />
|
|
||||||
<metadata
|
|
||||||
id="metadata3942">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
transform="translate(0,-987.3622)"
|
|
||||||
id="layer1">
|
|
||||||
<path
|
|
||||||
id="rect4674"
|
|
||||||
d="m 0,1052.3622 0,-65 5,0 c -0.172588,0 -0.337256,0.0295 -0.5,0.0625 -0.489111,0.1 -0.942345,0.31725 -1.28125,0.65625 -0.226206,0.2262 -0.404743,0.5135 -0.53125,0.8125 -0.126507,0.2991 -0.1875,0.62365 -0.1875,0.96875 0,0 0.075978,0.44705 0.1875,0.78125 l 19.84375,59.49995 c 0.142777,1.2451 1.185414,2.2188 2.46875,2.2188 l -25,0 z m 25,0 c 0.877549,0 1.647663,-0.441 2.09375,-1.125 0.06381,-0.098 0.1062,-0.2046 0.15625,-0.3125 0.02962,-0.062 0.06926,-0.1225 0.09375,-0.1875 0.04501,-0.1212 0.06741,-0.2459 0.09375,-0.375 0.009,-0.044 0.02457,-0.08 0.03125,-0.125 0.01878,-0.1235 0.03125,-0.2462 0.03125,-0.375 l 0,-60 c 0,-1.385 -1.114999,-2.5 -2.5,-2.5 l 5,0 0,65 -5,0 z"
|
|
||||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate" />
|
|
||||||
<path
|
|
||||||
id="path4697-6"
|
|
||||||
d="m 25,1052.3617 c -1.283336,0 -2.325973,-0.9737 -2.46875,-2.2187 L 2.6875,990.6429 C 2.575978,990.3087 2.5,989.8617 2.5,989.8617 c 0,-0.3451 0.060993,-0.6697 0.1875,-0.9688 0.126507,-0.299 0.305044,-0.5863 0.53125,-0.8125 0.338905,-0.339 0.792139,-0.5562 1.28125,-0.6562 0.162744,-0.033 0.327412,-0.062 0.5,-0.062 l 20,0 c 1.385001,0 2.5,1.115 2.5,2.5 l 0,60 c 0,0.1288 -0.01247,0.2515 -0.03125,0.375 -0.0067,0.045 -0.02225,0.081 -0.03125,0.125 -0.02634,0.1292 -0.04874,0.2538 -0.09375,0.375 -0.02449,0.065 -0.06413,0.1252 -0.09375,0.1875 -0.05005,0.1079 -0.09244,0.2145 -0.15625,0.3125 -0.446087,0.684 -1.216201,1.125 -2.09375,1.125 z m 0,-1.2187 c 0.474106,0 0.864734,-0.2114 1.09375,-0.5625 -0.02112,0.032 -0.0059,-0.01 0.0625,-0.1563 a 1.204452,1.204452 0 0 1 0,-0.031 c 0.0235,-0.049 0.05198,-0.052 0.0625,-0.062 0.0055,-0.016 0.0094,-0.035 0,-0.031 0.0017,-0.01 0.0055,-0.061 0.03125,-0.1875 0.008,-0.039 0.02555,-0.039 0.03125,-0.062 0.0098,-0.066 0.0055,-0.1027 0,-0.094 -0.0016,-0.03 0,-0.068 0,-0.094 l 0,-60 c 0,-0.7386 -0.542617,-1.2813 -1.28125,-1.2813 l -20,0 c -0.035353,0 -0.105322,0 -0.25,0.031 -0.296863,0.061 -0.546343,0.1713 -0.6875,0.3125 -0.089394,0.089 -0.205263,0.258 -0.28125,0.4375 -0.055315,0.1308 -0.058661,0.2832 -0.0625,0.4687 -2.52e-4,0.012 0,0.019 0,0.031 0.027982,0.1353 0.082499,0.2789 0.125,0.4062 l 19.84375,59.5005 a 1.204452,1.204452 0 0 1 0.03125,0.25 c 0.07527,0.6564 0.607054,1.125 1.28125,1.125 z"
|
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke:none" />
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 731 B |
6
embed/imgs/volume_rect_dot_plain.svg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="100" height="50" version="1.1" viewBox="0 0 100 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect y="21" width="100" height="8" fill="#fff"/>
|
||||||
|
<ellipse cx="50" cy="25" rx="10" ry="10" fill="#008000"/>
|
||||||
|
<rect y="21" width="50" height="8" fill="#008000"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 312 B |
1
embed/min/player.js
Normal file
92
embed/min/skins/default.css
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
.mistvideo{display:inline-block;position:relative;color:$stroke;font-family:sans-serif;background-color:#000;justify-content:center;align-items:center}
|
||||||
|
.mistvideo-controls{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
||||||
|
.mistvideo.novideo{overflow:visible}
|
||||||
|
.mistvideo-video{overflow:hidden}
|
||||||
|
svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;opacity:0}
|
||||||
|
[data-loading]{position:relative}
|
||||||
|
[data-loading=stalled] svg.icon.loading{transition:opacity 0s 3s}
|
||||||
|
[data-loading] svg.icon.loading{z-index:2;opacity:1}
|
||||||
|
[data-loading-css] .mistvideo-controls{display:none}
|
||||||
|
[data-hidecursor],[data-hidecursor] *,[data-hidecursor] .mistvideo-pointer{cursor:none}
|
||||||
|
.mistvideo-error{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background-color:$background;align-items:center;justify-content:center;text-align:center;z-index:2;cursor:default;min-height:fit-content;min-width:fit-content}
|
||||||
|
.mistvideo-error.show{display:flex}
|
||||||
|
.mistvideo-error .message{max-width:80%}
|
||||||
|
.mistvideo-error .message .details table{text-align:left}
|
||||||
|
.mistvideo-controls button,.mistvideo-error button,.mistvideo-video:not(.video-js) button{color:$stroke;border:1px solid $semiFill;background-color:$background;margin:.25em;padding:.5em 1em;opacity:.5;cursor:pointer}
|
||||||
|
button:hover{opacity:1}
|
||||||
|
select{background-color:transparent;color:$stroke;border:none;margin:0 .5em;font-size:inherit;cursor:pointer;-ms-background-color:red}
|
||||||
|
select>option{background-color:$background}
|
||||||
|
.browser-edge select,.browser-safari select{border:1px solid $semiFill;border-top:none;border-left:none;margin-top:2px}
|
||||||
|
@keyframes spin{
|
||||||
|
0%{transform:rotate(0)}
|
||||||
|
100%{transform:rotate(360deg)}
|
||||||
|
}
|
||||||
|
[data-fullscreen]{position:fixed;top:0;left:0;right:0;bottom:0;width:100%!important;height:100%!important}
|
||||||
|
video{display:block;flex-shrink:0}
|
||||||
|
table{color:inherit;font-size:inherit;font-style:inherit}
|
||||||
|
audio:not([controls]){display:block!important}
|
||||||
|
.mistvideo-padding{padding:5px 10px}
|
||||||
|
.mistvideo-pointer{cursor:pointer}
|
||||||
|
.description{color:$semiFill;font-size:.9em}
|
||||||
|
.mistvideo-container{display:flex;flex-wrap:nowrap}
|
||||||
|
.mistvideo-container.mistvideo{display:inline-flex;max-width:100%}
|
||||||
|
.mistvideo-container.mistvideo-row{flex-direction:row}
|
||||||
|
.mistvideo-container.mistvideo-column{flex-direction:column}
|
||||||
|
.mistvideo-container.mistvideo-center{justify-content:center}
|
||||||
|
.mistvideo-align-right{margin-left:auto;margin-right:0}
|
||||||
|
.hover_window_container.pos>.outer_window{position:absolute;pointer-events:none;overflow:hidden}
|
||||||
|
.hover_window_container.pos>.outer_window>.inner_window{position:absolute;pointer-events:all}
|
||||||
|
.hover_window_container:not(:hover)>.outer_window>.inner_window,.hover_window_container>.outer_window[data-hidecursor]>.inner_window{transition:all .5s ease-in .5s}
|
||||||
|
.outer_window>.inner_window{flex-grow:1}
|
||||||
|
.hover_window_container>.outer_window>.inner_window>*{flex-shrink:0}
|
||||||
|
.mistvideo-draggable{overflow:hidden}
|
||||||
|
.mistvideo-tooltip{position:absolute;background-color:$background;padding:.5em 1em;z-index:2}
|
||||||
|
:not(:hover)>.mistvideo-tooltip{transition:opacity .25s ease-in}
|
||||||
|
.mistvideo-tooltip .triangle{border:10px solid $background;position:absolute}
|
||||||
|
.mistvideo-tracks label{display:block}
|
||||||
|
.mistvideo-tracks label>span{margin-right:1em}
|
||||||
|
a{color:$accent}
|
||||||
|
.mistvideo-log .logs{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}
|
||||||
|
.mistvideo-placeholder{max-width:100%;max-height:100%}
|
||||||
|
.mistvideo-topright{position:absolute;top:0;right:0}
|
||||||
|
.mistvideo-topleft{position:absolute;top:0;left:0}
|
||||||
|
.mistvideo-delay-display{animation:appear 1s;animation-iteration-count:1;animation-timing-function:steps(1,end)}
|
||||||
|
@keyframes appear{
|
||||||
|
from{opacity:0}
|
||||||
|
to{opacity:1}
|
||||||
|
}
|
||||||
|
svg.icon{display:block;stroke-width:$strokeWidth;fill:none;stroke:none}
|
||||||
|
svg.icon .fill,svg.icon.fill{fill:$fill}
|
||||||
|
svg.icon .semiFill,svg.icon.semiFill{fill:$semiFill}
|
||||||
|
svg.icon .stroke,svg.icon.stroke{stroke:$stroke;vector-effect:non-scaling-stroke}
|
||||||
|
svg.icon.off .toggle .fill,svg.icon.off .toggle .semiFill,svg.icon.off .toggle.fill,svg.icon.off .toggle.semiFill{fill:none}
|
||||||
|
svg.icon .spin,svg.icon.spin{animation:spin 1.5s infinite linear;transform-origin:50% 50%}
|
||||||
|
.mistvideo{line-height:1.2;font-size:14.5px}
|
||||||
|
.mistvideo svg{margin:2.5px}
|
||||||
|
.mistvideo-background{background-color:$background}
|
||||||
|
.mistvideo-totalTime:before{content:'/';margin:.2em}
|
||||||
|
.mistvideo-progress{padding:10px 0;margin:-10px 0;z-index:2}
|
||||||
|
.mistvideo-progress>*{height:2px;background-color:$progressBackground;opacity:.95;position:relative}
|
||||||
|
.mistvideo-novideo .mistvideo-progress>*,.mistvideo-progress:hover>*{height:10px}
|
||||||
|
.mistvideo-progress:not(:hover)>*{transition:height .25s ease-in .5s}
|
||||||
|
.mistvideo-progress .bar{height:inherit;width:0;position:absolute;border-right:inherit;background-color:$accent;z-index:2}
|
||||||
|
.mistvideo-progress .buffer{height:inherit;width:0;position:absolute;background-color:$semiFill}
|
||||||
|
.mistvideo-progress .bar:after{content:'';border:5px solid $accent;border-radius:5px;position:absolute;right:-5px;top:50%;transform:translateY(-50%)}
|
||||||
|
.mistvideo-play[data-state=playing] svg.play{display:none}
|
||||||
|
.mistvideo-play[data-state=paused] svg.pause{display:none}
|
||||||
|
.mistvideo-main{align-items:center}
|
||||||
|
svg.icon.timeout{display:inline-block;height:1em;width:1em;margin:0;margin-right:.25em;vertical-align:top}
|
||||||
|
.mist.largeplay,.mist.muted{position:absolute;opacity:.5}
|
||||||
|
.mist.largeplay{top:50%;left:0;right:0;margin:auto;transform:translateY(-50%)}
|
||||||
|
.mist.muted{top:0;right:0;margin:1em}
|
||||||
|
.mistvideo-secondaryVideo{z-index:1;width:50%;height:50%}
|
||||||
|
.mistvideo-polling{display:inline-block;position:relative;width:25px;height:25px}
|
||||||
|
.mistvideo-polling svg.icon.loading{z-index:0;opacity:1}
|
||||||
|
.mistvideo[data-show-submenu] .mistvideo-submenu{right:5px}
|
||||||
|
.mistvideo[data-show-submenu] .mistvideo-controls{bottom:0}
|
||||||
|
.mistvideo-error[data-passive]{bottom:auto;left:auto;margin:.5em;padding:.5em}
|
||||||
|
.mistvideo-error[data-passive] .message{max-width:none}
|
||||||
|
.mistvideo-error .mistvideo-buttoncontainer{display:flex;flex-flow:row nowrap;justify-content:center}
|
||||||
|
.mistvideo-error .mistvideo-buttoncontainer .mistvideo-button{white-space:nowrap}
|
||||||
|
.browser-ie .mist.icon.loading{animation:spin 1.5s infinite linear;transform-origin:50% 50%}
|
||||||
|
.browser-ie .mist.icon.loading .spin{animation:none}
|
116
embed/min/skins/dev.css
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
.mistvideo{display:inline-block;position:relative;color:$stroke;font-family:sans-serif;background-color:#000;justify-content:center;align-items:center}
|
||||||
|
.mistvideo-controls{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
||||||
|
.mistvideo.novideo{overflow:visible}
|
||||||
|
.mistvideo-video{overflow:hidden}
|
||||||
|
svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;opacity:0}
|
||||||
|
[data-loading]{position:relative}
|
||||||
|
[data-loading=stalled] svg.icon.loading{transition:opacity 0s 3s}
|
||||||
|
[data-loading] svg.icon.loading{z-index:2;opacity:1}
|
||||||
|
[data-loading-css] .mistvideo-controls{display:none}
|
||||||
|
[data-hidecursor],[data-hidecursor] *,[data-hidecursor] .mistvideo-pointer{cursor:none}
|
||||||
|
.mistvideo-error{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background-color:$background;align-items:center;justify-content:center;text-align:center;z-index:2;cursor:default;min-height:fit-content;min-width:fit-content}
|
||||||
|
.mistvideo-error.show{display:flex}
|
||||||
|
.mistvideo-error .message{max-width:80%}
|
||||||
|
.mistvideo-error .message .details table{text-align:left}
|
||||||
|
.mistvideo-controls button,.mistvideo-error button,.mistvideo-video:not(.video-js) button{color:$stroke;border:1px solid $semiFill;background-color:$background;margin:.25em;padding:.5em 1em;opacity:.5;cursor:pointer}
|
||||||
|
button:hover{opacity:1}
|
||||||
|
select{background-color:transparent;color:$stroke;border:none;margin:0 .5em;font-size:inherit;cursor:pointer;-ms-background-color:red}
|
||||||
|
select>option{background-color:$background}
|
||||||
|
.browser-edge select,.browser-safari select{border:1px solid $semiFill;border-top:none;border-left:none;margin-top:2px}
|
||||||
|
@keyframes spin{
|
||||||
|
0%{transform:rotate(0)}
|
||||||
|
100%{transform:rotate(360deg)}
|
||||||
|
}
|
||||||
|
[data-fullscreen]{position:fixed;top:0;left:0;right:0;bottom:0;width:100%!important;height:100%!important}
|
||||||
|
video{display:block;flex-shrink:0}
|
||||||
|
table{color:inherit;font-size:inherit;font-style:inherit}
|
||||||
|
audio:not([controls]){display:block!important}
|
||||||
|
.mistvideo-padding{padding:5px 10px}
|
||||||
|
.mistvideo-pointer{cursor:pointer}
|
||||||
|
.description{color:$semiFill;font-size:.9em}
|
||||||
|
.mistvideo-container{display:flex;flex-wrap:nowrap}
|
||||||
|
.mistvideo-container.mistvideo{display:inline-flex;max-width:100%}
|
||||||
|
.mistvideo-container.mistvideo-row{flex-direction:row}
|
||||||
|
.mistvideo-container.mistvideo-column{flex-direction:column}
|
||||||
|
.mistvideo-container.mistvideo-center{justify-content:center}
|
||||||
|
.mistvideo-align-right{margin-left:auto;margin-right:0}
|
||||||
|
.hover_window_container.pos>.outer_window{position:absolute;pointer-events:none;overflow:hidden}
|
||||||
|
.hover_window_container.pos>.outer_window>.inner_window{position:absolute;pointer-events:all}
|
||||||
|
.hover_window_container:not(:hover)>.outer_window>.inner_window,.hover_window_container>.outer_window[data-hidecursor]>.inner_window{transition:all .5s ease-in .5s}
|
||||||
|
.outer_window>.inner_window{flex-grow:1}
|
||||||
|
.hover_window_container>.outer_window>.inner_window>*{flex-shrink:0}
|
||||||
|
.mistvideo-draggable{overflow:hidden}
|
||||||
|
.mistvideo-tooltip{position:absolute;background-color:$background;padding:.5em 1em;z-index:2}
|
||||||
|
:not(:hover)>.mistvideo-tooltip{transition:opacity .25s ease-in}
|
||||||
|
.mistvideo-tooltip .triangle{border:10px solid $background;position:absolute}
|
||||||
|
.mistvideo-tracks label{display:block}
|
||||||
|
.mistvideo-tracks label>span{margin-right:1em}
|
||||||
|
a{color:$accent}
|
||||||
|
.mistvideo-log .logs{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}
|
||||||
|
.mistvideo-placeholder{max-width:100%;max-height:100%}
|
||||||
|
.mistvideo-topright{position:absolute;top:0;right:0}
|
||||||
|
.mistvideo-topleft{position:absolute;top:0;left:0}
|
||||||
|
.mistvideo-delay-display{animation:appear 1s;animation-iteration-count:1;animation-timing-function:steps(1,end)}
|
||||||
|
@keyframes appear{
|
||||||
|
from{opacity:0}
|
||||||
|
to{opacity:1}
|
||||||
|
}
|
||||||
|
svg.icon{display:block;stroke-width:$strokeWidth;fill:none;stroke:none}
|
||||||
|
svg.icon .fill,svg.icon.fill{fill:$fill}
|
||||||
|
svg.icon .semiFill,svg.icon.semiFill{fill:$semiFill}
|
||||||
|
svg.icon .stroke,svg.icon.stroke{stroke:$stroke;vector-effect:non-scaling-stroke}
|
||||||
|
svg.icon.off .toggle .fill,svg.icon.off .toggle .semiFill,svg.icon.off .toggle.fill,svg.icon.off .toggle.semiFill{fill:none}
|
||||||
|
svg.icon .spin,svg.icon.spin{animation:spin 1.5s infinite linear;transform-origin:50% 50%}
|
||||||
|
.mistvideo{line-height:1.2;font-size:14.5px}
|
||||||
|
.mistvideo svg{margin:2.5px}
|
||||||
|
.mistvideo-background{background-color:$background}
|
||||||
|
.mistvideo-totalTime:before{content:'/';margin:.2em}
|
||||||
|
.mistvideo-progress{padding:10px 0;margin:-10px 0;z-index:2}
|
||||||
|
.mistvideo-progress>*{height:2px;background-color:$progressBackground;opacity:.95;position:relative}
|
||||||
|
.mistvideo-novideo .mistvideo-progress>*,.mistvideo-progress:hover>*{height:10px}
|
||||||
|
.mistvideo-progress:not(:hover)>*{transition:height .25s ease-in .5s}
|
||||||
|
.mistvideo-progress .bar{height:inherit;width:0;position:absolute;border-right:inherit;background-color:$accent;z-index:2}
|
||||||
|
.mistvideo-progress .buffer{height:inherit;width:0;position:absolute;background-color:$semiFill}
|
||||||
|
.mistvideo-progress .bar:after{content:'';border:5px solid $accent;border-radius:5px;position:absolute;right:-5px;top:50%;transform:translateY(-50%)}
|
||||||
|
.mistvideo-play[data-state=playing] svg.play{display:none}
|
||||||
|
.mistvideo-play[data-state=paused] svg.pause{display:none}
|
||||||
|
.mistvideo-main{align-items:center}
|
||||||
|
svg.icon.timeout{display:inline-block;height:1em;width:1em;margin:0;margin-right:.25em;vertical-align:top}
|
||||||
|
.mist.largeplay,.mist.muted{position:absolute;opacity:.5}
|
||||||
|
.mist.largeplay{top:50%;left:0;right:0;margin:auto;transform:translateY(-50%)}
|
||||||
|
.mist.muted{top:0;right:0;margin:1em}
|
||||||
|
.mistvideo-secondaryVideo{z-index:1;width:50%;height:50%}
|
||||||
|
.mistvideo-polling{display:inline-block;position:relative;width:25px;height:25px}
|
||||||
|
.mistvideo-polling svg.icon.loading{z-index:0;opacity:1}
|
||||||
|
.mistvideo[data-show-submenu] .mistvideo-submenu{right:5px}
|
||||||
|
.mistvideo[data-show-submenu] .mistvideo-controls{bottom:0}
|
||||||
|
.mistvideo-error[data-passive]{bottom:auto;left:auto;margin:.5em;padding:.5em}
|
||||||
|
.mistvideo-error[data-passive] .message{max-width:none}
|
||||||
|
.mistvideo-error .mistvideo-buttoncontainer{display:flex;flex-flow:row nowrap;justify-content:center}
|
||||||
|
.mistvideo-error .mistvideo-buttoncontainer .mistvideo-button{white-space:nowrap}
|
||||||
|
.browser-ie .mist.icon.loading{animation:spin 1.5s infinite linear;transform-origin:50% 50%}
|
||||||
|
.browser-ie .mist.icon.loading .spin{animation:none}
|
||||||
|
.mistvideo-log{margin:.5em 0}
|
||||||
|
.mistvideo-log .logs{max-height:10em;min-height:5em;width:100%;padding:.2em 0;padding-right:1em;overflow-y:auto;overflow-x:hidden;font-size:.9em}
|
||||||
|
.mistvideo-log .logs table td{vertical-align:top;padding:0}
|
||||||
|
.mistvideo-log .logs .entry .message{margin:0 .2em}
|
||||||
|
.mistvideo-log .logs .entry.type-error{color:$accent}
|
||||||
|
.mistvideo-log .logs .counter,.mistvideo-log .logs .timestamp{color:$semiFill}
|
||||||
|
.mistvideo-log .logs .timestamp:before{content:'['}
|
||||||
|
.mistvideo-log .logs .timestamp:after{content:']'}
|
||||||
|
.mistvideo-log .logs .counter:before{content:'('}
|
||||||
|
.mistvideo-log .logs .counter:after{content:'\00d7)'}
|
||||||
|
.mistvideo-devbuttons{font-size:.9em}
|
||||||
|
.mistvideo-devbuttons button{font-size:.8em;margin:.1em;padding:.2em .4em}
|
||||||
|
.mistvideo-forcePlayer>span,.mistvideo-forceSource>span,.mistvideo-forceType>span{display:inline-block;width:7em}
|
||||||
|
.mistvideo-forcePlayer>select,.mistvideo-forceSource>select,.mistvideo-forceType>select{width:15em;min-width:auto}
|
||||||
|
.mistvideo-devcontrols{margin:.5em 0}
|
||||||
|
.mistvideo-decodingIssues>*{display:flex;width:50%;max-width:20em;flex-flow:row nowrap;align-items:flex-end;justify-content:space-between}
|
||||||
|
.mistvideo-decodingIssues>*>:last-child{margin-right:.5em}
|
||||||
|
.mistvideo-decodingIssues{display:flex;flex-flow:row wrap;justify-content:space-between}
|
||||||
|
.mistvideo-decodingIssues label{position:relative}
|
||||||
|
.mistvideo-decodingIssues label .value{font-size:.8em}
|
||||||
|
svg.icon.graph{position:absolute;right:0;top:0;bottom:0;width:6em}
|
||||||
|
select{border-radius:0}
|
||||||
|
input[type=checkbox]{margin:0;margin-right:.2em;border:1px solid $semiFill;border-radius:0;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;width:.8em;height:.8em;color:inherit;position:relative;cursor:pointer}
|
||||||
|
input[type=checkbox]:checked:after{content:"\2713";position:absolute;bottom:-.2em;left:0;font-size:1.2em}
|
1
embed/min/wrappers/dashjs.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
mistplayers.dashjs={name:"Dash.js player",mimes:["dash/video/mp4"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return MistUtil.array.indexOf(this.mimes,t)==-1?false:true},isBrowserSupported:function(t,e,i){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"){i.log("This source ("+t+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){this.onreadylist=[]},scriptsrc:function(t){return t+"/dashjs.js"}};var p=mistplayers.dashjs.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=this;this.onDashLoad=function(){if(t.destroyed){return}t.log("Building DashJS player..");var r=document.createElement("video");if("Proxy"in window){var a={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in a.get){return a.get[e].apply(t,arguments)}var r=t[e];if(typeof r==="function"){return function(){return r.apply(t,arguments)}}return r},set:function(t,e,i){if(e in a.set){return a.set[e].call(t,i)}return t[e]=i}});if(t.info.type=="live"){a.get.duration=function(){var e=0;if(this.buffered.length){e=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-t.player.api.lastProgress.getTime())*.001;return e+i+-1*t.player.api.liveOffset+45};a.set.currentTime=function(e){var i=e-t.player.api.duration;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");t.video.currentTime=e};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0}}else{i.api=r}if(t.options.autoplay){r.setAttribute("autoplay","")}if(t.options.loop&&t.info.type!="live"){r.setAttribute("loop","")}if(t.options.poster){r.setAttribute("poster",t.options.poster)}if(t.options.controls=="stock"){r.setAttribute("controls","")}var s=dashjs.MediaPlayer().create();s.initialize(r,t.source.url,t.options.autoplay);i.dash=s;var o=["METRIC_ADDED","METRIC_CHANGED","METRICS_CHANGED","FRAGMENT_LOADING_STARTED","FRAGMENT_LOADING_COMPLETED","LOG","PLAYBACK_TIME_UPDATED","PLAYBACK_PROGRESS"];for(var n in dashjs.MediaPlayer.events){if(o.indexOf(n)<0){i.dash.on(dashjs.MediaPlayer.events[n],function(e){t.log("Player event fired: "+e.type)})}}t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};t.player.api.setSource=function(e){t.player.dash.attachSource(e)};t.player.api.setTrack=function(e,r){var a=MistUtil.tracks.parse(t.info.meta.tracks);if(!(e in a)||!(r in a[e])&&r!=0){t.log("Skipping trackselection of "+e+" track "+r+" because it does not exist");return}var s=i.dash.getBitrateInfoListFor("video").length-1;for(var o in t.info.meta.tracks){var n=t.info.meta.tracks[o];if(n.type==e){if(n.trackid==r){break}s--}}i.dash.setAutoSwitchQualityFor(e,false);i.dash.setFastSwitchEnabled(true);i.dash.setQualityFor(e,s)};i.dash.on("qualityChangeRendered",function(e){var r=i.dash.getBitrateInfoListFor("video").length-1;var a;for(var s in t.info.meta.tracks){var o=t.info.meta.tracks[s];if(o.type==e.mediaType){if(e.newQuality==r){a=o.trackid;break}r--}}MistUtil.event.send("playerUpdate_trackChanged",{type:e.mediaType,trackid:a},t.video)});MistUtil.event.addListener(r,"progress",function(e){if(t.container.getAttribute("data-loading")=="stalled"){t.container.removeAttribute("data-loading")}});i.api.unload=function(){i.dash.reset()};t.log("Built html");e(r)};if("dashjs"in window){this.onDashLoad()}else{var r=MistUtil.scripts.insert(t.urlappend(mistplayers.dashjs.scriptsrc(t.options.host)),{onerror:function(e){var i="Failed to load dashjs.js";if(e.message){i+=": "+e.message}t.showError(i)},onload:i.onDashLoad},t)}};
|
1
embed/min/wrappers/flash_strobe.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
mistplayers.flash_strobe={name:"Strobe Flash media playback",mimes:["flash/10","flash/11","flash/7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return this.mimes.indexOf(t)==-1?false:true},isBrowserSupported:function(t,e,i){if(MistUtil.http.url.split(e.url).protocol.slice(0,4)=="http"&&location.protocol!=MistUtil.http.url.split(e.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}var r=0;try{var a=navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin;if(a.version){r=a.version.split(".")[0]}else{r=a.description.replace(/([^0-9\.])/g,"").split(".")[0]}}catch(t){}try{r=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/([^0-9\,])/g,"").split(",")[0]}catch(t){}if(!r){return false}var l=t.split("/");return Number(r)>=Number(l[l.length-1])},player:function(){this.onreadylist=[]}};var p=mistplayers.flash_strobe.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=document.createElement("object");var r=document.createElement("embed");i.appendChild(r);function a(e){var a=t.options;function l(t,e){var i=document.createElement("param");i.setAttribute("name",t);i.setAttribute("value",e);return i}MistUtil.empty(i);i.appendChild(l("movie",t.urlappend(a.host+t.source.player_url)));var s="src="+encodeURIComponent(e)+"&controlBarMode="+(a.controls?"floating":"none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(a.live?"&streamType=live":"")+(a.autoplay?"&autoPlay=true":"");i.appendChild(l("flashvars",s));i.appendChild(l("allowFullScreen","true"));i.appendChild(l("wmode","direct"));if(a.autoplay){i.appendChild(l("autoPlay","true"))}r.setAttribute("src",t.urlappend(t.source.player_url));r.setAttribute("type","application/x-shockwave-flash");r.setAttribute("allowfullscreen","true");r.setAttribute("flashvars",s)}a(t.source.url);this.api={};this.setSize=function(t){i.setAttribute("width",t.width);i.setAttribute("height",t.height);r.setAttribute("width",t.width);r.setAttribute("height",t.height)};this.setSize(t.calcSize());this.onready(function(){if(t.container){t.container.removeAttribute("data-loading")}});this.api.setSource=function(t){a(t)};t.log("Built html");e(i)};
|
1
embed/min/wrappers/html5.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
mistplayers.html5={name:"HTML5 video player",mimes:["html5/application/vnd.apple.mpegurl","html5/video/mp4","html5/video/ogg","html5/video/webm","html5/audio/mp3","html5/audio/webm","html5/audio/ogg","html5/audio/wav"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.url).protocol=="http:"){i.log("This page was loaded over file://, the player might not behave as intended.")}else{i.log("HTTP/HTTPS mismatch for this source");return false}}var r=false;var a=e.split("/");a.shift();try{a=a.join("/");function n(e){var t=document.createElement("video");if(t&&t.canPlayType(e)!=""){r=t.canPlayType(e)}return r}if(a=="video/mp4"){function o(e){function t(t){return("0"+e.init.charCodeAt(t).toString(16)).slice(-2)}switch(e.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp3";case"AC3":return"ec-3";case"H264":return"avc1."+t(1)+t(2)+t(3);case"HEVC":return"hev1."+t(1)+t(6)+t(7)+t(8)+t(9)+t(10)+t(11)+t(12);default:return e.codec.toLowerCase()}}var s={};for(var l in i.info.meta.tracks){if(i.info.meta.tracks[l].type!="meta"){s[o(i.info.meta.tracks[l])]=1}}s=MistUtil.object.keys(s);if(s.length){if(s.length>t.simul_tracks){var p=0;for(var l in s){var u=n(a+';codecs="'+s[l]+'"');if(u){p++}}return p>=t.simul_tracks}a+=';codecs="'+s.join(",")+'"'}}r=n(a)}catch(e){}return r},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=e.source.type.split("/");i.shift();var r=document.createElement("video");r.setAttribute("crossorigin","anonymous");var a=document.createElement("source");a.setAttribute("src",e.source.url);r.source=a;r.appendChild(a);a.type=i.join("/");var n=["autoplay","loop","poster"];for(var o in n){var s=n[o];if(e.options[s]){r.setAttribute(s,e.options[s]===true?"":e.options[s])}}if(e.options.controls=="stock"){r.setAttribute("controls","")}if(e.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in l.get){return l.get[t].apply(e,arguments)}var r=e[t];if(typeof r==="function"){return function(){return r.apply(e,arguments)}}return r},set:function(e,t,i){if(t in l.set){return l.set[t].call(e,i)}return e[t]=i}});if(e.source.type=="html5/audio/mp3"){l.set.currentTime=function(){e.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(e.info.type=="live"){l.get.duration=function(){var t=0;if(this.buffered.length){t=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-e.player.api.lastProgress.getTime())*.001;return t+i-e.player.api.liveOffset};l.set.currentTime=function(t){var i=t-e.player.api.duration;e.player.api.liveOffset=i;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");e.player.api.setSource(MistUtil.http.url.addParam(e.source.url,{startunix:i}))};MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",function(){e.player.api.pausedAt=new Date});l.get.play=function(){return function(){if(e.player.api.paused&&e.player.api.pausedAt&&new Date-e.player.api.pausedAt>5e3){r.load();e.log("Reloading source..")}return r.play.apply(r,arguments)}};if(e.source.type=="html5/video/mp4"){l.get.currentTime=function(){return this.currentTime-e.player.api.liveOffset+e.info.lastms*.001}}}else{if(!isFinite(r.duration)){var p=0;for(var o in e.info.meta.tracks){p=Math.max(p,e.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return p*.001}}}}else{e.player.api=r}e.player.api.setSource=function(e){if(e!=this.source.src){this.source.src=e;this.load()}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=e.label;a.srclang=e.lang;a.src=e.src;a.setAttribute("default","")}};e.player.setSize=function(e){this.api.style.width=e.width+"px";this.api.style.height=e.height+"px"};t(r)};
|
1
embed/min/wrappers/videojs.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
mistplayers.videojs={name:"VideoJS player",mimes:["html5/application/vnd.apple.mpegurl"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){i.log("This source ("+e+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){},scriptsrc:function(e){return e+"/videojs.js"}};var p=mistplayers.videojs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;function r(){if(e.destroyed){return}e.log("Building VideoJS player..");var r=document.createElement("video");if(e.source.type!="html5/video/ogg"){r.crossOrigin="anonymous"}var o=e.source.type.split("/");o.shift();var n=document.createElement("source");n.setAttribute("src",e.source.url);i.source=n;r.appendChild(n);n.type=o.join("/");e.log("Adding "+n.type+" source @ "+e.source.url);if(n.type=="application/vnd.apple.mpegurl"){n.type="application/x-mpegURL"}MistUtil.class.add(r,"video-js");var s={};if(e.options.autoplay){s.autoplay=true}if(e.options.loop&&e.info.type!="live"){s.loop=true;r.loop=true}if(e.options.poster){s.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var l=document.createElement("link");l.rel="stylesheet";l.href=e.options.host+"/skins/videojs.css";l.id="videojs-css";document.head.appendChild(l)}}i.onready(function(){i.videojs=videojs(r,s,function(){e.log("Videojs initialized")});i.api.unload=function(){videojs(r).dispose()}});e.log("Built html");if("Proxy"in window&&"Reflect"in window){var a={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in a.get){return a.get[t].apply(e,arguments)}var r=e[t];if(typeof r==="function"){return function(){return r.apply(e,arguments)}}return r},set:function(e,t,i){if(t in a.set){return a.set[t].call(e,i)}return e[t]=i}});if(e.info.type=="live"){function p(e){var t=0;if(e.buffered.length){t=e.buffered.end(e.buffered.length-1)}return t}var u=90;a.get.duration=function(){return(e.info.lastms+(new Date).getTime()-e.info.updated.getTime())*.001};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});a.set.currentTime=function(t){var i=e.player.api.currentTime-t;var r=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(r*-10)/10+"s from live)");e.video.currentTime-=i};a.get.currentTime=function(){return this.currentTime+e.info.lastms*.001-e.player.api.liveOffset-u}}}else{i.api=r}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);r.parentNode.style.width=t.width+"px";r.parentNode.style.height=t.height+"px"}this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e.player.api.setSource=function(t){if(!e.player.videojs){return}if(e.player.videojs.src()!=t){e.player.videojs.src({type:e.player.videojs.currentSource().type,src:t})}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var o=document.createElement("track");r.appendChild(o);o.kind="subtitles";o.label=e.label;o.srclang=e.lang;o.src=e.src;o.setAttribute("default","")}};t(r)}if("videojs"in window){r()}else{var o=MistUtil.scripts.insert(e.urlappend(mistplayers.videojs.scriptsrc(e.options.host)),{onerror:function(t){var i="Failed to load videojs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:r},e)}};
|
1
embed/min/wrappers/webrtc.js
Normal file
48
embed/minimize.sh
Executable file
|
@ -0,0 +1,48 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Minimizing player code..";
|
||||||
|
|
||||||
|
echo " Minimizing JS..";
|
||||||
|
|
||||||
|
if [ "min/player.js" -ot "util.js" ] || [ "min/player.js" -ot "skins.js" ] || [ "min/player.js" -ot "controls.js" ] || [ "min/player.js" -ot "player.js" ]; then
|
||||||
|
echo " Minimizing 'util.js skins.js controls.js player.js' into 'min/player.js'..";
|
||||||
|
terser -mc -o min/player.js -- util.js skins.js controls.js player.js
|
||||||
|
fi
|
||||||
|
echo " Done.";
|
||||||
|
|
||||||
|
echo " Minimizing wrappers.."
|
||||||
|
|
||||||
|
if [ "min/wrappers/dashjs.js" -ot "wrappers/dashjs.js" ]; then
|
||||||
|
echo " Minimizing dashjs";
|
||||||
|
terser -mn -o min/wrappers/dashjs.js -- wrappers/dashjs.js
|
||||||
|
fi
|
||||||
|
if [ "min/wrappers/flash_strobe.js" -ot "wrappers/flash_strobe.js" ]; then
|
||||||
|
echo " Minimizing flash_strobe";
|
||||||
|
terser -mn -o min/wrappers/flash_strobe.js -- wrappers/flash_strobe.js
|
||||||
|
fi
|
||||||
|
if [ "min/wrappers/html5.js" -ot "wrappers/html5.js" ]; then
|
||||||
|
echo " Minimizing html5";
|
||||||
|
terser -mn -o min/wrappers/html5.js -- wrappers/html5.js
|
||||||
|
fi
|
||||||
|
if [ "min/wrappers/videojs.js" -ot "wrappers/videojs.js" ]; then
|
||||||
|
echo " Minimizing videojs";
|
||||||
|
terser -mn -o min/wrappers/videojs.js -- wrappers/videojs.js
|
||||||
|
fi
|
||||||
|
if [ "min/wrappers/webrtc.js" -ot "wrappers/webrtc.js" ]; then
|
||||||
|
echo " Minimizing webrtc";
|
||||||
|
terser -mn -o min/wrappers/webrtc.js -- wrappers/webrtc.js
|
||||||
|
fi
|
||||||
|
echo " Done.";
|
||||||
|
|
||||||
|
echo " Minimizing CSS..";
|
||||||
|
|
||||||
|
if [ "min/skins/default.css" -ot "skins/default.css" ] || [ "min/skins/default.css" -ot "skins/general.css" ]; then
|
||||||
|
echo " Minimizing default";
|
||||||
|
cleancss --format keep-breaks -o min/skins/default.css skins/general.css skins/default.css
|
||||||
|
fi
|
||||||
|
if [ "min/skins/dev.css" -ot "skins/default.css" ] || [ "min/skins/dev.css" -ot "skins/general.css" ] || [ "min/skins/dev.css" -ot "skins/dev.css" ]; then
|
||||||
|
echo " Minimizing dev";
|
||||||
|
cleancss --format keep-breaks -o min/skins/dev.css skins/general.css skins/default.css skins/dev.css
|
||||||
|
fi
|
||||||
|
echo " Done.";
|
||||||
|
echo "Done.";
|
1633
embed/mist.css
1127
embed/player.js
Normal file
46
embed/players/dash.all.min.js
vendored
8
embed/players/update.sh
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Dashjs"
|
||||||
|
wget https://cdn.dashjs.org/latest/dash.all.min.js -O dash.all.min.js
|
||||||
|
|
||||||
|
echo "Videojs"
|
||||||
|
echo "You'll want to check for the latest version at https://videojs.com/getting-started/#download-cdn"
|
||||||
|
wget https://vjs.zencdn.net/7.3.0/video.min.js -O video.min.js
|
24722
embed/players/video.js
13
embed/players/video.min.js
vendored
7
embed/players/videojs-contrib-hls.min.js
vendored
1
embed/players/webrtc.js
Normal file
2559
embed/skins.js
Normal file
131
embed/skins/default.css
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
.mistvideo {
|
||||||
|
line-height: 1.2;
|
||||||
|
font-size: 14.5px;
|
||||||
|
}
|
||||||
|
.mistvideo svg {
|
||||||
|
margin: 2.5px;
|
||||||
|
}
|
||||||
|
.mistvideo-background { background-color: $background; }
|
||||||
|
.mistvideo-totalTime:before {
|
||||||
|
content: '/';
|
||||||
|
margin: 0.2em;
|
||||||
|
}
|
||||||
|
.mistvideo-progress {
|
||||||
|
padding: 10px 0;
|
||||||
|
margin: -10px 0;
|
||||||
|
z-index: 2; /*keep above control bar*/
|
||||||
|
}
|
||||||
|
.mistvideo-progress > * {
|
||||||
|
height: 2px;
|
||||||
|
background-color: $progressBackground;
|
||||||
|
opacity: 0.95;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.mistvideo-novideo .mistvideo-progress > *,
|
||||||
|
.mistvideo-progress:hover > * {
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mistvideo-progress:not(:hover) > * {
|
||||||
|
transition: height 0.25s ease-in 0.5s;
|
||||||
|
}
|
||||||
|
.mistvideo-progress .bar {
|
||||||
|
height: inherit;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
border-right: inherit;
|
||||||
|
background-color: $accent;
|
||||||
|
z-index: 2; /*keep above buffer bar(s)*/
|
||||||
|
}
|
||||||
|
.mistvideo-progress .buffer {
|
||||||
|
height: inherit;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
background-color: $semiFill;
|
||||||
|
}
|
||||||
|
.mistvideo-progress .bar:after {
|
||||||
|
content: '';
|
||||||
|
border: 5px solid $accent;
|
||||||
|
border-radius: 5px;
|
||||||
|
position: absolute;
|
||||||
|
right: -5px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mistvideo-play[data-state="playing"] svg.play {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.mistvideo-play[data-state="paused"] svg.pause {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.mistvideo-main { align-items: center; }
|
||||||
|
|
||||||
|
svg.icon.timeout {
|
||||||
|
display: inline-block;
|
||||||
|
height: 1em;
|
||||||
|
width: 1em;
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 0.25em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mist.largeplay, .mist.muted {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.mist.largeplay {
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: auto;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
.mist.muted {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
.mistvideo-secondaryVideo {
|
||||||
|
z-index: 1;
|
||||||
|
width: 50%;
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
.mistvideo-polling {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
.mistvideo-polling svg.icon.loading {
|
||||||
|
z-index: 0;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.mistvideo[data-show-submenu] .mistvideo-submenu {
|
||||||
|
right: 5px;
|
||||||
|
}
|
||||||
|
.mistvideo[data-show-submenu] .mistvideo-controls {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.mistvideo-error[data-passive] {
|
||||||
|
bottom: auto;
|
||||||
|
left: auto;
|
||||||
|
margin: 0.5em;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
.mistvideo-error[data-passive] .message {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
.mistvideo-error .mistvideo-buttoncontainer {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.mistvideo-error .mistvideo-buttoncontainer .mistvideo-button {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.browser-ie .mist.icon.loading {
|
||||||
|
animation: spin 1.5s infinite linear;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
}
|
||||||
|
.browser-ie .mist.icon.loading .spin { animation: none; }
|
105
embed/skins/dev.css
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
.mistvideo-log {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
.mistvideo-log .logs {
|
||||||
|
max-height: 10em;
|
||||||
|
min-height: 5em;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.2em 0;
|
||||||
|
padding-right: 1em; /*for scrollbar*/
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
.mistvideo-log .logs table td {
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.mistvideo-log .logs .entry .message {
|
||||||
|
margin: 0 0.2em;
|
||||||
|
}
|
||||||
|
.mistvideo-log .logs .entry.type-error {
|
||||||
|
color: $accent;
|
||||||
|
}
|
||||||
|
.mistvideo-log .logs .timestamp,
|
||||||
|
.mistvideo-log .logs .counter {
|
||||||
|
color: $semiFill;
|
||||||
|
}
|
||||||
|
.mistvideo-log .logs .timestamp:before { content: '['; }
|
||||||
|
.mistvideo-log .logs .timestamp:after { content: ']'; }
|
||||||
|
.mistvideo-log .logs .counter:before { content: '('; }
|
||||||
|
.mistvideo-log .logs .counter:after { content: '\00d7)'; }
|
||||||
|
|
||||||
|
.mistvideo-devbuttons { font-size: 0.9em; }
|
||||||
|
.mistvideo-devbuttons button {
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin: 0.1em;
|
||||||
|
padding: 0.2em 0.4em;
|
||||||
|
}
|
||||||
|
.mistvideo-forceSource > span,
|
||||||
|
.mistvideo-forceType > span,
|
||||||
|
.mistvideo-forcePlayer > span { display: inline-block; width: 7em; }
|
||||||
|
.mistvideo-forceSource > select,
|
||||||
|
.mistvideo-forceType > select,
|
||||||
|
.mistvideo-forcePlayer > select {
|
||||||
|
width: 15em;
|
||||||
|
min-width: auto;
|
||||||
|
}
|
||||||
|
.mistvideo-devcontrols {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mistvideo-decodingIssues > * {
|
||||||
|
display: flex;
|
||||||
|
width: 50%;
|
||||||
|
max-width: 20em;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.mistvideo-decodingIssues > * > :last-child {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
.mistvideo-decodingIssues {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.mistvideo-decodingIssues label {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.mistvideo-decodingIssues label .value {
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
svg.icon.graph {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 6em;
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
input[type="checkbox"] {
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
border: 1px solid $semiFill;
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
-ms-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
width: 0.8em;
|
||||||
|
height: 0.8em;
|
||||||
|
color: inherit;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
input[type="checkbox"]:checked:after {
|
||||||
|
content: "\2713";
|
||||||
|
position: absolute;
|
||||||
|
bottom: -0.2em;
|
||||||
|
left: 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
224
embed/skins/general.css
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
.mistvideo {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
color: $stroke;
|
||||||
|
font-family: sans-serif;
|
||||||
|
background-color: #000;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.mistvideo-controls {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.mistvideo.novideo {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
.mistvideo-video {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
svg.icon.loading {
|
||||||
|
z-index: -1; /* don't use display: none because of transition for [data-loading=stalled] */
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
[data-loading] {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*wait before showing icon when stalled*/
|
||||||
|
[data-loading="stalled"] svg.icon.loading {
|
||||||
|
transition: opacity 0s 3s;
|
||||||
|
}
|
||||||
|
[data-loading] svg.icon.loading {
|
||||||
|
z-index: 2;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
[data-loading-css] .mistvideo-controls {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
[data-hidecursor],
|
||||||
|
[data-hidecursor] .mistvideo-pointer,
|
||||||
|
[data-hidecursor] *
|
||||||
|
{ cursor: none }
|
||||||
|
.mistvideo-error {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: $background;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 2; /*above progress bar*/
|
||||||
|
cursor: default; /*cursor won't show up if it was hidden because the mousemove event can no longer reach the video element*/
|
||||||
|
min-height: fit-content; /*overflow if needed*/
|
||||||
|
min-width: fit-content;
|
||||||
|
}
|
||||||
|
.mistvideo-error.show { display: flex; }
|
||||||
|
.mistvideo-error .message { max-width: 80%; }
|
||||||
|
.mistvideo-error .message .details table { text-align: left; }
|
||||||
|
.mistvideo-video:not(.video-js) button,
|
||||||
|
.mistvideo-error button,
|
||||||
|
.mistvideo-controls button
|
||||||
|
{
|
||||||
|
color: $stroke;
|
||||||
|
border: 1px solid $semiFill;
|
||||||
|
background-color: $background;
|
||||||
|
margin: 0.25em;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button:hover { opacity: 1; }
|
||||||
|
select {
|
||||||
|
background-color: transparent;
|
||||||
|
color: $stroke;
|
||||||
|
border: none;
|
||||||
|
margin: 0 0.5em;
|
||||||
|
font-size: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
-ms-background-color: red;
|
||||||
|
}
|
||||||
|
select > option {
|
||||||
|
background-color: $background;
|
||||||
|
}
|
||||||
|
|
||||||
|
.browser-edge select, .browser-safari select {
|
||||||
|
/*These browsers don't show an arrow for select boxes, causing them to be invisible when a border is not applied */
|
||||||
|
border: 1px solid $semiFill;
|
||||||
|
border-top: none;
|
||||||
|
border-left: none;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
|
||||||
|
[data-fullscreen] {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
video {
|
||||||
|
display: block;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
table { color: inherit; font-size: inherit; font-style: inherit; }
|
||||||
|
audio:not([controls]) { display: block !important; }
|
||||||
|
.mistvideo-padding { padding: 5px 10px; }
|
||||||
|
.mistvideo-pointer { cursor: pointer; }
|
||||||
|
.description {
|
||||||
|
color: $semiFill;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
.mistvideo-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
.mistvideo-container.mistvideo { display: inline-flex; max-width: 100%; }
|
||||||
|
.mistvideo-container.mistvideo-row { flex-direction: row; }
|
||||||
|
.mistvideo-container.mistvideo-column { flex-direction: column; }
|
||||||
|
.mistvideo-container.mistvideo-center { justify-content: center; }
|
||||||
|
|
||||||
|
.mistvideo-align-right {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover_window_container.pos > .outer_window {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.hover_window_container.pos > .outer_window > .inner_window {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
.hover_window_container:not(:hover) > .outer_window > .inner_window,
|
||||||
|
.hover_window_container > .outer_window[data-hidecursor] > .inner_window
|
||||||
|
{ transition: all 0.5s ease-in 0.5s; }
|
||||||
|
.outer_window > .inner_window { flex-grow: 1; }
|
||||||
|
.hover_window_container > .outer_window > .inner_window > * { flex-shrink: 0; }
|
||||||
|
|
||||||
|
.mistvideo-draggable {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mistvideo-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
background-color: $background;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
*:not(:hover) > .mistvideo-tooltip { transition: opacity 0.25s ease-in; }
|
||||||
|
.mistvideo-tooltip .triangle {
|
||||||
|
border: 10px solid $background;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.mistvideo-tracks label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mistvideo-tracks label > span {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $accent;
|
||||||
|
}
|
||||||
|
.mistvideo-log .logs {
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
-ms-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
.mistvideo-placeholder {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mistvideo-topright {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.mistvideo-topleft {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.mistvideo-delay-display {
|
||||||
|
animation: appear 1s;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
animation-timing-function: steps(1,end);
|
||||||
|
}
|
||||||
|
@keyframes appear { from { opacity: 0; } to { opacity: 1; } }
|
||||||
|
|
||||||
|
svg.icon {
|
||||||
|
display: block;
|
||||||
|
stroke-width: $strokeWidth;
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
svg.icon.fill, svg.icon .fill { fill: $fill; }
|
||||||
|
svg.icon.semiFill, svg.icon .semiFill { fill: $semiFill; }
|
||||||
|
svg.icon.stroke, svg.icon .stroke { stroke: $stroke; vector-effect: non-scaling-stroke; }
|
||||||
|
svg.icon.off .toggle.fill,
|
||||||
|
svg.icon.off .toggle.semiFill,
|
||||||
|
svg.icon.off .toggle .fill,
|
||||||
|
svg.icon.off .toggle .semiFill { fill: none; }
|
||||||
|
svg.icon.spin, svg.icon .spin {
|
||||||
|
animation: spin 1.5s infinite linear;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
}
|
1279
embed/skins/video-js.css
Normal file
954
embed/util.js
Normal file
|
@ -0,0 +1,954 @@
|
||||||
|
var MistUtil = {
|
||||||
|
format: {
|
||||||
|
time: function(secs,options){
|
||||||
|
if (isNaN(secs) || !isFinite(secs)) { return secs; }
|
||||||
|
if (!options) { options = {}; }
|
||||||
|
|
||||||
|
var ago = (secs < 0 ? " ago" : "");
|
||||||
|
secs = Math.abs(secs);
|
||||||
|
|
||||||
|
var days = Math.floor(secs / 86400)
|
||||||
|
secs = secs - days * 86400;
|
||||||
|
var hours = Math.floor(secs / 3600);
|
||||||
|
secs = secs - hours * 3600;
|
||||||
|
var mins = Math.floor(secs / 60);
|
||||||
|
var ms = Math.round((secs % 1)*1e3);
|
||||||
|
secs = Math.floor(secs - mins * 60);
|
||||||
|
var str = [];
|
||||||
|
if (days) {
|
||||||
|
days = days+" day"+(days > 1 ? "s" : "")+", ";
|
||||||
|
}
|
||||||
|
if ((hours) || (days)) {
|
||||||
|
str.push(hours);
|
||||||
|
str.push(("0"+mins).slice(-2));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
str.push(mins); //don't use 0 padding if there are no hours in front
|
||||||
|
}
|
||||||
|
str.push(("0"+Math.floor(secs)).slice(-2));
|
||||||
|
|
||||||
|
if (options.ms) {
|
||||||
|
str[str.length-1] += "."+("000"+ms).slice(-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (days ? days : "")+str.join(":")+ago;
|
||||||
|
},
|
||||||
|
ucFirst: function(string){
|
||||||
|
return string.charAt(0).toUpperCase()+string.slice(1);
|
||||||
|
},
|
||||||
|
number: function(num) {
|
||||||
|
if ((isNaN(Number(num))) || (num == 0)) { return num; }
|
||||||
|
|
||||||
|
//rounding
|
||||||
|
//use a significance of three, but don't round "visible" digits
|
||||||
|
var sig = Math.max(3,Math.ceil(Math.log(num)/Math.LN10));
|
||||||
|
var mult = Math.pow(10,sig - Math.floor(Math.log(num)/Math.LN10) - 1);
|
||||||
|
num = Math.round(num * mult) / mult;
|
||||||
|
|
||||||
|
//thousand seperation
|
||||||
|
if (num >= 1e4) {
|
||||||
|
var seperator = " ";
|
||||||
|
number = num.toString().split(".");
|
||||||
|
var regex = /(\d+)(\d{3})/;
|
||||||
|
while (regex.test(number[0])) {
|
||||||
|
number[0] = number[0].replace(regex,"$1"+seperator+"$2");
|
||||||
|
}
|
||||||
|
num = number.join(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
},
|
||||||
|
bytes: function(val){
|
||||||
|
if (isNaN(Number(val))) { return val; }
|
||||||
|
|
||||||
|
var suffix = ["bytes","KB","MB","GB","TB","PB"];
|
||||||
|
if (val == 0) {
|
||||||
|
unit = suffix[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var exponent = Math.floor(Math.log(Math.abs(val)) / Math.log(1024));
|
||||||
|
if (exponent < 0) {
|
||||||
|
unit = suffix[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val = val / Math.pow(1024,exponent);
|
||||||
|
unit = suffix[exponent];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.number(val)+unit;
|
||||||
|
},
|
||||||
|
mime2human: function(mime){
|
||||||
|
switch (mime) {
|
||||||
|
case "html5/video/webm": {
|
||||||
|
return "WebM";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "html5/application/vnd.apple.mpegurl": {
|
||||||
|
return "HLS";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "flash/10": {
|
||||||
|
return "Flash (RTMP)";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "flash/11": {
|
||||||
|
return "Flash (HDS)";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "flash/7": {
|
||||||
|
return "Flash (Progressive)";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "html5/video/mpeg": {
|
||||||
|
return "TS";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "html5/application/vnd.ms-ss": {
|
||||||
|
return "Smooth streaming";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "dash/video/mp4": {
|
||||||
|
return "DASH";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "webrtc": {
|
||||||
|
return "WebRTC";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "silverlight": {
|
||||||
|
return "Smooth streaming (Silverlight)";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "html5/text/vtt": {
|
||||||
|
return "VTT subtitles";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "html5/text/plain": {
|
||||||
|
return "SRT subtitles";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return mime.replace("html5/","").replace("video/","").replace("audio/","").toLocaleUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
class: {
|
||||||
|
//reroute classList functionalities if not supported; also avoid indexOf
|
||||||
|
add: function(DOMelement,item){
|
||||||
|
if ("classList" in DOMelement) {
|
||||||
|
DOMelement.classList.add(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var classes = this.get(DOMelement);
|
||||||
|
|
||||||
|
classes.push(item);
|
||||||
|
this.set(DOMelement,classes);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove: function(DOMelement,item){
|
||||||
|
if ("classList" in DOMelement) {
|
||||||
|
DOMelement.classList.remove(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var classes = this.get(DOMelement);
|
||||||
|
|
||||||
|
for (var i = classes.length-1; i >= 0; i--) {
|
||||||
|
if (classes[i] == item) {
|
||||||
|
classes.splice(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.set(DOMelement,classes);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function(DOMelement) {
|
||||||
|
var classes;
|
||||||
|
var className = DOMelement.getAttribute("class"); //DOMelement.className does not work on svg elements
|
||||||
|
|
||||||
|
if ((!className) || (className == "")) { classes = []; }
|
||||||
|
else { classes = className.split(" "); }
|
||||||
|
|
||||||
|
return classes;
|
||||||
|
},
|
||||||
|
set: function(DOMelement,classes) {
|
||||||
|
DOMelement.setAttribute("class",classes.join(" "));
|
||||||
|
},
|
||||||
|
has: function(DOMelement,hasClass){
|
||||||
|
return (DOMelement.className.split(" ").indexOf(hasClass) >= 0)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
object: {
|
||||||
|
//extend object1 with object2
|
||||||
|
extend: function(object1,object2,deep) {
|
||||||
|
for (var i in object2) {
|
||||||
|
if (deep && (typeof object2[i] == "object") && (!("nodeType" in object2[i]))) {
|
||||||
|
if (!(i in object1)) {
|
||||||
|
if (MistUtil.array.is(object2[i])) {
|
||||||
|
object1[i] = [];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
object1[i] = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.extend(object1[i],object2[i],true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
object1[i] = object2[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return object1;
|
||||||
|
},
|
||||||
|
//replace Object.keys
|
||||||
|
//if sorting: sort the keys alphabetically or use passed sorting function
|
||||||
|
//sorting gets these arguments: keya,keyb,valuea,valueb
|
||||||
|
keys: function(obj,sorting){
|
||||||
|
|
||||||
|
var keys = [];
|
||||||
|
for (var i in obj) {
|
||||||
|
keys.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sorting) {
|
||||||
|
if (typeof sorting != "function") {
|
||||||
|
sorting = function(keya,keyb){
|
||||||
|
if (keya > keyb) { return 1; }
|
||||||
|
if (keya < keyb) { return -1; }
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
keys.sort(function(keya,keyb){
|
||||||
|
return sorting(keya,keyb,obj[keya],obj[keyb]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
},
|
||||||
|
//replace Object.values
|
||||||
|
//if sorting: sort the keys alphabetically or use passed sorting function
|
||||||
|
//sorting gets these arguments: keya,keyb,valuea,valueb
|
||||||
|
values: function(obj,sorting){
|
||||||
|
|
||||||
|
var keys = this.keys(obj,sorting);
|
||||||
|
|
||||||
|
values = [];
|
||||||
|
for (var i in keys) {
|
||||||
|
values.push(obj[keys[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
//replace [].indexOf
|
||||||
|
indexOf: function(array,entry) {
|
||||||
|
if (!(array instanceof Array)) { throw "Tried to use indexOf on something that is not an array"; }
|
||||||
|
if ("indexOf" in array) { return array.indexOf(entry); }
|
||||||
|
|
||||||
|
for (var i; i < array.length; i++) {
|
||||||
|
if (array[i] == entry) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
},
|
||||||
|
//replace isArray
|
||||||
|
is: function(array) {
|
||||||
|
if ("isArray" in Array) {
|
||||||
|
return Array.isArray(array);
|
||||||
|
}
|
||||||
|
return Object.prototype.toString.call(array) === '[object Array]';
|
||||||
|
},
|
||||||
|
multiSort: function (array,sortby) {
|
||||||
|
/*
|
||||||
|
MistUtil.array.multiSort([].concat(video.info.source),[
|
||||||
|
{type: ["html5/video/webm","silverlight"]} or ["type",["html5/video/webm","silverlight"]]
|
||||||
|
,{simul_tracks:-1} or ["simul_tracks",-1]
|
||||||
|
,function(a){ return a.priority * -1; }
|
||||||
|
,"url"
|
||||||
|
]);
|
||||||
|
*/
|
||||||
|
|
||||||
|
var sortfunc = function(a,b){
|
||||||
|
if (isNaN(a) || isNaN(b)) {
|
||||||
|
return a.localeCompare(b);
|
||||||
|
}
|
||||||
|
return Math.sign(a-b);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!sortby.length) { return array.sort(sortfunc); }
|
||||||
|
|
||||||
|
function getValue(key,a) {
|
||||||
|
|
||||||
|
function parseIt(item,key,sortvalue){
|
||||||
|
if (!(key in item)) {
|
||||||
|
throw "Invalid sorting rule: "+JSON.stringify([key,sortvalue])+". \""+key+"\" is not a key of "+JSON.stringify(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof sortvalue == "number") {
|
||||||
|
//deals with something like {priority: -1}
|
||||||
|
if (key in item) {
|
||||||
|
return item[key] * sortvalue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//deals with something like {type:["webrtc"]}
|
||||||
|
var i = sortvalue.indexOf(item[key])
|
||||||
|
return (i >= 0 ? i : sortvalue.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//deals with something like function(a){ return a.foo + a.bar; }
|
||||||
|
if (typeof key == "function") { return key(a); }
|
||||||
|
|
||||||
|
if (typeof key == "object") {
|
||||||
|
if (key instanceof Array) {
|
||||||
|
//it's an array
|
||||||
|
return parseIt(a,key[0],key[1]);
|
||||||
|
}
|
||||||
|
//it's an object
|
||||||
|
for (var j in key) { //only listen to a single key
|
||||||
|
return parseIt(a,j,key[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key in a) {
|
||||||
|
return a[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw "Invalid sorting rule: "+key+". This should be a function, object or key of "+JSON.stringify(a)+".";
|
||||||
|
}
|
||||||
|
|
||||||
|
array.sort(function(a,b){
|
||||||
|
var output = 0;
|
||||||
|
for (var i in sortby) {
|
||||||
|
var key = sortby[i];
|
||||||
|
output = sortfunc(getValue(key,a),getValue(key,b));
|
||||||
|
if (output != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
});
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createUnique: function() {
|
||||||
|
var i = "uid"+Math.random().toString().replace("0.","");
|
||||||
|
if (document.querySelector("."+i)) {
|
||||||
|
//if this is already used, try again
|
||||||
|
return createUnique();
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
},
|
||||||
|
|
||||||
|
http: {
|
||||||
|
getpost: function(type,url,data,callback,errorCallback) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open(type, url, true);
|
||||||
|
if (type == "POST") { xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); }
|
||||||
|
|
||||||
|
if (errorCallback) { xhr.timeout = 8e3; } //go to timeout function after 8 seconds
|
||||||
|
|
||||||
|
xhr.onload = function() {
|
||||||
|
var status = xhr.status;
|
||||||
|
if ((status >= 200) && (status < 300)) {
|
||||||
|
callback(xhr.response);
|
||||||
|
}
|
||||||
|
else if (errorCallback) {
|
||||||
|
xhr.onerror = function() {
|
||||||
|
errorCallback(xhr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (errorCallback) {
|
||||||
|
xhr.onerror = function() {
|
||||||
|
errorCallback(xhr);
|
||||||
|
}
|
||||||
|
xhr.ontimeout = xhr.onerror;
|
||||||
|
}
|
||||||
|
if (type == "POST") {
|
||||||
|
var poststr;
|
||||||
|
var post = [];
|
||||||
|
for (var i in data) {
|
||||||
|
post.push(i+"="+encodeURIComponent(data[i]));
|
||||||
|
}
|
||||||
|
if (post.length) { poststr = post.join("&"); }
|
||||||
|
xhr.send(poststr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function(url,callback,errorCallback){
|
||||||
|
this.getpost("GET",url,null,callback,errorCallback);
|
||||||
|
},
|
||||||
|
post: function(url,data,callback,errorCallback){
|
||||||
|
this.getpost("POST",url,data,callback,errorCallback);
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
addParam: function(url,params){
|
||||||
|
var spliturl = url.split("?");
|
||||||
|
var ret = [spliturl.shift()];
|
||||||
|
var splitparams = [];
|
||||||
|
if (spliturl.length) {
|
||||||
|
splitparams = spliturl[0].split("&");
|
||||||
|
}
|
||||||
|
for (var i in params) {
|
||||||
|
splitparams.push(i+"="+params[i]);
|
||||||
|
}
|
||||||
|
if (splitparams.length) { ret.push(splitparams.join("&")); }
|
||||||
|
return ret.join("?");
|
||||||
|
},
|
||||||
|
split: function(url){
|
||||||
|
var a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
return {
|
||||||
|
protocol: a.protocol,
|
||||||
|
host: a.hostname,
|
||||||
|
hash: a.hash,
|
||||||
|
port: a.port,
|
||||||
|
path: a.pathname.replace(/\/*$/,"")
|
||||||
|
};
|
||||||
|
},
|
||||||
|
sanitizeHost: function(host){
|
||||||
|
var split = MistUtil.http.url.split(host);
|
||||||
|
return split.protocol + "//" + split.host + (split.port && (split.port != "") ? ":"+split.port : "") + (split.hash && (split.hash != "") ? "#"+split.hash : "") + (split.path ? split.path : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
css: {
|
||||||
|
cache: {},
|
||||||
|
load: function(url,colors,callback){
|
||||||
|
var style = document.createElement("style");
|
||||||
|
style.type = "text/css";
|
||||||
|
style.setAttribute("data-source",url);
|
||||||
|
if (callback) { style.callback = callback; }
|
||||||
|
var cache = this.cache;
|
||||||
|
|
||||||
|
function onCSSLoad(d) {
|
||||||
|
//parse rules and replace variables; expected syntax $abc[.abc]
|
||||||
|
var css = MistUtil.css.applyColors(d,colors);
|
||||||
|
|
||||||
|
if ("callback" in style) { style.callback(css); }
|
||||||
|
else { style.textContent = css; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url in cache) {
|
||||||
|
if (cache[url] instanceof Array) {
|
||||||
|
cache[url].push(onCSSLoad);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
onCSSLoad(cache[url]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//retrieve file contents
|
||||||
|
cache[url] = [onCSSLoad];
|
||||||
|
MistUtil.http.get(url,function(d){
|
||||||
|
for (var i in cache[url]) {
|
||||||
|
cache[url][i](d);
|
||||||
|
}
|
||||||
|
cache[url] = d;
|
||||||
|
},function(){
|
||||||
|
throw "Failed to load CSS from "+url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return style; //its empty now, but will be filled on load
|
||||||
|
},
|
||||||
|
applyColors: function(css,colors) {
|
||||||
|
return css.replace(/\$([^\s^;^}]*)/g,function(str,variable){
|
||||||
|
var index = variable.split(".");
|
||||||
|
var val = colors;
|
||||||
|
for (var j in index) {
|
||||||
|
val = val[index[j]];
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
createStyle: function(css,prepend,applyToChildren){
|
||||||
|
var style = document.createElement("style");
|
||||||
|
style.type = "text/css";
|
||||||
|
|
||||||
|
if (css) {
|
||||||
|
if (prepend) {
|
||||||
|
css = this.prependClass(css,prepend,applyToChildren);
|
||||||
|
}
|
||||||
|
style.textContent = css;
|
||||||
|
}
|
||||||
|
|
||||||
|
return style;
|
||||||
|
},
|
||||||
|
prependClass: function (css,prepend,applyToChildren) {
|
||||||
|
var style = false;
|
||||||
|
if (typeof css != "string") {
|
||||||
|
style = css;
|
||||||
|
if (!("unprepended" in style)) {
|
||||||
|
style.unprepended = style.textContent;
|
||||||
|
}
|
||||||
|
css = style.unprepended;
|
||||||
|
}
|
||||||
|
//remove all block comments
|
||||||
|
css = css.replace(/\/\*.*?\*\//g,"");
|
||||||
|
|
||||||
|
//save all @{} blocks
|
||||||
|
var save = css.match(/@.*?{.*}/g);
|
||||||
|
for (var i in save) {
|
||||||
|
css = css.replace(save[i],"@@@@");
|
||||||
|
}
|
||||||
|
|
||||||
|
//find and replace selectors
|
||||||
|
css = css.replace(/[^@]*?{[^]*?}/g,function(match){
|
||||||
|
var split = match.split("{")
|
||||||
|
var selectors = split[0].split(",");
|
||||||
|
var properties = "{"+split.slice(1).join("}");
|
||||||
|
|
||||||
|
for (var i in selectors) {
|
||||||
|
selectors[i] = selectors[i].trim();
|
||||||
|
var str = "."+prepend+selectors[i];
|
||||||
|
if (applyToChildren) {
|
||||||
|
str += ",\n."+prepend+" "+selectors[i];
|
||||||
|
}
|
||||||
|
selectors[i] = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return "\n"+selectors+" "+properties;
|
||||||
|
});
|
||||||
|
|
||||||
|
//reinsert saved blocks
|
||||||
|
for (var i in save) {
|
||||||
|
css = css.replace(/@@@@/,save[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style) {
|
||||||
|
style.textContent = css;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return css;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
empty: function(DOMelement) {
|
||||||
|
while (DOMelement.lastChild){
|
||||||
|
if (DOMelement.lastChild.lastChild) {
|
||||||
|
//also empty this child
|
||||||
|
this.empty(DOMelement.lastChild);
|
||||||
|
}
|
||||||
|
if ("attachedListeners" in DOMelement.lastChild) {
|
||||||
|
//remove attached event listeners
|
||||||
|
for (var i in DOMelement.lastChild.attachedListeners) {
|
||||||
|
MistUtil.event.removeListener(DOMelement.lastChild.attachedListeners[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DOMelement.removeChild(DOMelement.lastChild);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
event: {
|
||||||
|
send: function(type,message,target){
|
||||||
|
try {
|
||||||
|
var event = new Event(type,{
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true
|
||||||
|
});
|
||||||
|
event.message = message;
|
||||||
|
target.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
try {
|
||||||
|
var event = document.createEvent('Event');
|
||||||
|
event.initEvent(type,true,true);
|
||||||
|
event.message = message;
|
||||||
|
target.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
catch (e) { return false; }
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
addListener: function(DOMelement,type,callback,storeOnElement) {
|
||||||
|
//add an event listener and store the handles, so they can be cleared
|
||||||
|
|
||||||
|
DOMelement.addEventListener(type,callback);
|
||||||
|
|
||||||
|
if (!storeOnElement) { storeOnElement = DOMelement; }
|
||||||
|
if (!("attachedListeners" in storeOnElement)) {
|
||||||
|
storeOnElement.attachedListeners = [];
|
||||||
|
}
|
||||||
|
var output = {
|
||||||
|
element: DOMelement,
|
||||||
|
type: type,
|
||||||
|
callback: callback
|
||||||
|
};
|
||||||
|
|
||||||
|
storeOnElement.attachedListeners.push(output);
|
||||||
|
return output;
|
||||||
|
},
|
||||||
|
removeListener: function(data) {
|
||||||
|
data.element.removeEventListener(data.type, data.callback);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
scripts: {
|
||||||
|
list: {},
|
||||||
|
insert: function(src,onevent,MistVideo){
|
||||||
|
var scripts = this;
|
||||||
|
|
||||||
|
if (MistVideo) {
|
||||||
|
//register so we can remove it on unload
|
||||||
|
MistVideo.errorListeners.push({
|
||||||
|
src: src,
|
||||||
|
onevent: onevent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (src in this.list) {
|
||||||
|
//already present
|
||||||
|
//register to error listening
|
||||||
|
this.list[src].subscribers.push(onevent.onerror);
|
||||||
|
//execute onload
|
||||||
|
if ("onload" in onevent) {
|
||||||
|
if (this.hasLoaded) {
|
||||||
|
onevent.onload();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MistUtil.event.addListener(this.list[src].tag,"load",onevent.onload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var scripttag = document.createElement("script");
|
||||||
|
scripttag.hasLoaded = false;
|
||||||
|
scripttag.setAttribute("src",src);
|
||||||
|
scripttag.setAttribute("crossorigin","anonymous"); //must be set to get info about errors thrown
|
||||||
|
document.head.appendChild(scripttag);
|
||||||
|
scripttag.onerror = function(e){
|
||||||
|
onevent.onerror(e);
|
||||||
|
}
|
||||||
|
scripttag.onload = function(e){
|
||||||
|
this.hasLoaded = true;
|
||||||
|
if (!MistVideo.destroyed) { onevent.onload(e); }
|
||||||
|
}
|
||||||
|
scripttag.addEventListener("error",function(e){
|
||||||
|
onevent.onerror(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//error catching
|
||||||
|
var oldonerror = false;
|
||||||
|
if (window.onerror) {
|
||||||
|
oldonerror = window.onerror;
|
||||||
|
}
|
||||||
|
window.onerror = function(message,source,line,column,error){
|
||||||
|
if (oldonerror) {
|
||||||
|
oldonerror.apply(this,arguments);
|
||||||
|
}
|
||||||
|
if (source == src) {
|
||||||
|
onevent.onerror(error);
|
||||||
|
for (var i in scripts.list[src].subscribers) {
|
||||||
|
scripts.list[src].subscribers[i](error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.list[src] = {
|
||||||
|
subscribers: [onevent.onerror],
|
||||||
|
tag: scripttag
|
||||||
|
};
|
||||||
|
|
||||||
|
return scripttag;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
tracks: {
|
||||||
|
parse: function(metaTracks){
|
||||||
|
var output = {};
|
||||||
|
for (var i in metaTracks) {
|
||||||
|
var track = MistUtil.object.extend({},metaTracks[i]);
|
||||||
|
if (track.type == "meta") {
|
||||||
|
track.type = track.codec;
|
||||||
|
track.codec = "meta";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(track.type in output)) { output[track.type] = {}; }
|
||||||
|
output[track.type][track.trackid] = track;
|
||||||
|
|
||||||
|
//make up something logical for the track displayname
|
||||||
|
var name = {};
|
||||||
|
|
||||||
|
for (var j in track) {
|
||||||
|
switch (j) {
|
||||||
|
case "width":
|
||||||
|
name[j] = track.width+"×"+track.height;
|
||||||
|
break;
|
||||||
|
case "bps":
|
||||||
|
if (track.codec == "meta") { continue; }
|
||||||
|
if (track.bps > 0) {
|
||||||
|
var val;
|
||||||
|
if (track.bps > 1024*1024/8) {
|
||||||
|
val = Math.round(track.bps/1024/1024*8)+"mbps";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val = Math.round(track.bps/1024*8)+"kbps";
|
||||||
|
}
|
||||||
|
name[j] = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "fpks":
|
||||||
|
if (track.fpks > 0) {
|
||||||
|
name[j] = track.fpks/1e3+"fps";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "channels":
|
||||||
|
if (track.channels > 0) {
|
||||||
|
name[j] = (track.channels == 1 ? "Mono" : (track.channels == 2 ? "Stereo" : "Surround ("+track.channels+"ch)"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "rate":
|
||||||
|
name[j] = Math.round(track.rate)+"Khz";
|
||||||
|
break;
|
||||||
|
case "language":
|
||||||
|
if (track[j] != "Undetermined") { name[j] = track[j]; }
|
||||||
|
break;
|
||||||
|
case "codec":
|
||||||
|
if (track.codec == "meta") { continue; }
|
||||||
|
name[j] = track[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track.describe = name;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//filter what to display based on what is different
|
||||||
|
for (var type in output) {
|
||||||
|
var equal = false;
|
||||||
|
for (var i in output[type]) {
|
||||||
|
if (!equal) {
|
||||||
|
//fill equal with all the keys and values of the first track of this type
|
||||||
|
equal = MistUtil.object.extend({},output[type][i].describe);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (MistUtil.object.keys(output[type]).length > 1) {
|
||||||
|
//if there is more than one track of this type
|
||||||
|
for (var j in output[type][i].describe) {
|
||||||
|
if (equal[j] != output[type][i].describe[j]) {
|
||||||
|
//remove key from equal if not equal
|
||||||
|
delete equal[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//apply
|
||||||
|
for (var i in output[type]) {
|
||||||
|
var different = {};
|
||||||
|
var same = {};
|
||||||
|
for (var j in output[type][i].describe) {
|
||||||
|
if (!(j in equal)){
|
||||||
|
different[j] = output[type][i].describe[j];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
same[j] = output[type][i].describe[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output[type][i].different = different;
|
||||||
|
output[type][i].same = same;
|
||||||
|
var d = MistUtil.object.values(different);
|
||||||
|
output[type][i].displayName = (d.length ? d.join(", ") : MistUtil.object.values(output[type][i].describe).join(" "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isTouchDevice: function(){
|
||||||
|
return (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
|
||||||
|
//return true;
|
||||||
|
},
|
||||||
|
getPos: function(element,cursorLocation){
|
||||||
|
var style = element.currentStyle || window.getComputedStyle(element, null);
|
||||||
|
|
||||||
|
var zoom = 1;
|
||||||
|
var node = element;
|
||||||
|
while (node) {
|
||||||
|
if ((node.style.zoom) && (node.style.zoom != "")) {
|
||||||
|
zoom *= parseFloat(node.style.zoom,10);
|
||||||
|
}
|
||||||
|
node = node.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pos0 = element.getBoundingClientRect().left - (parseInt(element.borderLeftWidth,10) || 0);
|
||||||
|
|
||||||
|
var width = element.getBoundingClientRect().width;;
|
||||||
|
var perc = Math.max(0,((cursorLocation.clientX/zoom) - pos0) / width);
|
||||||
|
perc = Math.min(perc,1);
|
||||||
|
|
||||||
|
return perc;
|
||||||
|
},
|
||||||
|
|
||||||
|
createGraph: function(data,options){
|
||||||
|
var ns = "http://www.w3.org/2000/svg";
|
||||||
|
|
||||||
|
var svg = document.createElementNS(ns,"svg");
|
||||||
|
svg.setAttributeNS(null,"height","100%");
|
||||||
|
svg.setAttributeNS(null,"width","100%");
|
||||||
|
svg.setAttributeNS(null,"class","mist icon graph");
|
||||||
|
svg.setAttributeNS(null,"preserveAspectRatio","none");
|
||||||
|
|
||||||
|
var x_correction = data.x[0];
|
||||||
|
var lasty = data.y[0];
|
||||||
|
if (options.differentiate) {
|
||||||
|
for (var i = 1; i < data.y.length; i++) {
|
||||||
|
var diff = data.y[i] - lasty;
|
||||||
|
lasty = data.y[i];
|
||||||
|
data.y[i] = diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = [];
|
||||||
|
var area = {
|
||||||
|
x: {
|
||||||
|
min: data.x[0] - x_correction,
|
||||||
|
max: data.x[0] - x_correction
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
min: data.y[0]*-1,
|
||||||
|
max: data.y[0]*-1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateMinMax(x,y) {
|
||||||
|
if (arguments.length) {
|
||||||
|
area.x.min = Math.min(area.x.min,x);
|
||||||
|
area.x.max = Math.max(area.x.max,x);
|
||||||
|
area.y.min = Math.min(area.y.min,y*-1);
|
||||||
|
area.y.max = Math.max(area.y.max,y*-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//reprocess the entire path
|
||||||
|
var d = path[0].split(",");
|
||||||
|
area = {
|
||||||
|
x: {
|
||||||
|
min: d[0],
|
||||||
|
max: d[0]
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
min: d[1],
|
||||||
|
max: d[1]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (var i = 1; i < path.length; i++) {
|
||||||
|
var d = path[i].split(",");
|
||||||
|
updateMinMax(d[0],d[1]*-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path.push([data.x[0] - x_correction,data.y[0]*-1].join(","));
|
||||||
|
for (var i = 1; i < data.y.length; i++) {
|
||||||
|
updateMinMax(data.x[i] - x_correction,data.y[i]*-1);
|
||||||
|
path.push("L "+[data.x[i] - x_correction,data.y[i]*-1].join(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
//define gradient
|
||||||
|
var defs = document.createElementNS(ns,"defs");
|
||||||
|
svg.appendChild(defs);
|
||||||
|
var gradient = document.createElementNS(ns,"linearGradient");
|
||||||
|
defs.appendChild(gradient);
|
||||||
|
gradient.setAttributeNS(null,"id",MistUtil.createUnique());
|
||||||
|
gradient.setAttributeNS(null,"gradientUnits","userSpaceOnUse");
|
||||||
|
gradient.innerHTML += '<stop offset="0" stop-color="green"/>';
|
||||||
|
gradient.innerHTML += '<stop offset="0.33" stop-color="yellow"/>';
|
||||||
|
gradient.innerHTML += '<stop offset="0.66" stop-color="orange"/>';
|
||||||
|
gradient.innerHTML += '<stop offset="1" stop-color="red"/>';
|
||||||
|
|
||||||
|
function updateViewBox() {
|
||||||
|
if ("x" in options) {
|
||||||
|
if ("min" in options.x) { area.x.min = options.x.min; }
|
||||||
|
if ("max" in options.x) { area.x.max = options.x.max; }
|
||||||
|
if ("count" in options.x) { area.x.min = area.x.max - options.x.count; }
|
||||||
|
}
|
||||||
|
if ("y" in options) {
|
||||||
|
if ("min" in options.y) { area.y.min = options.y.max*-1; }
|
||||||
|
if ("max" in options.y) { area.y.max = options.y.min*-1; }
|
||||||
|
}
|
||||||
|
svg.setAttributeNS(null,"viewBox",[area.x.min,area.y.min,area.x.max - area.x.min,area.y.max - area.y.min].join(" "));
|
||||||
|
|
||||||
|
gradient.setAttributeNS(null,"x1",0);
|
||||||
|
gradient.setAttributeNS(null,"x2",0);
|
||||||
|
if (options.reverseGradient) {
|
||||||
|
gradient.setAttributeNS(null,"y1",area.y.max);
|
||||||
|
gradient.setAttributeNS(null,"y2",area.y.min);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gradient.setAttributeNS(null,"y1",area.y.min);
|
||||||
|
gradient.setAttributeNS(null,"y2",area.y.max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateViewBox();
|
||||||
|
|
||||||
|
var line = document.createElementNS(ns,"path");
|
||||||
|
svg.appendChild(line);
|
||||||
|
//line.setAttributeNS(null,"vector-effect","non-scaling-stroke");
|
||||||
|
line.setAttributeNS(null,"stroke-width","0.1");
|
||||||
|
line.setAttributeNS(null,"fill","none");
|
||||||
|
line.setAttributeNS(null,"stroke","url(#"+gradient.getAttribute("id")+")");
|
||||||
|
line.setAttributeNS(null,"d","M"+path.join(" L"));
|
||||||
|
|
||||||
|
line.addData = function(newData) {
|
||||||
|
|
||||||
|
if (options.differentiate) {
|
||||||
|
var diff = newData.y - lasty;
|
||||||
|
lasty = newData.y;
|
||||||
|
newData.y = diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
path.push([newData.x - x_correction,newData.y*-1].join(","));
|
||||||
|
if (options.x && options.x.count) {
|
||||||
|
if (path.length > options.x.count) {
|
||||||
|
path.shift();
|
||||||
|
updateMinMax();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateMinMax(newData.x - x_correction,newData.y*-1);
|
||||||
|
this.setAttributeNS(null,"d","M"+path.join(" L"));
|
||||||
|
updateViewBox();
|
||||||
|
};
|
||||||
|
svg.addData = function(newData){
|
||||||
|
line.addData(newData);
|
||||||
|
};
|
||||||
|
|
||||||
|
return svg;
|
||||||
|
},
|
||||||
|
getBrowser: function(){
|
||||||
|
var ua = window.navigator.userAgent;
|
||||||
|
|
||||||
|
if ((ua.indexOf("MSIE ") >= 0) || (ua.indexOf("Trident/") >= 0)) {
|
||||||
|
return "ie";
|
||||||
|
}
|
||||||
|
if (ua.indexOf("Edge/") >= 0) {
|
||||||
|
return "edge";
|
||||||
|
}
|
||||||
|
if ((ua.indexOf("Opera") >= 0) || (ua.indexOf('OPR') >= 0)) {
|
||||||
|
return "opera";
|
||||||
|
}
|
||||||
|
if (ua.indexOf("Chrome") >= 0) {
|
||||||
|
return "chrome";
|
||||||
|
}
|
||||||
|
if (ua.indexOf("Safari") >= 0) {
|
||||||
|
return "safari";
|
||||||
|
}
|
||||||
|
if (ua.indexOf("Firefox") >= 0) {
|
||||||
|
return "firefox";
|
||||||
|
}
|
||||||
|
return false; //unknown
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,162 +1,216 @@
|
||||||
mistplayers.dashjs = {
|
mistplayers.dashjs = {
|
||||||
name: 'Dash.js Player',
|
name: "Dash.js player",
|
||||||
version: '1.2',
|
mimes: ["dash/video/mp4"/*,"html5/application/vnd.ms-ss"*/],
|
||||||
mimes: ['dash/video/mp4'],
|
priority: MistUtil.object.keys(mistplayers).length + 1,
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
isMimeSupported: function (mimetype) {
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
return (MistUtil.array.indexOf(this.mimes,mimetype) == -1 ? false : true);
|
||||||
},
|
},
|
||||||
isBrowserSupported: function (mimetype,source,options) {
|
isBrowserSupported: function (mimetype,source,MistVideo) {
|
||||||
if ((options.host.substr(0,7) == 'http://') && (source.url.substr(0,8) == 'https://')) { return false; }
|
|
||||||
return (('MediaSource' in window) && (location.protocol != 'file:'));
|
//check for http/https mismatch
|
||||||
|
if (location.protocol != MistUtil.http.url.split(source.url).protocol) {
|
||||||
|
MistVideo.log("HTTP/HTTPS mismatch for this source");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//don't use dashjs if this location is loaded over file://
|
||||||
|
if (location.protocol == "file:") {
|
||||||
|
MistVideo.log("This source ("+mimetype+") won't load if the page is run via file://");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ("MediaSource" in window);
|
||||||
},
|
},
|
||||||
player: function(){this.onreadylist = [];}
|
player: function(){this.onreadylist = [];},
|
||||||
|
scriptsrc: function(host) { return host+"/dashjs.js"; }
|
||||||
};
|
};
|
||||||
var p = mistplayers.dashjs.player;
|
var p = mistplayers.dashjs.player;
|
||||||
p.prototype = new MistPlayer();
|
p.prototype = new MistPlayer();
|
||||||
p.prototype.build = function (options,callback) {
|
p.prototype.build = function (MistVideo,callback) {
|
||||||
var cont = document.createElement('div');
|
|
||||||
cont.className = 'mistplayer';
|
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
function onplayerload () {
|
this.onDashLoad = function() {
|
||||||
var ele = me.getElement('video');
|
if (MistVideo.destroyed) { return; }
|
||||||
ele.className = '';
|
|
||||||
cont.appendChild(ele);
|
|
||||||
ele.width = options.width;
|
|
||||||
ele.height = options.height;
|
|
||||||
|
|
||||||
if (options.autoplay) {
|
MistVideo.log("Building DashJS player..");
|
||||||
ele.setAttribute('autoplay','');
|
|
||||||
}
|
|
||||||
if (options.loop) {
|
|
||||||
ele.setAttribute('loop','');
|
|
||||||
}
|
|
||||||
if (options.poster) {
|
|
||||||
ele.setAttribute('poster',options.poster);
|
|
||||||
}
|
|
||||||
if (options.controls) {
|
|
||||||
if (options.controls == 'stock') {
|
|
||||||
ele.setAttribute('controls','');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
me.buildMistControls();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ele.addEventListener('error',function(e){
|
var ele = document.createElement("video");
|
||||||
var msg;
|
|
||||||
if ('message' in e) {
|
if ("Proxy" in window) {
|
||||||
msg = e.message;
|
var overrides = {
|
||||||
|
get: {},
|
||||||
|
set: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
MistVideo.player.api = new Proxy(ele,{
|
||||||
|
get: function(target, key, receiver){
|
||||||
|
if (key in overrides.get) {
|
||||||
|
return overrides.get[key].apply(target, arguments);
|
||||||
}
|
}
|
||||||
else {
|
var method = target[key];
|
||||||
msg = 'readyState: ';
|
if (typeof method === "function"){
|
||||||
switch (me.element.readyState) {
|
return function () {
|
||||||
case 0:
|
return method.apply(target, arguments);
|
||||||
msg += 'HAVE_NOTHING';
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
msg += 'HAVE_METADATA';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
msg += 'HAVE_CURRENT_DATA';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
msg += 'HAVE_FUTURE_DATA';
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
msg += 'HAVE_ENOUGH_DATA';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
msg += ' networkState: ';
|
|
||||||
switch (me.element.networkState) {
|
|
||||||
case 0:
|
|
||||||
msg += 'NETWORK_EMPTY';
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
msg += 'NETWORK_IDLE';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
msg += 'NETWORK_LOADING';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
msg += 'NETWORK_NO_SOURCE';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//prevent onerror loops
|
return method;
|
||||||
if (e.target == me.element) {
|
},
|
||||||
e.message = msg;
|
set: function(target, key, value) {
|
||||||
|
if (key in overrides.set) {
|
||||||
|
return overrides.set[key].call(target,value);
|
||||||
}
|
}
|
||||||
else {
|
return target[key] = value;
|
||||||
me.adderror(msg);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var events = ['abort','canplay','canplaythrough','durationchange','emptied','ended','interruptbegin','interruptend','loadeddata','loadedmetadata','loadstart','pause','play','playing','ratechange','seeked','seeking','stalled','volumechange','waiting'];
|
|
||||||
for (var i in events) {
|
if (MistVideo.info.type == "live") {
|
||||||
ele.addEventListener(events[i],function(e){
|
overrides.get.duration = function(){
|
||||||
me.addlog('Player event fired: '+e.type);
|
//this should indicate the end of Mist's buffer
|
||||||
|
var buffer_end = 0;
|
||||||
|
if (this.buffered.length) {
|
||||||
|
buffer_end = this.buffered.end(this.buffered.length-1)
|
||||||
|
}
|
||||||
|
var time_since_buffer = (new Date().getTime() - MistVideo.player.api.lastProgress.getTime())*1e-3;
|
||||||
|
return buffer_end + time_since_buffer + -1*MistVideo.player.api.liveOffset + 45;
|
||||||
|
};
|
||||||
|
overrides.set.currentTime = function(value){
|
||||||
|
var offset = value - MistVideo.player.api.duration;
|
||||||
|
//MistVideo.player.api.liveOffset = offset;
|
||||||
|
|
||||||
|
MistVideo.log("Seeking to "+MistUtil.format.time(value)+" ("+Math.round(offset*-10)/10+"s from live)");
|
||||||
|
|
||||||
|
MistVideo.video.currentTime = value;
|
||||||
|
//.player.api.setSource(MistUtil.http.url.addParam(MistVideo.source.url,{startunix:offset}));
|
||||||
|
}
|
||||||
|
MistUtil.event.addListener(ele,"progress",function(){
|
||||||
|
MistVideo.player.api.lastProgress = new Date();
|
||||||
});
|
});
|
||||||
|
MistVideo.player.api.lastProgress = new Date();
|
||||||
|
MistVideo.player.api.liveOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
me.api = ele;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MistVideo.options.autoplay) {
|
||||||
|
ele.setAttribute("autoplay","");
|
||||||
|
}
|
||||||
|
if ((MistVideo.options.loop) && (MistVideo.info.type != "live")) {
|
||||||
|
ele.setAttribute("loop","");
|
||||||
|
}
|
||||||
|
if (MistVideo.options.poster) {
|
||||||
|
ele.setAttribute("poster",MistVideo.options.poster);
|
||||||
|
}
|
||||||
|
if (MistVideo.options.controls == "stock") {
|
||||||
|
ele.setAttribute("controls","");
|
||||||
}
|
}
|
||||||
|
|
||||||
var player = dashjs.MediaPlayer().create();
|
var player = dashjs.MediaPlayer().create();
|
||||||
player.getDebug().setLogToBrowserConsole(false);
|
//player.getDebug().setLogToBrowserConsole(false);
|
||||||
player.initialize(ele,options.src,true);
|
player.initialize(ele,MistVideo.source.url,MistVideo.options.autoplay);
|
||||||
|
|
||||||
|
|
||||||
me.dash = player;
|
me.dash = player;
|
||||||
me.src = options.src;
|
|
||||||
|
|
||||||
|
//add listeners for events that we can log
|
||||||
me.addlog('Built html');
|
var skipEvents = ["METRIC_ADDED","METRIC_CHANGED","METRICS_CHANGED","FRAGMENT_LOADING_STARTED","FRAGMENT_LOADING_COMPLETED","LOG","PLAYBACK_TIME_UPDATED","PLAYBACK_PROGRESS"];
|
||||||
callback(cont);
|
for (var i in dashjs.MediaPlayer.events) {
|
||||||
|
if (skipEvents.indexOf(i) < 0) {
|
||||||
|
me.dash.on(dashjs.MediaPlayer.events[i],function(e){
|
||||||
|
MistVideo.log("Player event fired: "+e.type);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('dash' in window) {
|
MistVideo.player.setSize = function(size){
|
||||||
onplayerload();
|
this.api.style.width = size.width+"px";
|
||||||
}
|
this.api.style.height = size.height+"px";
|
||||||
else {
|
|
||||||
//load the dashjs player
|
|
||||||
var scripttag = document.createElement('script');
|
|
||||||
scripttag.src = options.host+'/dashjs.js';
|
|
||||||
me.addlog('Retrieving dashjs player code from '+scripttag.src);
|
|
||||||
document.head.appendChild(scripttag);
|
|
||||||
scripttag.onerror = function(){
|
|
||||||
me.askNextCombo('Failed to load dashjs.js');
|
|
||||||
}
|
|
||||||
scripttag.onload = function(){
|
|
||||||
onplayerload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.prototype.play = function(){ return this.element.play(); };
|
|
||||||
p.prototype.pause = function(){ return this.element.pause(); };
|
|
||||||
p.prototype.volume = function(level){
|
|
||||||
if (typeof level == 'undefined' ) { return this.element.volume; }
|
|
||||||
return this.element.volume = level;
|
|
||||||
};
|
|
||||||
p.prototype.play = function(){ return this.element.play(); };
|
|
||||||
p.prototype.load = function(){ return this.element.load(); };
|
|
||||||
if (document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
|
|
||||||
p.prototype.fullscreen = function(){
|
|
||||||
if(this.element.requestFullscreen) {
|
|
||||||
return this.element.requestFullscreen();
|
|
||||||
} else if(this.element.mozRequestFullScreen) {
|
|
||||||
return this.element.mozRequestFullScreen();
|
|
||||||
} else if(this.element.webkitRequestFullscreen) {
|
|
||||||
return this.element.webkitRequestFullscreen();
|
|
||||||
} else if(this.element.msRequestFullscreen) {
|
|
||||||
return this.element.msRequestFullscreen();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
MistVideo.player.api.setSource = function(url) {
|
||||||
p.prototype.resize = function(size){
|
MistVideo.player.dash.attachSource(url);
|
||||||
this.element.width = size.width;
|
};
|
||||||
this.element.height = size.height;
|
|
||||||
};
|
//trackswitching
|
||||||
p.prototype.updateSrc = function(src){
|
MistVideo.player.api.setTrack = function(type,id){
|
||||||
if (src == '') {
|
var meta = MistUtil.tracks.parse(MistVideo.info.meta.tracks);
|
||||||
this.dash.reset();
|
if ((!(type in meta)) || ((!(id in meta[type]) && (id != 0)))) {
|
||||||
|
MistVideo.log("Skipping trackselection of "+type+" track "+id+" because it does not exist");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.dash.attachSource(src);
|
|
||||||
return true;
|
//figure out what the track number is
|
||||||
};
|
//whyyyy did it have to be reverse order
|
||||||
|
var n = me.dash.getBitrateInfoListFor("video").length - 1;
|
||||||
|
for (var i in MistVideo.info.meta.tracks) {
|
||||||
|
var t = MistVideo.info.meta.tracks[i];
|
||||||
|
if (t.type == type) {
|
||||||
|
if (t.trackid == id) { break; }
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
me.dash.setAutoSwitchQualityFor(type,false); //turn off ABR rules //TODO do we want this by default?
|
||||||
|
me.dash.setFastSwitchEnabled(true); //show the new track asap
|
||||||
|
me.dash.setQualityFor(type,n);
|
||||||
|
//dash does change the track, but is appended to the buffer, so it seems to take a while..
|
||||||
|
}
|
||||||
|
|
||||||
|
//react to automatic trackswitching
|
||||||
|
me.dash.on("qualityChangeRendered",function(e){
|
||||||
|
//the newQuality-th track of type mediaType is being selected
|
||||||
|
|
||||||
|
//figure out the track id
|
||||||
|
//whyyyy did it have to be reverse order
|
||||||
|
var n = me.dash.getBitrateInfoListFor("video").length - 1;
|
||||||
|
var id;
|
||||||
|
for (var i in MistVideo.info.meta.tracks) {
|
||||||
|
var t = MistVideo.info.meta.tracks[i];
|
||||||
|
if (t.type == e.mediaType) {
|
||||||
|
if (e.newQuality == n) {
|
||||||
|
id = t.trackid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//create an event to pass this to the skin
|
||||||
|
MistUtil.event.send("playerUpdate_trackChanged",{
|
||||||
|
type: e.mediaType,
|
||||||
|
trackid: id
|
||||||
|
},MistVideo.video);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//dashjs keeps on spamming the stalled icon >_>
|
||||||
|
MistUtil.event.addListener(ele,"progress",function(e){
|
||||||
|
if (MistVideo.container.getAttribute("data-loading") == "stalled") {
|
||||||
|
MistVideo.container.removeAttribute("data-loading");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
me.api.unload = function(){
|
||||||
|
me.dash.reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
MistVideo.log("Built html");
|
||||||
|
callback(ele);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("dashjs" in window) {
|
||||||
|
this.onDashLoad();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
var scripttag = MistUtil.scripts.insert(MistVideo.urlappend(mistplayers.dashjs.scriptsrc(MistVideo.options.host)),{
|
||||||
|
onerror: function(e){
|
||||||
|
var msg = "Failed to load dashjs.js";
|
||||||
|
if (e.message) { msg += ": "+e.message; }
|
||||||
|
MistVideo.showError(msg);
|
||||||
|
},
|
||||||
|
onload: me.onDashLoad
|
||||||
|
},MistVideo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,26 +1,37 @@
|
||||||
mistplayers.flash_strobe = {
|
mistplayers.flash_strobe = {
|
||||||
name: 'Strobe Flash Media Playback',
|
name: "Strobe Flash media playback",
|
||||||
version: '1.1',
|
mimes: ["flash/10","flash/11","flash/7"],
|
||||||
mimes: ['flash/10','flash/11','flash/7'],
|
priority: MistUtil.object.keys(mistplayers).length + 1,
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
isMimeSupported: function (mimetype) {
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
||||||
},
|
},
|
||||||
isBrowserSupported: function (mimetype,source,options) {
|
isBrowserSupported: function (mimetype,source,MistVideo) {
|
||||||
//check for http / https crossovers
|
|
||||||
if ((options.host.substr(0,7) == 'http://') && (source.url.substr(0,8) == 'https://')) { return false; }
|
//check for http/https mismatch
|
||||||
|
if ((MistUtil.http.url.split(source.url).protocol.slice(0,4) == "http") && (location.protocol != MistUtil.http.url.split(source.url).protocol)) {
|
||||||
|
MistVideo.log("HTTP/HTTPS mismatch for this source");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var version = 0;
|
var version = 0;
|
||||||
try {
|
try {
|
||||||
// check in the mimeTypes
|
// check in the mimeTypes
|
||||||
version = navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin.description.replace(/([^0-9\.])/g, '').split('.')[0];
|
var plugin = navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin;
|
||||||
|
if (plugin.version) { version = plugin.version.split(".")[0]; }
|
||||||
|
else { version = plugin.description.replace(/([^0-9\.])/g, "").split(".")[0]; }
|
||||||
} catch(e){}
|
} catch(e){}
|
||||||
try {
|
try {
|
||||||
// for our special friend IE
|
// for our special friend IE
|
||||||
version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable("$version").replace(/([^0-9\,])/g, '').split(',')[0];
|
version = new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/([^0-9\,])/g, "").split(",")[0];
|
||||||
} catch(e){}
|
} catch(e){}
|
||||||
|
|
||||||
var mimesplit = mimetype.split('/');
|
if (!version) {
|
||||||
|
//flash is not enabled? Might need to ask permission first.
|
||||||
|
//TODO how? just let it build?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mimesplit = mimetype.split("/");
|
||||||
|
|
||||||
return Number(version) >= Number(mimesplit[mimesplit.length-1]);
|
return Number(version) >= Number(mimesplit[mimesplit.length-1]);
|
||||||
},
|
},
|
||||||
|
@ -28,39 +39,53 @@ mistplayers.flash_strobe = {
|
||||||
};
|
};
|
||||||
var p = mistplayers.flash_strobe.player;
|
var p = mistplayers.flash_strobe.player;
|
||||||
p.prototype = new MistPlayer();
|
p.prototype = new MistPlayer();
|
||||||
p.prototype.build = function (options,callback) {
|
p.prototype.build = function (MistVideo,callback) {
|
||||||
|
|
||||||
|
var ele = document.createElement("object");
|
||||||
|
var e = document.createElement("embed");
|
||||||
|
ele.appendChild(e);
|
||||||
|
|
||||||
|
function build(source) {
|
||||||
|
var options = MistVideo.options;
|
||||||
function createParam(name,value) {
|
function createParam(name,value) {
|
||||||
var p = document.createElement('param');
|
var p = document.createElement("param");
|
||||||
p.setAttribute('name',name);
|
p.setAttribute("name",name);
|
||||||
p.setAttribute('value',value);
|
p.setAttribute("value",value);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MistUtil.empty(ele);
|
||||||
var ele = this.getElement('object');
|
ele.appendChild(createParam("movie",MistVideo.urlappend(options.host+MistVideo.source.player_url)));
|
||||||
|
var flashvars = "src="+encodeURIComponent(source)+"&controlBarMode="+(options.controls ? "floating" : "none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(options.live ? "&streamType=live" : "")+(options.autoplay ? "&autoPlay=true" : "" );
|
||||||
ele.setAttribute('width',options.width);
|
ele.appendChild(createParam("flashvars",flashvars));
|
||||||
ele.setAttribute('height',options.height);
|
ele.appendChild(createParam("allowFullScreen","true"));
|
||||||
|
ele.appendChild(createParam("wmode","direct"));
|
||||||
ele.appendChild(createParam('movie',options.host+options.source.player_url));
|
|
||||||
var flashvars = 'src='+encodeURIComponent(options.src)+'&controlBarMode='+(options.controls ? 'floating' : 'none')+'&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3'+(options.live ? '&streamType=live' : '')+(options.autoplay ? '&autoPlay=true' : '' );
|
|
||||||
ele.appendChild(createParam('flashvars',flashvars));
|
|
||||||
ele.appendChild(createParam('allowFullScreen','true'));
|
|
||||||
ele.appendChild(createParam('wmode','direct'));
|
|
||||||
if (options.autoplay) {
|
if (options.autoplay) {
|
||||||
ele.appendChild(createParam('autoPlay','true'));
|
ele.appendChild(createParam("autoPlay","true"));
|
||||||
}
|
}
|
||||||
|
|
||||||
var e = document.createElement('embed');
|
e.setAttribute("src",MistVideo.urlappend(MistVideo.source.player_url));
|
||||||
ele.appendChild(e);
|
e.setAttribute("type","application/x-shockwave-flash");
|
||||||
e.setAttribute('src',options.source.player_url);
|
e.setAttribute("allowfullscreen","true");
|
||||||
e.setAttribute('type','application/x-shockwave-flash');
|
e.setAttribute("flashvars",flashvars);
|
||||||
e.setAttribute('allowfullscreen','true');
|
}
|
||||||
e.setAttribute('width',options.width);
|
build(MistVideo.source.url);
|
||||||
e.setAttribute('height',options.height);
|
|
||||||
e.setAttribute('flashvars',flashvars);
|
|
||||||
|
|
||||||
|
this.api = {};
|
||||||
|
this.setSize = function(size){
|
||||||
|
ele.setAttribute("width",size.width);
|
||||||
|
ele.setAttribute("height",size.height);
|
||||||
|
e.setAttribute("width",size.width);
|
||||||
|
e.setAttribute("height",size.height);
|
||||||
|
};
|
||||||
|
this.setSize(MistVideo.calcSize());
|
||||||
|
this.onready(function(){
|
||||||
|
if (MistVideo.container) { MistVideo.container.removeAttribute("data-loading"); }
|
||||||
|
});
|
||||||
|
this.api.setSource = function(url){
|
||||||
|
build(url);
|
||||||
|
}
|
||||||
|
|
||||||
this.addlog('Built html');
|
MistVideo.log("Built html");
|
||||||
callback(ele);
|
callback(ele);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,87 @@
|
||||||
mistplayers.html5 = {
|
mistplayers.html5 = {
|
||||||
name: 'HTML5 video player',
|
name: "HTML5 video player",
|
||||||
version: '1.1',
|
mimes: ["html5/application/vnd.apple.mpegurl","html5/video/mp4","html5/video/ogg","html5/video/webm","html5/audio/mp3","html5/audio/webm","html5/audio/ogg","html5/audio/wav"],
|
||||||
mimes: ['html5/application/vnd.apple.mpegurl','html5/video/mp4','html5/video/ogg','html5/video/webm','html5/audio/mp3','html5/audio/webm','html5/audio/ogg','html5/audio/wav'],
|
priority: MistUtil.object.keys(mistplayers).length + 1,
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
isMimeSupported: function (mimetype) {
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
return (MistUtil.array.indexOf(this.mimes,mimetype) == -1 ? false : true);
|
||||||
},
|
},
|
||||||
isBrowserSupported: function (mimetype,source,options,streaminfo) {
|
isBrowserSupported: function (mimetype,source,MistVideo) {
|
||||||
if ((['iPad','iPhone','iPod','MacIntel'].indexOf(navigator.platform) != -1) && (mimetype == 'html5/video/mp4')) { return false; }
|
|
||||||
|
|
||||||
var support = false;
|
//check for http/https mismatch
|
||||||
var shortmime = mimetype.split('/');
|
if (location.protocol != MistUtil.http.url.split(source.url).protocol) {
|
||||||
shortmime.shift();
|
if ((location.protocol == "file:") && (MistUtil.http.url.split(source.url).protocol == "http:")) {
|
||||||
|
MistVideo.log("This page was loaded over file://, the player might not behave as intended.");
|
||||||
if ((shortmime[0] == 'audio') && (streaminfo.height) && (!options.forceType) && (!options.forceSource)) {
|
}
|
||||||
//claim you don't support audio-only playback if there is video data, unless this mime is being forced
|
else {
|
||||||
|
MistVideo.log("HTTP/HTTPS mismatch for this source");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var support = false;
|
||||||
|
var shortmime = mimetype.split("/");
|
||||||
|
shortmime.shift();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var v = document.createElement((shortmime[0] == 'audio' ? 'audio' : 'video'));
|
shortmime = shortmime.join("/");
|
||||||
shortmime = shortmime.join('/')
|
|
||||||
if ((v) && (v.canPlayType(shortmime) != "")) {
|
function test(mime) {
|
||||||
support = v.canPlayType(shortmime);
|
var v = document.createElement("video");
|
||||||
|
if ((v) && (v.canPlayType(mime) != "")) {
|
||||||
|
support = v.canPlayType(mime);
|
||||||
}
|
}
|
||||||
|
return support;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shortmime == "video/mp4") {
|
||||||
|
function translateCodec(track) {
|
||||||
|
|
||||||
|
function bin2hex(index) {
|
||||||
|
return ("0"+track.init.charCodeAt(index).toString(16)).slice(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (track.codec) {
|
||||||
|
case "AAC":
|
||||||
|
return "mp4a.40.2";
|
||||||
|
case "MP3":
|
||||||
|
return "mp3";
|
||||||
|
//return "mp4a.40.34";
|
||||||
|
case "AC3":
|
||||||
|
return "ec-3";
|
||||||
|
case "H264":
|
||||||
|
return "avc1."+bin2hex(1)+bin2hex(2)+bin2hex(3);
|
||||||
|
case "HEVC":
|
||||||
|
return "hev1."+bin2hex(1)+bin2hex(6)+bin2hex(7)+bin2hex(8)+bin2hex(9)+bin2hex(10)+bin2hex(11)+bin2hex(12);
|
||||||
|
default:
|
||||||
|
return track.codec.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
var codecs = {};
|
||||||
|
for (var i in MistVideo.info.meta.tracks) {
|
||||||
|
if (MistVideo.info.meta.tracks[i].type != "meta") {
|
||||||
|
codecs[translateCodec(MistVideo.info.meta.tracks[i])] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
codecs = MistUtil.object.keys(codecs);
|
||||||
|
if (codecs.length) {
|
||||||
|
if (codecs.length > source.simul_tracks) {
|
||||||
|
//not all of the tracks have to work
|
||||||
|
var working = 0;
|
||||||
|
for (var i in codecs) {
|
||||||
|
var s = test(shortmime+";codecs=\""+codecs[i]+"\"");
|
||||||
|
if (s) {
|
||||||
|
working++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (working >= source.simul_tracks);
|
||||||
|
}
|
||||||
|
shortmime += ";codecs=\""+codecs.join(",")+"\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
support = test(shortmime);
|
||||||
} catch(e){}
|
} catch(e){}
|
||||||
return support;
|
return support;
|
||||||
},
|
},
|
||||||
|
@ -34,206 +92,159 @@ mistplayers.html5 = {
|
||||||
};
|
};
|
||||||
var p = mistplayers.html5.player;
|
var p = mistplayers.html5.player;
|
||||||
p.prototype = new MistPlayer();
|
p.prototype = new MistPlayer();
|
||||||
p.prototype.build = function (options,callback) {
|
p.prototype.build = function (MistVideo,callback) {
|
||||||
var cont = document.createElement('div');
|
var shortmime = MistVideo.source.type.split("/");
|
||||||
cont.className = 'mistplayer';
|
|
||||||
var me = this; //to allow nested functions to access the player class itself
|
|
||||||
|
|
||||||
var shortmime = options.source.type.split('/');
|
|
||||||
shortmime.shift();
|
shortmime.shift();
|
||||||
|
var video = document.createElement("video");
|
||||||
|
|
||||||
var ele = this.getElement((shortmime[0] == 'audio' ? 'audio' : 'video'));
|
//TODO verify: not required if player is loaded from same domain as it should always be when not in dev mode?
|
||||||
ele.className = '';
|
video.setAttribute("crossorigin","anonymous");//required for subs, breaks ogg?
|
||||||
cont.appendChild(ele);
|
|
||||||
|
|
||||||
if (options.source.type != "html5/video/ogg") {
|
var source = document.createElement("source");
|
||||||
ele.crossOrigin = 'anonymous'; //required for subtitles, but if ogg, the video won't load
|
source.setAttribute("src",MistVideo.source.url);
|
||||||
}
|
video.source = source;
|
||||||
|
video.appendChild(source);
|
||||||
|
source.type = shortmime.join("/");
|
||||||
|
|
||||||
if (shortmime[0] == 'audio') {
|
//apply options
|
||||||
this.setTracks = function() { return false; }
|
var attrs = ["autoplay","loop","poster"];
|
||||||
this.fullscreen = false;
|
for (var i in attrs) {
|
||||||
cont.className += ' audio';
|
var attr = attrs[i];
|
||||||
}
|
if (MistVideo.options[attr]) {
|
||||||
|
video.setAttribute(attr,(MistVideo.options[attr] === true ? "" : MistVideo.options[attr]));
|
||||||
this.addlog('Building HTML5 player..');
|
|
||||||
|
|
||||||
var source = document.createElement('source');
|
|
||||||
source.setAttribute('src',options.src);
|
|
||||||
this.source = source;
|
|
||||||
ele.appendChild(source);
|
|
||||||
source.type = shortmime.join('/');
|
|
||||||
this.addlog('Adding '+source.type+' source @ '+options.src);
|
|
||||||
|
|
||||||
if ((this.tracks.subtitle.length) && (this.subtitle)) {
|
|
||||||
for (var i in this.tracks.subtitle) {
|
|
||||||
var t = document.createElement('track');
|
|
||||||
ele.appendChild(t);
|
|
||||||
t.kind = 'subtitles';
|
|
||||||
t.label = this.tracks.subtitle[i].desc;
|
|
||||||
t.srclang = this.tracks.subtitle[i].lang;
|
|
||||||
t.src = this.subtitle+'?track='+this.tracks.subtitle[i].trackid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (MistVideo.options.controls == "stock") {
|
||||||
ele.width = options.width;
|
video.setAttribute("controls","");
|
||||||
ele.height = options.height;
|
|
||||||
ele.style.width = options.width+'px';
|
|
||||||
ele.style.height = options.height+'px';
|
|
||||||
|
|
||||||
if (options.autoplay) {
|
|
||||||
ele.setAttribute('autoplay','');
|
|
||||||
}
|
|
||||||
if (options.loop) {
|
|
||||||
ele.setAttribute('loop','');
|
|
||||||
}
|
|
||||||
if (options.poster) {
|
|
||||||
ele.setAttribute('poster',options.poster);
|
|
||||||
}
|
|
||||||
if (options.controls) {
|
|
||||||
if ((options.controls == 'stock') || (!this.buildMistControls())) {
|
|
||||||
//MistControls have failed to build in the if condition
|
|
||||||
ele.setAttribute('controls','');
|
|
||||||
}
|
}
|
||||||
|
if (MistVideo.info.type == "live") {
|
||||||
|
video.loop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cont.onclick = function(){
|
if (("Proxy" in window) && ("Reflect" in window)) {
|
||||||
if (ele.paused) { ele.play(); }
|
var overrides = {
|
||||||
else { ele.pause(); }
|
get: {},
|
||||||
|
set: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addlog('Built html');
|
MistVideo.player.api = new Proxy(video,{
|
||||||
|
get: function(target, key, receiver){
|
||||||
//forward events
|
if (key in overrides.get) {
|
||||||
ele.addEventListener('error',function(e){
|
return overrides.get[key].apply(target, arguments);
|
||||||
if (!e.isTrusted) { return; } //don't trigger on errors we have thrown ourselves
|
}
|
||||||
|
var method = target[key];
|
||||||
if (options.live) {
|
if (typeof method === "function"){
|
||||||
if ((ele.error) && (ele.error.code == 3)) {
|
return function () {
|
||||||
e.stopPropagation(); //dont let this error continue to prevent the core from trying to handle the error
|
return method.apply(target, arguments);
|
||||||
me.load();
|
}
|
||||||
me.cancelAskNextCombo();
|
}
|
||||||
e.message = 'Handled decoding error';
|
return method;
|
||||||
me.addlog('Decoding error: reloading..');
|
},
|
||||||
me.report({
|
set: function(target, key, value) {
|
||||||
type: 'playback',
|
if (key in overrides.set) {
|
||||||
warn: 'A decoding error was encountered, but handled'
|
return overrides.set[key].call(target,value);
|
||||||
|
}
|
||||||
|
return target[key] = value;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
if (MistVideo.source.type == "html5/audio/mp3") {
|
||||||
|
overrides.set.currentTime = function(){
|
||||||
|
MistVideo.log("Seek attempted, but MistServer does not currently support seeking in MP3.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg;
|
|
||||||
if ('message' in e) {
|
|
||||||
msg = e.message;
|
|
||||||
}
|
}
|
||||||
else if ((e.target.tagName == 'SOURCE') && (e.target.getAttribute('src') == '')) {
|
if (MistVideo.info.type == "live") {
|
||||||
e.stopPropagation();
|
|
||||||
//this error is triggered because the unload function was fired
|
overrides.get.duration = function(){
|
||||||
return;
|
//this should indicate the end of Mist's buffer
|
||||||
|
var buffer_end = 0;
|
||||||
|
if (this.buffered.length) {
|
||||||
|
buffer_end = this.buffered.end(this.buffered.length-1)
|
||||||
|
}
|
||||||
|
var time_since_buffer = (new Date().getTime() - MistVideo.player.api.lastProgress.getTime())*1e-3;
|
||||||
|
return buffer_end + time_since_buffer - MistVideo.player.api.liveOffset;
|
||||||
|
};
|
||||||
|
overrides.set.currentTime = function(value){
|
||||||
|
var offset = value - MistVideo.player.api.duration;
|
||||||
|
MistVideo.player.api.liveOffset = offset;
|
||||||
|
|
||||||
|
MistVideo.log("Seeking to "+MistUtil.format.time(value)+" ("+Math.round(offset*-10)/10+"s from live)");
|
||||||
|
|
||||||
|
MistVideo.player.api.setSource(MistUtil.http.url.addParam(MistVideo.source.url,{startunix:offset}));
|
||||||
|
}
|
||||||
|
MistUtil.event.addListener(video,"progress",function(){
|
||||||
|
MistVideo.player.api.lastProgress = new Date();
|
||||||
|
});
|
||||||
|
MistVideo.player.api.lastProgress = new Date();
|
||||||
|
MistVideo.player.api.liveOffset = 0;
|
||||||
|
|
||||||
|
|
||||||
|
MistUtil.event.addListener(video,"pause",function(){
|
||||||
|
MistVideo.player.api.pausedAt = new Date();
|
||||||
|
});
|
||||||
|
overrides.get.play = function(){
|
||||||
|
return function(){
|
||||||
|
if ((MistVideo.player.api.paused) && (MistVideo.player.api.pausedAt) && ((new Date()) - MistVideo.player.api.pausedAt > 5e3)) {
|
||||||
|
video.load();
|
||||||
|
MistVideo.log("Reloading source..");
|
||||||
|
}
|
||||||
|
|
||||||
|
return video.play.apply(video, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (MistVideo.source.type == "html5/video/mp4") {
|
||||||
|
overrides.get.currentTime = function(){
|
||||||
|
return this.currentTime - MistVideo.player.api.liveOffset + MistVideo.info.lastms * 1e-3;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg = 'readyState: ';
|
if (!isFinite(video.duration)) {
|
||||||
switch (me.element.readyState) {
|
var duration = 0;
|
||||||
case 0:
|
for (var i in MistVideo.info.meta.tracks) {
|
||||||
msg += 'HAVE_NOTHING';
|
duration = Math.max(duration,MistVideo.info.meta.tracks[i].lastms);
|
||||||
break;
|
}
|
||||||
case 1:
|
overrides.get.duration = function(){
|
||||||
msg += 'HAVE_METADATA';
|
if (isFinite(this.duration)) { return this.duration; }
|
||||||
break;
|
return duration * 1e-3;
|
||||||
case 2:
|
|
||||||
msg += 'HAVE_CURRENT_DATA';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
msg += 'HAVE_FUTURE_DATA';
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
msg += 'HAVE_ENOUGH_DATA';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
msg += ' networkState: ';
|
|
||||||
switch (me.element.networkState) {
|
|
||||||
case 0:
|
|
||||||
msg += 'NETWORK_EMPTY';
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
msg += 'NETWORK_IDLE';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
msg += 'NETWORK_LOADING';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
msg += 'NETWORK_NO_SOURCE';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
me.adderror(msg);
|
|
||||||
});
|
|
||||||
var events = ['abort','canplay','canplaythrough','durationchange','emptied','ended','interruptbegin','interruptend','loadeddata','loadedmetadata','loadstart','pause','play','playing','ratechange','seeked','seeking','stalled','volumechange','waiting','progress'];
|
|
||||||
for (var i in events) {
|
|
||||||
ele.addEventListener(events[i],function(e){
|
|
||||||
me.addlog('Player event fired: '+e.type);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
callback(cont);
|
|
||||||
}
|
|
||||||
p.prototype.play = function(){ return this.element.play(); };
|
|
||||||
p.prototype.pause = function(){ return this.element.pause(); };
|
|
||||||
p.prototype.volume = function(level){
|
|
||||||
if (typeof level == 'undefined' ) { return this.element.volume; }
|
|
||||||
return this.element.volume = level;
|
|
||||||
};
|
|
||||||
p.prototype.loop = function(bool){
|
|
||||||
if (typeof bool == 'undefined') {
|
|
||||||
return this.element.loop;
|
|
||||||
}
|
|
||||||
return this.element.loop = bool;
|
|
||||||
};
|
|
||||||
p.prototype.load = function(){
|
|
||||||
var load;
|
|
||||||
if (this.element.paused) {
|
|
||||||
load = this.element.load();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//sometimes there is a play / pause interrupt: try again
|
MistVideo.player.api = video;
|
||||||
//TODO figure out if this happens on paused or on playing
|
}
|
||||||
|
MistVideo.player.api.setSource = function(url) {
|
||||||
|
if (url != this.source.src) {
|
||||||
|
this.source.src = url;
|
||||||
this.load();
|
this.load();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//this helps to prevent the player from just showing a black screen after a reload
|
|
||||||
if (this.element.paused) {
|
|
||||||
var me = this;
|
|
||||||
var unpause = function(){
|
|
||||||
if (me.element.paused) {
|
|
||||||
me.element.play();
|
|
||||||
}
|
|
||||||
me.element.removeEventListener('progress',unpause);
|
|
||||||
}
|
|
||||||
this.element.addEventListener('progress',unpause);
|
|
||||||
}
|
|
||||||
|
|
||||||
return load;
|
|
||||||
};
|
|
||||||
if (document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
|
|
||||||
p.prototype.fullscreen = function(){
|
|
||||||
if(this.element.requestFullscreen) {
|
|
||||||
return this.element.requestFullscreen();
|
|
||||||
} else if(this.element.mozRequestFullScreen) {
|
|
||||||
return this.element.mozRequestFullScreen();
|
|
||||||
} else if(this.element.webkitRequestFullscreen) {
|
|
||||||
return this.element.webkitRequestFullscreen();
|
|
||||||
} else if(this.element.msRequestFullscreen) {
|
|
||||||
return this.element.msRequestFullscreen();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
MistVideo.player.api.setSubtitle = function(trackmeta) {
|
||||||
|
//remove previous subtitles
|
||||||
|
var tracks = video.getElementsByTagName("track");
|
||||||
|
for (var i = tracks.length - 1; i >= 0; i--) {
|
||||||
|
video.removeChild(tracks[i]);
|
||||||
|
}
|
||||||
|
if (trackmeta) { //if the chosen track exists
|
||||||
|
//add the new one
|
||||||
|
var track = document.createElement("track");
|
||||||
|
video.appendChild(track);
|
||||||
|
track.kind = "subtitles";
|
||||||
|
track.label = trackmeta.label;
|
||||||
|
track.srclang = trackmeta.lang;
|
||||||
|
track.src = trackmeta.src;
|
||||||
|
track.setAttribute("default","");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
MistVideo.player.setSize = function(size){
|
||||||
|
this.api.style.width = size.width+"px";
|
||||||
|
this.api.style.height = size.height+"px";
|
||||||
|
};
|
||||||
|
|
||||||
|
callback(video);
|
||||||
}
|
}
|
||||||
p.prototype.updateSrc = function(src){
|
|
||||||
this.source.setAttribute('src',src);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
p.prototype.resize = function(size){
|
|
||||||
this.element.width = size.width;
|
|
||||||
this.element.height = size.height;
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
mistplayers.img = {
|
|
||||||
name: 'HTML img tag',
|
|
||||||
version: '1.1',
|
|
||||||
mimes: ['html5/image/jpeg'],
|
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
|
||||||
},
|
|
||||||
isBrowserSupported: function (mimetype,source,options,streaminfo) {
|
|
||||||
//only use this if we are sure we just want an image
|
|
||||||
if ((options.forceType) || (options.forceSource) || (options.forcePlayer)) { return true; }
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
player: function(){this.onreadylist = [];}
|
|
||||||
};
|
|
||||||
var p = mistplayers.img.player;
|
|
||||||
p.prototype = new MistPlayer();
|
|
||||||
p.prototype.build = function (options,callback) {
|
|
||||||
var ele = this.getElement('img');
|
|
||||||
ele.src = options.src;
|
|
||||||
ele.style.display = 'block';
|
|
||||||
callback(ele);
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
mistplayers.jwplayer = {
|
|
||||||
name: 'JWPlayer',
|
|
||||||
version: '0.2',
|
|
||||||
mimes: ['html5/video/mp4','html5/video/webm','dash/video/mp4','flash/10','flash/7','html5/application/vnd.apple.mpegurl','html5/audio/mp3','html5/audio/aac'],
|
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
|
||||||
},
|
|
||||||
isBrowserSupported: function (mimetype) {
|
|
||||||
//TODO like, actually check the browser or something?
|
|
||||||
if (typeof jwplayer == 'function') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
player: function(){}
|
|
||||||
};
|
|
||||||
var p = mistplayers.jwplayer.player;
|
|
||||||
p.prototype = new MistPlayer();
|
|
||||||
p.prototype.build = function (options,callback) {
|
|
||||||
var ele = this.getElement('div');
|
|
||||||
|
|
||||||
this.jw = jwplayer(ele).setup({
|
|
||||||
file: options.src,
|
|
||||||
width: options.width,
|
|
||||||
height: options.height,
|
|
||||||
autostart: options.autoplay,
|
|
||||||
image: options.poster,
|
|
||||||
controls: options.controls
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addlog('Built html');
|
|
||||||
callback(ele);
|
|
||||||
}
|
|
||||||
p.prototype.play = function(){ return this.jw.play(); };
|
|
||||||
p.prototype.pause = function(){ return this.jw.pause(); };
|
|
||||||
p.prototype.volume = function(level){
|
|
||||||
if (typeof level == 'undefined' ) { return this.jw.getVolume/100; }
|
|
||||||
return this.jw.setVolume(level*100);
|
|
||||||
};
|
|
|
@ -1,101 +0,0 @@
|
||||||
mistplayers.polytrope = {
|
|
||||||
name: 'Polytrope Flash Player',
|
|
||||||
version: '0.2',
|
|
||||||
mimes: ['flash/11','flash/10','flash/7'],
|
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
|
||||||
},
|
|
||||||
isBrowserSupported: function (mimetype) {
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var version = 0;
|
|
||||||
try {
|
|
||||||
// check in the mimeTypes
|
|
||||||
version = navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin.description.replace(/([^0-9\.])/g, '').split('.')[0];
|
|
||||||
} catch(e){}
|
|
||||||
try {
|
|
||||||
// for our special friend IE
|
|
||||||
version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable("$version").replace(/([^0-9\,])/g, '').split(',')[0];
|
|
||||||
} catch(e){}
|
|
||||||
|
|
||||||
var mimesplit = mimetype.split('/');
|
|
||||||
|
|
||||||
return Number(version) >= Number(mimesplit[mimesplit.length-1]);
|
|
||||||
},
|
|
||||||
player: function(){}
|
|
||||||
};
|
|
||||||
var p = mistplayers.polytrope.player;
|
|
||||||
p.prototype = new MistPlayer();
|
|
||||||
p.prototype.build = function (options,callback) {
|
|
||||||
function createParam(name,value) {
|
|
||||||
var p = document.createElement('param');
|
|
||||||
p.setAttribute('name',name);
|
|
||||||
p.setAttribute('value',value);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO its not working.
|
|
||||||
|
|
||||||
/*
|
|
||||||
this.swf = this.video_instance_el.flash({
|
|
||||||
swf: "/shared/swf/videoplayer.swf?" + (new Date).getTime(),
|
|
||||||
width: "100%",
|
|
||||||
height: parseInt(this.options.element.height()),
|
|
||||||
wmode: "opaque",
|
|
||||||
menu: "false",
|
|
||||||
allowFullScreen: "true",
|
|
||||||
allowFullScreenInteractive: "true",
|
|
||||||
allowScriptAccess: "always",
|
|
||||||
id: "cucumbertv-swf-" + this.guid,
|
|
||||||
expressInstall: "/shared/swf/expressInstall.swf",
|
|
||||||
flashvars: {
|
|
||||||
rtmp_url: "rtmp://" + this.options.stream_host + "/play/",
|
|
||||||
stream_name: this.options.stream_name,
|
|
||||||
poster: this.options.poster,
|
|
||||||
autoplay: this.options.autoplay,
|
|
||||||
color_1: "0x1d1d1d",
|
|
||||||
color_2: "0xffffff",
|
|
||||||
buffer_time: .1,
|
|
||||||
is_streaming_url: "/api/user/is_streaming",
|
|
||||||
username: this.options.username,
|
|
||||||
mode: "v" == this.options.type ? "archive" : "live",
|
|
||||||
guid: this.guid
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<object data="/shared/swf/videoplayer.swf?1468312898591" type="application/x-shockwave-flash" id="cucumbertv-swf-4dc64c18-59af-91a2-d0c5-ab8df4f45c65" width="100%" height="660">
|
|
||||||
<param name="wmode" value="opaque">
|
|
||||||
<param name="menu" value="false">
|
|
||||||
<param name="allowFullScreen" value="true">
|
|
||||||
<param name="allowFullScreenInteractive" value="true">
|
|
||||||
<param name="allowScriptAccess" value="always">
|
|
||||||
<param name="expressInstall" value="/shared/swf/expressInstall.swf">
|
|
||||||
<param name="flashvars" value="rtmp_url=rtmp://www.stickystage.com/play/&stream_name=stickystage_archive+SrA-2016.07.08.23.54.08&poster=/stickystage/users/SrA/archive/SrA-2016.07.08.23.54.08.jpg&autoplay=true&color_1=0x1d1d1d&color_2=0xffffff&buffer_time=0.1&is_streaming_url=/api/user/is_streaming&username=SrA&mode=archive&guid=4dc64c18-59af-91a2-d0c5-ab8df4f45c65">
|
|
||||||
<param name="movie" value="/shared/swf/videoplayer.swf?1468312898591">
|
|
||||||
</object>
|
|
||||||
</div>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var ele = this.element('object');
|
|
||||||
ele.data = 'players/polytrope.swf';
|
|
||||||
ele.type = 'application/x-shockwave-flash';
|
|
||||||
ele.width = options.width;
|
|
||||||
ele.height = options.height;
|
|
||||||
|
|
||||||
/*
|
|
||||||
ele.appendChild(createParam('allowFullScreen','true'));
|
|
||||||
ele.appendChild(createParam('allowScriptAccess','always'));
|
|
||||||
var flashvars = 'rtmp_url=rtmp://www.stickystage.com/play/&stream_name=stickystage_archive+SrA-2016.07.08.23.54.08&poster=/stickystage/users/SrA/archive/SrA-2016.07.08.23.54.08.jpg&autoplay=true&color_1=0x1d1d1d&color_2=0xffffff&buffer_time=0.1&is_streaming_url=/api/user/is_streaming&username=SrA&mode=archive&guid=4dc64c18-59af-91a2-d0c5-ab8df4f45c65';
|
|
||||||
ele.appendChild(createParam('flashvars',flashvars));
|
|
||||||
ele.appendChild(createParam('movie','players/polytrope.swf'));
|
|
||||||
*/
|
|
||||||
|
|
||||||
ele.innerHTML = '<param name="wmode" value="opaque"> <param name="menu" value="false"> <param name="allowFullScreen" value="true"> <param name="allowFullScreenInteractive" value="true"> <param name="allowScriptAccess" value="always"> <param name="expressInstall" value="/shared/swf/expressInstall.swf"> <param name="flashvars" value="rtmp_url=rtmp://www.stickystage.com/play/&stream_name=stickystage_archive+SrA-2016.07.08.23.54.08&poster=http://stickystage.com/stickystage/users/SrA/archive/SrA-2016.07.08.23.54.08.jpg&autoplay=true&color_1=0x1d1d1d&color_2=0xffffff&buffer_time=0.1&is_streaming_url=/api/user/is_streaming&username=SrA&mode=archive&guid=4dc64c18-59af-91a2-d0c5-ab8df4f45c65"> <param name="movie" value="players/polytrope.swf">';
|
|
||||||
|
|
||||||
this.addlog('Built html');
|
|
||||||
callback(ele);
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
mistplayers.silverlight = {
|
|
||||||
name: 'Silverlight',
|
|
||||||
version: '1.1',
|
|
||||||
mimes: ['silverlight'],
|
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
|
||||||
},
|
|
||||||
isBrowserSupported: function (mimetype) {
|
|
||||||
var plugin;
|
|
||||||
try {
|
|
||||||
// check in the mimeTypes
|
|
||||||
plugin = navigator.plugins["Silverlight Plug-In"];
|
|
||||||
return !!plugin;
|
|
||||||
} catch(e){}
|
|
||||||
try {
|
|
||||||
// for our special friend IE
|
|
||||||
plugin = new ActiveXObject('AgControl.AgControl');
|
|
||||||
return true;
|
|
||||||
} catch(e){}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
player: function(){this.onreadylist = [];}
|
|
||||||
};
|
|
||||||
var p = mistplayers.silverlight.player;
|
|
||||||
p.prototype = new MistPlayer();
|
|
||||||
p.prototype.build = function (options,callback) {
|
|
||||||
function createParam(name,value) {
|
|
||||||
var p = document.createElement('param');
|
|
||||||
p.setAttribute('name',name);
|
|
||||||
p.setAttribute('value',value);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
var ele = this.getElement('object');
|
|
||||||
ele.setAttribute('data','data:application/x-silverlight,');
|
|
||||||
ele.setAttribute('type','application/x-silverlight');
|
|
||||||
ele.setAttribute('width',options.width);
|
|
||||||
ele.setAttribute('height',options.height);
|
|
||||||
ele.appendChild(createParam('source',encodeURI(options.src)+'/player.xap'));
|
|
||||||
ele.appendChild(createParam('initparams','autoload=false,'+(options.autoplay ? 'autoplay=true' : 'autoplay=false')+',displaytimecode=false,enablecaptions=true,joinLive=true,muted=false'));
|
|
||||||
|
|
||||||
var a = document.createElement('a');
|
|
||||||
ele.appendChild(a);
|
|
||||||
a.setAttribute('href','http://go.microsoft.com/fwlink/?LinkID=124807');
|
|
||||||
a.setAttribute('style','text-decoration: none;');
|
|
||||||
var img = document.createElement('img');
|
|
||||||
a.appendChild(img);
|
|
||||||
img.setAttribute('src','http://go.microsoft.com/fwlink/?LinkId=108181');
|
|
||||||
img.setAttribute('alt','Get Microsoft Silverlight');
|
|
||||||
img.setAttribute('style','border-style: none;')
|
|
||||||
|
|
||||||
this.addlog('Built html');
|
|
||||||
callback(ele);
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
mistplayers.myplayer = {
|
|
||||||
name: 'My video player',
|
|
||||||
version: '0.1',
|
|
||||||
mimes: ['my/mime/types'],
|
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
|
||||||
},
|
|
||||||
isBrowserSupported: function (mimetype) {
|
|
||||||
//TODO your code here
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
player: function(){}
|
|
||||||
};
|
|
||||||
var p = mistplayers.myplayer.player;
|
|
||||||
p.prototype = new MistPlayer();
|
|
||||||
p.prototype.build = function (options,callback) {
|
|
||||||
var ele = this.element('object');
|
|
||||||
|
|
||||||
//TODO your code here
|
|
||||||
|
|
||||||
this.addlog('Built html');
|
|
||||||
callback(ele);
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
mistplayers.theoplayer = {
|
|
||||||
name: 'TheoPlayer',
|
|
||||||
version: '0.2',
|
|
||||||
mimes: ['html5/application/vnd.apple.mpegurl','dash/video/mp4'],
|
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
|
||||||
},
|
|
||||||
isBrowserSupported: function (mimetype) {
|
|
||||||
//TODO like, actually check the browser or something?
|
|
||||||
if (typeof theoplayer == 'function') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
player: function(){}
|
|
||||||
};
|
|
||||||
var p = mistplayers.theoplayer.player;
|
|
||||||
p.prototype = new MistPlayer();
|
|
||||||
p.prototype.build = function (options,callback) {
|
|
||||||
var ele = this.getElement('video');
|
|
||||||
|
|
||||||
ele.src = options.src;
|
|
||||||
ele.width = options.width;
|
|
||||||
ele.height = options.height;
|
|
||||||
|
|
||||||
if (options.controls) {
|
|
||||||
ele.setAttribute('controls','');
|
|
||||||
}
|
|
||||||
if (options.autoplay) {
|
|
||||||
ele.setAttribute('autoplay','');
|
|
||||||
}
|
|
||||||
if (options.loop) {
|
|
||||||
ele.setAttribute('loop','');
|
|
||||||
}
|
|
||||||
if (options.poster) {
|
|
||||||
ele.setAttribute('poster',options.poster);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.theoplayer = theoplayer(ele);
|
|
||||||
|
|
||||||
this.addlog('Built html');
|
|
||||||
callback(ele);
|
|
||||||
}
|
|
||||||
p.prototype.play = function(){ return this.theoplayer.play(); };
|
|
||||||
p.prototype.pause = function(){ return this.theoplayer.pause(); };
|
|
||||||
p.prototype.volume = function(level){
|
|
||||||
if (typeof level == 'undefined' ) { return this.theoplayer.volume; }
|
|
||||||
return this.theoplayer.volume = level;
|
|
||||||
};
|
|
||||||
p.prototype.fullscreen = function(){
|
|
||||||
return this.theoplayer.requestFullscreen();
|
|
||||||
};
|
|
|
@ -1,221 +1,208 @@
|
||||||
mistplayers.videojs = {
|
mistplayers.videojs = {
|
||||||
name: 'VideoJS player',
|
name: "VideoJS player",
|
||||||
version: '1.1',
|
mimes: ["html5/application/vnd.apple.mpegurl"],
|
||||||
mimes: ['html5/video/mp4','html5/application/vnd.apple.mpegurl','html5/video/ogg','html5/video/webm'],
|
priority: MistUtil.object.keys(mistplayers).length + 1,
|
||||||
priority: Object.keys(mistplayers).length + 1,
|
|
||||||
isMimeSupported: function (mimetype) {
|
isMimeSupported: function (mimetype) {
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
||||||
},
|
},
|
||||||
isBrowserSupported: function (mimetype,source,options,streaminfo,logfunc) {
|
isBrowserSupported: function (mimetype,source,MistVideo) {
|
||||||
|
|
||||||
//dont use https if the player is loaded over http
|
//check for http/https mismatch
|
||||||
if ((options.host.substr(0,7) == 'http://') && (source.url.substr(0,8) == 'https://')) {
|
if (location.protocol != MistUtil.http.url.split(source.url).protocol) {
|
||||||
if (logfunc) { logfunc('HTTP/HTTPS mismatch for this source'); }
|
MistVideo.log("HTTP/HTTPS mismatch for this source");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//dont use videojs if this location is loaded over file://
|
//don't use videojs if this location is loaded over file://
|
||||||
if ((location.protocol == 'file:') && (mimetype == 'html5/application/vnd.apple.mpegurl')) {
|
if ((location.protocol == "file:") && (mimetype == "html5/application/vnd.apple")) {
|
||||||
if (logfunc) { logfunc('This source ('+mimetype+') won\'t work if the page is run via file://'); }
|
MistVideo.log("This source ("+mimetype+") won't load if the page is run via file://");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//dont use HLS if there is an MP3 audio track, unless we're on apple or edge
|
return ("MediaSource" in window);
|
||||||
if ((mimetype == 'html5/application/vnd.apple.mpegurl') && (['iPad','iPhone','iPod','MacIntel'].indexOf(navigator.platform) == -1) && (navigator.userAgent.indexOf('Edge') == -1)) {
|
|
||||||
var audio = false;
|
|
||||||
var nonmp3 = false;
|
|
||||||
for (var i in streaminfo.meta.tracks) {
|
|
||||||
var t = streaminfo.meta.tracks[i];
|
|
||||||
if (t.type == 'audio') {
|
|
||||||
audio = true;
|
|
||||||
if (t.codec != 'MP3') {
|
|
||||||
nonmp3 = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((audio) && (!nonmp3)) {
|
|
||||||
if (logfunc) { logfunc('This source has audio, but only MP3, and this browser can\'t play MP3 via HLS'); }
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return ('MediaSource' in window);
|
|
||||||
},
|
},
|
||||||
player: function(){this.onreadylist = [];}
|
player: function(){},
|
||||||
|
scriptsrc: function(host) { return host+"/videojs.js"; }
|
||||||
};
|
};
|
||||||
var p = mistplayers.videojs.player;
|
var p = mistplayers.videojs.player;
|
||||||
p.prototype = new MistPlayer();
|
p.prototype = new MistPlayer();
|
||||||
p.prototype.build = function (options,callback) {
|
p.prototype.build = function (MistVideo,callback) {
|
||||||
var me = this; //to allow nested functions to access the player class itself
|
var me = this; //to allow nested functions to access the player class itself
|
||||||
|
|
||||||
function onplayerload () {
|
function onVideoJSLoad () {
|
||||||
me.addlog('Building VideoJS player..');
|
if (MistVideo.destroyed) { return;}
|
||||||
|
|
||||||
var cont = document.createElement('div');
|
MistVideo.log("Building VideoJS player..");
|
||||||
cont.className = 'mistplayer';
|
|
||||||
|
|
||||||
var ele = me.getElement('video');
|
var ele = document.createElement("video");
|
||||||
cont.appendChild(ele);
|
if (MistVideo.source.type != "html5/video/ogg") {
|
||||||
ele.className = '';
|
ele.crossOrigin = "anonymous"; //required for subtitles, but if ogg, the video won"t load
|
||||||
if (options.source.type != "html5/video/ogg") {
|
|
||||||
ele.crossOrigin = 'anonymous'; //required for subtitles, but if ogg, the video won't load
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var shortmime = options.source.type.split('/');
|
var shortmime = MistVideo.source.type.split("/");
|
||||||
shortmime.shift();
|
shortmime.shift();
|
||||||
|
|
||||||
var source = document.createElement('source');
|
var source = document.createElement("source");
|
||||||
source.setAttribute('src',options.src);
|
source.setAttribute("src",MistVideo.source.url);
|
||||||
me.source = source;
|
me.source = source;
|
||||||
ele.appendChild(source);
|
ele.appendChild(source);
|
||||||
source.type = shortmime.join('/');
|
source.type = shortmime.join("/");
|
||||||
me.addlog('Adding '+source.type+' source @ '+options.src);
|
MistVideo.log("Adding "+source.type+" source @ "+MistVideo.source.url);
|
||||||
if (source.type == 'application/vnd.apple.mpegurl') { source.type = 'application/x-mpegURL'; }
|
if (source.type == "application/vnd.apple.mpegurl") { source.type = "application/x-mpegURL"; }
|
||||||
|
|
||||||
ele.className += ' video-js';
|
MistUtil.class.add(ele,"video-js");
|
||||||
ele.width = options.width;
|
|
||||||
ele.height = options.height;
|
|
||||||
ele.style.width = options.width+'px';
|
|
||||||
ele.style.height = options.height+'px';
|
|
||||||
|
|
||||||
var vjsopts = {
|
var vjsopts = {};
|
||||||
preload: 'auto'
|
|
||||||
};
|
|
||||||
|
|
||||||
if (options.autoplay) { vjsopts.autoplay = true; }
|
if (MistVideo.options.autoplay) { vjsopts.autoplay = true; }
|
||||||
if (options.loop) {
|
if ((MistVideo.options.loop) && (MistVideo.info.type != "live")) {
|
||||||
vjsopts.loop = true;
|
vjsopts.loop = true;
|
||||||
ele.loop = true;
|
ele.loop = true;
|
||||||
}
|
}
|
||||||
if (options.poster) { vjsopts.poster = options.poster; }
|
if (MistVideo.options.poster) { vjsopts.poster = MistVideo.options.poster; }
|
||||||
if (options.controls) {
|
if (MistVideo.options.controls == "stock") {
|
||||||
if ((options.controls == 'stock') || (!me.buildMistControls())) {
|
ele.setAttribute("controls","");
|
||||||
//MistControls have failed to build in the if condition
|
if (!document.getElementById("videojs-css")) {
|
||||||
ele.setAttribute('controls',true);
|
var style = document.createElement("link");
|
||||||
|
style.rel = "stylesheet";
|
||||||
|
style.href = MistVideo.options.host+"/skins/videojs.css";
|
||||||
|
style.id = "videojs-css";
|
||||||
|
document.head.appendChild(style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
me.onready(function(){
|
me.onready(function(){
|
||||||
me.videojs = videojs(ele,vjsopts,function(){
|
me.videojs = videojs(ele,vjsopts,function(){
|
||||||
me.addlog('Videojs initialized');
|
MistVideo.log("Videojs initialized");
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
me.addlog('Built html');
|
me.api.unload = function(){
|
||||||
|
videojs(ele).dispose();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
//forward events
|
MistVideo.log("Built html");
|
||||||
ele.addEventListener('error',function(e){
|
|
||||||
if (!e.isTrusted) { return; } //don't trigger on errors we have thrown ourselves
|
|
||||||
|
|
||||||
var msg;
|
if (("Proxy" in window) && ("Reflect" in window)) {
|
||||||
if ('message' in e) {
|
var overrides = {
|
||||||
msg = e.message;
|
get: {},
|
||||||
|
set: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
MistVideo.player.api = new Proxy(ele,{
|
||||||
|
get: function(target, key, receiver){
|
||||||
|
if (key in overrides.get) {
|
||||||
|
return overrides.get[key].apply(target, arguments);
|
||||||
|
}
|
||||||
|
var method = target[key];
|
||||||
|
if (typeof method === "function"){
|
||||||
|
return function () {
|
||||||
|
return method.apply(target, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return method;
|
||||||
|
},
|
||||||
|
set: function(target, key, value) {
|
||||||
|
if (key in overrides.set) {
|
||||||
|
return overrides.set[key].call(target,value);
|
||||||
|
}
|
||||||
|
return target[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (MistVideo.info.type == "live") {
|
||||||
|
function getLastBuffer(video) {
|
||||||
|
var buffer_end = 0;
|
||||||
|
if (video.buffered.length) {
|
||||||
|
buffer_end = video.buffered.end(video.buffered.length-1)
|
||||||
|
}
|
||||||
|
return buffer_end;
|
||||||
|
}
|
||||||
|
var HLSlatency = 90; //best guess..
|
||||||
|
|
||||||
|
overrides.get.duration = function(){
|
||||||
|
return (MistVideo.info.lastms + (new Date()).getTime() - MistVideo.info.updated.getTime())*1e-3;
|
||||||
|
};
|
||||||
|
MistVideo.player.api.lastProgress = new Date();
|
||||||
|
MistVideo.player.api.liveOffset = 0;
|
||||||
|
|
||||||
|
MistUtil.event.addListener(ele,"progress",function(){
|
||||||
|
MistVideo.player.api.lastProgress = new Date();
|
||||||
|
});
|
||||||
|
overrides.set.currentTime = function(value){
|
||||||
|
var diff = MistVideo.player.api.currentTime - value;
|
||||||
|
var offset = value - MistVideo.player.api.duration;
|
||||||
|
//MistVideo.player.api.liveOffset = offset;
|
||||||
|
|
||||||
|
MistVideo.log("Seeking to "+MistUtil.format.time(value)+" ("+Math.round(offset*-10)/10+"s from live)");
|
||||||
|
MistVideo.video.currentTime -= diff;
|
||||||
|
}
|
||||||
|
overrides.get.currentTime = function(){
|
||||||
|
return this.currentTime + MistVideo.info.lastms*1e-3 - MistVideo.player.api.liveOffset - HLSlatency;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg = 'readyState: ';
|
me.api = ele;
|
||||||
switch (me.element.readyState) {
|
|
||||||
case 0:
|
|
||||||
msg += 'HAVE_NOTHING';
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
msg += 'HAVE_METADATA';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
msg += 'HAVE_CURRENT_DATA';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
msg += 'HAVE_FUTURE_DATA';
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
msg += 'HAVE_ENOUGH_DATA';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
msg += ' networkState: ';
|
|
||||||
switch (me.element.networkState) {
|
|
||||||
case 0:
|
|
||||||
msg += 'NETWORK_EMPTY';
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
msg += 'NETWORK_IDLE';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
msg += 'NETWORK_LOADING';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
msg += 'NETWORK_NO_SOURCE';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
me.adderror(msg);
|
MistVideo.player.setSize = function(size){
|
||||||
|
if ("videojs" in MistVideo.player) {
|
||||||
|
MistVideo.player.videojs.dimensions(size.width,size.height);
|
||||||
|
|
||||||
});
|
//for some reason, the videojs' container won't be resized with the method above.
|
||||||
var events = ['abort','canplay','canplaythrough','durationchange','emptied','ended','interruptbegin','interruptend','loadeddata','loadedmetadata','loadstart','pause','play','playing','ratechange','seeked','seeking','stalled','volumechange','waiting','progress'];
|
//so let's cheat and do it ourselves
|
||||||
for (var i in events) {
|
ele.parentNode.style.width = size.width+"px";
|
||||||
ele.addEventListener(events[i],function(e){
|
ele.parentNode.style.height = size.height+"px";
|
||||||
me.addlog('Player event fired: '+e.type);
|
}
|
||||||
|
this.api.style.width = size.width+"px";
|
||||||
|
this.api.style.height = size.height+"px";
|
||||||
|
};
|
||||||
|
MistVideo.player.api.setSource = function(url) {
|
||||||
|
if (!MistVideo.player.videojs) { return; }
|
||||||
|
if (MistVideo.player.videojs.src() != url) {
|
||||||
|
MistVideo.player.videojs.src({
|
||||||
|
type: MistVideo.player.videojs.currentSource().type,
|
||||||
|
src: url
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
MistVideo.player.api.setSubtitle = function(trackmeta) {
|
||||||
|
//remove previous subtitles
|
||||||
|
var tracks = ele.getElementsByTagName("track");
|
||||||
|
for (var i = tracks.length - 1; i >= 0; i--) {
|
||||||
|
ele.removeChild(tracks[i]);
|
||||||
|
}
|
||||||
|
if (trackmeta) { //if the chosen track exists
|
||||||
|
//add the new one
|
||||||
|
var track = document.createElement("track");
|
||||||
|
ele.appendChild(track);
|
||||||
|
track.kind = "subtitles";
|
||||||
|
track.label = trackmeta.label;
|
||||||
|
track.srclang = trackmeta.lang;
|
||||||
|
track.src = trackmeta.src;
|
||||||
|
track.setAttribute("default","");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
callback(cont);
|
callback(ele);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('videojs' in window) {
|
if ("videojs" in window) {
|
||||||
onplayerload();
|
onVideoJSLoad();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//load the videojs player
|
//load the videojs player
|
||||||
var scripttag = document.createElement('script');
|
|
||||||
scripttag.src = options.host+'/videojs.js';
|
var scripttag = MistUtil.scripts.insert(MistVideo.urlappend(mistplayers.videojs.scriptsrc(MistVideo.options.host)),{
|
||||||
me.addlog('Retrieving videojs player code from '+scripttag.src);
|
onerror: function(e){
|
||||||
document.head.appendChild(scripttag);
|
var msg = "Failed to load videojs.js";
|
||||||
scripttag.onerror = function(){
|
if (e.message) { msg += ": "+e.message; }
|
||||||
me.askNextCombo('Failed to load videojs.js');
|
MistVideo.showError(msg);
|
||||||
}
|
},
|
||||||
scripttag.onload = function(){
|
onload: onVideoJSLoad
|
||||||
onplayerload();
|
},MistVideo);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.prototype.play = function(){ return this.element.play(); };
|
|
||||||
p.prototype.pause = function(){ return this.element.pause(); };
|
|
||||||
p.prototype.volume = function(level){
|
|
||||||
if (typeof level == 'undefined' ) { return this.element.volume; }
|
|
||||||
return this.element.volume = level;
|
|
||||||
};
|
|
||||||
p.prototype.loop = function(bool){
|
|
||||||
if (typeof bool == 'undefined') {
|
|
||||||
return this.element.loop;
|
|
||||||
}
|
|
||||||
return this.element.loop = bool;
|
|
||||||
};
|
|
||||||
p.prototype.load = function(){ return this.element.load(); };
|
|
||||||
if (document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
|
|
||||||
p.prototype.fullscreen = function(){
|
|
||||||
if(this.element.requestFullscreen) {
|
|
||||||
return this.element.requestFullscreen();
|
|
||||||
} else if(this.element.mozRequestFullScreen) {
|
|
||||||
return this.element.mozRequestFullScreen();
|
|
||||||
} else if(this.element.webkitRequestFullscreen) {
|
|
||||||
return this.element.webkitRequestFullscreen();
|
|
||||||
} else if(this.element.msRequestFullscreen) {
|
|
||||||
return this.element.msRequestFullscreen();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
p.prototype.updateSrc = function(src){
|
|
||||||
if ("videojs" in this) {
|
|
||||||
if (src == '') {
|
|
||||||
this.videojs.dispose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.videojs.src({
|
|
||||||
src: src,
|
|
||||||
type: this.source.type
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
429
embed/wrappers/webrtc.js
Normal file
|
@ -0,0 +1,429 @@
|
||||||
|
mistplayers.webrtc = {
|
||||||
|
name: "WebRTC player",
|
||||||
|
mimes: ["webrtc"],
|
||||||
|
priority: MistUtil.object.keys(mistplayers).length + 1,
|
||||||
|
isMimeSupported: function (mimetype) {
|
||||||
|
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
||||||
|
},
|
||||||
|
isBrowserSupported: function (mimetype,source,MistVideo) {
|
||||||
|
|
||||||
|
if ((!("WebSocket" in window)) || (!("RTCPeerConnection" in window))) { return false; }
|
||||||
|
|
||||||
|
//check for http/https mismatch
|
||||||
|
if (location.protocol.replace(/^http/,"ws") != MistUtil.http.url.split(source.url.replace(/^http/,"ws")).protocol) {
|
||||||
|
MistVideo.log("HTTP/HTTPS mismatch for this source");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
player: function(){}
|
||||||
|
};
|
||||||
|
var p = mistplayers.webrtc.player;
|
||||||
|
p.prototype = new MistPlayer();
|
||||||
|
p.prototype.build = function (MistVideo,callback) {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if ((typeof WebRTCBrowserEqualizerLoaded == "undefined") || (!WebRTCBrowserEqualizerLoaded)) {
|
||||||
|
//load it
|
||||||
|
var scripttag = document.createElement("script");
|
||||||
|
scripttag.src = MistVideo.urlappend(MistVideo.options.host+"/webrtc.js");
|
||||||
|
MistVideo.log("Retrieving webRTC browser equalizer code from "+scripttag.src);
|
||||||
|
document.head.appendChild(scripttag);
|
||||||
|
scripttag.onerror = function(){
|
||||||
|
MistVideo.showError("Failed to load webrtc browser equalizer",{nextCombo:5});
|
||||||
|
}
|
||||||
|
scripttag.onload = function(){
|
||||||
|
me.build(MistVideo,callback);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var video = document.createElement("video");
|
||||||
|
|
||||||
|
//apply options
|
||||||
|
var attrs = ["autoplay","loop","poster"];
|
||||||
|
for (var i in attrs) {
|
||||||
|
var attr = attrs[i];
|
||||||
|
if (MistVideo.options[attr]) {
|
||||||
|
video.setAttribute(attr,(MistVideo.options[attr] === true ? "" : MistVideo.options[attr]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (MistVideo.info.type == "live") {
|
||||||
|
video.loop = false;
|
||||||
|
}
|
||||||
|
if (MistVideo.options.controls == "stock") {
|
||||||
|
video.setAttribute("controls","");
|
||||||
|
}
|
||||||
|
video.setAttribute("crossorigin","anonymous");
|
||||||
|
this.setSize = function(size){
|
||||||
|
video.style.width = size.width+"px";
|
||||||
|
video.style.height = size.height+"px";
|
||||||
|
};
|
||||||
|
MistUtil.event.addListener(video,"loadeddata",correctSubtitleSync);
|
||||||
|
MistUtil.event.addListener(video,"seeked",correctSubtitleSync);
|
||||||
|
|
||||||
|
var seekoffset = 0;
|
||||||
|
var hasended = false;
|
||||||
|
this.listeners = {
|
||||||
|
on_connected: function() {
|
||||||
|
seekoffset = 0;
|
||||||
|
hasended = false;
|
||||||
|
this.webrtc.play();
|
||||||
|
},
|
||||||
|
on_disconnected: function() {
|
||||||
|
MistVideo.log("Websocket sent on_disconnect");
|
||||||
|
/*
|
||||||
|
If a VoD file ends, we receive an on_stop, but no on_disconnect
|
||||||
|
If a live stream ends, we receive an on_disconnect, but no on_stop
|
||||||
|
If MistOutWebRTC crashes, we receive an on_stop and then an on_disconnect
|
||||||
|
*/
|
||||||
|
if (hasended) {
|
||||||
|
MistVideo.showError("Connection to media server ended unexpectedly.");
|
||||||
|
}
|
||||||
|
video.pause();
|
||||||
|
},
|
||||||
|
on_answer_sdp: function (ev) {
|
||||||
|
if (!ev.result) {
|
||||||
|
MistVideo.showError("Failed to open stream.");
|
||||||
|
this.on_disconnected();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MistVideo.log("SDP answer received");
|
||||||
|
},
|
||||||
|
on_time: function(ev) {
|
||||||
|
//timeupdate
|
||||||
|
var oldoffset = seekoffset;
|
||||||
|
seekoffset = ev.current*1e-3 - video.currentTime;
|
||||||
|
if (Math.abs(oldoffset - seekoffset) > 1) { correctSubtitleSync(); }
|
||||||
|
|
||||||
|
var d = (ev.end == 0 ? Infinity : ev.end*1e-3);
|
||||||
|
if (d != duration) {
|
||||||
|
duration = d;
|
||||||
|
MistUtil.event.send("durationchange",d,video);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
on_seek: function(){
|
||||||
|
MistUtil.event.send("seeked",seekoffset,video);
|
||||||
|
video.play();
|
||||||
|
},
|
||||||
|
on_stop: function(){
|
||||||
|
MistVideo.log("Websocket sent on_stop");
|
||||||
|
MistUtil.event.send("ended",null,video);
|
||||||
|
hasended = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function WebRTCPlayer(){
|
||||||
|
this.peerConn = null;
|
||||||
|
this.localOffer = null;
|
||||||
|
this.isConnected = false;
|
||||||
|
var thisWebRTCPlayer = this;
|
||||||
|
|
||||||
|
this.on_event = function(ev) {
|
||||||
|
//if (ev.type != "on_time") { console.log(ev); }
|
||||||
|
switch (ev.type) {
|
||||||
|
case "on_connected": {
|
||||||
|
thisWebRTCPlayer.isConnected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "on_answer_sdp": {
|
||||||
|
thisWebRTCPlayer.peerConn
|
||||||
|
.setRemoteDescription({ type: "answer", sdp: ev.answer_sdp })
|
||||||
|
.then(function(){}, function(err) {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "on_disconnected": {
|
||||||
|
thisWebRTCPlayer.isConnected = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.type in me.listeners) {
|
||||||
|
return me.listeners[ev.type].call(me,ev);
|
||||||
|
}
|
||||||
|
MistVideo.log("Unhandled WebRTC event "+ev.type+": "+JSON.stringify(ev));
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.connect = function(callback){
|
||||||
|
thisWebRTCPlayer.signaling = new WebRTCSignaling(thisWebRTCPlayer.on_event);
|
||||||
|
thisWebRTCPlayer.peerConn = new RTCPeerConnection();
|
||||||
|
thisWebRTCPlayer.peerConn.ontrack = function(ev) {
|
||||||
|
video.srcObject = ev.streams[0];
|
||||||
|
if (callback) { callback(); }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
this.play = function(){
|
||||||
|
if (!this.isConnected) {
|
||||||
|
throw "Not connected, cannot play";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.peerConn
|
||||||
|
.createOffer({
|
||||||
|
offerToReceiveAudio: true,
|
||||||
|
offerToReceiveVideo: true,
|
||||||
|
})
|
||||||
|
.then(function(offer){
|
||||||
|
thisWebRTCPlayer.localOffer = offer;
|
||||||
|
thisWebRTCPlayer.peerConn
|
||||||
|
.setLocalDescription(offer)
|
||||||
|
.then(function(){
|
||||||
|
thisWebRTCPlayer.signaling.sendOfferSDP(thisWebRTCPlayer.localOffer.sdp);
|
||||||
|
}, function(err){console.error(err)});
|
||||||
|
}, function(err){ throw err; });
|
||||||
|
};
|
||||||
|
|
||||||
|
this.stop = function(){
|
||||||
|
if (!this.isConnected) { throw "Not connected, cannot stop." }
|
||||||
|
this.signaling.send({type: "stop"});
|
||||||
|
};
|
||||||
|
this.seek = function(seekTime){
|
||||||
|
if (!this.isConnected) { return; }
|
||||||
|
this.signaling.send({type: "seek", "seek_time": seekTime*1e3});
|
||||||
|
};
|
||||||
|
this.pause = function(){
|
||||||
|
if (!this.isConnected) { throw "Not connected, cannot pause." }
|
||||||
|
this.signaling.send({type: "pause"});
|
||||||
|
};
|
||||||
|
this.setTrack = function(obj){
|
||||||
|
if (!this.isConnected) { throw "Not connected, cannot set track." }
|
||||||
|
obj.type = "tracks";
|
||||||
|
this.signaling.send(obj);
|
||||||
|
};
|
||||||
|
this.getStats = function(callback){
|
||||||
|
this.peerConn.getStats().then(function(d){
|
||||||
|
var output = {};
|
||||||
|
var entries = Array.from(d.entries());
|
||||||
|
for (var i in entries) {
|
||||||
|
var value = entries[i];
|
||||||
|
if (value[1].type == "inbound-rtp") {
|
||||||
|
output[value[0]] = value[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(output);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//input only
|
||||||
|
/*
|
||||||
|
this.sendVideoBitrate = function(bitrate) {
|
||||||
|
this.send({type: "video_bitrate", video_bitrate: bitrate});
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.connect();
|
||||||
|
}
|
||||||
|
function WebRTCSignaling(onEvent){
|
||||||
|
this.ws = null;
|
||||||
|
|
||||||
|
this.ws = new WebSocket(MistVideo.source.url.replace(/^http/,"ws"));
|
||||||
|
|
||||||
|
this.ws.onopen = function() {
|
||||||
|
onEvent({type: "on_connected"});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.ws.onmessage = function(e) {
|
||||||
|
try {
|
||||||
|
var cmd = JSON.parse(e.data);
|
||||||
|
onEvent(cmd);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error("Failed to parse a response from MistServer",err,e.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* See http://tools.ietf.org/html/rfc6455#section-7.4.1 */
|
||||||
|
this.ws.onclose = function(ev) {
|
||||||
|
switch (ev.code) {
|
||||||
|
default: {
|
||||||
|
onEvent({type: "on_disconnected"});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendOfferSDP = function(sdp) {
|
||||||
|
this.send({type: "offer_sdp", offer_sdp: sdp});
|
||||||
|
};
|
||||||
|
this.send = function(cmd) {
|
||||||
|
if (!this.ws) {
|
||||||
|
throw "Not initialized, cannot send "+JSON.stringify(cmd);
|
||||||
|
}
|
||||||
|
this.ws.send(JSON.stringify(cmd));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.webrtc = new WebRTCPlayer();
|
||||||
|
|
||||||
|
this.api = {};
|
||||||
|
|
||||||
|
//override video duration
|
||||||
|
var duration;
|
||||||
|
Object.defineProperty(this.api,"duration",{
|
||||||
|
get: function(){ return duration; }
|
||||||
|
});
|
||||||
|
|
||||||
|
//override seeking
|
||||||
|
Object.defineProperty(this.api,"currentTime",{
|
||||||
|
get: function(){
|
||||||
|
return seekoffset + video.currentTime;
|
||||||
|
},
|
||||||
|
set: function(value){
|
||||||
|
seekoffset = value - video.currentTime;
|
||||||
|
video.pause();
|
||||||
|
me.webrtc.seek(value);
|
||||||
|
MistUtil.event.send("seeking",value,video);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//redirect properties
|
||||||
|
//using a function to make sure the "item" is in the correct scope
|
||||||
|
function reroute(item) {
|
||||||
|
Object.defineProperty(me.api,item,{
|
||||||
|
get: function(){ return video[item]; },
|
||||||
|
set: function(value){
|
||||||
|
return video[item] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var list = [
|
||||||
|
"volume"
|
||||||
|
,"muted"
|
||||||
|
,"loop"
|
||||||
|
,"paused",
|
||||||
|
,"error"
|
||||||
|
,"textTracks"
|
||||||
|
,"webkitDroppedFrameCount"
|
||||||
|
,"webkitDecodedFrameCount"
|
||||||
|
];
|
||||||
|
for (var i in list) {
|
||||||
|
reroute(list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//redirect methods
|
||||||
|
function redirect(item) {
|
||||||
|
if (item in video) {
|
||||||
|
me.api[item] = function(){
|
||||||
|
return video[item].call(video,arguments);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var list = ["load","getVideoPlaybackQuality"];
|
||||||
|
for (var i in list) {
|
||||||
|
redirect(list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//redirect play
|
||||||
|
me.api.play = function(){
|
||||||
|
if (me.api.currentTime) {
|
||||||
|
if ((!me.webrtc.isConnected) || (me.webrtc.peerConn.iceConnectionState != "completed")) {
|
||||||
|
me.webrtc.connect(function(){
|
||||||
|
me.webrtc.seek(me.api.currentTime);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
me.webrtc.seek(me.api.currentTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
video.play();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//redirect pause
|
||||||
|
me.api.pause = function(){
|
||||||
|
video.pause();
|
||||||
|
try {
|
||||||
|
me.webrtc.pause();
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
MistUtil.event.send("paused",null,video);
|
||||||
|
};
|
||||||
|
|
||||||
|
me.api.setTracks = function(obj){
|
||||||
|
me.webrtc.setTrack(obj);
|
||||||
|
};
|
||||||
|
function correctSubtitleSync() {
|
||||||
|
if (!me.api.textTracks[0]) { return; }
|
||||||
|
var currentoffset = me.api.textTracks[0].currentOffset || 0;
|
||||||
|
if (Math.abs(seekoffset - currentoffset) < 1) { return; } //don't bother if the change is small
|
||||||
|
var newCues = [];
|
||||||
|
for (var i = me.api.textTracks[0].cues.length-1; i >= 0; i--) {
|
||||||
|
var cue = me.api.textTracks[0].cues[i];
|
||||||
|
me.api.textTracks[0].removeCue(cue);
|
||||||
|
if (!("orig" in cue)) {
|
||||||
|
cue.orig = {start:cue.startTime,end:cue.endTime};
|
||||||
|
}
|
||||||
|
cue.startTime = cue.orig.start - seekoffset;
|
||||||
|
cue.endTime = cue.orig.end - seekoffset;
|
||||||
|
newCues.push(cue);
|
||||||
|
}
|
||||||
|
for (var i in newCues) {
|
||||||
|
me.api.textTracks[0].addCue(newCues[i]);
|
||||||
|
}
|
||||||
|
me.api.textTracks[0].currentOffset = seekoffset;
|
||||||
|
}
|
||||||
|
me.api.setSubtitle = function(trackmeta) {
|
||||||
|
//remove previous subtitles
|
||||||
|
var tracks = video.getElementsByTagName("track");
|
||||||
|
for (var i = tracks.length - 1; i >= 0; i--) {
|
||||||
|
video.removeChild(tracks[i]);
|
||||||
|
}
|
||||||
|
if (trackmeta) { //if the chosen track exists
|
||||||
|
//add the new one
|
||||||
|
var track = document.createElement("track");
|
||||||
|
video.appendChild(track);
|
||||||
|
track.kind = "subtitles";
|
||||||
|
track.label = trackmeta.label;
|
||||||
|
track.srclang = trackmeta.lang;
|
||||||
|
track.src = trackmeta.src;
|
||||||
|
track.setAttribute("default","");
|
||||||
|
|
||||||
|
//correct timesync
|
||||||
|
track.onload = correctSubtitleSync;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//loop
|
||||||
|
MistUtil.event.addListener(video,"ended",function(){
|
||||||
|
if (me.api.loop) {
|
||||||
|
me.webrtc.connect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ("decodingIssues" in MistVideo.skin.blueprints) {
|
||||||
|
//get additional dev stats
|
||||||
|
var vars = ["nackCount","pliCount","packetsLost","packetsReceived","bytesReceived"];
|
||||||
|
for (var j in vars) {
|
||||||
|
me.api[vars[j]] = 0;
|
||||||
|
}
|
||||||
|
var f = function() {
|
||||||
|
MistVideo.timers.start(function(){
|
||||||
|
me.webrtc.getStats(function(d){
|
||||||
|
for (var i in d) {
|
||||||
|
for (var j in vars) {
|
||||||
|
if (vars[j] in d[i]) {
|
||||||
|
me.api[vars[j]] = d[i][vars[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
f();
|
||||||
|
},1e3);
|
||||||
|
};
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
me.api.unload = function(){
|
||||||
|
try {
|
||||||
|
me.webrtc.stop();
|
||||||
|
} catch (e) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
callback(video);
|
||||||
|
|
||||||
|
};
|
327
src/embed.js
|
@ -1,327 +0,0 @@
|
||||||
function mistembed(streamname) {
|
|
||||||
|
|
||||||
//find the current script
|
|
||||||
var me;
|
|
||||||
if (('currentScript' in document) && (document.currentScript)) {
|
|
||||||
me = document.currentScript;
|
|
||||||
//not supported in old browsers :(
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var scripts = document.getElementsByTagName('script');
|
|
||||||
me = scripts[scripts.length - 1];
|
|
||||||
//not correct if the script is inserted dynamically, but this is how it used to be
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// return the current flash version
|
|
||||||
function flash_version() {
|
|
||||||
var version = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// check in the mimeTypes
|
|
||||||
version = navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin.description.replace(/([^0-9\.])/g, '').split('.')[0];
|
|
||||||
} catch(e){}
|
|
||||||
try {
|
|
||||||
// for our special friend IE
|
|
||||||
version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable("$version").replace(/([^0-9\,])/g, '').split(',')[0];
|
|
||||||
} catch(e){}
|
|
||||||
|
|
||||||
return parseInt(version, 10);
|
|
||||||
};
|
|
||||||
|
|
||||||
// return true if silverlight is installed
|
|
||||||
function silverlight_installed() {
|
|
||||||
var plugin;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// check in the mimeTypes
|
|
||||||
plugin = navigator.plugins["Silverlight Plug-In"];
|
|
||||||
return !!plugin;
|
|
||||||
} catch(e){}
|
|
||||||
try {
|
|
||||||
// for our special friend IE
|
|
||||||
plugin = new ActiveXObject('AgControl.AgControl');
|
|
||||||
return true;
|
|
||||||
} catch(e){}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// return true if the browser thinks it can play the mimetype
|
|
||||||
function html5_video_type(type) {
|
|
||||||
var support = false;
|
|
||||||
|
|
||||||
|
|
||||||
if (type == 'video/mp4') {
|
|
||||||
if ((navigator.userAgent.indexOf('MSIE') > -1) && (parseInt(navigator.userAgent.split('MSIE')[1]) <= 9)) {
|
|
||||||
//IE <= 9 doesn't support MP4, Firefox seems to correctly see it now.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (navigator.userAgent.indexOf('Firefox') > -1) {
|
|
||||||
//firefox claims to support MP4 but doesn't when:
|
|
||||||
// - under win xp
|
|
||||||
// - the stream is live
|
|
||||||
|
|
||||||
if (video.type == 'live') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//find "Windows NT X;" in user userAgent
|
|
||||||
//sorry, I don't like regexes.. I avoid them when I can :$
|
|
||||||
var s = navigator.userAgent.split('Windows NT ');
|
|
||||||
if (s.length > 1) {
|
|
||||||
s = s[1].split(';');
|
|
||||||
s = s[0];
|
|
||||||
if (Number(s) <= 5.1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
var v = document.createElement('video');
|
|
||||||
|
|
||||||
if( v && v.canPlayType(type) != "" )
|
|
||||||
{
|
|
||||||
support = true; // true-ish, anyway
|
|
||||||
}
|
|
||||||
} catch(e){}
|
|
||||||
|
|
||||||
return support;
|
|
||||||
}
|
|
||||||
|
|
||||||
//return true if rtsp is supported
|
|
||||||
function rtsp_support() {
|
|
||||||
var plugin;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// check in the mimeTypes
|
|
||||||
plugin = navigator.mimeTypes["application/x-google-vlc-plugin"];
|
|
||||||
return !!plugin;
|
|
||||||
} catch(e){}
|
|
||||||
try {
|
|
||||||
// for our special friend IE
|
|
||||||
plugin = new ActiveXObject('VideoLAN.Vlcplugin.1');
|
|
||||||
return true;
|
|
||||||
} catch(e){}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse a "type" string from the controller. Format:
|
|
||||||
// xxx/# (e.g. flash/3) or xxx/xxx/xxx (e.g. html5/application/ogg)
|
|
||||||
function parseType(type) {
|
|
||||||
var split = type.split('/');
|
|
||||||
|
|
||||||
if( split.length > 2 ) {
|
|
||||||
split[1] += '/' + split[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
return split;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return true if a type is supported
|
|
||||||
function hasSupport(type) {
|
|
||||||
var typemime = parseType(type);
|
|
||||||
|
|
||||||
switch(typemime[0]) {
|
|
||||||
case 'flash': return flash_version() >= parseInt(typemime[1], 10); break;
|
|
||||||
case 'html5': return html5_video_type(typemime[1]); break;
|
|
||||||
case 'rtsp': return rtsp_support(); break;
|
|
||||||
case 'silverlight': return silverlight_installed(); break;
|
|
||||||
default: return false; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// build HTML for certain kinds of types
|
|
||||||
function buildPlayer(src, container, videowidth, videoheight, vtype) {
|
|
||||||
// used to recalculate the width/height
|
|
||||||
var ratio;
|
|
||||||
|
|
||||||
// get the container's width/height
|
|
||||||
var containerwidth = parseInt(container.clientWidth, 10);
|
|
||||||
var containerheight = parseInt(container.clientHeight, 10);
|
|
||||||
|
|
||||||
if(videowidth > containerwidth && containerwidth > 0) {
|
|
||||||
ratio = videowidth / containerwidth;
|
|
||||||
|
|
||||||
videowidth /= ratio;
|
|
||||||
videoheight /= ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(videoheight > containerheight && containerheight > 0) {
|
|
||||||
ratio = videoheight / containerheight;
|
|
||||||
|
|
||||||
videowidth /= ratio;
|
|
||||||
videoheight /= ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
var maintype = parseType(src.type);
|
|
||||||
mistvideo[streamname].embedded = src;
|
|
||||||
|
|
||||||
switch(maintype[0]) {
|
|
||||||
case 'flash':
|
|
||||||
// maintype[1] is already checked (i.e. user has version > maintype[1])
|
|
||||||
var flashplayer,
|
|
||||||
url = encodeURIComponent(src.url) + '&controlBarMode=floating&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3' + (vtype == 'live' ? "&streamType=live" : "") + (autoplay ? '&autoPlay=true' : '');
|
|
||||||
|
|
||||||
/*
|
|
||||||
if( parseInt(maintype[1], 10) >= 10 ) {
|
|
||||||
flashplayer = 'http://fpdownload.adobe.com/strobe/FlashMediaPlayback_101.swf';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
flashplayer = 'http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf';
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
flashplayer = src.player_url;
|
|
||||||
|
|
||||||
container.innerHTML += '<object width="' + videowidth + '" height="' + videoheight + '">' +
|
|
||||||
'<param name="movie" value="' + flashplayer + '"></param>' +
|
|
||||||
'<param name="flashvars" value="src=' + url + '"></param>' +
|
|
||||||
'<param name="allowFullScreen" value="true"></param>' +
|
|
||||||
'<param name="allowscriptaccess" value="always"></param>' +
|
|
||||||
'<param name="wmode" value="direct"></param>' +
|
|
||||||
(autoplay ? '<param name="autoPlay" value="true">' : '') +
|
|
||||||
'<embed src="' + flashplayer + '" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="' + videowidth + '" height="' + videoheight + '" flashvars="src=' + url + '"></embed>' +
|
|
||||||
'</object>';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'html5':
|
|
||||||
container.innerHTML += '<video width="' + videowidth + '" height="' + videoheight + '" src="' + src.url + '" controls="controls" '+(autoplay ? 'autoplay="autoplay"' : '')+'><strong>No HTML5 video support</strong></video>';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'rtsp':
|
|
||||||
/*container.innerHTML += '<object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="'+videowidth+'" height="'+videoheight+'">'+
|
|
||||||
'<param name="src" value="'+encodeURI(src.url)+'">'+
|
|
||||||
'<param name="console" value="video1">'+
|
|
||||||
'<param name="controls" value="All">'+
|
|
||||||
'<param name="autostart" value="false">'+
|
|
||||||
'<param name="loop" value="false">'+
|
|
||||||
'<embed name="myMovie" src="'+encodeURI(src.url)+'" width="'+videowidth+'" height="'+videoheight+'" autostart="false" loop="false" nojava="true" console="video1" controls="All"></embed>'+
|
|
||||||
'<noembed>Something went wrong.</noembed>'+
|
|
||||||
'</object>'; //realplayer, doesnt work */
|
|
||||||
container.innerHTML += '<embed type="application/x-google-vlc-plugin"'+
|
|
||||||
'pluginspage="http://www.videolan.org"'+
|
|
||||||
'width="'+videowidth+'"'+
|
|
||||||
'height="'+videoheight+'"'+
|
|
||||||
'target="'+encodeURI(src.url)+'"'+
|
|
||||||
'autoplay="'+(autoplay ? 'yes' : 'no')+'"'+
|
|
||||||
'>'+
|
|
||||||
'</embed>'+
|
|
||||||
'<object classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921" codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab">'+
|
|
||||||
'</object>'; //vlc, seems to work, sort of. it's trying anyway
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'silverlight':
|
|
||||||
container.innerHTML += '<object data="data:application/x-silverlight," type="application/x-silverlight" width="' + videowidth + '" height="' + videoheight + '">'+
|
|
||||||
'<param name="source" value="' + encodeURI(src.url) + '/player.xap"/>'+
|
|
||||||
'<param name="onerror" value="onSilverlightError" />'+
|
|
||||||
'<param name="autoUpgrade" value="true" />'+
|
|
||||||
'<param name="background" value="white" />'+
|
|
||||||
'<param name="enableHtmlAccess" value="true" />'+
|
|
||||||
'<param name="minRuntimeVersion" value="3.0.40624.0" />'+
|
|
||||||
'<param name="initparams" value =\'autoload=false,'+(autoplay ? 'autoplay=true' : 'autoplay=false')+',displaytimecode=false,enablecaptions=true,joinLive=true,muted=false,playlist=<playList><playListItems><playListItem title="Test" description="testing" mediaSource="' + encodeURI(src.url) + '" adaptiveStreaming="true" thumbSource="" frameRate="25.0" width="" height=""></playListItem></playListItems></playList>\' />'+
|
|
||||||
'<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" /></a>'+
|
|
||||||
'</object>';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
container.innerHTML += '<strong>Missing embed code for output type "'+src.type+'"</strong>';
|
|
||||||
video.error = 'Missing embed code for output type "'+src.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var video = mistvideo[streamname],
|
|
||||||
container = document.createElement('div'),
|
|
||||||
forceType = false,
|
|
||||||
forceSupportCheck = false,
|
|
||||||
autoplay = true,
|
|
||||||
urlappend = false;
|
|
||||||
|
|
||||||
if (me.parentNode.hasAttribute('data-forcetype')) {
|
|
||||||
forceType = me.parentNode.getAttribute('data-forcetype');
|
|
||||||
}
|
|
||||||
if (me.parentNode.hasAttribute('data-forcesupportcheck')) {
|
|
||||||
forceSupportCheck = true;
|
|
||||||
}
|
|
||||||
if (me.parentNode.hasAttribute('data-noautoplay')) {
|
|
||||||
autoplay = false;
|
|
||||||
}
|
|
||||||
if (me.parentNode.hasAttribute('data-urlappend')) {
|
|
||||||
urlappend = me.parentNode.getAttribute('data-urlappend');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (video.width == 0) { video.width = 250; }
|
|
||||||
if (video.height == 0) { video.height = 250; }
|
|
||||||
|
|
||||||
// create the container
|
|
||||||
me.parentNode.insertBefore(container, me);
|
|
||||||
// set the class to 'mistvideo'
|
|
||||||
container.setAttribute('class', 'mistvideo');
|
|
||||||
// remove script tag
|
|
||||||
me.parentNode.removeChild(me);
|
|
||||||
|
|
||||||
if(video.error) {
|
|
||||||
// there was an error; display it
|
|
||||||
if (video.on_error){
|
|
||||||
container.innerHTML = video.on_error;
|
|
||||||
}else{
|
|
||||||
container.innerHTML = ['<strong>Error: ', video.error, '</strong>'].join('');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((typeof video.source == 'undefined') || (video.source.length < 1)) {
|
|
||||||
// no stream sources
|
|
||||||
if (video.on_error){
|
|
||||||
container.innerHTML = video.on_error;
|
|
||||||
}else{
|
|
||||||
container.innerHTML = '<strong>Error: no active source or compatible protocols for this stream</strong>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// no error, and sources found. Check the video types and output the best
|
|
||||||
// available video player.
|
|
||||||
var i,
|
|
||||||
vtype = (video.type ? video.type : 'unknown'),
|
|
||||||
foundPlayer = false,
|
|
||||||
len = video.source.length;
|
|
||||||
|
|
||||||
for (var i in video.source) {
|
|
||||||
var support = hasSupport(video.source[i].type);
|
|
||||||
video.source[i].browser_support = support;
|
|
||||||
if ((support) || (forceType)) {
|
|
||||||
if ((!forceType) || ((forceType) && (video.source[i].type.indexOf(forceType) >= 0))) {
|
|
||||||
if (foundPlayer === false) {
|
|
||||||
foundPlayer = i;
|
|
||||||
if (!forceSupportCheck) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (foundPlayer === false) {
|
|
||||||
// of all the streams given, none was supported (eg. no flash and HTML5 video). Display error
|
|
||||||
container.innerHTML = '<strong>No support for any player found</strong>';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// we support this kind of video, so build it.
|
|
||||||
var source = video.source[foundPlayer];
|
|
||||||
if (urlappend) {
|
|
||||||
source.url += urlappend;
|
|
||||||
source.relurl += urlappend;
|
|
||||||
}
|
|
||||||
else if (me.src.indexOf('?') != -1) {
|
|
||||||
var params = me.src.split('?');
|
|
||||||
params.shift();
|
|
||||||
params.join('?');
|
|
||||||
source.url += '?'+params;
|
|
||||||
source.relurl += '?'+params;
|
|
||||||
}
|
|
||||||
buildPlayer(source, container, video.width, video.height, vtype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (mistvideo[streamname].embedded ? mistvideo[streamname].embedded.type : false);
|
|
||||||
//keep empty line at end of file
|
|
||||||
}
|
|
|
@ -114,9 +114,12 @@ namespace Mist {
|
||||||
capa["url_match"].append("/info_$.js");
|
capa["url_match"].append("/info_$.js");
|
||||||
capa["url_match"].append("/json_$.js");
|
capa["url_match"].append("/json_$.js");
|
||||||
capa["url_match"].append("/player.js");
|
capa["url_match"].append("/player.js");
|
||||||
capa["url_match"].append("/player.css");
|
|
||||||
capa["url_match"].append("/videojs.js");
|
capa["url_match"].append("/videojs.js");
|
||||||
capa["url_match"].append("/dashjs.js");
|
capa["url_match"].append("/dashjs.js");
|
||||||
|
capa["url_match"].append("/webrtc.js");
|
||||||
|
capa["url_match"].append("/skins/default.css");
|
||||||
|
capa["url_match"].append("/skins/dev.css");
|
||||||
|
capa["url_match"].append("/skins/videojs.css");
|
||||||
capa["url_match"].append("/embed_$.js");
|
capa["url_match"].append("/embed_$.js");
|
||||||
capa["url_match"].append("/flashplayer.swf");
|
capa["url_match"].append("/flashplayer.swf");
|
||||||
capa["url_match"].append("/oldflashplayer.swf");
|
capa["url_match"].append("/oldflashplayer.swf");
|
||||||
|
@ -124,15 +127,11 @@ namespace Mist {
|
||||||
capa["optional"]["wrappers"]["help"] = "Which players are attempted and in what order.";
|
capa["optional"]["wrappers"]["help"] = "Which players are attempted and in what order.";
|
||||||
capa["optional"]["wrappers"]["default"] = "";
|
capa["optional"]["wrappers"]["default"] = "";
|
||||||
capa["optional"]["wrappers"]["type"] = "ord_multi_sel";
|
capa["optional"]["wrappers"]["type"] = "ord_multi_sel";
|
||||||
/*capa["optional"]["wrappers"]["allowed"].append("theoplayer");
|
|
||||||
capa["optional"]["wrappers"]["allowed"].append("jwplayer");*/
|
|
||||||
capa["optional"]["wrappers"]["allowed"].append("html5");
|
capa["optional"]["wrappers"]["allowed"].append("html5");
|
||||||
capa["optional"]["wrappers"]["allowed"].append("videojs");
|
capa["optional"]["wrappers"]["allowed"].append("videojs");
|
||||||
capa["optional"]["wrappers"]["allowed"].append("dashjs");
|
capa["optional"]["wrappers"]["allowed"].append("dashjs");
|
||||||
//capa["optional"]["wrappers"]["allowed"].append("polytrope"); //currently borked
|
capa["optional"]["wrappers"]["allowed"].append("webrtc");
|
||||||
capa["optional"]["wrappers"]["allowed"].append("flash_strobe");
|
capa["optional"]["wrappers"]["allowed"].append("flash_strobe");
|
||||||
capa["optional"]["wrappers"]["allowed"].append("silverlight");
|
|
||||||
capa["optional"]["wrappers"]["allowed"].append("img");
|
|
||||||
capa["optional"]["wrappers"]["option"] = "--wrappers";
|
capa["optional"]["wrappers"]["option"] = "--wrappers";
|
||||||
capa["optional"]["wrappers"]["short"] = "w";
|
capa["optional"]["wrappers"]["short"] = "w";
|
||||||
cfg->addConnectorOptions(8080, capa);
|
cfg->addConnectorOptions(8080, capa);
|
||||||
|
@ -294,6 +293,10 @@ namespace Mist {
|
||||||
fullURL.protocol = getProtocolForPort(fullURL.getPort());
|
fullURL.protocol = getProtocolForPort(fullURL.getPort());
|
||||||
}
|
}
|
||||||
std::string uAgent = H.GetHeader("User-Agent");
|
std::string uAgent = H.GetHeader("User-Agent");
|
||||||
|
|
||||||
|
std::string devSkin = "";
|
||||||
|
if (H.GetVar("dev").size()) { devSkin = ",skin:\"dev\""; }
|
||||||
|
|
||||||
H.Clean();
|
H.Clean();
|
||||||
H.SetHeader("Content-Type", "text/html");
|
H.SetHeader("Content-Type", "text/html");
|
||||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||||
|
@ -307,7 +310,7 @@ namespace Mist {
|
||||||
std::string hlsUrl = "/hls/"+streamName+"/index.m3u8";
|
std::string hlsUrl = "/hls/"+streamName+"/index.m3u8";
|
||||||
std::string mp4Url = "/"+streamName+".mp4";
|
std::string mp4Url = "/"+streamName+".mp4";
|
||||||
|
|
||||||
H.SetBody("<!DOCTYPE html><html><head><title>"+streamName+"</title><style>body{color:white;background:black;}</style></head><body><div class=mistvideo id=\""+streamName+"\"><noscript><video controls autoplay><source src=\""+hlsUrl+"\" type=\"application/vnd.apple.mpegurl\"><source src=\""+mp4Url+"\" type=\"video/mp4\"><a href=\""+hlsUrl+"\">Click here to play the video [Apple]</a><br><a href=\""+mp4Url+"\">Click here to play the video [MP4]</a></video></noscript><script src=\"player.js\"></script><script>mistPlay('"+streamName+"',{host:'"+fullURL.getUrl()+"',target:document.getElementById('"+streamName+"')})</script></div></body></html>");
|
H.SetBody("<!DOCTYPE html><html><head><title>"+streamName+"</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><style>html{margin:0;padding:0;display:table;width:100%;height:100%;}body{color:white;background:#0f0f0f;margin:0;padding:0;display:table-cell;vertical-align:middle;text-align:center}body>div>div{text-align:left;}</style></head><body><div class=mistvideo id=\""+streamName+"\"><noscript><video controls autoplay><source src=\""+hlsUrl+"\" type=\"application/vnd.apple.mpegurl\"><source src=\""+mp4Url+"\" type=\"video/mp4\"><a href=\""+hlsUrl+"\">Click here to play the video [Apple]</a><br><a href=\""+mp4Url+"\">Click here to play the video [MP4]</a></video></noscript><script src=\"player.js\"></script><script>mistPlay('"+streamName+"',{host:'"+fullURL.getUrl()+"',target:document.getElementById('"+streamName+"')"+devSkin+"})</script></div></body></html>");
|
||||||
if ((uAgent.find("iPad") != std::string::npos) || (uAgent.find("iPod") != std::string::npos) || (uAgent.find("iPhone") != std::string::npos)) {
|
if ((uAgent.find("iPad") != std::string::npos) || (uAgent.find("iPod") != std::string::npos) || (uAgent.find("iPhone") != std::string::npos)) {
|
||||||
H.SetHeader("Location",hlsUrl);
|
H.SetHeader("Location",hlsUrl);
|
||||||
H.SendResponse("307", "HLS redirect", myConn);
|
H.SendResponse("307", "HLS redirect", myConn);
|
||||||
|
@ -568,7 +571,7 @@ namespace Mist {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((H.url.length() > 9 && H.url.substr(0, 6) == "/info_" && H.url.substr(H.url.length() - 3, 3) == ".js") || (H.url.length() > 10 && H.url.substr(0, 7) == "/embed_" && H.url.substr(H.url.length() - 3, 3) == ".js") || (H.url.length() > 9 && H.url.substr(0, 6) == "/json_" && H.url.substr(H.url.length() - 3, 3) == ".js")){
|
if ((H.url.length() > 9 && H.url.substr(0, 6) == "/info_" && H.url.substr(H.url.length() - 3, 3) == ".js") || (H.url.length() > 9 && H.url.substr(0, 6) == "/json_" && H.url.substr(H.url.length() - 3, 3) == ".js")){
|
||||||
if (websocketHandler()){return;}
|
if (websocketHandler()){return;}
|
||||||
std::string reqHost = HTTP::URL(H.GetHeader("Host")).host;
|
std::string reqHost = HTTP::URL(H.GetHeader("Host")).host;
|
||||||
std::string useragent = H.GetVar("ua");
|
std::string useragent = H.GetVar("ua");
|
||||||
|
@ -600,24 +603,13 @@ namespace Mist {
|
||||||
}else{
|
}else{
|
||||||
response = json_resp.toString();
|
response = json_resp.toString();
|
||||||
}
|
}
|
||||||
if (rURL.substr(0, 7) == "/embed_" && !json_resp.isMember("error")){
|
|
||||||
#include "embed.js.h"
|
|
||||||
response.append("\n(");
|
|
||||||
if (embed_js[embed_js_len - 2] == ';'){//check if we have a trailing ;\n or just \n
|
|
||||||
response.append((char*)embed_js, (size_t)embed_js_len - 2); //remove trailing ";\n" from xxd conversion
|
|
||||||
}else{
|
|
||||||
response.append((char*)embed_js, (size_t)embed_js_len - 1); //remove trailing "\n" from xxd conversion
|
|
||||||
}
|
|
||||||
response.append("(\"" + streamName + "\"));\n");
|
|
||||||
}
|
|
||||||
H.SetBody(response);
|
H.SetBody(response);
|
||||||
H.SendResponse("200", "OK", myConn);
|
H.SendResponse("200", "OK", myConn);
|
||||||
H.Clean();
|
H.Clean();
|
||||||
return;
|
return;
|
||||||
} //embed code generator
|
} //embed code generator
|
||||||
|
|
||||||
|
if ((H.url == "/player.js") || ((H.url.substr(0, 7) == "/embed_") && (H.url.length() > 10) && (H.url.substr(H.url.length() - 3, 3) == ".js"))){
|
||||||
if (H.url == "/player.js"){
|
|
||||||
HTTP::URL fullURL(H.GetHeader("Host"));
|
HTTP::URL fullURL(H.GetHeader("Host"));
|
||||||
if (!fullURL.protocol.size()){
|
if (!fullURL.protocol.size()){
|
||||||
fullURL.protocol = getProtocolForPort(fullURL.getPort());
|
fullURL.protocol = getProtocolForPort(fullURL.getPort());
|
||||||
|
@ -627,7 +619,7 @@ namespace Mist {
|
||||||
H.Clean();
|
H.Clean();
|
||||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||||
H.setCORSHeaders();
|
H.setCORSHeaders();
|
||||||
H.SetHeader("Content-Type", "application/javascript");
|
H.SetHeader("Content-Type", "application/javascript; charset=utf-8");
|
||||||
if(method == "OPTIONS" || method == "HEAD"){
|
if(method == "OPTIONS" || method == "HEAD"){
|
||||||
H.SendResponse("200", "OK", myConn);
|
H.SendResponse("200", "OK", myConn);
|
||||||
H.Clean();
|
H.Clean();
|
||||||
|
@ -635,8 +627,10 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
|
|
||||||
response.append("if (typeof mistoptions == 'undefined') { mistoptions = {}; }\nif (!('host' in mistoptions)) { mistoptions.host = '"+fullURL.getUrl()+"'; }\n");
|
response.append("if (typeof mistoptions == 'undefined') { mistoptions = {}; }\nif (!('host' in mistoptions)) { mistoptions.host = '"+fullURL.getUrl()+"'; }\n");
|
||||||
#include "core.js.h"
|
|
||||||
response.append((char*)core_js, (size_t)core_js_len);
|
#include "player.js.h"
|
||||||
|
response.append((char*)player_js, (size_t)player_js_len);
|
||||||
|
|
||||||
jsonForEach(config->getOption("wrappers",true),it){
|
jsonForEach(config->getOption("wrappers",true),it){
|
||||||
bool used = false;
|
bool used = false;
|
||||||
if (it->asStringRef() == "html5"){
|
if (it->asStringRef() == "html5"){
|
||||||
|
@ -649,26 +643,6 @@ namespace Mist {
|
||||||
response.append((char*)flash_strobe_js, (size_t)flash_strobe_js_len);
|
response.append((char*)flash_strobe_js, (size_t)flash_strobe_js_len);
|
||||||
used = true;
|
used = true;
|
||||||
}
|
}
|
||||||
if (it->asStringRef() == "silverlight"){
|
|
||||||
#include "silverlight.js.h"
|
|
||||||
response.append((char*)silverlight_js, (size_t)silverlight_js_len);
|
|
||||||
used = true;
|
|
||||||
}
|
|
||||||
if (it->asStringRef() == "theoplayer"){
|
|
||||||
#include "theoplayer.js.h"
|
|
||||||
response.append((char*)theoplayer_js, (size_t)theoplayer_js_len);
|
|
||||||
used = true;
|
|
||||||
}
|
|
||||||
if (it->asStringRef() == "jwplayer"){
|
|
||||||
#include "jwplayer.js.h"
|
|
||||||
response.append((char*)jwplayer_js, (size_t)jwplayer_js_len);
|
|
||||||
used = true;
|
|
||||||
}
|
|
||||||
if (it->asStringRef() == "polytrope"){
|
|
||||||
#include "polytrope.js.h"
|
|
||||||
response.append((char*)polytrope_js, (size_t)polytrope_js_len);
|
|
||||||
used = true;
|
|
||||||
}
|
|
||||||
if (it->asStringRef() == "dashjs"){
|
if (it->asStringRef() == "dashjs"){
|
||||||
#include "dashjs.js.h"
|
#include "dashjs.js.h"
|
||||||
response.append((char*)dash_js, (size_t)dash_js_len);
|
response.append((char*)dash_js, (size_t)dash_js_len);
|
||||||
|
@ -679,9 +653,9 @@ namespace Mist {
|
||||||
response.append((char*)video_js, (size_t)video_js_len);
|
response.append((char*)video_js, (size_t)video_js_len);
|
||||||
used = true;
|
used = true;
|
||||||
}
|
}
|
||||||
if (it->asStringRef() == "img"){
|
if (it->asStringRef() == "webrtc"){
|
||||||
#include "img.js.h"
|
#include "webrtc.js.h"
|
||||||
response.append((char*)img_js, (size_t)img_js_len);
|
response.append((char*)webrtc_js, (size_t)webrtc_js_len);
|
||||||
used = true;
|
used = true;
|
||||||
}
|
}
|
||||||
if (!used) {
|
if (!used) {
|
||||||
|
@ -689,6 +663,10 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((rURL.substr(0, 7) == "/embed_") && (rURL.length() > 10) && (rURL.substr(rURL.length() - 3, 3) == ".js")){
|
||||||
|
response.append("var container = document.createElement(\"div\");\ncontainer.id = \""+streamName+"\";\ndocument.write(container.outerHTML);\nmistPlay(\""+streamName+"\",{target:document.getElementById(\""+streamName+"\")});");
|
||||||
|
}
|
||||||
|
|
||||||
H.SetBody(response);
|
H.SetBody(response);
|
||||||
H.SendResponse("200", "OK", myConn);
|
H.SendResponse("200", "OK", myConn);
|
||||||
H.Clean();
|
H.Clean();
|
||||||
|
@ -696,8 +674,9 @@ namespace Mist {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (H.url == "/player.css"){
|
if (H.url.substr(0, 7) == "/skins/"){
|
||||||
std::string response;
|
std::string response;
|
||||||
|
std::string url = H.url;
|
||||||
H.Clean();
|
H.Clean();
|
||||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||||
H.setCORSHeaders();
|
H.setCORSHeaders();
|
||||||
|
@ -708,8 +687,24 @@ namespace Mist {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "mist.css.h"
|
if (url == "/skins/default.css") {
|
||||||
response.append((char*)mist_css, (size_t)mist_css_len);
|
#include "skin_default.css.h"
|
||||||
|
response.append((char*)skin_default_css, (size_t)skin_default_css_len);
|
||||||
|
}
|
||||||
|
else if (url == "/skins/dev.css") {
|
||||||
|
#include "skin_dev.css.h"
|
||||||
|
response.append((char*)skin_dev_css, (size_t)skin_dev_css_len);
|
||||||
|
}
|
||||||
|
else if (url == "/skins/videojs.css") {
|
||||||
|
#include "skin_videojs.css.h"
|
||||||
|
response.append((char*)skin_videojs_css, (size_t)skin_videojs_css_len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
H.SetBody("Unknown stylesheet: "+url);
|
||||||
|
H.SendResponse("404", "Unknown stylesheet", myConn);
|
||||||
|
H.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
H.SetBody(response);
|
H.SetBody(response);
|
||||||
H.SendResponse("200", "OK", myConn);
|
H.SendResponse("200", "OK", myConn);
|
||||||
|
@ -728,10 +723,8 @@ namespace Mist {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "playervideo.js.h"
|
#include "player_video.js.h"
|
||||||
response.append((char*)playervideo_js, (size_t)playervideo_js_len);
|
response.append((char*)player_video_js, (size_t)player_video_js_len);
|
||||||
#include "playerhlsvideo.js.h"
|
|
||||||
response.append((char*)playerhlsvideo_js, (size_t)playerhlsvideo_js_len);
|
|
||||||
|
|
||||||
H.SetBody(response);
|
H.SetBody(response);
|
||||||
H.SendResponse("200", "OK", myConn);
|
H.SendResponse("200", "OK", myConn);
|
||||||
|
@ -750,10 +743,30 @@ namespace Mist {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "playerdashlic.js.h"
|
#include "player_dash_lic.js.h"
|
||||||
response.append((char*)playerdashlic_js, (size_t)playerdashlic_js_len);
|
response.append((char*)player_dash_lic_js, (size_t)player_dash_lic_js_len);
|
||||||
#include "playerdash.js.h"
|
#include "player_dash.js.h"
|
||||||
response.append((char*)playerdash_js, (size_t)playerdash_js_len);
|
response.append((char*)player_dash_js, (size_t)player_dash_js_len);
|
||||||
|
|
||||||
|
H.SetBody(response);
|
||||||
|
H.SendResponse("200", "OK", myConn);
|
||||||
|
H.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (H.url == "/webrtc.js"){
|
||||||
|
std::string response;
|
||||||
|
H.Clean();
|
||||||
|
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||||
|
H.setCORSHeaders();
|
||||||
|
H.SetHeader("Content-Type", "application/javascript");
|
||||||
|
if (method == "OPTIONS" || method == "HEAD"){
|
||||||
|
H.SendResponse("200", "OK", myConn);
|
||||||
|
H.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "player_webrtc.js.h"
|
||||||
|
response.append((char*)player_webrtc_js, (size_t)player_webrtc_js_len);
|
||||||
|
|
||||||
H.SetBody(response);
|
H.SetBody(response);
|
||||||
H.SendResponse("200", "OK", myConn);
|
H.SendResponse("200", "OK", myConn);
|
||||||
|
|