Changeset 374
- Timestamp:
- 09/20/09 18:16:22 (4 years ago)
- Files:
-
- 1 added
- 5 deleted
- 40 edited
- 1 copied
-
plugins/livestream/com/jeroenwijering/plugins/Livestream.as (modified) (2 diffs)
-
plugins/livestream/livestream.swf (modified) (previous)
-
plugins/qualitymonitor/com/jeroenwijering/plugins/QualityMonitor.as (modified) (5 diffs)
-
plugins/qualitymonitor/qualitymonitor.swf (modified) (previous)
-
plugins/qualitymonitor/qualitymonitor.xml (modified) (1 diff)
-
plugins/searchbar/com/jeroenwijering/plugins/Searchbar.as (modified) (1 diff)
-
plugins/searchbar/searchbar.swf (modified) (previous)
-
skins/playcasso/playcasso.swf (added)
-
testing/files/bitrates.xml (copied) (copied from testing/files/chapters.xml) (1 diff)
-
testing/files/bunnies.xml (deleted)
-
testing/files/bunny.m4v (deleted)
-
testing/files/bunny.mp4 (modified) (previous)
-
testing/files/chapters.xml (modified) (2 diffs)
-
testing/files/logobox.png (deleted)
-
testing/files/longtail.gif (deleted)
-
testing/files/streamers.xml (deleted)
-
testing/files/style.css (modified) (1 diff)
-
testing/index.html (modified) (2 diffs)
-
testing/settings.js (modified) (18 diffs)
-
trunk/as3/com/jeroenwijering/events/ModelEvent.as (modified) (1 diff)
-
trunk/as3/com/jeroenwijering/models/AbstractModel.as (modified) (3 diffs)
-
trunk/as3/com/jeroenwijering/models/HTTPModel.as (modified) (10 diffs)
-
trunk/as3/com/jeroenwijering/models/ImageModel.as (modified) (2 diffs)
-
trunk/as3/com/jeroenwijering/models/LivestreamModel.as (modified) (9 diffs)
-
trunk/as3/com/jeroenwijering/models/RTMPModel.as (modified) (20 diffs)
-
trunk/as3/com/jeroenwijering/models/SmoothModel.as (modified) (10 diffs)
-
trunk/as3/com/jeroenwijering/models/SoundModel.as (modified) (5 diffs)
-
trunk/as3/com/jeroenwijering/models/VideoModel.as (modified) (9 diffs)
-
trunk/as3/com/jeroenwijering/models/YoutubeModel.as (modified) (11 diffs)
-
trunk/as3/com/jeroenwijering/parsers/ASXParser.as (modified) (2 diffs)
-
trunk/as3/com/jeroenwijering/parsers/MediaParser.as (modified) (1 diff)
-
trunk/as3/com/jeroenwijering/parsers/SmoothParser.as (modified) (1 diff)
-
trunk/as3/com/jeroenwijering/parsers/XSPFParser.as (modified) (2 diffs)
-
trunk/as3/com/jeroenwijering/player/Controller.as (modified) (7 diffs)
-
trunk/as3/com/jeroenwijering/player/Model.as (modified) (13 diffs)
-
trunk/as3/com/jeroenwijering/player/Player.as (modified) (3 diffs)
-
trunk/as3/com/jeroenwijering/player/SPLoader.as (modified) (2 diffs)
-
trunk/as3/com/jeroenwijering/player/View.as (modified) (1 diff)
-
trunk/as3/com/jeroenwijering/plugins/Display.as (modified) (1 diff)
-
trunk/as3/com/jeroenwijering/plugins/Playlist.as (modified) (1 diff)
-
trunk/as3/com/jeroenwijering/plugins/Rightclick.as (modified) (2 diffs)
-
trunk/as3/com/jeroenwijering/plugins/Watermark.as (modified) (8 diffs)
-
trunk/as3/com/jeroenwijering/utils/NetClient.as (modified) (1 diff)
-
trunk/as3/com/jeroenwijering/utils/Stretcher.as (modified) (1 diff)
-
trunk/as3/player.swf (modified) (previous)
-
trunk/as3/yt.as (modified) (1 diff)
-
trunk/as3/yt.swf (modified) (previous)
Legend:
- Unmodified
- Added
- Removed
-
plugins/livestream/com/jeroenwijering/plugins/Livestream.as
r217 r374 50 50 public function Livestream():void { 51 51 connection = new NetConnection(); 52 connection.client = new Object(); 52 53 buildStage(); 53 54 }; … … 157 158 Logger.log('no livestream yet: '+evt.info.code,'livestream'); 158 159 break; 160 default: 161 Logger.log(evt.info,'livestream'); 162 break; 159 163 } 160 164 }; -
plugins/qualitymonitor/com/jeroenwijering/plugins/QualityMonitor.as
r338 r374 4 4 import com.jeroenwijering.events.*; 5 5 6 6 7 import flash.display.*; 7 8 import flash.events.*; 8 9 import flash.geom.Rectangle; 9 10 import flash.text.*; 11 import flash.utils.*; 12 10 13 11 14 /** 12 * A simple plugin that displays a search bar.15 * Show bitrate switching events. 13 16 **/ 14 17 public class QualityMonitor extends MovieClip implements PluginInterface { … … 17 20 /** Reference to the background clip. **/ 18 21 private var back:Sprite; 19 /** Reference to the graphics. **/20 public var config:Object = {};22 /** Configuration variables. **/ 23 public var config:Object ={}; 21 24 /** Reference to the textfield. **/ 22 25 private var field:TextField; 26 /** Reference to the checking interval. **/ 27 private var interval:Number; 23 28 /** Reference to the view of the player. **/ 24 29 private var view:AbstractView; … … 31 36 back = new Sprite(); 32 37 back.graphics.beginFill(0x000000,0.8); 33 back.graphics.drawRect(0,0,400, 30);38 back.graphics.drawRect(0,0,400,60); 34 39 addChild(back); 35 40 field = new TextField(); 36 var fmt:TextFormat = new TextFormat("_sans",11,0xFFFFFF); 37 fmt.align = 'center'; 38 field.defaultTextFormat = fmt; 39 field.x = field.y = 5; 40 field.htmlText = "Awaiting quality events"; 41 field.defaultTextFormat = new TextFormat("_sans",11,0xFFFFFF); 42 field.multiline = true; 43 field.x = 8; 44 field.y = 5; 41 45 addChild(field); 46 }; 47 48 49 /** Update quality metrics **/ 50 private function check():void { 51 var len:Number = 1; 52 if(view.playlist[view.config['item']]['levels']) { 53 len = view.playlist[view.config['item']]['levels'].length; 54 } 55 field.htmlText = 56 '<b>bandwidth:</b> ' + view.config['bandwidth'] + ' kbps<br/>' + 57 '<b>level:</b> ' + (view.config['level']+1) + ' of ' + len + '<br/>' + 58 '<b>width:</b> '+ view.config['width'] + ' pixels'; 42 59 }; 43 60 … … 47 64 view = vie; 48 65 view.addControllerListener(ControllerEvent.RESIZE,resizeHandler); 49 view.addModelListener('QUALITY',qualityHandler); 50 resizeHandler(new ControllerEvent(ControllerEvent.RESIZE)); 51 }; 52 53 54 /** Update quality metrics **/ 55 private function qualityHandler(evt:ModelEvent):void { 56 var txt:String = ''; 57 for(var i:String in evt.data) { 58 txt +='<b>'+i+':</b> '+evt.data[i]+' | '; 59 } 60 field.htmlText = txt.substr(0,txt.length-2); 66 interval = setInterval(check,1000); 61 67 }; 62 68 … … 64 70 /** Handle a resize. **/ 65 71 private function resizeHandler(evt:ControllerEvent):void { 66 back.width = config['width'];67 72 x = config['x']; 68 73 y = config['y']; 69 field.width = back.width - 10; 74 back.width = config['width']; 75 field.width = config['width']-10; 70 76 }; 71 77 -
plugins/qualitymonitor/qualitymonitor.xml
r338 r374 10 10 <href>http://developer.longtailvideo.com/trac/browser/plugins/qualitymonitor</href> 11 11 12 <flashvars> 13 <flashvar> 14 <name>position</name> 15 <default>over</default> 16 <description>Position of the plugin.</description> 17 </flashvar> 18 </flashvars> 12 <flashvars /> 19 13 20 14 </plugin> -
plugins/searchbar/com/jeroenwijering/plugins/Searchbar.as
r260 r374 24 24 size:40, 25 25 label:'Search', 26 position:' over',26 position:'bottom', 27 27 script:'http://gdata.youtube.com/feeds/api/videos?vq=QUERY&format=5' 28 28 }; -
testing/files/bitrates.xml
r204 r374 1 <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/"> 1 <rss version="2.0" 2 xmlns:media="http://search.yahoo.com/mrss/" 3 xmlns:jwplayer="http://developer.longtailvideo.com/trac/wiki/FlashFormats"> 2 4 <channel> 3 <title>Example media RSS playlist for the JW Player</title> 4 <link>http://developer.longtailvideo.com/trac</link> 5 <title>Playlist with bitrate switches</title> 5 6 6 7 <item> 7 <title>Opening credits</title> 8 <media:content url="http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="00:00" /> 9 <description>In which we meet Proog and Emo, the two characters of this movie.</description> 10 <link>http://orange.blender.org/</link> 8 <title>Progressive download</title> 9 <description>When bitrate switching a progressive download, the only actual switch is done on startup.</description> 10 <media:group> 11 <media:content bitrate="1500" width="1080" url="http://content.bitsontherun.com/videos/8Juv1MVa-67727.mp4" /> 12 <media:content bitrate="1100" width="720" url="http://content.bitsontherun.com/videos/8Juv1MVa-485.mp4" /> 13 <media:content bitrate="700" width="480" url="http://content.bitsontherun.com/videos/8Juv1MVa-484.mp4" /> 14 <media:content bitrate="400" width="320" url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" /> 15 <media:thumbnail url="http://content.bitsontherun.com/thumbs/8Juv1MVa-480.jpg" /> 16 </media:group> 11 17 </item> 12 18 13 19 <item> 14 <title>Wire attack</title> 15 <media:content url="http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="00:26" /> 16 <description>In which the computer world of our actors is being introduced.</description> 17 <link>http://orange.blender.org/</link> 20 <title>HTTP streaming</title> 21 <description>Bitrate switching for HTTP streaming is done on startup and with every seek and fullscreen switch.</description> 22 <media:content bitrate="1500" width="1080" url="http://content.bitsontherun.com/videos/8Juv1MVa-67727.mp4" /> 23 <media:content bitrate="1100" width="720" url="http://content.bitsontherun.com/videos/8Juv1MVa-485.mp4" /> 24 <media:content bitrate="700" width="480" url="http://content.bitsontherun.com/videos/8Juv1MVa-484.mp4" /> 25 <media:content bitrate="400" width="320" url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" /> 26 <media:thumbnail url="http://content.bitsontherun.com/thumbs/8Juv1MVa-480.jpg" /> 27 <jwplayer:type>http</jwplayer:type> 28 <jwplayer:streamer>starttime</jwplayer:streamer> 18 29 </item> 19 30 20 31 <item> 21 <title>The bird cave</title> 22 <media:content url="http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="01:10" /> 23 <description>In which Proog takes upon his role as a guide and savely sees Emo across.</description> 24 <link>http://orange.blender.org/</link> 25 </item> 26 27 <item> 28 <title>Answer the phone</title> 29 <media:content url="http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="02:30" /> 30 <description>In which Emo and Proog have their first argument.</description> 31 <link>http://orange.blender.org/</link> 32 </item> 33 34 <item> 35 <title>Across the gap</title> 36 <media:content url="http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="03:44" /> 37 <description>In which we learn that not everything here is what it looks like.</description> 38 <link>http://orange.blender.org/</link> 39 </item> 40 41 <item> 42 <title>Elevator Ride</title> 43 <media:content url="http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="04:53" /> 44 <description>In which Proog and Emo jump into space, and fall back again.</description> 45 <link>http://orange.blender.org/</link> 46 </item> 47 48 <item> 49 <title>Final Conflict</title> 50 <media:content url="http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="06:25" /> 51 <description>In which Emo does not tolerate Proogs guidance anymore, with fatal consequence.</description> 52 <link>http://orange.blender.org/</link> 53 </item> 54 55 <item> 56 <title>Ending Credits</title> 57 <media:content url="http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="09:25" /> 58 <description>In which the huge list of contributers to this project passes by.</description> 59 <link>http://orange.blender.org/</link> 32 <title>RTMP streaming</title> 33 <description>Bitrate switching for RTMP streaming is done on startup and with every seek and fullscreen switch.</description> 34 <media:group> 35 <media:content bitrate="1500" width="1080" url="videos/8Juv1MVa-67727.mp4" /> 36 <media:content bitrate="1100" width="720" url="videos/8Juv1MVa-485.mp4" /> 37 <media:content bitrate="700" width="480" url="videos/8Juv1MVa-484.mp4" /> 38 <media:content bitrate="400" width="320" url="videos/8Juv1MVa-483.mp4" /> 39 <media:thumbnail url="http://content.bitsontherun.com/thumbs/8Juv1MVa-480.jpg" /> 40 </media:group> 41 <jwplayer:type>rtmp</jwplayer:type> 42 <jwplayer:streamer>rtmp://fms.12E5.edgecastcdn.net/0012E5</jwplayer:streamer> 60 43 </item> 61 44 -
testing/files/chapters.xml
r204 r374 1 <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/"> 1 <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/" 2 xmlns:jwplayer="http://developer.longtailvideo.com/trac/wiki/FlashFormats"> 2 3 <channel> 3 4 <title>Example media RSS playlist for the JW Player</title> … … 6 7 <item> 7 8 <title>Opening credits</title> 8 <media:content url="http:// bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="00:00" />9 <media:content url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" type="video/mp4" start="00:00" /> 9 10 <description>In which we meet Proog and Emo, the two characters of this movie.</description> 10 11 <link>http://orange.blender.org/</link> 12 <jwplayer:type>bitgravity</jwplayer:type> 11 13 </item> 12 14 13 15 <item> 14 16 <title>Wire attack</title> 15 <media:content url="http:// bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="00:26" />17 <media:content url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" type="video/mp4" start="00:26" /> 16 18 <description>In which the computer world of our actors is being introduced.</description> 17 19 <link>http://orange.blender.org/</link> 20 <jwplayer:type>bitgravity</jwplayer:type> 18 21 </item> 19 22 20 23 <item> 21 24 <title>The bird cave</title> 22 <media:content url="http:// bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="01:10" />25 <media:content url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" type="video/mp4" start="01:10" /> 23 26 <description>In which Proog takes upon his role as a guide and savely sees Emo across.</description> 24 27 <link>http://orange.blender.org/</link> 28 <jwplayer:type>bitgravity</jwplayer:type> 25 29 </item> 26 30 27 31 <item> 28 32 <title>Answer the phone</title> 29 <media:content url="http:// bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="02:30" />33 <media:content url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" type="video/mp4" start="02:30" /> 30 34 <description>In which Emo and Proog have their first argument.</description> 31 35 <link>http://orange.blender.org/</link> 36 <jwplayer:type>bitgravity</jwplayer:type> 32 37 </item> 33 38 34 39 <item> 35 40 <title>Across the gap</title> 36 <media:content url="http:// bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="03:44" />41 <media:content url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" type="video/mp4" start="03:44" /> 37 42 <description>In which we learn that not everything here is what it looks like.</description> 38 43 <link>http://orange.blender.org/</link> 44 <jwplayer:type>bitgravity</jwplayer:type> 39 45 </item> 40 46 41 47 <item> 42 48 <title>Elevator Ride</title> 43 <media:content url="http:// bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="04:53" />49 <media:content url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" type="video/mp4" start="04:53" /> 44 50 <description>In which Proog and Emo jump into space, and fall back again.</description> 45 51 <link>http://orange.blender.org/</link> 52 <jwplayer:type>bitgravity</jwplayer:type> 46 53 </item> 47 54 48 55 <item> 49 56 <title>Final Conflict</title> 50 <media:content url="http:// bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="06:25" />57 <media:content url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" type="video/mp4" start="06:25" /> 51 58 <description>In which Emo does not tolerate Proogs guidance anymore, with fatal consequence.</description> 52 59 <link>http://orange.blender.org/</link> 60 <jwplayer:type>bitgravity</jwplayer:type> 53 61 </item> 54 62 55 63 <item> 56 64 <title>Ending Credits</title> 57 <media:content url="http:// bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/LJSVMnCF-326.flv" type="video/x-flv" start="09:25" />65 <media:content url="http://content.bitsontherun.com/videos/8Juv1MVa-483.mp4" type="video/mp4" start="09:25" /> 58 66 <description>In which the huge list of contributers to this project passes by.</description> 59 67 <link>http://orange.blender.org/</link> 68 <jwplayer:type>bitgravity</jwplayer:type> 60 69 </item> 61 70 -
testing/files/style.css
r185 r374 25 25 background-color: #F5F5F5; 26 26 border: 1px solid #7A2; 27 } 28 hr { 29 border:0; 30 clear: both; 31 display: block; 32 height: 10px; 33 width: 100%; 27 34 } 28 35 legend { -
testing/index.html
r331 r374 380 380 </fieldset> 381 381 <fieldset id="layout"> 382 <label>backcolor</label>383 <input type="text" name="backcolor" />384 382 <label>controlbar</label> 385 383 <input type="text" name="controlbar" /> 386 <label>dock</label>387 <input type="text" name="dock" />388 <label>frontcolor</label>389 <input type="text" name="frontcolor" />390 384 <label>height</label> 391 385 <input type="text" name="height" value="260" /> 392 386 <label>icons</label> 393 387 <input type="text" name="icons" /> 394 <label>l ightcolor</label>395 <input type="text" name="l ightcolor" />388 <label>logo</label> 389 <input type="text" name="logo" /> 396 390 <label>playlist</label> 397 391 <input type="text" name="playlist" /> 398 392 <label>playlistsize</label> 399 393 <input type="text" name="playlistsize" /> 394 <label>width</label> 395 <input type="text" name="width" value="400" /> 396 <hr/> 397 <label>backcolor</label> 398 <input type="text" name="backcolor" /> 399 <label>frontcolor</label> 400 <input type="text" name="frontcolor" /> 401 <label>lightcolor</label> 402 <input type="text" name="lightcolor" /> 400 403 <label>screencolor</label> 401 404 <input type="text" name="screencolor" /> 402 <label>width</label>403 <input type="text" name="width" value="400" />404 405 </fieldset> 405 406 <fieldset id="behaviour"> 406 407 <label>autostart</label> 407 408 <input type="text" name="autostart" /> 409 <label>bandwidth</label> 410 <input type="text" name="bandwidth" /> 408 411 <label>bufferlength</label> 409 412 <input type="text" name="bufferlength" /> 410 413 <label>displayclick</label> 411 414 <input type="text" name="displayclick" /> 412 <label>d isplaytitle</label>413 <input type="text" name="d isplaytitle" />415 <label>dock</label> 416 <input type="text" name="dock" /> 414 417 <label>item</label> 415 418 <input type="text" name="item" /> 416 419 <label>linktarget</label> 417 420 <input type="text" name="linktarget" /> 418 <label>logo</label>419 <input type="text" name="logo" />420 421 <label>mute</label> 421 422 <input type="text" name="mute" /> 422 <label>oncomplete</label>423 <input type="text" name="oncomplete" />424 423 <label>repeat</label> 425 424 <input type="text" name="repeat" /> … … 440 439 <label>id</label> 441 440 <input type="text" name="id" /> 442 <label>token</label>443 <input type="text" name="token" />444 441 </fieldset> 445 442 <span id="fieldsetspan"></span> -
testing/settings.js
r341 r374 8 8 '4.2':'../tags/mediaplayer-4.2/player.swf', 9 9 '4.1':'../tags/mediaplayer-4.1/player.swf', 10 '4.0':'../tags/mediaplayer-4.0/player.swf' 10 '4.0':'../tags/mediaplayer-4.0/player.swf', 11 'botr':'http://content.bitsontherun.com/staticfiles/videoplayer.swf' 11 12 }, 12 13 /** Available plugins to test. **/ … … 130 131 10: {}, 131 132 11: { 133 title:'HTTP streamed FLV', 134 file:'http://content.bitsontherun.com/videos/Qvxp3Jnv-68183.flv', 135 type:'http', 136 height:240, 137 width:400 138 }, 139 12: { 140 title:'HTTP streamed MP4', 141 file:'http://content.bitsontherun.com/videos/Qvxp3Jnv-483.mp4', 142 type:'bitgravity', 143 height:240, 144 width:400 145 }, 146 13: { 147 title:'RTMP streamed FLV', 148 file:'videos/Qvxp3Jnv-68183.flv', 149 type:'rtmp', 150 streamer:'rtmp://fms.12E5.edgecastcdn.net/0012E5', 151 height:240, 152 width:400 153 }, 154 14: { 155 title:'RTMP streamed MP4', 156 file:'videos/Qvxp3Jnv-483.mp4', 157 type:'rtmp', 158 streamer:'rtmp://fms.12E5.edgecastcdn.net/0012E5', 159 height:240, 160 width:400 161 }, 162 15: { 163 title:'RTMP streamed MP3', 164 file:'videos/Qvxp3Jnv-68182.mp3', 165 type:'rtmp', 166 streamer:'rtmp://fms.12E5.edgecastcdn.net/0012E5', 167 height:240, 168 width:400 169 }, 170 16: { 171 title:'Smooth streamed MP4', 172 file:'http://h264.code-shop.com:8080/bbb.mp4/bbb.ismc', 173 type:'smooth', 174 height:240, 175 width:500 176 }, 177 20: {}, 178 21: { 132 179 title:'ASX playlist', 133 180 file:'files/asx.xml', … … 137 184 playlistsize:400 138 185 }, 139 12: {186 22: { 140 187 title:'ATOM playlist', 141 188 file:'files/atom.xml', … … 145 192 playlistsize:400 146 193 }, 147 13: {194 23: { 148 195 title:'iRSS playlist', 149 196 file:'files/irss.xml', … … 153 200 playlistsize:400 154 201 }, 155 14: {202 24: { 156 203 title:'mRSS playlist', 157 204 file:'files/mrss.xml', … … 161 208 playlistsize:400 162 209 }, 163 15: {210 25: { 164 211 title:'SMIL playlist', 165 212 file:'files/smil.xml', … … 169 216 playlistsize:400 170 217 }, 171 16: {218 26: { 172 219 title:'XSPF playlist', 173 220 file:'files/xspf.xml', … … 177 224 playlistsize:400 178 225 }, 179 20: {}, 180 21: { 226 30: {}, 227 31: { 228 title:'Youtube playlist', 229 file:'http://gdata.youtube.com/feeds/api/standardfeeds/recently_featured?v=2', 230 height:240, 231 width:800, 232 playlist:'right', 233 playlistsize:400 234 }, 235 32: { 236 title:'Multibitrate playlist', 237 file:'files/bitrates.xml', 238 height:240, 239 width:800, 240 playlist:'right', 241 playlistsize:400, 242 plugins:'qualitymonitor' 243 }, 244 33: { 245 title:'Chapter playlist', 246 file:'files/chapters.xml', 247 height:240, 248 width:800, 249 playlist:'right', 250 playlistsize:400 251 }, 252 40: {}, 253 41: { 181 254 title:'Different colors', 182 file:'files/ bunnies.xml',255 file:'files/mrss.xml', 183 256 height:240, 184 257 width:800, … … 190 263 screencolor:'FFFFFF' 191 264 }, 192 22: {265 42: { 193 266 title:'Logo, title and no click', 194 file:'files/ bunnies.xml',267 file:'files/mrss.xml', 195 268 height:240, 196 269 width:800, … … 202 275 controlbar:'over' 203 276 }, 204 23: {277 43: { 205 278 title:'Autostart, shuffle and repeat', 206 file:'files/ bunnies.xml',279 file:'files/mrss.xml', 207 280 repeat:'always', 208 281 height:240, … … 216 289 playlistsize:400 217 290 }, 218 24: {291 44: { 219 292 title:'Stretched, stacked and muted', 220 file:'files/ bunnies.xml',293 file:'files/mrss.xml', 221 294 stretching:'fill', 222 295 height:240, … … 227 300 playlistsize:400 228 301 }, 229 25: {302 45: { 230 303 title:'Loading from config xml', 231 304 config:'files/config.xml', … … 233 306 width:500 234 307 }, 235 26: {308 46: { 236 309 title:'Start and duration flashvars', 237 310 file:'files/bunny.mp3', … … 243 316 autostart:'true' 244 317 }, 245 30: {},246 33: {247 title:'HTTP streamed FLV',248 file:'bunny.flv',249 streamer:'http://www.longtailvideo.com/jw/embed/xmoov.php',250 type:'http',251 height:240,252 width:400253 },254 34: {255 title:'Bitgravity streamed FLV',256 file:'http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/ntPYsD4L-326.flv',257 type:'bitgravity',258 displaytitle:'true',259 height:240,260 width:400261 },262 35: {263 title:'Bitgravity streamed MP4',264 file:'http://bitcast-a.bitgravity.com/botr/ifNSlhVa/videos/ntPYsD4L-327.mp4',265 type:'bitgravity',266 height:240,267 width:400268 },269 36: {270 title:'Highwinds streamed MP4',271 file:'http://hwcdn.net/i6s8g7u7/fms/ifNSlhVa/videos/YcCs0JoR-327.mp4',272 type:'highwinds',273 height:240,274 width:400275 },276 37: {277 title:'Livestream demo',278 file:'http://www.livestream.com/builtin',279 height:240,280 width:400281 },282 38: {283 title:'S3 Authenticated Video',284 file:'http%3A%2F%2Fcontent.longtailvideo.com%2Fvideos%2Fauthenticate.flv%3FAWSAccessKeyId%3DAKIAIMO2UYBVC6GA3WYQ%26Expires%3D1279755021%26Signature%3DOESMzl5TB%252Ff7rrSs18%252B52nPy9ww%253D',285 type:'video',286 height:240,287 width:400288 },289 39: {290 title:'Smooth stream',291 file:'files/smooth.ismc',292 height:240,293 width:400294 },295 318 50: {}, 296 319 51: { … … 311 334 }, 312 335 53: { 313 title:'Captions plugin (embedded captions)', 314 file:'../../testing/files/bunny.mp4', 315 height:240, 316 width:500, 317 plugins:'captions' 336 title:'Infobox and logobox plugins', 337 file:'files/mrss.xml', 338 height:320, 339 width:400, 340 plugins:'infobox,logobox', 341 'logobox.file':'files/watermark.png', 342 'logobox.link':'http://www.longtailvideo.com', 318 343 }, 319 344 54: { … … 331 356 width:500, 332 357 plugins:'hd', 333 'hd.file':'../../testing/files/bunny.m 4v'358 'hd.file':'../../testing/files/bunny.mp4' 334 359 }, 335 360 56: { 336 361 title:'Livestream plugin', 337 file:' ../../testing/files/bunny.flv',362 file:'files/bunny.png', 338 363 height:260, 339 364 width:500, 340 365 plugins:'livestream', 341 'livestream.file':'v doxadmin/jeroen/bunny.flv',366 'livestream.file':'videos/Qvxp3Jnv-483.mp4', 342 367 'livestream.image':'files/bunny.jpg', 343 'livestream.streamer':'rtmp://f l9.maelstrom.jet-stream.nl:80/vod/'368 'livestream.streamer':'rtmp://fms.12E5.edgecastcdn.net/0012E5' 344 369 }, 345 370 57: { … … 368 393 image:'files/bunny.jpg', 369 394 stretching:'fill', 395 playlist:'over', 370 396 height:260, 371 397 width:460, 372 plugins:'searchbar', 373 'searchbar.script':'files/bunnies.xml' 398 plugins:'searchbar' 374 399 }, 375 400 60: { … … 380 405 width:460, 381 406 plugins:'sharing', 382 'sharing.code':' %3Cembed%20src%3D%22http%3A%2F%2Fcontent.bitsontherun.com%2Fplayers%2FnPripu9l-1754.swf%22%20width%3D%22400%22%20height%3D%22250%22%20allowscriptaccess%3D%22always%22%20%2F%3E',407 'sharing.code':'<embed src="http://content.bitsontherun.com/players/nPripu9l-1754.swf" width="400" height="250" allowscriptaccess="always" />', 383 408 'sharing.link':'http://www.bigbuckbunny.org/' 384 409 }, 385 410 61: { 386 411 title:'Snapshot plugin', 387 file:'../../testing/files/bunny.m 4v',412 file:'../../testing/files/bunny.mp4', 388 413 height:260, 389 414 width:600, 390 415 plugins:'snapshot', 391 416 'snapshot.script':'http://www.jeroenwijering.com/test/snapshot/create.php' 392 },393 62: {394 title:'Infobox and logobox plugins',395 file:'files/mrss.xml',396 height:320,397 width:400,398 plugins:'infobox,logobox',399 'logobox.file':'files/logobox.png',400 'logobox.link':'http://www.jamitnews.com',401 },402 80: {},403 81: {404 title:'Playlist with streamers',405 file:'files/streamers.xml',406 height:240,407 width:800,408 playlist:'right',409 playlistsize:400,410 frontcolor:'000000',411 lightcolor:'77AA22'412 },413 82: {414 title:'Playlist with chapters',415 file:'files/chapters.xml',416 height:240,417 width:800,418 playlist:'right',419 playlistsize:400,420 streamer:'bitgravity',421 frontcolor:'000000',422 lightcolor:'77AA22'423 },424 83:{425 title:'Playlist from youtube',426 file:'http://gdata.youtube.com/feeds/api/standardfeeds/recently_featured?v=2',427 height:240,428 width:800,429 playlist:'right',430 playlistsize:400431 417 } 432 418 } -
trunk/as3/com/jeroenwijering/events/ModelEvent.as
r338 r374 18 18 public static var LOADED:String = "LOADED"; 19 19 public static var META:String = "META"; 20 public static var QUALITY:String = "QUALITY";21 20 public static var STATE:String = "STATE"; 22 21 public static var TIME:String = "TIME"; -
trunk/as3/com/jeroenwijering/models/AbstractModel.as
r166 r374 7 7 import com.jeroenwijering.events.*; 8 8 import com.jeroenwijering.player.Model; 9 import com.jeroenwijering.utils.Stretcher; 10 11 import flash.display.Sprite; 9 12 10 13 11 public class AbstractModel {14 public class AbstractModel extends Sprite { 12 15 13 16 … … 28 31 public function AbstractModel(mod:Model):void { 29 32 model = mod; 33 mouseEnabled = false; 30 34 }; 31 35 … … 48 52 /** Resume playback of the item. **/ 49 53 public function play():void {}; 54 55 56 /** Handle a resize of the display. **/ 57 public function resize():void { 58 Stretcher.stretch(this, 59 model.config['width'], 60 model.config['height'], 61 model.config['stretching'] 62 ); 63 }; 50 64 51 65 -
trunk/as3/com/jeroenwijering/models/HTTPModel.as
r354 r374 19 19 20 20 21 /** Offset in bytes of the last seek. **/ 22 private var byteoffset:Number = 0; 23 /** Save if the bandwidth checkin already occurs. **/ 24 private var bwcheck:Boolean; 25 /** Switch on startup if the bandwidth is not enough. **/ 26 private var bwswitch:Boolean = true; 21 27 /** NetConnection object for setup of the video stream. **/ 22 28 private var connection:NetConnection; 23 /** NetStream instance that handles the stream IO. **/24 private var stream:NetStream;25 /** Video object to be instantiated. **/26 private var video:Video;27 /** Sound control object. **/28 private var transform:SoundTransform;29 29 /** ID for the position interval. **/ 30 30 private var interval:Number; 31 /** Object with keyframe times and positions. **/ 32 private var keyframes:Object; 31 33 /** Interval ID for the loading. **/ 32 34 private var loadinterval:Number; 33 35 /** Save whether metadata has already been sent. **/ 34 36 private var meta:Boolean; 35 /** Object with keyframe times and positions. **/36 private var keyframes:Object;37 /** Offset in bytes of the last seek. **/38 private var byteoffset:Number;39 /** Offset in seconds of the last seek. **/40 private var timeoffset:Number;41 37 /** Boolean for mp4 / flv streaming. **/ 42 38 private var mp4:Boolean; 43 /** Load offset for bandwidth checking. **/44 private var loadtimer:Number;45 /** Variable that takes reloading into account. **/46 private var iterator:Number;47 39 /** Start parameter. **/ 48 40 private var startparam:String = 'start'; 41 /** NetStream instance that handles the stream IO. **/ 42 private var stream:NetStream; 43 /** Offset in seconds of the last seek. **/ 44 private var timeoffset:Number = 0; 45 /** Sound control object. **/ 46 private var transformer:SoundTransform; 47 /** Video object to be instantiated. **/ 48 private var video:Video; 49 49 50 50 … … 61 61 stream.bufferTime = model.config['bufferlength']; 62 62 stream.client = new NetClient(this); 63 transformer = new SoundTransform(); 63 64 video = new Video(320,240); 64 65 video.smoothing = model.config['smoothing']; 65 66 video.attachNetStream(stream); 66 transform = new SoundTransform(); 67 byteoffset = timeoffset = 0; 67 addChild(video); 68 68 }; 69 69 … … 89 89 90 90 91 /** Bandwidth is checked every four seconds as long as there's loading. **/ 92 private function getBandwidth(old:Number):void { 93 var ldd:Number = stream.bytesLoaded; 94 var bdw:Number = Math.round((ldd-old)*4/1000); 95 if(ldd < stream.bytesTotal) { 96 if(bdw > 0) { model.config['bandwidth'] = bdw; } 97 if(bwswitch) { 98 bwswitch = false; 99 if(getLevel() != model.config['level']) { 100 byteoffset = -1; 101 seek(position); 102 return; 103 } 104 } 105 setTimeout(getBandwidth,2000,ldd); 106 } 107 }; 108 109 110 /** Return which level best fits the display width and connection bandwidth. **/ 111 private function getLevel():Number { 112 var lvl:Number = item['levels'].length-1; 113 for (var i:Number=0; i<item['levels'].length; i++) { 114 if(model.config['width'] >= item['levels'][i].width && 115 model.config['bandwidth'] >= item['levels'][i].bitrate) { 116 lvl = i; 117 break; 118 } 119 } 120 return lvl; 121 }; 122 123 91 124 /** Return a keyframe byteoffset or timeoffset. **/ 92 125 private function getOffset(pos:Number,tme:Boolean=false):Number { … … 115 148 } 116 149 if(item['streamer']) { 117 url = item['streamer']; 118 url = getURLConcat(url,'file',item['file']); 150 if(item['streamer'].indexOf('/') > 0) { 151 url = item['streamer']; 152 url = getURLConcat(url,'file',item['file']); 153 } else { 154 startparam = item['streamer']; 155 } 119 156 } 120 157 if(mp4) { … … 147 184 item = itm; 148 185 position = timeoffset; 149 model.mediaHandler(video); 186 bwcheck = false; 187 if(item['levels']) { 188 model.config['level'] = getLevel(); 189 item['file'] = item['levels'][model.config['level']].url; 190 } 150 191 stream.play(getURL()); 151 iterator = 0;152 192 clearInterval(interval); 153 193 interval = setInterval(positionInterval,100); … … 155 195 loadinterval = setInterval(loadHandler,200); 156 196 model.config['mute'] == true ? volume(0): volume(model.config['volume']); 157 model.sendEvent(ModelEvent.BUFFER,{percentage:0});158 197 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 159 198 }; … … 171 210 clearInterval(loadinterval); 172 211 } 173 if(!loadtimer) { 174 loadtimer = setTimeout(loadTimeout,3000); 175 } 176 }; 177 178 179 /** timeout for checking the bitrate. **/ 180 private function loadTimeout():void { 181 var obj:Object = new Object(); 182 obj['bandwidth'] = Math.round(stream.bytesLoaded/1024/3*8); 183 if(item['duration']) { 184 obj['bitrate'] = Math.round(stream.bytesTotal/1024*8/item['duration']); 185 } 186 model.sendEvent('META',obj); 212 if(ldd > 0 && !bwcheck) { 213 bwcheck = true; 214 setTimeout(getBandwidth,2000,ldd); 215 } 187 216 }; 188 217 189 218 190 219 /** Get metadata information from netstream class. **/ 191 public function on Data(dat:Object):void {220 public function onClientData(dat:Object):void { 192 221 if(dat.width) { 193 222 video.width = dat.width; 194 223 video.height = dat.height; 224 super.resize(); 225 } 226 if(!item['duration'] && dat.duration) { 227 item['duration'] = dat.duration; 195 228 } 196 229 if(dat['type'] == 'metadata' && !meta) { … … 229 262 /** Interval for the position progress **/ 230 263 private function positionInterval():void { 231 iterator++; 232 if(iterator > 10) { 233 position = Math.round(stream.time*10)/10; 234 if (mp4) { 235 position += timeoffset; 236 } 237 } 238 var bfr:Number = Math.round(stream.bufferLength/stream.bufferTime*100); 239 if(bfr < 95 && position < Math.abs(item['duration']-stream.bufferTime-1)) { 240 model.sendEvent(ModelEvent.BUFFER,{percentage:bfr}); 241 if(model.config['state'] != ModelStates.BUFFERING && bfr < 25) { 242 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 243 } 244 } else if (bfr > 95 && model.config['state'] != ModelStates.PLAYING) { 264 var pos:Number = Math.round(stream.time*10)/10; 265 if(pos > position - timeoffset + 5) { 266 pos = position - timeoffset + 0.1; 267 } 268 if (mp4) { 269 pos += timeoffset; 270 } 271 var bfr:Number = stream.bufferLength/stream.bufferTime; 272 if(bfr < 0.5 && pos < item['duration']-5 && model.config['state'] != ModelStates.BUFFERING) { 273 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 274 } else if (bfr > 1 && model.config['state'] != ModelStates.PLAYING) { 245 275 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING}); 246 276 } 247 if(position < item['duration'] + 10) { 248 model.sendEvent(ModelEvent.TIME,{position:position,duration:item['duration']}); 277 if(pos < item['duration'] + 10) { 278 if(pos != position) { 279 model.sendEvent(ModelEvent.TIME,{position:pos,duration:item['duration']}); 280 position = pos; 281 } 249 282 } else if (item['duration'] > 0) { 250 283 stream.pause(); 251 284 clearInterval(interval); 252 285 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.COMPLETED}); 286 } 287 }; 288 289 290 /** The stage has been resize. **/ 291 override public function resize():void { 292 super.resize(); 293 if(item['levels'] && getLevel() != model.config['level']) { 294 byteoffset = getOffset(position); 295 timeoffset = position = getOffset(position,true); 296 load(item); 253 297 } 254 298 }; … … 301 345 if(stream.bytesLoaded+byteoffset < stream.bytesTotal) { 302 346 stream.close(); 303 } else { 347 } else { 304 348 stream.pause(); 305 349 } … … 313 357 314 358 315 /** Set the volume level. **/359 /** Set the volume. **/ 316 360 override public function volume(vol:Number):void { 317 transform .volume = vol/100;318 stream.soundTransform = transform ;361 transformer.volume = vol/100; 362 stream.soundTransform = transformer; 319 363 }; 320 364 -
trunk/as3/com/jeroenwijering/models/ImageModel.as
r169 r374 32 32 loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,progressHandler); 33 33 loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); 34 addChild(loader); 34 35 }; 35 36 … … 54 55 /** Load and place the image on stage. **/ 55 56 private function loaderHandler(evt:Event):void { 56 model.mediaHandler(loader);57 57 try { 58 58 Bitmap(loader.content).smoothing = true; 59 59 } catch (err:Error) {} 60 60 model.sendEvent(ModelEvent.META,{height:evt.target.height,width:evt.target.width}); 61 resize(); 61 62 play(); 62 63 }; -
trunk/as3/com/jeroenwijering/models/LivestreamModel.as
r342 r374 8 8 import com.jeroenwijering.models.AbstractModel; 9 9 import com.jeroenwijering.player.Model; 10 import com.jeroenwijering.utils.Logger;11 10 12 11 import flash.display.*; … … 21 20 /** URL of the livestream SWF. **/ 22 21 private const LOCATION:String = "http://cdn.livestream.com/chromelessPlayer/wrappers/SimpleWrapper.swf"; 23 /** Testing key for developer.longtailvideo.com. **/ 24 private var key:String = '8Y5Rp-6ikHTF0DaOYmxqBWNv8mAx7FdRjvbf2Kk-xWkAG0JUKJwrfGmnsgDfUlNMHqQUmpBOho4cmCyMKDT41I_H3riecIRlu9f1DNBkwF_We7mGBy3CD1fKSAbltsIn'; 22 25 23 26 24 /** Loader for loading the Livestream API. **/ … … 35 33 public function LivestreamModel(mod:Model):void { 36 34 super(mod); 35 mouseEnabled = true; 37 36 Security.allowDomain('*'); 38 37 loader = new Loader(); 39 38 loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderHandler); 40 39 loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); 40 addChild(loader); 41 41 }; 42 42 … … 44 44 private function applicationHandler(evt:Event):void { 45 45 wrapper = Object(loader.content).application; 46 Logger.log('wrapper loaded: '+wrapper);47 46 wrapper.addEventListener("ready", playerReadyHandler); 48 47 }; … … 56 55 57 56 58 /** Load the YouTube movie. **/57 /** Load the Livestream channel. **/ 59 58 override public function load(itm:Object):void { 60 59 item = itm; 61 60 position = item['start']; 62 model.sendEvent(ModelEvent.BUFFER,{percentage:0});63 61 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 64 62 if(player) { 65 63 play(); 66 64 } else { 65 Security.loadPolicyFile("http://cdn.livestream.com/crossdomain.xml"); 67 66 loader.load(new URLRequest(LOCATION),new LoaderContext(true, 68 67 ApplicationDomain.currentDomain,SecurityDomain.currentDomain)); … … 73 72 /** Livestream player SWF loaded. **/ 74 73 private function loaderHandler(evt:Event):void { 75 Logger.log('swf loaded: '+loader.content);76 74 loader.content.addEventListener('applicationComplete',applicationHandler); 77 };78 79 80 /** Pause the YouTube movie. **/81 override public function pause():void {82 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PAUSED});83 75 }; 84 76 … … 95 87 /** Chromeless player has succesfully loaded. **/ 96 88 private function playerReadyHandler(evt:Event):void { 97 Logger.log('player loaded: '+wrapper.getPlayer());98 89 player = wrapper.getPlayer(); 99 model.mediaHandler(player as DisplayObject);100 90 player.addEventListener("errorEvent", playerErrorHandler); 101 if(model.config['livestream.key']) { 102 player.devKey = model.config['livestream.key']; 103 } else { 104 player.devKey = key; 105 } 91 player.devKey = model.config['livestream.devkey']; 106 92 player.showMuteButton = false; 107 93 player.showPauseButton = false; … … 110 96 player.volumeOverlayEnabled = true; 111 97 player.volume = model.config['volume']/100; 98 resize(); 112 99 play(); 113 100 }; … … 119 106 var msg:String = Object(evt).message; 120 107 model.sendEvent(ModelEvent.ERROR,{message:msg}); 121 };122 123 124 /** Seek to position. **/125 override public function seek(pos:Number):void {126 position = pos;127 play();128 108 }; 129 109 -
trunk/as3/com/jeroenwijering/models/RTMPModel.as
r354 r374 22 22 23 23 24 /** Save if the bandwidth checkin already occurs. **/ 25 private var bwcheck:Boolean; 26 /** Switch if the bandwidth is not enough. **/ 27 private var bwswitch:Boolean = true; 24 28 /** NetConnection object for setup of the video stream. **/ 25 29 private var connection:NetConnection; … … 30 34 /** NetStream instance that handles the stream IO. **/ 31 35 private var stream:NetStream; 36 /** Offset in seconds of the last seek. **/ 37 private var timeoffset:Number = 0; 32 38 /** Sound control object. **/ 33 private var transform :SoundTransform;39 private var transformer:SoundTransform; 34 40 /** Save the location of the XML redirect. **/ 35 41 private var smil:String; 36 /** Save that the video has been started. **/ 37 private var started:Boolean; 38 /** Save that a file is unpublished. **/ 39 private var unpublished:Boolean; 42 /** Save that a stream is streaming. **/ 43 private var streaming:Boolean; 40 44 /** Video object to be instantiated. **/ 41 45 private var video:Video; … … 51 55 connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR,errorHandler); 52 56 connection.objectEncoding = ObjectEncoding.AMF0; 53 connection.client = new Object();57 connection.client = new NetClient(this); 54 58 loader = new URLLoader(); 55 59 loader.addEventListener(Event.COMPLETE, loaderHandler); 56 60 loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,errorHandler); 57 61 loader.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); 62 transformer = new SoundTransform(); 58 63 video = new Video(320,240); 59 64 video.smoothing = model.config['smoothing']; 60 transform = new SoundTransform();65 addChild(video); 61 66 }; 62 67 … … 69 74 70 75 76 /** Bandwidth is checked every four seconds as long as there's loading. **/ 77 private function getBandwidth():void { 78 if(streaming) { 79 connection.call("checkBandwidth",null); 80 } 81 }; 82 83 71 84 /** Extract the correct rtmp syntax from the file string. **/ 72 85 private function getID(url:String):String { 73 86 var ext:String = url.substr(-4); 74 if(ext == '.mp3') { 87 if(model.config['rtmp.prepend'] == false) { 88 return url; 89 } else if(ext == '.mp3') { 75 90 return 'mp3:'+url.substr(0,url.length-4); 76 } else if (ext == '.mp4' || ext == '.mov' || ext == '.aac' || ext == '.m4a' || ext =='.f4v') {91 } else if (ext=='.mp4' || ext=='.mov' || ext=='.m4v' || ext=='.aac' || ext=='.m4a' || ext=='.f4v') { 77 92 return 'mp4:'+url; 78 93 } else if (ext == '.flv') { … … 84 99 85 100 101 /** Return which level best fits the display width and connection bandwidth. **/ 102 private function getLevel():Number { 103 var lvl:Number = item['levels'].length-1; 104 for (var i:Number=0; i<item['levels'].length; i++) { 105 if(model.config['width'] >= item['levels'][i].width && 106 model.config['bandwidth'] >= item['levels'][i].bitrate) { 107 lvl = i; 108 break; 109 } 110 } 111 return lvl; 112 }; 113 114 86 115 /** Load content. **/ 87 116 override public function load(itm:Object):void { 88 117 item = itm; 89 118 position = 0; 90 model.sendEvent(ModelEvent.BUFFER,{percentage:0});119 timeoffset = item['start']; 91 120 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 92 121 if(model.config['rtmp.loadbalance']) { … … 94 123 loader.load(new URLRequest(smil)); 95 124 } else { 96 model.mediaHandler(video);97 125 connection.connect(item['streamer']); 98 126 } … … 105 133 item['streamer'] = xml.children()[0].children()[0].@base.toString(); 106 134 item['file'] = xml.children()[1].children()[0].@src.toString(); 107 model.mediaHandler(video);108 135 connection.connect(item['streamer']); 109 136 }; … … 111 138 112 139 /** Get metadata information from netstream class. **/ 113 public function on Data(dat:Object):void {140 public function onClientData(dat:Object):void { 114 141 if(dat.width) { 115 142 video.width = dat.width; 116 143 video.height = dat.height; 144 super.resize(); 145 model.sendEvent(ModelEvent.META,dat); 146 } 147 if(dat.duration && !item['duration']) { 148 item['duration'] = dat.duration; 117 149 } 118 150 if(dat.type == 'complete') { … … 123 155 stop(); 124 156 } 125 model.sendEvent(ModelEvent.META,dat); 157 if(dat.type == 'bandwidth') { 158 model.config['bandwidth'] = dat.bandwidth; 159 if(item['levels']) { 160 if(!streaming) { 161 setStream(); 162 } 163 setTimeout(getBandwidth,10000); 164 } 165 } 126 166 }; 127 167 … … 132 172 clearInterval(interval); 133 173 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PAUSED}); 134 if(started && item['duration'] == 0) { 135 stop(); 136 } 174 if(stream && item['duration'] == 0) { stop(); } 137 175 }; 138 176 … … 148 186 /** Interval for the position progress. **/ 149 187 private function positionInterval():void { 150 position = Math.round(stream.time*10)/10; 151 var bfr:Number = Math.round(stream.bufferLength/stream.bufferTime*100); 152 if(bfr < 95 && position < Math.abs(item['duration']-stream.bufferTime-1)) { 153 model.sendEvent(ModelEvent.BUFFER,{percentage:bfr}); 154 if(model.config['state'] != ModelStates.BUFFERING && bfr < 20) { 155 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 156 stream.bufferTime = model.config['bufferlength']; 157 model.sendEvent(ModelEvent.META,{bufferlength:model.config['bufferlength']}); 158 } 159 } else if (bfr > 95 && model.config['state'] != ModelStates.PLAYING) { 188 var pos:Number = Math.round((stream.time+timeoffset)*10)/10; 189 var bfr:Number = stream.bufferLength/stream.bufferTime; 190 if(bfr < 0.5 && pos < item['duration']-5 && model.config['state'] != ModelStates.BUFFERING) { 191 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 192 stream.bufferTime = model.config['bufferlength']; 193 } else if (bfr > 1 && model.config['state'] != ModelStates.PLAYING) { 160 194 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING}); 161 195 stream.bufferTime = model.config['bufferlength']*4; 162 model.sendEvent(ModelEvent.META,{bufferlength:model.config['bufferlength']*4}); 163 } 164 if(position < item['duration']) { 165 model.sendEvent(ModelEvent.TIME,{position:position,duration:item['duration']}); 196 } 197 if(pos < item['duration']) { 198 if(pos != position) { 199 model.sendEvent(ModelEvent.TIME,{position:pos,duration:item['duration']}); 200 position = pos; 201 } 166 202 } else if (!isNaN(position) && item['duration'] > 0) { 167 203 stream.pause(); 168 204 clearInterval(interval); 169 if(st arted&& item['duration'] == 0) { stop(); }205 if(stream && item['duration'] == 0) { stop(); } 170 206 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.COMPLETED}); 207 } 208 }; 209 210 211 /** Check if the level must be switched on resize. **/ 212 override public function resize():void { 213 super.resize(); 214 if(getLevel() != model.config['level']) { 215 seek( position); 171 216 } 172 217 }; … … 175 220 /** Seek to a new position. **/ 176 221 override public function seek(pos:Number):void { 177 position = pos; 222 position = 0; 223 timeoffset = pos; 178 224 clearInterval(interval); 179 if(model.config['state'] != ModelStates.PLAYING) { 225 interval = setInterval(positionInterval,100); 226 if(item['levels'] && getLevel() != model.config['level']) { 227 model.config['level'] = getLevel(); 228 item['file'] = item['levels'][model.config['level']].url; 229 } 230 if(model.config['state'] == ModelStates.PAUSED) { 180 231 stream.resume(); 181 232 } 182 interval = setInterval(positionInterval,100); 183 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING}); 184 stream.seek(position); 233 stream.play(getID(item['file']),timeoffset); 234 /*stream.play2({ 235 streamName:getID(item['file']), 236 start:timeoffset, 237 transition:'reset' 238 });*/ 239 streaming = true; 185 240 }; 186 241 … … 197 252 video.attachNetStream(stream); 198 253 model.config['mute'] == true ? volume(0): volume(model.config['volume']); 199 interval = setInterval(positionInterval,100); 200 stream.play(getID(item['file'])); 254 seek(timeoffset); 201 255 }; 202 256 … … 210 264 TEA.decrypt(evt.info.secureToken,model.config['token'])); 211 265 } 212 setStream(); 266 if(!item['levels']) { setStream(); } 267 connection.call("checkBandwidth",null); 213 268 var res:Responder = new Responder(streamlengthHandler); 214 269 connection.call("getStreamLength",res,getID(item['file'])); 215 connection.call("checkBandwidth",null);216 break;217 case 'NetStream.Play.Start':218 if(item['start'] > 0 && !started) { seek(item['start']); }219 started = true;220 270 break; 221 271 case 'NetStream.Seek.Notify': … … 234 284 var msg:String = evt.info.code; 235 285 if(evt.info['description']) { msg = evt.info['description']; } 286 stop(); 236 287 model.sendEvent(ModelEvent.ERROR,{message:msg}); 237 288 } … … 239 290 case 'NetStream.Failed': 240 291 case 'NetStream.Play.StreamNotFound': 241 if(unpublished) { 242 onData({type:'complete'}); 243 unpublished = false; 292 if(!streaming) { 293 onClientData({type:'complete'}); 244 294 } else { 245 295 stop(); … … 252 302 break; 253 303 case 'NetStream.Play.UnpublishNotify': 254 unpublished = true;255 break; 256 } 257 model.sendEvent( ModelEvent.META,evt.info);304 streaming = false; 305 break; 306 } 307 model.sendEvent('META',evt.info); 258 308 }; 259 309 … … 261 311 /** Destroy the stream. **/ 262 312 override public function stop():void { 263 if(stream) { 264 stream.close(); 265 } 313 if(stream.time) { stream.close(); } 314 streaming = false; 266 315 connection.close(); 267 started = false;268 316 clearInterval(interval); 269 317 position = 0; 318 timeoffset = item['start']; 270 319 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.IDLE}); 271 320 if(smil) { … … 277 326 /** Get the streamlength returned from the connection. **/ 278 327 private function streamlengthHandler(len:Number):void { 279 if(len > 0) { onData({type:'streamlength',duration:len}); }328 if(len && !item['duration']) { item['duration'] = len; } 280 329 }; 281 330 … … 283 332 /** Set the volume level. **/ 284 333 override public function volume(vol:Number):void { 285 transform .volume = vol/100;286 if(stream) { 287 stream.soundTransform = transform ;334 transformer.volume = vol/100; 335 if(stream) { 336 stream.soundTransform = transformer; 288 337 } 289 338 }; -
trunk/as3/com/jeroenwijering/models/SmoothModel.as
r355 r374 9 9 import com.jeroenwijering.parsers.SmoothParser; 10 10 import com.jeroenwijering.player.Model; 11 import com.jeroenwijering.utils.Logger; 11 12 12 import flash.display.Sprite;13 13 import flash.events.*; 14 14 import flash.media.*; … … 22 22 /** Currently playing chunk. **/ 23 23 private var chunk:Number; 24 /** Chunk that is up next. **/25 private var next:Number;26 24 /** All available video chunks. **/ 27 25 private var chunks:Array; 28 /** Container that switches the two video objects. **/29 private var container:Sprite;30 26 /** Index metadata of the stream. **/ 31 27 private var index:Object; 32 28 /** ID for the position interval. **/ 33 29 private var interval:Number; 34 /** Currently active level. **/35 private var level:Number = 0;36 /** All available quality levels. **/37 private var levels:Array;38 30 /** Loader that loads the manifest XML file. **/ 39 31 private var loader:URLLoader; 40 32 /** Soundtransform object. **/ 41 private var transform :SoundTransform;33 private var transformer:SoundTransform; 42 34 43 35 … … 45 37 public function SmoothModel(mod:Model):void { 46 38 super(mod); 47 container = new Sprite();48 container.graphics.drawRect(0,0,320,240);49 39 loader = new URLLoader(); 50 40 loader.addEventListener(Event.COMPLETE, loaderHandler); 51 41 loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,errorHandler); 52 42 loader.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); 53 transform = new SoundTransform();43 transformer = new SoundTransform(); 54 44 }; 55 45 … … 62 52 63 53 54 64 55 /** Load content. **/ 65 56 override public function load(itm:Object):void { 66 57 item = itm; 67 level = 0;68 58 chunk = 0; 69 59 position = item['start']; 70 60 if(model.config['mute']) { 71 transform .volume = 0;61 transformer.volume = 0; 72 62 } else { 73 transform .volume = model.config['volume']/100;63 transformer.volume = model.config['volume']/100; 74 64 } 75 65 loader.load(new URLRequest(item['file'])); 76 model.mediaHandler(container);77 model.sendEvent(ModelEvent.BUFFER,{percentage:0});78 66 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 79 67 }; … … 81 69 82 70 /** Load a chunk for playback. **/ 83 private function loadChunk(chk:Number):void { 84 //var url:String = item['file'].substr(0,item['file'].length-3)+'mp4'; 85 var url:String = 'http://h264.code-shop.com:8080/ccc.mp4'; 86 url += '?start='+chunks[chk]['start']; 87 url += '&end='+chunks[chk]['end']; 88 chunks[chk].connection = new NetConnection(); 89 chunks[chk].connection.connect(null); 90 chunks[chk].netstream = new NetStream(chunks[chk].connection); 91 chunks[chk].netstream.client = new Object(); 92 chunks[chk].netstream.soundTransform = transform; 93 chunks[chk].netstream.play(url); 94 chunks[chk].netstream.pause(); 95 chunks[chk].video = new Video(320,240); 96 chunks[chk].video.smoothing = model.config['smoothing']; 97 chunks[chk].video.visible = false; 98 chunks[chk].video.attachNetStream(chunks[chk].netstream); 99 container.addChild(chunks[chk].video); 100 next = chk; 101 }; 102 103 104 /** Start playing a chunk. **/ 105 private function playChunk(chk:Number=0):void { 106 chunks[chk].netstream.resume(); 107 chunks[chk].video.visible = true; 108 chunk = chk; 109 }; 110 111 112 /** Remove the current chunk. **/ 113 private function killChunk(chk:Number):void { 114 if(chunks[chk] && chunks[chk].netstream) { 115 chunks[chk].netstream.close(); 71 private function loadChunk(chk:Number,pse:Boolean=true):void { 72 var url:String = item['file'].substr(0,item['file'].length-5); 73 if(chunks[chk]) { 74 url += '_' + item['levels'][0].bitrate + '.mp4'; 75 url += '?start=' + chunks[chk]['start']; 76 url += '&end=' + chunks[chk]['end']; 77 chunks[chk].connection = new NetConnection(); 78 chunks[chk].connection.connect(null); 79 chunks[chk].netstream = new NetStream(chunks[chk].connection); 80 chunks[chk].netstream.client = new Object(); 81 chunks[chk].netstream.soundTransform = transformer; 82 chunks[chk].netstream.play(url); 83 chunks[chk].netstream.pause(); 84 chunks[chk].netstream.seek(0); 85 chunks[chk].video = new Video(); 86 chunks[chk].video.width = 320; 87 chunks[chk].video.height = 180; 88 chunks[chk].video.attachNetStream(chunks[chk].netstream); 116 89 } 117 90 }; … … 122 95 var xml:XML = XML(evt.target.data); 123 96 index = SmoothParser.parseIndex(xml); 124 model.sendEvent(ModelEvent.META,index);125 levels= SmoothParser.parseLevels(xml);97 item['duration'] = index['duration']; 98 item['levels'] = SmoothParser.parseLevels(xml); 126 99 chunks = SmoothParser.parseChunks(xml); 127 if( levels.length == 0 || chunks.length == 0) {100 if(item['levels'].length == 0 || chunks.length == 0) { 128 101 errorHandler(new ErrorEvent(ErrorEvent.ERROR,false,false, 129 102 "SmoothStreaming manifest contains no quality levels or chunks.")) 130 103 } else { 131 setLevel();132 104 seek(item['start']); 133 105 } … … 151 123 152 124 125 /** Start playing a chunk. **/ 126 private function playChunk(chk:Number=0):void { 127 chunks[chk].netstream.resume(); 128 loadChunk(chk+1); 129 chunk = chk; 130 setTimeout(showChunk,100); 131 }; 132 133 private function showChunk() { 134 addChild(chunks[chunk].video); 135 resize(); 136 }; 137 138 153 139 /** Interval for the position progress **/ 154 140 private function positionInterval():void { 155 var chk:Number = chunk;156 141 var obj:Object = chunks[chunk]; 157 var pos:Number= obj['start']+obj.netstream.time;142 position = obj['start']+obj.netstream.time; 158 143 if(model.config['state'] != ModelStates.PLAYING) { 159 144 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING}); 160 145 } 161 if(pos > obj['end']-0.15) { 162 setTimeout(killChunk,2000,chk); 163 playChunk(chk+1); 164 setTimeout(loadChunk,1000,chk+2); 146 if(position >= obj.end-0.1) { 147 playChunk(chunk+1); 165 148 } 166 if(pos < item['duration']) { 167 pos = Math.round(pos*10)/10; 168 if(pos != position) { 169 position = pos; 170 model.sendEvent(ModelEvent.TIME,{position:pos,duration:item['duration'],chunk:chk}); 171 } 149 if(position < item['duration']) { 150 model.sendEvent(ModelEvent.TIME,{position:position,duration:item['duration'],chunk:chunk}); 172 151 } else if (item['duration'] > 0) { 173 obj.netstream.pause();174 152 clearInterval(interval); 175 153 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.COMPLETED}); … … 182 160 position = pos; 183 161 clearInterval(interval); 184 killChunk(chunk);185 killChunk(next);186 162 for (var i:Number=0; i<chunks.length; i++) { 187 163 if(chunks[i]['end'] > pos && chunks[i]['start'] <= pos) { 188 164 loadChunk(i); 189 165 playChunk(i); 190 setTimeout(loadChunk,1000,i+1);191 166 break; 192 167 } … … 197 172 198 173 199 /** Set a specific stream level. **/200 private function setLevel():void {201 level = 0;202 model.sendEvent(ModelEvent.META,levels[level]);203 };204 205 206 174 /** Destroy the video. **/ 207 175 override public function stop():void { 208 killChunk(chunk);209 killChunk(next);210 176 clearInterval(interval); 211 177 position = item['start']; … … 216 182 /** Set the volume level. **/ 217 183 override public function volume(vol:Number):void { 218 transform .volume = vol/100;219 chunks[chunk].netstream.soundTransform = transform ;184 transformer.volume = vol/100; 185 chunks[chunk].netstream.soundTransform = transformer; 220 186 }; 221 187 -
trunk/as3/com/jeroenwijering/models/SoundModel.as
r210 r374 21 21 private var sound:Sound; 22 22 /** Sound control object. **/ 23 private var transform :SoundTransform;23 private var transformer:SoundTransform; 24 24 /** Sound channel object. **/ 25 25 private var channel:SoundChannel; … … 35 35 public function SoundModel(mod:Model):void { 36 36 super(mod); 37 transform = new SoundTransform();37 transformer = new SoundTransform(); 38 38 context = new SoundLoaderContext(model.config['bufferlength']*1000,true); 39 39 }; … … 98 98 model.sendEvent(ModelEvent.LOADED,{loaded:ldd,total:ttl}); 99 99 if(ldd/ttl > 0.1 && item['duration'] == 0) { 100 model.sendEvent(ModelEvent.META,{duration:sound.length/1000/ldd*ttl});100 item['duration'] = sound.length/1000/ldd*ttl; 101 101 } 102 102 if(ldd == ttl && ldd > 0) { … … 116 116 /** Play the sound. **/ 117 117 override public function play():void { 118 channel = sound.play(position*1000,0,transform );118 channel = sound.play(position*1000,0,transformer); 119 119 channel.addEventListener(Event.SOUND_COMPLETE,completeHandler); 120 120 interval = setInterval(positionInterval,100); … … 167 167 /** Set the volume level. **/ 168 168 override public function volume(vol:Number):void { 169 transform .volume = vol/100;169 transformer.volume = vol/100; 170 170 if(channel) { 171 channel.soundTransform = transform ;171 channel.soundTransform = transformer; 172 172 } 173 173 }; -
trunk/as3/com/jeroenwijering/models/VideoModel.as
r354 r374 8 8 import com.jeroenwijering.models.AbstractModel; 9 9 import com.jeroenwijering.player.Model; 10 import com.jeroenwijering.utils. NetClient;10 import com.jeroenwijering.utils.*; 11 11 12 12 import flash.events.*; … … 19 19 20 20 21 /** Save if the bandwidth checkin already occurs. **/ 22 private var bwcheck:Boolean; 23 /** Switch if the bandwidth is not enough. **/ 24 private var bwswitch:Boolean = true; 25 /** NetConnection object for setup of the video stream. **/ 26 private var connection:NetConnection; 27 /** ID for the position interval. **/ 28 private var interval:Number; 29 /** Interval ID for the loading. **/ 30 private var loading:Number; 31 /** NetStream instance that handles the stream IO. **/ 32 private var stream:NetStream; 33 /** Sound control object. **/ 34 private var transformer:SoundTransform; 21 35 /** Video object to be instantiated. **/ 22 protected var video:Video; 23 /** NetConnection object for setup of the video stream. **/ 24 protected var connection:NetConnection; 25 /** NetStream instance that handles the stream IO. **/ 26 protected var stream:NetStream; 27 /** Sound control object. **/ 28 protected var transform:SoundTransform; 29 /** ID for the position interval. **/ 30 protected var interval:Number; 31 /** Interval ID for the loading. **/ 32 protected var loadinterval:Number; 33 /** Load offset for bandwidth checking. **/ 34 protected var loadtimer:Number; 36 private var video:Video; 35 37 36 38 … … 46 48 stream.bufferTime = model.config['bufferlength']; 47 49 stream.client = new NetClient(this); 50 transformer = new SoundTransform(); 48 51 video = new Video(320,240); 49 52 video.smoothing = model.config['smoothing']; 50 53 video.attachNetStream(stream); 51 transform = new SoundTransform();54 addChild(video); 52 55 }; 53 56 54 57 55 58 /** Catch security errors. **/ 56 pr otectedfunction errorHandler(evt:ErrorEvent):void {59 private function errorHandler(evt:ErrorEvent):void { 57 60 stop(); 58 61 model.sendEvent(ModelEvent.ERROR,{message:evt.text}); 62 }; 63 64 65 /** Bandwidth is checked every four seconds as long as there's loading. **/ 66 private function getBandwidth(old:Number):void { 67 var ldd:Number = stream.bytesLoaded; 68 var bdw:Number = Math.round((ldd-old)*4/1000); 69 if(ldd < stream.bytesTotal) { 70 if(bdw > 0) { model.config['bandwidth'] = bdw; } 71 if(bwswitch) { 72 bwswitch = false; 73 if(getLevel() != model.config['level']) { 74 model.config['level'] = getLevel(); 75 item['file'] = item['levels'][model.config['level']].url; 76 load(item); 77 return; 78 } 79 } 80 setTimeout(getBandwidth,2000,ldd); 81 } 82 }; 83 84 85 /** Return which level best fits the display width and connection bandwidth. **/ 86 private function getLevel():Number { 87 var lvl:Number = item['levels'].length-1; 88 for (var i:Number=0; i<item['levels'].length; i++) { 89 if(model.config['width'] >= item['levels'][i].width && 90 model.config['bandwidth'] >= item['levels'][i].bitrate) { 91 lvl = i; 92 break; 93 } 94 } 95 return lvl; 59 96 }; 60 97 … … 64 101 item = itm; 65 102 position = 0; 66 model.mediaHandler(video); 103 bwcheck = false; 104 if(item['levels']) { 105 model.config['level'] = getLevel(); 106 item['file'] = item['levels'][model.config['level']].url; 107 } 67 108 stream.checkPolicyFile = true; 68 109 stream.play(item['file']); 110 clearInterval(interval); 69 111 interval = setInterval(positionInterval,100); 70 loadinterval = setInterval(loadHandler,200); 112 clearInterval(loading); 113 loading = setInterval(loadHandler,200); 71 114 model.config['mute'] == true ? volume(0): volume(model.config['volume']); 72 model.sendEvent(ModelEvent.BUFFER,{percentage:0});73 115 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 74 116 }; … … 76 118 77 119 /** Interval for the loading progress **/ 78 pr otectedfunction loadHandler():void {120 private function loadHandler():void { 79 121 var ldd:Number = stream.bytesLoaded; 80 122 var ttl:Number = stream.bytesTotal; 81 123 model.sendEvent(ModelEvent.LOADED,{loaded:ldd,total:ttl}); 82 if(ldd == ttl && ldd > 0) { 83 clearInterval(loadinterval); 84 } 85 if(!loadtimer) { 86 loadtimer = setTimeout(loadTimeout,3000); 87 } 88 }; 89 90 91 /** timeout for checking the bitrate. **/ 92 protected function loadTimeout():void { 93 model.sendEvent('META',{ 94 bandwidth:Math.round(stream.bytesLoaded/1024/3*8) 95 }); 124 if(ldd && ldd == ttl) { 125 clearInterval(loading); 126 } 127 if(ldd > 0 && !bwcheck) { 128 bwcheck = true; 129 setTimeout(getBandwidth,2000,ldd); 130 } 96 131 }; 97 132 98 133 99 134 /** Get metadata information from netstream class. **/ 100 public function on Data(dat:Object):void {135 public function onClientData(dat:Object):void { 101 136 if(dat.width) { 102 137 video.width = dat.width; 103 138 video.height = dat.height; 139 resize(); 140 } 141 if(dat.duration && !item['duration']) { 142 item['duration'] = dat.duration; 104 143 } 105 144 model.sendEvent(ModelEvent.META,dat); … … 124 163 125 164 /** Interval for the position progress **/ 126 protected function positionInterval():void { 127 position = Math.round(stream.time*10)/10; 128 var bfr:Number = Math.round(stream.bufferLength/stream.bufferTime*100); 129 if(bfr < 95 && position < Math.abs(item['duration']-stream.bufferTime-1)) { 130 model.sendEvent(ModelEvent.BUFFER,{percentage:bfr}); 131 if(model.config['state'] != ModelStates.BUFFERING && bfr < 25) { 132 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 165 private function positionInterval():void { 166 var pos:Number = Math.round(stream.time*10)/10; 167 var bfr:Number = stream.bufferLength/stream.bufferTime; 168 if(bfr < 0.5 && position < item['duration']-5 && model.config['state'] != ModelStates.BUFFERING) { 169 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 170 } else if (bfr > 1 && model.config['state'] != ModelStates.PLAYING) { 171 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING}); 172 } 173 if(pos < item['duration'] + 10) { 174 if(pos != position) { 175 position = pos; 176 model.sendEvent(ModelEvent.TIME,{position:pos,duration:item['duration']}); 133 177 } 134 } else if (bfr > 95 && model.config['state'] != ModelStates.PLAYING) {135 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING});136 }137 if(position < item['duration'] + 10) {138 model.sendEvent(ModelEvent.TIME,{position:position,duration:item['duration']});139 178 } else if (item['duration']) { 140 179 stream.pause(); … … 155 194 156 195 /** Receive NetStream status updates. **/ 157 pr otectedfunction statusHandler(evt:NetStatusEvent):void {196 private function statusHandler(evt:NetStatusEvent):void { 158 197 switch (evt.info.code) { 159 198 case "NetStream.Play.Stop": … … 179 218 stream.pause(); 180 219 } 181 loadtimer = undefined; 182 clearInterval(loadinterval); 220 clearInterval(loading); 183 221 clearInterval(interval); 184 222 position = 0; … … 187 225 188 226 189 /** Set the volume level. **/227 /** Set the volume. **/ 190 228 override public function volume(vol:Number):void { 191 transform .volume = vol/100;192 stream.soundTransform = transform ;229 transformer.volume = vol/100; 230 stream.soundTransform = transformer; 193 231 }; 194 232 -
trunk/as3/com/jeroenwijering/models/YoutubeModel.as
r183 r374 8 8 import com.jeroenwijering.models.AbstractModel; 9 9 import com.jeroenwijering.player.Model; 10 import com.jeroenwijering.utils.Logger; 10 11 11 12 import flash.display.Loader; … … 14 15 import flash.net.URLRequest; 15 16 import flash.system.Security; 17 import flash.utils.setTimeout; 16 18 17 19 … … 27 29 /** connection from the YT proxy. **/ 28 30 private var inbound:LocalConnection; 29 /** Save that the meta has been sent. **/30 private var metasent:Boolean;31 31 /** Save that a load call has been sent. **/ 32 32 private var loading:Boolean; 33 33 /** Save the connection state. **/ 34 34 private var connected:Boolean; 35 /** URL of a custom youtube swf. **/36 private var location:String;37 35 38 36 … … 41 39 super(mod); 42 40 Security.allowDomain('*'); 43 var url:String = model.display.loaderInfo.url;44 if(url.indexOf('http://') == 0) {45 unique = Math.random().toString().substr(2);46 var str:String = url.substr(0,url.indexOf('.swf'));47 location = str.substr(0,str.lastIndexOf('/')+1)+'yt.swf?unique='+unique;48 } else {49 unique = '1';50 location = 'yt.swf';51 }52 41 outgoing = new LocalConnection(); 53 42 outgoing.allowDomain('*'); … … 58 47 inbound.allowInsecureDomain('*'); 59 48 inbound.addEventListener(StatusEvent.STATUS,onLocalConnectionStatusChange); 60 //inbound.addEventListener(AsyncErrorEvent.ASYNC_ERROR,errorHandler);61 49 inbound.client = this; 62 50 loader = new Loader(); 63 51 loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); 52 addChild(loader); 64 53 }; 65 54 … … 89 78 90 79 80 /** Get the location of yt.swf. **/ 81 private function getLocation():String { 82 var loc:String; 83 var url:String = loaderInfo.url; 84 if(url.indexOf('http://') == 0) { 85 unique = Math.random().toString().substr(2); 86 loc = url.substr(0,url.indexOf('.swf')); 87 loc = loc.substr(0,loc.lastIndexOf('/')+1)+'yt.swf?unique='+unique; 88 } else { 89 unique = '1'; 90 loc = 'yt.swf'; 91 } 92 return loc; 93 }; 94 91 95 /** Load the YouTube movie. **/ 92 96 override public function load(itm:Object):void { … … 97 101 if(outgoing) { 98 102 var gid = getID(item['file']); 99 resize(model.config['width'],model.config['width']/4*3);100 103 outgoing.send('AS3_'+unique,"loadVideoById",gid,item['start']); 101 model.mediaHandler(loader);104 resize(); 102 105 } 103 106 } else { 107 loader.load(new URLRequest(getLocation())); 104 108 inbound.connect('AS2_'+unique); 105 loader.load(new URLRequest(location)); 106 } 107 model.sendEvent(ModelEvent.BUFFER,{percentage:0}); 109 } 108 110 model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING}); 109 111 }; … … 134 136 135 137 /** error was thrown without this handler **/ 136 public function onLocalConnectionStatusChange(evt:StatusEvent):void { 137 // model.sendEvent(ModelEvent.META,{status:evt.code}); 138 }; 138 public function onLocalConnectionStatusChange(evt:StatusEvent):void {}; 139 139 140 140 141 141 /** Catch youtube errors. **/ 142 public function onError(erc:String):void { 143 model.sendEvent(ModelEvent.ERROR,{message:"YouTube error (video not found?):\n"+item['file']}); 142 public function onError(erc:Number):void { 144 143 stop(); 144 var msg:String = 'Video not found or deleted: ' + getID(item['file']); 145 if(erc == 101 || erc == 150) { 146 msg = 'Embedding this video is disabled by its owner.'; 147 } 148 model.sendEvent(ModelEvent.ERROR,{message:msg}); 145 149 }; 146 150 … … 149 153 public function onStateChange(stt:Number):void { 150 154 switch(Number(stt)) { 151 case -1:152 // model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.IDLE});153 break;154 155 case 0: 155 156 if(model.config['state'] != ModelStates.BUFFERING && model.config['state'] != ModelStates.IDLE) { … … 180 181 public function onTimeChange(pos:Number,dur:Number):void { 181 182 model.sendEvent(ModelEvent.TIME,{position:pos,duration:dur}); 182 if(!metasent) { 183 model.sendEvent(ModelEvent.META,{width:320,height:240,duration:dur}); 184 metasent = true; 185 } 183 if(!item['duration']) { item['duration'] = dur; } 184 186 185 }; 187 186 188 187 189 188 /** Resize the YT player. **/ 190 public function resize(wid:Number,hei:Number){191 outgoing.send('AS3_'+unique,"setSize", wid,hei);189 override public function resize():void { 190 outgoing.send('AS3_'+unique,"setSize",model.config['width'],model.config['height']); 192 191 }; 193 192 … … 202 201 /** Destroy the youtube video. **/ 203 202 override public function stop():void { 204 metasent = false;205 203 outgoing.send('AS3_'+unique,"stopVideo"); 206 204 position = 0; -
trunk/as3/com/jeroenwijering/parsers/ASXParser.as
r161 r374 6 6 7 7 import com.jeroenwijering.parsers.JWParser; 8 import com.jeroenwijering.parsers.MediaParser; 8 9 import com.jeroenwijering.utils.Strings; 9 10 … … 56 57 } 57 58 } 59 itm = MediaParser.parseGroup(obj,itm); 58 60 itm = JWParser.parseEntry(obj,itm); 59 61 return itm; -
trunk/as3/com/jeroenwijering/parsers/MediaParser.as
r211 r374 42 42 itm = MediaParser.parseGroup(i,itm); 43 43 } 44 if(i.@width && i.@bitrate) { 45 if(!itm.levels) { 46 itm.levels = new Array(); 47 } 48 itm.levels.push({ 49 width:i.@width.toString(), 50 bitrate:i.@bitrate.toString(), 51 url:i.@url.toString() 52 }); 53 } 44 54 break; 45 55 case 'title': -
trunk/as3/com/jeroenwijering/parsers/SmoothParser.as
r338 r374 45 45 for each (var i:XML in dat.children()[0].children()) { 46 46 if (i.localName().toLowerCase() == 'qualitylevel') { 47 var obj:Object = new Object(); 48 for(var j:Number=0; j<i.@*.length(); j++) { 49 obj[i.@*[j].name().toString().toLowerCase()] = i.@*[j].toString(); 50 } 47 var obj:Object = { 48 bitrate:Number(i.@Bitrate.toString())/1000, 49 width:Number(i.@Width.toString())/1, 50 height:Number(i.@Height.toString())/1 51 }; 51 52 Logger.log(obj); 52 53 arr.push(obj); -
trunk/as3/com/jeroenwijering/parsers/XSPFParser.as
r161 r374 6 6 7 7 import com.jeroenwijering.parsers.JWParser; 8 import com.jeroenwijering.parsers.MediaParser; 8 9 import com.jeroenwijering.utils.Strings; 9 10 … … 58 59 } 59 60 } 61 itm = MediaParser.parseGroup(obj,itm); 60 62 itm = JWParser.parseEntry(obj,itm); 61 63 return itm; -
trunk/as3/com/jeroenwijering/player/Controller.as
r354 r374 55 55 'sdp':'video', 56 56 'swf':'image', 57 'vp6':'video', 58 'smc':'smooth' 57 'vp6':'video' 59 58 }; 60 59 /** Elements of config that are part of the playlist. **/ … … 99 98 public function closeMVC(mdl:Model,vie:View):void { 100 99 model= mdl; 101 model.addEventListener(ModelEvent.META,metaHandler);102 100 model.addEventListener(ModelEvent.STATE,stateHandler); 103 101 view = vie; … … 136 134 /** Set the fullscreen rectangle **/ 137 135 private function fullscreenrect():void { 138 var srx:Number = Capabilities.screenResolutionX;139 var asr:Number = srx/Capabilities.screenResolutionY;140 136 var pnt:Point = skin.parent.localToGlobal(new Point(skin.x,skin.y)); 141 try { 142 var wid:Number = playlist[config['item']]['width']; 143 } catch (err:Error) {} 144 if(wid && wid > srx) { 145 skin.stage["fullScreenSourceRect"] = new Rectangle(pnt.x,pnt.y,srx,Capabilities.screenResolutionY); 146 } else if(wid && wid > srx/2) { 147 skin.stage["fullScreenSourceRect"] = new Rectangle(pnt.x,pnt.y,wid,Math.round(wid/asr)); 148 } else { 149 skin.stage["fullScreenSourceRect"] = new Rectangle(pnt.x,pnt.y,srx/2,Capabilities.screenResolutionY/2); 150 } 137 skin.stage["fullScreenSourceRect"] = new Rectangle( 138 pnt.x, 139 pnt.y, 140 Capabilities.screenResolutionX, 141 Capabilities.screenResolutionY 142 ); 151 143 }; 152 144 … … 274 266 275 267 276 /** Update playlist item duration. **/277 private function metaHandler(evt:ModelEvent):void {278 if(evt.data.duration && playlist[config['item']]['duration'] == 0) {279 playlist[config['item']]['duration'] = evt.data.duration;280 }281 if(evt.data.width) {282 playlist[config['item']]['width'] = evt.data.width;283 playlist[config['item']]['height'] = evt.data.height;284 }285 };286 287 288 268 /** Save new state of the mute switch and send volume. **/ 289 269 private function muteHandler(evt:ViewEvent):void { … … 374 354 if (config['item'] == 0) { 375 355 playItem(playlist.length-1); 376 } else { 356 } else { 377 357 playItem(config['item']-1); 378 358 } … … 385 365 var dps:String = skin.stage['displayState']; 386 366 } catch (err:Error) {} 387 if(dps == 'fullScreen' && config['resizing']) {367 if(dps == 'fullScreen') { 388 368 config['fullscreen'] = true; 389 369 sploader.layoutFullscreen(); 390 370 } else { 391 if(config['resizing']) { 392 config['width'] = skin.stage.stageWidth; 393 config['height'] = skin.stage.stageHeight; 394 } 371 config['width'] = skin.stage.stageWidth; 372 config['height'] = skin.stage.stageHeight; 395 373 config['fullscreen'] = false; 396 374 sploader.layoutNormal(); … … 431 409 private function stateHandler(evt:ModelEvent):void { 432 410 if(evt.data.newstate == ModelStates.COMPLETED) { 433 if(config['oncomplete'] == 'link') {434 linkHandler();435 }436 411 switch (config['repeat']) { 437 412 case 'single': -
trunk/as3/com/jeroenwijering/player/Model.as
r331 r374 21 21 /** Object with all configuration variables. **/ 22 22 public var config:Object; 23 /** Reference to the display MovieClip. **/ 24 public var display:MovieClip; 25 /** Object with all display variables. **/ 26 private var sploader:SPLoader; 23 /** Reference to the media element. **/ 24 public var media:Sprite; 27 25 /** Reference to the player's controller. **/ 28 26 private var controller:Controller; … … 40 38 public function Model(cfg:Object,skn:MovieClip,ldr:SPLoader,ctr:Controller):void { 41 39 config = cfg; 42 display = MovieClip(skn.getChildByName('display'));43 sploader = ldr;44 40 controller = ctr; 45 41 controller.addEventListener(ControllerEvent.ITEM,itemHandler); … … 51 47 controller.addEventListener(ControllerEvent.STOP,stopHandler); 52 48 controller.addEventListener(ControllerEvent.VOLUME,volumeHandler); 49 models = new Object(); 53 50 thumb = new Loader(); 54 51 thumb.contentLoaderInfo.addEventListener(Event.COMPLETE,thumbHandler); 55 52 thumb.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,thumbHandler); 56 Draw.clear(display.media); 57 display.addChildAt(thumb,display.getChildIndex(display.media)); 58 display.media.visible = false; 59 models = new Object(); 53 var dpl:MovieClip = skn.getChildByName('display') as MovieClip; 54 media = dpl.media as Sprite; 55 media.visible = false; 56 Draw.clear(media); 57 dpl.addChildAt(thumb,dpl.getChildIndex(media)); 60 58 }; 61 59 … … 66 64 }; 67 65 66 /** Check if the currently playing item is audio only. **/ 67 private function audioOnly():Boolean { 68 var ext:String = item['file'].substr(-3); 69 if(ext == 'm4a' || ext == 'mp3' || ext == 'aac') { 70 return true; 71 } else { 72 return false; 73 } 74 }; 75 68 76 69 77 /** Item change: stop the old model and start the new one. **/ … … 71 79 if(item) { 72 80 models[item['type']].stop(); 81 media.removeChild(models[item['type']]); 73 82 } 74 83 item = controller.playlist[config['item']]; 75 84 if(models[item['type']]) { 85 media.addChild(models[item['type']]); 76 86 models[item['type']].load(item); 77 87 } else { … … 90 100 91 101 92 /**93 * Place the mediafile fro the current model on stage.94 *95 * @param obj The displayobject (MovieClip/Video/Loader) to display.96 **/97 public function mediaHandler(obj:DisplayObject=undefined):void {98 Draw.clear(display.media);99 display.media.addChild(obj);100 resizeHandler();101 };102 103 104 102 /** Make the current model toggle its mute state. **/ 105 103 private function muteHandler(evt:ControllerEvent):void { … … 119 117 if(evt.data.state == true) { 120 118 models[item['type']].play(); 121 } else { 119 } else { 122 120 models[item['type']].pause(); 123 121 } … … 126 124 127 125 128 /** Load a new thumbnail.**/126 /** Load a thumb; either from the playlist or (if there) player-wide. **/ 129 127 private function playlistHandler(evt:ControllerEvent):void { 130 128 var img:String = controller.playlist[config['item']]['image']; … … 137 135 138 136 /** Resize the media and thumb. **/ 139 private function resizeHandler(evt:Event=null):void { 140 var wid:Number = sploader.getPlugin('display').config['width']; 141 var hei:Number = sploader.getPlugin('display').config['height']; 142 Stretcher.stretch(display.media,wid,hei,config['stretching']); 143 if(thumb.width > 10 && wid > 10) { 144 Stretcher.stretch(thumb,wid,hei,config['stretching']); 145 } 137 private function resizeHandler(evt:ControllerEvent):void { 138 if(thumb.width) { thumbResize(); }; 139 if(item) { models[item['type']].resize(); } 146 140 }; 147 141 … … 163 157 164 158 165 /** 159 /** 166 160 * Dispatch events to the View/ Controller. 167 161 * When switching states, the thumbnail is shown/hidden. … … 173 167 public function sendEvent(typ:String,dat:Object):void { 174 168 if(typ == ModelEvent.STATE) { 175 if(dat.newstate == config['state']) {176 return;177 }178 169 dat['oldstate'] = config['state']; 179 170 config['state'] = dat.newstate; … … 182 173 sendEvent(ModelEvent.LOADED,{loaded:0,offset:0,total:0}); 183 174 case ModelStates.COMPLETED: 184 if(config['oncomplete'] != 'none') { 185 thumb.visible = true; 186 display.media.visible = false; 187 sendEvent(ModelEvent.TIME,{position:item['start'],duration:item['duration']}); 188 } 175 thumb.visible = true; 176 media.visible = false; 177 sendEvent(ModelEvent.TIME,{position:item['start'],duration:item['duration']}); 189 178 break; 190 179 case ModelStates.PLAYING: 191 if(item['file'].substr(-3) == 'm4a' || 192 item['file'].substr(-3) == 'mp3' || 193 item['file'].substr(-3) == 'aac') { 194 thumb.visible = true; 195 display.media.visible = false; 196 } else { 197 thumb.visible = false; 198 display.media.visible = true; 199 } 180 thumb.visible = audioOnly(); 181 media.visible = !audioOnly(); 200 182 break; 201 183 } 202 } else if(dat.width) {203 resizeHandler();204 184 } 205 185 Logger.log(dat,typ); … … 213 193 Bitmap(thumb.content).smoothing = true; 214 194 } catch (err:Error) {} 215 resizeHandler(); 195 thumbResize(); 196 }; 197 198 199 /** Resize the thumbnail. **/ 200 private function thumbResize():void { 201 Stretcher.stretch(thumb,config['width'],config['height'],config['stretching']); 216 202 }; 217 203 -
trunk/as3/com/jeroenwijering/player/Player.as
r354 r374 48 48 49 49 autostart:false, 50 bandwidth:5000, 50 51 bufferlength:1, 51 52 displayclick:'play', 52 53 fullscreen:false, 53 54 item:0, 55 level:0, 54 56 linktarget:'_blank', 55 57 logo:undefined, 56 58 mute:false, 57 oncomplete:'rewind',58 59 repeat:'none', 59 resizing:true,60 60 shuffle:false, 61 61 smoothing:true, … … 70 70 id:undefined, 71 71 plugins:undefined, 72 version:'4.6. 535'72 version:'4.6.374' 73 73 }; 74 74 /** Reference to all stage graphics. **/ … … 141 141 model.addModel(new HTTPModel(model),'http'); 142 142 model.addModel(new ImageModel(model),'image'); 143 //model.addModel(new LivestreamModel(model),'livestream');143 model.addModel(new LivestreamModel(model),'livestream'); 144 144 model.addModel(new RTMPModel(model),'rtmp'); 145 145 model.addModel(new SmoothModel(model),'smooth'); -
trunk/as3/com/jeroenwijering/player/SPLoader.as
r298 r374 264 264 plugins[overs[j]]['visible'] = true; 265 265 } 266 if(config['resizing']) { 267 config['width'] = bounds.width; 268 config['height'] = bounds.height; 269 } 266 config['width'] = bounds.width; 267 config['height'] = bounds.height; 270 268 }; 271 269 … … 285 283 } 286 284 } 287 if(config['resizing']) { 288 config['width'] = skin.stage.stageWidth; 289 config['height'] = skin.stage.stageHeight; 290 } 285 config['width'] = skin.stage.stageWidth; 286 config['height'] = skin.stage.stageHeight; 291 287 }; 292 288 -
trunk/as3/com/jeroenwijering/player/View.as
r216 r374 43 43 _config['client'] = 'FLASH '+Capabilities.version; 44 44 _skin = skn; 45 if(_config['resizing']) { 46 _skin.stage.scaleMode = "noScale"; 47 _skin.stage.align = "TL"; 48 _skin.stage.addEventListener(Event.RESIZE,resizeHandler); 49 } else { 50 _skin.stage.addEventListener(FullScreenEvent.FULL_SCREEN,resizeHandler); 51 } 45 _skin.stage.scaleMode = "noScale"; 46 _skin.stage.align = "TL"; 47 _skin.stage.addEventListener(Event.RESIZE,resizeHandler); 52 48 sploader = ldr; 53 49 controller = ctr; -
trunk/as3/com/jeroenwijering/plugins/Display.as
r242 r374 69 69 clip.addEventListener(MouseEvent.CLICK,clickHandler); 70 70 clip.buttonMode = true; 71 clip.mouseChildren = false;72 71 } 73 72 if(clip.logo) { -
trunk/as3/com/jeroenwijering/plugins/Playlist.as
r242 r374 298 298 continue; 299 299 } else if(itm == 'image') { 300 if(config['thumbs'] != false && 300 if(config['thumbs'] != false && view.config['playlist'] != 'none' && 301 301 (view.playlist[idx]['image'] || view.playlist[idx]['playlist.image'])) { 302 302 var img:MovieClip = buttons[idx].c.image; -
trunk/as3/com/jeroenwijering/plugins/Rightclick.as
r211 r374 55 55 view = vie; 56 56 view.skin.contextMenu = context; 57 // Add the 'fullscreen' menuitem.58 57 try { 59 58 fullscreen = new ContextMenuItem('Toggle Fullscreen...'); 60 59 addItem(fullscreen,fullscreenHandler); 61 60 } catch (err:Error) {} 62 // Add the 'stretching' menuitem.63 61 stretching = new ContextMenuItem('Stretching is '+view.config['stretching']+'...'); 64 62 addItem(stretching,stretchHandler); 65 // Add the 'about' menuitem.66 63 if(view.config['abouttext'] == 'JW Player' || view.config['abouttext'] == undefined) { 67 64 about = new ContextMenuItem('About JW Player '+view.config['version']+'...'); … … 70 67 } 71 68 addItem(about,aboutHandler); 72 // Add the 'debug' menuitem.73 69 if(Capabilities.isDebugger == true || view.config['debug'] != 'none') { 74 70 debug = new ContextMenuItem('Logging to '+Logger.output+'...'); -
trunk/as3/com/jeroenwijering/plugins/Watermark.as
r354 r374 4 4 import com.jeroenwijering.events.*; 5 5 import com.jeroenwijering.utils.*; 6 7 import fl.transitions.*;8 import fl.transitions.easing.*;9 6 10 7 import flash.display.*; … … 23 20 public var clip:MovieClip; 24 21 /** Configuration flashvars pushed by the player. **/ 25 public var config:Object = {}; 22 public var config:Object = { 23 position:'over' 24 }; 26 25 /** Configuration flashvars, not overwritten by the player. **/ 27 26 private var _config:Object = { … … 61 60 /** Fade out watermark. **/ 62 61 private function hide():void { 63 _config['state'] = false; 64 clip.mouseEnabled = false; 65 TransitionManager.start(clip,{ 66 type:Fade, 67 direction:Transition.OUT, 68 duration:0.3, 69 easing:Regular.easeIn 70 }); 62 Animations.fade(clip,0,0.1); 71 63 }; 72 64 … … 80 72 for (var i:String in config) { _config[i] = config[i]; } 81 73 } 82 clip.visible = false;83 clip.alpha = _config['out'];84 74 clip.buttonMode = true; 85 75 clip.addEventListener(MouseEvent.CLICK,clickHandler); … … 94 84 loader.load(new URLRequest(_config['file'])); 95 85 } 86 clip.alpha = 0; 87 clip.visible = false; 96 88 }; 97 89 … … 106 98 /** Handle mouse out state **/ 107 99 private function outHandler(evt:MouseEvent):void { 108 clip.alpha = _config['out'];100 Animations.fade(clip,0,0.2); 109 101 }; 110 102 … … 112 104 /** Handle mouse over state **/ 113 105 private function overHandler(evt:MouseEvent):void { 114 clip.alpha = _config['over']; 106 clearTimeout(timeout); 107 Animations.fade(clip,_config['over'],0.1); 115 108 }; 116 109 … … 135 128 /** Fade in watermark. **/ 136 129 private function show():void { 137 if(!_config['state']) { 138 _config['state'] = true; 139 TransitionManager.start(clip,{ 140 type:Fade, 141 direction:Transition.IN, 142 duration:0.3, 143 easing:Regular.easeIn 144 }); 145 } 130 Animations.fade(clip,_config['out'],0.1); 146 131 timeout = setTimeout(hide,_config['timeout']*1000); 147 clip.mouseEnabled = true;148 132 }; 149 133 -
trunk/as3/com/jeroenwijering/utils/NetClient.as
r213 r374 31 31 out[i] = dat[i]; 32 32 } 33 callback.on Data(out);33 callback.onClientData(out); 34 34 }; 35 35 -
trunk/as3/com/jeroenwijering/utils/Stretcher.as
r210 r374 28 28 * @param hei The target height. 29 29 * @param typ The stretching type. 30 ***/30 **/ 31 31 public static function stretch(clp:DisplayObject,wid:Number,hei:Number,typ:String='uniform'):void { 32 32 var xsc:Number = wid/clp.width; -
trunk/as3/yt.as
r161 r374 73 73 }; 74 74 function onPlayerError(erc:Number) { 75 _as2_to_as3.send('AS2_'+unique,"onError", stt);75 _as2_to_as3.send('AS2_'+unique,"onError",erc); 76 76 clearInterval(timeInterval); 77 77 };
Note: See TracChangeset
for help on using the changeset viewer.
