Skip to content
Browse files

Merge Popcorn.js v0.9 into master

  • Loading branch information...
2 parents 57ceac8 + aae4e9f commit ce66d472ce3a76685ae47f35feac52b173f47d02 @cadecairos cadecairos committed Oct 5, 2011
Showing with 3,133 additions and 2,945 deletions.
  1. +4 −3 .gitmodules
  2. +2 −0 AUTHORS
  3. +68 −36 Makefile
  4. +4 −2 build/jslint-check.js
  5. +0 −86 demos/popcorn/index.html
  6. +0 −95 demos/popcorn/style.css
  7. BIN demos/popcorn/team.jpg
  8. +0 −76 demos/popcorn/xml/data.xml
  9. +4 −0 effects/applyclass/popcorn.applyclass.html
  10. +1 −0 modules/sequence
  11. +64 −0 modules/timeline-sources/popcorn.timeline-sources.js
  12. +43 −0 modules/timeline-sources/popcorn.timeline-sources.unit.html
  13. +79 −0 modules/timeline-sources/popcorn.timeline-sources.unit.js
  14. +18 −13 parsers/parserJSON/popcorn.parserJSON.unit.html
  15. +15 −6 parsers/parserJSON/popcorn.parserJSON.unit.js
  16. +4 −0 parsers/parserSBV/popcorn.parserSBV.unit.html
  17. +4 −0 parsers/parserSRT/popcorn.parserSRT.unit.html
  18. +4 −0 parsers/parserSSA/popcorn.parserSSA.unit.html
  19. +4 −0 parsers/parserTTML/popcorn.parserTTML.unit.html
  20. +4 −0 parsers/parserTTXT/popcorn.parserTTXT.unit.html
  21. +4 −0 parsers/parserVTT/popcorn.parserVTT.unit.html
  22. +4 −0 parsers/parserXML/popcorn.parserXML.unit.html
  23. +2 −1 parsers/parserXML/popcorn.parserXML.unit.js
  24. +4 −0 players/baseplayer/popcorn.baseplayer.unit.html
  25. +0 −1 players/sequence
  26. +8 −7 players/youtube/popcorn.youtube.html
  27. +164 −502 players/youtube/popcorn.youtube.js
  28. +317 −176 players/youtube/popcorn.youtube.unit.js
  29. +23 −25 plugins/attribution/popcorn.attribution.html
  30. +63 −31 plugins/attribution/popcorn.attribution.js
  31. +19 −15 plugins/attribution/popcorn.attribution.unit.html
  32. +37 −38 plugins/attribution/popcorn.attribution.unit.js
  33. +14 −14 plugins/code/popcorn.code.html
  34. +50 −32 plugins/code/popcorn.code.js
  35. +8 −4 plugins/code/popcorn.code.unit.html
  36. +20 −20 plugins/code/popcorn.code.unit.js
  37. +48 −47 plugins/facebook/popcorn.facebook.html
  38. +158 −118 plugins/facebook/popcorn.facebook.js
  39. +17 −16 plugins/facebook/popcorn.facebook.unit.html
  40. +113 −57 plugins/facebook/popcorn.facebook.unit.js
  41. +7 −7 plugins/flickr/popcorn.flickr.html
  42. +7 −2 plugins/flickr/popcorn.flickr.js
  43. +19 −15 plugins/flickr/popcorn.flickr.unit.html
  44. +18 −18 plugins/flickr/popcorn.flickr.unit.js
  45. +23 −23 plugins/footnote/popcorn.footnote.html
  46. +26 −14 plugins/footnote/popcorn.footnote.js
  47. +9 −5 plugins/footnote/popcorn.footnote.unit.html
  48. +28 −27 plugins/footnote/popcorn.footnote.unit.js
  49. +27 −29 plugins/gml/popcorn.gml.html
  50. +29 −37 plugins/gml/popcorn.gml.js
  51. +18 −16 plugins/gml/popcorn.gml.unit.html
  52. +30 −30 plugins/gml/popcorn.gml.unit.js
  53. +20 −16 plugins/googlefeed/popcorn.googlefeed.html
  54. +25 −25 plugins/googlefeed/popcorn.googlefeed.js
  55. +19 −15 plugins/googlefeed/popcorn.googlefeed.unit.html
  56. +32 −32 plugins/googlefeed/popcorn.googlefeed.unit.js
  57. +80 −45 plugins/googlemap/popcorn.googlemap.html
  58. +41 −43 plugins/googlemap/popcorn.googlemap.js
  59. +20 −16 plugins/googlemap/popcorn.googlemap.unit.html
  60. +38 −39 plugins/googlemap/popcorn.googlemap.unit.js
  61. +8 −9 plugins/image/popcorn.image.html
  62. +20 −20 plugins/image/popcorn.image.js
  63. +14 −12 plugins/image/popcorn.image.unit.html
  64. +16 −16 plugins/image/popcorn.image.unit.js
  65. +47 −47 plugins/lastfm/popcorn.lastfm.html
  66. +50 −38 plugins/lastfm/popcorn.lastfm.js
  67. +19 −15 plugins/lastfm/popcorn.lastfm.unit.html
  68. +37 −37 plugins/lastfm/popcorn.lastfm.unit.js
  69. +15 −16 plugins/linkedin/popcorn.linkedin.html
  70. +27 −27 plugins/linkedin/popcorn.linkedin.js
  71. +18 −15 plugins/linkedin/popcorn.linkedin.unit.html
  72. +45 −45 plugins/linkedin/popcorn.linkedin.unit.js
  73. +18 −20 plugins/lowerthird/popcorn.lowerthird.html
  74. +38 −19 plugins/lowerthird/popcorn.lowerthird.js
  75. +18 −14 plugins/lowerthird/popcorn.lowerthird.unit.html
  76. +27 −27 plugins/lowerthird/popcorn.lowerthird.unit.js
  77. +43 −23 plugins/mustache/popcorn.mustache.js
  78. +8 −4 plugins/mustache/popcorn.mustache.unit.html
  79. +42 −41 plugins/mustache/popcorn.mustache.unit.js
  80. +22 −22 plugins/openmap/popcorn.openmap.html
  81. +73 −41 plugins/openmap/popcorn.openmap.js
  82. +18 −16 plugins/openmap/popcorn.openmap.unit.html
  83. +46 −46 plugins/openmap/popcorn.openmap.unit.js
  84. +9 −7 plugins/pause/popcorn.pause.html
  85. +11 −7 plugins/pause/popcorn.pause.unit.html
  86. +53 −48 plugins/pause/popcorn.pause.unit.js
  87. +7 −7 plugins/processing/popcorn.processing.html
  88. +80 −69 plugins/processing/popcorn.processing.js
  89. +11 −7 plugins/processing/popcorn.processing.unit.html
  90. +19 −19 plugins/processing/popcorn.processing.unit.js
  91. +20 −24 plugins/subtitle/popcorn.subtitle.html
  92. +18 −18 plugins/subtitle/popcorn.subtitle.js
  93. +26 −24 plugins/subtitle/popcorn.subtitle.unit.html
  94. +38 −40 plugins/subtitle/popcorn.subtitle.unit.js
  95. +30 −30 plugins/tagthisperson/popcorn.tagthisperson.html
  96. +44 −24 plugins/tagthisperson/popcorn.tagthisperson.js
  97. +21 −17 plugins/tagthisperson/popcorn.tagthisperson.unit.html
  98. +35 −35 plugins/tagthisperson/popcorn.tagthisperson.unit.js
  99. +18 −18 plugins/timeline/popcorn.timeline.html
  100. +18 −18 plugins/timeline/popcorn.timeline.js
  101. +18 −14 plugins/timeline/popcorn.timeline.unit.html
  102. +54 −48 plugins/timeline/popcorn.timeline.unit.js
  103. +23 −26 plugins/twitter/popcorn.twitter.html
Sorry, we could not display the entire diff because it was too big.
View
7 .gitmodules
@@ -1,3 +1,4 @@
-[submodule "players/sequence"]
- path = players/sequence
- url = git://github.com/rwldrn/popcorn.sequence.git
+
+[submodule "modules/sequence"]
+ path = modules/sequence
+ url = https://github.com/rwldrn/popcorn.sequence.git
View
2 AUTHORS
@@ -19,3 +19,5 @@ Cole Gillespie
Nick Doiron
Bobby Richter
Jon Buckley
+Mathew Schranz
+Brian Chirls
View
104 Makefile
@@ -6,6 +6,7 @@ PLUGINS_DIR = ${PREFIX}/plugins
PARSERS_DIR = ${PREFIX}/parsers
PLAYERS_DIR = ${PREFIX}/players
EFFECTS_DIR = $(PREFIX)/effects
+MODULES_DIR = $(PREFIX)/modules
# Version number used in naming release files. Defaults to git commit sha.
VERSION ?= $(shell git show -s --pretty=format:%h)
@@ -27,6 +28,10 @@ POPCORN_SRC = ${PREFIX}/popcorn.js
POPCORN_DIST = ${DIST_DIR}/popcorn.js
POPCORN_MIN = ${DIST_DIR}/popcorn.min.js
+# modules
+MODULES_DIST = ${DIST_DIR}/popcorn.modules.js
+MODULES_MIN = ${DIST_DIR}/popcorn.modules.min.js
+
# plugins
PLUGINS_DIST = ${DIST_DIR}/popcorn.plugins.js
PLUGINS_MIN = ${DIST_DIR}/popcorn.plugins.min.js
@@ -52,32 +57,44 @@ PARSERS_SRC := $(filter-out %unit.js, $(shell find ${PARSERS_DIR} -name 'popcorn
# Grab all popcorn.<player-name>.js files from players dir
PLAYERS_SRC := $(filter-out %unit.js, $(shell find ${PLAYERS_DIR} -name 'popcorn.*.js' -print))
-# Grab all popcorn.<effect-name>.js files from players dir
+# Grab all popcorn.<effect-name>.js files from effects dir
EFFECTS_SRC := $(filter-out %unit.js, $(shell find $(EFFECTS_DIR) -name 'popcorn.*.js' -print))
-# Grab all popcorn.<player-name>.unit.js files from plugins dir
+# Grab all popcorn.<Module-name>.js files from modules dir
+MODULES_SRC := $(filter-out %unit.js, $(shell find $(MODULES_DIR) -name 'popcorn.*.js' -print))
+
+# Grab all popcorn.<plugin-name>.unit.js files from plugins dir
PLUGINS_UNIT := $(shell find ${PLUGINS_DIR} -name 'popcorn.*.unit.js' -print)
-# Grab all popcorn.<player-name>.unit.js files from parsers dir
+# Grab all popcorn.<parser-name>.unit.js files from parsers dir
PARSERS_UNIT := $(shell find ${PARSERS_DIR} -name 'popcorn.*.unit.js' -print)
# Grab all popcorn.<player-name>.unit.js files from players dir
PLAYERS_UNIT := $(shell find ${PLAYERS_DIR} -name 'popcorn.*.unit.js' -print)
-# Grab all popcorn.<effects>.unit.js files from players dir
+# Grab all popcorn.<effects>.unit.js files from effects dir
EFFECTS_UNIT := $(shell find $(EFFECTS_DIR) -name 'popcorn.*.unit.js' -print)
+# Grab all popcorn.<module-name>.unit.js files from modules dir
+MODULES_UNIT := $(shell find $(MODULES_DIR) -name 'popcorn.*.unit.js' -print)
+
# popcorn + plugins
POPCORN_COMPLETE_LIST := --js ${POPCORN_SRC} \
+ $(shell for js in ${MODULES_SRC} ; do echo --js $$js ; done) \
$(shell for js in ${PLUGINS_SRC} ; do echo --js $$js ; done) \
$(shell for js in ${PARSERS_SRC} ; do echo --js $$js ; done) \
$(shell for js in ${PLAYERS_SRC} ; do echo --js $$js ; done)
POPCORN_COMPLETE_DIST = ${DIST_DIR}/popcorn-complete.js
POPCORN_COMPLETE_MIN = ${DIST_DIR}/popcorn-complete.min.js
-# Create a versioned license header for js files we ship: arg1=source arg2=dest
-add_license = cat ${PREFIX}/LICENSE_HEADER | sed -e 's/@VERSION/${VERSION}/' > $(2) ; \
- cat $(1) >> $(2)
+# Create a versioned license header for js files we ship
+add_license = cat $(PREFIX)/LICENSE_HEADER | sed -e 's/@VERSION/${VERSION}/' > $(1).__hdr__ ; \
+ cat $(1).__hdr__ $(1) >> $(1).__tmp__ ; rm -f $(1).__hdr__ ; \
+ mv $(1).__tmp__ $(1)
+
+# Create a version parameter for Popcorn
+add_version = cat $(1) | sed -e 's/@VERSION/${VERSION}/' > $(1).__tmp__ ; \
+ mv $(1).__tmp__ $(1)
# Run the file through jslint
run_lint = @@$(RHINO) build/jslint-check.js $(1)
@@ -92,23 +109,35 @@ ${DIST_DIR}:
popcorn: ${POPCORN_DIST}
-${POPCORN_DIST}: ${POPCORN_SRC} | ${DIST_DIR}
- @@echo "Building" ${POPCORN_DIST}
- @@$(call add_license, $(POPCORN_SRC), $(POPCORN_DIST))
+${POPCORN_DIST}: $(POPCORN_SRC) | $(DIST_DIR)
+ @@echo "Building" $(POPCORN_DIST)
+ @@cp $(POPCORN_SRC) $(POPCORN_DIST)
+ @@$(call add_license, $(POPCORN_DIST))
+ @@$(call add_version, $(POPCORN_DIST))
-min: ${POPCORN_MIN} ${PLUGINS_MIN} ${PARSERS_MIN} ${PLAYERS_MIN} $(EFFECTS_MIN) ${POPCORN_COMPLETE_MIN}
+min: setup ${POPCORN_MIN} ${MODULES_MIN} ${PLUGINS_MIN} ${PARSERS_MIN} ${PLAYERS_MIN} $(EFFECTS_MIN) ${POPCORN_COMPLETE_MIN}
${POPCORN_MIN}: ${POPCORN_DIST}
@@echo "Building" ${POPCORN_MIN}
- @@$(call compile, --js ${POPCORN_DIST}, ${POPCORN_MIN}.tmp)
- @@$(call add_license, ${POPCORN_MIN}.tmp, ${POPCORN_MIN})
- @@rm ${POPCORN_MIN}.tmp
+ @@$(call compile, --js $(POPCORN_DIST), $(POPCORN_MIN))
+ @@$(call add_license, $(POPCORN_MIN))
+ @@$(call add_version, $(POPCORN_MIN))
-${POPCORN_COMPLETE_MIN}: update ${POPCORN_SRC} ${PLUGINS_SRC} ${PARSERS_SRC} $(EFFECTS_SRC) ${DIST_DIR}
+${POPCORN_COMPLETE_MIN}: ${POPCORN_SRC} ${MODULES_SRC} ${PLUGINS_SRC} ${PARSERS_SRC} $(EFFECTS_SRC) ${DIST_DIR}
@@echo "Building" ${POPCORN_COMPLETE_MIN}
- @@$(call compile, ${POPCORN_COMPLETE_LIST}, ${POPCORN_COMPLETE_MIN}.tmp)
- @@$(call add_license, ${POPCORN_COMPLETE_MIN}.tmp, ${POPCORN_COMPLETE_MIN})
- @@rm ${POPCORN_COMPLETE_MIN}.tmp
+ @@$(call compile, $(POPCORN_COMPLETE_LIST), $(POPCORN_COMPLETE_MIN))
+ @@$(call add_license, $(POPCORN_COMPLETE_MIN))
+ @@$(call add_version, $(POPCORN_COMPLETE_MIN))
+
+modules: setup ${MODULES_DIST}
+
+${MODULES_MIN}: ${MODULES_DIST}
+ @@echo "Building" ${MODULES_MIN}
+ @@$(call compile, $(shell for js in ${MODULES_SRC} ; do echo --js $$js ; done), ${MODULES_MIN})
+
+${MODULES_DIST}: ${MODULES_SRC} ${DIST_DIR}
+ @@echo "Building ${MODULES_DIST}"
+ @@cat ${MODULES_SRC} > ${MODULES_DIST}
plugins: ${PLUGINS_DIST}
@@ -150,16 +179,24 @@ $(EFFECTS_DIST): $(EFFECTS_SRC) $(DIST_DIR)
@@echo "Building $(EFFECTS_DIST)"
@@cat $(EFFECTS_SRC) > $(EFFECTS_DIST)
-complete: update ${POPCORN_SRC} ${PARSERS_SRC} ${PLUGINS_SRC} ${PLAYERS_SRC} $(EFFECTS_SRC) ${DIST_DIR}
- @@echo "Building popcorn + plugins + parsers + players + effects..."
- @@cat ${POPCORN_SRC} ${PLUGINS_SRC} ${PARSERS_SRC} ${PLAYERS_SRC} $(EFFECTS_SRC) > ${POPCORN_COMPLETE_DIST}.tmp
- @@$(call add_license, ${POPCORN_COMPLETE_DIST}.tmp, ${POPCORN_COMPLETE_DIST})
- @@rm ${POPCORN_COMPLETE_DIST}.tmp
+complete: setup ${POPCORN_SRC} ${MODULES_SRC} ${PARSERS_SRC} ${PLUGINS_SRC} ${PLAYERS_SRC} $(EFFECTS_SRC) ${DIST_DIR}
+ @@echo "Building popcorn + modules + plugins + parsers + players + effects..."
+ @@cat ${POPCORN_SRC} ${MODULES_SRC} ${PLUGINS_SRC} ${PARSERS_SRC} ${PLAYERS_SRC} $(EFFECTS_SRC) > $(POPCORN_COMPLETE_DIST)
+ @@$(call add_license, $(POPCORN_COMPLETE_DIST))
+ @@$(call add_version, $(POPCORN_COMPLETE_DIST))
lint:
@@echo "Checking Popcorn against JSLint..."
@@$(call run_lint,popcorn.js)
+lint-core-tests:
+ @@echo "Checking core unit tests against JSLint..."
+ @@$(call run_lint,test/popcorn.unit.js)
+
+lint-modules:
+ @@echo "Checking all modules against JSLint..."
+ @@$(call run_lint,$(MODULES_SRC))
+
lint-plugins:
@@echo "Checking all plugins against JSLint..."
@@$(call run_lint,$(PLUGINS_SRC))
@@ -176,6 +213,10 @@ lint-effects:
@@echo "Checking all effects against JSLint..."
@@$(call run_lint,$(EFFECTS_SRC))
+lint-modules-tests:
+ @@echo "Checking modules unit tests against JSLint..."
+ @@$(call run_lint,$(MODULES_UNIT))
+
lint-plugin-tests:
@@echo "Checking plugin unit tests against JSLint..."
@@$(call run_lint,$(PLUGINS_UNIT))
@@ -192,7 +233,7 @@ lint-player-tests:
@@echo "Checking player unit tests against JSLint..."
@@$(call run_lint,$(PLAYERS_UNIT))
-lint-unit-tests: lint-plugin-tests lint-parser-tests lint-player-tests lint-effects-tests
+lint-unit-tests: lint-modules-tests lint-plugin-tests lint-parser-tests lint-player-tests lint-effects-tests
@@echo "completed"
# Create a mirror copy of the tree in dist/ using popcorn-complete.js
@@ -212,6 +253,7 @@ testing: complete
@@rm -fr ${TESTING_MIRROR}/AUTHORS ${TESTING_MIRROR}/LICENSE ${TESTING_MIRROR}/LICENSE_HEADER \
${TESTING_MIRROR}/Makefile ${TESTING_MIRROR}/readme.md
@@touch "${TESTING_MIRROR}/THIS IS A TESTING MIRROR -- READ-ONLY"
+ $(call overwrite_js, ${TESTING_MIRROR}/modules)
$(call overwrite_js, ${TESTING_MIRROR}/plugins)
$(call overwrite_js, ${TESTING_MIRROR}/players)
$(call overwrite_js, ${TESTING_MIRROR}/parsers)
@@ -222,16 +264,6 @@ clean:
@@echo "Removing Distribution directory:" ${DIST_DIR}
@@rm -rf ${DIST_DIR}
-# Setup any git submodules we need
-SEQUENCE_SRC = ${PLAYERS_DIR}/sequence/popcorn.sequence.js
-
-setup: ${SEQUENCE_SRC} update
-
-update:
+setup:
@@echo "Updating submodules..."
- @@git submodule update
- @@cd players/sequence; git pull origin master
-
-${SEQUENCE_SRC}:
- @@echo "Setting-up submodules..."
- @@git submodule init
+ @@git submodule update --init
View
6 build/jslint-check.js
@@ -9,7 +9,9 @@ var ok = {
"Use '!==' to compare with 'null'.": true,
"Expected an assignment or function call and instead saw an expression.": true,
"Expected a 'break' statement before 'case'.": true,
- "'e' is already defined.": true
+ "'e' is already defined.": true,
+ "Don't make functions within a loop.": true,
+ "['out'] is better written in dot notation.": true
};
function check(src)
@@ -26,7 +28,7 @@ function check(src)
print( " Problem at line " + w.line + " character " + w.character + ": " + w.reason );
}
}
-
+
if ( found > 0 ) {
print( "\n" + found + " Error(s) found." );
} else {
View
86 demos/popcorn/index.html
@@ -1,86 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <script src="../../popcorn.js"></script>
- <link href="style.css" rel="stylesheet" type="text/css" />
-
- <!-- This is needed for google maps api -->
- <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
- <!-- These two are needed for google news api -->
- <script src="http://google.com/jsapi"></script>
- <script>google.load("elements", "1", {packages : ["newsshow"]});</script>
- <!-- This is needed for language translation -->
- <script>google.load("language", "1");</script>
-</head>
-<body>
- <!-- Start Contents -->
- <div id="contents">
- <!-- Start Left Contents -->
- <div class="left-content">
- <!-- Start Video Div -->
- <br />
- <div id="videoContainer" class="video-div">
- <video src="http://scotland.proximity.on.ca/sdowne/popcornIntroDemo/demo.ogg" data-timeline-sources="xml/data.xml" style="-moz-transform: scaleX(1.2); height:300px;" controls></video>
- <div id="translateinfo"style="z-index:2;position:absolute;color:white;textShadow:black 2px 2px 6px;font-size:18px;font-family:arial;max-width:480px;font-weight:bold;top: 230px;left:-20px"></div>
- <div id="translateinfofrench" style="z-index:2;position:absolute;color:white;textShadow:black 2px 2px 6px;font-style:italic;font-family:arial;max-width:480px;font-size:18px;font-weight:bold;top:260px;left:-20px"></div>
- </div>
-
- <div class="video-info" style="display:none">
- <!-- Start Choose Language -->
- <div class="choose-language">
- <h2>Choose your language</h2>
- <select id="language">
- <option value="zh">Chinese</option>
- <option value="fr" selected="selected">French</option>
- <option value="de">German</option>
- <option value="it">Italian</option>
- <option value="ja">Japanese</option>
- <option value="ko">Korean</option>
- <option value="fa">Persian</option>
- <option value="pl">Polish</option>
- <option value="pt">Portuguese</option>
- <option value="es">Spanish</option>
- </select>
- <span id="credit">
- with help from
- <a href="http://google.com/translate">Google Translate</a> and <a href="http://jquery.com">
- jQuery</a>
- </span>
- </div>
- <!-- End Choose Language -->
- </div>
- <!-- End Video Info -->
- <div id="attribinfo" style="display:none;background:white;width:409px;height:100px;text-align:left;padding-left:4px;"></div>
- </div><br />
-
- </div><!-- End Video Div -->
- <div class="right-content">
- <h1>Google Maps</h1>
- <div id="mapinfo" style="width:400px;height:250px" ></div>
-
- <div id="imageinfo" style="display:none;top:330px;width:400px;text-align:left;"> <!--needed for imageCommand -->
- <h1>Popcorn-js Team</h1>
- </div>
-
- <div id="wikiinfo" style="display:none;top:330px;background:black;color:white;width:400px;height:220px;text-align:left;padding-left:4px;position:absolute;">
- <h1>Wikipedia</h1><br>
- </div>
- <div id="flickrinfo" style="display:none;top:330px;color:white;background:black;width:400px;height:220px;text-align:left;position:absolute">
- <h1>Flickr</h1>
- </div>
- <div id="twitterinfo" style="display:none;top:330px;color:white;background:white;width:400px;height:100px;text-align:left;align:left">
- <br />
- </div>
-
- </div>
- <br />
- <div class="full-content">
-
- <div id="iframeinfo"></div>
- <div id="iframeinfo"></div>
-
- </div>
- </div>
- </body>
-</html>
-
View
95 demos/popcorn/style.css
@@ -1,95 +0,0 @@
-html, body{
-height: 100%;
-}
-
-body {
- line-height: 1;
- font-family: Helvetica, Arial, "Lucida Grande";
- font-size: 15px;
-}
-a{
- text-decoration: none;
- color: #cc433d;
-}
-
-a:hover{
- color: #f27c77;
-}
-/* Layout */
-
-body{
- background-color: #000000;
-}
-
-.left-content{
- width:520px;
- float: left;
- padding-left:20px
-}
-.right-content{
- float: left;
- width:400px;
- padding-left:0px;
- padding-top: 0px;
-}
-.full-content{
- width:960px;
- padding-left:20px;
-}
-.video-div{
- position:relative;
- border-style: "groove";
- margin-bottom: 20px;
- margin-right: 20px;
- margin-left: 45px;
- clear: both;
- font-size: 15px !important;
-}
-
-h1{
- border: 1px solid #9f9f9f;
- background-color:#1c749d;
- -moz-border-radius:8px;
- border-radius:8px;
- -webkit-border-radius:8px;
- background-image: -moz-linear-gradient(top, #3d96c0, #1a729b);/* Firefox 3.6 */
- background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0, #1a729b),color-stop(1, #3d96c0));/* Safari & Chrome */
- padding: 5px 20px 6px 12px;
- min-width:365px;
- font-size:15px;
- color: #FFF;
- font-weight: normal;
- display: inline-block;
- border-bottom-color: #1c749d;
- /*box-shadow:inset 0 0 1px #FFF;
- -moz-box-shadow:inset 0 1px 0 #6fb9db;*/
-}
-.choose-language h2, .choose-language div{
-color: #FFF;
-opacity:.8;
-}
-
-.choose-language h2{
-font-size: 12px;
-padding-bottom: 3px;
-}
-
-.choose-language a{
-font-weight: bold;
-color: #FFF;
-text-decoration: underline;
-}
-
-.choose-language a:hover{
-opacity:1;
-}
-
-#credit{
-padding: 5px 0;
-font-size: 10px;
-color: #FFF;
-}
-.choose-language select,.choose-language span, .choose-language select *{
-color: #000;
-font-size: 12px;
-}
View
BIN demos/popcorn/team.jpg
Deleted file not rendered
View
76 demos/popcorn/xml/data.xml
@@ -1,76 +0,0 @@
-<popcorn>
- <timeline>
- <subtitles language="en" target="translateinfo">
- <subtitle in="00:00:00:00" out="00:00:02:00">I am one of the lead developers of </subtitle>
- <subtitle in="00:00:02:00" out="00:00:05:00">popcorn a JavaScript library that adds </subtitle>
- <subtitle in="00:00:05:00" out="00:00:07:00">timeline based data to any video.</subtitle>
- <subtitle in="00:00:08:00" out="00:00:09:00">I am going to show you what popcorn</subtitle>
- <subtitle in="00:00:09:00" out="00:00:12:00">can do. Right now all you see is me</subtitle>
- <subtitle in="00:00:12:00" out="00:00:14:00">talking on the screen you can’t really</subtitle>
- <subtitle in="00:00:14:00" out="00:00:17:00">do anything but watch. Let’s make this </subtitle>
- <subtitle in="00:00:17:00" out="00:00:19:00">video more exciting. Let me add </subtitle>
- <subtitle in="00:00:19:00" out="00:00:22:00">some French subtitles. Popcorn uses</subtitle>
- <subtitle in="00:00:22:00" out="00:00:24:00">Google Translate to translate subtitles</subtitle>
- <subtitle in="00:00:24:00" out="00:00:27:00">to any language. You might be curious</subtitle>
- <subtitle in="00:00:27:00" out="00:00:29:00">to know that this video was filmed in</subtitle>
- <subtitle in="00:00:29:00" out="00:00:32:00">Toronto, Ontario. If you don’t know </subtitle>
- <subtitle in="00:00:32:00" out="00:00:34:00">exactly where that is feel free to </subtitle>
- <subtitle in="00:00:34:00" out="00:00:36:00">pause this video and investigate the</subtitle>
- <subtitle in="00:00:36:00" out="00:00:39:00">map. Popcorn was built by five people,</subtitle>
- <subtitle in="00:00:39:00" out="00:00:42:00">there they are. We collaborated with </subtitle>
- <subtitle in="00:00:42:00" out="00:00:44:00">filmmakers and artists to ensure that</subtitle>
- <subtitle in="00:00:44:00" out="00:00:47:00">popcorn is easy to use. Let me show</subtitle>
- <subtitle in="00:00:47:00" out="00:00:49:00">you some other cool features. Keep in</subtitle>
- <subtitle in="00:00:49:00" out="00:00:51:00">mind that you can have any feature </subtitle>
- <subtitle in="00:00:51:00" out="00:00:54:00">appear and disappear at any time</subtitle>
- <subtitle in="00:00:54:00" out="56.5">during the video. Popcorn makes it </subtitle>
- <subtitle in="56.5" out="00:00:59:00">possible to pull data from twitter.</subtitle>
- <subtitle in="00:00:59:00" out="00:01:01:00">Let’s see what people are saying </subtitle>
- <subtitle in="00:01:01:00" out="00:01:02:00">about popcorn right now.</subtitle>
- <subtitle in="00:01:03:00" out="00:01:04:00">You can also showcase your work </subtitle>
- <subtitle in="00:01:04:00" out="00:01:07:00">by pulling data from a flicker account.</subtitle>
- <subtitle in="00:01:07:00" out="00:01:09:00">Here are some pictures I posted.</subtitle>
- <subtitle in="00:01:09:00" out="00:01:10:00">If you are not quite sure what</subtitle>
- <subtitle in="00:01:10:00" out="00:01:12:00">Flicker is take a second to read</subtitle>
- <subtitle in="00:01:12:00" out="00:01:15:00">about it on Wikipedia. To try</subtitle>
- <subtitle in="00:01:15:00" out="00:01:17:00">out popcorn visit our homepage,</subtitle>
- <subtitle in="00:01:17:00" >it is displayed just below me. </subtitle>
-
- </subtitles>
- <subtitles language="en" target="translateinfofrench" languagesrc="language">
- <subtitle in="00:00:19:00" out="00:00:22:00">some French subtitles. Popcorn uses</subtitle>
- <subtitle in="00:00:22:00" out="00:00:24:00">Google Translate to translate subtitles</subtitle>
- <subtitle in="00:00:24:00" out="00:00:27:00">to any language. You might be curious</subtitle>
- <subtitle in="00:00:27:00" out="00:00:29:00">to know that this video was filmed in</subtitle>
- <subtitle in="00:00:29:00" out="00:00:32:00">Toronto, Ontario. If you don’t know </subtitle>
- <subtitle in="00:00:32:00" out="00:00:34:00">exactly where that is feel free to </subtitle>
- <subtitle in="00:00:34:00" out="00:00:36:00">pause this video and investigate the</subtitle>
- <subtitle in="00:00:36:00" out="00:00:39:00">map. Popcorn was built by five people,</subtitle>
- <subtitle in="00:00:39:00" out="00:00:42:00">there they are. We collaborated with </subtitle>
- <subtitle in="00:00:42:00" out="00:00:44:00">filmmakers and artists to ensure that</subtitle>
- <subtitle in="00:00:44:00" out="00:00:47:00">popcorn is easy to use. Let me show</subtitle>
- <subtitle in="00:00:47:00" out="00:00:49:00">you some other cool features. Keep in</subtitle>
- <subtitle in="00:00:49:00" out="00:00:51:00">mind that you can have any feature </subtitle>
- <subtitle in="00:00:51:00" out="00:00:54:00">appear and disappear at any time</subtitle>
- <subtitle in="00:00:54:00" out="56.5">during the video. Popcorn makes it </subtitle>
- <subtitle in="56.5" out="00:00:59:00">possible to pull data from twitter.</subtitle>
- <subtitle in="00:00:59:00" out="00:01:01:00">Let’s see what people are saying </subtitle>
- <subtitle in="00:01:01:00" out="00:01:02:00">about popcorn right now.</subtitle>
- <subtitle in="00:01:03:00" out="00:01:04:00">You can also showcase your work </subtitle>
- <subtitle in="00:01:04:00" out="00:01:07:00">by pulling data from a flicker account.</subtitle>
- <subtitle in="00:01:07:00" out="00:01:09:00">Here are some pictures I posted.</subtitle>
- <subtitle in="00:01:09:00" out="00:01:10:00">If you are not quite sure what</subtitle>
- <subtitle in="00:01:10:00" out="00:01:12:00">Flicker is take a second to read</subtitle>
- <subtitle in="00:01:12:00" out="00:01:15:00">about it on Wikipedia. To try</subtitle>
- <subtitle in="00:01:15:00" out="00:01:17:00">out popcorn visit our homepage,</subtitle>
- <subtitle in="00:01:17:00" >it is displayed just below me. </subtitle>
- </subtitles>
- <location in="00:00:29:00" long="-79.403323" lat="43.665429" target="mapinfo" zoom="16"/>
- <wiki in="00:01:12:00" out="00:01:15:00" src="http://en.wikipedia.org/wiki/Metadata" description="Metadata" numberOfWords="250" lang="en" target="wikiinfo"/>
- <flickr in="00:01:06:00" out="00:01:10:00" target="flickrinfo" userid="54210095@N08" numberofimages="3" height="80" width="115" padding="8px"/>
- <twitter in="00:00:59:00" out="00:01:05:00" title="&lt;b&gt;popcorn-js&lt;/b&gt;" source="popcorn-js" target="twitterinfo" width="400" height="120"/>
- <image in="00:00:40:00" out="00:00:50:00" src="team.jpg" width="400" target="imageinfo"/>
- <webpage in="00:01:15:00" target="iframeinfo" width="920" height="200" src="http://webmademovies.org" description="WebMadeMovies"></webpage>
-
- </timeline>
-</popcorn>
View
4 effects/applyclass/popcorn.applyclass.html
@@ -49,6 +49,10 @@ <h1 id="qunit-header">Popcorn flash effect Demo</h1>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
1 modules/sequence
@@ -0,0 +1 @@
+Subproject commit 45ec9d69ae770a3b221d4ba8b935ae19c76cb34f
View
64 modules/timeline-sources/popcorn.timeline-sources.js
@@ -0,0 +1,64 @@
+(function( Popcorn ) {
+ document.addEventListener( "DOMContentLoaded", function() {
+
+ // Supports non-specific elements
+ var dataAttr = "data-timeline-sources",
+ medias = document.querySelectorAll( "[" + dataAttr + "]" );
+
+ Popcorn.forEach( medias, function( idx, key ) {
+
+ var media = medias[ key ],
+ hasDataSources = false,
+ dataSources, data, popcornMedia;
+
+ // Ensure that the DOM has an id
+ if ( !media.id ) {
+
+ media.id = Popcorn.guid( "__popcorn" );
+ }
+
+ // Ensure we're looking at a dom node
+ if ( media.nodeType && media.nodeType === 1 ) {
+
+ popcornMedia = Popcorn( "#" + media.id );
+
+ dataSources = ( media.getAttribute( dataAttr ) || "" ).split( "," );
+
+ if ( dataSources[ 0 ] ) {
+
+ Popcorn.forEach( dataSources, function( source ) {
+
+ // split the parser and data as parser!file
+ data = source.split( "!" );
+
+ // if no parser is defined for the file, assume "parse" + file extension
+ if ( data.length === 1 ) {
+
+ // parse a relative URL for the filename, split to get extension
+ data = source.match( /(.*)[\/\\]([^\/\\]+\.\w+)$/ )[ 2 ].split( "." );
+
+ data[ 0 ] = "parse" + data[ 1 ].toUpperCase();
+ data[ 1 ] = source;
+ }
+
+ // If the media has data sources and the correct parser is registered, continue to load
+ if ( dataSources[ 0 ] && popcornMedia[ data[ 0 ] ] ) {
+
+ // Set up the media and load in the datasources
+ popcornMedia[ data[ 0 ] ]( data[ 1 ] );
+
+ }
+ });
+
+ }
+
+ // Only play the media if it was specified to do so
+ if ( !!popcornMedia.autoplay ) {
+ popcornMedia.play();
+ }
+
+ }
+ });
+ }, false );
+
+})( Popcorn );
View
43 modules/timeline-sources/popcorn.timeline-sources.unit.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Popcorn Module: Timeline-Sources</title>
+ <link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
+ <script src="../../test/qunit/qunit.js"></script>
+
+ <script src="../../popcorn.js"></script>
+ <script src="popcorn.timeline-sources.js"></script>
+ <script src="popcorn.timeline-sources.unit.js"></script>
+ <script src="../../parsers/parserJSON/popcorn.parserJSON.js"></script>
+</head>
+<body>
+ <h1 id="qunit-header">Popcorn Module: timeline-sources</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"></ol>
+ <div id="qunit-fixture"> </div>
+
+ <video id='video'
+ controls preload='auto'
+ width= '250px'
+ poster="../../test/poster.png"
+ data-timeline-sources="../../parsers/parserJSON/data/video.json">
+
+ <source id='mp4'
+ src="../../test/trailer.mp4"
+ type='video/mp4; codecs="avc1, mp4a"'>
+
+ <source id='ogv'
+ src="../../test/trailer.ogv"
+ type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
+
+ <p>Your user agent does not support the HTML5 Video element.</p>
+
+ </video
+</body>
+</html>
View
79 modules/timeline-sources/popcorn.timeline-sources.unit.js
@@ -0,0 +1,79 @@
+(function( Popcorn ) {
+
+ var setupCalled = 0,
+ startCalled = 0,
+ endCalled = 0;
+
+ Popcorn.plugin( "footnote", function( options ) {
+ return {
+ _setup: function() {
+ setupCalled++;
+ },
+ start: function() {
+ startCalled++;
+ },
+ end: function() {
+ endCalled++;
+ }
+ };
+ });
+
+ Popcorn.plugin( "googlemap", function( options ) {
+ return {
+ _setup: function() {
+ setupCalled++;
+ },
+ start: function() {
+ startCalled++;
+ },
+ end: function() {
+ endCalled++;
+ }
+ };
+ });
+
+ Popcorn.plugin( "webpage", function( options ) {
+ return {
+ _setup: function() {
+ setupCalled++;
+ },
+ start: function() {
+ startCalled++;
+ },
+ end: function() {
+ endCalled++;
+ }
+ };
+ });
+
+ test( "Timeline-sources Module", function() {
+ expect( 3 );
+
+ var count = 0,
+ p = Popcorn.instances[ 0 ].volume( 0 );
+
+ function plus() {
+ if ( ++count === 3 ) {
+ start();
+ }
+ }
+
+ stop();
+
+ p.exec( 3, function() {
+ equals( startCalled, 5, "start was called 5 times from the parsed data" );
+ plus();
+ p.currentTime( 9 );
+ });
+
+ p.exec( 10.5, function() {
+ equals( endCalled, 5, "end was called 5 times from the parsed data" );
+ plus()
+ });
+
+ equals( setupCalled, 5, "setup was called 5 times from the parsed data" );
+ plus();
+
+ });
+
+})( Popcorn );
View
31 parsers/parserJSON/popcorn.parserJSON.unit.html
@@ -4,13 +4,14 @@
<title>Popcorn 0.3 JSON parser Plug-in Tes</title>
<link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
<script src="../../test/qunit/qunit.js"></script>
- <!--
- do not move - this must be called immediately prior to
+ <!--
+ do not move - this must be called immediately prior to
popcorn-api-draft.js
-->
<script src="../../test/jquery.js"></script>
-
+
<script src="../../popcorn.js"></script>
+ <script src="../../modules/timeline-sources/popcorn.timeline-sources.js"></script>
<script src="../../plugins/webpage/popcorn.webpage.js"></script>
<script src="../../plugins/footnote/popcorn.footnote.js"></script>
<script src="../../plugins/googlemap/popcorn.googlemap.js"></script>
@@ -24,29 +25,33 @@ <h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture"> </div>
-
- <video id='video'
+
+ <video id='video'
controls
width= '250px'
- poster="../../test/poster.png">
+ poster="../../test/poster.png">
<source id='mp4'
src="../../test/trailer.mp4"
- type='video/mp4; codecs="avc1, mp4a"'>
+ type='video/mp4; codecs="avc1, mp4a"'>
<source id='ogv'
src="../../test/trailer.ogv"
- type='video/ogg; codecs="theora, vorbis"'>
+ type='video/ogg; codecs="theora, vorbis"'>
- <p>Your user agent does not support the HTML5 Video element.</p>
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
- </video>
+ <p>Your user agent does not support the HTML5 Video element.</p>
+
+ </video>
<audio id='audio' data-timeline-sources="data/audio.json" controls>
<source src="../../test/italia.mp4" type='audio/mp4; codecs="mp4a.40.2"'>
<source src="../../test/italia.ogg" type='audio/ogg; codecs="vorbis"'>
</audio>
-
+
<style>
.displays {
width: 300px;
@@ -57,12 +62,12 @@ <h2 id="qunit-userAgent"></h2>
<div style="width:300px;float:left">
<div class="displays" id="video-iframe-container"></div>
<div class="displays" id="video-map-container"></div>
- <div class="displays" id="video-footnote-container"></div>
+ <div class="displays" id="video-footnote-container"></div>
</div>
<div style="width:300px;float:left">
<div class="displays" id="audio-iframe-container"></div>
<div class="displays" id="audio-map-container"></div>
- <div class="displays" id="audio-footnote-container"></div>
+ <div class="displays" id="audio-footnote-container"></div>
</div>
</body>
</html>
View
21 parsers/parserJSON/popcorn.parserJSON.unit.js
@@ -31,11 +31,8 @@ test("Popcorn 0.3 JSON Parser Plugin", function () {
var idx = 0;
- //console.log( data );
-
Popcorn.forEach( data.json.data, function (dataObj) {
- //console.log( dataObj );
Popcorn.forEach( dataObj, function ( obj, key ) {
equals( trackData.history[idx].indexOf(key), 0, "history item '" + trackData.history[idx] + "' matches data key '"+ key+ "' at correct index" );
@@ -85,7 +82,20 @@ test("Popcorn 0.3 JSON Parser Plugin - AUDIO", function () {
trackData,
trackEvents,
interval,
- audiocorn = Popcorn.getInstanceById("audio");
+ audiocorn;
+
+ function getInstance( id ) {
+ var instance;
+ for ( var i = 0, l = Popcorn.instances.length; i < l; i++ ) {
+ instance = instance = Popcorn.instances[ i ];
+ if ( instance.media.id === id ) {
+ return instance;
+ }
+ }
+ throw( "instance not found" );
+ }
+
+ audiocorn = getInstance( "audio" );
function plus() {
if ( ++count === expects ) {
@@ -115,8 +125,7 @@ test("Popcorn 0.3 JSON Parser Plugin - AUDIO", function () {
var historyItem = trackData.history[ idx ];
- console.log( historyItem, key );
- equal( historyItem.indexOf(key), 0, "history item '" + historyItem + "' matches data key '"+ key+ "' at correct index" );
+ equal( historyItem.indexOf( key ), 0, "history item '" + historyItem + "' matches data key '"+ key+ "' at correct index" );
plus();
idx++;
View
4 parsers/parserSBV/popcorn.parserSBV.unit.html
@@ -35,6 +35,10 @@ <h2 id="qunit-userAgent"></h2>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
View
4 parsers/parserSRT/popcorn.parserSRT.unit.html
@@ -35,6 +35,10 @@ <h2 id="qunit-userAgent"></h2>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
View
4 parsers/parserSSA/popcorn.parserSSA.unit.html
@@ -35,6 +35,10 @@ <h2 id="qunit-userAgent"></h2>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
View
4 parsers/parserTTML/popcorn.parserTTML.unit.html
@@ -35,6 +35,10 @@ <h2 id="qunit-userAgent"></h2>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
View
4 parsers/parserTTXT/popcorn.parserTTXT.unit.html
@@ -35,6 +35,10 @@ <h2 id="qunit-userAgent"></h2>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
View
4 parsers/parserVTT/popcorn.parserVTT.unit.html
@@ -35,6 +35,10 @@ <h2 id="qunit-userAgent"></h2>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
View
4 parsers/parserXML/popcorn.parserXML.unit.html
@@ -34,6 +34,10 @@ <h2 id="qunit-userAgent"></h2>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
View
3 parsers/parserXML/popcorn.parserXML.unit.js
@@ -11,6 +11,7 @@ test("Popcorn 0.1 XML Parser Plugin", function () {
start();
// clean up added events after tests
clearInterval( interval );
+ poppercorn.pause();
}
}
@@ -55,7 +56,7 @@ test("Popcorn 0.1 XML Parser Plugin", function () {
poppercorn.parseXML( "data/unit.XML", function() {
- poppercorn.currentTime(5);
+ poppercorn.currentTime(5).play();
});
});
View
4 players/baseplayer/popcorn.baseplayer.unit.html
@@ -65,6 +65,10 @@ <h2 id="qunit-userAgent"></h2>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
+
+ <source id='webm'
+ src="../../test/trailer.webm"
+ type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
1 players/sequence
@@ -1 +0,0 @@
-Subproject commit 01eb7df20bc9e58c9cab108789f7b4ea7c347925
View
15 players/youtube/popcorn.youtube.html
@@ -15,14 +15,15 @@
<script>
// Helper function to get elements
function element(id) {
+
return document.getElementById(id);
}
document.addEventListener( 'DOMContentLoaded', function() {
var paused = true,
popcorn;
- popcorn = Popcorn( Popcorn.youtube( 'video', 'http://www.youtube.com/watch?v=9oar9glUCL0', { width: 400, controls: 0, annotations: 3 } ) );
+ popcorn = Popcorn.youtube( '#video', 'http://www.youtube.com/watch?v=9oar9glUCL0' );
popcorn = popcorn
.footnote({
@@ -94,19 +95,18 @@
element( 'player-time' ).innerHTML = popcorn.currentTime();
})
// Update button labels
- .listen( 'playing' , function() {
+ .listen( 'play' , function() {
paused = false;
element( 'btn-play-pause' ).innerHTML = 'Pause';
})
.listen('pause', function() {
paused = true;
element( 'btn-play-pause' ).innerHTML = 'Play';
- })
- popcorn.mute()
- .play();
-
+ });
+
// Setup UI after loaded
popcorn.listen( 'load', function() {
+
element( 'player-status' ).innerHTML = 'Ready';
element( 'player_vol' ).innerHTML = popcorn.volume();
@@ -121,6 +121,7 @@
// Seek
element('btn-seek').addEventListener('click', function() {
+
popcorn.currentTime( 30 );
}, false);
@@ -131,7 +132,7 @@
}, false);
element('btn-mute').addEventListener('click', function() {
- popcorn.mute();
+ popcorn.mute( !popcorn.media.muted );
}, false);
});
}, false );
View
666 players/youtube/popcorn.youtube.js
@@ -1,558 +1,220 @@
-// Popcorn Youtube Player Wrapper
-
-var onYouTubePlayerReady;
-
-( function( Popcorn ) {
- /**
- * Youtube wrapper for popcorn.
- * This plug-in adds capability for Popcorn.js to deal with Youtube
- * videos. This plug-in also doesn't use Popcorn's plugin() API and
- * instead hacks directly into Popcorn's core.
- *
- * To use this plug-in, onYouTubePlayerReady() event handler needs to be
- * called by the Youtube video player, before videos can be registered.
- * Once videos are registered, calls to them can be made the same way as
- * regular Popcorn objects. Also note that enablejsapi=1 needs to be added
- * to the embed code, in order for Youtube's JavaScript API to work.
- *
- * Note that there are a few methods, properties and events that are not
- * supported. See the bottom of this plug-in for a complete list.
- */
-
- // Intended
- var undef;
-
- // Config parameters
- // 33 ms per update is suitable for 30 fps
- // 0.05 sec tolerance between old and new times to determine if currentTime has been set programatically
- // 250 ms progress interval as specified by WHATWG
- var timeupdateInterval = 33,
- timeCheckInterval = 0.5,
- progressInterval = 250;
-
- // Ready State Constants
- var READY_STATE_HAVE_NOTHING = 0,
- READY_STATE_HAVE_METADATA = 1,
- READY_STATE_HAVE_CURRENT_DATA = 2,
- READY_STATE_HAVE_FUTURE_DATA = 3,
- READY_STATE_HAVE_ENOUGH_DATA = 4;
-
- // Youtube State Constants
- var YOUTUBE_STATE_UNSTARTED = -1,
- YOUTUBE_STATE_ENDED = 0,
- YOUTUBE_STATE_PLAYING = 1,
- YOUTUBE_STATE_PAUSED = 2,
- YOUTUBE_STATE_BUFFERING = 3,
- YOUTUBE_STATE_CUED = 5;
-
- var urlRegex = /^.*[\/=](.{11})/;
-
- // Collection of all Youtube players
- var registry = {},
- loadedPlayers = {};
-
- var abs = Math.abs;
-
- Popcorn.getScript( "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" );
-
- // Extract the id from a web url
- function extractIdFromUrl( url ) {
- if ( !url ) {
- return;
- }
+// A global callback for youtube... that makes me angry
+var onYouTubePlayerReady = function( containerId ) {
- var matches = urlRegex.exec( url );
+ onYouTubePlayerReady[ containerId ] && onYouTubePlayerReady[ containerId ]();
+};
+onYouTubePlayerReady.stateChangeEventHandler = {};
- // Return id, which comes after first equals sign
- return matches ? matches[1] : "";
- }
+Popcorn.player( "youtube", {
+ _setup: function( options ) {
- // Extract the id from a player url
- function extractIdFromUri( url ) {
- if ( !url ) {
- return;
- }
+ var media = this,
+ youtubeObject,
+ container = document.createElement( "div" ),
+ currentTime = 0,
+ seekTime = 0,
+ seeking = false,
- var matches = urlRegex.exec( url );
+ // state code for volume changed polling
+ volumeChanged = false,
+ lastMuted = false,
+ lastVolume = 0;
- // Return id, which comes after first equals sign
- return matches ? matches[1] : "";
- }
+ container.id = media.id + Popcorn.guid();
- function getPlayerAddress( vidId, playerId ) {
- if( !vidId ) {
- return;
- }
+ media.appendChild( container );
- return "http://www.youtube.com/e/" + id;
- }
+ var youtubeInit = function() {
- function makeSWF( url, container ) {
- var bounds,
- params,
- flashvars,
- attributes,
- self = this;
+ var flashvars,
+ params,
+ attributes,
+ src;
- if ( !window.swfobject ) {
- setTimeout( function() {
- makeSWF.call( self, url, container );
- }, 1 );
- return;
- }
+ // expose a callback to this scope, that is called from the global callback youtube calls
+ onYouTubePlayerReady[ container.id ] = function() {
- bounds = container.getBoundingClientRect();
+ youtubeObject = document.getElementById( container.id );
- // Determine width/height/etc based on container
- this.width = container.style.width || 460;
- this.height = container.style.height || 350;
+ // more youtube callback nonsense
+ onYouTubePlayerReady.stateChangeEventHandler[ container.id ] = function( state ) {
- // Just in case we got the attributes as strings. We'll need to do math with these later
- this.width = parseFloat(this.width);
- this.height = parseFloat(this.height);
+ // playing is state 1
+ // paused is state 2
+ if ( state === 1 ) {
- // For calculating position relative to video (like subtitles)
- this.offsetWidth = this.width;
- this.offsetHeight = this.height;
- this.offsetLeft = bounds.left;
- this.offsetTop = bounds.top;
+ media.paused && media.play();
+ // youtube fires paused events while seeking
+ // this is the only way to get seeking events
+ } else if ( state === 2 ) {
- this.offsetParent = container.offsetParent;
+ // silly logic forced on me by the youtube API
+ // calling youtube.seekTo triggers multiple events
+ // with the second events getCurrentTime being the old time
+ if ( seeking && seekTime === currentTime && seekTime !== youtubeObject.getCurrentTime() ) {
- flashvars = {
- playerapiid: this.playerId,
- controls: this.controls,
- iv_load_policy: this.iv_load_policy
- };
+ seeking = false;
+ youtubeObject.seekTo( currentTime );
+ return;
+ }
- params = {
- allowscriptaccess: 'always',
- allowfullscreen: 'true',
- // This is so we can overlay html on top of Flash
- wmode: 'transparent'
+ currentTime = youtubeObject.getCurrentTime();
+ media.dispatchEvent( "timeupdate" );
+ !media.paused && media.pause();
+ }
+ };
- };
+ // youtube requires callbacks to be a string to a function path from the global scope
+ youtubeObject.addEventListener( "onStateChange", "onYouTubePlayerReady.stateChangeEventHandler." + container.id );
- attributes = {
- id: this.playerId
- };
+ var timeupdate = function() {
- swfobject.embedSWF( "http://www.youtube.com/e/" + this.vidId +"?enablejsapi=1&playerapiid=" + this.playerId + "&version=3",
- this.playerId, this.width, this.height, "8", null, flashvars, params, attributes );
- }
+ if ( !media.paused ) {
- // Called when a player is loaded
- // Playerid must match the element id
- onYouTubePlayerReady = function ( playerId ) {
- var vid = registry[playerId];
+ currentTime = youtubeObject.getCurrentTime();
+ media.dispatchEvent( "timeupdate" );
+ setTimeout( timeupdate, 10 );
+ }
+ };
- loadedPlayers[playerId] = 1;
+ var volumeupdate = function() {
- // Video hadn't loaded yet when ctor was called
- vid.video = document.getElementById( playerId );
- vid.duration = vid.video.getDuration();
+ if ( lastMuted !== youtubeObject.isMuted() ) {
+ lastMuted = youtubeObject.isMuted();
+ media.dispatchEvent( "volumechange" );
+ }
- // Issue load event
- vid.dispatchEvent( 'load' );
- vid.dispatchEvent( "durationchange" );
- };
+ if ( lastVolume !== youtubeObject.getVolume() ) {
- Popcorn.youtube = function( elementId, url, options ) {
- return new Popcorn.youtube.init( elementId, url, options );
- };
+ lastVolume = youtubeObject.getVolume();
+ media.dispatchEvent( "volumechange" );
+ }
- Popcorn.youtube.init = function( elementId, url, options ) {
- if ( !elementId ) {
- throw "Element id is invalid.";
- } else if ( /file/.test( location.protocol ) ) {
- throw "This must be run from a web server.";
- }
+ setTimeout( volumeupdate, 250 );
+ };
+
+ media.play = function() {
+
+ media.paused = false;
+ media.dispatchEvent( "play" );
- options = options || {};
+ media.dispatchEvent( "playing" );
+ timeupdate();
+ youtubeObject.playVideo();
+ };
- var self = this;
+ media.pause = function() {
- this.playerId = elementId + Popcorn.guid();
- this.readyState = READY_STATE_HAVE_NOTHING;
- this._eventListeners = {};
- this.loadStarted = false;
- this.loadedData = false;
- this.fullyLoaded = false;
- this.paused = false;
+ if ( !media.paused ) {
- // If supplied as number, append 'px' on end
- // If suppliied as '###' or '###px', convert to number and append 'px' back on end
- options.width = options.width && (+options.width)+"px";
- options.height = options.height && (+options.height)+"px";
+ media.paused = true;
+ media.dispatchEvent( "pause" );
+ youtubeObject.pauseVideo();
+ }
+ };
- // show controls on video. Integer value - 1 is for show, 0 is for hide
- this.controls = +options.controls === 0 || +options.controls === 1 ? options.controls : 1;
+ Popcorn.player.defineProperty( media, "currentTime", {
+ set: function( val ) {
- // show video annotations, 1 is show, 3 is hide
- this.iv_load_policy = +options.annotations === 1 || +options.annotations === 3 ? options.annotations : 1;
+ // make sure val is a number
+ currentTime = seekTime = +val;
+ seeking = true;
+ media.dispatchEvent( "seeked" );
+ media.dispatchEvent( "timeupdate" );
+ youtubeObject.seekTo( currentTime );
+ return currentTime;
+ },
+ get: function() {
- this._target = document.getElementById( elementId );
- this._container = document.createElement( "div" );
- this._container.id = this.playerId;
- this._container.style.height = this._target.style.height = options.height || this._target.style.height || "350px";
- this._container.style.width = this._target.style.width = options.width || this._target.style.width || "460px";
- this._target.appendChild( this._container );
- this.parentNode = this._target.parentNode;
+ return currentTime;
+ }
+ });
- this.offsetHeight = +this._target.offsetHeight;
- this.offsetWidth = +this._target.offsetWidth;
+ Popcorn.player.defineProperty( media, "muted", {
+ set: function( val ) {
- this.currentTime = this.previousCurrentTime = 0;
- this.volume = this.previousVolume = this.preMuteVol = 1;
- this.duration = 0;
+ if ( youtubeObject.isMuted() !== val ) {
- this.vidId = extractIdFromUrl( url ) || extractIdFromUri( url );
+ if ( val ) {
- if ( !this.vidId ) {
- throw "Could not find video id";
- }
+ youtubeObject.mute();
+ } else {
- this.addEventListener( "load", function() {
- // For calculating position relative to video (like subtitles)
- this.offsetWidth = this.video.offsetWidth;
- this.offsetHeight = this.video.offsetHeight;
- this.offsetParent = this.video.offsetParent;
+ youtubeObject.unMute();
+ }
- // Set up stuff that requires the API to be loaded
- this.registerYoutubeEventHandlers();
- this.registerInternalEventHandlers();
- });
+ lastMuted = youtubeObject.isMuted();
+ media.dispatchEvent( "volumechange" );
+ }
- (function() {
- var hasBeenCalled = 0;
+ return youtubeObject.isMuted();
+ },
+ get: function() {
- self.addEventListener( "playing", function() {
- if (hasBeenCalled) {
- return;
- }
+ return youtubeObject.isMuted();
+ }
+ });
- hasBeenCalled = 1;
- self.duration = self.video.getDuration();
- self.dispatchEvent( "durationchange" );
+ Popcorn.player.defineProperty( media, "volume", {
+ set: function( val ) {
- });
- })();
+ if ( youtubeObject.getVolume() !== val ) {
- if ( loadedPlayers[this.playerId] ) {
- this.video = registry[this.playerId].video;
+ youtubeObject.setVolume( val );
+ lastVolume = youtubeObject.getVolume();
+ media.dispatchEvent( "volumechange" );
+ }
- this.vidId = this.vidId || extractIdFromUrl( this._container.getAttribute( "src" ) ) || extractIdFromUri( this._container.getAttribute( "src" ) );
+ return youtubeObject.getVolume();
+ },
+ get: function() {
- if (this.vidId !== registry[this.playerId].vidId ) {
- this.video.cueVideoById( this.vidId );
- } else {
- // Same video, new ctor. Force a seek to the beginning
- this.previousCurrentTime = 1;
- }
+ return youtubeObject.getVolume();
+ }
+ });
- this.dispatchEvent( 'load' );
- } else if ( this._container ) {
- makeSWF.call( this, url, this._container );
- } else {
- // Container not yet loaded, get it on DOMDontentLoad
- document.addEventListener( "DOMContentLoaded", function() {
- self._container = document.getElementById( elementId );
+ media.readyState = 4;
+ media.dispatchEvent( "load" );
+ media.duration = youtubeObject.getDuration();
+ media.dispatchEvent( "durationchange" );
+ volumeupdate();
- if ( !self._container ) {
- throw "Could not find container!";
- }
+ media.dispatchEvent( "loadeddata" );
+ };
- makeSWF.call( self, url, self._container );
- }, false);
- }
+ options.controls = +options.controls === 0 || +options.controls === 1 ? options.controls : 1;
+ options.annotations = +options.annotations === 1 || +options.annotations === 3 ? options.annotations : 1;
- registry[this.playerId] = this;
- };
- // end Popcorn.youtube.init
-
- Popcorn.extend( Popcorn.youtube.init.prototype, {
-
- // For internal use only.
- // Register handlers to YouTube events.
- registerYoutubeEventHandlers: function() {
- var youcorn = this,
- stateChangeHandler = 'Popcorn.youtube.stateChangeEventHandler',
- errorHandler = 'Popcorn.youtube.errorEventHandler';
-
- this.video.addEventListener( 'onStateChange', stateChangeHandler );
- this.video.addEventListener( 'onError', errorHandler );
-
- /**
- * Since Flash can only call named functions, they are declared
- * separately here.
- */
- Popcorn.youtube.stateChangeEventHandler = function( state ) {
- // In case ctor has been called many times for many ctors
- // Only use latest ctor call for each player id
- var self = registry[youcorn.playerId];
-
- if ( state === YOUTUBE_STATE_UNSTARTED ) {
- self.readyState = READY_STATE_HAVE_METADATA;
- self.dispatchEvent( 'loadedmetadata' );
- } else if ( state === YOUTUBE_STATE_ENDED ) {
- self.dispatchEvent( 'ended' );
- } else if ( state === YOUTUBE_STATE_PLAYING ) {
- // Being able to play means current data is loaded.
- if ( !this.loadedData ) {
- this.loadedData = true;
- self.dispatchEvent( 'loadeddata' );
- }
+ flashvars = {
+ playerapiid: container.id,
+ controls: options.controls,
+ iv_load_policy: options.annotations
+ };
- self.readyState = READY_STATE_HAVE_CURRENT_DATA;
- self.dispatchEvent( 'playing' );
- } else if ( state === YOUTUBE_STATE_PAUSED ) {
- self.dispatchEvent( 'pause' );
- } else if ( state === YOUTUBE_STATE_BUFFERING ) {
- self.dispatchEvent( 'waiting' );
- } else if ( state === YOUTUBE_STATE_CUED ) {
- // not handled
- Popcorn.nop();
- }
+ params = {
+ wmode: "transparent",
+ allowScriptAccess: "always"
};
- Popcorn.youtube.errorEventHandler = function( state ) {
- youcorn.dispatchEvent( 'error' );
+ attributes = {
+ id: container.id
};
- },
-
- // For internal use only.
- // Start current time and loading progress syncing intervals.
- registerInternalEventHandlers: function() {
- this.addEventListener( 'playing', function() {
- this.startTimeUpdater();
- });
- this.addEventListener( 'loadedmetadata', function() {
- this.startProgressUpdater();
- });
- },
-
- play: function() {
- // In case called before video is loaded, defer acting
- if ( !loadedPlayers[this.playerId] ) {
- this.addEventListener( "load", function() {
- this.play();
- });
- return;
- }
-
- this.dispatchEvent( 'play' );
- this.video.playVideo();
- },
-
- pause: function() {
- // In case called before video is loaded, defer acting
- if ( !loadedPlayers[this.playerId] ) {
- this.addEventListener( "load", this.pause );
- return;
- }
-
- this.video.pauseVideo();
- // pause event is raised by Youtube.
- },
-
- load: function() {
- // In case called before video is loaded, defer acting
- if ( !loadedPlayers[this.playerId] ) {
- this.addEventListener( "load", function() {
- this.load();
- });
- return;
- }
-
- this.video.playVideo();
- this.video.pauseVideo();
- },
-
- seekTo: function( time ) {
- var playing = this.video.getPlayerState() == YOUTUBE_STATE_PLAYING;
- this.video.seekTo( time, true );
-
- // Prevent Youtube's behaviour to start playing video after seeking.
- if ( !playing ) {
- this.video.paused = true;
- this.video.pauseVideo();
- } else {
- this.video.paused = false;
- }
-
- // Data need to be loaded again.
- if ( !this.fullyLoaded ) {
- this.loadedData = false;
- }
-
- // Raise event.
- this.dispatchEvent( 'seeked' );
- },
-
- // Mute is toggleable
- mute: function() {
- // In case called before video is loaded, defer acting
- if ( !loadedPlayers[this.playerId] ) {
- this.addEventListener( "load", this.mute );
- return;
- }
-
- if ( this.volume !== 0 ) {
- this.preMuteVol = this.volume;
- this.setVolume( 0 );
- } else {
- this.setVolume( this.preMuteVol );
- }
- },
-
- // Expects beteween 0 and 1
- setVolume: function( vol ) {
- this.volume = this.previousVolume = vol;
- this.video.setVolume( vol * 100 );
- this.dispatchEvent( 'volumechange' );
- },
-
- addEventListener: function( evt, func ) {
- var evtName = evt.type || evt;
-
- if ( !this._eventListeners[evtName] ) {
- this._eventListeners[evtName] = [];
- }
-
- this._eventListeners[evtName].push( func );
- },
-
- /**
- * Notify event listeners about an event.
- */
- dispatchEvent: function( name ) {
- var evtName = name.type || name;
- if ( !this._eventListeners[evtName] ) {
- return;
- }
-
- var self = this;
-
- Popcorn.forEach( this._eventListeners[evtName], function( evt ) {
- evt.call( self, null );
- });
- },
-
- /* Unsupported methods. */
-
- defaultPlaybackRate: function( arg ) {
- },
-
- playbackRate: function( arg ) {
- },
-
- getBoundingClientRect: function() {
- var b,
- self = this;
-
- if ( this.video ) {
- b = this.video.getBoundingClientRect();
-
- return {
- bottom: b.bottom,
- left: b.left,
- right: b.right,
- top: b.top,
-
- // These not guaranteed to be in there
- width: b.width || ( b.right - b.left ),
- height: b.height || ( b.bottom - b.top )
- };
- } else {
- b = self._container.getBoundingClientRect();
-
- // Update bottom, right for expected values once the container loads
- return {
- left: b.left,
- top: b.top,
- width: self._target.offsetWidth,
- height: self._target.offsetHeight,
- bottom: b.top + self._target.offsetWidth,
- right: b.left + self._target.offsetHeight
- };
- }
- },
-
- startTimeUpdater: function() {
- var state = typeof this.video.getPlayerState != "function" ? this.readyState : this.video.getPlayerState(),
- self = this,
- seeked = 0;
-
- if ( abs( this.currentTime - this.previousCurrentTime ) > timeCheckInterval ) {
- // Has programatically set the currentTime
- this.previousCurrentTime = this.currentTime - timeCheckInterval;
- this.seekTo( this.currentTime );
- seeked = 1;
- } else {
- this.previousCurrentTime = this.currentTime;
- this.currentTime = typeof this.video.getCurrentTime != "function" ? this.currentTime : this.video.getCurrentTime();
- }
-
- if ( this.volume !== this.previousVolume ) {
- this.setVolume( this.volume );
- }
-
- if ( state !== YOUTUBE_STATE_ENDED && state !== YOUTUBE_STATE_PAUSED || seeked ) {
- this.dispatchEvent( 'timeupdate' );
- }
-
- if( state !== YOUTUBE_STATE_ENDED ) {
- setTimeout( function() {
- self.startTimeUpdater.call(self);
- }, timeupdateInterval);
- }
- },
-
- startProgressUpdater: function() {
- var bytesLoaded = this.video.getVideoBytesLoaded(),
- bytesToLoad = this.video.getVideoBytesTotal(),
- self = this;
-
- // do nothing if size is not yet determined
- if ( bytesToLoad === 0 ) {
- return;
- }
-
- // raise an event if load has just started
- if ( !this.loadStarted ) {
- this.loadStarted = true;
- this.dispatchEvent( 'loadstart' );
- }
-
- // fully loaded
- if ( bytesLoaded >= bytesToLoad ) {
- this.fullyLoaded = true;
- this.readyState = READY_STATE_HAVE_ENOUGH_DATA;
- this.dispatchEvent( 'canplaythrough' );
- return;
- }
-
- this.dispatchEvent( 'progress' );
-
- setTimeout( function() {
- self.startProgressUpdater.call( self );
- }, progressInterval);
+
+ src = /^.*[\/=](.{11})/.exec( media.src )[ 1 ];
+
+ swfobject.embedSWF( "http://www.youtube.com/e/" + src + "?enablejsapi=1&playerapiid=" + container.id + "&version=3",
+ container.id, media.offsetWidth, media.offsetHeight, "8", null,
+ flashvars, params, attributes );
+ };
+
+ if ( !window.swfobject ) {
+
+ Popcorn.getScript( "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js", youtubeInit );
+ } else {
+
+ youtubeInit();
}
- }); // end Popcorn.extend
-
- /* Unsupported properties and events. */
-
- /**
- * Unsupported events are:
- * * suspend
- * * abort
- * * emptied
- * * stalled
- * * canplay
- * * seeking
- * * ratechange
- */
-
-})( Popcorn );
+ }
+});
View
493 players/youtube/popcorn.youtube.unit.js
@@ -1,189 +1,323 @@
-test( "Popcorn YouTube Plugin Event Tests", function() {
-
- function plus(){
- if ( ++count == expects ) {
- start();
+test("Update Timer", function () {
+
+ QUnit.reset();
+
+ var p2 = Popcorn.youtube( '#video2', 'http://www.youtube.com/watch?v=9oar9glUCL0' ),
+ expects = 12,
+ count = 0,
+ execCount = 0,
+ // These make sure events are only fired once
+ // any second call will produce a failed test
+ forwardStart = false,
+ forwardEnd = false,
+ backwardStart = false,
+ backwardEnd = false,
+ wrapperRunning = { one: false, two: false, };
+
+ function plus() {
+ if ( ++count === expects ) {
+ // clean up added events after tests
+ Popcorn.removePlugin( "forwards" );
+ Popcorn.removePlugin( "backwards" );
+ Popcorn.removePlugin( "wrapper" );
+ p2.removePlugin( "exec" );
+ start();
}
}
-
- QUnit.reset();
-
- // events must be fired in this order
- var expectedEvents = [
- 'play',
- 'loadeddata',
- 'playing',
- 'volumechange',
- 'pause',
- 'play',
- 'playing',
- 'seeked',
- 'volumechange',
- 'volumechange',
- 'playing',
- 'pause',
- 'ended'
- ];
-
- var popcorn = Popcorn( Popcorn.youtube( 'video', "http://www.youtube.com/e/ac7KhViaVqc" ) ),
- count = 0,
- eventCount = 0,
- added = [],
- set1Executed = false,
- set2Executed = false,
- set3Executed = false,
- expects = expectedEvents.length + 6,
- listeners = [];
-
- stop( 15000 );
- expect(expects);
-
- popcorn.volume(1); // is muted later
-
- // check time sync
- popcorn.exec(2, function() {
- ok( popcorn.currentTime() >= 2, "Check time synchronization." );
- plus();
- ok( popcorn.video.paused == false, "Video is not paused" );
- plus();
- });
- popcorn.exec(49, function() {
- ok( popcorn.currentTime() >= 49, "Check time synchronization." );
- plus();
+
+ // These tests come close to 10 seconds on chrome, increasing to 15
+ stop();
+
+ Popcorn.plugin( "forwards", function () {
+ return {
+ start: function ( event, options ) {
+
+ if ( !options.startFired ) {
+
+ options.startFired = true;
+ forwardStart = !forwardStart;
+ ok( forwardStart, "forward's start fired" );
+ plus();
+ }
+ },
+ end: function ( event, options ) {
+
+ if ( !options.endFired ) {
+
+ options.endFired = true;
+ forwardEnd = !forwardEnd;
+ p2.currentTime(1).play();
+ ok( forwardEnd, "forward's end fired" );
+ plus();
+ }
+ }
+ };
});
- popcorn.exec(40, function() {
- ok( false, "This should not be run." );
+
+ p2.forwards({
+ start: 3,
+ end: 4
});
-
- // register each events
- for ( var i in expectedEvents ) {
- (function( event ) {
- // skip same listeners already added
- for ( var i in added ) {
- if ( added[i] == event ) {
- return;
+ Popcorn.plugin( "backwards", function () {