diff --git a/gin/favicon/favicon.ico b/gin/favicon/favicon.ico new file mode 100755 index 0000000..66b657b Binary files /dev/null and b/gin/favicon/favicon.ico differ diff --git a/gin/gin b/gin/gin new file mode 100755 index 0000000..c5dacc3 Binary files /dev/null and b/gin/gin differ diff --git a/gin/gin.go b/gin/gin.go new file mode 100755 index 0000000..9cc6986 --- /dev/null +++ b/gin/gin.go @@ -0,0 +1,21 @@ +package main + +import ( + "github.com/gin-gonic/gin" + "net/http" +) + +func main() { + router := gin.Default() + + router.LoadHTMLFiles("index.html") + router.StaticFS("/strobe", http.Dir("./strobe")) + router.StaticFS("/favicon.ico", http.Dir("./favicon")) + router.GET("/", func(c *gin.Context) { + c.HTML(http.StatusOK, "index.html", gin.H{ + }) + }) + + + router.Run("192.168.0.107:8080") +} diff --git a/gin/index.html b/gin/index.html new file mode 100755 index 0000000..8795afc --- /dev/null +++ b/gin/index.html @@ -0,0 +1,43 @@ + + + + Live Streaming + + + + + + + +
+ + diff --git a/gin/strobe/AdvertisementPlugin.swf b/gin/strobe/AdvertisementPlugin.swf new file mode 100755 index 0000000..85bc6bf Binary files /dev/null and b/gin/strobe/AdvertisementPlugin.swf differ diff --git a/gin/strobe/GTrackPlugin.swf b/gin/strobe/GTrackPlugin.swf new file mode 100755 index 0000000..941eb4b Binary files /dev/null and b/gin/strobe/GTrackPlugin.swf differ diff --git a/gin/strobe/MASTPlugin.swf b/gin/strobe/MASTPlugin.swf new file mode 100755 index 0000000..a90a4c4 Binary files /dev/null and b/gin/strobe/MASTPlugin.swf differ diff --git a/gin/strobe/OSMF.swc b/gin/strobe/OSMF.swc new file mode 100755 index 0000000..fd387de Binary files /dev/null and b/gin/strobe/OSMF.swc differ diff --git a/gin/strobe/SMILPlugin.swf b/gin/strobe/SMILPlugin.swf new file mode 100755 index 0000000..5d90225 Binary files /dev/null and b/gin/strobe/SMILPlugin.swf differ diff --git a/gin/strobe/StrobeMediaPlayback.html b/gin/strobe/StrobeMediaPlayback.html new file mode 100755 index 0000000..d6eeb5f --- /dev/null +++ b/gin/strobe/StrobeMediaPlayback.html @@ -0,0 +1,143 @@ + + + + Strobe Media Playback + + + + + + + + + + + + + + +
+ + + Strobe Media Playback + + osmf logo + +
+ + + + + + + +
+
+

+ Alternative content +

+
+
+

+ Click on one of the links below to have it loaded +

+

+ +

+
+ Player Setup + + diff --git a/gin/strobe/StrobeMediaPlayback.swf b/gin/strobe/StrobeMediaPlayback.swf new file mode 100755 index 0000000..cba5891 Binary files /dev/null and b/gin/strobe/StrobeMediaPlayback.swf differ diff --git a/gin/strobe/YouTubePlugin.swf b/gin/strobe/YouTubePlugin.swf new file mode 100755 index 0000000..9159aa6 Binary files /dev/null and b/gin/strobe/YouTubePlugin.swf differ diff --git a/gin/strobe/advertisement-demo.html b/gin/strobe/advertisement-demo.html new file mode 100755 index 0000000..3d0ca18 --- /dev/null +++ b/gin/strobe/advertisement-demo.html @@ -0,0 +1,286 @@ + + + + + Advertisement Demo + + + + + + + +

OSMF Reference Plug-in Demo for Advertisements

+

+ This reference plug-in makes it easy to add simple advertisement experiences to an OSMF-based video player. +

+

+ It provides sample code for both linear and non-linear ad insertions, and it can serve as a starting point for plug-ins that are required to integrate with advertisement backends. +

+
+
+ Alternative content +
+
+
+

Interactive Ad Controls

+ Display a non-liniar advertisement (overlay ad) +
+ Play a linear advertisement (mid-roll ad) +
+
+
+

Sample Composition Scenarios

+ Enable Stage Video (the changed value will be used only after selecting a new scenario) +
+ Pre-roll, mid-roll, overlay, post-roll +
+ + ST-397 - GPU Decoding issue on stagevideo: Win7, Flash Player version WIN 10,2,152,26 (debug) +
+ FIXED! - ST-398 - Crash when playing HDS content in an advertisement scenario (pre roll) +
+ ST-399 - StageVideo Crash when removing the video content from the Stage before going into full screen and adding it back once the full screen transition has finished +
+ RTMP Dynamic Streaming +
+ HDS Picture in Picture +
+
+
+
+

Demo Outline

+

+ You can select from a set of predefined advertisement scenarios and you can insert either linear or overlay ads using the provided interactive controls. +

+

+ All the advertisements except the pre-rolls are being pre-buffered, so you should experience seamless playback for mid-rolls. (post-rolls need to be pre-buffered as well, but pre-buffering for post-rolls is not implemented yet). +

+

+ Take a closer look at the Stage Video instance count which is being displayed in the info overlay (top-left corner). On desktops you should see 4 available StageVideo instances and you should see them being picked up as you add more overlay ads. +

+ +
+
+

Details

+

+ The Advertisement Reference plug-in is intended to to demonstrate best practices related to ad insertion in OSMF-based players. + +

+

+ The plug-in provides both a JavaScript based API as well as a very simple configuration API (flashvars) which can be used when embedding the player. +

+

+ You can view the source to learn about how the current configuration and JavaScript API work. +

+

FlashVars configuration

+

+ To activate the plug-in, you simply load the plug-in as normal, but add a reference to the swf: +

+

+        plugin_ads: "AdvertisementPlugin.swf"
+            
+ +

+ For setting the pre-roll, mid-roll and the post-roll ads, all you need is to add the paths to the ads and the time when the mid-roll ad or the overlay ad needs to be displayed. +

+

+ Note that this plug-in can be configured to load only one mid-roll ad and one overlay ad using the flashvars configuration. + Feel free to extend it as needed, or to use the JavaScript API described below. +

+
	
+		ads_preroll: "http://gcdn.2mdn.net/MotifFiles/html/1379578/PID_938961_1237818260000_women.flv",
+		ads_postroll: "http://gcdn.2mdn.net/MotifFiles/html/1379578/PID_938961_1237818260000_women.flv",
+		ads_midroll: "http://gcdn.2mdn.net/MotifFiles/html/1379578/PID_938961_1237818260000_women.flv",
+		ads_midrollTime: 20,
+		ads_overlay: "http://gcdn.2mdn.net/MotifFiles/html/1379578/PID_938961_1237818260000_women.flv",
+		ads_overlayTime: 25
+			
+

+

The JavaScript API

+

+ For using the JavaScript API exposed by the plugin you need to get the reference to the StrobeMediaPlayback instance and simply interact with the plugin. +

+

+ The following snippet will insert an overlay ad, at some random position. +

+
	
+		player.strobeMediaPlayback.displayNonLiniarAd (
+			"http://gcdn.2mdn.net/MotifFiles/html/1379578/PID_938961_1237818260000_women.flv", {
+				right: options.width/2 * Math.random(),
+				bottom: options.height/2 * Math.random(),
+				scaleMode: "none"});
+			
+

+ The following snippet will interrupt the current media playback and will play a linear ad instead: +

+
	
+		player.strobeMediaPlayback.displayLiniarAd("http://gcdn.2mdn.net/MotifFiles/html/1379578/PID_938961_1237818260000_women.flv");
+			
+ +
+
+

Known Limitations

+
    +
  1. + Strobe Media Playback needs to disable the scrubBar while the linear ads are being played back. (not implemented yet) +
  2. +
  3. + Strobe Media Playback needs to display a widget during linear ad playback. This can be something like this: "Advertisement. Video will resume in 10 seconds..." +
  4. +
  5. + The plugin does not handle the ordering (depth) of the advertisements at this point. While using the plugin you should be aware that the advertisement that + is added last will be added on top of the other medias/ads that are being currently played. +
  6. +
  7. + With the current implementation of this plug-in, it should be pretty simple to create any kind of interactive ads you can imagine. This is just a start. +
  8. +
+
+ + diff --git a/gin/strobe/configuration.xml b/gin/strobe/configuration.xml new file mode 100755 index 0000000..3bc9251 --- /dev/null +++ b/gin/strobe/configuration.xml @@ -0,0 +1,45 @@ + + http://mysite.com/my.flv + + + + + + + + + + + + + + + + + ConfigurationEchoPlugin1.swf + + + + + + + + + + + + + + ConfigurationEchoPlugin2.swf + + + + + + + + + + + + \ No newline at end of file diff --git a/gin/strobe/debug-mobile.html b/gin/strobe/debug-mobile.html new file mode 100755 index 0000000..3c6e46c --- /dev/null +++ b/gin/strobe/debug-mobile.html @@ -0,0 +1,291 @@ + + + + Strobe Media Playback + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+
+

+ Alternative content +

+
+
+ + +

logs (the last 50 lines). New logs will be displayed if they match: +

+
+
+
+
+ +
+ Press F11 to make the browser window enter/exit full screen. +
+
+ + + + + + + + + + + + + + + + + +
+ + +
+ Key Statistics +
+
+ + +
+ Rendering Info +
+
+ + +
+ Dynamic Streaming Info +
+
+ + +
+ Buffer Info +
+
+ + +
+ PlaybackOptimizationMetrics +
+ + +
+ StrobeMediaPlayer +
+
+ + +
+ NetStream +
+ + +
+ NetStreamInfo +
+
+ + + + +
+ Resource Metadata +
+
+
+
+ + diff --git a/gin/strobe/debug.html b/gin/strobe/debug.html new file mode 100755 index 0000000..b9da02f --- /dev/null +++ b/gin/strobe/debug.html @@ -0,0 +1,279 @@ + + + + Strobe Media Playback + + + + + + + + + + + + + +
+ + + + + + + +
+
+

+ Alternative content +

+
+
+ + +

logs (the last 50 lines). New logs will be displayed if they match: +

+
+
+
+
+ +
+ Press F11 to make the browser window enter/exit full screen. +
+
+ + + + + + + + + + + + + + + + + +
+ + +
+ Key Statistics +
+
+ + +
+ Rendering Info +
+
+ + +
+ Dynamic Streaming Info +
+
+ + +
+ Buffer Info +
+
+ + +
+ PlaybackOptimizationMetrics +
+ + +
+ StrobeMediaPlayer +
+
+ + +
+ NetStream +
+ + +
+ NetStreamInfo +
+
+ + + + +
+ Resource Metadata +
+
+
+
+ + diff --git a/gin/strobe/embed-samples.html b/gin/strobe/embed-samples.html new file mode 100755 index 0000000..299ce33 --- /dev/null +++ b/gin/strobe/embed-samples.html @@ -0,0 +1,64 @@ + + + + + Flash/Strobe Media Playback - iframe embed sample + + +

Strobe Media Playback for Flash and HTML5 <video>

+

<iframe> embed code

+

The simplest embed strategy is using iframes. This is likely to become a standard across major video sites.

+

Sample embed code

+
	
+        <:iframe src="embed.html?
+			src=http://players.edgesuite.net/videos/big_buck_bunny/bbb_448x252.mp4" 
+			class="strobemediaplayback-video-player" type="text/html" 
+			width="833" 
+			height="641">
+        <:/iframe>			
+		
+

Live Demos

+ Basic embed code sample +
+ +
+

jQuery plugin

+

As a web designer, you might want to use our jQuery plugin instead of the iframe. Like this you have complete control over the video playback and the experience arround the player.

+

Using the jQuery snippet also saves a HTTP request, so if you have control over the pages where the video is hosted this approach is much better.

+

Sample embed code

+
        	
+            <div id="strobemediaplayback" style="width:640px; height:480px"></div>
+			<script type="text/javascript" src="lib/swfobject.js"></script>
+            <script type="text/javascript" src="lib/jquery/jquery-1.4.2.js"></script>
+            <script type="text/javascript" src="jquery.strobemediaplayback.js"></script>
+            
+            <script type="text/javascript">
+            $(function(){
+                var options = {
+                    src: "http://players.edgesuite.net/videos/big_buck_bunny/bbb_448x252.mp4",
+                    width: 640,
+                    height: 480
+                };
+                // Now we are ready to generate the video tags
+                $("#strobemediaplayback").strobemediaplayback(options);
+            });
+            </script>		
+		
+

Live Demos

+ jQuery basic sample +
+ jQuery basic sample - favor HTML5 <video> playback - embed.html?favorFlashOverHtml5Video=false +
+

Custom Chrome

+

Instead of using the default browser chrome it is possible to use a custom control bar. Like this you have full control over the playback controls look and feel.

+ + +

Live Demos

+ Favor Flash over HTML5 video (default) +
+ Favor Html5 video over Flash +
+ + + + diff --git a/gin/strobe/embed.html b/gin/strobe/embed.html new file mode 100755 index 0000000..1285e88 --- /dev/null +++ b/gin/strobe/embed.html @@ -0,0 +1,58 @@ + + + + + Flash/Strobe Media Playback + + + + + + + + + + + + +
Alternative content
+ + diff --git a/gin/strobe/expressInstall.swf b/gin/strobe/expressInstall.swf new file mode 100755 index 0000000..0fbf8fc Binary files /dev/null and b/gin/strobe/expressInstall.swf differ diff --git a/gin/strobe/hello-world-javascript.html b/gin/strobe/hello-world-javascript.html new file mode 100755 index 0000000..fa2fae9 --- /dev/null +++ b/gin/strobe/hello-world-javascript.html @@ -0,0 +1,75 @@ + + + + Strobe Media Playback + + + + +
+
+ ... : ... +
+ Play/Pause
+ +
+

Alternative content

+
+ + \ No newline at end of file diff --git a/gin/strobe/hello-world-jquery-plugin.html b/gin/strobe/hello-world-jquery-plugin.html new file mode 100755 index 0000000..e5b5145 --- /dev/null +++ b/gin/strobe/hello-world-jquery-plugin.html @@ -0,0 +1,140 @@ + + + + + Flash/Strobe Media Playback + + + + + + + + + + + +
Alternative content
+ + +
+
+ ... : ... +
+
Play/Pause
+ +
+ OSMF SD +
+ OSMF HD +
+ SMP SD +
+ SMP HD +
+ http://media.w3.org/2010/05/sintel/trailer.mp4 +
+ http://players.edgesuite.net/videos/big_buck_bunny/bbb_448x252.mp4 +

OGG files, for Firefox HTML5 only

+ http://media.w3.org/2010/05/sintel/trailer.ogv +
+ http://players.edgesuite.net/videos/big_buck_bunny/bbb_448x252.ogg +
+
+ + diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_Background.PNG b/gin/strobe/html5-images/SMP_Tablet_InCon_Background.PNG new file mode 100755 index 0000000..36e475b Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_Background.PNG differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Disabled.png b/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Disabled.png new file mode 100755 index 0000000..52a96ba Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Disabled.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Norm.png b/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Norm.png new file mode 100755 index 0000000..375f76c Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Norm.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Over.png b/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Over.png new file mode 100755 index 0000000..5d66805 Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_FULLS_Over.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_PAUSE_Norm.png b/gin/strobe/html5-images/SMP_Tablet_InCon_PAUSE_Norm.png new file mode 100755 index 0000000..e73c727 Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_PAUSE_Norm.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_PAUSE_Over.png b/gin/strobe/html5-images/SMP_Tablet_InCon_PAUSE_Over.png new file mode 100755 index 0000000..1d2a33a Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_PAUSE_Over.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_PLAY_Norm.png b/gin/strobe/html5-images/SMP_Tablet_InCon_PLAY_Norm.png new file mode 100755 index 0000000..d5d1efd Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_PLAY_Norm.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_PLAY_Over.png b/gin/strobe/html5-images/SMP_Tablet_InCon_PLAY_Over.png new file mode 100755 index 0000000..8210bdd Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_PLAY_Over.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubBack.png b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubBack.png new file mode 100755 index 0000000..0cf817e Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubBack.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubLoad.png b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubLoad.png new file mode 100755 index 0000000..a039c2c Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubLoad.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubPlyd.png b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubPlyd.png new file mode 100755 index 0000000..5e59f37 Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubPlyd.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubSrch.png b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubSrch.png new file mode 100755 index 0000000..a4a8b60 Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubSrch.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubTab_N.png b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubTab_N.png new file mode 100755 index 0000000..17a3a4e Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubTab_N.png differ diff --git a/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubTab_O.png b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubTab_O.png new file mode 100755 index 0000000..b2a1461 Binary files /dev/null and b/gin/strobe/html5-images/SMP_Tablet_InCon_ScrubTab_O.png differ diff --git a/gin/strobe/images/adobe-lq.png b/gin/strobe/images/adobe-lq.png new file mode 100755 index 0000000..bbc5549 Binary files /dev/null and b/gin/strobe/images/adobe-lq.png differ diff --git a/gin/strobe/images/dynstream.png b/gin/strobe/images/dynstream.png new file mode 100755 index 0000000..e04b2d2 Binary files /dev/null and b/gin/strobe/images/dynstream.png differ diff --git a/gin/strobe/images/music.jpg b/gin/strobe/images/music.jpg new file mode 100755 index 0000000..7f37f0d Binary files /dev/null and b/gin/strobe/images/music.jpg differ diff --git a/gin/strobe/images/osmf_horizontal_red.png b/gin/strobe/images/osmf_horizontal_red.png new file mode 100755 index 0000000..8dd78d7 Binary files /dev/null and b/gin/strobe/images/osmf_horizontal_red.png differ diff --git a/gin/strobe/images/playlist.jpg b/gin/strobe/images/playlist.jpg new file mode 100755 index 0000000..004ac5e Binary files /dev/null and b/gin/strobe/images/playlist.jpg differ diff --git a/gin/strobe/images/poster.png b/gin/strobe/images/poster.png new file mode 100755 index 0000000..0b6b22a Binary files /dev/null and b/gin/strobe/images/poster.png differ diff --git a/gin/strobe/images/poster1.png b/gin/strobe/images/poster1.png new file mode 100755 index 0000000..0fb36de Binary files /dev/null and b/gin/strobe/images/poster1.png differ diff --git a/gin/strobe/images/poster2.jpg b/gin/strobe/images/poster2.jpg new file mode 100755 index 0000000..46834db Binary files /dev/null and b/gin/strobe/images/poster2.jpg differ diff --git a/gin/strobe/images/progressive.png b/gin/strobe/images/progressive.png new file mode 100755 index 0000000..0e49359 Binary files /dev/null and b/gin/strobe/images/progressive.png differ diff --git a/gin/strobe/images/thumb1.jpg b/gin/strobe/images/thumb1.jpg new file mode 100755 index 0000000..985eeaf Binary files /dev/null and b/gin/strobe/images/thumb1.jpg differ diff --git a/gin/strobe/images/thumb2.jpg b/gin/strobe/images/thumb2.jpg new file mode 100755 index 0000000..4c5914c Binary files /dev/null and b/gin/strobe/images/thumb2.jpg differ diff --git a/gin/strobe/images/tooth.png b/gin/strobe/images/tooth.png new file mode 100755 index 0000000..029c6f8 Binary files /dev/null and b/gin/strobe/images/tooth.png differ diff --git a/gin/strobe/images/vegetation.jpg b/gin/strobe/images/vegetation.jpg new file mode 100755 index 0000000..09432e5 Binary files /dev/null and b/gin/strobe/images/vegetation.jpg differ diff --git a/gin/strobe/jquery-custom-chrome.html b/gin/strobe/jquery-custom-chrome.html new file mode 100755 index 0000000..c039a33 --- /dev/null +++ b/gin/strobe/jquery-custom-chrome.html @@ -0,0 +1,162 @@ + + + + + Flash/Strobe Media Playback + + + + + + + + + +
+
+
+
+ Alternative Content +
+ + +
+ +
+ +
+
+
+
+
+
+
+ + +
+ 0:00 / 0:00 +
+
+
+
+
+
+ ... +
+
+ ... +
+ +
+

MP4 files, for Chrome & Safari

+ http://osmf.org/dev/videos/cathy1_SD.mp4 +
+ http://osmf.org/dev/videos/cathy1_HD.mp4 +
+ http://osmf.org/dev/videos/cathy2_SD.mp4 +
+ http://osmf.org/dev/videos/cathy2_HD.mp4 +
+ http://media.w3.org/2010/05/sintel/trailer.mp4 +
+ http://players.edgesuite.net/videos/big_buck_bunny/bbb_448x252.mp4 +

OGG files, for Firefox HTML5 only

+ http://media.w3.org/2010/05/sintel/trailer.ogv +
+ http://players.edgesuite.net/videos/big_buck_bunny/bbb_448x252.ogg +
+ diff --git a/gin/strobe/jquery-embed-sample.html b/gin/strobe/jquery-embed-sample.html new file mode 100755 index 0000000..b499d28 --- /dev/null +++ b/gin/strobe/jquery-embed-sample.html @@ -0,0 +1,42 @@ + + + + + Flash/Strobe Media Playback + + + + + + + + + +
Alternative content
+ + diff --git a/gin/strobe/jquery.strobemediaplayback.css b/gin/strobe/jquery.strobemediaplayback.css new file mode 100755 index 0000000..ba276ef --- /dev/null +++ b/gin/strobe/jquery.strobemediaplayback.css @@ -0,0 +1,269 @@ +body { + background: #000000; +} + +.smp { + width: 24px; + height: 24px; + background: transparent url(jquery.strobemediaplayback.png) no-repeat; + display: block; +} + +.play { + background-position: 0 0; +} + +a.play:hover { + background-position: 0 -24px; +} + +a.play:active { + background-position: 0 -48px; +} + +.pause { + background-position: -24px 0; +} + +a.pause:hover { + background-position: -24px -24px; +} + +a.pause:active { + background-position: -24px -48px; +} + +.volume.low { + background-position: -24px -72px; +} + +a.volume.low:hover { + background-position: -24px -96px; +} + +a.volume.low:active { + background-position: -24px -120px; +} + +.volume.med { + background-position: -48px -72px; +} + +a.volume.med:hover { + background-position: -48px -96px; +} + +a.volume.med:active { + background-position: -48px -120px; +} + +.volume.high { + background-position: -72px -72px; +} + +a.volume.high:hover { + background-position: -72px -96px; +} + +a.volume.high:active { + background-position: -72px -120px; +} + +.volume.mute { + background-position: 0 -72px; +} + +a.volume.mute:hover { + background-position: 0 -96px; +} + +a.volume.mute:active { + background-position: 0 -120px; +} + +.fullscreen { + background-position: -48px -0px; +} + +a.fullscreen:hover { + background-position: -48px -24px; +} + +a.fullscreen:active { + background-position: -48px -48px; +} + +.fullscreen.on { + background-position: -72px -0px; +} + +a.fullscreen.on:hover { + background-position: -72px -24px; +} + +a.fullscreen.on:active { + background-position: -72px -48px; +} + +.playoverlay { + display:none; + z-index: 1001; + width: 116px; + height: 107px; + background: transparent url(jquery.strobemediaplayback.png) no-repeat; + background-position: -92px 0; +} + +a.playoverlay:hover, a.playoverlay:active { + background-position: -92px -107px; +} + +.strobeMediaPlaybackControlBar { + background-color: #000000; + color: #E8E8E8; + height: 30px; + opacity: 0.9; + position: absolute; + border: 1px solid #404040; + outline: 1px solid #101010; + outline-offset: 1px; + z-index: 1000; + /*bottom: 2px;*/ + width: 100%; + left: 2px; +} + +.smp { + position: absolute; + margin: 3px; + margin-top: 3.5px; + border: none; +} + +.time { + margin: 7px; + margin-top: 8px; + font-size: 11px; + border: none; +} + +.fullscreen { + right: 5px; +} + +.volume { + right: 5px; +} + +.time { + font-family: sans-serif; + position: absolute; + right: 55px; +} + +.play, .pause { + float: left; +} + +.smp-video { + border: none; +} + +#html5MediaPlayback { + position: relative; + width: 640px; + height: 362px; + top: 0px; + left: 0px; + background-color: #000000; +} + +.video-progress2 { + opacity: 1; + left: 40px; + display: block; + position: absolute; + padding: 0px; + margin: 0px; + height: 10px; + border: none; + margin-top: 12px; + +} + +.video-track { + margin-top: 0; + width: 100%; + border: 1px solid #404040; + outline: 1px solid #897048; + outline-offset: 1px; + background: #777777; + height: 4px; + display: block; + position: absolute; + z-index: 1; + padding-right: 9px; + overflow:hidden; +} + +.played { + display: block; + background-color: #00ADFC; + width: 0; + left: 0; + position: absolute; + z-index: 2; + height: inherit; +} + +.buffered { + display: block; + background-color: #557A8E; + width: 2px; + left: 0; + position: absolute; + z-index: 2; + height: inherit; + border-right: 1px solid #ffffff; +} +.buffered.done { + border: none; +} + +.slider { + display: block; + position: absolute; + width: 12px; + height: 12px; + left: 0; + z-index: 3; + margin: 0px; + border: 1px solid #000000; + outline: 1px solid #897048; + outline-offset: 1px; + background-color: #D6D6D6; + padding: 0 1px; + margin-top: -3.5px; + opacity: 1; +} + +a.slider:hover, a.slider:active { + /*border: 4px solid #000000;*/ + background-color: #E8E8E8; + -moz-box-shadow: 0px 0px 5px #ffffff; + -webkit-box-shadow: 0px 0px 5px #ffffff; + box-shadow: 0px 0px 5px #ffffff; + outline: none; +} + +.smp-error { + display:none; + position:absolute; + top:10%; + padding: 30px; +} + +.disabled { + opacity:0.4; + display:none; +} diff --git a/gin/strobe/jquery.strobemediaplayback.js b/gin/strobe/jquery.strobemediaplayback.js new file mode 100755 index 0000000..e835235 --- /dev/null +++ b/gin/strobe/jquery.strobemediaplayback.js @@ -0,0 +1,449 @@ +/***************************************************** +* +* Copyright 2010 Adobe Systems Incorporated. All Rights Reserved. +* +***************************************************** +* The contents of this file are subject to the Berkeley Software Distribution (BSD) Licence +* (the "License"); you may not use this file except in +* compliance with the License. +* +* Software distributed under the License is distributed on an "AS IS" +* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +* License for the specific language governing rights and limitations +* under the License. +* +* +* The Initial Developer of the Original Code is Adobe Systems Incorporated. +* Portions created by Adobe Systems Incorporated are Copyright (C) 2010 Adobe Systems +* Incorporated. All Rights Reserved. +* +*****************************************************/ + +/** + * jQuery plugin that generate the necessary video playback mark-up. + * @param {Object} /iPad/i + */ +(function($, undefined){ + + + /** + * Adapts the options of the video player based on the device/browser capabilities. + */ + var AdaptiveExperienceConfigurator = function(){ + }; + + var adaptiveExperienceConfiguratorMethods = { + + initialize: function(){ + this.userAgent = navigator.userAgent; + + this.isiPad = this.userAgent.match(/iPad/i) != null; + this.isiPhone = this.userAgent.match(/iPhone/i) != null; + this.isAndroid = this.userAgent.match(/Android/i) != null; + + this.screenWidth = screen.width; + this.screenHeight = screen.width; + this.isPhone = this.screenHeight < 360; + this.isTablet = this.screenHeight >= 360 && this.screenHeight <= 768; + this.isDesktop = this.screenHeight > 768; + + this.hasHTML5VideoCapability = !!document.createElement('video').canPlayType; + this.flashPlayerVersion = swfobject.getFlashPlayerVersion(); + this.hasFlashPlayerCapability = this.flashPlayerVersion.major >= 10; + }, + + adapt: function(options){ + + if (!this.userAgent) { + // Initialize lazily + this.initialize(); + } + + // First, extend with default values + options = $.extend({}, $.fn.strobemediaplayback.defaults, options); + this.changed = true; + var i = 0, n = this.rules.length; + while (this.changed) { + this.changed = false; + for (i = 0; i < n; i++) { + this.rules[i](this, options); + } + this.changed = false; + } + return options; + }, + + setOption: function(options, name, value){ + if (!options.hasOwnProperty(name) || options[name] != value) { + options[name] = value; + this.changed = true; + } + }, + + rules: [ + //playerImplementation + function(context, options){ + if (options.favorFlashOverHtml5Video && context.hasFlashPlayerCapability) { + context.setOption(options, "useHTML5", false); + } + else { + if (!options.favorFlashOverHtml5Video && context.hasHTML5VideoCapability) { + context.setOption(options, "useHTML5", true); + } + else { + if (options.favorFlashOverHtml5Video) { + context.setOption(options, "useHTML5", !context.hasFlashPlayerCapability); + } + else { + context.setOption(options, "useHTML5", context.hasHTML5VideoCapability); + } + } + } + }, + + //neverUseJavaScriptControlsOnIPhone: + function(context, options){ + if (context.isiPhone) { + context.setOption(options, "javascriptControls", false); + } + }, + + //hideVolumeControlOnIPad: + function(context, options){ + if (context.isiPad) { + context.setOption(options, "disabledControls", ".volume"); + } + }, + + // No Flash & No HTML5 Video + function(context, options){ + if (!context.hasFlashPlayerCapability && !context.hasHTML5VideoCapability) { + context.setOption(options, "javascriptControls", false); + context.setOption(options, "displayAlternativeContent", true); + } + } + ] + }; + + AdaptiveExperienceConfigurator.prototype = adaptiveExperienceConfiguratorMethods; + + $.fn.adaptiveexperienceconfigurator = new AdaptiveExperienceConfigurator(); + + var StrobeMediaPlayback = function(element, options){ + this.element = element; + this.$element = $(element); + this.options = $.extend({}, $.fn.strobemediaplayback.defaults, options); + }; + + // HACK: keeps the reference to the context of the function which uses swfobject + // - needed for the swfobject.js error callback handler. + var onFlashEmbedCompleteThisReference = null; + + var strobeMediaPlaybackMethods = { + initialize: function() { + // Detect video playback capabilities and adapt the settings + this.options = $.fn.adaptiveexperienceconfigurator.adapt(this.options); + + if (this.options.useHTML5) { + var $video = $(""); + $video.attr("id", this.options.id); + $video.attr("class", "smp_video"); + $video.attr("preload", "none"); + $video.attr("width", this.options.width); + $video.attr("height", this.options.height); + $video.attr("src", this.options.src); + + if (this.options.loop) + { + $video.attr("loop", "loop"); + } + if (this.options.autoPlay) + { + $video.attr("autoplay", "autoplay"); + } + if (this.options.controlBarMode != "none") + { + $video.attr("controls", "controls"); + } + if (this.options.poster != "") + { + $video.attr("poster", this.options.poster); + } + this.$element.replaceWith($video); + + this.$video = $video; + this.video = $video[0]; + } + else { + this.options.queryString = $.fn.strobemediaplayback.generateQueryString(this.options); + var flashvars = this.options; + flashvars.javascriptCallbackFunction = "$.fn.strobemediaplayback.triggerHandler"; + var params = { + allowFullScreen: "true", + wmode: "direct" + }; + var attributes = { + id: this.options.id, + name: this.options.id + }; + onFlashEmbedCompleteThisReference = this; + swfobject.embedSWF(this.options.swf, + this.$element.attr("id"), + this.options.width, + this.options.height, + this.options.minimumFlashPlayerVersion, + this.options.expressInstallSwfUrl, + flashvars, params, attributes, + this.onFlashEmbedComplete); + + this.monitor = new VideoElementMonitor(null); + + this.$video = this.monitor.$videoElement; + this.video = this.monitor.videoElement; + proxyMediaElements[this.options.id] = this.monitor; + } + }, + + onFlashEmbedComplete: function(event) + { + if (!event.success && $.fn.adaptiveexperienceconfigurator.hasHTML5VideoCapability) + { + onFlashEmbedCompleteThisReference.useHTML5 = true; + onFlashEmbedCompleteThisReference.initialize(); + } + else { + // TODO: Error notification - failed to embed the video -> fallback to displaying a link? + } + } + } + + StrobeMediaPlayback.prototype = strobeMediaPlaybackMethods; + + $.fn.strobemediaplayback = function(options){ + + var instances = [], i; + + var result = null; + + this.each(function(){ + var strobeMediaPlayback = new StrobeMediaPlayback(this, options); + instances.push(strobeMediaPlayback); + }); + + for (i = 0; i < instances.length; i++) { + instances[i].initialize(); + if (result == null) { + result = instances[i].$video; + } + else{ + result.push(instances[i].video); + } + } + return result; + }; + + /** + * Plug-in default values + */ + $.fn.strobemediaplayback.defaults = { + favorFlashOverHtml5Video: true, + swf: "StrobeMediaPlayback.swf", + //javascriptCallbackFunction: "org.strobemediaplayback.triggerHandler", + javascriptCallbackFunction: "$.fn.strobemediaplayback.triggerHandler", + + minimumFlashPlayerVersion: "10.0.0", + expressInstallSwfUrl: "expressInstall.swf", + autoPlay: false, + loop: false, + controlBarMode: "docked", + poster: "" + }; + + + /** + * Utitility method that will retrieve the page parameters from the Query String. + */ + $.fn.strobemediaplayback.parseQueryString = function(queryString){ + var options = {}; + + var queryPairs = queryString.split('&'), queryPair, n = queryPairs.length; + for (var i = 0; i < n; i++) { + queryPair = queryPairs[i].split('='); + if (queryPair[1] == "true" || queryPair[1] == "false") { + options[queryPair[0]] = (queryPair[1] == "true"); + } + else { + var number = parseFloat(queryPair[1]); + if (!isNaN(number)) { + options[queryPair[0]] = number; + } + else { + options[queryPair[0]] = queryPair[1]; + } + } + } + return options; + } + + + /** + * Utitility method that will retrieve the page parameters from the Query String. + */ + $.fn.strobemediaplayback.generateQueryString = function(options){ + var queryStrings = []; + for (var key in options) { + if (queryStrings.length > 0) { + queryStrings.push("&"); + } + queryStrings.push(encodeURIComponent(key)); + queryStrings.push("="); + queryStrings.push((options[key])); + } + return queryStrings.join(""); + } + + var proxyMediaElements = {}; + var proxiedMediaElements = {}; + + $.fn.strobemediaplayback.triggerHandler = function(id, eventName, updatedProperties){ + var proxyMediaElement = proxyMediaElements[id]; + if (typeof proxyMediaElement != 'undefined') { + + if (typeof proxiedMediaElements[id] == 'undefined') { + strobeMediaPlayback = document.getElementById(id); + proxiedMediaElements[id] = strobeMediaPlayback; + + proxyMediaElement.strobeMediaPlayback = strobeMediaPlayback; + proxyMediaElement.videoElement.play = jQuery.proxy(strobeMediaPlayback.play2, proxyMediaElement.strobeMediaPlayback); + proxyMediaElement.videoElement.pause = jQuery.proxy(strobeMediaPlayback.pause, proxyMediaElement.strobeMediaPlayback); + proxyMediaElement.videoElement.load = jQuery.proxy(proxyMediaElement.load, proxyMediaElement); + proxyMediaElement.videoElement.strobeMediaPlayback = strobeMediaPlayback; + monitorChanges(proxyMediaElement); + } + proxyMediaElement.update(updatedProperties, [eventName], proxyMediaElement); + } + } + /** + * Custom video playback controls + */ + var writableProperties = "src preload currentTime defaultPlaybackRate playbackRate autoplay loop controls volume muted".split(" "); + + var timeRangeProperties = "played seekable buffered".split(" "); + var timeRangeMethods = { + start: function(index){ + return this._start[index]; + }, + end: function(index){ + return this._end[index]; + } + } + + var monitorChanges = function(monitor){ + var i = writableProperties.length; + while (i--) { + var propertyName = writableProperties[i]; + if (monitor.cc.hasOwnProperty(propertyName) && + monitor.videoElement.hasOwnProperty(propertyName) && + monitor.cc[propertyName] != monitor.videoElement[propertyName]) { + var setter = "set" + propertyName.charAt(0).toUpperCase() + propertyName.substring(1); + monitor.strobeMediaPlayback[setter](monitor.videoElement[propertyName]); + monitor.cc[propertyName] = monitor.videoElement[propertyName]; + } + } + setTimeout(function(){ + monitorChanges(monitor) + }, 500); + }; + + var VideoElementMonitor = function($strobeMediaPlayback) { + this.videoElement = { + duration: 0, + currentTime: 0, + paused: true, + muted: false + }; + + this.cc = { + duration: 0, + currentTime: 0, + paused: true, + muted: false + }; + + this.$videoElement = $(this.videoElement); + } + + var isPropertyChanged = function(object, cc, propertyName) + { + return !object.hasOwnProperty(propertyName) && object[propertyName] != cc[propertyName]; + } + + var videoElementMonitorMethods = { + load: function(){ + this.strobeMediaPlayback.setSrc(this.videoElement.src); + this.strobeMediaPlayback.load(); + }, + + update: function(properties, events, monitor){ + var propertyName; + for (propertyName in properties) { + if (jQuery.inArray("emptied", events) < 0 && + monitor.cc.hasOwnProperty(propertyName) && + monitor.videoElement.hasOwnProperty(propertyName) && + (monitor.cc[propertyName] != monitor.videoElement[propertyName] && + !isNaN(monitor.cc[propertyName]) && + !isNaN(monitor.videoElement[propertyName]))) { + // this value changed + continue; + } + + monitor.cc[propertyName] = properties[propertyName]; + monitor.videoElement[propertyName] = properties[propertyName]; + if (jQuery.inArray(propertyName, timeRangeProperties) >= 0) { + monitor.videoElement[propertyName].start = timeRangeMethods.start; + monitor.videoElement[propertyName].end = timeRangeMethods.end; + } + } + + if (events) { + var i = events.length; + while (i--) { + monitor.$videoElement.triggerHandler(events[i]); + } + } + } + } + + VideoElementMonitor.prototype = videoElementMonitorMethods; +})(jQuery); + + +/* + * Generate org.strobemediaplayback namespace - which will be used by the + * Flash/Strobe Media Playback once it is ready + */ +if (typeof org == 'undefined') { + var org = {}; +} + +if (typeof org.strobemediaplayback == 'undefined') { + org.strobemediaplayback = {}; +} + +if (typeof org.strobemediaplayback.proxied == 'undefined') { + org.strobemediaplayback.proxied = {}; +} + +org.strobemediaplayback.triggerHandler = function(id, eventName, updatedProperties){ + alert("--org.strobemediaplayback.triggerHandler"); + if (eventName == "onJavaScriptBridgeCreated") { + if (typeof onJavaScriptBridgeCreated == "function") { + onJavaScriptBridgeCreated(id); + } + } + else { + if (typeof org.strobemediaplayback.proxied[id] != 'undefined') { + org.strobemediaplayback.proxied[id].update(updatedProperties, [eventName], org.strobemediaplayback.proxied[id]); + } + } +} diff --git a/gin/strobe/jquery.strobemediaplayback.png b/gin/strobe/jquery.strobemediaplayback.png new file mode 100755 index 0000000..648a979 Binary files /dev/null and b/gin/strobe/jquery.strobemediaplayback.png differ diff --git a/gin/strobe/jquery.strobemediaplaybackchrome.js b/gin/strobe/jquery.strobemediaplaybackchrome.js new file mode 100755 index 0000000..1df53f1 --- /dev/null +++ b/gin/strobe/jquery.strobemediaplaybackchrome.js @@ -0,0 +1,432 @@ +/***************************************************** +* +* Copyright 2010 Adobe Systems Incorporated. All Rights Reserved. +* +***************************************************** +* The contents of this file are subject to the Berkeley Software Distribution (BSD) Licence +* (the "License"); you may not use this file except in +* compliance with the License. +* +* Software distributed under the License is distributed on an "AS IS" +* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +* License for the specific language governing rights and limitations +* under the License. +* +* +* The Initial Developer of the Original Code is Adobe Systems Incorporated. +* Portions created by Adobe Systems Incorporated are Copyright (C) 2010 Adobe Systems +* Incorporated. All Rights Reserved. +* +*****************************************************/ + +/** + * + */ +(function($, undefined){ + /** + * + */ + var StrobeMediaPlaybackChrome = function(element, options){ + this.$window = $(window); + this.$document = $(document); + this.element = element; + this.$element = $(element); + this.options = $.extend({}, $.fn.strobemediaplaybackchrome.defaults, options); + }; + + + var strobeMediaPlaybackChromeMethods = { + initialize: function(){ + if (!this.options.javascriptControls) { + this.$element.find(".strobeMediaPlaybackControlBar,.smp-error,.playoverlay").hide(); + return; + } + + this.$player = this.$element; //$("#" + this.options.id) + this.player = this.element; //this.$player.get(0); + +//409 // TODO: Encapsulate this in a dedicated class +//410 if (!this.options.useHTML5) { +//411 +//412 this.monitor = new VideoElementMonitor(this.$player); +//413 this.$player.data("videoElement", this.monitor.$videoElement); +//414 this.player = this.monitor.videoElement; +//415 this.$player = this.monitor.$videoElement; +//416 org.strobemediaplayback.proxied[this.options.id] = this.monitor; +//417 monitorChanges(this.monitor); +//418 } + + this.sliding = false; + this.$element = $("#strobemediaplayback"); + this.playOverlay = this.$element.find('.playoverlay'); + this.play = this.$element.find('.smp.play'); + this.mute = this.$element.find('.smp.volume'); + this.time = this.$element.find('.time'); + this.currentTimeLabel = this.$element.find('.currentTime'); + this.durationLabel = this.$element.find('.duration'); + this.errorOverlay = this.$element.find('.smp-error'); + this.fullscreen = this.$element.find('.fullscreen'); + + this.play.bind('click', this, this.onPlayClick); + this.playOverlay.bind('click', this, this.onPlayClick); + this.mute.bind('click', this, this.onMuteClick); + this.fullscreen.bind('click', this, this.onFullScreenClick); + + this.$player.bind("play", this, this.onPlay); + this.$player.bind("pause", this, this.onPause); + this.$player.bind("volumechange", this, this.onVolumeChange); + this.$player.bind("durationchange", this, this.onDurationChange); + this.$player.bind("timeupdate", this, this.onTimeUpdate); + this.$player.bind("waiting", this, this.onWaiting); + this.$player.bind("seeking", this, this.onSeeking); + this.$player.bind("seeked", this, this.onSeeked); + this.$player.bind("ended", this, this.onPause); + this.$player.bind("error", this, this.onError); + this.$player.bind("progress", this, this.onProgress); + + this.timeTrack = this.$element.find(".video-track"); + this.slider = this.$element.find(".slider"); + this.played = this.$element.find(".played"); + this.buffered = this.$element.find(".buffered"); + + this.slider.bind("mousedown", this, this.onSliderMouseDown); + this.slider.bind("touchstart", this, this.onSliderMouseDown); + + // Keep here for further experimentation + //this.slider.bind("touchmove", this, this.onTouchMove); + + this.timeTrack.bind('mousedown', this, this.onTimeTrackClick); + + this.$window.bind("orientationchange", this, this.onOrinetationChangeOrResize); + this.$window.bind("resize", this, this.onOrinetationChangeOrResize); + + if (options.disabledControls) { + this.$element.find(options.disabledControls).addClass("disabled"); + } + + this.isFullScreen = false; + this.layoutControlBar(this.options.width, this.options.height); + }, + + onSliderMouseDown: function(event){ + var duration, time, player; + if (!event.data.sliding) { + event.preventDefault(); + + // TODO: Move the sliding code into a special widget + player = event.data.player; + event.data.sliding = true; + duration = player.duration; + event.data.onProgress(event); + var timeTrack = event.data.timeTrack; + var slider = event.data.slider; + + var moveTarget = event.data.$document; + moveTarget.bind("mousemove", event.data, onMouseMove); + moveTarget.bind("touchmove", event.data, onMouseMove); + + moveTarget.bind("mouseup", event.data, onMouseUp); + moveTarget.bind("touchend", event.data, onMouseUp); + + moveTarget.bind("touchcancel", event.data, onTouchCancel); + + } + + function onMouseMove(event){ + event.preventDefault(); + var timeTrackWidth = event.data.timeTrack.outerWidth(); + var offsetLeft = event.data.timeTrack.offset().left; + var x = event.clientX; + var originalEvent = event.originalEvent; + if (typeof x == 'undefined' && originalEvent && originalEvent.touches && originalEvent.touches.length > 0) { + x = originalEvent.touches[0].pageX; + } + var relativePosition = (x - offsetLeft) / (timeTrackWidth); + + time = duration * relativePosition; + if (time < duration && time > 0) { + + var timePercent = (Math.max(0, time) / duration * 100); + event.data.slider.css({ + "left": timePercent + "%" + }); + + event.data.played.css({ + "width": timePercent + "%" + }); + event.data.seekTime = time; + event.data.onProgress(event); + } + + }; + + function onMouseUp(event){ + moveTarget.unbind("mousemove"); + moveTarget.unbind("touchmove"); + + moveTarget.unbind("mouseup"); + moveTarget.unbind("touchend"); + + if (time > 0) { + event.data.seekTime = 0; + player.currentTime = time; + } + event.data.sliding = false; + }; + + function onTouchCancel(event){ + event.data.seekTime = 0; + event.data.sliding = false; + }; + }, + + onOrinetationChangeOrResize: function(event){ + event.data.layoutControlBar(event.data.options.width, event.data.options.height); + }, + + onPlayClick: function(event){ + var player = event.data.player; + + if (player.paused) { + player.play(); + } + else { + player.pause(); + } + }, + + onMuteClick: function(event){ + var player = event.data.player; + player.muted = !player.muted; + }, + + onFullScreenClick: function(event){ + event.data.$element.parent().toggleClass("fullscreen-mode"); + }, + + onTimeTrackClick: function(event){ + var duration = event.data.player.duration; + var timeTrackWidth = event.data.timeTrack.outerWidth(); + var offsetLeft = event.data.timeTrack.offset().left; + var relativePosition = (event.clientX - offsetLeft) / (timeTrackWidth); + + var time = duration * relativePosition; + + if (time > 0) { + event.data.player.currentTime = time; + } + + + $("#seekDebug").html("clientX=" + event.clientX + " width=" + timeTrackWidth + " duration=" + duration + " time=" + time); + }, + + onPlay: function(event){ + event.data.errorOverlay.hide(); + event.data.play.removeClass("play").addClass("pause"); + if (event.data.useHTML5 && + event.data.options.hasOwnProperty("playButtonOverlay") && + event.data.options.playButtonOverlay) { + event.data.playOverlay.fadeOut(600); + } + }, + + onPause: function(event){ + event.data.play.removeClass("pause").addClass("play"); + if (event.data.useHTML5 && event.data.options.playButtonOverlay) { + event.data.playOverlay.fadeIn(600); + } + }, + + onWaiting: function(event){ + // $("#debug").append("BUFFERING"); + event.data.buffered.css({ + "width": 0 + }); + }, + + onError: function(event){ + //$("#debug").append("ERROR" + event.data.player.error.code); + if (event.data.useHTML5) { + var message; + switch (event.target.error.code) { + case event.target.error.MEDIA_ERR_ABORTED: + message = 'You aborted the video playback.'; + break; + case event.target.error.MEDIA_ERR_NETWORK: + message = 'A network error caused the video download to fail part-way.'; + break; + case event.target.error.MEDIA_ERR_DECODE: + message = 'The video playback was aborted due to a corruption problem or because the video used features your browser did not support.'; + break; + case event.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED: + message = 'The video could not be loaded, either because the server or network failed or because the format is not supported.'; + break; + default: + message = 'An unknown error occurred.'; + break; + } + //$("#debug").append(message); + event.data.errorOverlay.html(message); + event.data.errorOverlay.show(); + } + }, + + onSeeking: function(event){ + // $("#debug").append("SEEKING"); + }, + + onSeeked: function(event){ + event.data.onProgress(event); + }, + + onVolumeChange: function(event){ + if (event.data.player.muted) { + event.data.mute.addClass("mute"); + } + else { + event.data.mute.removeClass("mute"); + } + }, + + onDurationChange: function(event){ + var duration = event.data.player.duration; + var currentTime = event.data.player.currentTime; + + var timeDuration = formatTimeStatus(currentTime, duration); + + event.data.currentTimeLabel.html(timeDuration[0]); + event.data.durationLabel.html(timeDuration[1]); + }, + + onTimeUpdate: function(event){ + if (event.data.sliding) { + return; + } + var duration = event.data.player.duration; + var currentTime = event.data.player.currentTime; + + var timeDuration = formatTimeStatus(currentTime, duration); + + event.data.currentTimeLabel.html(timeDuration[0]); + event.data.durationLabel.html(timeDuration[1]); + + var timePercent = (Math.max(0, currentTime) / duration * 100); + + event.data.slider.css({ + "left": timePercent + "%" + }); + + event.data.played.css({ + "width": timePercent + "%" + }); + + event.data.onProgress(event); + }, + + onProgress: function(event){ + var bufferedPercent = 0; + + if (!event.data.player.seeking) { + var buffered = event.data.player.buffered; + + var time = event.data.seekTime || Math.max(0, event.data.player.currentTime); + //$("#debug").append(buffered.length + "-" + buffered.end(buffered.length - 1)); + var timePercent = time / event.data.player.duration * 100; + if (buffered) { + var lastBuffered = buffered.end(buffered.length - 1); + bufferedPercent = (lastBuffered / event.data.player.duration) * 100; + bufferedPercent -= timePercent; + //$("#debug").append(bufferedPercent); + } + if (timePercent + bufferedPercent > 100) { + bufferedPercent = 100 - timePercent; + } + } + var css = { + "left": timePercent + "%", + "width": bufferedPercent + "%" + } + if (bufferedPercent + timePercent > 99) { + event.data.buffered.addClass("done") + } + else { + event.data.buffered.removeClass("done") + } + event.data.buffered.css(css); + }, + + layoutControlBar: function(newWidth, newHeight){ + if (this.useHTML5 && this.options.playButtonOverlay) { + this.playOverlay.fadeIn(600); + this.playOverlay.css({ + "left": (newWidth / 2 - this.playOverlay.width() / 2) + "px", + "top": (newHeight / 2 - this.playOverlay.height() / 2) + "px" + }); + } + + $('.video-progress2').css({ + "width": (newWidth - 200) + "px" + }); + + //$('.strobeMediaPlaybackControlBar').fadeIn(600); + $('.strobeMediaPlaybackControlBar').css({ + "width": newWidth - 6 + "px" + }); + } + + } + + StrobeMediaPlaybackChrome.prototype = strobeMediaPlaybackChromeMethods; + + + /** + * jQuery plugin hook + */ + $.fn.strobemediaplaybackchrome = function(options){ + var instances = [], i; + var result = this.each(function(){ + instances.push(new StrobeMediaPlaybackChrome(this, options)); + }); + + for (i = 0; i < instances.length; i++) { + instances[i].initialize(); + } + return result; + }; + + /** + * jQuery plugin defaults + */ + $.fn.strobemediaplaybackchrome.defaults = { + javascriptControls: false + }; + + + // Internals, private functions + + function onMouseMove(event){ + showControlBar(); + } + + function formatTimeStatus(currentPosition, totalDuration){ + var h; + var m; + var s; + function prettyPrintSeconds(seconds, leadingMinutes, leadingHours){ + seconds = Math.floor(isNaN(seconds) ? 0 : Math.max(0, seconds)); + h = Math.floor(seconds / 3600); + m = Math.floor(seconds % 3600 / 60); + s = seconds % 60; + return ((h > 0 || leadingHours) ? (h + ":") : "") + + (((h > 0 || leadingMinutes) && m < 10) ? "0" : "") + + m + + ":" + + (s < 10 ? "0" : "") + + s; + } + + var totalDurationString = prettyPrintSeconds(totalDuration); + var currentPositionString = prettyPrintSeconds(currentPosition, h > 0 || m > 9, h > 0); + return [currentPositionString, totalDurationString]; + } +})(jQuery); \ No newline at end of file diff --git a/gin/strobe/jsdemo.css b/gin/strobe/jsdemo.css new file mode 100755 index 0000000..cf3715b --- /dev/null +++ b/gin/strobe/jsdemo.css @@ -0,0 +1,67 @@ +.smp-controls +{ + width: 640px; + font-size: 0.9em; +} +.smp-top-container +{ + width: 630px; + padding: 5px; +} + +.smp-volume +{ + width: 10%; + height: 9px; + + padding-left: 30px; + display: inline-block; +} + +.smp-time +{ + float: right; +} + +.smp-mbr-indicator +{ + float: right; + margin-right: 10px; +} + +.smp-mbr-items +{ + position:absolute; + top: 370px; + left: 310px; + width: 250px; + z-index:200; + background-color: black; + display: inline; +} + +.smp-mbr-item +{ + display:block; + margin:0; + padding:0; +} + +.smp-mbr-auto +{ +; +} + +.smp-progress +{ + width: 630px; + padding: 0 5px; + font-size: 8px; +} + +.smp-mbr-items button +{ + width: 100%; + text-align: right; +} + \ No newline at end of file diff --git a/gin/strobe/jsdemo.html b/gin/strobe/jsdemo.html new file mode 100755 index 0000000..555d7e2 --- /dev/null +++ b/gin/strobe/jsdemo.html @@ -0,0 +1,611 @@ + + + + Strobe Media Playback + + + + + + + + + + + + + + + + + + + + + + + + + +
Strobe Media Playback
+ + + + + + + + + +
+
+

Alternative content

+
+
+
+ + + + + +
+
+ 0:00 / 0:00 + + +
+ +
+
+
+
+
+
+ +
+
+
+

At the left we can see...

+

At the right we can see the...

+

...the head-snarlers

+

Everything is safe. Perfectly safe.

+

Emo?

+

Watch out!

+

Are you hurt?

+

I don't think so. You?

+

I'm Ok.

+

Get up. Emo, it's not safe here.

+

Let's go.

+

What's next?

+

You'll see!

+

(howling wind)

+

Emo. This way.

+

Follow me!

+

(buzzing wires and chattery conversations)

+

Hurry Emo!

+

(louder telephone voices)

+

(phone ringing)

+

You're not paying attention!

+

I just want to answer the... ...phone.

+

Emo, look, I mean listen.

+

You have to learn to listen.

+

This is not some game.

+

You, i mean we, we could easily die out here.

+

Listen, listen to the sounds of the machine.

+

Listen to your breathing.

+

(Buzzing wires)

+

(laughing)

+

(oriental dance music)

+

Well, don't you ever get tired of this?

+

Tired?!?

+

Emo, the machine is like clockwork.

+

One move out of place...

+

...and you're ground to a pulp.

+

But isn't it -

+

Pulp, Emo! Is that what you want, pulp?

+

Emo, your goal in life...

+

...pulp?

+

(loud metal sounds)

+

Emo, close your eyes.

+

Why? - Now!

+

Ok.

+

Good.

+

What do you see at your left side, Emo?

+

Nothing. - Really?

+

No, nothing at all.

+

And at your right, what do you see at your right side, Emo?

+

The same Proog, exactly the same...

+

...nothing! - Great.

+

(sound of camera flash)

+

(engine drone)

+

Listen Proog! Do you hear that! (amusement park music)

+

Can we go here?

+

There? It isn't safe, Emo.

+

But... - Trust me, it's not.

+

Maybe I could...

+

No.

+

NO!

+

Any further questions, Emo?

+

No.

+

Emo?

+

Emo, why...

+

Emo...

+

...why can't you see the beauty of this place?

+

The way it works.

+

How perfect it is.

+

No, Proog, I don't see.

+

I don't see because there's nothing there.

+

And why should I trust my life to something that isn't there?

+

Well can you tell me that?

+

Answer me!

+

Proog...

+

...you're a sick man!

+

Stay away from me!

+

No! Emo! It's a trap!

+

Hah, it's a trap.

+

At the left side you can see|the hanging gardens of Babylon!

+

How's that for a trap?

+

No, Emo.

+

At the right side you can see... ...well guess what...

+

...the colossus of Rhodes!

+

No!

+

The colossus of Rhodes and it is here just for you Proog.

+

It is there...

+

I'm telling you, Emo...

+

...it is.

+

(howling wind)

+ +
+
+ + + +
+
+ + +
+
+
+
+
+
+ +
+ + +
+
+ + + \ No newline at end of file diff --git a/gin/strobe/jsdemo.js b/gin/strobe/jsdemo.js new file mode 100755 index 0000000..5d059d4 --- /dev/null +++ b/gin/strobe/jsdemo.js @@ -0,0 +1,439 @@ +/*********************************************************** + * Copyright 2010 Adobe Systems Incorporated. All Rights Reserved. + * + * ********************************************************* + * The contents of this file are subject to the Berkeley Software Distribution (BSD) Licence + * (the "License"); you may not use this file except in + * compliance with the License. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * + * The Initial Developer of the Original Code is Adobe Systems Incorporated. + * Portions created by Adobe Systems Incorporated are Copyright (C) 2010 Adobe Systems + * Incorporated. All Rights Reserved. + * + **********************************************************/ + +if (typeof org == 'undefined') { var org = {}; } +if (typeof org.strobemediaplayback == 'undefined') { org.strobemediaplayback = {}; } +if (typeof org.strobemediaplayback.players == 'undefined') { org.strobemediaplayback.players = {}; } + +org.strobemediaplayback.initializeControlBar = function() +{ + $(".smp-volume").slider({ + orientation: 'horizontal', + range: "min", + max: 100.0, + value: 100.0 + }); + + $(".smp-progress").slider({ + orientation: 'horizontal', + range: "min", + max: 100.0, + value: 100.0 + }); + + //$(".smp-progress.ui-corner-all").removeClass("ui-corner-all"); + //$(".smp-progress a.ui-corner-all").removeClass("ui-corner-all"); + + $('.smp-play').button({ + text: false, + icons: { + primary: 'ui-icon-play' + } + }); + + $('.smp-mute').button({ + text: false, + icons: { + primary: 'ui-icon-volume-on' + } + }); + + $('.smp-mbr-indicator').button({ + text: false, + icons: { + primary: 'ui-icon-signal' + } + }); +} + +org.strobemediaplayback.formatTimeStatus = function(currentPosition, totalDuration) +{ + var h; + var m; + var s; + function prettyPrintSeconds(seconds, leadingMinutes, leadingHours) + { + seconds = Math.floor(isNaN(seconds) ? 0 : Math.max(0, seconds)); + h = Math.floor(seconds / 3600); + m = Math.floor(seconds % 3600 / 60); + s = seconds % 60; + return ((h>0||leadingHours) ? (h + ":") : "") + + (((h>0||leadingMinutes) && m<10) ? "0" : "") + + m + ":" + + (s<10 ? "0" : "") + + s; + } + + var totalDurationString = prettyPrintSeconds(totalDuration); + var currentPositionString = prettyPrintSeconds(currentPosition, h>0||m>9, h>0); + return currentPositionString + " / " + totalDurationString; +} + +org.strobemediaplayback.StrobeMediaPlaybackJSUI = function(player, controlBar) +{ + this.currentTime = 0; + this.player = player; + this.controlBar = controlBar; + this.play = $('.smp-play', this.controlBar); + this.mute = $('.smp-mute', this.controlBar); + this.volume = $('.smp-volume', this.controlBar); + this.time = $('.smp-time', this.controlBar); + this.progress = $('.smp-progress', this.controlBar); + this.dynamicStreamingIndicator = $('.smp-mbr-indicator', this.controlBar); + this.dynamicStreamingItems = $('.smp-mbr-items', this.controlBar); + + this.play.bind('click', this, this.onPlayClick); + this.progress.bind('slide', this, this.onProgressSlide); + this.progress.bind('change', this, this.onProgressSlide); + this.mute.bind('click', this, this.onMuteClick); + this.volume.bind('slide', this, this.onVolumeSlide); + this.volume.bind('change', this, this.onVolumeSlide); + + this.dynamicStreamingIndicator.hide(); + this.dynamicStreamingIndicator.bind('mouseover', this, this.onDynamicStreamingMouseOver); + this.dynamicStreamingIndicator.bind('mouseout', this, this.onDynamicStreamingMouseOut); + this.dynamicStreamingIndicator.bind('click', this, this.onDynamicStreamingClick); + + this.dynamicStreamingItems.hide(); + + //$(player).show(); +} + +org.strobemediaplayback.StrobeMediaPlaybackJSUI.prototype = +{ + onDurationChange: function(duration) + { + this.duration = duration; + $(this.time).html(org.strobemediaplayback.formatTimeStatus(this.currentTime, this.duration)); + $(".smp-progress").slider({ + max: this.duration, + value: Math.max(0, this.currentTime) + }); + }, + + onCurrentTimeChange: function(currentTime) + { + this.currentTime = currentTime; + $(this.time).html(org.strobemediaplayback.formatTimeStatus(currentTime, this.duration)); + + this.progress.slider({ + max: this.duration, + value: Math.max(0, currentTime) + }); + }, + + onVolumeChange: function(value) + { + this.volume.slider("value", value * 100.0); + }, + + onMutedChange : function(value) + { + if (value == false) // Seems to be a BUG? + { + this.mute.button('option', { + icons: { + primary: 'ui-icon-volume-on' + } + }); + } + else + { + this.mute.button('option', { + icons: { + primary: 'ui-icon-volume-off' + } + }); + } + }, + + onMediaPlayerStateChange : function(value) + { + //alert("onMediaPlayerStateChange:" + value); + var options; + if (value == 'playing') + { + options = + { + label: 'pause', + icons: { + primary: 'ui-icon-pause' + } + }; + } + else if (value == 'paused' || value == 'ready') + { + options = + { + label: 'play', + icons: { + primary: 'ui-icon-play' + } + }; + } + this.play.button('option', options); + }, + + onSwitchingChange: function(value, playerId) + { + if (value == false) + { + this.onRedrawDynamicStreamItems(value, playerId); + } + else + { + //alert("start switching"); + } + }, + + onRedrawDynamicStreamItems: function(value, playerId) + { + if (value == false) + { + var dynamicStreams=this.player.getStreamItems(); + var buttonText; + var button; + button = $(''); + if (this.player.getAutoDynamicStreamSwitch() == true) + { + button.button( + { + icons: + { + primary: 'ui-icon-circle-triangle-e' + } + } + ); + } + else + { + button.button(); + button.bind("click", this, this.onMBRItemChange); + } + + this.dynamicStreamingItems.empty(); + this.dynamicStreamingItems.append(button); + + for (var idx = 0; idx < dynamicStreams.length; idx ++) + { + buttonText = dynamicStreams[idx]['width'] + "x" + dynamicStreams[idx]['height'] + " @ " + dynamicStreams[idx]['bitrate'] + "kbps"; + button = $('