Comparar commits
86 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 5337efb0e7 | |||
| 05338dc704 | |||
| c3da40b3d8 | |||
| c84f0386bb | |||
| e9e1eeae63 | |||
| 2ecee69838 | |||
| 69088f3c20 | |||
| 4e6c5bc539 | |||
| 43f10ab655 | |||
| 234f7acf84 | |||
| c40cd9b03c | |||
| f5681765fd | |||
| a0f06a5908 | |||
| f67c5d951c | |||
| f5ab5d5c43 | |||
| 8719371e21 | |||
| 372ec827a3 | |||
| b994a177f9 | |||
| 9bea1b768f | |||
| 52975871e1 | |||
| ca9d044ae9 | |||
| 84e1f508e7 | |||
| 79d5694c99 | |||
| fbadb72eb1 | |||
| a4213763be | |||
| cd4f7e1945 | |||
| 58aaa100aa | |||
| 8437f704c7 | |||
| 375a201303 | |||
| ecd8fcc46e | |||
| 304921128c | |||
| 20d5342da2 | |||
| 14e250cdf4 | |||
| 66068858d7 | |||
| 17cec68bbb | |||
| 740fca702c | |||
| c4fb8b6fb4 | |||
| e967754c27 | |||
| 2b59be792d | |||
| c0c6db7071 | |||
| e14909468a | |||
| 865f914dad | |||
| 7631edae24 | |||
| 24bda85d73 | |||
| 528fa52b29 | |||
| c6c63df7fd | |||
| fa9e97bb56 | |||
| 0c2e3f5f5a | |||
| 7106c005ed | |||
| fb446cd059 | |||
| b9af34b33d | |||
| baab54c560 | |||
| 244159d9e9 | |||
| 61aad619a8 | |||
| a2249ddf3e | |||
| 23c219d0ce | |||
| a6b549813e | |||
| 4f34034c51 | |||
| 9b881cdf13 | |||
| 219f83e1f2 | |||
| e6967528cc | |||
| 3c21510d72 | |||
| 24e6e72dc4 | |||
| 34896d1f2c | |||
| 18ef75afbb | |||
| 16d9525fa8 | |||
| 0deba6e673 | |||
| 3708b1b6a5 | |||
| 386161c5b9 | |||
| aa72d9b050 | |||
| c345889535 | |||
| b7e7da427f | |||
| c6153f7556 | |||
| 11a75fe74f | |||
| 8a5f667159 | |||
| a2651b9ab5 | |||
| 1fedf3c1b9 | |||
| 2dc3de9de1 | |||
| d1824d7c28 | |||
| a9c9722647 | |||
| 534fb39e89 | |||
| 35dfa99e59 | |||
| a4986cd5f9 | |||
| 2d8f283680 | |||
| f9c1905840 | |||
| aca861a190 |
@@ -10,3 +10,29 @@ CHANGELOG
|
||||
|
||||
---- 3.0.4 / 2012-01-12 / undefined-source-fix ---------------------------------
|
||||
* Fixing an undefined source when no sources exist on load
|
||||
|
||||
---- 3.0.5 / 2012-01-12 / event-layer-x-deprecation-fix ------------------------
|
||||
* Removed deprecated event.layerX and layerY
|
||||
|
||||
---- 3.0.6 / 2012-01-12 / docs-url-fix -----------------------------------------
|
||||
* Fixed wrong URL for CDN in docs
|
||||
|
||||
---- 3.0.7 / 2012-01-12 / fixing-ie8-poster-bug --------------------------------
|
||||
* Fixed an ie8 breaking bug with the poster
|
||||
|
||||
---- 3.0.8 / 2012-01-23 / fix-ie-controls-hiding -------------------------------
|
||||
* Fixed issue with controls not hiding in IE due to no opacity support
|
||||
|
||||
---- 3.1.0 / 2012-01-30 / leonardo ---------------------------------------------
|
||||
* Added CSS fix for Firefox 9 fullscreen (in the rare case that it's enabled)
|
||||
* Replaced swfobject with custom embed to save file size.
|
||||
* Added flash iframe-mode, an experimental method for getting around flash reloading issues.
|
||||
* Fixed issue with volume knob position. Improved controls fading.
|
||||
* Fixed ian issue with triggering fullscreen a second time.
|
||||
* Fixed issue with getting attributes in Firefox 3.0
|
||||
* Escaping special characters in source URL for Flash
|
||||
* Added a check for if Firefox is enabled which fixes a Firefox 9 issue
|
||||
* Stopped spinner from showing on 'stalled' events since browsers sometimes don't show that they've recovered.
|
||||
* Fixed CDN Version which was breaking dev.html
|
||||
* Made full-window mode more independent
|
||||
* Added rakefile for release generation
|
||||
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
require 'rubygems'
|
||||
require 'yaml'
|
||||
require 'httparty'
|
||||
|
||||
namespace :build do
|
||||
|
||||
desc "Build version for current '/c/' CDN copy and locked in version"
|
||||
task :current do
|
||||
Rake::Task["build:source"].execute
|
||||
|
||||
cdn_version_num = "#{version['major']}.#{version['minor']}"
|
||||
|
||||
['c', cdn_version_num].each do |vsn|
|
||||
Rake::Shell["mkdir dist/#{vsn}"]
|
||||
|
||||
File.open("dist/#{vsn}/video.js", "w+") do |file|
|
||||
file.puts File.read("dist/video.min.js").sub('GENERATED_CDN_VSN', vsn)
|
||||
end
|
||||
|
||||
Rake::Shell["cp dist/video-js.min.css dist/#{vsn}/video-js.css"]
|
||||
Rake::Shell["cp dist/video-js.swf dist/#{vsn}/video-js.swf"]
|
||||
Rake::Shell["cp dist/video-js.png dist/#{vsn}/video-js.png"]
|
||||
Rake::Shell["cp dist/demo.html dist/#{vsn}/demo.html"]
|
||||
end
|
||||
|
||||
Rake::Shell["mkdir dist/video-js"]
|
||||
|
||||
File.open("dist/video-js/video.min.js", "w+") do |file|
|
||||
file.puts File.read("dist/video.min.js").sub('GENERATED_CDN_VSN', cdn_version_num)
|
||||
end
|
||||
|
||||
File.open("dist/video-js/video.js", "w+") do |file|
|
||||
file.puts File.read("dist/video.js").sub('GENERATED_CDN_VSN', cdn_version_num)
|
||||
end
|
||||
|
||||
Rake::Shell["cp dist/video-js.min.css dist/video-js/video-js.min.css"]
|
||||
Rake::Shell["cp dist/video-js.css dist/video-js/video-js.css"]
|
||||
Rake::Shell["cp dist/video-js.swf dist/video-js/video-js.swf"]
|
||||
Rake::Shell["cp dist/video-js.png dist/video-js/video-js.png"]
|
||||
Rake::Shell["cp dist/demo.html dist/video-js/demo.html"]
|
||||
|
||||
Rake::Shell["cd dist && zip -r video-js-#{version_number}.zip video-js && cd .."]
|
||||
|
||||
if `git name-rev --name-only HEAD`.strip != 'stable'
|
||||
Rake::Log["*** WARNING: NOT ON STABLE BRANCH!!! ***"]
|
||||
end
|
||||
end
|
||||
|
||||
desc "Build source files for packaging"
|
||||
task :source do
|
||||
Rake::Log["Building Version: " << version_number]
|
||||
|
||||
if File.exist?("dist")
|
||||
Rake::Shell["rm -r dist"]
|
||||
end
|
||||
|
||||
# Make distribution folder
|
||||
Rake::Shell["mkdir dist"]
|
||||
|
||||
Rake::Log["Combining source files"]
|
||||
combined = ""
|
||||
|
||||
first_files = [ '_begin.js', 'core.js', 'lib.js' ]
|
||||
|
||||
first_files.each do |item|
|
||||
Rake::Log[item]
|
||||
combined << File.read("src/#{item}")
|
||||
end
|
||||
|
||||
Dir.foreach('src') do |item|
|
||||
next if (['.', '..', '.DS_Store', 'setup.js', '_end.js'] + first_files).include? item
|
||||
combined << File.read("src/#{item}")
|
||||
end
|
||||
|
||||
# combined << File.read("flash/swfobject.js")
|
||||
combined << File.read("src/setup.js")
|
||||
combined << File.read("src/_end.js")
|
||||
|
||||
Rake::Log["Adding version number"]
|
||||
combined = combined.gsub('GENERATED_AT_BUILD', version_number)
|
||||
|
||||
File.open('dist/video.js', "w+") do |file|
|
||||
file.puts "" << combined
|
||||
end
|
||||
|
||||
Rake::Log["Copying CSS and updated version"]
|
||||
File.open('dist/video-js.css', "w+") do |file|
|
||||
file.puts File.read("design/video-js.css").gsub('GENERATED_AT_BUILD', version_number)
|
||||
end
|
||||
|
||||
Rake::Log["Copying suppporting files"]
|
||||
Rake::Shell["cp design/video-js.png dist/video-js.png"]
|
||||
Rake::Shell["cp flash/video-js.swf dist/video-js.swf"]
|
||||
|
||||
Rake::Shell["cp build/release-files/README.md dist/README.md"]
|
||||
Rake::Shell["cp build/release-files/demo.html dist/demo.html"]
|
||||
Rake::Shell["cp LGPLv3-LICENSE.txt dist/LGPLv3-LICENSE.txt"]
|
||||
|
||||
Rake::Log["Minimizing JavaScript"]
|
||||
Rake::Shell["java -jar build/lib/yuicompressor-2.4.7.jar dist/video.js -o dist/video.min.js"]
|
||||
|
||||
Rake::Log["Minimizing CSS"]
|
||||
Rake::Shell["java -jar build/lib/yuicompressor-2.4.7.jar dist/video-js.css -o dist/video-js.min.css"]
|
||||
|
||||
Rake::Log[version_number << " Built"]
|
||||
end
|
||||
|
||||
desc "Build list of source files for easy inclusion in projects"
|
||||
task :js_source do
|
||||
|
||||
File.open("dev/source-list.js", "w+") do |file|
|
||||
file.puts "var vjsSourceList = [];"
|
||||
|
||||
src_array = ["src/core", "src/lib"]
|
||||
last = ["src/setup"] # "flash/swfobject",
|
||||
exclude = [".", "..", ".DS_Store", "_end.js", "_begin.js"]
|
||||
|
||||
Dir.foreach('src') do |item|
|
||||
next if exclude.include? item
|
||||
|
||||
item_name = "src/" << item.sub(".js", "")
|
||||
|
||||
next if (src_array + last).include? item_name
|
||||
|
||||
src_array << item_name
|
||||
end
|
||||
|
||||
src_array = src_array + last
|
||||
|
||||
src_array.each do |item|
|
||||
file.puts "vjsSourceList.push('#{item}')"
|
||||
end
|
||||
# file.puts "vjsSourceList.push('src/#{item.sub(".js", "")}')"
|
||||
# file.puts "vjsSourceList.push('flash/swfobject.js')"
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def version
|
||||
YAML.load(File.read("VERSION.yml"))
|
||||
end
|
||||
|
||||
def version_number
|
||||
"#{version['major']}.#{version['minor']}.#{version['patch']}"
|
||||
end
|
||||
|
||||
module Rake
|
||||
class Shell
|
||||
def self.[](command)
|
||||
output = %x[#{command}]
|
||||
if $?.to_i > 0
|
||||
puts "-----> Process aborted"
|
||||
puts " Exit status: #{$?}"
|
||||
exit($?.to_i)
|
||||
end
|
||||
puts output
|
||||
end
|
||||
end
|
||||
|
||||
class Log
|
||||
def self.[](message)
|
||||
puts "-----> #{message.split("\n").join("\n ")}"
|
||||
end
|
||||
end
|
||||
end
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
---
|
||||
major: 3
|
||||
patch: 4
|
||||
minor: 0
|
||||
patch: 0
|
||||
minor: 1
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ cat src/controls.js >> dist/video.js
|
||||
cat src/tracks.js >> dist/video.js
|
||||
|
||||
# h5swf temporarily requires swfobject
|
||||
cat flash/swfobject.js >> dist/video.js
|
||||
# cat flash/swfobject.js >> dist/video.js
|
||||
|
||||
cat src/setup.js >> dist/video.js
|
||||
cat src/_end.js >> dist/video.js
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<head>
|
||||
<title>Video.js | HTML5 Video Player</title>
|
||||
|
||||
<link href="video-js.css" rel="stylesheet" type="text/css">
|
||||
<link href="http://vjs.zencdn.net/c/video-js.css" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- video.js must be in the <head> for older IEs to work. -->
|
||||
<script src="video.js"></script>
|
||||
<script src="http://vjs.zencdn.net/c/video.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
body { background-color: #ccc; font-size: 11px; font-family: 'Helvetica Neue', helvetica, arial; }
|
||||
#main { width: 1000px; margin: 10px auto 0; }
|
||||
td, th { text-align: left; vertical-align: top; }
|
||||
td.info-col { width: 240px; }
|
||||
td.data { text-align: right; }
|
||||
span.na { color: red; }
|
||||
span.undefined { color: #999; }
|
||||
@@ -1,75 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>HTML5 Video Player</title>
|
||||
|
||||
<link rel="stylesheet" href="../design/video-js.css" type="text/css">
|
||||
<!--[if lt IE 9]>
|
||||
<script>
|
||||
document.createElement("video"); // HTML5 Shiv. Must be in <head>.
|
||||
</script>
|
||||
<![endif]-->
|
||||
|
||||
<!--[if IE]>
|
||||
<script src="https://getfirebug.com/firebug-lite.js" type="text/javascript" charset="utf-8"></script>
|
||||
<![endif]-->
|
||||
|
||||
|
||||
<script src="../src/core.js"></script>
|
||||
<script src="../src/lib.js"></script>
|
||||
<script src="../src/ecma.js"></script>
|
||||
<script src="../src/json.js"></script>
|
||||
|
||||
<script src="../src/component.js"></script>
|
||||
<script src="../src/player.js"></script>
|
||||
<script src="../src/tech.js"></script>
|
||||
<script src="../src/controls.js"></script>
|
||||
<script src="../src/events.js"></script>
|
||||
<script src="../src/tracks.js"></script>
|
||||
|
||||
<script src="../flash/swfobject.js"></script>
|
||||
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="compare.css" type="text/css">
|
||||
<script type="text/javascript" src="compare.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<table border="0" cellspacing="5" cellpadding="5">
|
||||
<tr><th colspan="2">HTML5</th><th colspan="2">Flash</th></tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<video id="vid1" class="video-js vjs-default-skin" controls preload="auto" width="480" height="198"
|
||||
poster="http://video-js.zencoder.com/oceans-clip.png">
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm'>
|
||||
</video>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<video id="vid2" class="video-js vjs-default-skin" controls preload="auto" width="480" height="198"
|
||||
poster="http://video-js.zencoder.com/oceans-clip.png">
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4'>
|
||||
<!-- <source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm'> -->
|
||||
</video>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="info-col">
|
||||
<table id="html5_props" border="0" cellspacing="0" cellpadding="0"></table>
|
||||
</td>
|
||||
<td class="info-col">
|
||||
<div id="html5_events"></div>
|
||||
</td>
|
||||
<td class="info-col">
|
||||
<table id="flash_props" border="0" cellspacing="0" cellpadding="0"></table>
|
||||
</td>
|
||||
<td class="info-col">
|
||||
<div id="flash_events"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,70 +0,0 @@
|
||||
_V_.options.flash.swf = "../flash/video-js.swf";
|
||||
_V_.options.flash.swf = "http://andylemay.com/dev/videojs/VideoJS.swf";
|
||||
|
||||
$(function(){
|
||||
var tech, i, tname, player,
|
||||
techList = ["html5","flash"],
|
||||
props = "error,currentSrc,networkState,buffered,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoWidth,videoHeight,textTracks,preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,controls,volume,muted,defaultMuted,poster".split(","),
|
||||
methods = "play,pause,src,load,canPlayType,addTextTrack",
|
||||
notUsed = "mediaGroup,controller,videoTracks,audioTracks,defaultPlaybackRate";
|
||||
|
||||
for (i=0; i < techList.length; i++) {
|
||||
tech = techList[i];
|
||||
tname = tech.toLowerCase();
|
||||
|
||||
player = _V_("vid"+(i+1), { "techOrder":[tech] });
|
||||
|
||||
_V_.each(_V_.html5.events, function(evt){
|
||||
|
||||
player.addEvent(evt, _V_.proxy(tname, function(evt){
|
||||
var eventsId = "#"+this+"_events",
|
||||
type = evt.type,
|
||||
prev = $(eventsId+" div").first();
|
||||
|
||||
if (prev && prev.html() && prev.html().indexOf(type + " ") === 0) {
|
||||
var countSpan = prev.children(".count");
|
||||
countSpan.html(parseInt(countSpan.html() || 1) + 1);
|
||||
} else {
|
||||
$("#"+this+"_events").prepend("<div>" + evt.type + " <span class='count'></span></div>");
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
var propTable = $("#"+tname+"_props");
|
||||
_V_.each(props, function(prop){
|
||||
propTable.append("<tr><th>"+prop+"</th><td id='"+tname+prop+"' class='data'></td></tr>")
|
||||
});
|
||||
|
||||
setInterval(_V_.proxy(player, function(){
|
||||
_V_.each(props, _V_.proxy(this, function(prop){
|
||||
var result = ""
|
||||
try {
|
||||
result = this[prop]();
|
||||
if (result === false) result = "false";
|
||||
if (result === true) result = "true";
|
||||
if (result === "") result = "''";
|
||||
if (result === null) result = "<span class='undefined'>null</span>";
|
||||
if (result === undefined) result = "<span class='undefined'>undefined</span>";
|
||||
if (typeof result.start == "function") {
|
||||
var newResult = "", i;
|
||||
if (result.length > 0) {
|
||||
|
||||
for (i=0;i<result.length;i++) {
|
||||
newResult += "l:"+result.length+" s:"+result.start(i)+" e:"+result.end(i);
|
||||
}
|
||||
} else {
|
||||
newResult = "-";
|
||||
}
|
||||
result = newResult;
|
||||
// result = result.toString();
|
||||
// result = (result.length > 0) ? "s:"+result.start(0)+" e:"+result.end(0) : "-";
|
||||
}
|
||||
} catch(e) {
|
||||
result = "<span class='na'>N/A</span>";
|
||||
}
|
||||
$("#"+this.techName+prop).html(result);
|
||||
}));
|
||||
}), 500);
|
||||
|
||||
};
|
||||
});
|
||||
+32
-10
@@ -1,7 +1,9 @@
|
||||
/*
|
||||
VideoJS Default Styles (http://videojs.com)
|
||||
Version 3.0
|
||||
Version GENERATED_AT_BUILD
|
||||
*/
|
||||
|
||||
/*
|
||||
REQUIRED STYLES (be careful overriding)
|
||||
================================================================================ */
|
||||
/* When loading the player, the video tag is replaced with a DIV,
|
||||
@@ -25,6 +27,9 @@ REQUIRED STYLES (be careful overriding)
|
||||
/* Playback technology elements expand to the width/height of the containing div. <video> or <object> */
|
||||
.video-js .vjs-tech { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
|
||||
/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when checking fullScreenEnabled. */
|
||||
.video-js:-moz-full-screen { position: absolute; }
|
||||
|
||||
/* Fullscreen Styles */
|
||||
body.vjs-full-window {
|
||||
padding: 0; margin: 0;
|
||||
@@ -46,10 +51,31 @@ body.vjs-full-window {
|
||||
position: relative; width: 100%; max-height: 100%;
|
||||
}
|
||||
|
||||
|
||||
/* Subtiles Styles */
|
||||
.video-js .vjs-subtitles { color: #fff; font-size: 20px; text-align: center; position: absolute; bottom: 40px; left: 0; right: 0; }
|
||||
|
||||
/* Fading sytles, used to fade control bar. */
|
||||
.vjs-fade-in {
|
||||
visibility: visible !important; /* Needed to make sure things hide in older browsers too. */
|
||||
opacity: 1 !important;
|
||||
|
||||
-webkit-transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||
-moz-transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||
-ms-transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||
-o-transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||
transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||
}
|
||||
.vjs-fade-out {
|
||||
visibility: hidden !important;
|
||||
opacity: 0 !important;
|
||||
|
||||
-webkit-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||
-moz-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||
-ms-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||
-o-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||
transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||
}
|
||||
|
||||
/* DEFAULT SKIN (override in another file to create new skins)
|
||||
================================================================================
|
||||
Instead of editing this file, I recommend creating your own skin CSS file to be included after this file,
|
||||
@@ -60,8 +86,6 @@ so you can upgrade to newer versions easier. You can remove all these styles by
|
||||
position: absolute;
|
||||
bottom: 0; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
|
||||
left: 0; right: 0; /* 100% width of div */
|
||||
opacity: 0.85;
|
||||
display: none; /* Start hidden */
|
||||
margin: 0; padding: 0; /* Controls are absolutely position, so no padding necessary */
|
||||
height: 2.6em; /* Including any margin you want above or below control items */
|
||||
color: #fff; border-top: 1px solid #404040;
|
||||
@@ -78,12 +102,10 @@ so you can upgrade to newer versions easier. You can remove all these styles by
|
||||
/*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#242424', endColorstr='#171717',GradientType=0 );*/ /* IE6-9 */
|
||||
background: linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* W3C */
|
||||
|
||||
/* Fade-in using CSS Transitions */
|
||||
-webkit-transition: opacity 0.3s linear;
|
||||
-moz-transition: opacity 0.3s linear;
|
||||
-o-transition: opacity 0.3s linear;
|
||||
-ms-transition: opacity 0.3s linear;
|
||||
transition: opacity 0.3s linear;
|
||||
/* Start hidden and with 0 opacity. Opacity is used to fade in modern browsers. */
|
||||
/* Can't use display block to hide initially because widths of slider handles aren't calculated and avaialbe for positioning correctly. */
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* General styles for individual controls. */
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
<script src="src/controls.js"></script>
|
||||
<script src="src/events.js"></script>
|
||||
<script src="src/tracks.js"></script>
|
||||
|
||||
<script src="flash/swfobject.js"></script>
|
||||
|
||||
<script src="src/setup.js"></script>
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// Attempting to create a portable script that loads source files in order. So we can change which files are included and have it change multiple places.
|
||||
var vjsSourceList = ["require",
|
||||
'order!../../src/core.js',
|
||||
'order!../../src/lib.js',
|
||||
'order!../../src/component.js',
|
||||
'order!../../src/controls.js',
|
||||
'order!../../src/ecma.js',
|
||||
'order!../../src/events.js',
|
||||
'order!../../src/json.js',
|
||||
'order!../../src/player.js',
|
||||
'order!../../src/tech.js',
|
||||
'order!../../src/tracks.js',
|
||||
'order!../../flash/swfobject.js',
|
||||
'order!../../src/setup.js'
|
||||
];
|
||||
|
||||
// Not going to be used in production, so eval ok.
|
||||
require([vjsSourceList])
|
||||
|
||||
// var requireEval = '';
|
||||
// for (var i=0; i < vjsSourceList.length; i++) {
|
||||
// requireEval += 'require(["order!'+vjsSourceList[i]+'"], function() { ';
|
||||
// }
|
||||
//
|
||||
// requireEval += 'var libsLoaded = true;'
|
||||
//
|
||||
// for (var i=0; i < vjsSourceList.length; i++) {
|
||||
// requireEval += ' }); ';
|
||||
// }
|
||||
//
|
||||
// eval(requireEval);
|
||||
+2144
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+12
-12
@@ -1,13 +1,13 @@
|
||||
var vjsSourceList = [];
|
||||
vjsSourceList.push('_begin.js')
|
||||
vjsSourceList.push('_end.js')
|
||||
vjsSourceList.push('component.js')
|
||||
vjsSourceList.push('controls.js')
|
||||
vjsSourceList.push('core.js')
|
||||
vjsSourceList.push('ecma.js')
|
||||
vjsSourceList.push('events.js')
|
||||
vjsSourceList.push('json.js')
|
||||
vjsSourceList.push('lib.js')
|
||||
vjsSourceList.push('player.js')
|
||||
vjsSourceList.push('tech.js')
|
||||
vjsSourceList.push('tracks.js')
|
||||
vjsSourceList.push('src/core')
|
||||
vjsSourceList.push('src/lib')
|
||||
vjsSourceList.push('src/component')
|
||||
vjsSourceList.push('src/controls')
|
||||
vjsSourceList.push('src/ecma')
|
||||
vjsSourceList.push('src/events')
|
||||
vjsSourceList.push('src/json')
|
||||
vjsSourceList.push('src/player')
|
||||
vjsSourceList.push('src/tech')
|
||||
vjsSourceList.push('src/tracks')
|
||||
vjsSourceList.push('flash/swfobject')
|
||||
vjsSourceList.push('src/setup')
|
||||
|
||||
+2
-2
@@ -186,7 +186,7 @@ Now that you have access to a ready player, you can control the video or respond
|
||||
|
||||
{% highlight javascript %}
|
||||
|
||||
myPlayer.enterFullScreen();
|
||||
myPlayer.requestFullScreen();
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
@@ -197,7 +197,7 @@ Now that you have access to a ready player, you can control the video or respond
|
||||
|
||||
{% highlight javascript %}
|
||||
|
||||
myPlayer.exitFullScreen();
|
||||
myPlayer.cancelFullScreen();
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@ You can download the Video.js source and host it on your own servers, or use the
|
||||
|
||||
{% highlight html %}
|
||||
|
||||
<script src="http://vjs.zencdn.com/c/video.js"></script>
|
||||
<link href="http://vjs.zencdn.com/c/video-js.css" rel="stylesheet">
|
||||
<script src="http://vjs.zencdn.net/c/video.js"></script>
|
||||
<link href="http://vjs.zencdn.net/c/video-js.css" rel="stylesheet">
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
var vjsSourceList = [];
|
||||
+2
-3
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
Video.js - HTML5 Video Player
|
||||
Version 3.0r2
|
||||
Version GENERATED_AT_BUILD
|
||||
|
||||
LGPL v3 LICENSE INFO
|
||||
This file is part of Video.js. Copyright 2011 Zencoder, Inc.
|
||||
@@ -21,5 +21,4 @@ along with Video.js. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Self-executing function to prevent global vars and help with minification
|
||||
;(function(window, undefined){
|
||||
var document = window.document;
|
||||
|
||||
var document = window.document;
|
||||
@@ -2,8 +2,5 @@
|
||||
// Expose to global
|
||||
window.VideoJS = window._V_ = VideoJS;
|
||||
|
||||
// Run Auto-load players
|
||||
_V_.autoSetup();
|
||||
|
||||
// End self-executing function
|
||||
})(window);
|
||||
+54
-41
@@ -45,18 +45,18 @@ _V_.Component = _V_.Class.extend({
|
||||
init: function(player, options){
|
||||
this.player = player;
|
||||
|
||||
if (options && options.el) {
|
||||
// Allow for overridding default component options
|
||||
options = this.options = _V_.merge(this.options || {}, options);
|
||||
|
||||
// Create element if one wasn't provided in options
|
||||
if (options.el) {
|
||||
this.el = options.el;
|
||||
} else {
|
||||
this.el = this.createElement();
|
||||
}
|
||||
|
||||
// Array of sub-components
|
||||
if (options && options.components) {
|
||||
_V_.each.call(this, options.components, function(comp){
|
||||
this.addComponent(comp);
|
||||
});
|
||||
}
|
||||
// Add any components in options
|
||||
this.initComponents();
|
||||
},
|
||||
|
||||
destroy: function(){},
|
||||
@@ -71,38 +71,47 @@ _V_.Component = _V_.Class.extend({
|
||||
return "";
|
||||
},
|
||||
|
||||
initComponents: function(){
|
||||
var options = this.options;
|
||||
if (options && options.components) {
|
||||
// Loop through components and add them to the player
|
||||
this.eachProp(options.components, function(name, opts){
|
||||
|
||||
// Allow waiting to add components until a specific event is called
|
||||
var tempAdd = this.proxy(function(){
|
||||
this.addComponent(name, opts);
|
||||
});
|
||||
|
||||
if (opts.loadEvent) {
|
||||
this.one(opts.loadEvent, tempAdd)
|
||||
} else {
|
||||
tempAdd();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Add child components to this component.
|
||||
// Will generate a new child component and then append child component's element to this component's element.
|
||||
// Takes either the name of the UI component class, or an object that contains a name, UI Class, and options.
|
||||
addComponent: function(nameORobj){
|
||||
var name, componentClass, options, component;
|
||||
addComponent: function(name, options){
|
||||
var componentClass, component;
|
||||
|
||||
if (typeof nameORobj == "string") {
|
||||
name = nameORobj;
|
||||
// Make sure options is at least an empty object to protect against errors
|
||||
options = options || {};
|
||||
|
||||
// Can also pass in object to define a different class than the name and add other options
|
||||
} else {
|
||||
name = nameORobj.name;
|
||||
componentClass = nameORobj.componentClass;
|
||||
options = nameORobj.options;
|
||||
}
|
||||
|
||||
if (!componentClass) {
|
||||
// Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
|
||||
componentClass = _V_.capitalize(name);
|
||||
}
|
||||
// Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
|
||||
componentClass = options.componentClass || _V_.capitalize(name);
|
||||
|
||||
// Create a new object & element for this controls set
|
||||
// If there's no .player, this is a player
|
||||
component = new _V_[componentClass](this.player || this, options);
|
||||
|
||||
if (this.components === undefined) {
|
||||
this.components = [];
|
||||
}
|
||||
this.components.push(component);
|
||||
|
||||
// Add the UI object's element to the container div (box)
|
||||
this.el.appendChild(component.el);
|
||||
|
||||
// Set property name on player. Could cause conflicts with other prop names, but it's worth making refs easy.
|
||||
this[name] = component;
|
||||
},
|
||||
|
||||
/* Display
|
||||
@@ -114,6 +123,16 @@ _V_.Component = _V_.Class.extend({
|
||||
hide: function(){
|
||||
this.el.style.display = "none";
|
||||
},
|
||||
|
||||
fadeIn: function(){
|
||||
this.removeClass("vjs-fade-out");
|
||||
this.addClass("vjs-fade-in");
|
||||
},
|
||||
|
||||
fadeOut: function(){
|
||||
this.removeClass("vjs-fade-in");
|
||||
this.addClass("vjs-fade-out");
|
||||
},
|
||||
|
||||
addClass: function(classToAdd){
|
||||
_V_.addClass(this.el, classToAdd);
|
||||
@@ -134,6 +153,9 @@ _V_.Component = _V_.Class.extend({
|
||||
triggerEvent: function(type, e){
|
||||
return _V_.triggerEvent(this.el, type, e);
|
||||
},
|
||||
one: function(type, fn) {
|
||||
_V_.one.call(this, this.el, type, fn);
|
||||
},
|
||||
|
||||
/* Ready - Trigger functions when component is ready
|
||||
================================================================================ */
|
||||
@@ -167,22 +189,13 @@ _V_.Component = _V_.Class.extend({
|
||||
|
||||
/* Utility
|
||||
================================================================================ */
|
||||
each: function(arr, fn){
|
||||
if (!arr || arr.length === 0) { return; }
|
||||
for (var i=0,j=arr.length; i<j; i++) {
|
||||
if (fn.call(this, arr[i], i)) { break; }
|
||||
}
|
||||
},
|
||||
each: function(arr, fn){ _V_.each.call(this, arr, fn); },
|
||||
|
||||
extend: function(obj){
|
||||
for (var attrname in obj) {
|
||||
if (obj.hasOwnProperty(attrname)) { this[attrname]=obj[attrname]; }
|
||||
}
|
||||
},
|
||||
eachProp: function(obj, fn){ _V_.eachProp.call(this, obj, fn); },
|
||||
|
||||
extend: function(obj){ _V_.merge(this, obj) },
|
||||
|
||||
// More easily attach 'this' to functions
|
||||
proxy: function(fn){
|
||||
return _V_.proxy(this, fn);
|
||||
}
|
||||
proxy: function(fn){ return _V_.proxy(this, fn); }
|
||||
|
||||
});
|
||||
externo
+73
-30
@@ -140,7 +140,7 @@ _V_.FullscreenToggle = _V_.Button.extend({
|
||||
},
|
||||
|
||||
onClick: function(){
|
||||
if (!this.player.videoIsFullScreen) {
|
||||
if (!this.player.isFullScreen) {
|
||||
this.player.requestFullScreen();
|
||||
} else {
|
||||
this.player.cancelFullScreen();
|
||||
@@ -188,7 +188,11 @@ _V_.LoadingSpinner = _V_.Component.extend({
|
||||
|
||||
player.addEvent("seeking", _V_.proxy(this, this.show));
|
||||
player.addEvent("error", _V_.proxy(this, this.show));
|
||||
player.addEvent("stalled", _V_.proxy(this, this.show));
|
||||
|
||||
// Not showing spinner on stalled any more. Browsers may stall and then not trigger any events that would remove the spinner.
|
||||
// Checked in Chrome 16 and Safari 5.1.2. http://help.videojs.com/discussions/problems/883-why-is-the-download-progress-showing
|
||||
// player.addEvent("stalled", _V_.proxy(this, this.show));
|
||||
|
||||
player.addEvent("waiting", _V_.proxy(this, this.show));
|
||||
},
|
||||
|
||||
@@ -218,13 +222,30 @@ _V_.LoadingSpinner = _V_.Component.extend({
|
||||
/* Control Bar
|
||||
================================================================================ */
|
||||
_V_.ControlBar = _V_.Component.extend({
|
||||
|
||||
options: {
|
||||
loadEvent: "play",
|
||||
components: {
|
||||
"playToggle": {},
|
||||
"fullscreenToggle": {},
|
||||
"currentTimeDisplay": {},
|
||||
"timeDivider": {},
|
||||
"durationDisplay": {},
|
||||
"remainingTimeDisplay": {},
|
||||
"progressControl": {},
|
||||
"volumeControl": {},
|
||||
"muteToggle": {}
|
||||
}
|
||||
},
|
||||
|
||||
init: function(player, options){
|
||||
this._super(player, options);
|
||||
|
||||
player.addEvent("play", this.proxy(this.show));
|
||||
|
||||
player.addEvent("mouseover", this.proxy(this.reveal));
|
||||
player.addEvent("mouseout", this.proxy(this.conceal));
|
||||
player.addEvent("play", this.proxy(function(){
|
||||
this.fadeIn();
|
||||
this.player.addEvent("mouseover", this.proxy(this.fadeIn));
|
||||
this.player.addEvent("mouseout", this.proxy(this.fadeOut));
|
||||
}));
|
||||
},
|
||||
|
||||
createElement: function(){
|
||||
@@ -233,13 +254,14 @@ _V_.ControlBar = _V_.Component.extend({
|
||||
});
|
||||
},
|
||||
|
||||
// Used for transitions (fading out)
|
||||
reveal: function(){
|
||||
this.el.style.opacity = 1;
|
||||
fadeIn: function(){
|
||||
this._super();
|
||||
this.player.triggerEvent("controlsvisible");
|
||||
},
|
||||
|
||||
conceal: function(){
|
||||
this.el.style.opacity = 0;
|
||||
fadeOut: function(){
|
||||
this._super();
|
||||
this.player.triggerEvent("controlshidden");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -354,24 +376,18 @@ _V_.Slider = _V_.Component.extend({
|
||||
init: function(player, options){
|
||||
this._super(player, options);
|
||||
|
||||
_V_.each.call(this, this.components, function(comp){
|
||||
if (comp instanceof _V_[this.barClass]) {
|
||||
this.bar = comp;
|
||||
} else if (comp instanceof _V_[this.handleClass]) {
|
||||
this.handle = comp;
|
||||
}
|
||||
});
|
||||
|
||||
player.addEvent(this.playerEvent, _V_.proxy(this, this.update));
|
||||
|
||||
this.addEvent("mousedown", this.onMouseDown);
|
||||
this.addEvent("focus", this.onFocus);
|
||||
this.addEvent("blur", this.onBlur);
|
||||
|
||||
// Update Display
|
||||
// Need to wait for styles to be loaded.
|
||||
// TODO - replace setTimeout with stylesReady function.
|
||||
setTimeout(this.proxy(this.update), 0);
|
||||
this.player.addEvent("controlsvisible", this.proxy(this.update));
|
||||
|
||||
// This is actually to fix the volume handle position. http://twitter.com/#!/gerritvanaaken/status/159046254519787520
|
||||
// this.player.one("timeupdate", this.proxy(this.update));
|
||||
|
||||
this.update();
|
||||
},
|
||||
|
||||
createElement: function(type, attrs) {
|
||||
@@ -422,12 +438,15 @@ _V_.Slider = _V_.Component.extend({
|
||||
// If there is a handle, we need to account for the handle in our calculation for progress bar
|
||||
// so that it doesn't fall short of or extend past the handle.
|
||||
if (handle) {
|
||||
|
||||
var box = this.el,
|
||||
boxWidth = box.offsetWidth,
|
||||
|
||||
handleWidth = handle.el.offsetWidth,
|
||||
|
||||
// The width of the handle in percent of the containing box
|
||||
// In IE, widths may not be ready yet causing NaN
|
||||
handlePercent = (handle.el.offsetWidth) ? handle.el.offsetWidth / boxWidth : 0,
|
||||
handlePercent = (handleWidth) ? handleWidth / boxWidth : 0,
|
||||
|
||||
// Get the adjusted size of the box, considering that the handle's center never touches the left or right side.
|
||||
// There is a margin of half the handle's width on both sides.
|
||||
@@ -491,6 +510,12 @@ _V_.Slider = _V_.Component.extend({
|
||||
// Progress Control: Seek, Load Progress, and Play Progress
|
||||
_V_.ProgressControl = _V_.Component.extend({
|
||||
|
||||
options: {
|
||||
components: {
|
||||
"seekBar": {}
|
||||
}
|
||||
},
|
||||
|
||||
createElement: function(){
|
||||
return this._super("div", {
|
||||
className: "vjs-progress-control vjs-control"
|
||||
@@ -502,8 +527,16 @@ _V_.ProgressControl = _V_.Component.extend({
|
||||
// Seek Bar and holder for the progress bars
|
||||
_V_.SeekBar = _V_.Slider.extend({
|
||||
|
||||
barClass: "PlayProgressBar",
|
||||
handleClass: "SeekHandle",
|
||||
options: {
|
||||
components: {
|
||||
"loadProgressBar": {},
|
||||
|
||||
// Set property names to bar and handle to match with the parent Slider class is looking for
|
||||
"bar": { componentClass: "PlayProgressBar" },
|
||||
"handle": { componentClass: "SeekHandle" }
|
||||
}
|
||||
},
|
||||
|
||||
playerEvent: "timeupdate",
|
||||
|
||||
init: function(player, options){
|
||||
@@ -610,6 +643,12 @@ _V_.SeekHandle = _V_.Component.extend({
|
||||
// Progress Control: Seek, Load Progress, and Play Progress
|
||||
_V_.VolumeControl = _V_.Component.extend({
|
||||
|
||||
options: {
|
||||
components: {
|
||||
"volumeBar": {}
|
||||
}
|
||||
},
|
||||
|
||||
createElement: function(){
|
||||
return this._super("div", {
|
||||
className: "vjs-volume-control vjs-control"
|
||||
@@ -620,8 +659,13 @@ _V_.VolumeControl = _V_.Component.extend({
|
||||
|
||||
_V_.VolumeBar = _V_.Slider.extend({
|
||||
|
||||
barClass: "VolumeLevel",
|
||||
handleClass: "VolumeHandle",
|
||||
options: {
|
||||
components: {
|
||||
"bar": { componentClass: "VolumeLevel" },
|
||||
"handle": { componentClass: "VolumeHandle" }
|
||||
}
|
||||
},
|
||||
|
||||
playerEvent: "volumechange",
|
||||
|
||||
createElement: function(){
|
||||
@@ -726,8 +770,7 @@ _V_.Poster = _V_.Button.extend({
|
||||
},
|
||||
|
||||
createElement: function(){
|
||||
_V_.log(this.player.options.poster)
|
||||
return this._super("img", {
|
||||
return _V_.createElement("img", {
|
||||
className: "vjs-poster",
|
||||
src: this.player.options.poster,
|
||||
|
||||
|
||||
+56
-48
@@ -38,7 +38,10 @@ var VideoJS = function(id, addOptions, ready){
|
||||
},
|
||||
|
||||
// Shortcut
|
||||
_V_ = VideoJS;
|
||||
_V_ = VideoJS,
|
||||
|
||||
// CDN Version. Used to target right flash swf.
|
||||
CDN_VERSION = "GENERATED_CDN_VSN";
|
||||
|
||||
VideoJS.players = {};
|
||||
|
||||
@@ -49,15 +52,7 @@ VideoJS.options = {
|
||||
// techOrder: ["flash","html5"],
|
||||
|
||||
html5: {},
|
||||
flash: {
|
||||
swf: "http://vjs.zencdn.net/c/video-js.swf"
|
||||
// swf: "https://s3.amazonaws.com/video-js/3.0b/video-js.swf"
|
||||
// swf: "http://video-js.zencoder.com/3.0b/video-js.swf"
|
||||
// swf: "http://video-js.com/test/video-js.swf"
|
||||
// swf: "http://video-js.com/source/flash/video-js.swf"
|
||||
// swf: "http://video-js.com/source/flash/video-js.swf"
|
||||
// swf: "video-js.swf"
|
||||
},
|
||||
flash: { swf: "http://vjs.zencdn.net/c/video-js.swf" },
|
||||
|
||||
// Default of web browser is 300x150. Should rely on source width/height.
|
||||
width: "auto",
|
||||
@@ -67,46 +62,59 @@ VideoJS.options = {
|
||||
defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
|
||||
|
||||
// Included control sets
|
||||
components: [
|
||||
"poster",
|
||||
"loadingSpinner",
|
||||
"bigPlayButton",
|
||||
{ name: "controlBar", options: {
|
||||
components: [
|
||||
"playToggle",
|
||||
"fullscreenToggle",
|
||||
"currentTimeDisplay",
|
||||
"timeDivider",
|
||||
"durationDisplay",
|
||||
"remainingTimeDisplay",
|
||||
{ name: "progressControl", options: {
|
||||
components: [
|
||||
{ name: "seekBar", options: {
|
||||
components: [
|
||||
"loadProgressBar",
|
||||
"playProgressBar",
|
||||
"seekHandle"
|
||||
]}
|
||||
}
|
||||
]}
|
||||
},
|
||||
{ name: "volumeControl", options: {
|
||||
components: [
|
||||
{ name: "volumeBar", options: {
|
||||
components: [
|
||||
"volumeLevel",
|
||||
"volumeHandle"
|
||||
]}
|
||||
}
|
||||
]}
|
||||
},
|
||||
"muteToggle"
|
||||
]
|
||||
}},
|
||||
"subtitlesDisplay"/*, "replay"*/
|
||||
]
|
||||
components: {
|
||||
"poster": {},
|
||||
"loadingSpinner": {},
|
||||
"bigPlayButton": {},
|
||||
"controlBar": {},
|
||||
"subtitlesDisplay": {}
|
||||
}
|
||||
|
||||
// components: [
|
||||
// "poster",
|
||||
// "loadingSpinner",
|
||||
// "bigPlayButton",
|
||||
// { name: "controlBar", options: {
|
||||
// components: [
|
||||
// "playToggle",
|
||||
// "fullscreenToggle",
|
||||
// "currentTimeDisplay",
|
||||
// "timeDivider",
|
||||
// "durationDisplay",
|
||||
// "remainingTimeDisplay",
|
||||
// { name: "progressControl", options: {
|
||||
// components: [
|
||||
// { name: "seekBar", options: {
|
||||
// components: [
|
||||
// "loadProgressBar",
|
||||
// "playProgressBar",
|
||||
// "seekHandle"
|
||||
// ]}
|
||||
// }
|
||||
// ]}
|
||||
// },
|
||||
// { name: "volumeControl", options: {
|
||||
// components: [
|
||||
// { name: "volumeBar", options: {
|
||||
// components: [
|
||||
// "volumeLevel",
|
||||
// "volumeHandle"
|
||||
// ]}
|
||||
// }
|
||||
// ]}
|
||||
// },
|
||||
// "muteToggle"
|
||||
// ]
|
||||
// }},
|
||||
// "subtitlesDisplay"/*, "replay"*/
|
||||
// ]
|
||||
};
|
||||
|
||||
// Set CDN Version of swf
|
||||
if (CDN_VERSION != "GENERATED_CDN_VSN") {
|
||||
_V_.options.flash.swf = "http://vjs.zencdn.net/"+CDN_VERSION+"/video-js.swf"
|
||||
}
|
||||
|
||||
// Automatically set up any tags that have a data-setup attribute
|
||||
_V_.autoSetup = function(){
|
||||
var options, vid, player,
|
||||
|
||||
+8
-1
@@ -226,6 +226,13 @@ _V_.extend({
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
},
|
||||
|
||||
one: function(elem, type, fn) {
|
||||
_V_.addEvent(elem, type, function(){
|
||||
_V_.removeEvent(elem, type, arguments.callee)
|
||||
fn.apply(this, arguments);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -288,7 +295,7 @@ _V_.Event.prototype = {
|
||||
isPropagationStopped: returnFalse,
|
||||
isImmediatePropagationStopped: returnFalse
|
||||
};
|
||||
_V_.Event.props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" ");
|
||||
_V_.Event.props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" ");
|
||||
|
||||
function returnTrue(){ return true; }
|
||||
function returnFalse(){ return false; }
|
||||
|
||||
@@ -15,6 +15,7 @@ _V_.extend({
|
||||
|
||||
// Device Checks
|
||||
isIE: function(){ return !+"\v1"; },
|
||||
isFF: function(){ return !!_V_.ua.match("Firefox") },
|
||||
isIPad: function(){ return navigator.userAgent.match(/iPad/i) !== null; },
|
||||
isIPhone: function(){ return navigator.userAgent.match(/iPhone/i) !== null; },
|
||||
isIOS: function(){ return VideoJS.isIPhone() || VideoJS.isIPad(); },
|
||||
@@ -39,6 +40,15 @@ _V_.extend({
|
||||
}
|
||||
},
|
||||
|
||||
eachProp: function(obj, fn){
|
||||
if (!obj) { return; }
|
||||
for (var name in obj) {
|
||||
if (obj.hasOwnProperty(name)) {
|
||||
fn.call(this, name, obj[name]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
el: function(id){ return document.getElementById(id); },
|
||||
createElement: function(tagName, attributes){
|
||||
var el = document.createElement(tagName),
|
||||
|
||||
+70
-52
@@ -8,8 +8,8 @@ _V_.Player = _V_.Component.extend({
|
||||
|
||||
var el = this.el = _V_.createElement("div"), // Div to contain video and controls
|
||||
options = this.options = {},
|
||||
width = options.width = tag.width,
|
||||
height = options.height = tag.height,
|
||||
width = options.width = tag.getAttribute('width'),
|
||||
height = options.height = tag.getAttribute('height'),
|
||||
|
||||
// Browsers default to 300x150 if there's no width/height or video size data.
|
||||
initWidth = width || 300,
|
||||
@@ -81,9 +81,7 @@ _V_.Player = _V_.Component.extend({
|
||||
// When the API is ready, loop through the components and add to the player.
|
||||
if (options.controls) {
|
||||
this.ready(function(){
|
||||
this.each(this.options.components, function(set){
|
||||
this.addComponent(set);
|
||||
});
|
||||
this.initComponents();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -127,34 +125,36 @@ _V_.Player = _V_.Component.extend({
|
||||
tracks: []
|
||||
};
|
||||
|
||||
options.src = this.tag.src;
|
||||
options.src = this.tag.getAttribute("src");
|
||||
options.controls = this.tag.getAttribute("controls") !== null;
|
||||
options.poster = this.tag.poster;
|
||||
options.preload = this.tag.preload;
|
||||
options.poster = this.tag.getAttribute("poster");
|
||||
options.preload = this.tag.getAttribute("preload");
|
||||
options.autoplay = this.tag.getAttribute("autoplay") !== null; // hasAttribute not IE <8 compatible
|
||||
options.loop = this.tag.getAttribute("loop") !== null;
|
||||
options.muted = this.tag.getAttribute("muted") !== null;
|
||||
|
||||
for (var c,i=0,j=this.tag.children;i<j.length;i++) {
|
||||
c = j[i];
|
||||
if (c.nodeName == "SOURCE") {
|
||||
options.sources.push({
|
||||
src: c.src,
|
||||
type: c.type,
|
||||
media: c.media,
|
||||
title: c.title
|
||||
});
|
||||
}
|
||||
if (c.nodeName == "TRACK") {
|
||||
options.tracks.push(new _V_.Track({
|
||||
src: c.getAttribute("src"),
|
||||
kind: c.getAttribute("kind"),
|
||||
srclang: c.getAttribute("srclang"),
|
||||
label: c.getAttribute("label"),
|
||||
'default': c.getAttribute("default") !== null,
|
||||
title: c.getAttribute("title")
|
||||
}, this));
|
||||
|
||||
if (this.tag.hasChildNodes()) {
|
||||
for (var c,i=0,j=this.tag.childNodes;i<j.length;i++) {
|
||||
c = j[i];
|
||||
if (c.nodeName == "SOURCE") {
|
||||
options.sources.push({
|
||||
src: c.getAttribute('src'),
|
||||
type: c.getAttribute('type'),
|
||||
media: c.getAttribute('media'),
|
||||
title: c.getAttribute('title')
|
||||
});
|
||||
}
|
||||
if (c.nodeName == "TRACK") {
|
||||
options.tracks.push(new _V_.Track({
|
||||
src: c.getAttribute("src"),
|
||||
kind: c.getAttribute("kind"),
|
||||
srclang: c.getAttribute("srclang"),
|
||||
label: c.getAttribute("label"),
|
||||
'default': c.getAttribute("default") !== null,
|
||||
title: c.getAttribute("title")
|
||||
}, this));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
@@ -227,15 +227,15 @@ _V_.Player = _V_.Component.extend({
|
||||
// First is a plugin reload issue in Firefox that has been around for 11 years: https://bugzilla.mozilla.org/show_bug.cgi?id=90268
|
||||
// Then with the new fullscreen API, Mozilla and webkit browsers will reload the flash object after going to fullscreen.
|
||||
// To get around this, we're unloading the tech, caching source and currentTime values, and reloading the tech once the plugin is resized.
|
||||
reloadTech: function(betweenFn){
|
||||
_V_.log("unloadingTech")
|
||||
this.unloadTech();
|
||||
_V_.log("unloadedTech")
|
||||
if (betweenFn) { betweenFn.call(); }
|
||||
_V_.log("LoadingTech")
|
||||
this.loadTech(this.techName, { src: this.values.src })
|
||||
_V_.log("loadedTech")
|
||||
},
|
||||
// reloadTech: function(betweenFn){
|
||||
// _V_.log("unloadingTech")
|
||||
// this.unloadTech();
|
||||
// _V_.log("unloadedTech")
|
||||
// if (betweenFn) { betweenFn.call(); }
|
||||
// _V_.log("LoadingTech")
|
||||
// this.loadTech(this.techName, { src: this.values.src })
|
||||
// _V_.log("loadedTech")
|
||||
// },
|
||||
|
||||
/* Fallbacks for unsupported event types
|
||||
================================================================================ */
|
||||
@@ -463,19 +463,18 @@ _V_.Player = _V_.Component.extend({
|
||||
requestFullScreen: function(){
|
||||
var requestFullScreen = _V_.support.requestFullScreen;
|
||||
|
||||
this.isFullScreen = true;
|
||||
|
||||
// Check for browser element fullscreen support
|
||||
if (requestFullScreen) {
|
||||
|
||||
// Flash and other plugins get reloaded when you take their parent to fullscreen.
|
||||
// To fix that we'll remove the tech, and reload it after the resize has finished.
|
||||
if (this.tech.support.fullscreenResize === false) {
|
||||
if (this.tech.support.fullscreenResize === false && this.options.flash.iFrameMode != true) {
|
||||
|
||||
this.pause();
|
||||
this.unloadTech();
|
||||
|
||||
_V_.addEvent(document, "keydown", _V_.proxy(this, function(e){
|
||||
_V_.log("asdf", e)
|
||||
}));
|
||||
|
||||
_V_.addEvent(document, requestFullScreen.eventName, this.proxy(function(){
|
||||
_V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
|
||||
this.loadTech(this.techName, { src: this.values.src });
|
||||
@@ -487,6 +486,11 @@ _V_.Player = _V_.Component.extend({
|
||||
this.el[requestFullScreen.requestFn]();
|
||||
}
|
||||
|
||||
// In case the user presses escape to exit fullscreen, we need to update fullscreen status
|
||||
_V_.addEvent(document, requestFullScreen.eventName, this.proxy(function(){
|
||||
this.isFullScreen = document[requestFullScreen.isFullScreen];
|
||||
}));
|
||||
|
||||
} else if (this.tech.supportsFullScreen()) {
|
||||
this.apiCall("enterFullScreen");
|
||||
|
||||
@@ -494,7 +498,6 @@ _V_.Player = _V_.Component.extend({
|
||||
this.enterFullWindow();
|
||||
}
|
||||
|
||||
this.videoIsFullScreen = true;
|
||||
this.triggerEvent("fullscreenchange");
|
||||
|
||||
return this;
|
||||
@@ -508,14 +511,13 @@ _V_.Player = _V_.Component.extend({
|
||||
|
||||
// Flash and other plugins get reloaded when you take their parent to fullscreen.
|
||||
// To fix that we'll remove the tech, and reload it after the resize has finished.
|
||||
if (this.tech.support.fullscreenResize === false) {
|
||||
if (this.tech.support.fullscreenResize === false && this.options.flash.iFrameMode != true) {
|
||||
|
||||
this.pause();
|
||||
this.unloadTech();
|
||||
|
||||
_V_.addEvent(document, requestFullScreen.eventName, this.proxy(function(){
|
||||
_V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
|
||||
_V_.log("document fullscreeneventchange")
|
||||
this.loadTech(this.techName, { src: this.values.src })
|
||||
}));
|
||||
|
||||
@@ -532,14 +534,14 @@ _V_.Player = _V_.Component.extend({
|
||||
this.exitFullWindow();
|
||||
}
|
||||
|
||||
this.videoIsFullScreen = false;
|
||||
this.isFullScreen = false;
|
||||
this.triggerEvent("fullscreenchange");
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
enterFullWindow: function(){
|
||||
this.videoIsFullScreen = true;
|
||||
this.isFullWindow = true;
|
||||
|
||||
// Storing original doc overflow value to return to when fullscreen is off
|
||||
this.docOrigOverflow = document.documentElement.style.overflow;
|
||||
@@ -559,12 +561,16 @@ _V_.Player = _V_.Component.extend({
|
||||
|
||||
fullWindowOnEscKey: function(event){
|
||||
if (event.keyCode == 27) {
|
||||
this.cancelFullScreen();
|
||||
if (this.isFullScreen == true) {
|
||||
this.cancelFullScreen();
|
||||
} else {
|
||||
this.exitFullWindow();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
exitFullWindow: function(){
|
||||
this.videoIsFullScreen = false;
|
||||
this.isFullWindow = false;
|
||||
_V_.removeEvent(document, "keydown", this.fullWindowOnEscKey);
|
||||
|
||||
// Unhide scroll bars.
|
||||
@@ -608,7 +614,7 @@ _V_.Player = _V_.Component.extend({
|
||||
if (tech.canPlaySource.call(this, source)) {
|
||||
|
||||
// If this technology is already loaded, set source
|
||||
if (techName == this.currentTechName) {
|
||||
if (techName == this.techName) {
|
||||
this.src(source); // Passing the source object
|
||||
|
||||
// Otherwise load this technology with chosen source
|
||||
@@ -725,6 +731,8 @@ _V_.Player = _V_.Component.extend({
|
||||
(function(){
|
||||
var requestFn,
|
||||
cancelFn,
|
||||
eventName,
|
||||
isFullScreen,
|
||||
playerProto = _V_.Player.prototype;
|
||||
|
||||
// Current W3C Spec
|
||||
@@ -734,6 +742,7 @@ _V_.Player = _V_.Component.extend({
|
||||
requestFn = "requestFullscreen";
|
||||
cancelFn = "exitFullscreen";
|
||||
eventName = "fullscreenchange";
|
||||
isFullScreen = "fullScreen";
|
||||
|
||||
// Webkit (Chrome/Safari) and Mozilla (Firefox) have working implementaitons
|
||||
// that use prefixes and vary slightly from the new W3C spec. Specifically, using 'exit' instead of 'cancel',
|
||||
@@ -743,10 +752,18 @@ _V_.Player = _V_.Component.extend({
|
||||
|
||||
_V_.each(["moz", "webkit"], function(prefix){
|
||||
|
||||
if (document[prefix + "CancelFullScreen"] !== undefined) {
|
||||
// https://github.com/zencoder/video-js/pull/128
|
||||
if ((prefix != "moz" || document.mozFullScreenEnabled) && document[prefix + "CancelFullScreen"] !== undefined) {
|
||||
requestFn = prefix + "RequestFullScreen";
|
||||
cancelFn = prefix + "CancelFullScreen";
|
||||
eventName = prefix + "fullscreenchange";
|
||||
|
||||
if (prefix == "webkit") {
|
||||
isFullScreen = prefix + "IsFullScreen";
|
||||
} else {
|
||||
_V_.log("moz here")
|
||||
isFullScreen = prefix + "FullScreen";
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -757,7 +774,8 @@ _V_.Player = _V_.Component.extend({
|
||||
_V_.support.requestFullScreen = {
|
||||
requestFn: requestFn,
|
||||
cancelFn: cancelFn,
|
||||
eventName: eventName
|
||||
eventName: eventName,
|
||||
isFullScreen: isFullScreen
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
_V_.addEvent(window, "load", function(){
|
||||
_V_.windowLoaded = true;
|
||||
});
|
||||
_V_.autoSetupTimeout();
|
||||
|
||||
// Run Auto-load players
|
||||
_V_.autoSetup();
|
||||
+292
-56
@@ -66,7 +66,7 @@ _V_.html5 = _V_.PlaybackTech.extend({
|
||||
|
||||
this.triggerReady();
|
||||
},
|
||||
|
||||
|
||||
destroy: function(){
|
||||
this.player.tag = false;
|
||||
this.removeTriggers();
|
||||
@@ -87,7 +87,7 @@ _V_.html5 = _V_.PlaybackTech.extend({
|
||||
if (!el || this.support.movingElementInDOM === false) {
|
||||
|
||||
// If the original tag is still there, remove it.
|
||||
if (el) {
|
||||
if (el) {
|
||||
player.el.removeChild(el);
|
||||
}
|
||||
|
||||
@@ -183,23 +183,23 @@ _V_.html5 = _V_.PlaybackTech.extend({
|
||||
setLoop: function(val){ this.el.loop = val; },
|
||||
|
||||
error: function(){ return this.el.error; },
|
||||
networkState: function(){ return this.el.networkState; },
|
||||
readyState: function(){ return this.el.readyState; },
|
||||
// networkState: function(){ return this.el.networkState; },
|
||||
// readyState: function(){ return this.el.readyState; },
|
||||
seeking: function(){ return this.el.seeking; },
|
||||
initialTime: function(){ return this.el.initialTime; },
|
||||
startOffsetTime: function(){ return this.el.startOffsetTime; },
|
||||
played: function(){ return this.el.played; },
|
||||
seekable: function(){ return this.el.seekable; },
|
||||
// initialTime: function(){ return this.el.initialTime; },
|
||||
// startOffsetTime: function(){ return this.el.startOffsetTime; },
|
||||
// played: function(){ return this.el.played; },
|
||||
// seekable: function(){ return this.el.seekable; },
|
||||
ended: function(){ return this.el.ended; },
|
||||
videoTracks: function(){ return this.el.videoTracks; },
|
||||
audioTracks: function(){ return this.el.audioTracks; },
|
||||
videoWidth: function(){ return this.el.videoWidth; },
|
||||
videoHeight: function(){ return this.el.videoHeight; },
|
||||
textTracks: function(){ return this.el.textTracks; },
|
||||
defaultPlaybackRate: function(){ return this.el.defaultPlaybackRate; },
|
||||
playbackRate: function(){ return this.el.playbackRate; },
|
||||
mediaGroup: function(){ return this.el.mediaGroup; },
|
||||
controller: function(){ return this.el.controller; },
|
||||
// videoTracks: function(){ return this.el.videoTracks; },
|
||||
// audioTracks: function(){ return this.el.audioTracks; },
|
||||
// videoWidth: function(){ return this.el.videoWidth; },
|
||||
// videoHeight: function(){ return this.el.videoHeight; },
|
||||
// textTracks: function(){ return this.el.textTracks; },
|
||||
// defaultPlaybackRate: function(){ return this.el.defaultPlaybackRate; },
|
||||
// playbackRate: function(){ return this.el.playbackRate; },
|
||||
// mediaGroup: function(){ return this.el.mediaGroup; },
|
||||
// controller: function(){ return this.el.controller; },
|
||||
controls: function(){ return this.player.options.controls; },
|
||||
defaultMuted: function(){ return this.el.defaultMuted; }
|
||||
});
|
||||
@@ -223,7 +223,7 @@ _V_.html5.events = "loadstart,suspend,abort,error,emptied,stalled,loadedmetadata
|
||||
/* HTML5 Device Fixes ---------------------------------------------------------- */
|
||||
|
||||
_V_.html5.prototype.support = {
|
||||
|
||||
|
||||
// Support for tech specific full screen. (webkitEnterFullScreen, not requestFullscreen)
|
||||
// http://developer.apple.com/library/safari/#documentation/AudioVideo/Reference/HTMLVideoElementClassReference/HTMLVideoElement/HTMLVideoElement.html
|
||||
// Seems to be broken in Chromium/Chrome && Safari in Leopard
|
||||
@@ -246,7 +246,7 @@ if (_V_.isAndroid()) {
|
||||
}
|
||||
|
||||
|
||||
/* VideoJS-SWF - Custom Flash Player with HTML5-ish API
|
||||
/* VideoJS-SWF - Custom Flash Player with HTML5-ish API - https://github.com/zencoder/video-js-swf
|
||||
================================================================================ */
|
||||
_V_.flash = _V_.PlaybackTech.extend({
|
||||
|
||||
@@ -254,17 +254,26 @@ _V_.flash = _V_.PlaybackTech.extend({
|
||||
this.player = player;
|
||||
|
||||
var source = options.source,
|
||||
parentEl = options.parentEl,
|
||||
placeHolder = this.el = _V_.createElement("div", { id: parentEl.id + "_temp_flash" }),
|
||||
objId = player.el.id+"_flash_api",
|
||||
playerOptions = player.options;
|
||||
|
||||
// Which element to embed in
|
||||
parentEl = options.parentEl,
|
||||
|
||||
// Create a temporary element to be replaced by swf object
|
||||
placeHolder = this.el = _V_.createElement("div", { id: parentEl.id + "_temp_flash" }),
|
||||
|
||||
// Generate ID for swf object
|
||||
objId = player.el.id+"_flash_api",
|
||||
|
||||
// Store player options in local var for optimization
|
||||
playerOptions = player.options,
|
||||
|
||||
// Merge default flashvars with ones passed in to init
|
||||
flashVars = _V_.merge({
|
||||
|
||||
// SWF Callback Functions
|
||||
readyFunction: "_V_.flash.onSWFReady",
|
||||
eventProxyFunction: "_V_.flash.onSWFEvent",
|
||||
errorEventProxyFunction: "_V_.flash.onSWFErrorEvent",
|
||||
readyFunction: "_V_.flash.onReady",
|
||||
eventProxyFunction: "_V_.flash.onEvent",
|
||||
errorEventProxyFunction: "_V_.flash.onError",
|
||||
|
||||
// Player Settings
|
||||
autoplay: playerOptions.autoplay,
|
||||
@@ -274,32 +283,30 @@ _V_.flash = _V_.PlaybackTech.extend({
|
||||
|
||||
}, options.flashVars),
|
||||
|
||||
// Merge default parames with ones passed in
|
||||
params = _V_.merge({
|
||||
allowScriptAccess: "always",
|
||||
wmode: "opaque",
|
||||
bgcolor: "#000000"
|
||||
wmode: "opaque", // Opaque is needed to overlay controls, but can affect playback performance
|
||||
bgcolor: "#000000" // Using bgcolor prevents a white flash when the object is loading
|
||||
}, options.params),
|
||||
|
||||
// Merge default attributes with ones passed in
|
||||
attributes = _V_.merge({
|
||||
id: objId,
|
||||
name: objId,
|
||||
name: objId, // Both ID and Name needed or swf to identifty itself
|
||||
'class': 'vjs-tech'
|
||||
}, options.attributes);
|
||||
|
||||
|
||||
// EDIT: Trying to just us a manual <img> for poster.
|
||||
// if (playerOptions.poster) {
|
||||
// flashVars.poster = playerOptions.poster;
|
||||
// }
|
||||
}, options.attributes)
|
||||
;
|
||||
|
||||
// If source was supplied pass as a flash var.
|
||||
if (source) {
|
||||
flashVars.src = source.src;
|
||||
flashVars.src = encodeURIComponent(source.src);
|
||||
}
|
||||
|
||||
// Add to box.
|
||||
// Add placeholder to player div
|
||||
_V_.insertFirst(placeHolder, parentEl);
|
||||
|
||||
// Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
|
||||
// This allows resetting the playhead when we catch the reload
|
||||
if (options.startTime) {
|
||||
this.ready(function(){
|
||||
this.load();
|
||||
@@ -308,14 +315,146 @@ _V_.flash = _V_.PlaybackTech.extend({
|
||||
});
|
||||
}
|
||||
|
||||
swfobject.embedSWF(options.swf, placeHolder.id, "480", "270", "9.0.124", "", flashVars, params, attributes);
|
||||
// Flash iFrame Mode
|
||||
// In web browsers there are multiple instances where changing the parent element or visibility of a plugin causes the plugin to reload.
|
||||
// - Firefox just about always. https://bugzilla.mozilla.org/show_bug.cgi?id=90268 (might be fixed by version 13)
|
||||
// - Webkit when hiding the plugin
|
||||
// - Webkit and Firefox when using requestFullScreen on a parent element
|
||||
// Loading the flash plugin into a dynamically generated iFrame gets around most of these issues.
|
||||
// Issues that remain include hiding the element and requestFullScreen in Firefox specifically
|
||||
|
||||
// There's on particularly annoying issue with this method which is that Firefox throws a security error on an offsite Flash object loaded into a dynamically created iFrame.
|
||||
// Even though the iframe was inserted into a page on the web, Firefox + Flash considers it a local app trying to access an internet file.
|
||||
// I tried mulitple ways of setting the iframe src attribute but couldn't find a src that worked well. Tried a real/fake source, in/out of domain.
|
||||
// Also tried a method from stackoverflow that caused a security error in all browsers. http://stackoverflow.com/questions/2486901/how-to-set-document-domain-for-a-dynamically-generated-iframe
|
||||
// In the end the solution I found to work was setting the iframe window.location.href right before doing a document.write of the Flash object.
|
||||
// The only downside of this it seems to trigger another http request to the original page (no matter what's put in the href). Not sure why that is.
|
||||
|
||||
// NOTE (2012-01-29): Cannot get Firefox to load the remote hosted SWF into a dynamically created iFrame
|
||||
// Firefox 9 throws a security error, unleess you call location.href right before doc.write.
|
||||
// Not sure why that even works, but it causes the browser to look like it's continuously trying to load the page.
|
||||
// Firefox 3.6 keeps calling the iframe onload function anytime I write to it, causing an endless loop.
|
||||
|
||||
if (options.iFrameMode == true && !_V_.isFF) {
|
||||
|
||||
// Create iFrame with vjs-tech class so it's 100% width/height
|
||||
var iFrm = _V_.createElement("iframe", {
|
||||
id: objId + "_iframe",
|
||||
name: objId + "_iframe",
|
||||
className: "vjs-tech",
|
||||
scrolling: "no",
|
||||
marginWidth: 0,
|
||||
marginHeight: 0,
|
||||
frameBorder: 0
|
||||
});
|
||||
|
||||
// Update ready function names in flash vars for iframe window
|
||||
flashVars.readyFunction = "ready";
|
||||
flashVars.eventProxyFunction = "events";
|
||||
flashVars.errorEventProxyFunction = "errors";
|
||||
|
||||
// Tried multiple methods to get this to work in all browsers
|
||||
|
||||
// Tried embedding the flash object in the page first, and then adding a place holder to the iframe, then replacing the placeholder with the page object.
|
||||
// The goal here was to try to load the swf URL in the parent page first and hope that got around the firefox security error
|
||||
// var newObj = _V_.flash.embed(options.swf, placeHolder, flashVars, params, attributes);
|
||||
// (in onload)
|
||||
// var temp = _V_.createElement("a", { id:"asdf", innerHTML: "asdf" } );
|
||||
// iDoc.body.appendChild(temp);
|
||||
|
||||
// Tried embedding the flash object through javascript in the iframe source.
|
||||
// This works in webkit but still triggers the firefox security error
|
||||
// iFrm.src = "javascript: document.write('"+_V_.flash.getEmbedCode(options.swf, flashVars, params, attributes)+"');";
|
||||
|
||||
// Tried an actual local iframe just to make sure that works, but it kills the easiness of the CDN version if you require the user to host an iframe
|
||||
// We should add an option to host the iframe locally though, because it could help a lot of issues.
|
||||
// iFrm.src = "iframe.html";
|
||||
|
||||
// Wait until iFrame has loaded to write into it.
|
||||
_V_.addEvent(iFrm, "load", _V_.proxy(this, function(){
|
||||
|
||||
var iDoc, objTag, swfLoc,
|
||||
iWin = iFrm.contentWindow,
|
||||
varString = "";
|
||||
|
||||
|
||||
// The one working method I found was to use the iframe's document.write() to create the swf object
|
||||
// This got around the security issue in all browsers except firefox.
|
||||
// I did find a hack where if I call the iframe's window.location.href="", it would get around the security error
|
||||
// However, the main page would look like it was loading indefinitely (URL bar loading spinner would never stop)
|
||||
// Plus Firefox 3.6 didn't work no matter what I tried.
|
||||
// if (_V_.ua.match("Firefox")) {
|
||||
// iWin.location.href = "";
|
||||
// }
|
||||
|
||||
// Get the iFrame's document depending on what the browser supports
|
||||
iDoc = iFrm.contentDocument ? iFrm.contentDocument : iFrm.contentWindow.document;
|
||||
|
||||
// Tried ensuring both document domains were the same, but they already were, so that wasn't the issue.
|
||||
// Even tried adding /. that was mentioned in a browser security writeup
|
||||
// document.domain = document.domain+"/.";
|
||||
// iDoc.domain = document.domain+"/.";
|
||||
|
||||
// Tried adding the object to the iframe doc's innerHTML. Security error in all browsers.
|
||||
// iDoc.body.innerHTML = swfObjectHTML;
|
||||
|
||||
// Tried appending the object to the iframe doc's body. Security error in all browsers.
|
||||
// iDoc.body.appendChild(swfObject);
|
||||
|
||||
// Using document.write actually got around the security error that browsers were throwing.
|
||||
// Again, it's a dynamically generated (same domain) iframe, loading an external Flash swf.
|
||||
// Not sure why that's a security issue, but apparently it is.
|
||||
iDoc.write(_V_.flash.getEmbedCode(options.swf, flashVars, params, attributes));
|
||||
|
||||
// Setting variables on the window needs to come after the doc write because otherwise they can get reset in some browsers
|
||||
// So far no issues with swf ready event being called before it's set on the window.
|
||||
iWin.player = this.player;
|
||||
|
||||
// Create swf ready function for iFrame window
|
||||
iWin.ready = _V_.proxy(this.player, function(currSwf){
|
||||
var el = iDoc.getElementById(currSwf),
|
||||
player = this,
|
||||
tech = player.tech;
|
||||
|
||||
// Update reference to playback technology element
|
||||
tech.el = el;
|
||||
|
||||
// Now that the element is ready, make a click on the swf play the video
|
||||
_V_.addEvent(el, "click", tech.proxy(tech.onClick));
|
||||
|
||||
// Make sure swf is actually ready. Sometimes the API isn't actually yet.
|
||||
_V_.flash.checkReady(tech);
|
||||
});
|
||||
|
||||
// Create event listener for all swf events
|
||||
iWin.events = _V_.proxy(this.player, function(swfID, eventName, other){
|
||||
var player = this;
|
||||
if (player && player.techName == "flash") {
|
||||
player.triggerEvent(eventName);
|
||||
}
|
||||
});
|
||||
|
||||
// Create error listener for all swf errors
|
||||
iWin.errors = _V_.proxy(this.player, function(swfID, eventName){
|
||||
_V_.log("Flash Error", eventName);
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
// Replace placeholder with iFrame (it will load now)
|
||||
placeHolder.parentNode.replaceChild(iFrm, placeHolder);
|
||||
|
||||
// If not using iFrame mode, embed as normal object
|
||||
} else {
|
||||
_V_.flash.embed(options.swf, placeHolder, flashVars, params, attributes);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
destroy: function(){
|
||||
this.el.parentNode.removeChild(this.el);
|
||||
},
|
||||
|
||||
// setupTriggers: function(){}, // Using global onSWFEvent func to distribute events
|
||||
// setupTriggers: function(){}, // Using global onEvent func to distribute events
|
||||
|
||||
play: function(){ this.el.vjs_play(); },
|
||||
pause: function(){ this.el.vjs_pause(); },
|
||||
@@ -346,6 +485,7 @@ _V_.flash = _V_.PlaybackTech.extend({
|
||||
|
||||
// Create setters and getters for attributes
|
||||
(function(){
|
||||
|
||||
var api = _V_.flash.prototype,
|
||||
readWrite = "preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted".split(","),
|
||||
readOnly = "error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks".split(","),
|
||||
@@ -359,7 +499,8 @@ _V_.flash = _V_.PlaybackTech.extend({
|
||||
|
||||
createGetter = function(attr){
|
||||
api[attr] = function(){ return this.el.vjs_getProperty(attr); };
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
// Create getter and setters for all read/write attributes
|
||||
_V_.each(readWrite, function(attr){
|
||||
@@ -371,12 +512,14 @@ _V_.flash = _V_.PlaybackTech.extend({
|
||||
_V_.each(readOnly, function(attr){
|
||||
createGetter(attr);
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
/* Flash Support Testing -------------------------------------------------------- */
|
||||
|
||||
_V_.flash.isSupported = function(){
|
||||
return swfobject.hasFlashPlayerVersion("10");
|
||||
return _V_.flash.version()[0] >= 10;
|
||||
// return swfobject.hasFlashPlayerVersion("10");
|
||||
};
|
||||
|
||||
_V_.flash.canPlaySource = function(srcObj){
|
||||
@@ -395,14 +538,14 @@ _V_.flash.prototype.support = {
|
||||
progressEvent: false,
|
||||
timeupdateEvent: false,
|
||||
|
||||
// Resizing plugins using request fullscreen reloads the plugin
|
||||
// Resizing plugins using request fullscreen reloads the plugin
|
||||
fullscreenResize: false,
|
||||
|
||||
// Resizing plugins in Firefox always reloads the plugin (e.g. full window mode)
|
||||
parentResize: !(_V_.ua.match("Firefox"))
|
||||
};
|
||||
|
||||
_V_.flash.onSWFReady = function(currSwf){
|
||||
_V_.flash.onReady = function(currSwf){
|
||||
|
||||
var el = _V_.el(currSwf);
|
||||
|
||||
@@ -426,26 +569,119 @@ _V_.flash.onSWFReady = function(currSwf){
|
||||
// The SWF isn't alwasy ready when it says it is. Sometimes the API functions still need to be added to the object.
|
||||
// If it's not ready, we set a timeout to check again shortly.
|
||||
_V_.flash.checkReady = function(tech){
|
||||
|
||||
// Check if API property exists
|
||||
if (tech.el.vjs_getProperty) {
|
||||
|
||||
// If so, tell tech it's ready
|
||||
tech.triggerReady();
|
||||
|
||||
// Otherwise wait longer.
|
||||
} else {
|
||||
|
||||
setTimeout(function(){
|
||||
_V_.flash.checkReady(tech);
|
||||
}, 50);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
_V_.flash.onSWFEvent = function(swfID, eventName, other){
|
||||
// Trigger events from the swf on the player
|
||||
_V_.flash.onEvent = function(swfID, eventName){
|
||||
var player = _V_.el(swfID).player;
|
||||
player.triggerEvent(eventName);
|
||||
};
|
||||
|
||||
// Log errors from the swf
|
||||
_V_.flash.onError = function(swfID, err){
|
||||
_V_.log("Flash Error", err, swfID);
|
||||
};
|
||||
|
||||
// Flash Version Check
|
||||
_V_.flash.version = function(){
|
||||
var version = '0,0,0'
|
||||
|
||||
// IE
|
||||
try {
|
||||
var player = _V_.el(swfID).player;
|
||||
if (player && player.techName == "flash") {
|
||||
player.triggerEvent(eventName);
|
||||
}
|
||||
} catch(err) {
|
||||
_V_.log(err);
|
||||
version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
|
||||
|
||||
// other browsers
|
||||
} catch(e) {
|
||||
try {
|
||||
if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
|
||||
version = (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1];
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
return version.split(",");
|
||||
}
|
||||
|
||||
// Flash embedding method. Only used in non-iframe mode
|
||||
_V_.flash.embed = function(swf, placeHolder, flashVars, params, attributes){
|
||||
var code = _V_.flash.getEmbedCode(swf, flashVars, params, attributes),
|
||||
|
||||
// Get element by embedding code and retrieving created element
|
||||
obj = _V_.createElement("div", { innerHTML: code }).childNodes[0],
|
||||
|
||||
par = placeHolder.parentNode
|
||||
;
|
||||
|
||||
placeHolder.parentNode.replaceChild(obj, placeHolder);
|
||||
|
||||
// IE6 seems to have an issue where it won't initialize the swf object after injecting it.
|
||||
// This is a dumb temporary fix
|
||||
if (_V_.isIE()) {
|
||||
var newObj = par.childNodes[0];
|
||||
setTimeout(function(){
|
||||
newObj.style.display = "block";
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
};
|
||||
|
||||
_V_.flash.onSWFErrorEvent = function(swfID, eventName){
|
||||
_V_.log("Flash Error", eventName);
|
||||
};
|
||||
_V_.flash.getEmbedCode = function(swf, flashVars, params, attributes){
|
||||
|
||||
var objTag = '<object type="application/x-shockwave-flash"',
|
||||
flashVarsString = '',
|
||||
paramsString = ''
|
||||
attrsString = '';
|
||||
|
||||
// Convert flash vars to string
|
||||
if (flashVars) {
|
||||
_V_.eachProp(flashVars, function(key, val){
|
||||
flashVarsString += (key + "=" + val + "&");
|
||||
});
|
||||
}
|
||||
|
||||
// Add swf, flashVars, and other default params
|
||||
params = _V_.merge({
|
||||
movie: swf,
|
||||
flashvars: flashVarsString,
|
||||
allowScriptAccess: "always", // Required to talk to swf
|
||||
allowNetworking: "all" // All should be default, but having security issues.
|
||||
}, params);
|
||||
|
||||
// Create param tags string
|
||||
_V_.eachProp(params, function(key, val){
|
||||
paramsString += '<param name="'+key+'" value="'+val+'" />';
|
||||
});
|
||||
|
||||
attributes = _V_.merge({
|
||||
// Add swf to attributes (need both for IE and Others to work)
|
||||
data: swf,
|
||||
|
||||
// Default to 100% width/height
|
||||
width: "100%",
|
||||
height: "100%"
|
||||
|
||||
}, attributes);
|
||||
|
||||
// Create Attributes string
|
||||
_V_.eachProp(attributes, function(key, val){
|
||||
attrsString += (key + '="' + val + '" ');
|
||||
});
|
||||
|
||||
return objTag + attrsString + '>' + paramsString + '</object>';
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário