Comparar commits
74 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 | |||
| b7e7da427f | |||
| 1fedf3c1b9 | |||
| 35dfa99e59 | |||
| a4986cd5f9 | |||
| 2d8f283680 | |||
| f9c1905840 | |||
| aca861a190 |
@@ -19,3 +19,20 @@ CHANGELOG
|
||||
|
||||
---- 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: 7
|
||||
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 %}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
var vjsSourceList = [];
|
||||
+2
-3
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
Video.js - HTML5 Video Player
|
||||
Version 3.0
|
||||
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
+72
-28
@@ -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(){
|
||||
|
||||
+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,
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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